uartctrl: Implement CP437 to DEC VT character conversion

This commit is contained in:
Nero 2021-04-05 18:59:44 +00:00
parent 963aebd948
commit 85d0949ec7
3 changed files with 163 additions and 32 deletions

View File

@ -83,5 +83,5 @@ qemu-floppy5: fd360.img $(ROMS)
qemu-hdd: hdd.img $(ROMS)
$(QEMU) $(QEMU_ARGS) -boot c -hda hdd.img
qemu-uartctrl: uartctrl.rom
$(QEMU) $(QEMU_ARGS) -option-rom uartctrl.rom -serial stdio
qemu-uartctrl: uartctrl.rom chartab.bs
$(QEMU) $(QEMU_ARGS) -option-rom uartctrl.rom -serial stdio -hda chartab.bs

66
boot/chartab.asm Normal file
View File

@ -0,0 +1,66 @@
org 0x7C00
init xor ax, ax
mov ss, ax
mov sp, ax
mov ax, 0x0e20
xor bx, bx
int 0x10
mov cx, 0x10
.hloop mov al, 0x20
int 0x10
mov al, cl
neg al
add al, 0x10
call btoa
int 0x10
loop .hloop
mov al, 0x0A
int 0x10
mov al, 0x0D
int 0x10
mov cx, 0x20
.line test cl, 0x0F
jnz .loop
mov al, cl
sar al, 1
sar al, 1
sar al, 1
sar al, 1
and al, 0xF
call btoa
mov ah, 0x0e
int 0x10
mov al, 0x20
int 0x10
.loop mov al, cl
int 0x10
mov al, 0x20
int 0x10
mov al, cl
inc cx
and al, 0xF
cmp al, 0xF
jne .loop
mov al, 0x0A
int 0x10
mov al, 0x0D
int 0x10
cmp cx, 0x100
jc .line
halt hlt
jmp halt
btoa add al, 0x30
cmp al, 0x3A
jc .ret
add al, 7
.ret ret
times (0x1FE - ($-$$)) db 0
dw 0xAA55

View File

@ -7,6 +7,10 @@
%define clock 115200
%define baud 9600
%ifndef CODEPAGE
%define CODEPAGE 437
%endif
data equ (uart + 0) ; data register
ier equ (uart + 1)
fcr equ (uart + 2)
@ -19,6 +23,7 @@ msr equ (uart + 6)
absolute 0xE0 ; data in bios data area
pstate resw 1 ; parser resume offset
parg resb 1 ; accumulator for numerical CSI arguments
curcs resb 1 ; current charset we put remote term in
section .text
db 0x55, 0xAA
@ -72,12 +77,6 @@ init push ax
mov al, 8
out dx, al
; hook boot interrupt
xor ax, ax
mov ds, ax
mov word [4*0x19], int19
mov word [4*0x19+2], cs
; hook video services
; keep original ptr in intvec 47h for chaining
mov ax, int10
@ -87,6 +86,9 @@ init push ax
mov word [4*0x47], ax
mov word [4*0x47+2], bx
; reset parser state
mov word [0x400+pstate], parse.start
; hook uart irq
mov word [4*(0x08+irq)], intu
mov word [4*(0x08+irq)+2], cs
@ -97,9 +99,6 @@ init push ax
and al, ~(1 << irq)
out dx, al
; reset parser state
mov word [0x400+pstate], parse.start
call greet
pop ds
@ -132,6 +131,26 @@ putc mov ah, al
out dx, al
ret
; set charset
; IN AL '0', 'A' or 'B'
setcs test al, al
jz .fret
push ds
; set DS
mov dx, 0x40
mov ds, dx
cmp al, [curcs]
je .ret
mov [curcs], al
mov al, 0x1B
call putc
mov al, '('
call putc
mov al, [curcs]
call putc
.ret pop ds
.fret ret
pdx: ; this double-call is essentially a 4 times repeating loop
call .l1
.l1: call .l2
@ -155,29 +174,27 @@ pputc mov ah, 0x0e
int 0x10
ret
; system bootstrap
int19 sti
xor ax, ax
int 0x16
mov dx, ax
call pdx
mov al, 0x0A
call pputc
mov al, 0x0D
call pputc
jmp int19
; video services
int10 cmp ah, 0x0e
jne .chain
push ax
push bx
push dx
push ax
; activate character set for current char
mov bx, csmap
cs xlatb
call setcs
pop ax
push ax
; look up what we need to write out
mov bx, ecmap
cs xlatb
call putc
pop dx
pop ax
pop dx
pop bx
.chain sub sp, 4
push bp
@ -263,7 +280,7 @@ parse call ugetc
je .vt_o
jmp parse
.csi mov byte [parg], 0 ; reset argument
.csicon call ugetc
.csicon call ugetc ; number parsing
cmp al, 0x30
jc parse
cmp al, 0x3A
@ -275,15 +292,17 @@ parse call ugetc
add al, dl
mov [parg], al
jmp .csicon
.nonum cmp al, '~'
.nonum cmp al, '~' ; \e[...$c handling
jne .letter
mov al, [parg]
mov al, [parg] ; \e[$n~ lookup $n
mov bx, fkeysn
jmp .lookup
.vt_o call ugetc ; VT100 \eO... sequences
.letter sub al, 0x40
.letter sub al, 0x40 ; look up special key by letter
mov bx, fkeysc
.lookup cs xlatb
.lookup cmp al, 0x40 ; special key lookup, bx assumed
jnc parse
cs xlatb
cmp al, 0
je parse
mov dh, al
@ -293,7 +312,8 @@ parse call ugetc
align 128
; ascii -> XT scancode map
; this assumes US querty layout
%if CODEPAGE = 437
; US Keyboard layout
kmap db 0x00,0x1E,0x30,0x2E, 0x20,0x12,0x21,0x22, 0x23,0x0F,0x24,0x25, 0x26,0x1C,0x31,0x18
db 0x19,0x10,0x13,0x1F, 0x14,0x16,0x2F,0x11, 0x2D,0x15,0x2C,0x01, 0x2B,0x1B,0x07,0x0C
@ -306,6 +326,51 @@ kmap db 0x00,0x1E,0x30,0x2E, 0x20,0x12,0x21,0x22, 0x23,0x0F,0x24,0x25, 0x26,0x1C
db 0x29,0x1E,0x30,0x2E, 0x20,0x12,0x21,0x22, 0x23,0x17,0x24,0x25, 0x26,0x32,0x31,0x18
db 0x19,0x10,0x13,0x1F, 0x14,0x16,0x2F,0x11, 0x2D,0x15,0x2C,0x1A, 0x2B,0x1B,0x29,0x70
; character map
; resolves codepage character to character in charset (see next table)
ecmap db 0x00,0x01,0x02,0x03, 0x60,0x05,0x06,0x07, 0x08,0x09,0x0A,0x0B, 0x0C,0x0D,0x0E,0x0F
db 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 0x18,0x19,0x1A,0x1B, 0x1C,0x1D,0x1E,0x1F
db 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27, 0x28,0x29,0x2A,0x2B, 0x2C,0x2D,0x2E,0x2F
db 0x30,0x31,0x32,0x33, 0x34,0x35,0x36,0x37, 0x38,0x39,0x3A,0x3B, 0x3C,0x3D,0x3E,0x3F
db 0x40,0x41,0x42,0x43, 0x44,0x45,0x46,0x47, 0x48,0x49,0x4A,0x4B, 0x4C,0x4D,0x4E,0x4F
db 0x50,0x51,0x52,0x53, 0x54,0x55,0x56,0x57, 0x58,0x59,0x5A,0x5B, 0x5C,0x5D,0x5E,0x5F
db 0x60,0x61,0x62,0x63, 0x64,0x65,0x66,0x67, 0x68,0x69,0x6A,0x6B, 0x6C,0x6D,0x6E,0x6F
db 0x70,0x71,0x72,0x73, 0x74,0x75,0x76,0x77, 0x78,0x79,0x7A,0x7B, 0x7C,0x7D,0x7E,0x7F
db 0x47,0x7c,0x69,0x62, 0x64,0x60,0x65,0x67, 0x6A,0x6B,0x68,0x6f, 0x6e,0x6c,0x44,0x45
db 0x49,0x66,0x46,0x74, 0x76,0x72,0x7b,0x79, 0x7d,0x56,0x5C,0x22, 0x23,0x25,'P' ,'f'
db 0x61,0x6D,0x73,0x7a, 0x71,0x51,0x2A,0x3A, 0x3F,0x2C,0x2C,0x3d, 0x3c,0x21,0x2b,0x3b
db 0x61,0x61,0x61,0x78, 0x75,0x75,0x75,0x6B, 0x6B,0x75,0x78,0x6B, 0x6a,0x6a,0x6a,0x6b
db 0x6D,0x76,0x77,0x74, 0x71,0x6E,0x74,0x74, 0x6D,0x6C,0x76,0x77, 0x74,0x71,0x6E,0x76
db 0x76,0x77,0x77,0x6D, 0x6D,0x6C,0x6C,0x6E, 0x6E,0x6A,0x6C,0x61, 0x61,0x61,0x61,0x61
db 0x61,0x62,0x47,0x70, 0x53,0x73,0x35,0x74, 0x46,0x6A,0x57,0x64, 0x42,0x66,0x65,0x5C
db 0x4F,0x67,0x7A,0x79, 0x24,0x25,0x43,0x49, 0x66,0x7E,0x7E,0x21, 0x32,0x32,0x61,0x5F
; character set map
; resolves codepage character to DEC charset (A,B,0,1,<)
csmap db 0,0,0,0, '0',0,0,0, 0,0,0,0, 0,0,0,0
db 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
db 0,'B','B','B', 'B','B','B','B', 'B','B','B','B', 'B','B','B','B'
db 'B','B','B','B', 'B','B','B','B', 'B','B','B','B', 'B','B','B','B'
db 'B','B','B','B', 'B','B','B','B', 'B','B','B','B', 'B','B','B','B'
db 'B','B','B','B', 'B','B','B','B', 'B','B','B','B', 'B','B','B','B'
db 'B','B','B','B', 'B','B','B','B', 'B','B','B','B', 'B','B','B','B'
db 'B','B','B','B', 'B','B','B','B', 'B','B','B','B', 'B','B','B',0
db 'A','A','A','A', 'A','A','A','A', 'A','A','A','A', 'A','A','A','A'
db 'A','A','A','A', 'A','A','A','A', 'A','A','A','A', 'A','A','B','B'
db 'A','A','A','A', 'A','A','A','A', 'A','A','A','A', 'A','A','A','A'
db '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0'
db '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0'
db '0','0','0','0', '0','0','0','0', '0','0','0','0', '0','0','0','0'
db '>','>','>','>', '>','>','A','>', '>','>','>','>', '>','>','>','>'
db '>','0','0','0', '>','>','>','>', '0','0','0','>', 'A','A','0','0'
%endif
; function keys by character
; \eO$c, looks up $c to XT scancode
; table is like ascii, except it starts at 0x40 '@'