;-------------------------------------------------------------------------
;    video.asm                                 created 5-11-85
;
;    VIDEO ROUTINES
;    (C) COPYRIGHT 1985 BY THOMAS D. WEBB
;
;    ALL RIGHTS RESERVED.
;    PERMISSION IS GRANTED FOR UNLIMITED PERSONAL, NON-COMMERCIAL USE.
;
;    COMPUTER LANGUAGE   Vol 3, Number 1   Jan 1986     pages 49 - 58
;
;-------------------------------------------------------------------------
;
;    Revised  2-21-86 by David Lovelock to run under Microsoft's C Ver 3.00
;             and Microsoft's Macro Assembler Ver 3.00
;
;-------------------------------------------------------------------------

TITLE              VIDEO
                   NAME    VIDEO

BUFFER_SIZE        EQU     2000D     ;THE VIDEO BUFFER SIZE IN WORDS
NUM_BYTES_IN_ROW   EQU     80        ;NUMBER OF BYTES IN A ROW
MONOCHROME_SEGADR  EQU     0B000H    ;ADDRESS OF MONOCHROME BUFFER
GRAPHICS_SEGADR    EQU     0B800H    ;ADDRESS OF GRAPHICS BUFFER

STACK              SEGMENT           PARA STACK 'STACK'
                   DB                64 DUP ('STACK   ')
STACK              ENDS


IGROUP             GROUP   _TEXT
                   ASSUME  CS:IGROUP,SS:STACK

_TEXT              SEGMENT BYTE PUBLIC 'CODE'
;-------------------------------------------------------------------------
; CLEAR            (ROUTINE 1)
;   THIS ROUTINE CLEARS THE SCREEN
;
; THE C LANGUAGE CALL IS:
;       CLEAR();
;-------------------------------------------------------------------------
                   PUBLIC  _CLEAR
_CLEAR             PROC    NEAR
                   PUSH    BP        ;THE FRAME POINTER
                   MOV     AH,6      ;SCROLL ACTIVE PAGE UP
                   MOV     AL,019H   ;CLEAR 25 LINES
                   MOV     CX,0H     ;UPPER LEFT OF SCROLL
                   MOV     DX,2479H  ;UPPER RIGHT OF SCROLL
                   MOV     BH,7H     ;USE NORMAL ATTIBUTE ON BLANKED LINE
                   INT     10H       ;VIDEO-IO
                   POP     BP        ;THE FRAME POINTER
                   RET
_CLEAR             ENDP
;-------------------------------------------------------------------------
; LOCATE           (ROUTINE 2)
;  THIS ROUTINE WILL LOCATE THE CURSOR AT A ROW AND COLUMN ON THE SCREEN
;
; THE C LANGUAGE CALL IS:
;       LOCATE(ROW,COLUMN);
;       ROW RANGE IS 0 - 24
;       COL RANGE IS 0 - 79
;-------------------------------------------------------------------------
                   PUBLIC  _LOCATE
_LOCATE            PROC    NEAR
                   PUSH    BP        ;THE FRAME POINTER
                   MOV     BP,SP     ;POINT TO MOST RECENT STACK ELEMENT
                   MOV     DH,[BP+4] ;GET THE ROW ...
                   MOV     DL,[BP+6] ;... AND THE COLUMN
                   MOV     BH,0H     ;GRAPHICS PAGE NO.
                   MOV     AH,2H     ;SET CURSOR POSITION
                   INT     10H       ;VIDEO-IO
                   POP     BP        ;THE FRAME POINTER
                   RET
_LOCATE            ENDP
;-------------------------------------------------------------------------
; CURSIZE          (ROUTINE 3)
;  THIS ROUTINE SETS THE SIZE OF THE CURSOR
;
; THE C LANGUAGE CALL IS:
;       CURSIZE(START_LINE,STOP_LINE);
;       START_LINE = 12 IS NORMAL FOR MONOCHROME ADAPTER
;       STOP_LINE  = 13 IS NORMAL FOR MONOCHROME ADAPTER
;-------------------------------------------------------------------------
                   PUBLIC  _CURSIZE
_CURSIZE           PROC    NEAR
                   PUSH    BP        ;THE FRAME POINTER
                   MOV     BP,SP     ;POINT TO MOST RECENT STACK ELEMENT
                   MOV     CH,[BP+4] ;CURSOR START LINE
                   MOV     CL,[BP+6] ;CURSOR STOP LINE
                   MOV     AH,1H     ;SET CURSOR TYPE
                   INT     10H       ;VIDEO-IO
                   POP     BP        ;THE FRAME POINTER
                   RET
_CURSIZE           ENDP
;-------------------------------------------------------------------------
; GET_MODE          (ROUTINE 4)
;  THIS ROUTINE RETURNS THE CRT MODE IN AL, AND THE NUMBER OF
;  CHARACTER COLUMNS ON THE SCREEN IN AH.
;
; THE C LANGUAGE CALL IS:
;       mode_area.value = get_mode();
;       WHERE mode_area is defined as :
;       union
;       {
;         int value;
;         struct
;           {
;             char al;
;             char ah;
;           } al_ah;
;        } mode_area;
;-------------------------------------------------------------------------
                   PUBLIC  _GET_MODE
_GET_MODE          PROC    NEAR
                   PUSH    BP        ;THE FRAME POINTER
                   MOV     AX,0      ;CLEAR THE REGISTER
                   MOV     AH,15     ;GET CURRENT VIDEO MODE
                   INT     10H       ;VIDEO-IO
                   POP     BP        ;THE FRAME POINTER
                   RET
_GET_MODE          ENDP
;-------------------------------------------------------------------------
; SET_VIDEO_ADDRESS (ROUTINE 5)
;  THIS ROUTINE IS USED IN SEVERAL OF THE OTHER ROUTINES TO TEST THE
;  VIDEO MODE AND TO SET THE CORRECT VIDEO BUFFER ADDRESS (MON OR GR).
;  THE VIDEO BUFFER ADDRESS IS RETURNED IN AX.
;-------------------------------------------------------------------------
SET_VIDEO_ADDRESS  PROC    NEAR
                   CALL    _GET_MODE             ;GET CRT MODE
                   CMP     AL,7H                 ;IS IT MOMOCHROME?
                   JNE     ITS_GRAPHICS
                   MOV     AX,MONOCHROME_SEGADR  ;MONO BUFF SEG ADDR
                   JMP     RETURN
ITS_GRAPHICS:      MOV     AX,GRAPHICS_SEGADR    ;GRAPHICS BUFF SEG ADDR
RETURN:            RET
SET_VIDEO_ADDRESS  ENDP
;-------------------------------------------------------------------------
; CALC_VIDEO_OFFSET (ROUTINE 6)
;  THIS ROUTINE IS USED IN SEVERAL OF THE OTHER ROUTINES TO CALCULATE
;  THE OFFSET INTO THE VIDEO BUFFER FOR MOVING CHARACTERS.
;  DX MUST BE SET TO THE ROW, AND CX TO THE COLUMN.  OFFSET RETURNED IN AX.
;-------------------------------------------------------------------------
CALC_VIDEO_OFFSET  PROC    NEAR
                   MOV     AX,NUM_BYTES_IN_ROW   ;NUMBER OF BYTES IN ROW
                   MUL     DX                    ;RESULT IS IN AX
                   ADD     AX,CX                 ;THE COLUMN
                   SHL     AX,1                  ;MULTIPLY BY 2 FOR CHAR/ATTR
                   RET
CALC_VIDEO_OFFSET  ENDP
;-------------------------------------------------------------------------
; ISRTSTR           (ROUTINE 7)
;  THIS ROUTINE POSITIONS ITSELF IN THE VIDEO BUFFER, THEN INSERTS A
;  NULL-TERMINATED STRING, ALONG WITH AN ATTRIBUTE, DIRECTLY INTO THE
;  VIDEO BUFFER.
; THE C LANGUAGE CALL IS:  ISRTSTR(ROW,COLUMN,STRING,ATTR);
;    Normal attribute is 7
;    ROW between 0 and 24
;    COL between 0 and 79
;-------------------------------------------------------------------------
                   PUBLIC  _ISRTSTR
_ISRTSTR           PROC    NEAR
                   PUSH    ES
                   PUSH    BP                  ;THE FRAME POINTER
                   MOV     BP,SP               ;POINT TO STACK
                   MOV     DX,[BP+6]           ;GET THE ROW
                   MOV     CX,[BP+8]           ;GET THE COLUMN
                   CALL    CALC_VIDEO_OFFSET   ;CALC OFFSET INTO VID BUFFER
                   MOV     DI,AX               ;OFFSET RETURNED IN AX
                   MOV     SI,[BP+10]          ;GET SOURCE STRING OFFSET
                   MOV     DH,[BP+12]          ;GET ATTRIBUTE
                   CALL    SET_VIDEO_ADDRESS   ;SET MONO OR GRAPHICS
                   MOV     ES,AX               ;VID BUFFER ADDRESS INTO ES
ISRT_LOOP:         MOV     DL,BYTE PTR [SI]    ;CHARACTER TO INSERT
                   CMP     DL,0                ;END OF STRING?
                   JE      ISRTSTR_EXIT        ;EXIT IF YES
                   MOV     ES:WORD PTR [DI],DX ;MOVE CHAR AND ATT TO CRT BUF
                   ADD     DI,2H               ;POINT TO NEXT CRT BUF LOC
                   ADD     SI,1H               ;POINT TO NEXT SOURCE STR BYTE
                   JMP     ISRT_LOOP           ;GO MOVE ANOTHER WORD
ISRTSTR_EXIT:      POP     BP
                   POP     ES
                   RET
_ISRTSTR           ENDP
;-------------------------------------------------------------------------
; ISRTCNT           (ROUTINE 8)
;  THIS ROUTINE POSITIONS ITSELF IN THE VIDEO BUFFER, THEN INSERTS N
;  BYTES FROM AN ARRAY, ALONG WITH AN ATTRIBUTE, DIRECTLY INTO THE
;  VIDEO BUFFER.
; THE C LANGUAGE CALL IS:  ISRTCNT(ROW,COLUMN,STRING,ATTR,NUM_BYTES);
;    Normal attribute is 7
;    ROW between 0 and 24
;    COL between 0 and 79
;-------------------------------------------------------------------------
                   PUBLIC  _ISRTCNT
_ISRTCNT           PROC    NEAR
                   PUSH    ES
                   PUSH    BP                  ;THE FRAME POINTER
                   MOV     BP,SP               ;POINT TO STACK
                   MOV     DX,[BP+6]           ;GET THE ROW
                   MOV     CX,[BP+8]           ;GET THE COLUMN
                   CALL    CALC_VIDEO_OFFSET   ;CAL OFFSET INTO VID BUFFER
                   MOV     DI,AX               ;OFFSET RETURNED IN AX
                   MOV     SI,[BP+10]          ;GET SOURCE STRING OFFSET
                   MOV     DH,[BP+12]          ;GET ATTRIBUTE
                   MOV     CX,[BP+14]          ;GET NUMBER OF BYTES
                   CALL    SET_VIDEO_ADDRESS   ;SET MONO OR GRAPHICS
                   MOV     ES,AX               ;VID BUFFER ADDRESS INTO ES
ISRTCNT_LOOP:      MOV     DL,BYTE PTR [SI]    ;CHARACTER TO INSERT
                   MOV     ES:WORD PTR [DI],DX ;MOVE CHAR AND ATT TO CRT BUF
                   ADD     DI,2H               ;POINT TO NEXT CRT BUF LOC
                   ADD     SI,1H               ;POINT TO NEXT SOURCE STR BYTE
                   LOOP    ISRTCNT_LOOP        ;GO MOVE ANOTHER WORD
ISRTCNT_EXIT:      POP     BP
                   POP     ES
                   RET
_ISRTCNT           ENDP
;-------------------------------------------------------------------------
; PUTCHAT           (ROUTINE 9)
;  THIS ROUTINE WRITES A CHARACTER AND ATTRIBUTE TO THE SCREEN.
;  THE CURSOR DOES NOT MOVE.
; THE C LANGUAGE CALL IS:  PUTCHAT(CHARACTER,ATTRIBUTE);
;    Normal attribute is 7
;-------------------------------------------------------------------------
                   PUBLIC  _PUTCHAT
_PUTCHAT           PROC    NEAR                ;
                   PUSH    BP                  ;THE FRAME POINTER
                   MOV     BP,SP               ;POINT TO STACK
                   MOV     AL,[BP+4]           ;GET THE CHARACTER
                   MOV     BL,[BP+6]           ;GET THE ATTRIBUTE
                   MOV     BH,0H               ;DISPLAY PAGE #
                   MOV     CX,1H               ;NUMBER TO WRITE
                   MOV     AH,9H               ;WRITE
                   INT     10H                 ;VIDEO_IO
                   POP     BP
                   RET
_PUTCHAT           ENDP
;-------------------------------------------------------------------------
; CRTBUF            (ROUTINE 10)
;  THIS ROUTINE ACCEPTS TWO PARAMETERS
;      1.  SAVE = 0 AND REPLACE = 1
;      2.  THE ADDRESS TO SAVE THE VIDEO BUFFER INTO OR REPLACE THE
;          VIDEO BUFFER FROM.
;      CALLS CRTSAVE TO SAVE THE CRT BUFFER.
;      CALLS CRTREPL TO REPLACE THE CRT BUFFER.
; THE C LANGUAGE CALL IS:  CRTBUF(SAVE,SAVE_AREA);
;                     OR:  CRTBUF(REPLACE,SAVE_AREA);
;-------------------------------------------------------------------------
                   PUBLIC  _CRTBUF
_CRTBUF            PROC    NEAR
                   PUSH    BP                  ;THE FRAME POINTER
                   MOV     BP,SP               ;POINT TO STACK
                   MOV     DX,[BP+4]           ;SAVE/RESTORE INDICATOR
                   CMP     DX,0                ;SAVE ?
                   JNE     RESTORE_IT
SAVE_IT:           CALL    CRTSAVE
                   JMP     CRTBUF_EXIT
RESTORE_IT:        CALL    CRTREPL
CRTBUF_EXIT:       POP     BP
                   RET
_CRTBUF            ENDP
;-------------------------------------------------------------------------
; CRTSAVE           (ROUTINE 11)
;    CALLED BY CRTBUF TO SAVE CRT BUFFER INTO A SAVE AREA
;-------------------------------------------------------------------------
CRTSAVE            PROC    NEAR
                   PUSH    ES                  ;ES AND DS ARE MODIFIED ..
                   PUSH    DS                  ;.. SO SAVE THEM
                   PUSH    BP                  ;SAVE FRAME POINTER
                   MOV     BP,SP               ;ADDRESS THE STACK
                   MOV     CX,DS               ;DATA SEG IN DESTINATION
                   MOV     ES,CX               ;ES HAS DEST SEG ADDRESS
                   MOV     DI,[BP+14]          ;DESTINATION OFSET
                   MOV     CX,BUFFER_SIZE      ;BUFFER SIZE IN WORDS
                   CALL    SET_VIDEO_ADDRESS   ;SET MONO OR GRAPHICS
                   MOV     DS,AX               ;VIDEO BUFFER ADDR INTO DS
                   MOV     SI,0                ;SOURCE OFFSET
                   CLD                         ;SET DF=0 TO MOVE FORWARD
REP                MOVSW                       ;MOVE 2000 WORDS
                   POP     BP                  ;THE FRAME POINTER
                   POP     DS                  ;MUST RESTORE DS ..
                   POP     ES                  ;.. AND ES
                   RET
CRTSAVE            ENDP
;-------------------------------------------------------------------------
; CRTREPL           (ROUTINE 12)
;    CALLED BY CRTBUF TO REPLACE CRT BUFFER FROM A SAVE AREA
;-------------------------------------------------------------------------
CRTREPL            PROC    NEAR
                   PUSH    ES                  ;ES IS MODIFIED SO SAVE IT
                   PUSH    BP                  ;SAVE FRAME POINTER
                   MOV     BP,SP               ;ADDRESS THE STACK
                   MOV     SI,[BP+12]          ;SOURCE OFFSET
                   CALL    SET_VIDEO_ADDRESS   ;SET MONO OR GRAPHICS
                   MOV     ES,AX               ;VIDEO BUFFER ADDR INTO DS
                   MOV     DI,0                ;DESTINATION OFFSET
                   MOV     CX,BUFFER_SIZE      ;BUFFER SIZE IN WORDS
                   CLD                         ;SET DF=0 TO MOVE FORWARD
REP                MOVSW                       ;MOVE 2000 WORDS
                   POP     BP                  ;THE FRAME POINTER
                   POP     ES                  ;MUST RESTORE ES
                   RET
CRTREPL            ENDP
;-------------------------------------------------------------------------
; SCANCRT           (ROUTINE 13)
;  THIS ROUTINE POSITIONS ITSELF IN THE CRT BUFFER, THEN MOVES N BYTES,
;  NOT NULL-TERMINATED, TO THE ADDRESS OF AN ARAY PROVIDED BY THE CALLER.
;
; THE C LANGUAGE CALL IS:  SCANCRT(ROW,COLUMN,STRING,NUM_BYTES);
;-------------------------------------------------------------------------
                   PUBLIC  _SCANCRT
_SCANCRT           PROC    NEAR
                   PUSH    ES                  ;ES IS MODIFIED SO SAVE IT
                   PUSH    BP                  ;THE FRAME POINTER
                   MOV     BP,SP               ;POINT TO STACK
                   MOV     DX,[BP+6]           ;GET THE ROW
                   MOV     CX,[BP+8]           ;GET THE COLUMN
                   CALL    CALC_VIDEO_OFFSET   ;CALC OFFSET INTO VID BUFFER
                   MOV     DI,AX               ;OFFSET RETURNED IN AX
                   MOV     SI,[BP+10]          ;GET SOURCE STRING OFFSET
                   MOV     CX,[BP+12]          ;NUMBER OF BYTES TO MOVE
                   CALL    SET_VIDEO_ADDRESS   ;SET MONO OR GRAPHICS
                   MOV     ES,AX               ;VID BUFFER ADDRESS INTO ES
SCAN_LOOP:         MOV     DL,ES:BYTE PTR [DI] ;GET CHAR FROM CRT BUFFER
                   MOV     BYTE PTR [SI],DL    ;MOVE CHAR TO STRING IN CALLER
                   ADD     DI,2H               ;POINT TO NEXT CRT BUF LOC
                   ADD     SI,1H               ;POINT TO NEXT DEST STR BYTE
                   LOOP    SCAN_LOOP
SCAN_EXIT:         POP     BP
                   POP     ES                  ;MUST RESTORE ES
                   RET
_SCANCRT           ENDP


_TEXT              ENDS
                   END
