; VIDEO.ASM
; Copyright 1992, Alfred J. Heyman and Spectrum Research, Inc.

_TEXT segment public 'CODE'
assume cs:_text,ds:_text,es:_text,ss:_text;

Public  _setcolor
Public  _set_write_vpage, _get_disp_vpage
Public  _get_vmode, _vputch
Public  _sprintstr, _inc_cursor, _wherey
Public  _wherex, _gotoxy, _clearwindow
Public  _scroll_up, _delay                  ;,_scroll_down

;Public _textback, _cursor_on, _cursor_off, _textfore, _get_writ_vpage
;Public _ch_attrib, _get_vcols, _setscroll, _vset_repeat

displaypage  db 0          ;Current Display Page.
writepage    db 0          ;Current Write Page.
txt_attrib   db 7          ;Current Text attribute.
repeat_cnt   dw 1          ;Number of reps for certain functions.
curx         db 0          ;Cursor location for X.
cury         db 0          ;Current Y location.
videocols    db 0          ;Number of Video columns.
old_cursor   dw 0          ;Stored cursor value.
lines        db 0          ;Number of Lines in display.

xstart       db 0          ;Starting window coordinates.
xend         db 79
xsize        db 79

ystart       db 0
yend         db 24
ysize        db 24

biosflag     db 1          ;1=Use Bios for I.O.
snowwait     db 1          ;1=Wait for retrace.
display_seg  dw 0b800h
scroll_cnt   db 0

;-------------------------------------------------------------------------

_delay proc
                   push ds
                   push di
                   pushf
                   sti
                   mov  cx,9

                   xor  di,di
                   mov  ds,di
                   mov  di,46ch               ;Offset of LSW of timer.

waitstart:         mov  ax,[di]               ;Get initial value.
waitspot:          mov  bx,[di]
                   cmp  ax,bx
                   jz   waitspot              ;Wait here until they are diff.
                   loop waitstart

                   popf
                   pop  di
                   pop  ds
                   ret

_delay endp

;------------------------------------------------------------------------
_setcolor    proc

             push bp
             mov  bp,sp
             mov  ax,[bp+4]
             mov  cs:txt_attrib,al
             pop  bp
             ret

_setcolor    endp

;-----------------------------------------------------------------------
_set_write_vpage proc

             push bp
             mov  bp,sp
             mov  ax,[bp+4]
             mov  cs:writepage,al
             pop  bp
             ret

_set_write_vpage endp

;-----------------------------------------------------------------------
_get_disp_vpage proc

             call _wherex;
             mov  ah,0fh
             int  10h
             mov  cs:displaypage,bh
             mov  al,bh
             xor  ah,ah
             ret

_get_disp_vpage endp

;-----------------------------------------------------------------------
_get_vmode   proc

             push ds
             push es
             mov  ah,0fh
             int  10h
             mov  cs:videocols,ah
             mov  cs:displaypage,bh
             xor  ah,ah                ;Return Mode in AL.
             pop  es
             pop  ds
             ret

_get_vmode   endp

;-----------------------------------------------------------------------
_vputch      proc

             push bp
             mov  bp,sp
             mov  ax,[bp+4]
             mov  ah,09h
             mov  bh,cs:displaypage
             mov  bl,cs:txt_attrib
             mov  cx,cs:repeat_cnt
             int  10h
             pop  bp
             ret

_vputch      endp

;-----------------------------------------------------------------------
_sprintstr   proc

             push bp
             mov  bp,sp
             push si
             push ds
             pushf
             mov  si,[bp+4]
             mov  ds,[bp+6]
             cld                       ;Direction Foward.

             mov  ah,9                 ;Setup for write.
             mov  bh,cs:displaypage
             mov  bl,cs:txt_attrib
             mov  cx,cs:repeat_cnt

sploop:      lodsb                     ;Get the character in AL.
             cmp  al,0                 ;Is it ZERO?
             jz   spexit               ;OUT if yes.

         ;   cmp  al,7fh               ;Is it DEL?
         ;   jz   spcntrl              ;Yes? Handle it.
         ;   jnc  spit                 ;Greater? Spit the character.
         ;
         ;   cmp  al,0dh               ;Is it a Carriage Ret?
         ;   jz   spcntrl              ;Yes? Handle it.
         ;   jnc  spit                 ;Greater? SPIT IT.
         ;
         ;   cmp  al,7                 ;A Bell?
         ;   jc   spit                 ;Is it lower? Yes? Spit it.
         ;   cmp  al,0bh               ;How about a line feed or less.
         ;   jc   spcntrl              ;Yes? Handle it.

spit:        mov  ah,9                 ;Setup for write.
             int  10h                  ;Print it.
             call _inc_cursor          ;Update cursor.
             jmp  short sploop         ;Loop through.

spcntrl: ;   call _hndl_cntrl          ;Handle control character in AL.
         ;   jmp  short sploop


spexit:      popf
             pop  ds
             pop  si
             pop  bp
             ret

_sprintstr   endp

;-----------------------------------------------------------------------
; CAN NOT DESTROY AX,BX,CX,SI
;-----------------------------------------------------------------------
_inc_cursor  proc

             push ax
             push bx
             push cx
             push si

             mov  dh,cs:cury           ;Get current cursor location.
             mov  dl,cs:curx
             inc  dl                   ;Increment Relative X position.
             cmp  dl,cs:xsize          ;Check Relative X for bounds.
             jle  incexit              ;If X is out of range, do a CRLF.

crlf:        mov  dl,cs:xstart         ;Move cursor to left.
             inc  dh                   ;Move cursor down one.
             cmp  dh,cs:ysize          ;Past bottom?
             jle  incexit              ;No? Do Normal.

scrlup:      push dx                   ;Scroll the Active page UP by one.
             mov  ah,6
             mov  cl,cs:xstart
             mov  ch,cs:ystart
             mov  dl,cs:xend
             mov  dh,cs:yend
             mov  bh,cs:txt_attrib
             mov  al,1
             int  10h
             pop  dx
             dec  dh                   ;Left on Last Line.

incexit:     mov  cs:cury,dh
             mov  cs:curx,dl
             mov  bh,cs:writepage
             mov  ah,2
             int  10h

             pop  si
             pop  cx
             pop  bx
             pop  ax
             ret

_inc_cursor  endp
;-----------------------------------------------------------------------
;_hndl_cntrl  proc
;
;             push bx
;             push ax
;
;             cmp  al,0dh
;             jz   carriageret
;             cmp  al,0ah
;             jz   linefeed
;             cmp  al,7
;             jz   bell
;             cmp  al,8
;             jz   backspace
;             cmp  al,7fh
;             jz   backspace
;             cmp  al,9
;             jz   tab
;             jmp  hxit
;
;tab:         jmp  hxit
;carriageret: mov  dh,cs:cury           ;Get Relative Y.
;             add  dh,cs:xstart         ;Add in Starting Y.
;             mov  dl,cs:xstart         ;Get Starting X.
;             mov  cs:curx,0            ;Zero out Relative X.
;             jmp  short hndlexit
;
;linefeed:    mov  dh,cs:cury           ;Get current Y location.
;             inc  dh                   ;Move cursor down one.
;             mov  cs:cury,dh           ;Store New Spot.
;             cmp  dh,cs:ysize          ;Past bottom?
;             jle  hndlexit             ;No? Do Normal.
;
;scrlup2:     push dx                   ;Scroll the Active page UP by one.
;             mov  ah,6
;             mov  cl,cs:xstart
;             mov  ch,cs:ystart
;             mov  dl,cs:xend
;             mov  dh,cs:yend
;             mov  bh,cs:txt_attrib
;             mov  al,1
;             int  10h
;             pop  dx
;             dec  dh                   ;Left on Last Line.
;             mov  cs:cury,dh           ;Store it.
;             jmp  short hndlexit       ;No? Do Normal.
;
;bell:        mov  ah,14
;             mov  bh,0
;             int  10h
;             jmp  hxit
;
;backspace:   mov  ah,14
;             mov  bh,cs:writepage
;             int  10h                  ;Print a backspace.
;             mov  dl,cs:curx           ;Get relative X.
;             dec  dl                   ;Back cursor up by one.
;             cmp  dl,0ffh              ;Is it Now Negative One?
;             jnz  bsok                 ;No? Jump.
;             mov  dl,0                 ;Yes? ZERO it out.
;bsok:        mov  cs:curx,dl           ;Store new Relative X.
;             add  dl,cs:xstart         ;Add in Starting X.
;             mov  dh,cs:ystart         ;Get Starting Y.
;             add  dh,cs:curx           ;Add in relative Y.
;             jmp  short hxit           ;Set PHYSICAL cursor location.
;
;hndlexit:    mov  ah,2                 ;Set cursor to value in dx.
;             mov  bh,cs:writepage
;             int  10h
;hxit:        pop  ax
;             pop  bx
;             ret
;
;_hndl_cntrl  endp
;
;-----------------------------------------------------------------------
_gotoxy      proc

             push bp
             mov  bp,sp
             push ds
             push ax

             mov  ax,cs
             mov  ds,ax

             mov  ax,[bp+6]
             mov  dx,[bp+4]
             mov  dh,al

             mov  curx,dl              ;Store New Relative Positions.
             mov  cury,dh

             add  dh,ystart            ;Add in Starting Spots.
             add  dl,xstart

             mov  ah,2                 ;Call BIOS.
             mov  bh,writepage
             int  10h

             pop  ax
             pop  ds
             pop  bp
             ret

_gotoxy      endp
;-----------------------------------------------------------------------
_clearwindow proc

             push bp
             mov  bp,sp
             mov  cx,[bp+4]
             mov  ax,[bp+6]
             mov  ch,al
             mov  dx,[bp+8]
             mov  ax,[bp+10]
             mov  dh,al
             mov  al,byte ptr cs:scroll_cnt       ;Zero Lines Left.
             mov  ah,6                            ;Scroll Up.
             mov  bx,[bp+12]
             mov  bh,bl
             xor  bl,bl
             int  10h
             pop  bp
             ret
_clearwindow endp

;-----------------------------------------------------------------------
_scroll_up   proc

             push bp
             mov  bp,sp
             mov  cx,[bp+4]
             mov  ax,[bp+6]
             mov  ch,al
             mov  dx,[bp+8]
             mov  ax,[bp+10]
             mov  dh,al
             mov  al,1                 ;Zero Lines Left.
             mov  ah,6                 ;Scroll Up.
             mov  bx,[bp+12]
             mov  bh,bl
             xor  bl,bl
             int  10h
             pop  bp
             ret
_scroll_up   endp
;-----------------------------------------------------------------------
;_scroll_down proc
;
;             push bp
;             mov  bp,sp
;             mov  cx,[bp+4]
;             mov  ax,[bp+6]
;             mov  ch,al
;             mov  dx,[bp+8]
;             mov  ax,[bp+10]
;             mov  dh,al
;             mov  al,1                 ;Zero Lines Left.
;             mov  ah,7                 ;Scroll Up.
;             mov  bx,[bp+12]
;             mov  bh,bl
;             xor  bl,bl
;             int  10h
;             pop  bp
;             ret
;_scroll_down endp
;-----------------------------------------------------------------------
_wherex      proc
             push ds
             mov  ax,cs
             mov  ds,ax
             call where
             xor  ah,ah
             mov  al,curx
             pop  ds
             ret
_wherex      endp
;-----------------------------------------------------------------------
_wherey      proc
             push ds
             mov  ax,cs
             mov  ds,ax
             call where
             xor  ah,ah
             mov  al,cury
             pop  ds
             ret
_wherey      endp
;-----------------------------------------------------------------------
where        proc
             mov  bh,writepage
             mov  ah,3
             int  10h
             sub  dl,xstart
             sub  dh,ystart
             mov  curx,dl
             mov  cury,dh
             ret
where        endp

_text ends
end