|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 45847 (0xb317)
Types: TextFile
Names: »msyp98.asm«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦71044c191⟧ »EurOpenD3/misc/kermit.ms-2.32.tar.Z«
└─⟦31f2d420d⟧
└─⟦this⟧ »msyp98.asm«
;+ This is MSYPC98.ASM VT100 emulation for NEC-PC9801 by.H.Fujii
;
; ESC sequence
; - General rule -
; 1) 2-byte sequence
; a) ESC Fs terminated by 6/0 - 7/14
; b) ESC Fp terminated by 3/0 - 3/15
; c) ESC Fe terminated by 4/0 - 5/15
; 2) multibyte sequnce
; a) ESC I...I Fp terminated by 3/0 - 3/15 (private sequence)
; b) ESC I...I Ft terminated by 4/0 - 7/14 (standard sequence)
; where I is 2/0 - 2/15
; 3) control sequnce
; a) CSI P...P I...I Ft terminated by 4/0 - 6/15 (standard sequence)
; b) CSI P...P I...I Fp terminated by 7/0 - 7/14 (private sequence)
; where CSI is 9/11 or ESC 5/11 (one of ESC Fe sequnce)
; P is 3/0 - 3/15,
; 3/11 is separator
; 3/15 is private parameter introducer
; I is 2/0 - 2/15
;
; CRT display character
;
; Character plane
; F E D C B A 9 8 7 6 5 4 3 2 1 0
; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
; | 0 | | ANK code | ANK
; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
;
; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
; |0| JIS 2nd | |JIS 1st - '20'X| Kanji Left half
; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
; |1| JIS 2nd | |JIS 1st - '20'X| Kanji Right half
; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
;
;
; Attribute plane
; 7 6 5 4 3 2 1 0
; +-+-+-+-+-+-+-+-+
; |G|R|B| | | | | |
; +-+-+-+-+-+-+-+-+
; ^ ^ ^ ^ ^ ^ ^ ^
; | | | | | | | |
; | | | | | | | secret (0)
; | | | | | | blink (1)
; | | | | | reverse (1)
; | | | | underline (1)
; | | | vertical line/graph pattern
; color
;
DOS equ 021h ; MS-DOS function
WRITE2 equ 40h ; MS-DOS WRITE function (version2)
ESCAPE equ 1Bh
BIOS equ 018h ; CRT BIOS
CHR_REV equ 04h
CRT_TXT_SEG equ 0A000h
PRIVP_FLG equ 08000h
AUTOWRAP_BIT equ 001h
public vt100,vt100_ini,vt100_save,vt100_restore
public vt100_modlin, vt100_dump, vt100_color
datas segment public 'datas'
extrn curkey_mode:byte, keypad_mode:byte
extrn vt100_flags:byte
extrn kanji_rmode:byte
vt_init db 0
vt_graph db 0
vt_chrset db 0
vt_chratr db 0 ; current character attributes
vt_blkatr db 0 ; blank area attributes
vt_kanji_code db 2
vt_knjmode db 0 ; Kanji mode if 1
vt_kanji1 db 0 ; Kanji 1st byte
vt_kanji2 db 0
vt_nrmatr db 0E1h ; normal character attributes
vt_hglatr db 0A0h ; highlight character attribute
vt_blnatr db 002h ; blink character attribute
vt_modatr db 0C5h ; mode line character attributes
esc_prv db 0
esc_seq db 0
esc_len dw 0
esc_buf db 128 dup (?)
esc_P_pnt dw 0
esc_P_buf dw 64 dup (?)
priv_param dw 0
char_GL dw ?
char_GR dw ?
char_G0 db 0
char_G1 db 1
char_G2 db 0
char_G3 db 1
sng_char db 1,0
vt_gset db 0EAh,087h,009h,00Ch,00Dh,00Ah,0DFh,08Fh
db 015h,00Bh,09Bh,099h,098h,09Ah,08Fh,094h
db 094h,095h,081h,080h,093h,092h,090h,091h
db 096h,01Dh,01Ch,01Eh,01Fh,0F1h,0A5h,020h
vram_line label word
dw 0000h ; 0-line
dw 00a0h ; 1
dw 0140h ; 2
dw 01e0h ; 3
dw 0280h ; 4
dw 0320h ; 5
dw 03c0h ; 6
dw 0460h ; 7
dw 0500h ; 8
dw 05a0h ; 9
dw 0640h ;10
dw 06e0h ;11
dw 0780h ;12
dw 0820h ;13
dw 08c0h ;14
dw 0960h ;15
dw 0a00h ;16
dw 0aa0h ;17
dw 0b40h ;18
dw 0be0h ;19
dw 0c80h ;20
dw 0d20h ;21
dw 0dc0h ;22
dw 0e60h ;23
vram_last_line dw 0f00h ;24
;
I_am_vt100 db 5
db ESCAPE,"[?6c"
I_am_vt220 db 16
db ESCAPE,"[?62;1;2;6;7;8c"
cur_col db 0
cur_row db 0
cur_save_col db 0
cur_save_row db 0
;
vt_top db 0
vt_bottom db 23
dump_pntr dw ?
dump_buffer db 256 dup (?)
datas ends
code segment public 'code'
assume cs:code,ds:datas
extrn s2jis:near, jis2s:near
;
; VT100 terminal emulator
;
VT100_INI PROC NEAR
cmp vt_init,0
je vt100_ini_1
jmp vt100_ini_ex
vt100_ini_1:
mov vt_init,1
mov vt_graph,0
mov cur_col,0
mov cur_row,0
mov cur_save_col,0
mov cur_save_row,0
mov al,vt_nrmatr
mov vt_chratr,al
mov vt_blkatr,al
mov vt_top,0
mov vt_bottom,23
mov priv_param,0
;
mov char_G0,0
mov char_G1,1
mov char_G2,0
mov char_G3,1
;
mov char_GL,offset char_G0
mov char_GR,offset char_G1
;
; Erase entire screen
;
push es
push di
mov ax,CRT_TXT_SEG
mov es,ax
mov di,1000h ; page 2
mov cx,0800h
cld
mov ax,0020h
rep stosw
mov di,1000h
add di,02000h ; text attributes
mov al,vt_blkatr
xor ah,ah
mov cx,0800h
rep stosw
;
pop di
pop es
;
vt100_ini_ex:
ret
VT100_INI ENDP
VT100_XCHG PROC NEAR
;
; exchange page 1 and 2
;
push ax
push bx
push cx
push si
push di
push es
;
mov ax,CRT_TXT_SEG
mov es,ax
mov cx,800h
mov si,0
mov di,si
add di,1000h
;
vt100_xchg1:
mov ax,es:[si]
mov bx,es:[di]
mov es:[si],bx
mov es:[di],ax
add si,2
add di,2
loop vt100_xchg1
;
mov cx,800h
mov si,2000h
mov di,si
add si,1000h
;
vt100_xchg2:
mov ax,es:[si]
mov bx,es:[di]
mov es:[si],bx
mov es:[di],ax
add si,2
add di,2
loop vt100_xchg2
pop es
pop di
pop si
pop cx
pop bx
pop ax
ret
VT100_XCHG ENDP
;
; save VT100 screen (return to page 1)
;
VT100_SAVE PROC NEAR
push ax
push dx
;
mov ah,0Dh ; stop display
int BIOS
;
call vt100_xchg
;
;@@ mov ah,0Eh
;@@ xor dx,dx
;@@ int BIOS
mov ah,0Ch ; start dispay
int BIOS
;
pop dx
pop ax
ret
VT100_SAVE ENDP
;
; restore VT100 screen (return to page 2)
;
VT100_RESTORE PROC NEAR
push ax
push dx
;
mov ah,0Dh ; stop display
int BIOS
;
call vt100_xchg
;
;@@ mov ah,0Eh
;@@ mov dx,vram_line
;@@ int BIOS
mov ah,0Ch ; start display
int BIOS
call locate_cur
;
pop dx
pop ax
ret
VT100_RESTORE ENDP
VT100_MODLIN PROC NEAR
;
; Mode line display control
;
; Inputs:
; dx offset address of the mode line buffer;
; The 1st byte of the mode line buffer must contain the
; the number of characters in the buffer. If it is zero,
; the mode line is cleared.
;
push es
push di
push si
;
push dx
cld
pop si
xor ch,ch
mov cl,[si]
inc si
dec cx
;
mov ax,CRT_TXT_SEG
mov es,ax
mov di,vram_last_line
mov bx,cx
mov cx,80
xor ah,ah
mov al,' '
rep stosw
mov di,vram_last_line
add di,02000h
mov al,vt_modatr
cmp bx,0
jg vt100_modlin_01
mov al,vt_blkatr
vt100_modlin_01:
mov cx,80
rep stosw
;
cmp bx,0
jle vt100_modlin_ex
;
xor ax,ax
mov cx,bx
mov di,vram_last_line
vt100_modlin_1:
movsb
stosb
loop vt100_modlin_1
;
vt100_modlin_ex:
call locate_cur
;
pop si
pop di
pop es
ret
VT100_MODLIN ENDP
VT100_COLOR PROC NEAR
;
; Change color to the value specified in AX.
; al color index for normal character
; ah color index for highlighted character
;
push ax
push bx
push cx
cmp al,-1
je vt100_color1
mov bl,vt_nrmatr
mov bh,vt_chratr
and bl,1Fh ; mask other bit
and bh,1Fh
mov cl,5
shl al,cl
or bl,al
or bh,al
mov vt_nrmatr,bl
mov vt_chratr,bh
mov vt_blkatr,bh
vt100_color1:
cmp ah,-1
je vt100_color2
mov bl,vt_hglatr
and bl,1Fh
mov cl,5
shl ah,cl
or bl,ah
mov vt_hglatr,bl
vt100_color2:
pop cx
pop bx
pop ax
ret
VT100_COLOR ENDP
scrn_mode proc near
;
; set screen mode to normal(AL=0)/reverse(AL=1)
; [NOTE]
; registers AX and BX are broken when return
;
push cx
push di
push es
;
mov bx,ax
mov ax,CRT_TXT_SEG
mov es,ax
mov di,vram_line
add di,2000h
mov cx,1920 ; 1920 = 80 x 24
cmp bl,0
je scrn_mode2
scrn_mode1:
or BYTE PTR es:[di],CHR_REV
add di,2
loop scrn_mode1
or vt_nrmatr,CHR_REV
or vt_chratr,CHR_REV
or vt_blkatr,CHR_REV
jmp scrn_mode3
scrn_mode2:
and BYTE PTR es:[di],NOT CHR_REV
add di,2
loop scrn_mode2
and vt_nrmatr,NOT CHR_REV
and vt_chratr,NOT CHR_REV
and vt_blkatr,NOT CHR_REV
scrn_mode3:
pop es
pop di
pop cx
ret
scrn_mode endp
locate_cur proc near
;
; locate cursor at (cur_row,cur_col)
;
; [NOTE]
; Registers ax, bx and dx are to be broken when return.
;
mov dh,cur_row
mov dl,cur_col
call vram_ofs
shr bx,1
cli
locate_cur1:
in al,60h
test al,04h ; test GDC state
jz locate_cur1 ; z = not ready
mov al,49h
out 62h,al
mov al,bl
out 60h,al
mov al,bh
out 60h,al
sti
ret
locate_cur endp
;
disp_char proc near
;
; Display character in AX on the screen.
; Cursor moves to the next character position.
;
mov dh,cur_row
mov dl,cur_col
call vram_ofs
mov di,bx
mov dx,CRT_TXT_SEG
push es
mov es,dx
mov es:[di],ax
xor ah,ah
mov al,vt_chratr
add di,02000h
stosw
pop es
inc cur_col
mov al,cur_col
cmp al,80
jb disp_char_loc
test vt100_flags,AUTOWRAP_BIT
jnz disp_char_wrap ; nz = AutoWrap
mov cur_col,79 ; stay at right margin
jmp disp_char_ex
disp_char_wrap:
mov cur_col,0
mov bl,cur_row
cmp bl,vt_bottom
jl disp_char_wrap1
je disp_char_wrap2
inc cur_row
cmp cur_row,23
jle disp_char_loc
mov cur_row,23
jmp disp_char_loc
disp_char_wrap1:
inc cur_row
jmp disp_char_loc
disp_char_wrap2:
mov al,vt_top
mov ah,vt_bottom
mov cx,1
call scroll_up
disp_char_loc:
call locate_cur
disp_char_ex:
ret
disp_char endp
;---------------------------
VT100_DUMP PROC NEAR
;---------------------------
; Dump screen. This procedure dump the VT100 screen on the disk using
; MS-DOS function 40H (int 21H).
;
; Inputs
; BX file handle
;
; Outputs
; None
;
push cx
push dx
push es
push si
push di
mov ax,CRT_TXT_SEG
mov es,ax
mov si,vram_line
mov cx,24
vt100_dump0:
push cx
mov di,offset dump_buffer
mov dump_pntr,di
mov cx,80
;
vt100_dump1:
mov ax,es:[si]
cmp ah,0 ; Kanji ?
je vt100_dump3 ; e = no.
add ax,20h ; convert to jis
and ax,7F7Fh ; mask 8th bit
call jis2s ; convert to shift jis
mov [di],al
mov [di+1],ah
add di,2
add si,4
dec cx
mov dump_pntr,di
jmp vt100_dump2
vt100_dump3:
mov [di],al ; remove Kanji flag etc in ah.
inc di
add si,2
cmp al,' ' ; Is it blank ?
je vt100_dump2 ; e = yes.
mov dump_pntr,di
vt100_dump2:
loop vt100_dump1
;
mov di,dump_pntr
mov ax,0A0Dh ; add CR/LF
mov [di],ax
add dump_pntr,2
mov cx,dump_pntr
sub cx,offset dump_buffer
mov dx,offset dump_buffer
mov ah,WRITE2 ; write function
int DOS
;
pop cx
loop vt100_dump0
;
pop di
pop si
pop es
pop dx
pop cx
ret
VT100_DUMP ENDP
;---------------------------
VT100 PROC NEAR
;---------------------------
;
; Character display routine in VT-100 mode
;
vt_disp:
cmp al,20h
jb vt_disp_C0 ; C0 control characters
jmp vt_disp_D0
vt_disp_ex:
mov cx,0
ret
; C0 control characters
vt_disp_C0:
cmp al,10h
jl vt_disp_C00
jmp vt_disp_C01
vt_disp_C00:
jne vt_disp_n00
jmp vt_disp_ex
vt_disp_n00:
vt_disp_n06:
cmp al,07h ; Bell ?
jne vt_disp_n07
mov al,06h
out 37h,al
mov cx,0D000h
bell_loop:
loop bell_loop
mov al,07h
out 37h,al
jmp vt_disp_ex
vt_disp_n07:
cmp al,08h ; BS ?
jne vt_disp_n08
cmp cur_col,0
jle vt_disp_ex
dec cur_col
call locate_cur
jmp vt_disp_ex
vt_disp_n08:
cmp al,09h ; HT ?
jne vt_disp_n09
jmp disp_TAB
vt_disp_n09:
cmp al,0Ah ; LF ?
jne vt_disp_n0A
jmp disp_LF
vt_disp_n0A:
cmp al,0Bh ; VT ?
jne vt_disp_n0B
jmp disp_LF
vt_disp_n0B:
cmp al,0Ch ; FF ?
jne vt_disp_n0C
jmp disp_LF
vt_disp_n0C:
cmp al,0Dh ; CR ?
jne vt_disp_n0D
mov cur_col,0
call locate_cur
jmp vt_disp_ex
vt_disp_n0D:
cmp al,0Eh
jne vt_disp_n0E ; SO ?
mov char_GL,offset char_G1
jmp vt_disp_ex
vt_disp_n0E:
cmp al,0Fh ; SI ?
jne vt_disp_n0F
mov char_GL,offset char_G0
jmp vt_disp_ex
vt_disp_n0F:
jmp vt_disp_ex
vt_disp_C01:
cmp al,18h ; CAN ?
jne vt_disp_n18
mov esc_seq,0
jmp vt_disp_ex
vt_disp_n18:
cmp al,1Ah ; SUB ?
jne vt_disp_n1a
mov esc_seq,0
jmp vt_disp_ex
vt_disp_n1A:
cmp al,1Bh ; ESC ?
jne vt_disp_n1B
jmp vt_esc_0
vt_disp_n1B:
jmp vt_disp_ex
;
disp_lf:
mov bl,vt_bottom ; get bottom margin
cmp cur_row,bl
jl disp_lf2 ; above boundary
je disp_lf1 ; on the boundary
inc cur_row
cmp cur_row,23 ; screen boundary
jle disp_lf3
mov cur_row,23
jmp disp_lf3
disp_lf1:
mov cur_row,bl
mov al,vt_top
mov ah,vt_bottom
mov cx,1
call scroll_up
jmp disp_lf3
disp_lf2:
inc cur_row
disp_lf3:
call locate_cur
jmp vt_disp_ex
disp_tab:
mov al,cur_col
mov cl,3
shr al,cl
inc al
shl al,cl
cmp al,79
jle disp_tab1
mov al,79
disp_tab1:
mov cur_col,al
call locate_cur
jmp vt_disp_ex
; non C0 characters
vt_disp_D0:
cmp al,7Fh ; DEL ?
jne vt_disp_n7f
jmp vt_disp_ex
vt_disp_n7f:
cmp esc_seq,0 ; In ESC sequence ?
je vt_disp_x ; e = no, jump to normal sequence
cmp esc_seq,1 ; 1st character in ESC seq.?
jne vt_disp_1 ; ne = no, check the sequnce type
jmp vt_esc_1
vt_disp_1:
cmp esc_seq,2
jne vt_disp_2
jmp vt_esc_2
vt_disp_2:
cmp esc_seq,3
jne vt_disp_3
jmp vt_esc_3
vt_disp_3:
cmp esc_seq,4
jne vt_disp_x
jmp vt_esc_4
vt_disp_x:
cmp vt_knjmode,0
je try_KNJ0
jmp try_KNJ1
try_KNJ0:
cmp vt_kanji_code,0
jne try_KNJ1
jmp disp_out
try_KNJ1:
test vt_kanji_code,1 ; JIS Kanji code?
jz try_KNJ2
jmp KNJ_JIS
try_KNJ2:
cmp kanji_rmode,0 ; Kanji code?
je try_KNJ3
jmp KNJ_DEC
try_KNJ3:
jmp disp_out
;
KNJ_JIS:
cmp vt_knjmode,0
je KNJ_JIS1
jmp KNJ_DEC3
KNJ_JIS1:
and al,07Fh
mov vt_kanji1,al
mov vt_knjmode,1
jmp vt_disp_ex
;
KNJ_DEC:
cmp vt_knjmode,0
jne KNJ_DEC3
and al,07Fh
mov vt_kanji1,al
mov vt_knjmode,1
jmp vt_disp_ex
KNJ_DEC3:
and al,07Fh
mov ah,al
mov al,vt_kanji1
sub ax,020h
push ax
call disp_char
pop ax
or ax,8000h
call disp_char
mov vt_knjmode,0
jmp vt_disp_ex
;
disp_out:
mov bx,char_GL
cmp al,80h
jb disp_out0
mov bx,char_GR
disp_out0:
mov ah,[bx]
mov vt_graph,ah
xor ah,ah
cmp vt_graph,0
je disp_out1
cmp ax,060h
jl disp_out1
cmp ax,07Fh
jg disp_out1
sub ax,060h
mov bx,offset vt_gset
add bx,ax
mov al,[bx]
disp_out1:
call disp_char
jmp vt_disp_ex
;
; ESC sequence analysis
;
vt_esc_0:
mov esc_seq,1
mov esc_len,0
mov esc_P_pnt,0
mov bx,offset esc_P_buf
mov word ptr [bx],0
jmp vt_disp_ex
vt_esc_1:
and al,07Fh
cmp al,05Fh
ja vt_esc_do ; char is in 6/0 - 7/15, i.e., single
cmp al,03Fh
jbe vt_esc_2
jmp vt_esc_c1 ; char is in 4/0 - 5/15, i.e, C1
vt_esc_2:
cmp al,02Fh
ja vt_esc_do
cmp al,01Fh
jbe vt_esc_done
jmp vt_esc_I ; char is in 2/0 - 2/15, i.e., I
vt_esc_done:
mov esc_seq,0
jmp vt_disp_ex
vt_esc_do:
cmp al,'='
jne vt_esc_do10
mov keypad_mode,1
jmp vt_esc_done
vt_esc_do10:
cmp al,'>'
jne vt_esc_do20
mov keypad_mode,0
jmp vt_esc_done
vt_esc_do20:
cmp al,'<' ; VT52 -> ANSI mode ?
jne vt_esc_do30
jmp vt_esc_done
vt_esc_do30:
cmp al,'B'
je vt_esc_do32
cmp al,'A' ; use U.S for U.K
jne vt_esc_do40
jmp vt_esc_do34
vt_esc_do32:
mov bx,offset esc_P_buf
mov ah,[bx]
cmp ah,24h
jne vt_esc_do36
or vt_kanji_code,1
jmp vt_esc_done
vt_esc_do34:
mov bx,offset esc_P_buf
mov ah,[bx]
vt_esc_do36:
sub ah,28h
and ah,3
mov bx,offset char_G0
add bl,ah
mov byte ptr [bx],0
jmp vt_esc_done
vt_esc_do40:
cmp al,'H'
je vt_esc_do42
cmp al,'J'
jne vt_esc_do50
vt_esc_do42:
mov bx,offset esc_P_buf
mov ah,[bx]
cmp ah,28h
jne vt_esc_do44
and vt_kanji_code,0FEh
vt_esc_do44:
jmp vt_esc_done
vt_esc_do50:
cmp al,'0'
jne vt_esc_do60
mov bx,offset esc_P_buf
mov ah,[bx]
sub ah,28h
and ah,3
mov bx,offset char_G0
add bl,ah
mov byte ptr [bx],1
jmp vt_esc_done
vt_esc_do60:
vt_esc_do70:
cmp al,'7'
jne vt_esc_do80
mov al,cur_row
mov cur_save_row,al
mov al,cur_col
mov cur_save_col,al
jmp vt_esc_done
vt_esc_do80:
cmp al,'8'
jne vt_esc_doXX
mov al,cur_save_row
mov cur_row,al
mov al,cur_save_col
mov cur_col,al
call locate_cur
jmp vt_esc_done
vt_esc_doXX:
jmp vt_esc_done
vt_esc_I:
mov esc_seq,2
xor ah,ah
mov bx,offset esc_P_buf
add bx,esc_P_pnt
mov word ptr [bx],ax
add esc_P_pnt,2
jmp vt_disp_ex
;
vt_esc_c1:
cmp al,'['
jne vt_c1_try_IND
jmp vt_c1_CSI
vt_c1_try_IND:
cmp al,'D'
jne vt_c1_try_RI
jmp vt_c1_IND
vt_c1_try_RI:
cmp al,'M'
jne vt_c1_try_NEL
jmp vt_c1_RI
vt_c1_try_NEL:
cmp al,'E'
jne vt_c1_xxx
jmp vt_c1_NEL
vt_c1_xxx:
jmp vt_esc_done
vt_c1_CSI:
mov esc_seq,3
mov esc_len,0
mov esc_P_pnt,0
mov bx,offset esc_P_buf
mov word ptr [bx],0
mov priv_param,0
jmp vt_disp_ex
vt_esc_3:
cmp al,030h ; Parameter (3/0-3/15) ?
jb vt_esc_4
cmp al,03Fh
jbe vt_esc_P
vt_esc_4:
cmp al,020h ; Intermediate (2/0-2/15) ?
jb vt_esc_5
cmp al,02Fh
jbe vt_esc_CI
cmp al,040h ; Terminator (4/0-7/14) ?
jb vt_esc_5
jmp vt_esc_C1do
vt_esc_5:
jmp vt_esc_done
;
vt_esc_P:
cmp al,03ah
jae vt_esc_P1
mov bx,offset esc_P_buf
add bx,esc_P_pnt
mov cx,[bx] ; cx is previous value
and cx,7FFFh ; mask private parameter flag
mov dx,cx
shl dx,1
shl dx,1
add dx,cx
shl dx,1 ; dx is (previous value)*10
xor ah,ah
sub ax,030h
add ax,dx ; ax is (previous value)*10 + new
or ax,priv_param ; set private parameter flag
mov [bx],ax
jmp vt_disp_ex
vt_esc_P1:
cmp al,'?' ; Private parameter ? (3/15)
jne vt_esc_P11
mov priv_param,PRIVP_FLG
jmp vt_disp_ex
vt_esc_P11:
add esc_P_pnt,2 ; separator
mov bx,offset esc_P_buf
add bx,esc_P_pnt
mov word ptr [bx],0 ; clear for next parameter
jmp vt_disp_ex
vt_esc_CI:
mov esc_seq,4
jmp vt_disp_ex
vt_esc_C1do:
cmp al,'K'
jne vt_esc_C1do_10
jmp vt_esc_K
vt_esc_C1do_10:
cmp al,'J'
jne vt_esc_C1do_20
jmp vt_esc_J
vt_esc_C1do_20:
cmp al,'H'
jne vt_esc_C1do_25
jmp vt_esc_H
vt_esc_C1do_25:
cmp al,'f'
jne vt_esc_C1do_30
jmp vt_esc_H
vt_esc_C1do_30:
cmp al,'A'
jb vt_esc_C1do_40
cmp al,'D'
ja vt_esc_C1do_40
jmp vt_esc_ABCD
vt_esc_C1do_40:
cmp al,'r'
jne vt_esc_C1do_50
jmp vt_esc_SCR
vt_esc_C1do_50:
cmp al,'L'
jne vt_esc_C1do_60
jmp vt_esc_L
vt_esc_C1do_60:
cmp al,'M'
jne vt_esc_C1do_70
jmp vt_esc_M
vt_esc_C1do_70:
cmp al,'m'
jne vt_esc_C1do_80
jmp vt_esc_CATR
vt_esc_C1do_80:
cmp al,'c'
jne vt_esc_C1do_90
jmp vt_esc_DA
vt_esc_C1do_90:
cmp al,'h'
jne vt_esc_C1do_100
jmp vt_esc_SET_M
vt_esc_C1do_100:
cmp al,'l'
jne vt_esc_C1do_110
jmp vt_esc_RESET_M
vt_esc_C1do_110:
vt_esc_C1do_ex:
jmp vt_esc_done
;
vt_esc_DA:
; Device attributes
mov si,offset I_am_vt100
xor cx,cx
mov cl,[si]
inc si
mov esc_seq,0
ret
;
; Character attributes
; 0 All off
; 1 Bold (Highlight)
; 4 Underscored
; 5 Blinking
; 7 Reverse
; 22 Normal intensity
; 24 Not underlined
; 25 Not blinking
; 27 Positive image
;
vt_esc_CATR:
push cx
push si
mov si,offset esc_P_buf
mov cx,esc_P_pnt
shr cx,1
inc cx
vt_esc_CATR1:
mov bx,[si]
cmp bx,0
jne vt_esc_CATR2
mov al,vt_nrmatr
mov vt_chratr,al
jmp vt_esc_CATRX
vt_esc_CATR2:
cmp bx,1
jne vt_esc_CATR3
mov al,vt_chratr ; Bold
and al,01Fh
or al,vt_hglatr
mov vt_chratr,al
jmp vt_esc_CATRX
vt_esc_CATR3:
cmp bx,4
jne vt_esc_CATR5
or vt_chratr,8 ; Underscored
jmp vt_esc_CATRX
vt_esc_CATR5:
cmp bx,5
jne vt_esc_CATR7
or vt_chratr,2 ; Blinking
jmp vt_esc_CATRX
vt_esc_CATR7:
cmp bx,7
jne vt_esc_CATR22
mov al,CHR_REV ; Reverse
xor vt_chratr,al
jmp vt_esc_CATRX
vt_esc_CATR22:
cmp bx,22
jne vt_esc_CATR24
jmp vt_esc_CATRX
vt_esc_CATR24:
cmp bx,24
jne vt_esc_CATR25
and vt_chratr,0F7h ; not Underscored
jmp vt_esc_CATRX
vt_esc_CATR25:
cmp bx,25
jne vt_esc_CATR27
and vt_chratr,0FDh ; not blinking
jmp vt_esc_CATRX
vt_esc_CATR27:
cmp bx,27
jne vt_esc_CATRX
and vt_chratr,0FBh ; positive image
vt_esc_CATRX:
add si,2
loop vt_esc_CATR1
pop si
pop cx
jmp vt_esc_C1do_ex
;
; Set mode
; 2 Keyboard locked
; 4 Insert mode
; 12 Send-Receive off
; 20 LF is newline
; ?1 Cursor Key is application
; ?3 132 column
; ?4 Smooth scroll
; ?5 Reverse screen
; ?6 Origin mode relative
; ?7 Auto Wrap on
; ?8 Auto repeate on
; ?18 Print form feed on
; ?19 Print extent is full screen
; ?25 Text cursor enable on
;
vt_esc_SET_M:
push cx
push si
mov si,offset esc_P_buf
mov cx,esc_P_pnt
shr cx,1
inc cx
vt_esc_SET_M1:
mov bx,[si]
cmp bx,1+PRIVP_FLG ; ?1 = Cursor key application ?
jne vt_esc_SET_M2 ; ne = no
mov curkey_mode,1
jmp vt_esc_SET_MX
vt_esc_SET_M2:
vt_esc_SET_M3:
cmp bx,3+PRIVP_FLG ; ?3 = 132 Column ?
jne vt_esc_SET_M4
jmp vt_esc_SET_MX
vt_esc_SET_M4:
vt_esc_SET_M5:
cmp bx,5+PRIVP_FLG ; ?5 = reverse screen ?
jne vt_esc_SET_M6
mov ax,1
call scrn_mode
jmp vt_esc_SET_MX
vt_esc_SET_M6:
vt_esc_SET_M7:
cmp bx,7+PRIVP_FLG ; ?7 = AutoWrap ?
jne vt_esc_SET_M8
or vt100_flags,AUTOWRAP_BIT
jmp vt_esc_SET_MX
vt_esc_SET_M8:
vt_esc_SET_MX:
add si,2
loop vt_esc_SET_M1
pop si
pop cx
jmp vt_esc_C1do_ex
;
; Reset mode
; 2 Keyboard Unlocked
; 4 Replace mode
; 12 Send-Receive on
; 20 LF is line feed
; ?1 Normal cursor key
; ?2 Enter VT52 mode
; ?3 80 column
; ?4 Jump scroll
; ?5 Normal screen
; ?6 Orgin mode is absolute
; ?7 Auto wrap off
; ?8 Auto repeat off
; ?18 Print form feed off
; ?19 Print extent is scroll region
; ?25 Text cursor enable off
;
vt_esc_RESET_M:
push cx
push si
mov si,offset esc_P_buf
mov cx,esc_P_pnt
shr cx,1
inc cx
vt_esc_RESET_M1:
mov bx,[si]
cmp bx,1+PRIVP_FLG ; ?1 = Normal cursor key ?
jne vt_esc_RESET_M2
mov curkey_mode,0
jmp vt_esc_RESET_MX
vt_esc_RESET_M2:
vt_esc_RESET_M5:
cmp bx,5+PRIVP_FLG ; ?5 = normal screen ?
jne vt_esc_RESET_M6
mov ax,0
call scrn_mode
jmp vt_esc_RESET_MX
vt_esc_RESET_M6:
vt_esc_RESET_M7:
cmp bx,7+PRIVP_FLG
jne vt_esc_RESET_M8
and vt100_flags,(not AUTOWRAP_BIT)
jmp vt_esc_RESET_MX
vt_esc_RESET_M8:
vt_esc_RESET_MX:
add si,2
loop vt_esc_RESET_M1
pop si
pop cx
jmp vt_esc_C1do_ex
;
vt_esc_ABCD:
mov bx,offset esc_P_buf
mov bx,[bx]
cmp bx,1
jae vt_esc_ABCD1
mov bx,1
vt_esc_ABCD1:
cmp al,'B'
je vt_esc_CUD
cmp al,'C'
je vt_esc_CUR
cmp al,'D'
je vt_esc_CUL
vt_esc_CUU:
xor ah,ah
mov al,cur_row
sub ax,bx
xor bh,bh
mov bl,vt_top
cmp ax,bx
jge vt_esc_CUU1
mov ax,bx
vt_esc_CUU1:
mov cur_row,al
jmp vt_esc_ABCD_ex
vt_esc_CUD:
xor ah,ah
mov al,cur_row
add ax,bx
cmp al,vt_bottom
jle vt_esc_CUD1
mov al,vt_bottom
vt_esc_CUD1:
mov cur_row,al
jmp vt_esc_ABCD_ex
vt_esc_CUR:
xor ah,ah
mov al,cur_col
add ax,bx
cmp ax,79
jle vt_esc_CUR1
mov ax,79
vt_esc_CUR1:
mov cur_col,al
jmp vt_esc_ABCD_ex
vt_esc_CUL:
xor ah,ah
mov al,cur_col
sub ax,bx
cmp ax,0
jge vt_esc_CUL1
mov ax,0
vt_esc_CUL1:
mov cur_col,al
vt_esc_ABCD_ex:
call locate_cur
jmp vt_esc_C1do_ex
;
vt_esc_K:
mov bx,offset esc_P_buf
mov ax,[bx]
cmp ax,0
jne vt_esc_K1
mov dh,cur_row
mov dl,cur_col
call vram_ofs
mov ax,bx
mov dh,cur_row
mov dl,79
jmp vt_esc_KX
vt_esc_K1:
cmp ax,1
jne vt_esc_K2
mov dh,cur_row
mov dl,0
call vram_ofs
mov ax,bx
mov dh,cur_row
mov dl,cur_col
jmp vt_esc_KX
vt_esc_K2:
cmp ax,2
jne vt_esc_K3
mov dh,cur_row
mov dl,0
call vram_ofs
mov ax,bx
mov dh,cur_row
mov dl,79
jmp vt_esc_KX
vt_esc_K3:
jmp vt_esc_C1do_ex
vt_esc_KX:
call vram_ofs
call vt_erase
jmp vt_esc_C1do_ex
;
vt_esc_L:
mov al,cur_row
cmp al,vt_top
jge vt_esc_L01
jmp vt_esc_C1do_ex
vt_esc_L01:
cmp al,vt_bottom
jle vt_esc_L02
jmp vt_esc_C1do_ex
vt_esc_L02:
mov bx,offset esc_P_buf
mov cx,[bx]
cmp cx,0
jg vt_esc_L1
mov cx,1
vt_esc_L1:
mov ah,vt_bottom
call scroll_down
mov cur_col,0
call locate_cur
jmp vt_esc_C1do_ex
vt_esc_M:
mov al,cur_row
cmp al,vt_top
jge vt_esc_M01
jmp vt_esc_C1do_ex
vt_esc_M01:
cmp al,vt_bottom
jle vt_esc_M02
jmp vt_esc_C1do_ex
vt_esc_M02:
mov bx,offset esc_P_buf
mov cx,[bx]
cmp cx,0
jg vt_esc_M1
mov cx,1
vt_esc_M1:
mov ah,vt_bottom
call scroll_up
mov cur_col,0
call locate_cur
jmp vt_esc_C1do_ex
vt_esc_J:
mov bx,offset esc_P_buf
mov ax,[bx]
cmp ax,0
jg vt_esc_J1
mov dh,cur_row
mov dl,cur_col
call vram_ofs
mov ax,bx
mov dh,23
mov dl,79
call vram_ofs
jmp vt_esc_JX
vt_esc_J1:
cmp ax,1
jg vt_esc_J2
mov dh,0
mov dl,0
call vram_ofs
mov ax,bx
mov dh,cur_row
mov dl,cur_col
call vram_ofs
jmp vt_esc_JX
vt_esc_J2:
mov dh,0
mov dl,0
call vram_ofs
mov ax,bx
mov dh,23
mov dl,79
call vram_ofs
vt_esc_JX:
call vt_erase
jmp vt_esc_C1do_ex
;
vt_esc_H:
mov bx,offset esc_P_buf
mov ax,[bx]
cmp ax,1
jae vt_esc_H1
mov ax,1
vt_esc_H1:
cmp ax,24
jbe vt_esc_H2
mov ax,24
vt_esc_H2:
dec ax
mov cur_row,al
xor ax,ax
cmp esc_P_pnt,2
jb vt_esc_H5
mov ax,[bx+2]
cmp ax,1
jae vt_esc_H3
mov ax,1
vt_esc_H3:
cmp ax,80
jbe vt_esc_H4
mov ax,80
vt_esc_H4:
dec ax
vt_esc_H5:
mov cur_col,al
call locate_cur
jmp vt_esc_C1do_ex
; Set scroll region.
; It is NOT clear that this command affects the cursor position
; or not. In my experence, cursor moves to the left-top corner of the
; entire screen (i.e., same as <ESC>[1;1H ).
vt_esc_SCR:
mov bx,offset esc_P_buf
mov ax,[bx]
cmp ax,1
jae vt_esc_SCR1
mov ax,1
vt_esc_SCR1:
cmp ax,24
jbe vt_esc_SCR2
mov ax,24
vt_esc_SCR2:
dec ax
mov vt_top,al
mov ax,24
cmp esc_P_pnt,2
jb vt_esc_SCR4
mov ax,[bx+2]
cmp ax,1
jae vt_esc_SCR3
mov ax,24
vt_esc_SCR3:
cmp ax,24
jbe vt_esc_SCR4
mov ax,24
vt_esc_SCR4:
dec ax
vt_esc_SCR5:
mov vt_bottom,al
mov cur_row,0
mov cur_col,0
call locate_cur
jmp vt_esc_C1do_ex
;
; Erase from VRAM address AX to BX
;
vt_erase:
cld
push es
mov cx,bx
sub cx,ax
shr cx,1
inc cx
mov di,ax
push cx
push di
mov ax,CRT_TXT_SEG
mov es,ax
mov ax,0020h
rep stosw
pop di
add di,2000h
pop cx
xor ah,ah
mov al,vt_blkatr
rep stosw
pop es
ret
;-------------
; Scroll-down
;-------------
; scroll down n-lines in the region [Pt,Pb]. The cursor does not move.
;
; Input paramters:
; al: top row position Pt
; ah: bottom row position Pb
; cl: number of lines n (must be > 0)
; Registers:
; ax, bx, cx, dx, si, di are broken
scroll_down:
mov bl,ah
sub bl,al
cmp cl,bl ; n <= bottom - top ?
jle scroll_down_2 ; yes, text remains.
jmp scroll_down_3 ; no text remains.
scroll_down_2:
mov dh,ah
sub dh,cl
mov dl,79
call vram_ofs
mov si,bx ; si is VRAM(bottom-n,79)
mov dh,al
xor dl,dl
call vram_ofs
mov cx,si
sub cx,bx
shr cx,1 ; byte counts -> word counts
inc cx ; number of words to be moved
mov dh,ah
mov dl,79
call vram_ofs
mov di,bx ; di is VRAM(bottom,79)
push es
push ds
mov ax,CRT_TXT_SEG
mov bl,vt_blkatr ; save attribute before ds cahnge
mov es,ax
mov ds,ax
push cx ; save word count
push di ; save destination address
push si ; save source address
std
rep movsw ; move the text codes
mov cx,di
sub cx,si
shr cx,1
mov ax,0020h ; fill blank
rep stosw
;
pop si
pop di
pop cx ; cx, si, di are restored
add di,2000h ; attribute block
add si,2000h
rep movsw ; move the attributes
mov cx,di
sub cx,si
shr cx,1
mov al,bl ; fill attributes
xor ah,ah
rep stosw
;
cld
pop ds
pop es
jmp scroll_down_ex
scroll_down_3:
mov dh,al
xor dl,dl
call vram_ofs
mov cx,bx
mov dh,ah
mov dl,79
call vram_ofs
mov ax,cx
call vt_erase
scroll_down_ex:
ret
;
;-----------
; Scroll-up
;-----------
; scroll up n-lines in the region [Pt,Pb]. The cursor does not move.
;
; Input paramters:
; al: top row position Pt
; ah: bottom row position Pb (ah must be > al)
; cl: number of lines n (must be > 0)
; Registers:
; ax, bx, cx, dx, si, di are broken
scroll_up:
mov bl,ah
sub bl,al
cmp cl,bl ; n <= bottom - top ?
jle scroll_up_2 ; yes, text remains.
jmp scroll_up_3 ; no text remains.
scroll_up_2:
mov dh,al
add dh,cl
xor dl,dl
call vram_ofs
mov si,bx ; si is VRAM(top+n,0)
mov dh,ah
xor dl,79
call vram_ofs
mov cx,bx
sub cx,si
shr cx,1 ; byte counts -> word counts
inc cx ; number of words to be moved
mov dh,al
xor dl,dl
call vram_ofs
mov di,bx ; di is VRAM(top,0)
push es
push ds
mov ax,CRT_TXT_SEG
mov bl,vt_blkatr ; save attribute before ds cahnge
mov es,ax
mov ds,ax
push cx ; save word count
push di ; save destination address
push si ; save source address
cld
rep movsw ; move the text codes
mov cx,si
sub cx,di
shr cx,1
mov ax,0020h ; fill blank
rep stosw
;
pop si
pop di
pop cx ; cx, si, di are restored
add di,2000h ; attribute block
add si,2000h
rep movsw ; move the attributes
mov cx,si
sub cx,di
shr cx,1
mov al,bl ; fill attributes
xor ah,ah
rep stosw
;
cld
pop ds
pop es
jmp scroll_up_ex
scroll_up_3:
mov dh,al
xor dl,dl
call vram_ofs
mov cx,bx
mov dh,ah
mov dl,79
call vram_ofs
mov ax,cx
call vt_erase
scroll_up_ex:
ret
;
; Calculate VRAM offset address from (col,row)
; Inputs:
; dh: row (0-23)
; dl: col (0-79)
; Output:
; bx: VRAM offset address
;
; dx is broken when return
vram_ofs:
xor bx,bx
mov bl,dh
shl bx,1
add bx,offset vram_line
mov bx,[bx]
xor dh,dh
shl dl,1
add bx,dx
ret
; C1 8-bit control character
;----------------------
; Index ( 8/4 ); ESC D
;----------------------
; Moves the cursor down one line in the same column. If the cursor
; is at the bottom margin, the screen perform a scroll-up.
vt_c1_IND:
mov ah,cur_row
cmp ah,vt_bottom
jl vt_c1_IND_1
je vt_c1_IND_2
jmp vt_esc_done
vt_c1_IND_1:
inc ah
mov cur_row,ah
call locate_cur
jmp vt_esc_done
vt_c1_IND_2:
mov al,vt_top
mov cx,1
call scroll_up
jmp vt_esc_done
;-------------------------------
; Reverse index ( 8/13 ); ESC M
;-------------------------------
; Moves the cursor up one line in the same column. If the cursor is
; at the top margin, the screen performs a scroll-down.
vt_c1_RI:
mov al,cur_row
cmp al,vt_top
jg vt_c1_RI_1
jmp vt_c1_RI_2
vt_c1_RI_1:
dec al
jmp vt_c1_RI_3
vt_c1_RI_2:
mov al,vt_top
mov ah,vt_bottom
mov cx,1
call scroll_down
mov al,vt_top
vt_c1_RI_3:
mov cur_row,al
call locate_cur
jmp vt_esc_done
;--------------------------
; Next line ( 8/5 ); ESC E
;--------------------------
; Moves the cursor to the first position on the next line.
; If the cursor is at the bottom margin, the screen performs a
; scroll-up.
vt_c1_NEL:
mov ah,cur_row
cmp ah,vt_bottom
jl vt_c1_NEL_1
je vt_c1_NEL_2
jmp vt_esc_done
vt_c1_NEL_1:
inc ah
mov cur_row,ah
mov cur_col,0
call locate_cur
jmp vt_esc_done
vt_c1_NEL_2:
mov al,vt_top
mov cx,1
call scroll_up
mov cur_col,0
call locate_cur
jmp vt_esc_done
;
VT100 ENDP
code ends
end