;+ This is MSYP98.ASM VT100 emulation for NEC-PC9801 by.H.Fujii ; ; Update History ; 17-Apr-1991 vt_ourarg in vt100_modlin1 for modeline is changed. ; prn_out is replaced by pntchr. ; [these are done by Joe Doupnik] ; 01-Sep-1990 DCS is interpreted. Bugs for C0 characters in ESC/CSI seq. ; have been fixed. ; Saved CX in vt100_modlin. ; 29-Jul-1990 DCS is separated and ignored. ; 27-Jul-1990 For MS-Kermit v3.02 ; 25-Jun-1990 Fixed bug of ESC FF (forgot to clear ESC flag). ; 04-Aug-1989 Fixed wrong ESC M (reverse index) and ESC E (next line). ; 30-May-1989 ESC [ 0 m resets colors to default (color in command mode). ; 21-Apr-1989 Backquote modification for display is moved to disp_char. ; 19-Apr-1989 Put CR/LF for CSI*;1H in the cooked-log file. ; 16-Apr-1989 Installed Cooked log ; 17-Jan-1989 Bug in VT100_color. Highlight color set was wrong. ; 03-Dec-1988 Bug report from Mikami-san at NTT software lab. for ; ESC[;r. The routine for 'set scroll region' is fixed. ; 06-Nov-1988 Bug found in VT100_SAVE. In some situation, VT100 screen ; is not restored correctly. ; 10-Sep-1988 Autoprint feateres are installed ; 14-Aug-1988 Roll-Up/Down features with simple circular movement. ; ; ESC sequence ; - General rule - ; 1) 2-byte sequence ; a) ESC Fs terminated by 6/0 - 7/14 (standard sequence) ; b) ESC Fp terminated by 3/0 - 3/15 (private sequence) ; c) ESC Fe terminated by 4/0 - 5/15 (C1 control character) ; 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 ; ; Cotrol sequence ; 1) CSI P...P I...I Ft terminated by 4/0 - 6/15 (standard sequence) ; 2) 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 ; F E D C B A 9 8 7 6 5 4 3 2 1 0 ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ ; | N/A | |G|R|B| | | | | | ; +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ ; ^ ^ ^ ^ ^ ^ ^ ^ ; | | | | | | | | ; | | | | | | | secret (0) ; | | | | | | blink (1) ; | | | | | reverse (1) ; | | | | underline (1) ; | | | vertical line/graph pattern ; color ; ; ; The following Japanese Industrial Standards specify the Kana-Kanji treatment ; for information interchange. ; ; JIS C 6226: ; Code of the Japanese Graphic Character Set ; for Information Intercahnge ; ; JIS C 6228: ; Code Extension Techniques for Use with the Code ; for Information Interchange . ; ; In these standards, each byte of the multi-byte code is in the range ; 2/1 - 7/14. Each character is specified by an index of the current character ; table. In 7-bit environment, every index is the character code itself (or the ; first byte of the multi-byte character code). In 8-bit environment, there are ; two sets of current character table, called GL and GR. A GL-character is ; specified by the character code itself, and a GR-character is specified by ; the character code with 8-th bits on. ; As intermediate character sets, four sets of characters can be used at onece. ; These sets are called G0, G1, G2 and G3. To invoke these sets to the current ; character set(s), ; ; in 7-bit environment, ; ; 0/F Shift In Invoke G0 character set ; 0/E Shift Out Invoke G1 character set ; ESC 6/E Locking Shift 2 Invoke G2 character set ; ESC 6/F Locking Shift 3 Invoke G3 character set ; ; ESC 4/E Single Shift 2 Invoke G2 character ; ESC 4/F Single Shift 3 Invoke G3 character ; ; in 8-bit environment, ; ; 0/F Locking Shift 0 Invoke G0 character set to GL ; 0/E Locking Shift 1 Invoke G1 character set to GL ; ESC 7/E Locking Shift 1 Right Invoke G1 character set to GR ; ESC 6/E Locking Shift 2 Invoke G2 character set to GL ; ESC 7/D Locking Shift 2 Right Invoke G2 character set to GR ; ESC 6/F Locking Shift 3 Invoke G3 character set to GL ; ESC 7/C Locking Shift 3 Right Invoke G3 character set to GR ; ; 8/E Single Shift 2 Invoke G2 character ; 8/F Single Shift 3 Invoke G3 character. ; ; To designate the single-byte character set, (JIS C 6228: 5.3.7) ; ESC 2/8 F and ESC 2/12 F to G0 character set ; ESC 2/9 F and ESC 2/13 F to G1 character set ; ESC 2/10 F and ESC 2/14 F to G2 character set ; ESC 2/11 F and ESC 2/15 F to G3 character set ; ; where F is a final character in the range 3/0 - 7/14 which specifies the ; character set. For example, ; ; F Character Set ; ---- ------------- ; 4/1 UK ; 4/2 US (ASCII) ; 4/9 JIS Katakana ; 4/10 JIS Roman ; 4/11 Germany ; 5/2 France ; 5/4 Chinese Roman ; 5/9 Italy ; 5/10 Spain ; 5/11 Greek ; . ; ; To designate the multi-byte character set, (JIS C 6226: 5.3.8) ; ESC 2/4 F and ESC 2/4 2/12 F to G0 character set ; ESC 2/4 2/9 F and ESC 2/4 2/13 F to G1 character set ; ESC 2/4 2/10 F and ESC 2/4 2/14 F to G2 character set ; ESC 2/4 2/11 F and ESC 2/4 2/15 F to G3 character set ; ; where F is a final character in the range 3/0 - 7/14 which specifies the ; character set. For example, ; ; F Character Set ; --- ------------- ; 4/0 JIS C 6226 - 1978 ; 4/1 Chinese Kanji ; 4/2 JIS C 6226 - 1983 ; . ; ; Corresponding Internatial Standard is ISO 2022. ; include mssdef.h include msxp98.h ; NUL equ 0 CSI equ 9Bh ; ROLLMEM_MIN equ 40 ; minimum & maximum number of ROLLMEM_MAX equ 4000 ; paragraphs for roll-back buffer ; CHR_REV equ 04h CRT_TXT_SEG equ 0A000h PRIVP_FLG equ 08000h in_ESC_MODE equ 1 in_CSI_MODE equ 2 in_DCS_MODE equ 3 VT52_DCA_L equ 64 VT52_DCA_C equ 65 IN_SIXEL equ 66 public vt100,vt100_ini,vt100_save,vt100_restore,vt100_reset public vt100_modlin, vt100_dump, vt100_color public vt100_rupn, vt100_rdnn, vt100_prnl, vt100_prns public set_modlin public prn_chk public char_SS, char_GL, char_GR public gnrm_color, gbck_color data segment public 'data' extrn flags:byte, trans:byte extrn cpu_clock:byte, vtgrph_flg:byte, vttest_flg:byte extrn curkey_mode:byte, keypad_mode:byte extrn display_mode:byte extrn keyin_dos:byte extrn kanji_rcode:byte, kanji_scode:byte extrn vt100_cursr:byte extrn vt100_flags:byte, vt100_pflag:byte extrn vt100_lflag:byte, vt100_gflag:byte extrn vt_ourarg:byte extrn def_color:byte, scn_color:byte vt_saveseg dw ? ; segment address to save screen vt_rollseg dw ? ; segment address to roll-up screen vt_rollmxs dw ? ; maximum segment address allocated vt_rollmxl dw ? vt_rollcur dw ? ; current segment address vt_rollcln dw 0 ; current line number of the buffer vt_rollfil dw 1 vt_rollnum dw 0 vt_init db 0 vt_wrap db 0 ; wrap request flag vt_graph db 0 vt_chrset db 0 vt_chratr db 0 ; current character attributes vt_blkatr db 0 ; blank area attributes vt_nrmatr db 0E1h ; normal character attributes vt_hglatr db 0C0h ; highlight character attribute vt_modatr db 0C5h ; mode line character attributes vt_in_stat db 0 ; in status line flag vt_stat_type db 1 ; status line type stat_col db 0 ; column in status line stat_row db 24 ; row of the status line (from 0) sixel_disp_on db 0, 0 save_flags db ? save_graph db ? save_chrset db ? save_chratr db ? save_blkatr db ? vt_knjmode db 0 ; Kanji mode if 1 vt_kanji1 db 0 ; Kanji 1st byte vt_kanji2 db 0 ; The fllowing parameters are used for ESC/CSI/DCS sequence. ; seq_stage: 0 normal character stage ; 1 in ESC seq. ; 2 in ESC intermediate stage ; 3 in CSI (parameter) stage. ; 4 in CSI intermediate stage ; 5 in DCS (parameter) stage. ; 6 in DCS intermediate stage ; spec_mode db 0 spec_stage db 0 I_pnt dw 0 I_buf db 128 dup (?) P_pnt dw 0 P_buf dw 128 dup (?) priv_pflg dw 0 priv_char db 0 char_SS dw 0 ; GL for single shift char_GL dw ? char_GR dw ? char_save_SS dw ? char_save_GL dw ? char_save_GR dw ? char_G0 db CSET_JISROMAN char_G1 db CSET_DECGRAPH char_G2 db CSET_JISKATAKANA char_G3 db CSET_JISC6226 char_save_G0 db ? char_save_G1 db ? char_save_G2 db ? char_save_G3 db ? ; Normal PC98 color table ; gnrm_color db 000h,000h,000h ; 0:black db 000h,000h,0ffh ; 1:blue db 0ffh,000h,000h ; 2:red db 0ffh,000h,0ffh ; 3:magenta db 000h,0ffh,000h ; 4:green db 000h,0ffh,0ffh ; 5:cyan db 0ffh,0ffh,000h ; 6:yellow db 0ffh,0ffh,0ffh ; 7:white db 0afh,0afh,0afh ; 8:light-gray db 000h,000h,0afh ; 9:dark-blue db 0afh,000h,000h ; 10:dark-red db 0afh,000h,0afh ; 11:dark-magenta db 000h,0afh,000h ; 12:dark-green db 000h,0afh,0afh ; 13:dark-cyan db 0afh,0afh,000h ; 14:dark-yellow db 07fh,07fh,07fh ; 15:dark-gray ; gbck_color db 000h,000h,000h ; 0: db 000h,000h,000h ; 1: db 000h,000h,000h ; 2: db 000h,000h,000h ; 3: db 000h,000h,000h ; 4: db 000h,000h,000h ; 5: db 000h,000h,000h ; 6: db 000h,000h,000h ; 7: db 000h,000h,000h ; 8: db 000h,000h,000h ; 9: db 000h,000h,000h ; 10: db 000h,000h,000h ; 11: db 000h,000h,000h ; 12: db 000h,000h,000h ; 13: db 000h,000h,000h ; 14: db 000h,000h,000h ; 15: 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 even C0_func_tab dw vt_disp_none ; 00H NUL dw vt_disp_none ; 01H SOH dw vt_disp_none ; 02H STX dw vt_disp_none ; 03H ETX dw vt_disp_none ; 04H EOT dw vt_disp_none ; 05H ENQ dw vt_disp_none ; 06H ACK dw vt_disp_BEL ; 07H BEL dw vt_disp_BS ; 08H BS dw vt_disp_HT ; 09H HT dw vt_disp_LF ; 0AH LF dw vt_disp_LF ; 0BH VT dw vt_disp_LF ; 0CH FF dw vt_disp_CR ; 0DH CR dw vt_disp_SO ; 0EH SO dw vt_disp_SI ; 0FH SI ; dw vt_disp_none ; 10H DLE dw vt_disp_none ; 11H DC1 (XON) dw vt_disp_none ; 12H DC2 dw vt_disp_none ; 13H DC3 (XOFF) dw vt_disp_none ; 14H DC4 dw vt_disp_none ; 15H NAK dw vt_disp_none ; 16H SYN dw vt_disp_none ; 17H ETB dw vt_disp_CAN ; 18H CAN dw vt_disp_none ; 19H EM dw vt_disp_SUB ; 1AH SUB dw vt_disp_ESC ; 1BH ESC dw vt_disp_none ; 1CH FS dw vt_disp_GS ; 1DH GS dw vt_disp_none ; 1EH RS dw vt_disp_none ; 1FH US ; even vram_line 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 vram_botm_line dw 0e60h ;23 vram_last_line dw 0f00h ;24 ; I_am_vt52 db 3 db ESCAPE,"/Z" I_am_vt102 db 5 db ESCAPE,"[?6c" I_am_vt220 db 16 db ESCAPE,"[?62;1;2;6;7;8c" I_am_fine db 4 db ESCAPE,"[0n" My_cursor_is db ESCAPE,"[" db 10 dup (?) cur_col db 0 cur_row db 0 cur_save_col db 0 cur_save_row db 0 text_col db 0 text_row db 0 text_top db 0 text_bottom db 0 color_index_table db 0, 2, 4, 6, 1, 3, 5, 7 ; vt_phys_top db 0 vt_phys_bottom db 23 vt_top db 0 vt_bottom db 23 tabstops db 80 dup (?) ; tab stop table db 1,1 ; guard nam_none db ' ' nam_vt52 db 'VT52 ' nam_vt100 db 'VT102 ' LED_buff db '....' nam_tek db 'TEK4010/14' nam_prn db ' PRN' nam_nprn db ' ' dump_pntr dw ? dump_buffer db 256 dup (?) dump_mode db 0 watch_pnd dw 0 watch_buf db 12 dup (?) watch_lvl db 0 watch_mod db 0 ; ; Kermit mode line buffer ; mode_len db 0 mode_ker db 'Esc-chr: ' mode_esc db '^]' db ' help: ' mode_hlp db '^]' db '? port:' mode_prt db '1' db ' speed:' mode_spd db ' ' db ' parity:' mode_pty db 'none' db ' echo:' mode_ech db 'rem' db ' ' mode_trm db ' ' mode_prn db ' ' MODE_LINE_LENG = $ - mode_len unkbaud db ' Unk ' ; must be 5 characters baudname db ' 45.5' db ' 50 ' db ' 75 ' db ' 110 ' db '134.5' db ' 150 ' db ' 300 ' db ' 600 ' db ' 1200' db ' 1800' db ' 2000' db ' 2400' db ' 4800' db ' 9600' db '19200' db '38400' db '57.6K' db '115 K' BAUDNSIZ equ 18 parityname db 'even' ; must be 4 characters db 'mark' db 'none' db 'odd ' db 'spc ' lclename db 'loc' remename db 'rem' data ends code segment public 'code' assume cs:code,ds:data,es:nothing extrn sbrk:near ; memory allocation routine in mssker extrn s2jis:near, jis2s:near ; in MSZP98 extrn set_cursor:near ; in MSZP98 extrn set_gpalette:near ; in MSGP98 extrn gdisp_on:near, gdisp_off:near ; in MSGP98 extrn tek4014_color:near ; in MSGP98 extrn set_gcolor:near ; in MSGP98 extrn pntchr:near extrn outcapt:near ; in MSXP98 extrn set_cur_color:near ; in MSXP98 extrn sixel_in:near ; in MSGP98 extrn sixel_clear:near ; in MSGP98 extrn sixel:near ; in MSGP98 ; ; VT100 terminal emulator ; ; ;----------------------------------------------------------- ; ; Initilization routine ; This is called from lclini, local initialization routine. VT100_INI PROC NEAR cmp vt_init,0 je vt100_ini_1 jmp vt100_ini_ex vt100_ini_1: mov vt_init,1 ; ; Allocate memory to save screen ; mov ax,2000h ; display + attributes call sbrk mov vt_saveseg,ax ; ; Check the memory size ; mov bx,0FFFFh ; allocate full integer (must fail) mov ah,ALLOC ; memory allocation int DOS ; system call. BX has number of free para. mov ax,bx cmp ax,2000 ; keep 32K for COMMAND.COM (in parag. size) ja vt100_ini_r1 mov ax,ROLLMEM_MIN jmp vt100_ini_r2 vt100_ini_r1: sub ax,2000 cmp ax,ROLLMEM_MAX jbe vt100_ini_r2 mov ax,ROLLMEM_MAX vt100_ini_r2: xor dx,dx mov cx,20 ; number of parag. per line div cx mov vt_rollmxl,ax mov cx,20 ; number of parag. per line mul cx push ax ; save number of parag. mov bx,ax mov ah,ALLOC ; allocate memory int DOS mov vt_rollseg,ax mov vt_rollcur,ax mov vt_rollcln,0 mov vt_rollfil,1 pop bx add ax,bx mov vt_rollmxs,ax ; vt100_ini_ex: call vt100_soft_res ; reset software parameters ret VT100_INI ENDP VT100_RESET PROC NEAR call vt100_soft_res call vt100_restore call vt100_modlin ret VT100_RESET ENDP VT100_SOFT_RES PROC NEAR ; ; Software reset terminal (* means not supported yet) ; * Text cursor On ; Insert/Replace Replace ; Origin Mode Absolute ; Autowrap Off ; * Keyboard Action Unlocked ; Keypad Mode Numeric ; Cursor Key Mode Normal ; Top Margin 1 ; Bottom Margin 24 ; Character Sets default ; Video Character Normal ; push ax push bx ; mov sixel_disp_on,0 ; no sixel display mov vt100_gflag,1 push si mov si,offset def_color ; set color to default call set_cur_color call vt100_color pop si ; mov vt_in_stat,0 ; main screen mov vt_stat_type,1 ; mov ax,'..' ; LED-clear mov bx,offset LED_buff mov [bx],ax mov [bx+2],ax ; and vt100_flags,(not INSERT_BIT) and vt100_flags,(not ORIGIN_BIT) and vt100_flags,(not AUTOWRAP_BIT) mov vt100_pflag,0 ; flags for printer control mov vt100_cursr,0 ; cursor style mov curkey_mode,0 mov keypad_mode,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 al,vt_phys_top mov vt_top,al mov al,vt_phys_bottom mov vt_bottom,al mov priv_pflg,0 ; mov char_G0,CSET_JISROMAN mov char_G1,CSET_DECGRAPH mov char_G2,CSET_JISKATAKANA mov char_G3,CSET_JISC6226 ; mov vt_graph,0 mov char_SS,0 mov char_GL,offset char_G0 mov char_GR,offset char_G3 ; ; Erase save area ; push es push di cld mov ax,vt_saveseg mov es,ax mov di,0 ; offset address mov cx,0800h mov ax,0020h rep stosw mov al,vt_blkatr xor ah,ah mov cx,0800h rep stosw ; pop di pop es ; ; Initialize TAB table ; push cx push dx ; mov bx,offset tabstops mov cx,80 xor ax,ax vt_ini_t1: mov dl,0 test ax,7 jnz vt_ini_t2 mov dl,1 vt_ini_t2: push bx add bx,ax mov byte ptr [bx],dl pop bx inc ax loop vt_ini_t1 ; pop dx pop cx ; call set_modlin ; set Kermit modeline buffer call save_cursor pop bx pop ax ret VT100_SOFT_RES ENDP ; ; save VT100 screen ; VT100_SAVE PROC NEAR push ax push cx push dx push ds push es ; cld ; mov ah,0Dh ; stop display int BIOS ; mov ax,vt_saveseg mov es,ax ; destination segment address mov di,0 mov si,vram_line ; set source address [06-Nov-88] push si ; save it for later use [06-Nov-88] mov ax,CRT_TXT_SEG mov ds,ax mov cx,0800h rep movsw pop si ; remember source address [06-Nov-88] add si,2000h ; attribute area mov cx,0800h rep movsw ; pop es pop ds ; ; clear mode line ; mov al,vt_blkatr call vt_stat_clr ; mov ah,0Ch ; start dispay int BIOS ; mov ax,0 call set_cursor ; restore cursor attributes ; mov si,offset gnrm_color call set_gpalette call gdisp_off ; pop dx pop cx pop ax ; ret VT100_SAVE ENDP ; ; restore VT100 screen ; VT100_RESTORE PROC NEAR push ax push bx push cx push dx push ds push es ; cld ; mov ah,0Dh ; stop display int BIOS ; mov ax,CRT_TXT_SEG mov es,ax ; destination sagment address mov di,vram_line push di mov ax,vt_saveseg mov ds,ax mov si,0 mov cx,0800h rep movsw pop di add di,2000h ; attribute area mov cx,0800h rep movsw ; mov ah,0Ch ; start dispay int BIOS ; pop es pop ds ; xor ax,ax mov al,vt100_cursr call set_cursor ; set cursor attributes ; call locate_cur ; call set_gcolor call gdisp_on ; pop dx pop cx pop bx pop ax ; ret VT100_RESTORE ENDP set_termnam proc near push ax push cx push si push di push es ; mov ax,ds mov es,ax ; terminal type mov cx,10 ; length of terminal name mov si,offset nam_vt52 cmp flags.vtflg,ttvt52 je set_termnam1 mov si,offset nam_vt100 cmp flags.vtflg,ttvt100 je set_termnam1 mov si,offset nam_tek cmp flags.vtflg,tttek je set_termnam1 mov si,offset nam_none set_termnam1: mov di,offset mode_trm rep movsb ; pop es pop di pop si pop cx pop ax ret set_termnam endp ; set_prnstat proc push ax push cx push si push di push es ; mov ax,ds mov es,ax ; ; printer status ; mov cx,4 mov si,offset nam_nprn test vt100_pflag,(AUTOPRINT_BIT+PRINTCTRL_BIT) jz set_prnstat1 mov si,offset nam_prn set_prnstat1: mov di,offset mode_prn rep movsb pop es pop di pop si pop cx pop ax ret set_prnstat endp ; SET_MODLIN PROC NEAR ; set the mode line buffer ; push es mov ax,ds mov es,ax ; mov al,' ' mov ah,trans.escchr cmp ah,020h jge set_modlin1 mov al,'^' or ah,040h set_modlin1: mov word ptr mode_esc,ax mov word ptr mode_hlp,ax ; mov al,vt_ourarg.baudb mov si,offset unkbaud ; Assume unknown baud. mov cx,5 ; length of baud space cmp al,BAUDNSIZ ; too big? jnb set_modlin2 ; yes, use default mul cl xor ah,ah add ax,offset baudname mov si,ax set_modlin2: mov di,offset mode_spd rep movsb ; mov al,vt_ourarg.prt cmp al,'A' jae set_modlin3 add al,'0' ; convert to character set_modlin3: mov mode_prt,al ; mov al,vt_ourarg.parity xor ah,ah mov cx,4 imul cl add ax,offset parityname mov si,ax mov di,offset mode_pty rep movsb ; mov si,offset lclename test vt_ourarg.flgs,lclecho jnz set_modlin4 mov si,offset remename set_modlin4: mov cx,3 mov di,offset mode_ech rep movsb ; call set_termnam call set_prnstat ; mov mode_len,MODE_LINE_LENG ; pop es ret SET_MODLIN ENDP ; vt_stat_clr proc near ; ; clear status line with attribute in AL. ; push bx push es push di push si ; mov bx,ax cld mov ax,CRT_TXT_SEG mov es,ax mov di,vram_last_line mov cx,80 xor ah,ah mov al,' ' rep stosw mov di,vram_last_line add di,02000h mov al,bl mov cx,80 rep stosw ; mov ax,bx pop si pop di pop es pop bx ret vt_stat_clr 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 ax push cx cmp vt_stat_type,0 ; clear status buffer ? jne vt100_modlin1 ; ne=no. mov al,vt_blkatr ; attribute call vt_stat_clr ; clear the status line jmp vt100_modlin_ex ; and return ; vt100_modlin1: cmp vt_stat_type,1 ; Kermit mode line control ? jne vt100_modlin2 ; ne=no. test vt_ourarg.flgs,modoff ; mode line off ? jz vt100_modlin1_1 ; z=no. mov al,vt_blkatr call vt_stat_clr jmp vt100_modlin_ex ; ; display kermit mode line ; vt100_modlin1_1: mov al,vt_modatr call vt_stat_clr ; push es push di push si ; cld xor ch,ch mov cl,mode_len mov si,offset mode_ker mov ax,CRT_TXT_SEG mov es,ax mov di,vram_last_line xor ah,ah vt100_modlin1_2: mov al,[si] mov es:[di],ax inc si add di,2 loop vt100_modlin1_2 ; pop si pop di pop es jmp vt100_modlin_ex ; vt100_modlin2: ;@@ mov al,vt_modatr ;@@ call vt_stat_clr ; vt100_modlin_ex: call locate_cur ; pop cx pop ax ret VT100_MODLIN ENDP VT100_COLOR PROC NEAR ; ; Change color to the value specified in [si]. ; [si] color index for foreground ; [si+1] color index for background ; [si+2] color index for highlight ; [si+3] color index for modeline ; push ax push cx ; mov al,[si] and vt_nrmatr,1Fh ; mask color attributes and vt_chratr,1Fh and vt_blkatr,1Fh mov cl,5 shl al,cl or vt_nrmatr,al or vt_chratr,al or vt_blkatr,al ; push di push si mov al,[si+1] xor ah,ah mov si,offset gnrm_color add si,ax add si,ax add si,ax mov di,offset gbck_color mov cx,16 vt100_color1: mov al,[si] mov [di],al inc di mov al,[si+1] mov [di],al inc di mov al,[si+2] mov [di],al inc di loop vt100_color1 pop si pop di ; mov al,[si+2] and vt_hglatr,1Fh ; mask color attributes mov cl,5 shl al,cl or vt_hglatr,al ; mov al,[si+3] and vt_modatr,1Fh ; mask color attributes mov cl,5 shl al,cl or vt_modatr,al ; pop cx pop ax ret VT100_COLOR ENDP mrsave proc near ; ; save n lines (given by CL) in roll-up buffer (circular). ; push ax push cx push si push di push ds push es ; xor ch,ch ; clear high byte of CX mov si,vram_line mrsave1: cmp cx,0 jle mrsave3 push cx push ds mov ax,vt_rollcur ; current roll-buffer segment mov es,ax ; destination segment address mov di,0 ; destination offset address mov ax,CRT_TXT_SEG mov ds,ax ; source segment address push si ; save the source offset address mov cx,80 ; words per line rep movsw ; save the text area pop si add si,2000h ; offset address of the attribute area mov cx,80 rep movsw ; save the attribute area sub si,2000h ; return to text area pop ds pop cx dec cx inc vt_rollcln ; update lines add vt_rollcur,20 ; update segment address. 20 parag. per line mov ax,vt_rollfil cmp ax,vt_rollmxl jge mrsave2 inc vt_rollfil mrsave2: mov ax,vt_rollcln cmp ax,vt_rollmxl ; exceed maximum lines ? jl mrsave1 mov ax,vt_rollseg mov vt_rollcur,ax mov vt_rollcln,0 jmp mrsave1 mrsave3: pop es pop ds pop di pop si pop cx pop ax ret mrsave endp prn_chk proc near ; ; Check the printer port ; carry on -- printer not ready ; push ax mov ah,ioctl mov al,7 ; get output status of printer push bx mov bx,4 ; file handle for system printer int dos pop bx jc prn_chk1 ; c = printer not ready cmp al,0ffh ; Ready status? je prn_chk2 ; e = Ready prn_chk1: call vt_bell stc prn_chk2: pop ax ret prn_chk endp VT100_RUPN proc near ; ; roll-up n lines (n is given in cx) ; cx will be broken when return. ; 1) copy the last line of the screen to the current save area ; 2) decrement the save area pointer ; 3) scroll down the screen by one line ; 4) copy the current save area to the top of screen ; 5) increment the number of moved lines ; push ax push dx push si push di push es ; vt100_rupn_1: cmp cx,0 jg vt100_rupn_2 jmp vt100_rupn_ex vt100_rupn_2: mov ax,vt_rollnum inc ax cmp ax,vt_rollfil jl vt100_rupn_3 jmp vt100_rupn_ex ; vt100_rupn_3: push cx ; save counter mov ax,vt_rollcur mov es,ax mov di,0 ; push ds ; mov ax,CRT_TXT_SEG mov si,vram_botm_line push si mov cx,80 mov ds,ax cld rep movsw pop si add si,2000h ; attribute area mov cx,80 rep movsw ; save attributes ; pop ds ; mov cx,20 ; one line (display + attributes) cmp vt_rollcln,0 jg vt100_rupn_4 mov ax,vt_rollmxl mov vt_rollcln,ax mov ax,vt_rollmxs mov vt_rollcur,ax vt100_rupn_4: dec vt_rollcln mov ax,vt_rollcln sub vt_rollcur,cx ; mov cx,vram_botm_line sub cx,vram_line mov di,vram_last_line dec di mov si,vram_botm_line dec si std mov ax,CRT_TXT_SEG ; push ds ; push cx push di push si mov ds,ax mov es,ax std rep movsb pop si pop di pop cx add si,2000h add di,2000h rep movsb ; pop ds cld ; mov di,vram_line mov si,0 mov ax,CRT_TXT_SEG mov es,ax mov ax,vt_rollcur ; push ds ; mov ds,ax mov cx,80 push di rep movsw pop di add di,2000h mov cx,80 rep movsw ; pop ds ; inc vt_rollnum pop cx ; restore line counter dec cx jmp vt100_rupn_1 ; vt100_rupn_ex: pop es pop di pop si pop dx pop ax ret VT100_RUPN endp VT100_RDNN proc near ; ; roll-down n lines (n is given in CX). ; CX will be broken when return. ; 1) copy the top of the screen to the current save area ; 2) increment the save area pointer ; 3) screen scroll up one line ; 4) copy the current save area to the bottom of the screen ; 5) decrement the number of moved lines ; push ax push dx push si push di push es ; vt100_rdnn_1: cmp cx,0 jg vt100_rdnn_2 jmp vt100_rdnn_ex vt100_rdnn_2: mov ax,vt_rollnum cmp ax,0 jg vt100_rdnn_3 jmp vt100_rdnn_ex ; vt100_rdnn_3: push cx ; save line counter mov ax,vt_rollcur mov es,ax mov di,0 ; push ds ; mov ax,CRT_TXT_SEG mov si,vram_line push si mov cx,80 mov ds,ax cld rep movsw pop si add si,2000h ; attribute area mov cx,80 rep movsw ; save attributes ; pop ds ; increment save-area pointer mov cx,20 ; one line (display + attributes) inc vt_rollcln add vt_rollcur,cx mov ax,vt_rollcln cmp ax,vt_rollmxl jl vt100_rdnn_4 mov vt_rollcln,0 mov ax,vt_rollseg mov vt_rollcur,ax vt100_rdnn_4: ; mov cx,vram_botm_line sub cx,vram_line mov di,vram_line mov si,di add si,160 mov ax,CRT_TXT_SEG ; push ds ; push cx push di push si mov ds,ax mov es,ax rep movsb pop si pop di pop cx add si,2000h add di,2000h rep movsb ; pop ds ; mov di,vram_botm_line mov si,0 mov ax,CRT_TXT_SEG mov es,ax mov ax,vt_rollcur ; push ds ; mov ds,ax mov cx,80 push di rep movsw pop di add di,2000h mov cx,80 rep movsw ; pop ds ; dec vt_rollnum pop cx ; restore line counter dec cx jmp vt100_rdnn_1 ; vt100_rdnn_ex: pop es pop di pop si pop dx pop ax ret VT100_RDNN 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_mode0 scrn_mode1: ; light background dark text. test vt_nrmatr,CHR_REV jz scrn_mode1L jmp scrn_mode3 scrn_mode1L: xor BYTE PTR es:[di],CHR_REV add di,2 loop scrn_mode1L or vt_nrmatr,CHR_REV or vt_chratr,CHR_REV or vt_blkatr,CHR_REV jmp scrn_mode3 scrn_mode0: ; dark background light text. test vt_nrmatr,CHR_REV jnz scrn_mode0L jmp scrn_mode3 scrn_mode0L: xor BYTE PTR es:[di],CHR_REV add di,2 loop scrn_mode0L 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 move_cur mov vt_wrap,0 ; new position clears wrap req. flag ret locate_cur endp ; move_cur proc near ; ; Move cursor at (dh:row,dl:col) ; Registers ax, bx and dx are broken when return. ; call vram_ofs ; get VRAM address in BX shr bx,1 cli move_cur1: in al,60h test al,04h ; test GDC status jz move_cur1 ; z=not ready mov al,49h out 62h,al mov al,bl out 60h,al mov al,bh out 60h,al sti ret move_cur endp ; disp_char proc near ; ; Display character in AX on the screen. ; Cursor moves to the next character position. ; AX:will be broken when return. ; cmp ax,00060h ; backquote special treatment jne disp_char_mod1 mov ax,06009h ; for backquote jmp disp_char_modx disp_char_mod1: ;@@ cmp ax,0005Ch ; backslash ;@@ jne disp_char_mod2 ;@@ mov ax,000EFh disp_char_mod2: disp_char_modx: ; push es ; save segment reg. mov dx,CRT_TXT_SEG ; set vram segment address mov es,dx cmp vt_wrap,0 ; wrap requested ? je disp_char_nowrap ; e = no. ; mov cur_col,0 ; return to left margin mov bl,cur_row cmp bl,vt_bottom ; exceed bottom margin ? jl disp_char_wrap1 ; l = No. je disp_char_wrap2 inc cur_row mov bl,cur_row cmp bl,vt_phys_bottom jle disp_char_nowrap mov bl,vt_phys_bottom mov cur_row,bl jmp disp_char_nowrap disp_char_wrap1: inc cur_row jmp disp_char_nowrap disp_char_wrap2: push ax mov al,vt_top mov ah,vt_bottom mov cx,1 call scroll_up pop ax disp_char_nowrap: mov dh,cur_row ; get current cursor position mov dl,cur_col call vram_ofs ; get vram offset address in bx mov di,bx ; set destination test vt100_flags,INSERT_BIT ; insert mode ? jz disp_char_noins ; z = no cmp cur_col,79 ; at left margin ? jge disp_char_noins ; ge = Yes. No characters shifted mov cx,79 sub cl,cur_col ; get num. of chars. to be shifted mov dh,cur_row mov dl,79 call vram_ofs ; get destination offset address mov di,bx ; set destination reg mov si,bx sub si,2 ; source offset address push ds ; save data-seg. reg. mov dx,CRT_TXT_SEG mov ds,dx std ; inverse direction rep movsw ; shift the characters cld ; reset direction flag pop ds ; restore data-seg. reg. disp_char_noins: mov es:[di],ax ; put the character xor ah,ah ; clear higher bit mov al,vt_chratr ; load attribute add di,02000h ; attribute offset address stosw ; put attribute and increment address pop es ; restore segment inc cur_col ; update cursor position mov al,cur_col cmp al,79 ; exceed right margin ? jbe disp_char_loc ; be = No. mov cur_col,79 ; stay at right margin test vt100_flags,AUTOWRAP_BIT ; Autowrap enable ? jz disp_char_ex ; z = No. NoWrap mov vt_wrap,1 ; wrap request jmp disp_char_ex ; all done. disp_char_loc: call locate_cur disp_char_ex: ret disp_char endp save_cursor proc near ; saves ; 1) cursor position mov al,cur_row mov cur_save_row,al mov al,cur_col mov cur_save_col,al ; 2) graphic rendition mov al,vt_graph mov save_graph,al mov al,vt_chrset mov save_chrset,al mov al,vt_chratr mov save_chratr,al mov al,vt_blkatr mov save_blkatr,al ; mov ax,char_SS mov char_save_SS,ax mov ax,char_GL mov char_save_GL,ax mov ax,char_GR mov char_save_GR,ax ; mov al,char_G0 mov char_save_G0,al mov al,char_G1 mov char_save_G1,al mov al,char_G2 mov char_save_G2,al mov al,char_G3 mov char_save_G3,al ; 3) state of wrap flag ; 4) state of origin mode mov al,vt100_flags mov save_flags,al ; 5) state of selective erase ret save_cursor endp restore_cursor proc near ; 1) state of selective erase ; 2) state of origin mode and vt100_flags,(not ORIGIN_BIT) mov al,save_flags and al,ORIGIN_BIT or vt100_flags,al ; 3) state of wrap flag and vt100_flags,(not AUTOWRAP_BIT) mov al,save_flags and al,AUTOWRAP_BIT or vt100_flags,al ; 4) graphic rendition mov al,save_graph mov vt_graph,al mov al,save_chrset mov vt_chrset,al mov al,save_chratr mov vt_chratr,al mov al,save_blkatr mov vt_blkatr,al ; mov ax,char_save_SS mov char_SS,ax mov ax,char_save_GL mov char_GL,ax mov ax,char_save_GR mov char_GR,ax ; mov al,char_save_G0 mov char_G0,al mov al,char_save_G1 mov char_G1,al mov al,char_save_G2 mov char_G2,al mov al,char_save_G3 mov char_G3,al ; 5) cursor position mov al,cur_save_row mov cur_row,al mov al,cur_save_col mov cur_col,al call locate_cur ret restore_cursor endp vt_dump proc near ; ; copy the one line image from es:[si] to dump buffer. ; input ; ES:SI ; outputs ; CX contains number of characters. ; ES:SI will be updated (points to the next line). ; push ax push di ; mov dump_mode,0 mov di,offset dump_buffer mov dump_pntr,di mov cx,80 ; vt_dump1: mov ax,es:[si] cmp ah,0 ; 1 byte code ? je vt_dump3 ; e = yes. cmp al,09h ; ANK ? jne vt_dump11 ; ne = no. mov al,ah mov ah,0 jmp vt_dump3 vt_dump11: cmp dump_mode,0 je vt_dump12 mov byte ptr [di],ESCAPE mov word ptr [di+1],'0)' add di,3 mov dump_pntr,di mov dump_mode,0 vt_dump12: 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 vt_dump2 vt_dump3: ; check graphic code. It is overrap over the shift-JIS kanji code. ; In that case, we should put the ESC seq to change the character set. cmp al,80h jbe vt_dump6 cmp al,0FCh ja vt_dump6 cmp al,09Fh jbe vt_dump5 cmp al,0E0h jb vt_dump6 vt_dump5: cmp dump_mode,0 jne vt_dump4 mov byte ptr [di],ESCAPE mov word ptr [di+1],'3)' add di,3 mov dump_pntr,di mov dump_mode,1 jmp vt_dump4 vt_dump6: cmp dump_mode,0 je vt_dump4 mov byte ptr [di],ESCAPE mov word ptr [di+1],'0)' add di,3 mov dump_pntr,di mov dump_mode,0 vt_dump4: mov [di],al ; remove Kanji flag etc in ah. inc di add si,2 cmp al,' ' ; Is it blank ? je vt_dump2 ; e = yes. mov dump_pntr,di vt_dump2: dec cx jcxz vt_dump7 jmp vt_dump1 ; vt_dump7: mov di,dump_pntr cmp dump_mode,0 je vt_dump8 mov byte ptr [di],ESCAPE mov word ptr [di+1],'0)' add di,3 vt_dump8: mov ax,0A0Dh ; add CR/LF mov [di],ax add di,2 mov cx,di sub cx,offset dump_buffer ; pop di pop ax ret vt_dump endp vt_prn proc near ; ; copy the one line image from es:[si] to dump buffer as a printer ; image. ; ; input ; ES:SI ; outputs ; CX contains number of characters. ; ES:SI will be updated (points to the next line). ; push ax push di ; mov dump_mode,0 mov di,offset dump_buffer mov dump_pntr,di mov cx,80 ; vt_prn1: mov ax,es:[si] cmp ah,0 ; 1 byte code ? je vt_prn3 ; e = yes. vt_prn11: cmp dump_mode,0 ; in 2 byte mode ? jne vt_prn12 ; ne = yes. mov byte ptr [di],ESCAPE mov byte ptr [di+1],'K' ; Kanji mode. add di,2 mov dump_pntr,di mov dump_mode,1 vt_prn12: add ax,20h ; convert to jis and ax,7F7Fh ; mask 8th bit mov [di],al mov [di+1],ah add di,2 add si,4 dec cx mov dump_pntr,di jmp vt_prn2 vt_prn3: cmp dump_mode,0 ; in 1 byte mode ? je vt_prn4 ; e = yes. mov byte ptr [di],ESCAPE mov byte ptr [di+1],'H' ; High density pica mode. add di,2 mov dump_pntr,di mov dump_mode,0 vt_prn4: mov [di],al ; remove Kanji flag etc in ah. inc di add si,2 cmp al,' ' ; Is it blank ? je vt_prn2 ; e = yes. mov dump_pntr,di vt_prn2: dec cx jcxz vt_prn7 jmp vt_prn1 ; vt_prn7: mov di,dump_pntr cmp dump_mode,0 je vt_prn8 mov byte ptr [di],ESCAPE mov byte ptr [di+1],'H' add di,2 vt_prn8: mov ax,0A0Dh ; add CR/LF mov [di],ax add di,2 mov cx,di sub cx,offset dump_buffer ; pop di pop ax ret vt_prn endp vt_bell proc near push ax push cx ; mov al,06h out 37h,al mov cx,0D000h vt_bell1: loop vt_bell1 mov al,07h out 37h,al ; pop cx pop ax vt_bell 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 call vt_dump mov ah,WRITE2 ; write function mov dx,offset dump_buffer int DOS ; pop cx loop vt100_dump0 ; pop di pop si pop es pop dx pop cx ret VT100_DUMP ENDP ;------------------------------------------------------------------------------ VT100_PRNC PROC NEAR ; ; Printer control (Transparent printing). ; - Watches the control seunce CSI 4 i (turns off printer controller mode). ; If this sequence is found, control returns to normal terminal mode. ; - Until CSI 4 i sequnce is found, all the received characters are sent to ; the printer without displaying them on the screen except NUL, XON, XOFF, ; CSI 5 i and CSI 4 i. ; mov di,offset watch_buf ; get buffer pointer add di,watch_pnd ; adjust pointer mov [di],al ; save the character inc watch_pnd ; increment the pointer ; cmp watch_lvl,0 ; normal sequnce ? jne vt100_prnc_n0 ; ne = no. jmp vt100_prnc_L0 vt100_prnc_n0: cmp watch_lvl,1 ; next ESC ? jne vt100_prnc_n1 ; ne = no. jmp vt100_prnc_L1 vt100_prnc_n1: cmp watch_lvl,2 ; after CSI ? jne vt100_prnc_n2 ; ne = no. jmp vt100_prnc_L2 vt100_prnc_n2: cmp watch_lvl,3 ; final character ? jne vt100_prnc_n3 ; ne = no. jmp vt100_prnc_L3 vt100_prnc_n3: ; *** if come here, PROGRAM ERROR *** mov watch_lvl,0 mov watch_pnd,0 jmp vt100_prnc_OUT ; vt100_prnc_L0: mov watch_lvl,1 ; assume ESC cmp al,ESCAPE ; ESC ? je vt100_prnc_L0_1 ; e = yes. mov watch_lvl,2 ; assume CSI cmp al,CSI ; CSI ? je vt100_prnc_L0_1 ; e = yes. jmp vt100_prnc_OUT ; vt100_prnc_L0_1: mov di,offset watch_buf mov watch_pnd,0 mov [di],al inc watch_pnd jmp vt100_prnc_ex ; vt100_prnc_L1: cmp al,'[' je vt100_prnc_L1_1 jmp vt100_prnc_OUT vt100_prnc_L1_1: mov watch_lvl,2 jmp vt100_prnc_ex ; vt100_prnc_L2: mov watch_mod,al cmp al,'5' je vt100_prnc_L2_1 cmp al,'4' je vt100_prnc_L2_1 jmp vt100_prnc_OUT vt100_prnc_L2_1: mov watch_lvl,3 jmp vt100_prnc_ex ; vt100_prnc_L3: cmp al,'i' jne vt100_prnc_OUT mov watch_pnd,0 ; clear pending buffer cmp watch_mod,'4' ; off the printer control ? jne vt100_prnc_L3_1 ; ne = no. and vt100_pflag,(not PRINTCTRL_BIT) vt100_prnc_L3_1: jmp vt100_prnc_ex ; vt100_prnc_OUT: mov di,offset watch_buf mov cx,watch_pnd vt100_prnc_OUT1: mov ah,LSTOUT mov dl,[di] int DOS jc vt100_prnc_OUT2 inc di loop vt100_prnc_OUT1 mov watch_pnd,0 jmp vt100_prnc_ex ; vt100_prnc_OUT2: call vt_bell and vt100_pflag,(not (AUTOPRINT_BIT+PRINTCTRL_BIT)) mov watch_pnd,0 ; vt100_prnc_ex: xor ah,ah xor cx,cx ret VT100_PRNC ENDP ;------------------------------------------------------------------------------ VT100_PRNL PROC NEAR ; ; Print the current line on the printer ; push dx ; push bx mov dh,cur_row mov dl,0 call vram_ofs mov si,bx pop bx ; push es mov ax,CRT_TXT_SEG mov es,ax call vt_prn pop es ; mov di,offset dump_buffer vt100_prnl1: mov al,[di] call pntchr jc vt100_prnl2 inc di loop vt100_prnl1 jmp vt100_prnl3 ; vt100_prnl2: call vt_bell and vt100_pflag,(not (AUTOPRINT_BIT+PRINTCTRL_BIT)) ; vt100_prnl3: ; pop dx ret VT100_PRNL ENDP ;------------------------------------------------------------------------------ VT100_PRNS PROC NEAR ; ; Print the current screen on the printer. ; Similar to dump. ; push cx push dx push es push si push di ; test vt100_pflag,AUTOPRINT_BIT ; printer off? jnz vt100_prns1 ; nz = no not. it is on. call prn_chk ; check the printer port jnc vt100_prns1 ; nc = ready. jmp vt100_prns5 ; vt100_prns1: mov ax,CRT_TXT_SEG mov es,ax mov si,vram_line mov cx,24 test vt100_pflag,PRINTEXT_BIT ; full screen printing? jnz vt100_prns2 ; nz = yes. mov al,vt_top ; determine start address xor ah,ah mov cx,ax shl ax,1 mov si,offset vram_line add si,ax mov si,[si] mov al,vt_bottom xor ah,ah xchg ax,cx sub cx,ax inc cx vt100_prns2: push cx call vt_prn mov di,offset dump_buffer ; vt100_prns3: mov al,[di] call pntchr jc vt100_prns4 inc di loop vt100_prns3 ; pop cx loop vt100_prns2 ; test vt100_pflag,PRINTFF_BIT ; must print FF ? jz vt100_prns5 ; z = no. mov al,FF call pntchr jc vt100_prns4 jmp vt100_prns5 ; vt100_prns4: call vt_bell and vt100_pflag,(not (AUTOPRINT_BIT+PRINTCTRL_BIT)) ; vt100_prns5: pop di pop si pop es pop dx pop cx ret VT100_PRNS ENDP ;------------------------------------------------------------------------------ VT100 PROC NEAR ; ; The main program for VT100 emulator ; Inputs: ; AL character code ; Outputs: ; AH results ; 0:Normal, in this case, ; CX number of characters to be sent to communication port ; DS:SI character string to be sent ; ; AH non zero means 'change to the tek4010 emulation mode' ; 1:only change the mode. do not pass any character. ; 2:change the mode and send the character in AL. ; 3:change the mode and send the characters in DH and DL. ; DX character pair to be sent to tek4010 emulator if AH=3. ; ;------------------------------------------------------------------------------ ; ; Character display routine in VT-100 mode ; vt_disp: mov vt_rollnum,0 ; cmp spec_mode,0 ; in special mode ? je vt_disp_NRM ; e = No. go to normal process. cmp spec_mode,IN_ESC_MODE ; in ESC sequence ? jne vt_disp_01 ; ne = No. check other sequnce. jmp vt_disp_inESC ; go to ESC sequence procedure. vt_disp_01: cmp spec_mode,IN_CSI_MODE ; in CSI sequence ? jne vt_disp_02 ; ne = No. check other sequnce. jmp vt_disp_inCSI ; go to CSI sequence procedure. vt_disp_02: cmp spec_mode,IN_DCS_MODE ; in DCS sequence ? jne vt_disp_03 ; ne = No. jmp vt_disp_inDCS ; go to DCS sequence procedure. vt_disp_03: mov spec_mode,0 ; May be my program error. treate as ; normal character. ; vt_disp_NRM: cmp al,080h ; C0/GL character ? jae vt_disp_C1GR ; ae = No. ; ; C0/D0 character ; cmp al,020h ; C0 code ? jae vt_disp_GL ; ae = No. This is GL code. jmp vt_disp_C0 ; do C0 control. vt_disp_GL: cmp al,07Fh ; DEL code ? je vt_disp_ex ; e = Yes. Ignore this character. cmp char_SS,0 ; single shift in progress ? je vt_disp_GL2 ; e = No. mov bx,char_SS ; single shift jmp disp_out ; display character vt_disp_GL2: mov bx,char_GL ; GL character jmp disp_out ; display character vt_disp_ex: mov ah,0 ; continue vt emulation mov cx,0 ret ; ; C1/GR character ; vt_disp_C1GR: cmp al,0A0h ; C1 code ? jae vt_disp_GR ; ae = No. This is GR code jmp vt_disp_C1 ; do C1 control vt_disp_GR: cmp al,0FFh ; 8 bit DEL code ? je vt_disp_ex ; e = Yes. Ignore this character and al,07Fh cmp char_SS,0 ; Single shift in progress ? je vt_disp_GR2 ; e = No. mov bx,char_SS ; set single shift jmp disp_out vt_disp_GR2: mov bx,char_GR ; GR character ;----------------------------------- ; Display the character code. ; Inputs: ; AL: Character code ; BX: Address of the character set ;----------------------------------- disp_out: cmp vt_knjmode,0 ; multi-byte code in progress ? jne disp_Kanji ; ne = Yes. jmp disp_out0 ; 1st byte character code. ; disp_Kanji: mov vt_kanji2,al ; save Kanji 2nd byte ; ; test logging ; cmp vt100_lflag,(LOGCOOK_BIT+LOGENAB_BIT) ; log enabled and cooked jne disp_Kanji_1 ; ne = No. mov ah,vt_kanji2 mov al,vt_kanji1 call jis2s ; convert to shift JIS call outcapt ; log 1st byte xchg ah,al call outcapt ; log 2nd byte disp_Kanji_1: ; ; Display Kanji ; mov ah,vt_kanji2 ; restore Kanji 2nd byte mov al,vt_kanji1 ; restore Kanji 1st byte sub ax,020h push ax call disp_char pop ax or ax,8000h call disp_char mov vt_knjmode,0 mov char_SS,0 ; reset single shift jmp vt_disp_ex ; disp_out0: mov ah,[bx] ; Get character set number mov vt_graph,ah xor ah,ah cmp vt_graph,CSET_JISROMAN ; JIS roman character set ? jne disp_out1 jmp disp_outit disp_out1: cmp vt_graph,CSET_DECGRAPH ; DEC special graphics character set ? jne disp_out2 jmp disp_DECGRAPH disp_out2: cmp vt_graph,CSET_JISC6226 ; JIS 2-byte Kanji code ? jne disp_out3 jmp disp_JISC6226 disp_out3: cmp vt_graph,CSET_JISKATAKANA jne disp_out4 jmp disp_JISKATAKANA disp_out4: jmp disp_outit ;--------------------------------------- disp_DECGRAPH: cmp ax,060h jge disp_DECGRAPH1 jmp disp_outit disp_DECGRAPH1: sub ax,060h mov bx,offset vt_gset add bx,ax mov al,[bx] jmp disp_outit disp_JISC6226: mov vt_kanji1,al mov vt_knjmode,1 jmp vt_disp_ex disp_JISKATAKANA: or al,080h disp_outit: cmp vt100_lflag,(LOGCOOK_BIT+LOGENAB_BIT) jne disp_outit_1 call outcapt disp_outit_1: call disp_char mov char_SS,0 ; reset single shift jmp vt_disp_ex ; ;------------------------------------------------- ; C0 control characters ; Note that only CAN and SUB clear ESC, CSI stage. ;------------------------------------------------- vt_disp_C0: push ax mov bx,offset C0_func_tab ; jump table address xor ah,ah shl ax,1 add bx,ax pop ax jmp [bx] ; ; No action ; vt_disp_none: jmp vt_disp_ex ; ; BEL ; vt_disp_BEL: mov al,06h out 37h,al mov cx,0D000h bell_loop: loop bell_loop mov al,07h out 37h,al jmp vt_disp_ex ; ; BS ; vt_disp_BS: mov vt_knjmode,0 ; clear multi-byte flag cmp cur_col,0 jg vt_disp_BS_1 jmp vt_disp_ex vt_disp_BS_1: dec cur_col call locate_cur jmp vt_disp_ex ; ; HT ; vt_disp_HT: mov vt_knjmode,0 ; clear multi-byte flag cmp vt100_lflag,(LOGCOOK_BIT+LOGENAB_BIT) jne vt_disp_HT0 call outcapt vt_disp_HT0: push bx ; save BX register mov bx,offset tabstops ; set address of tabstops mov al,cur_col ; get current cursor position xor ah,ah ; clear higher byte add bx,ax ; tab table pointer vt_disp_HT1: cmp al,79 ; right margin ? jge vt_disp_HT2 ; ge = Yes. do not move any more inc al ; move position inc bx ; update table pointer cmp byte ptr [bx],0 ; TAB stop position ? je vt_disp_HT1 ; e = No. increment pointer and cont. ; vt_disp_HT2: pop bx mov cur_col,al ; save the new cursor position call locate_cur ; and move the cursor jmp vt_disp_ex ; ; LF ; vt_disp_LF: mov vt_knjmode,0 ; clear multi-byte flag cmp vt100_lflag,(LOGCOOK_BIT+LOGENAB_BIT) jne vt_disp_LF0 call outcapt vt_disp_LF0: test vt100_pflag,AUTOPRINT_BIT ; auto-print requested ? jz vt_disp_LF5 ; z = no. call vt100_prnl ; print the current line vt_disp_LF5: mov bl,vt_bottom ; get bottom margin cmp cur_row,bl jl vt_disp_LF2 ; above boundary je vt_disp_LF1 ; on the boundary inc cur_row mov bl,vt_phys_bottom cmp cur_row,bl ; screen boundary jle vt_disp_LF3 mov cur_row,bl jmp vt_disp_LF3 vt_disp_LF1: mov cur_row,bl mov al,vt_top mov ah,vt_bottom mov cx,1 call scroll_up jmp vt_disp_LF3 vt_disp_LF2: inc cur_row vt_disp_LF3: test vt100_flags,NEWLINE_BIT ; newline enabled ? jz vt_disp_LF4 ; z = no. mov cur_col,0 vt_disp_LF4: call locate_cur jmp vt_disp_ex ; ; CR ; vt_disp_CR: mov vt_knjmode,0 ; clear multi-byte flag cmp vt100_lflag,(LOGCOOK_BIT+LOGENAB_BIT) jne vt_disp_CR0 call outcapt vt_disp_CR0: mov cur_col,0 call locate_cur jmp vt_disp_ex ; ; SO ; vt_disp_SO: mov vt_knjmode,0 ; clear multi-byte flag mov char_GL,offset char_G1 jmp vt_disp_ex ; ; SI ; vt_disp_SI: mov vt_knjmode,0 ; clear multi-byte flag mov char_GL,offset char_G0 jmp vt_disp_ex ; ; CAN ; vt_disp_CAN: mov vt_knjmode,0 ; clear multi-byte flag mov spec_mode,0 ; clear ESC/CSI seq. jmp vt_disp_ex ; ; SUB ; vt_disp_SUB: mov vt_knjmode,0 ; clear multi-byte flag mov spec_mode,0 ; clear ESC/CSI seq. mov ax,001Ah jmp disp_outit ; and display it. ; vt_disp_ESC: mov vt_knjmode,0 ; clear multi-byte flag mov spec_mode,in_ESC_MODE ; enter in ESC mode mov spec_stage,0 ; show that just entered mov I_pnt,0 mov bx,offset I_buf mov word ptr [bx],0 jmp vt_disp_ex ; ; GS Enter tektronix mode if tek4010 enabled ; vt_disp_GS: test vt100_flags,AUTOTEK_BIT jnz vt_disp_GS_01 jmp vt_disp_ex vt_disp_GS_01: mov vt_knjmode,0 ; clear multi-byte flag mov spec_mode,0 mov ah,2 ; pass character in AL mov cx,0 ret ; ;---------------------- ; C1 control characters ;---------------------- vt_disp_C1: mov vt_knjmode,0 ; clear multi-byte flag cmp al,084h ; IND jne vt_disp_C1_n84 jmp vt_C1_IND vt_disp_C1_n84: cmp al,085h ; NEL jne vt_disp_C1_n85 jmp vt_C1_NEL vt_disp_C1_n85: cmp al,088h ; HTS jne vt_disp_C1_n88 jmp vt_C1_HTS vt_disp_C1_n88: cmp al,08Dh ; RI jne vt_disp_C1_n8D jmp vt_C1_RI vt_disp_C1_n8D: cmp al,08Eh ; SS2 jne vt_disp_C1_n8E jmp vt_C1_SS2 vt_disp_C1_n8E: cmp al,08Fh ; SS3 jne vt_disp_C1_n8F jmp vt_C1_SS3 vt_disp_C1_n8F: cmp al,090h ; DCS jne vt_disp_C1_n90 jmp vt_C1_DCS vt_disp_C1_n90: cmp al,09Bh ; CSI jne vt_disp_C1_n9B jmp vt_C1_CSI vt_disp_C1_n9B: cmp al,09Ch ; ST jne vt_disp_C1_n9C jmp vt_C1_ST vt_disp_C1_n9C: jmp vt_disp_ex ;-------------------------------------------- vt_disp_vt52ESC: cmp al,'A' jb vt_disp_vt52ESC_nD cmp al,'D' ja vt_disp_vt52ESC_nD mov WORD PTR P_buf,1 jmp vt_CSI_ABCD vt_disp_vt52ESC_nD: cmp al,'H' jne vt_disp_vt52ESC_nH mov cur_col,0 mov cur_row,0 call locate_cur jmp vt_esc_done vt_disp_vt52ESC_nH: cmp al,'I' jne vt_disp_vt52ESC_nI jmp vt_C1_RI vt_disp_vt52ESC_nI: cmp al,'J' jne vt_disp_vt52ESC_nJ mov WORD PTR P_buf,0 jmp vt_CSI_J vt_disp_vt52ESC_nJ: cmp al,'K' jne vt_disp_vt52ESC_nK mov WORD PTR P_buf,0 jmp vt_CSI_K vt_disp_vt52ESC_nK: cmp al,'Y' jne vt_disp_vt52ESC_nY mov spec_stage,VT52_DCA_L vt_disp_vt52ESC_nY: cmp al,'F' ; enter graphics mode ? jne vt_disp_vt52ESC_nF jmp vt_esc_done vt_disp_vt52ESC_nF: cmp al,'G' ; leave graphics mode ? jne vt_disp_vt52ESC_nG jmp vt_esc_done vt_disp_vt52ESC_nG: cmp al,'W' ; enter printer control mode ? jne vt_disp_vt52ESC_nW jmp vt_esc_done vt_disp_vt52ESC_nW: cmp al,'X' ; leave printer control mode ? jne vt_disp_vt52ESC_nX jmp vt_esc_done vt_disp_vt52ESC_nX: cmp al,'V' ; print cursor line ? jne vt_disp_vt52ESC_nV jmp vt_esc_done vt_disp_vt52ESC_nV: ; ; Non VT52 sequence is interpreted as VT100 sequence. ; add al,040h ; convert to C1 jmp vt_disp_c1 ; vt_disp_vt52ESC_YL: xor ah,ah sub ax,32 mov P_buf,ax mov spec_stage,VT52_DCA_C jmp vt_disp_ex ; vt_disp_vt52ESC_YC: push ax xor ah,ah sub ax,32 mov cur_col,al mov ax,P_buf mov cur_row,al call locate_cur pop ax jmp vt_esc_done ;------------------------------------------------------------------------------ ; ESC sequence analysis ; Note that VT100 allows many C0 characters in ESC-seq. vt_disp_inESC: cmp al,07Eh ; check the allowed range ja vt_disp_inESCe ; error. cmp al,020h ; normal GL character ? jae vt_disp_inESC1 ; ae = yes. ; C0 control character cmp spec_stage,0 ; 1st character in ESC seq.? je vt_disp_inESC0 ; e = Yes. Need check ESC FF. jmp vt_disp_C0 vt_disp_inESC0: cmp al,0Ch ; FF ? je vt_disp_ESC_FF ; e = Yes. Need special treatment. jmp vt_disp_C0 ; ; ESC FF:Enter tektronix mode if tek4010 enabled ; vt_disp_ESC_FF: test vt100_flags,AUTOTEK_BIT ; AutoTek enabled ? jnz vt_disp_ESC_FF_do ; nz = Yes. jmp vt_disp_C0 vt_disp_ESC_FF_do: mov spec_mode,0 ; ESC sequnce done. [25-Jun-1990] mov ah,3 ; pass character in DX mov dh,ESCAPE mov dl,al mov cx,0 ret ;-------------- vt_disp_inESC1: cmp spec_stage,0 ; 1st character in ESC seq.? jne vt_disp_inESC2 ; ne = no, check the sequnce type jmp vt_esc_1 vt_disp_inESC2: cmp spec_stage,1 ; ESC with I sequence ? jne vt_disp_inESC3 jmp vt_esc_2 vt_disp_inESC3: cmp flags.vtflg,ttvt52 jne vt_disp_inESCe ; cmp spec_stage,VT52_DCA_L jne vt_disp_inESC4 jmp vt_disp_VT52ESC_YL vt_disp_inESC4: cmp spec_stage,VT52_DCA_C jne vt_disp_inESCe jmp vt_disp_VT52ESC_YC vt_disp_inESCe: mov spec_mode,0 ; Sequence error. Clear flags and jmp vt_disp_NRM ; treat as normal case. ;-------------------------------- ; 1st byte just after the ESC ; AL is in 2/0 - 7/E vt_esc_1: cmp al,02Fh ja vt_esc_10 ; char is in 3/0 - 7/14, i.e., single mov spec_stage,1 ; set mutibyte flag jmp vt_esc_I ; and goto I-seq. vt_esc_10: cmp al,05Fh ja vt_esc_do_s ; char is in 6/0 - 7/14, i.e., single cmp al,040h jb vt_esc_do_s ; char is in 3/0 - 3/15, i.e., single ; now AL is in 4/0 - 5/15, i.e., C1 except for a few cases cmp al,'Z' ; DECDA ? jne vt_esc_11 jmp vt_CSI_DA vt_esc_11: cmp flags.vtflg,ttvt52 ; vt52 mode ? jne vt_esc_12 ; ne = no. jmp vt_disp_vt52ESC vt_esc_12: add al,040h ; convert to C1 jmp vt_disp_c1 ; display the C1 character ;-------------------------------- ; in multi-byte ESC seq. ; AL is 2/0 - 7/E vt_esc_2: cmp al,02Fh jbe vt_esc_I ; char is in 2/0 - 2/15, i.e., I jmp vt_esc_do_m ; char is in 3/0 - 7/14, i.e., final vt_esc_I: mov bx,offset I_buf add bx,I_pnt mov byte ptr [bx],al inc I_pnt jmp vt_disp_ex ; vt_esc_done: vt_CSI_done: mov spec_mode,0 jmp vt_disp_ex ; ; Found the final character of the ESC sequence ; ; Single-byte ESC seq. ; 3/0 - 3/15 private seq. ; 6/0 - 7/14 standard seq. vt_esc_do_s: cmp al,6Eh jne vt_esc_do_n6E mov char_GL,offset char_G2 jmp vt_esc_done vt_esc_do_n6E: cmp al,6Fh jne vt_esc_do_n6F mov char_GL,offset char_G3 jmp vt_esc_done vt_esc_do_n6F: cmp al,7Ch jne vt_esc_do_n7C mov char_GR,offset char_G3 jmp vt_esc_done vt_esc_do_n7C: cmp al,7Dh jne vt_esc_do_n7D mov char_GR,offset char_G2 jmp vt_esc_done vt_esc_do_n7D: cmp al,7Eh jne vt_esc_do_n7E mov char_GR,offset char_G1 jmp vt_esc_done vt_esc_do_n7E: cmp al,63h ; ESC c jne vt_esc_do_n63 call vt100_reset jmp vt_esc_done vt_esc_do_n63: cmp al,3Dh ; ESC = jne vt_esc_do_n3D mov keypad_mode,1 jmp vt_esc_done vt_esc_do_n3D: cmp al,3Eh ; ESC > jne vt_esc_do_n3E mov keypad_mode,0 jmp vt_esc_done vt_esc_do_n3E: cmp al,37h ; ESC 7 jne vt_esc_do_n37 call save_cursor jmp vt_esc_done vt_esc_do_n37: cmp al,38h ; ESC 8 jne vt_esc_do_n38 call restore_cursor jmp vt_esc_done vt_esc_do_n38: cmp al,3Ch ; ESC < VT52 -> ANSI mode ? jne vt_esc_do_n3C mov flags.vtflg,ttvt100 call set_termnam call vt100_modlin jmp vt_esc_done vt_esc_do_n3C: jmp vt_esc_done ; ; Multi-byte ESC seq. ; 3/0 - 3/15 Private seq. ; 4/0 - 7/14 Standard seq. vt_esc_do_m: vt_esc_do32: mov bx,offset I_buf mov ah,byte ptr [bx] cmp ah,24h ; multibyte designation code ? jne vt_esc_do34 jmp vt_desig_m vt_esc_do34: cmp ah,28h ; singlebyte desig. code (2/8-2/15)? jb vt_esc_do36 ; b = no. cmp ah,2Fh ; ja vt_esc_do36 ; a = no. jmp vt_desig_s vt_esc_do36: cmp al,'0' ; Possible Select Tek mode ? jne vt_esc_do37 ; ne = no cmp I_pnt,2 jne vt_esc_do37 cmp ah,'%' ; Tek4105 Select code 1st byte ? jne vt_esc_do37 ; ne = no inc bx ; next int. char. mov ah,byte ptr [bx] cmp ah,'!' ; Tek4105 Select code 2nd byte ? jne vt_esc_do37 mov vt100_gflag,5 ; Tek41xx screen color mov ah,1 ; enter Tek mode mov cx,0 mov spec_mode,0 ; clear ESC/CSI seq. ret vt_esc_do37: jmp vt_esc_done ; unknown ;------------------------------------- ; designate single byte character set ; vt_desig_s: and ah,3 mov bx,offset char_G0 add bl,ah mov ah,CSET_JISROMAN cmp al,49h jne vt_desig_s1 mov ah,CSET_JISKATAKANA jmp vt_desig_s2 vt_desig_s1: cmp al,30h jne vt_desig_s2 mov ah,CSET_DECGRAPH vt_desig_s2: mov byte ptr [bx],ah jmp vt_esc_done ; ; designate multi-byte character set. ; vt_desig_m: mov ah,0 cmp I_pnt,1 jbe vt_desig_m1 add bx,1 mov ah,byte ptr [bx] and ah,3 vt_desig_m1: mov bx,offset char_G0 add bl,ah mov ah,CSET_JISC6226 mov byte ptr [bx],ah jmp vt_esc_done ;---------------------------------------------------- ; Control seuence analysis ; Note that VT100 allows C0 characters in CSI seq. vt_disp_inCSI: cmp al,07Eh ; check the range ja vt_disp_inCSIe ; error. cmp al,020h ; C0 character ? jae vt_disp_inCSI1 ; ae = no. It is GL. jmp vt_disp_C0 vt_disp_inCSI1: cmp spec_stage,0 ; 1st character in CSI ? jne vt_disp_inCSI2 ; ne = No. jmp vt_CSI_1 ; CSI with Parameters vt_disp_inCSI2: cmp spec_stage,1 ; in intermediates ? jne vt_disp_inCSI3 jmp vt_CSI_2 ; CSI with Intermediates vt_disp_inCSI3: vt_disp_inCSIe: mov spec_mode,0 ; clear flags and treat as normal jmp vt_disp_NRM ; vt_disp_inCSIx: mov spec_mode,0 jmp vt_disp_ex ;----------------------------------------------------- ; DCS analysis ;----------------------------------------------------- vt_disp_inDCS: cmp al,07Fh ; check the range jae vt_disp_inDCSe ; sequence error. cmp al,08h jb vt_disp_inDCSe cmp al,0Dh jbe vt_disp_inDCS1 cmp al,020h jb vt_disp_inDCSe vt_disp_inDCS1: cmp spec_stage,IN_SIXEL jne vt_disp_inDCS2 call sixel jmp vt_disp_ex vt_disp_inDCS2: jmp vt_DCS_1 vt_disp_inDCSe: mov spec_mode,0 ; sequence error. jmp vt_disp_NRM ;-------------------------- vt_DCS_do: cmp al,'q' ; sixel ? jne vt_DCS_do_nq mov spec_stage,IN_SIXEL call sixel_in mov vt100_gflag,2 mov sixel_disp_on,1 vt_DCS_do_nq: jmp vt_disp_ex ;---------------------------------------------------------- ; CSI & DCS sequence analysys ;---------------------------------------------------------- vt_DCS_1: vt_CSI_1: cmp al,030h ; Parameter (3/0-3/15) ? jb vt_CSI_2 cmp al,03Fh jbe vt_CSI_Para mov spec_stage,1 vt_CSI_2: cmp al,020h ; Intermediate (2/0-2/15) ? jb vt_CSI_3 cmp al,02Fh jbe vt_CSI_Intr cmp al,040h ; Terminator (4/0-7/14) ? jb vt_CSI_3 cmp spec_mode,IN_CSI_MODE jne vt_CSI_2_1 jmp vt_CSI_do vt_CSI_2_1: jmp vt_DCS_do vt_CSI_3: jmp vt_CSI_done ; ; Parameter (3/0-3/15) ; vt_CSI_Para: cmp al,03ah jae vt_CSI_Para1 mov bx,offset P_buf add bx,P_pnt mov cx,[bx] ; cx = previous value and cx,7FFFh ; mask private parameter flag mov dx,cx shl dx,1 shl dx,1 add dx,cx ; dx = cx*5 shl dx,1 ; dx = (previous value)*10 xor ah,ah sub ax,030h add ax,dx ; ax is (previous value)*10 + new or ax,priv_pflg ; set private parameter flag mov [bx],ax ; save it jmp vt_disp_ex vt_CSI_Para1: cmp al,'?' ; Private parameter ? (3/15) jne vt_CSI_Para11 mov priv_pflg,PRIVP_FLG jmp vt_disp_ex vt_CSI_Para11: add P_pnt,2 ; separator mov bx,offset P_buf add bx,P_pnt mov word ptr [bx],0 ; clear for next parameter jmp vt_disp_ex ; ; Intermediate (2/0-2/15) ; vt_CSI_Intr: mov bx,offset I_buf add bx,I_pnt mov byte ptr [bx],al inc I_pnt jmp vt_disp_ex ;------------------------ ; Do the control sequence ;------------------------ vt_CSI_do: cmp al,'K' jne vt_CSI_do_10 jmp vt_CSI_K vt_CSI_do_10: cmp al,'J' jne vt_CSI_do_20 jmp vt_CSI_J vt_CSI_do_20: cmp al,'H' jne vt_CSI_do_25 jmp vt_CSI_H vt_CSI_do_25: cmp al,'f' jne vt_CSI_do_30 jmp vt_CSI_H vt_CSI_do_30: cmp al,'A' jb vt_CSI_do_40 cmp al,'D' ja vt_CSI_do_40 jmp vt_CSI_ABCD vt_CSI_do_40: cmp al,'r' jne vt_CSI_do_50 jmp vt_CSI_SCR vt_CSI_do_50: cmp al,'L' jne vt_CSI_do_60 jmp vt_CSI_L vt_CSI_do_60: cmp al,'M' jne vt_CSI_do_70 jmp vt_CSI_M vt_CSI_do_70: cmp al,'m' jne vt_CSI_do_80 jmp vt_CSI_CATR vt_CSI_do_80: cmp al,'c' jne vt_CSI_do_90 jmp vt_CSI_DA vt_CSI_do_90: cmp al,'h' jne vt_CSI_do_100 jmp vt_CSI_SET_M vt_CSI_do_100: cmp al,'l' jne vt_CSI_do_110 jmp vt_CSI_RESET_M vt_CSI_do_110: cmp al,'n' jne vt_CSI_do_120 jmp vt_CSI_DSR vt_CSI_do_120: cmp al,'q' jne vt_CSI_do_130 jmp vt_CSI_LED vt_CSI_do_130: cmp al,'P' jne vt_CSI_do_140 jmp vt_CSI_DCH vt_CSI_do_140: cmp al,'@' jne vt_CSI_do_150 jmp vt_CSI_ICH vt_CSI_do_150: cmp al,'X' jne vt_CSI_do_160 jmp vt_CSI_ECH vt_CSI_do_160: cmp al,'g' jne vt_CSI_do_170 jmp vt_CSI_TBC vt_CSI_do_170: cmp al,'i' jne vt_CSI_do_180 jmp vt_CSI_PRN vt_CSI_do_180: cmp al,'}' jne vt_CSI_do_190 jmp vt_CSI_DECSASD vt_CSI_do_190: cmp al,'~' jne vt_CSI_do_200 jmp vt_CSI_DECSSDT vt_CSI_do_200: vt_CSI_do_ex: jmp vt_CSI_done ; vt_CSI_DA: ; Device attributes mov si,offset I_am_vt52 cmp flags.vtflg,ttvt52 je vt_CSI_DA_1 mov si,offset I_am_vt102 vt_CSI_DA_1: xor cx,cx mov cl,[si] inc si mov spec_mode,0 ; done the sequence mov ah,0 ret ; vt_CSI_DSR: ; ; Device status report ; Host to VT VT returns ; CSI 5 n CSI 0 n no mulfunction ; CSI 3 n mulfunction ; ; CSI 6 n CSI Pr;Pc R cursor position is Pr(row) ; Pc (column) ; mov spec_mode,0 ; done the sequence mov si,offset P_buf ; get param. buff address mov bx,[si] ; get parameter value cmp bx,5 je vt_CSI_DSR5 cmp bx,6 je vt_CSI_DSR6 jmp vt_CSI_do_ex ; vt_CSI_DSR5: mov si,offset I_am_fine xor cx,cx mov cl,[si] inc si mov ah,0 ret vt_CSI_DSR6: mov si,offset My_cursor_is add si,2 mov cx,2 ; xor ax,ax mov al,cur_row inc ax cmp ax,100 jb vt_CSI_DSR61 mov bx,100 div bl or al,30h mov byte ptr [si],al inc si inc cx mov al,ah xor ah,ah jmp vt_CSI_DSR62 vt_CSI_DSR61: cmp ax,10 jb vt_CSI_DSR63 vt_CSI_DSR62: mov bx,10 div bl or al,30h mov byte ptr [si],al inc si inc cx mov al,ah xor ah,ah vt_CSI_DSR63: or al,30h mov byte ptr [si],al inc si inc cx ; mov byte ptr [si],';' inc si inc cx ; xor ax,ax mov al,cur_col inc ax cmp ax,100 jb vt_CSI_DSR64 mov bx,100 div bl or al,30h mov byte ptr [si],al inc si inc cx mov al,ah xor ah,ah jmp vt_CSI_DSR65 vt_CSI_DSR64: cmp ax,10 jb vt_CSI_DSR66 vt_CSI_DSR65: mov bx,10 div bl or al,30h mov byte ptr [si],al inc si inc cx mov al,ah xor ah,ah vt_CSI_DSR66: or al,30h mov byte ptr [si],al inc si inc cx ; mov byte ptr [si],'R' inc si inc cx ; mov si,offset My_cursor_is mov ah,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 ; 30-37 Foreground color = 30 + colors (colors: 1=red, 2=green, 4=blue) ; vt_CSI_CATR: push cx push si mov si,offset P_buf mov cx,P_pnt shr cx,1 inc cx vt_CSI_CATR1: mov bx,[si] cmp bx,0 jne vt_CSI_CATR2 push si mov si,offset def_color ; reset to default color call set_cur_color call vt100_color pop si call set_gcolor mov al,vt_nrmatr mov vt_chratr,al jmp vt_CSI_CATRX vt_CSI_CATR2: cmp bx,1 jne vt_CSI_CATR3 mov al,vt_chratr ; Bold and al,01Fh or al,vt_hglatr mov vt_chratr,al jmp vt_CSI_CATRX vt_CSI_CATR3: cmp bx,4 jne vt_CSI_CATR5 or vt_chratr,8 ; Underscored jmp vt_CSI_CATRX vt_CSI_CATR5: cmp bx,5 jne vt_CSI_CATR7 or vt_chratr,2 ; Blinking jmp vt_CSI_CATRX vt_CSI_CATR7: cmp bx,7 jne vt_CSI_CATR22 test vt_nrmatr,CHR_REV jz vt_CSI_CATR7_1 and vt_chratr,(not CHR_REV) jmp vt_CSI_CATRX vt_CSI_CATR7_1: or vt_chratr,CHR_REV jmp vt_CSI_CATRX vt_CSI_CATR22: cmp bx,22 jne vt_CSI_CATR24 jmp vt_CSI_CATRX vt_CSI_CATR24: cmp bx,24 jne vt_CSI_CATR25 and vt_chratr,0F7h ; not Underscored jmp vt_CSI_CATRX vt_CSI_CATR25: cmp bx,25 jne vt_CSI_CATR27 and vt_chratr,0FDh ; not blinking jmp vt_CSI_CATRX vt_CSI_CATR27: cmp bx,27 jne vt_CSI_CATR30 test vt_nrmatr,CHR_REV jz vt_CSI_CATR27_1 or vt_chratr,CHR_REV jmp vt_CSI_CATRX vt_CSI_CATR27_1: and vt_chratr,(not CHR_REV) ; positive image jmp vt_CSI_CATRX vt_CSI_CATR30: cmp bx,30 jb vt_CSI_CATR40 cmp bx,37 ja vt_CSI_CATR40 mov ax,bx sub ax,30 mov bx,offset color_index_table add bx,ax mov al,[bx] push si mov si,offset scn_color mov [si],al call vt100_color ; set color pop si jmp vt_CSI_CATRX vt_CSI_CATR40: cmp bx,40 jb vt_CSI_CATRX cmp bx,47 ja vt_CSI_CATRX mov ax,bx sub ax,40 mov bx,offset color_index_table add bx,ax mov al,[bx] push si mov si,offset scn_color mov [si+1],al call vt100_color pop si call set_gcolor ; vt_CSI_CATRX: add si,2 dec cx jcxz vt_CSI_CATRXX jmp vt_CSI_CATR1 vt_CSI_CATRXX: pop si pop cx jmp vt_CSI_do_ex ; LED control vt_CSI_LED: push cx push si mov si,offset P_buf mov cx,P_pnt shr cx,1 inc cx vt_CSI_LED1: mov bx,[si] cmp bx,0 jb vt_CSI_LEDX jne vt_CSI_LED2 mov ax,'..' mov bx,offset LED_buff mov [bx],ax mov [bx+2],ax jmp vt_CSI_LED3 vt_CSI_LED2: cmp bx,4 ja vt_CSI_LEDX mov ax,bx dec bx add bx,offset LED_buff add al,'0' mov [bx],al vt_CSI_LED3: vt_CSI_LEDX: add si,2 loop vt_CSI_LED1 call set_termnam call vt100_modlin pop si pop cx jmp vt_CSI_do_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 ; ?38 Tektronix graphic mode ; vt_CSI_SET_M: push cx push si mov si,offset P_buf mov cx,P_pnt shr cx,1 inc cx vt_CSI_SET_M0: mov bx,[si] vt_CSI_SET_M4: cmp bx,4 ; 4 = Insert mode ? jne vt_CSI_SET_M5 ; ne = no or vt100_flags,INSERT_BIT jmp vt_CSI_SET_MX vt_CSI_SET_M5: vt_CSI_SET_M20: cmp bx,20 ; 20 = Newline mode ? jne vt_CSI_SET_M21 ; ne = no or vt100_flags,NEWLINE_BIT jmp vt_CSI_SET_MX vt_CSI_SET_M21: ; ; Private sequence ; vt_CSI_SET_MP1: cmp bx,1+PRIVP_FLG ; ?1 = Cursor key application ? jne vt_CSI_SET_MP2 ; ne = no mov curkey_mode,1 jmp vt_CSI_SET_MX vt_CSI_SET_MP2: vt_CSI_SET_MP3: cmp bx,3+PRIVP_FLG ; ?3 = 132 Column ? jne vt_CSI_SET_MP4 jmp vt_CSI_SET_MX vt_CSI_SET_MP4: vt_CSI_SET_MP5: cmp bx,5+PRIVP_FLG ; ?5 = reverse screen ? jne vt_CSI_SET_MP6 mov ax,1 call scrn_mode jmp vt_CSI_SET_MX vt_CSI_SET_MP6: cmp bx,6+PRIVP_FLG ; ?6 = Origin relative mode ? jne vt_CSI_SET_MP7 or vt100_flags,ORIGIN_BIT mov al,vt_top mov cur_row,al mov cur_col,0 call locate_cur jmp vt_CSI_SET_MX vt_CSI_SET_MP7: cmp bx,7+PRIVP_FLG ; ?7 = AutoWrap ? jne vt_CSI_SET_MP8 or vt100_flags,AUTOWRAP_BIT jmp vt_CSI_SET_MX vt_CSI_SET_MP8: cmp bx,18+PRIVP_FLG ; ?18 = Print form feed jne vt_CSI_SET_MP19 or vt100_pflag,PRINTFF_BIT jmp vt_CSI_SET_MX vt_CSI_SET_MP19: cmp bx,19+PRIVP_FLG ; ?19 = Print Extent jne vt_CSI_SET_MP20 or vt100_pflag,PRINTEXT_BIT jmp vt_CSI_SET_MX vt_CSI_SET_MP20: vt_CSI_SET_MP38: cmp bx,38+PRIVP_FLG ; ?38 = Tektronix mode jne vt_CSI_SET_MP39 pop si pop cx mov spec_mode,0 ; done the sequence. mov vt100_gflag,4 ; Tek40xx color mov ah,1 ; do not pass the character mov al,0 mov cx,0 ret vt_CSI_SET_MP39: vt_CSI_SET_MX: add si,2 dec cx jcxz vt_CSI_SET_MX0 jmp vt_CSI_SET_M0 vt_CSI_SET_MX0: pop si pop cx jmp vt_CSI_do_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_CSI_RESET_M: push cx push si mov si,offset P_buf mov cx,P_pnt shr cx,1 inc cx vt_CSI_RESET_M0: mov bx,[si] vt_CSI_RESET_M4: cmp bx,4 ; 4 = Replace mode ? jne vt_CSI_RESET_M5 ; ne = no. and vt100_flags,(not INSERT_BIT) jmp vt_CSI_RESET_MX vt_CSI_RESET_M5: vt_CSI_RESET_M20: cmp bx,20 ; 20 = Linefeed mode ? jne vt_CSI_RESET_M21 ; ne = no. and vt100_flags,(not NEWLINE_BIT) jmp vt_CSI_RESET_MX vt_CSI_RESET_M21: ; ; Private sequence ; vt_CSI_RESET_MP1: cmp bx,1+PRIVP_FLG ; ?1 = Normal cursor key ? jne vt_CSI_RESET_MP2 mov curkey_mode,0 jmp vt_CSI_RESET_MX vt_CSI_RESET_MP2: cmp bx,2+PRIVP_FLG ; ?2 = Enter VT52 mode ? jne vt_CSI_RESET_MP3 mov flags.vtflg,ttvt52 call set_termnam ; set terminal name call vt100_modlin ; re-display mode line jmp vt_CSI_RESET_MX vt_CSI_RESET_MP3: vt_CSI_RESET_MP5: cmp bx,5+PRIVP_FLG ; ?5 = normal screen ? jne vt_CSI_RESET_MP6 mov ax,0 call scrn_mode jmp vt_CSI_RESET_MX vt_CSI_RESET_MP6: cmp bx,6+PRIVP_FLG ; ?6 = Origin absolute mode ? jne vt_CSI_RESET_MP7 and vt100_flags,(not ORIGIN_BIT) mov cur_row,0 mov cur_col,0 call locate_cur jmp vt_CSI_RESET_MX vt_CSI_RESET_MP7: cmp bx,7+PRIVP_FLG jne vt_CSI_RESET_MP8 and vt100_flags,(not AUTOWRAP_BIT) jmp vt_CSI_RESET_MX vt_CSI_RESET_MP8: cmp bx,18+PRIVP_FLG jne vt_CSI_RESET_MP19 and vt100_pflag,(not PRINTFF_BIT) jmp vt_CSI_RESET_MX vt_CSI_RESET_MP19: cmp bx,19+PRIVP_FLG jne vt_CSI_RESET_MP20 and vt100_pflag,(not PRINTEXT_BIT) jmp vt_CSI_RESET_MX vt_CSI_RESET_MP20: vt_CSI_RESET_MX: add si,2 dec cx jcxz vt_CSI_RESET_MX0 jmp vt_CSI_RESET_M0 vt_CSI_RESET_MX0: pop si pop cx jmp vt_CSI_do_ex ; vt_CSI_ABCD: mov bx,offset P_buf mov bx,[bx] cmp bx,1 jae vt_CSI_ABCD1 mov bx,1 vt_CSI_ABCD1: cmp al,'B' je vt_CSI_CUD cmp al,'C' je vt_CSI_CUR cmp al,'D' je vt_CSI_CUL vt_CSI_CUU: xor ah,ah mov al,cur_row sub ax,bx xor bh,bh mov bl,vt_top cmp ax,bx jge vt_CSI_CUU1 mov ax,bx vt_CSI_CUU1: mov cur_row,al jmp vt_CSI_ABCD_ex vt_CSI_CUD: xor ah,ah mov al,cur_row add ax,bx cmp al,vt_bottom jle vt_CSI_CUD1 mov al,vt_bottom vt_CSI_CUD1: mov cur_row,al jmp vt_CSI_ABCD_ex vt_CSI_CUR: xor ah,ah mov al,cur_col add ax,bx cmp ax,79 jle vt_CSI_CUR1 mov ax,79 vt_CSI_CUR1: mov cur_col,al jmp vt_CSI_ABCD_ex vt_CSI_CUL: xor ah,ah mov al,cur_col sub ax,bx cmp ax,0 jge vt_CSI_CUL1 mov ax,0 vt_CSI_CUL1: mov cur_col,al vt_CSI_ABCD_ex: call locate_cur jmp vt_CSI_do_ex ; vt_CSI_K: mov bx,offset P_buf mov ax,[bx] cmp ax,0 jne vt_CSI_K1 mov dh,cur_row mov dl,cur_col call vram_ofs mov ax,bx mov dh,cur_row mov dl,79 jmp vt_CSI_KX vt_CSI_K1: cmp ax,1 jne vt_CSI_K2 mov dh,cur_row mov dl,0 call vram_ofs mov ax,bx mov dh,cur_row mov dl,cur_col jmp vt_CSI_KX vt_CSI_K2: cmp ax,2 jne vt_CSI_K3 mov dh,cur_row mov dl,0 call vram_ofs mov ax,bx mov dh,cur_row mov dl,79 jmp vt_CSI_KX vt_CSI_K3: jmp vt_CSI_do_ex vt_CSI_KX: call vram_ofs call vt_erase jmp vt_CSI_do_ex ; vt_CSI_L: mov al,cur_row cmp al,vt_top jge vt_CSI_L01 jmp vt_CSI_do_ex vt_CSI_L01: cmp al,vt_bottom jle vt_CSI_L02 jmp vt_CSI_do_ex vt_CSI_L02: mov bx,offset P_buf mov cx,[bx] cmp cx,0 jg vt_CSI_L1 mov cx,1 vt_CSI_L1: mov ah,vt_bottom call scroll_down mov cur_col,0 call locate_cur jmp vt_CSI_do_ex vt_CSI_M: mov al,cur_row cmp al,vt_top jge vt_CSI_M01 jmp vt_CSI_do_ex vt_CSI_M01: cmp al,vt_bottom jle vt_CSI_M02 jmp vt_CSI_do_ex vt_CSI_M02: mov bx,offset P_buf mov cx,[bx] cmp cx,0 jg vt_CSI_M1 mov cx,1 vt_CSI_M1: mov ah,vt_bottom call scroll_up mov cur_col,0 call locate_cur jmp vt_CSI_do_ex vt_CSI_J: mov bx,offset P_buf mov ax,[bx] cmp ax,0 jg vt_CSI_J1 mov dh,cur_row mov dl,cur_col call vram_ofs mov ax,bx mov dh,vt_phys_bottom mov dl,79 call vram_ofs jmp vt_CSI_JX vt_CSI_J1: cmp ax,1 jg vt_CSI_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_CSI_JX vt_CSI_J2: cmp sixel_disp_on,1 jne vt_CSI_J2_1 call sixel_clear mov vt100_gflag,1 mov sixel_disp_on,0 vt_CSI_J2_1: mov dh,0 mov dl,0 call vram_ofs mov ax,bx mov dh,vt_phys_bottom mov dl,79 call vram_ofs vt_CSI_JX: call vt_erase jmp vt_CSI_do_ex ; ; Cursor Position CUP CSI Pl ; Pc H ; vt_CSI_H: mov bx,offset P_buf mov ax,[bx] cmp ax,1 jae vt_CSI_H1 mov ax,1 vt_CSI_H1: test vt100_flags,ORIGIN_BIT ; relative mode ? jz vt_CSI_H2 ; z = no. add al,vt_top ; convert to absolute cmp al,vt_bottom jbe vt_CSI_H3 mov al,vt_bottom jmp vt_CSI_H31 vt_CSI_H2: cmp ax,24 jbe vt_CSI_H3 mov ax,24 vt_CSI_H3: dec ax vt_CSI_H31: mov cur_row,al xor ax,ax cmp P_pnt,2 jb vt_CSI_H6 mov ax,[bx+2] cmp ax,1 jae vt_CSI_H4 mov ax,1 vt_CSI_H4: cmp ax,80 jbe vt_CSI_H5 mov ax,80 vt_CSI_H5: dec ax vt_CSI_H6: mov cur_col,al ; ; put the CR/LF for the cooked log. ; cmp vt100_lflag,(LOGCOOK_BIT+LOGENAB_BIT) jne vt_CSI_H61 ;@@ cmp al,0 ;@@ jne vt_CSI_H61 mov al,0Dh ; put CR call outcapt mov al,0Ah ; put LF call outcapt vt_CSI_H61: ; call locate_cur jmp vt_CSI_do_ex ; ; Chracter editing functions ; CSI Pn @ ICH Inserts Pn blank characters ; CSI Pn P DCH Deletes Pn characters ; CSI Pn X ECH Erases Pn characters ; In each function, action starts from current cursor position ; and the cursor does not move. ; ; Insert characters (ICH) -- CSI Pn @ vt_CSI_ICH: vt_CSI_ICH1: mov bx,offset P_buf ; get the address of the parameter mov cx,[bx] ; get the parameter value cmp cx,0 jg vt_CSI_ICH2 mov cx,1 ; use default vt_CSI_ICH2: std ; backward direction mov dl,79 ; set destination (row,col) mov dh,cur_row call vram_ofs mov di,bx ; set destination address xor ax,ax mov al,cur_col mov bx,ax ; save column position add ax,cx ; ax = cur_col + Pn cmp ax,79 ; inside the right margin ? jle vt_CSI_ICH3 ; le = Yes. mov cx,80 sub cx,bx ; cx = 80 - cur_col jmp vt_CSI_ICH4 vt_CSI_ICH3: push cx ; save Pn mov dx,79 sub dx,cx ; dx = 79 - Pn mov dh,cur_row call vram_ofs ; get VRAM offset address mov si,bx ; set source address mov cx,80 sub cx,ax ; cx = 80 - cur_col - Pn mov ax,CRT_TXT_SEG push es ; save segment registers push ds mov es,ax ; set segment registers mov ds,ax push si push di push cx rep movsw ; move the characters pop cx pop di pop si add di,2000h ; attribute area add si,2000h rep movsw ; move the attributes sub di,2000h pop ds pop es pop cx ; restore Pn vt_CSI_ICH4: push es push cx push di mov ax,CRT_TXT_SEG mov es,ax mov ax,20h ; set blank code rep stosw pop di pop cx add di,2000h ; attribute area mov al,vt_nrmatr ; set normal attributes rep stosw pop es cld ; reset direction flag jmp vt_CSI_do_ex ; Delete characters (DCH) -- CSI Pn P vt_CSI_DCH: vt_CSI_DCH1: mov bx,offset P_buf ; get the address of the parameter mov cx,[bx] ; get the parameter value cmp cx,0 jg vt_CSI_DCH2 mov cx,1 ; use default vt_CSI_DCH2: cld xor ax,ax mov al,cur_col mov dh,cur_row mov dl,cur_col call vram_ofs ; get the destination address mov di,bx ; set the destination address mov bx,ax ; save column position add ax,cx ; ax = cur_col + Pn cmp ax,79 ; inside the right margin ? jle vt_CSI_DCH3 ; le = Yes. mov cx,80 sub cx,bx ; cx = 80 - cur_col jmp vt_CSI_DCH4 vt_CSI_DCH3: push cx mov cx,80 sub cx,ax ; cx = 80 - cur_col - Pn mov dh,cur_row ; set curosr pointer mov dl,al call vram_ofs ; get VRAM offset address mov si,bx ; set the source address mov ax,CRT_TXT_SEG push es ; save segment registers push ds mov es,ax ; set segment registers mov ds,ax push si push di push cx rep movsw ; move the characters pop cx pop di pop si add di,2000h add si,2000h rep movsw ; move the attributes sub di,2000h pop ds pop es pop cx vt_CSI_DCH4: push es push cx push di mov ax,CRT_TXT_SEG mov es,ax mov ax,20h ; set blank code rep stosw pop di pop cx add di,2000h mov al,vt_blkatr ; set blank attributes rep stosw pop es jmp vt_CSI_do_ex ; Erase characters (ECH) -- CSI Pn X vt_CSI_ECH: vt_CSI_ECH1: mov bx,offset P_buf ; get the address of the parameter mov cx,[bx] ; get the parameter value cmp cx,0 jg vt_CSI_ECH2 mov cx,1 ; use default vt_CSI_ECH2: cld xor ax,ax mov al,cur_col mov dh,cur_row mov dl,cur_col call vram_ofs ; get the destination address mov di,bx ; set the destination address mov bx,ax ; save column position add ax,cx ; ax = cur_col + Pn cmp ax,79 ; inside the right margin ? jle vt_CSI_ECH3 ; le = Yes. mov cx,80 sub cx,bx ; cx = 80 - cur_col vt_CSI_ECH3: push es push cx push di mov ax,CRT_TXT_SEG mov es,ax mov ax,20h ; set blank code rep stosw pop di pop cx add di,2000h mov al,vt_nrmatr ; set normal attributes rep stosw pop es jmp vt_CSI_do_ex ; Tabulation Clear (TBC) ; CSI g ; CSI 0 g Clears a horizontal tab stop at cursor position ; CSI 3 g Clears all horizontal tab stops vt_CSI_TBC: mov bx,offset P_buf mov ax,[bx] ; get the parameter value cmp ax,0 ; zero ? je vt_CSI_TBC0 ; e = yes. cmp ax,3 ; 3 ? je vt_CSI_TBC3 ; e = yes. jmp vt_CSI_do_ex ; not supported ; vt_CSI_TBC0: xor ax,ax mov al,cur_col ; get current cursor position mov bx,offset tabstops add bx,ax mov byte ptr [bx],0 ; clear the tab jmp vt_CSI_do_ex ; vt_CSI_TBC3: push es push di mov ax,ds mov es,ax ; set destination segment mov di,offset tabstops ; set destination offset mov cx,80 ; number of bytes mov ax,0 ; data = 0 cld rep stosb ; store it pop di pop es jmp vt_CSI_do_ex ; Printer control ; * not implemented yet ; CSI i Prints the screen (full/scroll region) display. ; CSI 0 i Same as above. ; * CSI 4 i Turns off printer controller mode. ; * CSI 5 i Turns on printer controller mode (transparent printing). ; CSI ? 1 i Prints the display line containing the cursor. ; CSI ? 4 i Turns off auto print mode. ; CSI ? 5 i Turns on auto print mode. ; vt_CSI_PRN: mov bx,offset P_buf mov ax,[bx] ; get the parameter value cmp ax,0 ; 0 je vt_CSI_PRN_S0 ; e = yes. cmp ax,1+PRIVP_FLG ; ?1 je vt_CSI_PRN_P1 ; e = yes. cmp ax,4+PRIVP_FLG ; ?4 je vt_CSI_PRN_P4 ; e = yes. cmp ax,5+PRIVP_FLG ; ?5 ? je vt_CSI_PRN_P5 ; e = yes. jmp vt_CSI_do_ex ; not supported ; vt_CSI_PRN_S0: call vt100_prns jmp vt_CSI_do_ex ; vt_CSI_PRN_P1: test vt100_pflag,AUTOPRINT_BIT ; printer off? jnz vt_CSI_PRN_P1_1 ; nz = no not. it is on. call prn_chk ; check the printer port jc vt_CSI_PRN_P1_2 ; c = not ready. vt_CSI_PRN_P1_1: call vt100_prnl vt_CSI_PRN_P1_2: jmp vt_CSI_do_ex ; vt_CSI_PRN_P4: and vt100_pflag,(not AUTOPRINT_BIT) ; turns off the printer call set_prnstat ; show printer status call vt100_modlin ; re-display mode line jmp vt_CSI_do_ex ; vt_CSI_PRN_P5: test vt100_pflag,AUTOPRINT_BIT ; printer off? jnz vt_CSI_PRN_P5_1 ; nz = no not. do nothing. call prn_chk ; check the printer port jc vt_CSI_PRN_P5_1 ; c = not ready. or vt100_pflag,AUTOPRINT_BIT ; turns on auto print call set_prnstat ; show printer status call vt100_modlin ; re-display mode line vt_CSI_PRN_P5_1: jmp vt_CSI_do_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 [1;1H ). ; - The above statement was wrong. In ORIGIN mode, the cursor goes to ; left-top corner of the scroll region. Thanx for VTTEST. [01-Oct-88]. ; - Bugs for funny scroll region are fixed. Thanx for VTTEST. [01-Oct-88]. ; - Bug for ESC[;r is fixed. [03-Dec-88]. vt_CSI_SCR: mov bx,offset P_buf cmp P_pnt,2 ; have good number of parameters ? je vt_CSI_SCR1 ; e = yes. ja vt_CSI_SCR7 ; a = too many. Ignore. [03-Dec-88]. mov ax,[bx] mov bx,24 ; set to default jmp vt_CSI_SCR2 vt_CSI_SCR1: mov ax,[bx] mov bx,[bx+2] vt_CSI_SCR2: cmp ax,1 jae vt_CSI_SCR3 mov ax,1 vt_CSI_SCR3: cmp bx,0 ; Pb = 0? [03-Dec-88] ja vt_CSI_SCR31 ; a = no. [03-Dec-88] mov bx,24 ; set to default. [03-Dec-88]. jmp vt_CSI_SCR4 ; [03-Dec-88]. vt_CSI_SCR31: ; [03-Dec-88]. cmp bx,24 jbe vt_CSI_SCR4 mov bx,24 vt_CSI_SCR4: cmp ax,bx ; Pt < Pb ? jae vt_CSI_SCR7 ; ae = no. Do nothing. vt_CSI_SCR5: dec ax dec bx mov vt_top,al mov vt_bottom,bl test vt100_flags,ORIGIN_BIT ; origin relative mode ? jnz vt_CSI_SCR6 ; nz = Yes. Use vt_top. mov ax,0 vt_CSI_SCR6: mov cur_row,al mov cur_col,0 call locate_cur vt_CSI_SCR7: jmp vt_CSI_do_ex ; vt_CSI_DECSASD: cmp I_pnt,1 ; requires 1 intermediate char. je vt_CSI_DECSASD_1 ; e=yes, we have. jmp vt_CSI_do_ex vt_CSI_DECSASD_1: cmp I_buf,'$' ; required character ? je vt_CSI_DECSASD_2 ; e=yes, we have. jmp vt_CSI_do_ex vt_CSI_DECSASD_2: mov ax,P_buf ; P_buf always has at least 0. cmp ax,0 je vt_CSI_DECSASD_3 jmp vt_CSI_DECSASD_5 ; vt_CSI_DECSASD_3: cmp vt_in_stat,0 ; already in main screen ? jne vt_CSI_DECSASD_4 jmp vt_CSI_do_ex vt_CSI_DECSASD_4: mov vt_in_stat,0 mov al,cur_row mov stat_row,al mov al,cur_col mov stat_col,al mov al,text_row mov cur_row,al mov al,text_col mov cur_col,al mov al,text_top mov vt_top,al mov al,text_bottom mov vt_bottom,al call locate_cur jmp vt_CSI_do_ex ; vt_CSI_DECSASD_5: cmp vt_in_stat,1 ; already in status line ? jne vt_CSI_DECSASD_6 jmp vt_CSI_do_ex vt_CSI_DECSASD_6: cmp vt_stat_type,2 ; host writable status line ? je vt_CSI_DECSASD_7 ; e=yes. jmp vt_CSI_do_ex vt_CSI_DECSASD_7: mov vt_in_stat,1 mov al,cur_row mov text_row,al mov al,cur_col mov text_col,al mov al,vt_top mov text_top,al mov al,vt_bottom mov text_bottom,al ; mov al,stat_col mov cur_col,al mov al,stat_row mov cur_row,al mov vt_top,al mov vt_bottom,al call locate_cur jmp vt_CSI_do_ex ; vt_CSI_DECSSDT: cmp I_pnt,1 ; requires 1 intermediate char. je vt_CSI_DECSSDT_1 ; e=yes, we have. jmp vt_CSI_do_ex vt_CSI_DECSSDT_1: cmp I_buf,'$' ; required character ? je vt_CSI_DECSSDT_2 ; e=yes, we have. jmp vt_CSI_do_ex vt_CSI_DECSSDT_2: mov ax,P_buf ; P_buf always has at least 1 param. cmp ax,2 ; allowed parameter? jbe vt_CSI_DECSSDT_3 ; be=yes. jmp vt_CSI_do_ex vt_CSI_DECSSDT_3: cmp al,vt_stat_type ; same type? jne vt_CSI_DECSSDT_4 ; ne=no. jmp vt_CSI_do_ex vt_CSI_DECSSDT_4: cmp ax,2 ; host writable ? jne vt_CSI_DECSSDT_5 ; ne=no. push ax mov al,vt_blkatr call vt_stat_clr ; clear status line pop ax mov stat_col,0 ; cursor move to left margin vt_CSI_DECSSDT_5: mov vt_stat_type,al call vt100_modlin jmp vt_CSI_do_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: cmp al,0 jne scroll_up_1 call mrsave ; save into roll buffer scroll_up_1: 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-vt_phys_bottom) ; 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 ;----------------------------- ; Single shift 2 (8/14); ESC N ;----------------------------- ; Temporarily invokes G2 character set into GL for the next graphic ; character. vt_c1_SS2: mov char_SS,offset char_G2 jmp vt_esc_done ;----------------------------- ; Single shift 3 (8/15); ESC O ;----------------------------- ; Temporarily invokes G3 character set into GL for the next graphic ; character. vt_c1_SS3: mov char_SS,offset char_G3 jmp vt_esc_done ;---------------------- ; 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 je vt_c1_RI_2 ; [04-Aug-1989] cmp al,0 ; [04-Aug-1989] jg vt_c1_RI_1 ; [04-Aug-1989] jmp vt_esc_done ; [04-Aug-1989] 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 cmp ah,vt_phys_bottom ; [04-Aug-1989] jl vt_c1_NEL_1 ; [04-Aug-1989] 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 ;---------------------------------- ; Horizontal tab set (8/08); ESC H ;---------------------------------- vt_c1_HTS: xor ax,ax mov al,cur_col mov bx,offset tabstops add bx,ax ; tab pointer mov byte ptr [bx],1 jmp vt_esc_done ; ;------------------------------------------- ; Device Control String (9/0); ESC P ;------------------------------------------- vt_c1_DCS: mov spec_mode,in_DCS_MODE mov P_pnt,0 mov bx,offset P_buf mov word ptr [bx],0 mov I_pnt,0 mov bx,offset I_buf mov byte ptr [bx],0 mov priv_pflg,0 jmp vt_disp_ex ; ;------------------------------------------- ; Control Sequence Introducer (9/11); ESC [ ;------------------------------------------- vt_c1_CSI: mov spec_mode,in_CSI_MODE mov P_pnt,0 mov bx,offset P_buf mov word ptr [bx],0 mov I_pnt,0 mov bx,offset I_buf mov byte ptr [bx],0 mov priv_pflg,0 jmp vt_disp_ex ; ;------------------------------------------- ; String Terminator (9/12); ESC \ ;------------------------------------------- vt_c1_ST: mov spec_mode,0 jmp vt_disp_ex ; VT100 ENDP code ends end