X-Authentication-Warning: delorie.com: mail set sender to opendos-bounces using -f Date: Thu, 4 Dec 2003 09:56:42 -0500 Message-Id: <200312041456.hB4EugkR014652@envy.delorie.com> From: DJ Delorie To: opendos AT delorie DOT com In-reply-to: <3FCE4C60.20586.3407B89@localhost> (shadow@shadowgard.com) Subject: Re: ANSI.SYS References: <3FCE1EC1 DOT 3772 DOT 294B30C AT localhost> (shadow AT shadowgard DOT com) <3FCE4C60 DOT 20586 DOT 3407B89 AT localhost> Reply-To: opendos AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: opendos AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk > > I used to have a VT52.SYS driver too... > > > > Oh wait, I still do :-) > > Can I have a copy? I make no guarantees about how well it works on modern computers... title VT-52 ; Copyright 1989 DJ Delorie .286c check_ega equ 1 dqq struc ofs dw ? seg dw ? dqq ends wqq struc w dw ? wqq ends bqq struc b db ? bqq ends rqq struc len db ? unit db ? code db ? status dw ? q1 dd ? q2 dd ? single db ? ; single byte read (no wait) trans dd ? count dw ? rqq ends cesc struc db ? dw ? cesc ends cocall macro which call [which] pop [which] endm cseg segment byte assume cs:cseg,ds:nothing,es:nothing,ss:nothing org 0 success equ 0100h busy equ 0200h header label near dd -1 dw 8003h ; replaces stdin and stdout dw strat dw intr db 'VT52$ ' req dd ? dw 200 dup (?) stack label word strat proc far mov cs:[req].ofs,bx mov cs:[req].seg,es ret strat endp intr proc far sti push ds push es push ax push bx push cx push dx push di push si mov ax,cs mov ds,ax les bx,req mov si,offset cmd_table mov cl,es:[bx].code mov ch,0 shl cx,1 add si,cx call [si].w les bx,req mov es:[bx].status,ax pop si pop di pop dx pop cx pop bx pop ax pop es pop ds ret cmd_table: dw cmd_init ; init dw cmd_none ; media check dw cmd_none ; bpb dw cmd_none ; ioctl input dw cmd_input ; input dw cmd_input_now ; nondestructive input no wait dw cmd_input_stat ; input status dw cmd_input_flush ; input flush dw cmd_output ; output dw cmd_output ; output with verify dw cmd_output_stat ; output status dw cmd_none ; output flush dw cmd_none ; ioctl output dw 10 dup(cmd_none) intr endp cmd_none proc near mov ax,success ret cmd_none endp ;============================================================================ old_int10 dd ? fgc db ? bgc db ? has_ega db ? ; 1=EGA, 0=other getc dw ? ; for cocalls int10: cmp ah,14 je fnct_14 cmp ax,0003h ; mode select je fnct_3 ; cmp ah,1 ; cursor type set ; je fnct_1 cmp ah,0 ; other mode set je mode_0 jmp cs:[old_int10] mode_0: pushf call cs:[old_int10] pusha mov ah,3 mov bh,0 int 10h mov ah,1 int 10h popa iret fnct_1: pusha push ds mov ax,0 mov ds,ax mov ds:[460h],cx ; store cursor mode now mov al,ds:[485h] ; bytes per character cmp al,10 je ch_ok sub al,8 ; difference cmp cl,5 jbe cl_ok add cl,al cl_ok: cmp ch,5 jbe ch_ok add ch,al ch_ok: mov dx,3d4h mov al,10 ; cursor start mov ah,ch out dx,ax inc al ; cursor end mov ah,cl out dx,ax pop ds popa iret fnct_3: sti pusha push ds push cs pop ds call mode_3_setup pop ds popa iret fnct_14: sti pusha push ds push cs pop ds cocall getc pop ds popa iret ;============================================================================ max_col db ? max_row db ? cur_mode db ? cur_page db ? temp db ? save_cur dw 0 color_save dw 0 wrap db 0 crt_mode db 0 status_line equ 1 lines43 equ 2 intense db 0 ; 1=intense tty_write_init: pop [getc] ; first time - pop only mov fgc,7 mov bgc,0 tty_write: cocall getc ; get character from user push ax mov ah,15 int 10h mov [cur_mode],al mov [cur_page],bh mov ah,3 int 10h push es xor ax,ax mov es,ax mov al,es:[484h] if check_ega cmp has_ega,1 je ega_rows mov al,24 ; if not EGA, assume 25 lines. ega_rows: endif test [crt_mode],status_line jz tty_no_status dec al tty_no_status: mov [max_row],al mov al,es:[44ah] dec al mov [max_col],al pop es pop ax ; cursor in (dh,dl) cur_page in bh cmp al,7 je print_bell cmp al,8 je print_bs cmp al,9 je print_tab cmp al,10 je print_lf cmp al,13 je print_cr cmp al,27 jne print_char_do jmp escape print_char_do: jmp print_char print_bell: call fast_beep jmp tty_write print_tab: and dl,not 7 add dl,8 jmp set_cursor print_bs: cmp dl,0 je set_cursor dec dl jmp set_cursor print_cr: mov dl,0 jmp set_cursor print_lf: cmp dh,[max_row] jae scroll_up inc dh set_cursor: mov ah,2 mov bh,[cur_page] int 10h jmp tty_write scroll_up: mov bh,[cur_page] mov dh,[max_row] mov ah,2 int 10h mov ax,0601h ; scroll one line up mov dh,[max_row] mov dl,[max_col] xor cx,cx mov bh,[bgc] shl bh,1 shl bh,1 shl bh,1 shl bh,1 or bh,[fgc] cmp [cur_mode],3 jbe do_scroll cmp [cur_mode],7 je do_scroll mov bh,0 do_scroll: int 10h cmp [intense],1 jne no_intense mov dx,3d8h in al,dx and al,0dfh out dx,al no_intense: jmp tty_write escape: cocall getc mov si,offset esc_lookup_table escape_loop: cmp [si],al je esc_found cmp [si].b,0 je esc_invalid add si,3 jmp escape_loop esc_invalid: jmp tty_write esc_found: jmp [si+1] esc_lookup_table label byte cesc <'+',offset esc_plus> cesc <'-',offset esc_minus> cesc <'[',offset esc_ansi> cesc <'A',offset esc_cA> cesc <'B',offset esc_cB> cesc <'C',offset esc_cC> cesc <'D',offset esc_cD> cesc <'E',offset esc_cE> cesc <'H',offset esc_cH> cesc <'I',offset esc_cI> cesc <'J',offset esc_cJ> cesc <'K',offset esc_cK> cesc <'Y',offset esc_cY> cesc <'b',offset esc_b> cesc <'c',offset esc_c> cesc <'j',offset esc_j> cesc <'i',offset esc_i> cesc <'k',offset esc_k> cesc <'m',offset esc_m> cesc <'s',offset esc_s> cesc <'w',offset esc_w> cesc <0,0> ;----------------------------------------------------------------------------- esc_plus: if check_ega cmp has_ega,1 jne plus_exit endif cmp [max_row],40 ja plus_exit or [crt_mode],lines43 mov ax,0003h int 10h plus_exit: jmp tty_write ;------------------------------------------------------------------------------ esc_minus: if check_ega cmp has_ega,1 jne plus_exit endif cmp [max_row],30 jb minus_exit and [crt_mode],not lines43 mov ax,0003h int 10h minus_exit: jmp tty_write ;------------------------------------------------------------------------------ esc_ansi: next_digit: cocall getc cmp al,';' je next_digit cmp al,'0' jb end_digits cmp al,'9' ja end_digits jmp next_digit end_digits: cmp al,'J' je clear_screen jmp tty_write clear_screen: mov ax,0600h mov dh,[max_row] mov dl,[max_col] xor cx,cx mov bh,[bgc] shl bh,1 shl bh,1 shl bh,1 shl bh,1 or bh,[fgc] cmp [cur_mode],3 jbe do_scroll2 cmp [cur_mode],7 je do_scroll2 mov bh,0 do_scroll2: int 10h mov ah,2 mov bh,[cur_page] xor dx,dx ; upper left corner int 10h test [crt_mode],lines43 jz scroll_nocur mov ah,1 mov cx,0007h int 10h scroll_nocur: jmp tty_write ;------------------------------------------------------------------------------ esc_cA: mov ah,3 mov bh,[cur_page] int 10h cmp dh,0 je end_cA dec dh mov bh,[cur_page] mov ah,2 int 10h end_cA: jmp tty_write ;------------------------------------------------------------------------------ esc_cB: mov ah,3 mov bh,[cur_page] int 10h cmp dh,[max_row] jae end_cB inc dh mov bh,[cur_page] mov ah,2 int 10h end_cB: jmp tty_write ;------------------------------------------------------------------------------ esc_cC: mov ah,3 mov bh,[cur_page] int 10h cmp dl,[max_col] jae end_cC inc dl mov ah,2 mov bh,[cur_page] int 10h end_cC: jmp tty_write ;------------------------------------------------------------------------------ esc_cD: mov ah,3 mov bh,[cur_page] int 10h cmp dl,0 je end_cD dec dl mov ah,2 mov bh,[cur_page] int 10h end_cD: jmp tty_write ;------------------------------------------------------------------------------ esc_cE: jmp clear_screen ;------------------------------------------------------------------------------ esc_cH: mov ah,2 mov bh,[cur_page] xor dx,dx int 10h jmp tty_write ;------------------------------------------------------------------------------ esc_cI: mov bh,[cur_page] mov dh,[max_row] mov ah,2 int 10h mov ax,0701h ; scroll one line up mov dh,[max_row] mov dl,[max_col] xor cx,cx mov bh,[bgc] shl bh,1 shl bh,1 shl bh,1 shl bh,1 or bh,[fgc] cmp [cur_mode],3 jbe do_dscroll cmp [cur_mode],7 je do_dscroll mov bh,0 do_dscroll: int 10h jmp tty_write ;------------------------------------------------------------------------------ esc_cJ: mov ah,3 mov bh,[cur_page] int 10h mov ch,dh inc ch mov ax,0600h mov dh,[max_row] mov dl,[max_col] mov cl,0 mov bh,[bgc] shl bh,1 shl bh,1 shl bh,1 shl bh,1 or bh,[fgc] cmp [cur_mode],3 jbe do_cleareos cmp [cur_mode],7 je do_cleareos mov bh,0 do_cleareos: int 10h ; fall through to esc-K ;------------------------------------------------------------------------------ esc_cK: mov ah,3 mov bh,[cur_page] int 10h push dx neg dl add dl,[max_col] inc dl mov cl,dl xor ch,ch mov al,' ' mov bh,[cur_page] mov ah,9 mov bl,[bgc] shl bl,1 shl bl,1 shl bl,1 shl bl,1 or bl,[fgc] cmp [cur_mode],3 jbe do_scroll3 cmp [cur_mode],7 je do_scroll3 mov bl,0 do_scroll3: int 10h pop dx jmp set_cursor ;------------------------------------------------------------------------------ esc_cY: cocall getc sub al,' ' cmp al,'s'-' ' jne skip_status_line mov al,[max_row] inc al skip_status_line: mov [temp],al cocall getc sub al,' ' mov dh,[temp] mov dl,al mov ah,2 mov bh,[cur_page] int 10h jmp tty_write ;------------------------------------------------------------------------------ esc_b: mov ax,1003h ; set blink mov bl,1 int 10h mov [intense],0 jmp tty_write ;------------------------------------------------------------------------------ esc_c: cocall getc call hex2dec mov [temp],al cocall getc call hex2dec mov ch,[temp] mov cl,al mov ah,1 int 10h jmp tty_write ;------------------------------------------------------------------------------ esc_i: mov ax,1003h ; set intensify mov bl,0 int 10h mov [intense],1 mov dx,3d8h in al,dx and al,0dfh out dx,al jmp tty_write ;------------------------------------------------------------------------------ esc_j: mov ah,3 mov bh,[cur_page] int 10h mov [save_cur],dx jmp tty_write ;------------------------------------------------------------------------------ esc_k: mov ah,2 mov bh,[cur_page] mov dx,[save_cur] int 10h jmp tty_write ;------------------------------------------------------------------------------ esc_m: cocall getc cmp al,'s' je save_color cmp al,'r' je restore_color cmp al,'*' je esc_m_fgsame call hex2bin mov [fgc],al esc_m_fgsame: cocall getc cmp al,'*' je esc_m_bgsame call hex2bin mov [bgc],al esc_m_bgsame: jmp tty_write save_color: mov al,[fgc] mov ah,[bgc] mov [color_save],ax jmp tty_write restore_color: mov ax,[color_save] mov [fgc],al mov [bgc],ah jmp tty_write ;------------------------------------------------------------------------------ esc_s: cocall getc cmp al,'1' je enable_status_line cmp al,'0' je disable_status_line finished_status_line: jmp tty_write enable_status_line: ; turn status line on test [crt_mode],status_line jnz finished_status_line mov ah,3 mov bh,[cur_page] int 10h dec [max_row] or [crt_mode],status_line cmp dh,[max_row] jbe finished_status_line jmp scroll_up disable_status_line: ; turn status line off test [crt_mode],status_line jz finished_status_line inc [max_row] and [crt_mode],not status mov ah,3 mov bh,[cur_page] int 10h push dx mov dh,[max_row] xor dl,dl mov ah,2 mov bh,[cur_page] int 10h mov ah,9 mov bl,[bgc] shl bl,1 shl bl,1 shl bl,1 shl bl,1 or bl,[fgc] cmp [cur_mode],3 jbe disable_status_2 cmp [cur_mode],7 je disable_status_2 mov bl,0 disable_status_2: mov cl,[max_col] inc cl xor ch,ch mov al,' ' int 10h pop dx mov ah,2 mov bh,[cur_page] int 10h jmp tty_write ;------------------------------------------------------------------------------ esc_w: cocall getc and al,1 mov [wrap],al jmp tty_write ;------------------------------------------------------------------------------ print_char: push dx mov cx,1 mov ah,9 mov bl,[bgc] shl bl,1 shl bl,1 shl bl,1 shl bl,1 or bl,[fgc] mov bh,[cur_page] cmp [cur_mode],3 jbe bgblink_ok and bl,7fh bgblink_ok: int 10h pop dx cmp dl,[max_col] jae print_eol inc dl jmp set_cursor print_eol: cmp [wrap],1 je print_exit mov dl,0 cmp dh,[max_row] je print_eos ja in_status_line inc dh jmp set_cursor in_status_line: jmp tty_write print_eos: jmp scroll_up print_exit: jmp tty_write ;============================================================================ hex2dec: sub al,'0' cmp al,9 jbe hex_ok sub al,7 hex_ok: and al,0fh ret hex2bin: call hex2dec push si mov si,offset hex_tbl xor ah,ah add si,ax mov al,[si] pop si ret hex_tbl db 0,9,12,13,10,11,14,15,8,1,4,5,2,3,6,7 ;============================================================================ mode_3_setup: pushf call [old_int10] ; do mode set test [crt_mode],lines43 jz mode_3_exit mov ax,1112h mov bx,0 mov dx,43 int 10h mov ah,1 mov cx,0007h int 10h mode_3_exit: ret ;============================================================================ fast_beep proc near push ax push cx mov al,0b6h out 43h,al mov al,1500 and 255 out 42h,al jmp $+2 mov al,1500 shr 8 out 42h,al in al,61h push ax or al,3 out 61h,al mov cx,30000 loop $ pop ax out 61h,al pop cx pop ax ret fast_beep endp ;============================================================================ key_queue db ? queue_full db 0 cmd_input: mov cx,es:[bx].count lds di,es:[bx].trans cmd_input_loop: cmp [queue_full],1 je cmd_input_queue mov ah,0 int 16h cmp al,0 jne cmd_input_normal mov [key_queue],ah mov [queue_full],1 jmp cmd_input_normal cmd_input_queue: mov al,[key_queue] mov [queue_full],0 cmd_input_normal: mov [di],al inc di loop cmd_input_loop mov ax,success ret ;============================================================================ cmd_input_now proc near cmp [queue_full],1 jne cmd_input_now_int mov al,[key_queue] mov es:[bx].single,al mov ax,success jmp cmd_input_now_end cmd_input_now_int: mov ah,1 int 16h mov es:[bx].single,al mov ax,success jnz cmd_input_now_end or ax,busy cmd_input_now_end: ret cmd_input_now endp ;============================================================================ cmd_input_stat proc near cmp [queue_full],1 je cmd_input_stat_end mov ah,1 int 16h mov ax,success jnz cmd_input_stat_end or ax,busy cmd_input_stat_end: ret cmd_input_stat endp ;============================================================================ cmd_input_flush proc near jmp cmd_input_flush_end mov [queue_full],0 mov ah,1 int 16h jz cmd_input_flush_end mov ah,0 int 16h jmp cmd_input_flush cmd_input_flush_end: mov ax,success ret cmd_input_flush endp ;============================================================================ cmd_output proc near mov cx,es:[bx].count lds si,es:[bx].trans cmd_output_loop: mov ah,14 mov al,ds:[si] inc si push si push cx int 10h pop cx pop si loop cmd_output_loop mov ax,success ret cmd_output endp ;============================================================================ cmd_output_stat proc near mov ax,success ret cmd_output_stat endp ;============================================================================ cmd_init proc near mov ax,cs mov ds,ax if check_ega push bx mov has_ega,0 ; innocent until proven guilty mov ax,1200h mov bx,10h mov cx,-1 int 10h cmp cx,-1 je no_ega mov has_ega,1 no_ega: pop bx endif mov getc,offset tty_write_init cocall getc ; to initialize mov ax,0 mov ds,ax mov ax,ds:[40h] mov old_int10.ofs,ax mov ax,ds:[42h] mov old_int10.seg,ax mov ds:[40h].w,offset int10 mov ds:[42h].w,cs mov ax,cs mov ds,ax mov dx,offset banner mov ah,9 ; print string int 21h mov es:[bx].trans.ofs,offset cmd_init mov es:[bx].trans.seg,cs mov ax,success ret cmd_init endp banner db 'VT-52 emulator has been loaded.',13,10,'$' cseg ends end