Last active
January 2, 2017 10:17
-
-
Save wizzwizz4/37a203a3997e7b2c7979cc9191d3439b to your computer and use it in GitHub Desktop.
An archive of the VT52 assembly code found at http://www.delorie.com/opendos//archives/browse.cgi?p=opendos/2003/12/04/09:58:08 (copied literally except possible memory corruption)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment