mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 01:14:21 +00:00
1069 lines
30 KiB
Plaintext
1069 lines
30 KiB
Plaintext
title 'Virtual Screen Handler '
|
||
|
||
|
||
;******************************************************
|
||
; *
|
||
; This module contains all code necessary for *
|
||
; full screen buffering on a serial (VT-52) *
|
||
; terminal. *
|
||
; Note: assumes m_alloc in XIOS header has been *
|
||
; initialized to reserve space for screen *
|
||
; images. *
|
||
; Last changed : 2/11/84 *
|
||
; *
|
||
;******************************************************
|
||
|
||
|
||
include vscreen.equ
|
||
include system.lib
|
||
include chrcomm.equ
|
||
include serdata.equ
|
||
|
||
eject
|
||
|
||
dseg
|
||
|
||
extrn mem_alloc:word
|
||
extrn ocdesctbl:word
|
||
public screen_image_tbl
|
||
|
||
cseg
|
||
|
||
public vs_init
|
||
public vs_conout
|
||
public default_esc
|
||
public vs_switch
|
||
public set_up_bx
|
||
extrn conout1:near
|
||
extrn serial_out:near
|
||
|
||
;************************************************
|
||
; VIRTUAL SCREEN INITIALIZATION *
|
||
;************************************************
|
||
|
||
;==========
|
||
vs_init:
|
||
;==========
|
||
|
||
mov ax, mem_alloc ; segment address given by GENCCPM
|
||
mov bx, offset scrn_image0 ; get first screen image
|
||
xor ch,ch
|
||
mov cl, nvcons ; do init for each virtual console
|
||
|
||
init_scrn: ; init each structure with the segment
|
||
mov vs_screen_seg,ax ; address of its char/attrib buffer
|
||
add bx, vs_struc_len
|
||
add ax,((crt_size + 15) shr 4) * 2
|
||
loop init_scrn
|
||
|
||
mov ah, vsa_normal ; attribute = normal
|
||
mov al, blank ; char = blank
|
||
mov bx, offset scrn_image0 ; with normal attribute byte
|
||
mov cl, nvcons
|
||
push es
|
||
|
||
clear_scrn: ; do one clear for each virtual console
|
||
push cx
|
||
mov es, vs_screen_seg ; get segment address back
|
||
sub di,di
|
||
mov cx, crt_size ; get screen size
|
||
rep stosw ; paint screen with blanks
|
||
pop cx
|
||
add bx,vs_struc_len ; index to next screen structure
|
||
loop clear_scrn
|
||
pop es ; we're done
|
||
ret
|
||
|
||
|
||
eject
|
||
;******************************************************
|
||
; *
|
||
; ENTRY POINT FOR VIRTUAL SCREEN UPDATES *
|
||
; *
|
||
;******************************************************
|
||
|
||
;===========
|
||
vs_conout:
|
||
;===========
|
||
|
||
mov bx,dx ; BL = virtual console #
|
||
shl bx,1
|
||
mov bx,screen_image_tbl[bx] ; get virtual screen structure
|
||
mov al,cl ! mov ah,dl ; Set up AX for subroutines
|
||
mov cx,0 ! push ax ; AH = console #, AL = character
|
||
call vs_escape_rt ; This is the escape handler if in middle
|
||
; of a sequence. Default is CONOUT01.
|
||
cmp cx,0 ! jne conout01 ; CX = 0 if in escape sequence
|
||
; = ffff if regular char
|
||
|
||
other_char: ; Either we're in the middle of an
|
||
; escape sequence or it's a special char.
|
||
pop cx ! mov dl,ch ; Fall through to physical output.
|
||
xor ch,ch ; Virtual update has been done.
|
||
jmp conout1
|
||
|
||
conout01:
|
||
mov di, offset spec_char_tab ; check if special char (CR,LF,BS,ESC)
|
||
mov si, offset spec_func_tab ; if so, co_look_up jmps to corresponding
|
||
call co_look_up ; function
|
||
jcxz conout02 ; else,update image with simple character
|
||
jmp other_char
|
||
|
||
conout02: ; simple character handling
|
||
pop cx ! mov dl,ch ! xor ch,ch ; restore console # and char
|
||
mov di,vs_cursor ; starting point of single char copy
|
||
|
||
push es ; BX = virtual screen structure
|
||
mov es,vs_screen_seg ; ES = segment of virtual screen
|
||
mov ah,vs_attrib ; AH -> current attribute
|
||
|
||
mov al,cl ; CL,AL -> new char
|
||
stosw
|
||
pop es ; DI pts to next attribute/char word
|
||
|
||
cmp vs_column,crt_col - 1 ; see if we need a CR-LF
|
||
jb inc_col ; no, go move cursor one to the right
|
||
test vs_mode,vsm_no_wrap ; if in wrap mode, don't do CR-LF
|
||
jz conout03 ; and continue on to physical output
|
||
call carriage_return ; else update virtual cursor,col & row
|
||
call line_feed
|
||
|
||
conout03:
|
||
jmp conout1
|
||
|
||
inc_col:
|
||
call r_right ; updates cursor by one (to the right)
|
||
jmp conout1
|
||
|
||
|
||
|
||
;************************************************
|
||
; *
|
||
; SPECIAL CHARACTER OUTPUT ROUTINES *
|
||
; *
|
||
;************************************************
|
||
|
||
;----------------
|
||
carriage_return:
|
||
;----------------
|
||
; entry: BX = screen structure
|
||
; exit : BX preserved
|
||
|
||
push dx
|
||
xor dx,dx
|
||
xchg vs_column,dl ; set column to zero
|
||
shl dx,1 ; back up cursor
|
||
sub vs_cursor,dx
|
||
pop dx
|
||
ret
|
||
|
||
;----------------
|
||
line_feed:
|
||
;----------------
|
||
; entry: BX = screen structure
|
||
; exit : BX preserved
|
||
|
||
cmp vs_row, crt_row - 1
|
||
je lf_scroll ; are we at bottom of screen?
|
||
jmp d_down ; no, move cursor down a line
|
||
lf_scroll:
|
||
push dx
|
||
xor dl,dl ; yes, adjust top & bottom pointers
|
||
mov dh, crt_row - 1
|
||
call scroll_up
|
||
pop dx
|
||
jmp erase_line
|
||
|
||
;-----------------
|
||
back_space:
|
||
;-----------------
|
||
; entry: BX = screen structure
|
||
; exit : BX = preserved
|
||
|
||
mov di,vs_cursor
|
||
test di,di ; are we at home position ?
|
||
jz bs_ret ; yes, ignore backspace
|
||
cmp vs_column,0 ; are we at the beginning of a line ?
|
||
je bs_row ; yes, try previous line
|
||
dec vs_column ; else, simple case : dec # cols
|
||
jmps bs_set_cursor
|
||
bs_row:
|
||
test vs_mode,vsm_no_wrap ; if in nowrap mode, don't back up to
|
||
jnz bs_ret ; previous line
|
||
dec vs_row ; else, dec current row and
|
||
mov vs_column,crt_col - 1 ; show column at end of line
|
||
bs_set_cursor:
|
||
sub di,2 ; DI = cursor
|
||
mov vs_cursor,di
|
||
bs_ret:
|
||
ret
|
||
|
||
|
||
|
||
|
||
;*******************************************************
|
||
;
|
||
; ESCAPE SEQUENCE ROUTINES
|
||
;
|
||
;*******************************************************
|
||
|
||
|
||
;----------
|
||
co_look_up:
|
||
;----------
|
||
; entry: BX = address of screen structure
|
||
; AH = device number
|
||
; AL = char to scan for
|
||
; DI = ptr to lookup table
|
||
; SI = function table
|
||
; exit : CX = 0ffffh if special char found
|
||
; 0 if no spec char found
|
||
; if not spec function, AX & BX preserved
|
||
|
||
mov bp,es ! mov dx,ds
|
||
mov es,dx
|
||
xor cx,cx ! mov cl,[di] ; first byte of di is length of table
|
||
mov dx,cx ! inc di
|
||
repne scasb ; cruise through table for match
|
||
mov es,bp ; restore ES
|
||
je lookup_func ; got a match, go get function
|
||
ret ; else, return with CX = 0
|
||
lookup_func:
|
||
inc cx ; CX = number matched on
|
||
sub dx,cx ! shl dx,1 ; function number
|
||
add si,dx
|
||
call word ptr [si]
|
||
xor cx,cx ! dec cx ; return with CX = 0ffffh
|
||
ret
|
||
|
||
;----------
|
||
escape_rt:
|
||
;----------
|
||
; entry: BX = screen structure
|
||
; AL = current byte in esc sequence
|
||
; exit : vs_escape_rt = address of next routine to execute
|
||
; in this sequence
|
||
|
||
mov vs_escape_rt,offset escape1
|
||
ret
|
||
escape1:
|
||
mov vs_escape_rt, offset default_esc ; assume done with escape
|
||
mov di, offset esc_tbl ; if more to do, this field
|
||
mov si, offset esc_func_tbl ; will be set by handler
|
||
push cx ; save CX to show in esc
|
||
call co_look_up ; sequence
|
||
pop cx
|
||
ret
|
||
|
||
;----------
|
||
home: ; ESC H
|
||
;----------
|
||
|
||
xor ax,ax
|
||
mov vs_cursor,ax
|
||
mov vs_column,al
|
||
mov vs_row,al
|
||
ret
|
||
|
||
;----------
|
||
right: ; ESC C
|
||
;----------
|
||
|
||
cmp vs_column,crt_col - 1 ; if at end of screen, ignore it
|
||
jb r_right
|
||
ret
|
||
r_right:
|
||
add vs_cursor,2
|
||
inc vs_column
|
||
ret
|
||
|
||
;----------
|
||
left: ; ESC D
|
||
;----------
|
||
|
||
cmp vs_column,0 ; if at beginning of screen, ignore it
|
||
ja l_left
|
||
ret
|
||
l_left:
|
||
sub vs_cursor,2
|
||
dec vs_column
|
||
ret
|
||
|
||
;----------
|
||
down: ; ESC B
|
||
;----------
|
||
|
||
cmp vs_row,crt_row - 1 ; if at bottom of screen, ignore it
|
||
jb d_down
|
||
ret
|
||
d_down:
|
||
add vs_cursor,crt_col * 2
|
||
inc vs_row
|
||
ret
|
||
|
||
;----------
|
||
up: ; ESC A
|
||
;----------
|
||
|
||
cmp vs_row,0 ; if at top of screen, ignore it
|
||
ja d_up
|
||
ret
|
||
d_up:
|
||
sub vs_cursor,crt_col * 2
|
||
dec vs_row
|
||
ret
|
||
|
||
|
||
;---------------
|
||
up_with_scroll: ; ESC I
|
||
;---------------
|
||
|
||
cmp vs_row,0 ; if not on the top line, mov the cursor
|
||
ja up ; to the top only
|
||
push dx
|
||
xor dl,dl ; else, scroll it up
|
||
mov dh,crt_row - 1 ; start row = 0, end row = screen bottom
|
||
call scroll_down ; cursor stays the same
|
||
pop dx
|
||
jmp erase_line
|
||
|
||
;----------
|
||
save: ; ESC j
|
||
;----------
|
||
|
||
mov ah,vs_row ; save row and col in xy
|
||
mov al, vs_column
|
||
mov vs_xy,ax
|
||
mov ax,vs_cursor ; save cursor
|
||
mov vs_oldcursor,ax
|
||
ret
|
||
|
||
;----------
|
||
restore: ; ESC k
|
||
;----------
|
||
|
||
mov ax,vs_xy
|
||
mov vs_column,al
|
||
mov vs_row,ah
|
||
mov ax,vs_oldcursor
|
||
mov vs_cursor,ax
|
||
ret
|
||
|
||
;-----------
|
||
x_and_y: ; ESC Y
|
||
;-----------
|
||
|
||
mov vs_escape_rt,offset xy_row ; wait for row
|
||
ret
|
||
xy_row:
|
||
sub al,32
|
||
cmp al,crt_row - 1
|
||
jbe row_ok
|
||
mov vs_escape_rt,offset xy_ret
|
||
ret
|
||
row_ok:
|
||
mov vs_row,al
|
||
mov vs_escape_rt,offset xy_col ; wait for column
|
||
ret
|
||
xy_col:
|
||
sub al,32
|
||
cmp al,crt_col - 1
|
||
jbe xy_set_col
|
||
mov al,crt_col - 1
|
||
xy_set_col:
|
||
mov vs_column,al ; Set the new column #
|
||
push cx ! push dx
|
||
xor ax,ax
|
||
mov al,vs_row ; Use new row and column to compute
|
||
mov cx,crt_col * 2 ; new cursor position.
|
||
mul cx
|
||
xor cx,cx
|
||
mov cl,vs_column
|
||
shl cx,1
|
||
add ax,cx
|
||
mov vs_cursor,ax
|
||
pop dx ! pop cx
|
||
|
||
xy_ret:
|
||
mov vs_escape_rt, offset default_esc
|
||
ret
|
||
|
||
;---------------
|
||
erase_screen: ; ESC E
|
||
;---------------
|
||
|
||
push es ! push cx
|
||
mov es, vs_screen_seg ; get virtual screen segment
|
||
mov ax, 0720H ; put normal attribute with blank
|
||
mov cx, crt_size ; do entire screen
|
||
xor di,di ; start at position zero
|
||
rep stosw
|
||
pop cx ! pop es
|
||
ret
|
||
|
||
;---------------
|
||
erase_begin: ; ESC B
|
||
;---------------
|
||
|
||
push es ! push cx
|
||
mov es, vs_screen_seg ; get virtual screen segment
|
||
mov ax,vs_cursor ; get number of words to erase from
|
||
shr ax,1 ; beginning of screen
|
||
mov cx,ax
|
||
mov ax, 0720h ; give them all normal atrributes
|
||
xor di,di ; start at top of screen
|
||
rep stosw
|
||
pop cx ! pop es
|
||
ret
|
||
|
||
;---------------
|
||
erase_end: ; ESC J
|
||
;---------------
|
||
|
||
push es ! push cx
|
||
mov es,vs_screen_seg ; get virtual screen segment
|
||
mov ax,vs_cursor
|
||
mov di,ax ; erase from cursor to the end
|
||
shr ax,1
|
||
mov cx,crt_size
|
||
sub cx,ax ; CX = total # words to erase
|
||
mov ax,0720h ; given them all normal attributes
|
||
rep stosw
|
||
pop cx ! pop es
|
||
ret
|
||
|
||
;---------------
|
||
erase_line: ; ESC l
|
||
;---------------
|
||
|
||
push es ! push cx ! push dx
|
||
mov es,vs_screen_seg ; get virtual screen segment
|
||
xor ax,ax
|
||
mov al,vs_row
|
||
mov cx,crt_col
|
||
mul cx ; get word offset of current row
|
||
shl ax,1 ; make it a byte offset
|
||
mov di,ax ; start erasing here
|
||
mov ax,0720h ; give them all normal attributes
|
||
rep stosw
|
||
pop dx ! pop cx ! pop es
|
||
ret
|
||
|
||
;---------------
|
||
erase_bol: ; ESC o
|
||
;---------------
|
||
|
||
push es! push cx ! push dx ; erase from beginning of line
|
||
mov es,vs_screen_seg
|
||
xor ax,ax
|
||
mov al,vs_row ; current row
|
||
mov cx,crt_col * 2
|
||
mul cx
|
||
mov di,ax ; beginning offset - word
|
||
xor cx,cx
|
||
mov cl,vs_column ; number of words to erase
|
||
inc cx ; on this line
|
||
mov ax,0720h ; give them all normal attributes
|
||
rep stosw
|
||
pop dx ! pop cx ! pop es
|
||
ret
|
||
|
||
;---------------
|
||
erase_eol: ; ESC K
|
||
;---------------
|
||
|
||
push es ! push cx ; erase to end of line
|
||
mov es,vs_screen_seg ; get virtual screen segment
|
||
mov di,vs_cursor ; start to erase here
|
||
mov cx,crt_col
|
||
sub cl,vs_column ; number of words to erase on this line
|
||
mov ax,0720h ; give them all normal attributes
|
||
rep stosw
|
||
pop cx ! pop es
|
||
ret
|
||
|
||
;---------------
|
||
insert_line: ; ESC L
|
||
;---------------
|
||
|
||
push ax ! push dx
|
||
mov dl,vs_row ; start row
|
||
mov dh,crt_row - 1 ; ending row
|
||
call scroll_down ; make room for the new line
|
||
call erase_line ; erase the old one
|
||
xor ax,ax
|
||
xchg al,vs_column ; set cursor
|
||
shl ax,1
|
||
sub vs_cursor,ax
|
||
pop dx ! pop ax
|
||
ret
|
||
|
||
;---------------
|
||
delete_line: ; ESC M
|
||
;---------------
|
||
;
|
||
; ENTRY : BX -> screen structure
|
||
; EXIT : BX _> same
|
||
|
||
push ax ! push dx
|
||
mov dl,vs_row ; scroll up first
|
||
mov dh,crt_row - 1
|
||
call scroll_up
|
||
mov vs_row[bx], crt_row - 1
|
||
call erase_line ; then erase the line
|
||
call carriage_return
|
||
pop dx ! pop ax
|
||
ret
|
||
|
||
;---------------
|
||
delete_char: ; ESC N
|
||
;---------------
|
||
|
||
push es ! push cx
|
||
mov es,vs_screen_seg ; get virtual screen segment
|
||
mov di,vs_cursor
|
||
mov si,di
|
||
add si,2
|
||
xor cx,cx
|
||
mov cl,crt_col - 1
|
||
sub cl,vs_column
|
||
push ds ! push es ! pop ds
|
||
rep movsw
|
||
mov 0[di],0720h ; put a blank in last column
|
||
pop ds ! pop cx ! pop es
|
||
ret
|
||
|
||
;---------------
|
||
enter_reverse: ; ESC p
|
||
;---------------
|
||
|
||
push ax ! push es ! push di
|
||
;mov es, vs_screen_seg
|
||
mov al, vs_mode
|
||
or al,vsa_reverse
|
||
mov vs_mode, al
|
||
;mov di, vs_cursor
|
||
;mov ax, es:[di]
|
||
;mov ah,vsa_reverse
|
||
;mov es:[di],ax
|
||
mov al, vsa_reverse
|
||
mov vs_attrib,al
|
||
pop di ! pop es ! pop ax
|
||
ret
|
||
|
||
|
||
;---------------
|
||
exit_reverse: ; ESC q
|
||
;---------------
|
||
|
||
push ax ! push es ! push di
|
||
;mov es, vs_screen_seg
|
||
mov al, vs_mode
|
||
and al, not vsa_reverse
|
||
mov vs_mode, al
|
||
;mov di, vs_cursor
|
||
;mov ax, es:[di]
|
||
;mov ah, vsa_normal
|
||
;mov es:[di],ax
|
||
mov al, vsa_normal
|
||
mov vs_attrib,al
|
||
pop di ! pop es ! pop ax
|
||
ret
|
||
|
||
;---------------
|
||
enter_blink: ; ESC s
|
||
;---------------
|
||
|
||
ret
|
||
|
||
;---------------
|
||
exit_blink: ; ESC t
|
||
;---------------
|
||
|
||
ret
|
||
|
||
;---------------
|
||
enter_bright: ; ESC r
|
||
;---------------
|
||
|
||
ret
|
||
|
||
;---------------
|
||
exit_bright: ; ESC u
|
||
;---------------
|
||
|
||
ret
|
||
|
||
;---------------
|
||
enable_cursor: ; ESC e
|
||
;---------------
|
||
|
||
ret
|
||
|
||
;---------------
|
||
disable_cursor: ; ESC f
|
||
;---------------
|
||
|
||
ret
|
||
|
||
;---------------
|
||
enable_wrap: ; ESC v
|
||
;---------------
|
||
|
||
and vs_mode,not vsm_no_wrap
|
||
ret
|
||
|
||
;---------------
|
||
disable_wrap: ; ESC w
|
||
;---------------
|
||
|
||
or vs_mode,vsm_no_wrap
|
||
ret
|
||
|
||
|
||
;***********************************************************
|
||
;
|
||
; SUBROUTINES FOR VIRTUAL SCREEN UPDATES
|
||
;
|
||
;***********************************************************
|
||
|
||
;----------
|
||
scroll_up: ; scroll up in the range given in AX
|
||
;----------
|
||
; entry: AH = virtual screen #
|
||
; BX = screen structure
|
||
; DL = starting row - 0 relative
|
||
; DH = ending row - 0 relative
|
||
; exit : AX,BX,ES preserved
|
||
|
||
push es ! push cx ! push dx
|
||
mov es,vs_screen_seg ; DX = start,end rows AL = virt. console #
|
||
mov cx,dx ; save copy of start,end rows
|
||
xor ax,ax ! mov al,dl ; set up SI,DI
|
||
mov dx,crt_col * 2
|
||
mul dx ! mov di,ax ; DX,AX = byte offset starting row
|
||
add ax,crt_col * 2
|
||
mov si,ax ! mov ax,cx ; SI = first word to copy from
|
||
sub ah,al ! xor al,al
|
||
xchg al,ah ; set up CX for # words to copy
|
||
mov dx,crt_col
|
||
mul dx ! mov cx,ax
|
||
push ds ! push es! pop ds
|
||
rep movsw
|
||
pop ds ! pop dx ! pop cx ! pop es
|
||
ret
|
||
|
||
;----------
|
||
scroll_down:
|
||
;----------
|
||
; entry: AH = virtual console number
|
||
; BX = screen structure
|
||
; DL = start row
|
||
; DH = end row
|
||
; exit : AX,BX,ES preserved
|
||
|
||
push ax ! push cx ! push es
|
||
mov es,vs_screen_seg
|
||
mov cx,dx
|
||
xor ax,ax
|
||
mov al,dh
|
||
inc al
|
||
push dx
|
||
mov dx,crt_col * 2
|
||
mul dx
|
||
sub ax,2
|
||
mov di,ax
|
||
sub ax,crt_col * 2
|
||
mov si,ax
|
||
std
|
||
mov ax,cx
|
||
sub ah,al
|
||
xor al,al
|
||
xchg al,ah
|
||
mov dx,crt_col
|
||
mul dx
|
||
mov cx,ax
|
||
pop dx
|
||
push ds ! push es ! pop ds
|
||
rep movsw
|
||
pop ds ! pop es ! pop cx ! pop ax
|
||
cld
|
||
ret
|
||
|
||
;----------
|
||
default_esc:
|
||
;----------
|
||
; entry : CX = 0
|
||
; exit : CX = ffffh - flag for simple char
|
||
; CX = 0 for escape or backspace
|
||
|
||
dec cx
|
||
ret
|
||
|
||
eject
|
||
;**********************************************************
|
||
; *
|
||
; SCREEN SWITCH ROUTINES *
|
||
; *
|
||
;**********************************************************
|
||
|
||
;=========
|
||
vs_switch: ; Switch Screen with full screen buffering
|
||
;=========
|
||
;
|
||
; input: dl = Vcon to switch to
|
||
; dh = Pcon to do the switch on
|
||
;
|
||
|
||
switch_init:
|
||
|
||
mov bx, dx
|
||
xor bh, bh
|
||
shl bx,1
|
||
mov bx, screen_image_tbl[bx] ;; BX -> screen structure
|
||
mov es, vs_screen_seg ;; ES -> screen image buffer
|
||
|
||
push word ptr vs_mode
|
||
push word ptr vs_column ;; save row and col for cursor
|
||
push word ptr vs_row ;; restore.
|
||
|
||
set_up:
|
||
call set_up_bx ;; BX -> output Q ctl structure
|
||
call ser_home ;; home physical cursor
|
||
call ser_clear ;; clear physical screen
|
||
call ser_ex_rev ;; just to be safe
|
||
|
||
xor di,di ;; DI -> our cursor
|
||
xor dh,dh ;; DL -> # columns done so far
|
||
mov dl, 0ffh
|
||
mov al, vsa_normal ;; AL -> attribute
|
||
xor ah,ah ;; Default attribute is normal.
|
||
|
||
switch_loop:
|
||
mov cx, es:[di] ;; CX -> new atrribute, char
|
||
cmp al,ch ;; new attribute ?
|
||
je switch_loop1 ;; no, send the char
|
||
|
||
send_esc_seq:
|
||
push dx ! push cx
|
||
test ch, vsa_reverse
|
||
jnz ent_rev
|
||
call ser_ex_rev
|
||
jmp done_esc
|
||
|
||
ent_rev:
|
||
call ser_ent_rev
|
||
|
||
done_esc:
|
||
pop cx ! pop dx
|
||
xor ah,ah
|
||
mov al,ch ;; update attribute
|
||
|
||
switch_loop1:
|
||
push dx ! push ax
|
||
xor ch,ch
|
||
call serial_out ;; send the char
|
||
inc di ! inc di ;; DI -> curr char count
|
||
pop ax ! pop dx
|
||
inc dl ;; DL -> column count
|
||
|
||
total_check:
|
||
push di ! dec di ! dec di
|
||
cmp di,(crt_size * 2) - 2 ;; DI -> total chars sent so far
|
||
pop di
|
||
jae redo_cursor
|
||
|
||
line_check:
|
||
cmp dl, crt_col - 1 ;; are we at the end of line ?
|
||
jb switch_loop ;; no, do total chars check
|
||
call car_ret ;; do the CR/LF
|
||
mov dl, 0ffh ;; reset col count to 0
|
||
jmps switch_loop
|
||
|
||
redo_cursor:
|
||
pop ax ! pop dx ;; AL -> row, DL -> col
|
||
call restore_cursor
|
||
|
||
chk_wrap:
|
||
pop dx ;; get mode back
|
||
test dl, vsm_no_wrap ;; check for wrap-around mode
|
||
jnz dis_wrap
|
||
call ser_en_wrap
|
||
jmps chk_rev
|
||
dis_wrap:
|
||
call ser_dis_wrap
|
||
|
||
chk_rev:
|
||
test dl, vsa_reverse ;; check for inverse video
|
||
jz ex_rev
|
||
call ser_ent_rev
|
||
jmps curr_vc
|
||
|
||
ex_rev:
|
||
call ser_ex_rev
|
||
|
||
curr_vc:
|
||
ret ;; back to switch module
|
||
|
||
|
||
;-----------
|
||
set_up_bx:
|
||
;-----------
|
||
|
||
xor bx, bx
|
||
mov bl, dh ;; use Pcon to index into the Xmit Q's
|
||
shl bx, 1
|
||
mov bx, ocdesctbl[bx] ;; bx -> Xmit Q control
|
||
ret
|
||
|
||
|
||
ser_ent_rev:
|
||
;-----------
|
||
; Sends Z-29/19 escape sequence for Enter Reverse Mode
|
||
;
|
||
; Entry : BX -> Xmit Q control structure
|
||
;
|
||
mov oesc_cnt[bx], 2
|
||
mov cl, esc
|
||
call serial_out
|
||
mov cl, 'p'
|
||
call serial_out
|
||
ret
|
||
|
||
ser_ex_rev:
|
||
;----------
|
||
; Sends Z-29/19 escape sequence for Exit Reverse Mode
|
||
;
|
||
; Entry : BX -> Xmit Q control structure
|
||
;
|
||
mov oesc_cnt[bx], 2
|
||
mov cl, esc
|
||
call serial_out
|
||
mov cl, 'q'
|
||
call serial_out
|
||
ret
|
||
|
||
ser_en_wrap:
|
||
;-----------
|
||
; Sends Z-29/19 escape sequence for Enable Wrap Mode
|
||
;
|
||
; Entry : BX -> Xmit Q control structure
|
||
;
|
||
mov oesc_cnt[bx], 2
|
||
mov cl, esc
|
||
call serial_out
|
||
mov cl, 'v'
|
||
call serial_out
|
||
ret
|
||
|
||
ser_dis_wrap:
|
||
;-----------
|
||
; Sends Z-29/19 escape sequence for Disable Wrap Mode
|
||
;
|
||
; Entry: BX -> Xmit Q control structure
|
||
;
|
||
mov oesc_cnt[bx], 2
|
||
mov cl, esc
|
||
call serial_out
|
||
mov cl, 'w'
|
||
call serial_out
|
||
ret
|
||
|
||
ser_home:
|
||
;--------
|
||
; Sends Z-29/19 escape sequence for Home Cursor
|
||
;
|
||
; Entry : BX -> Xmit Q control structure
|
||
;
|
||
mov oesc_cnt[bx], 2
|
||
mov cl, esc
|
||
call serial_out
|
||
mov cl, 'H'
|
||
call serial_out
|
||
ret
|
||
|
||
ser_clear:
|
||
;---------
|
||
; Sends Z-29/19 escape sequence for Clear Screen
|
||
;
|
||
; Entry : BX -> Xmit Q control structure
|
||
;
|
||
mov oesc_cnt[bx], 2
|
||
mov cl, esc
|
||
call serial_out
|
||
mov cl, 'E'
|
||
call serial_out
|
||
ret
|
||
|
||
|
||
car_ret:
|
||
;-----------
|
||
; Sends a carriage return/ linefeed to Z-29/19 .
|
||
;
|
||
;
|
||
push ax ! push si
|
||
mov cl, 0ah
|
||
call serial_out
|
||
mov cl, 0dh
|
||
call serial_out
|
||
pop si ! pop ax
|
||
ret
|
||
|
||
|
||
restore_cursor:
|
||
;--------------
|
||
; Sends Z-29/19 escape sequence to reposition cursor
|
||
;
|
||
; Entry : BX -> Xmit Q control structure
|
||
;
|
||
push dx ! push ax
|
||
mov oesc_cnt[bx],4
|
||
mov cl, esc
|
||
call serial_out
|
||
mov cl, 'Y'
|
||
call serial_out
|
||
pop ax ;; row #
|
||
add al, 32 ;; normalize for terminal
|
||
mov cl,al
|
||
call serial_out
|
||
pop dx ;; col #
|
||
add dl, 32 ;; move cursor 1 char past last char
|
||
mov cl,dl
|
||
call serial_out
|
||
ret
|
||
|
||
|
||
|
||
|
||
dseg
|
||
|
||
|
||
;***************************************************************
|
||
; *
|
||
; SPECIAL OUTPUT CHARACTER TABLES *
|
||
; *
|
||
;***************************************************************
|
||
|
||
spec_char_tab db 4
|
||
db cr,lf,backsp,escape
|
||
|
||
spec_func_tab dw carriage_return
|
||
dw line_feed
|
||
dw back_space
|
||
dw escape_rt
|
||
|
||
;***************************************************************
|
||
; *
|
||
; ESCAPE SEQUENCE TABLES *
|
||
; *
|
||
;***************************************************************
|
||
|
||
esc_tbl db 28
|
||
|
||
db 'H','C','D','S','A'
|
||
db 'I','j','k','Y','E'
|
||
db 'b','J','l','o','K'
|
||
db 'L','M','N','p','q'
|
||
db 'r','u','s','t','a'
|
||
db 'f','v','w'
|
||
|
||
esc_func_tbl dw home
|
||
dw right
|
||
dw left
|
||
dw down
|
||
dw up
|
||
dw up_with_scroll
|
||
|
||
dw save
|
||
dw restore
|
||
dw x_and_y
|
||
|
||
dw erase_screen
|
||
dw erase_begin
|
||
dw erase_end
|
||
dw erase_line
|
||
dw erase_bol
|
||
dw erase_eol
|
||
|
||
dw insert_line
|
||
dw delete_line
|
||
dw delete_char
|
||
|
||
dw enter_reverse
|
||
dw exit_reverse
|
||
dw enter_bright
|
||
dw exit_bright
|
||
dw enter_blink
|
||
dw exit_blink
|
||
|
||
dw enable_cursor
|
||
dw disable_cursor
|
||
dw enable_wrap
|
||
dw disable_wrap
|
||
|
||
|
||
;*****************************************************************
|
||
; *
|
||
; VIRTUAL SCREEN IMAGE TABLE *
|
||
; *
|
||
;*****************************************************************
|
||
|
||
|
||
screen_image_tbl dw scrn_image0
|
||
dw scrn_image1
|
||
dw scrn_image2
|
||
dw scrn_image3
|
||
dw scrn_image4
|
||
dw scrn_image5
|
||
dw scrn_image6
|
||
dw scrn_image7
|
||
|
||
scrn_image0 dw 0,0 ;cursor, oldcursor
|
||
db 0,0,2 ;col, row, mode
|
||
db vsa_normal ;attribute
|
||
dw 0,0,0 ;xy, oldxy, screen segment
|
||
dw offset default_esc ;default: first char = reg char
|
||
|
||
scrn_image1 dw 0,0 ;cursor, oldcursor
|
||
db 0,0,2 ;col, row, mode
|
||
db vsa_normal ;attribute
|
||
dw 0,0,0 ;xy, oldxy, screen segment
|
||
dw offset default_esc ;default: first char = reg char
|
||
|
||
scrn_image2 dw 0,0 ;cursor, oldcursor
|
||
db 0,0,2 ;col, row, mode
|
||
db vsa_normal ;attribute
|
||
dw 0,0,0 ;xy, oldxy, screen segment
|
||
dw offset default_esc ;default: first char = reg char
|
||
|
||
scrn_image3 dw 0,0 ;cursor, oldcursor
|
||
db 0,0,2 ;col, row, mode
|
||
db vsa_normal ;attribute
|
||
dw 0,0,0 ;xy, oldxy, screen segment
|
||
dw offset default_esc ;default: first char = reg char
|
||
|
||
scrn_image4 dw 0,0 ;cursor, oldcursor
|
||
db 0,0,2 ;col, row, mode
|
||
db vsa_normal ;attribute
|
||
dw 0,0,0 ;xy, oldxy, screen segment
|
||
dw offset default_esc ;default: first char = reg char
|
||
|
||
scrn_image5 dw 0,0 ;cursor, oldcursor
|
||
db 0,0,2 ;col, row, mode
|
||
db vsa_normal ;attribute
|
||
dw 0,0,0 ;xy, oldxy, screen segment
|
||
dw offset default_esc ;default: first char = reg char
|
||
|
||
scrn_image6 dw 0,0 ;cursor, oldcursor
|
||
db 0,0,2 ;col, row, mode
|
||
db vsa_normal ;attribute
|
||
dw 0,0,0 ;xy, oldxy, screen segment
|
||
dw offset default_esc ;default: first char = reg char
|
||
|
||
scrn_image7 dw 0,0 ;cursor, oldcursor
|
||
db 0,0,2 ;col, row, mode
|
||
db vsa_normal ;attribute
|
||
dw 0,0,0 ;xy, oldxy, screen segment
|
||
dw offset default_esc ;default: first char = reg char
|
||
|
||
end |