; GETCD.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, _textback, _textfore, _cursor_off
Public  _cursor_on, _set_write_vpage, _set_disp_vpage, _get_disp_vpage
Public  _get_writ_vpage, _get_vmode, _get_vcols, _vset_repeat, _vputch
Public  _sprintstr, _inc_cursor, _wherey, _blink, _intensity
Public  _wherex, _gotoxy, _clearwindow, _ega_43_line, _ega_25_line
Public  _ch_attrib, _scroll_up, _scroll_down, _setscroll, _bang, _delay


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
                   mov  cx,9

                   mov  di,0
                   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

                   pop  di
                   pop  ds
                   ret

_delay endp

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

_bang        proc

             mov  cx,12
bangagain:   push cx

             mov  ah,6
             mov  al,2
             mov  bh,7
             mov  cx,0c00h
             mov  dx,194fh
             int  10h

             mov  ah,7
             mov  al,2
             mov  bh,7
             mov  cx,0
             mov  dx,0c4fh
             int  10h    

             pop  cx
             loop bangagain

             ret


_bang        endp

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

_ch_attrib   proc

             push bp
             mov  bp,sp
             mov  ax,[bp+4]
             mov  cl,al

             push cx
             mov  bh,cs:displaypage     ;Get character at cursor location to AL.
             mov  ah,8
             int  10h
             pop  cx                    ;Put character down with new attribute.

             mov  bl,cl
             mov  bh,cs:displaypage
             mov  ah,9
             mov  cx,1
             int  10h
             pop  bp
             ret

_ch_attrib   endp

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

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

_setcolor    endp

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

_setscroll   proc

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

_setscroll   endp

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

_textback    proc

             push bp
             mov  bp,sp
             mov  ax,[bp+4]
             and  ax,7                 ;Mask Out Unwanted data.
             mov  cl,4
             shl  al,cl                ;Move color to background spot.
             and  cs:txt_attrib,8fh    ;Mask out old background color.
             or   cs:txt_attrib,al     ;Put in new background color.
             pop  bp
             ret

_textback    endp

;-----------------------------------------------------------------------
_textfore    proc

             push bp
             mov  bp,sp
             mov  ax,[bp+4]
             and  ax,7                 ;Mask Out Unwanted data.
             and  cs:txt_attrib,0f8h   ;Mask out old foreground color.
             or   cs:txt_attrib,al     ;Put in new foreground color.
             pop  bp
             ret

_textfore    endp

;-----------------------------------------------------------------------
_cursor_off  proc

             mov  ah,3
             int  10h                  ;Get cursor type.
             mov  cs:old_cursor,cx     ;Save type.
             mov  cx,0e00h             ;Value for hidden cursor.
             mov  ah,1
             int  10h                  ;Set cursor type.
             ret

_cursor_off  endp
;-----------------------------------------------------------------------
_cursor_on   proc

             mov  ah,1
             mov  cx,cs:old_cursor
             int  10h
             ret

_cursor_on   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


;-----------------------------------------------------------------------
_set_disp_vpage proc

             push bp
             mov  bp,sp
             mov  ax,[bp+4]
             mov  cs:displaypage,al
             mov  ah,5
             int  10h
             pop  bp
             ret

_set_disp_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_writ_vpage proc

             mov  al,cs:writepage
             xor  ah,ah
             ret

_get_writ_vpage endp

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

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

_get_vmode   endp

;-----------------------------------------------------------------------
_get_vcols   proc

             call _wherex
             mov  ah,0fh
             int  10h
             mov  al,ah
             xor  ah,ah
             mov  cs:videocols,al
             ret

_get_vcols   endp

;-----------------------------------------------------------------------
_vset_repeat proc

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

_vset_repeat 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
;-----------------------------------------------------------------------
_ega_43_line proc

             mov  ax,3                 ;Color 80 X 25
             mov  bx,0
             int  10h

             mov  ax,1112h             ;43 Line mode.
             int  10h

             mov  ax,0                 ;GotoXY 0,0
             push ax
             push ax
             call _gotoxy

             push ds
             xor  ax,ax
             mov  ds,ax
             or   byte ptr ds:[487h],1
             pop  ds

             mov  ah,1                 ;Change cursor type.
             mov  cx,600h
             int  10h

             mov  ax,1200h             ;Alternate printscreen routine.
             mov  bx,20h
             int  10h

             ret

_ega_43_line endp
;-----------------------------------------------------------------------
_ega_25_line proc

             mov  ax,3                 ;Color 80 X 25
             mov  bx,0
             int  10h

             mov  ax,0                 ;GotoXY 0,0
             push ax
             push ax
             call _gotoxy

             push ds
             xor  ax,ax
             mov  ds,ax
             and  byte ptr ds:[487h],254
             pop  ds

             mov  ah,1                 ;Change cursor type.
             mov  cx,607h
             int  10h

             ret

_ega_25_line endp
;-----------------------------------------------------------------------
_blink       proc

             push bp
             mov  bp,sp
             mov  ax,[bp+4]
             and  cs:txt_attrib,7fh
             mov  cl,7
             shl  al,cl
             or   cs:txt_attrib,al
             pop  bp
             ret

_blink       endp
;-----------------------------------------------------------------------
_intensity   proc

             push bp
             mov  bp,sp
             mov  ax,[bp+4]
             and  cs:txt_attrib,0f7h
             mov  cl,3
             shl  al,cl
             or   cs:txt_attrib,al
             pop  bp
             ret

_intensity   endp
;------------------------------------------------form-------------------

_text ends
end