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-hdd: hdd.img $(ROMS)
$(QEMU) $(QEMU_ARGS) -boot c -hda hdd.img $(QEMU) $(QEMU_ARGS) -boot c -hda hdd.img
qemu-uartctrl: uartctrl.rom qemu-uartctrl: uartctrl.rom chartab.bs
$(QEMU) $(QEMU_ARGS) -option-rom uartctrl.rom -serial stdio $(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 clock 115200
%define baud 9600 %define baud 9600
%ifndef CODEPAGE
%define CODEPAGE 437
%endif
data equ (uart + 0) ; data register data equ (uart + 0) ; data register
ier equ (uart + 1) ier equ (uart + 1)
fcr equ (uart + 2) fcr equ (uart + 2)
@ -19,6 +23,7 @@ msr equ (uart + 6)
absolute 0xE0 ; data in bios data area absolute 0xE0 ; data in bios data area
pstate resw 1 ; parser resume offset pstate resw 1 ; parser resume offset
parg resb 1 ; accumulator for numerical CSI arguments parg resb 1 ; accumulator for numerical CSI arguments
curcs resb 1 ; current charset we put remote term in
section .text section .text
db 0x55, 0xAA db 0x55, 0xAA
@ -72,12 +77,6 @@ init push ax
mov al, 8 mov al, 8
out dx, al 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 ; hook video services
; keep original ptr in intvec 47h for chaining ; keep original ptr in intvec 47h for chaining
mov ax, int10 mov ax, int10
@ -87,6 +86,9 @@ init push ax
mov word [4*0x47], ax mov word [4*0x47], ax
mov word [4*0x47+2], bx mov word [4*0x47+2], bx
; reset parser state
mov word [0x400+pstate], parse.start
; hook uart irq ; hook uart irq
mov word [4*(0x08+irq)], intu mov word [4*(0x08+irq)], intu
mov word [4*(0x08+irq)+2], cs mov word [4*(0x08+irq)+2], cs
@ -97,9 +99,6 @@ init push ax
and al, ~(1 << irq) and al, ~(1 << irq)
out dx, al out dx, al
; reset parser state
mov word [0x400+pstate], parse.start
call greet call greet
pop ds pop ds
@ -132,6 +131,26 @@ putc mov ah, al
out dx, al out dx, al
ret 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 pdx: ; this double-call is essentially a 4 times repeating loop
call .l1 call .l1
.l1: call .l2 .l1: call .l2
@ -155,29 +174,27 @@ pputc mov ah, 0x0e
int 0x10 int 0x10
ret 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 ; video services
int10 cmp ah, 0x0e int10 cmp ah, 0x0e
jne .chain jne .chain
push ax push bx
push dx 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 call putc
pop dx
pop ax pop ax
pop dx
pop bx
.chain sub sp, 4 .chain sub sp, 4
push bp push bp
@ -263,7 +280,7 @@ parse call ugetc
je .vt_o je .vt_o
jmp parse jmp parse
.csi mov byte [parg], 0 ; reset argument .csi mov byte [parg], 0 ; reset argument
.csicon call ugetc .csicon call ugetc ; number parsing
cmp al, 0x30 cmp al, 0x30
jc parse jc parse
cmp al, 0x3A cmp al, 0x3A
@ -275,15 +292,17 @@ parse call ugetc
add al, dl add al, dl
mov [parg], al mov [parg], al
jmp .csicon jmp .csicon
.nonum cmp al, '~' .nonum cmp al, '~' ; \e[...$c handling
jne .letter jne .letter
mov al, [parg] mov al, [parg] ; \e[$n~ lookup $n
mov bx, fkeysn mov bx, fkeysn
jmp .lookup jmp .lookup
.vt_o call ugetc ; VT100 \eO... sequences .vt_o call ugetc ; VT100 \eO... sequences
.letter sub al, 0x40 .letter sub al, 0x40 ; look up special key by letter
mov bx, fkeysc mov bx, fkeysc
.lookup cs xlatb .lookup cmp al, 0x40 ; special key lookup, bx assumed
jnc parse
cs xlatb
cmp al, 0 cmp al, 0
je parse je parse
mov dh, al mov dh, al
@ -293,7 +312,8 @@ parse call ugetc
align 128 align 128
; ascii -> XT scancode map ; 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 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 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 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 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 ; function keys by character
; \eO$c, looks up $c to XT scancode ; \eO$c, looks up $c to XT scancode
; table is like ascii, except it starts at 0x40 '@' ; table is like ascii, except it starts at 0x40 '@'