|
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