; ANSI1-5ASM  Revised 8/24/85 Dave Terry for QuickBasic Compiler
; ANSI1-4ASM  Revised 8/23/85 Dave Staehlin

ANSI_PRNT SEGMENT PUBLIC 'CODESG'       ;By  David W. Terry
          ASSUME CS:ANSI_PRNT           ;    3036 So. Putnam Ct.
          PUBLIC ANSI                   ;    West Valley City, UT 84120

;                      Screen scroll mods by David C. Staehlin
;                                            5430 Candle Glow NE
;                                            Albuquerque, NM 87111
;
;                                                                                              Data (505) 821-7379 24 Hrs, 2400 Baud
STRG_LEN          DW 0                  ;CHANGED TO LENGTH OF STRING PASSED
VID_PAGE          DB 0                  ;Active video page
;
;
ANSI      PROC    FAR
          PUSH    BP
          MOV     BP,SP
;
          MOV     SI,10[BP]         ;GET STRING DESCRIPTOR
          MOV     BL,[SI+ 2]        ;REARRANGE LOW/HIGH BYTES
          MOV     BH,[SI+ 3]        ;NOW BX HOLDS THE ADDRESS OF THE STRING
          MOV     AX,[SI]           ;GET STRING LENGTH
          ADD     AX,BX             ;ADD INITIAL OFFSET (BX) TO LENGTH
          MOV     STRG_LEN,AX       ;STORE OFFSET PLUS LENGTH

          PUSH    BX
          MOV     AH,15             ;Get current video state
          INT     10H
          MOV     VID_PAGE,BH       ;Save it
          POP     BX

          MOV     AH,02             ;SET UP FOR FUNCTION CALL 02H
LOOP:
          MOV     DL,[BX]           ;SET DL TO CHARACTER TO PRINT
          PUSH    DX                ;Save the character in AX 'till we check..
          CALL    WHERE_ARE_WE      ; where the cursor is.......
          CMP     DH,17H            ;Row 23?
          JL      NOPE              ; Jump if less......
          CMP     DH,18H            ;Row 25?
          JNZ     NEXT2             ;Keep checking if not
          DEC     BX                ; Else backup one character
          JMP     SCROLL2           ; And go scroll the screen
;
NEXT2:    POP     DX                ;And restore the stack to where it was
          CMP     DL,0AH            ;Do we have a line feed?
          JZ      SCROLL            ; Yup - scroll this sucker!
          CMP     DL,0DH            ;  How about a carriage return?
          JNZ     NOPE1             ;  Nope - just go display it.......
          INC     BX                ;  Yup - see if next char is a line feed
          MOV     DX,[BX]
          CMP     DL,0AH            ;  Well, is it?
          JZ      SCROLL            ;  It sure is - let's go scroll
          DEC     BX                ;  Oops - just a carriage return
          JMP     SCROLL            ;  But let's go scroll it anyway

NOPE:     POP     DX
NOPE1:    INT     21H               ;Else just display it - same old boring stuff
SKIPIT:   INC     BX
          CMP     BX,STRG_LEN
          JL      LOOP              ;LOOP UNTIL ALL CHARS PROCESSED
;
          MOV     AH,03             ;SET UP FOR ROM-BIOS CALL (03H)
          MOV     BH,VID_PAGE       ;TO READ THE CURRENT CURSOR POSITION
          INT     10H               ;  DH = ROW   DL = COLUMN
          INC     DH                ;ADD 1 TO ROW (BECAUSE TOP OF SCREEN = 0)
          INC     DL                ;ADD 1 TO COL (BECAUSE POS 1 = 0)
;
          MOV     SI,[BP]+ 8
          MOV     [SI],DH           ;PASS BACK ROW COORDINATE
          MOV     SI,[BP]+ 6
          MOV     [SI],DL           ;PASS BACK COLUMN COORDINATE
;
          POP     BP
          RET     6
ANSI      ENDP

Where_Are_We:                    ;Get the current cursor position
          PUSH    AX                ;Save the registers
          PUSH    BX
          PUSH    CX
          MOV     AH,03             ;SET UP FOR ROM-BIOS CALL (03H)
          MOV     BH,VID_PAGE       ;TO READ THE CURRENT CURSOR POSITION
          INT     10H               ;  DH = ROW   DL = COLUMN
          POP     CX                ;Restore the registers
          POP     BX
          POP     AX
          RET                        ;And go back from wence we came

SCROLL2:  POP     DX                ;Put the stack like it was
SCROLL:   CALL    SCROLLIT          ;Scroll the screen
          JMP     SKIPIT

SCROLLIT: PUSH    AX                ;Save the registers that will be affected
          PUSH    BX
          PUSH    CX
          PUSH    DX
          PUSH    BP
          MOV     AH,2              ;Now set cursor position to 23,0
          MOV     DX,1700H          ;so we can get the proper character
          MOV     BH,VID_PAGE       ;attribute
          INT     10H
          MOV     AH,8              ;Get the current character attribute
          MOV     BH,VID_PAGE
          INT     10H
          MOV     BH,AH             ;Transfer the attribute to BH for next call
          MOV     AH,6              ;Otherwise scroll 23 lines
          MOV     AL,1              ; Only blank line 23
          MOV     CX,0000H          ; Begin scroll at position 0,0
          MOV     DX,174FH          ; End scroll at Line 23, Col 79
          INT     10H               ; And do it.......
          MOV     AH,2              ;Now set cursor position to 23,0
          MOV     DX,1700H
          MOV     BH,VID_PAGE
          INT     10H
          POP     BP
          POP     DX                ;Restore the stack like it was
          POP     CX
          POP     BX
          POP     AX
          RET

ANSI_PRNT ENDS
          END
