From 85d0949ec7e1c5ce36e6958e7a03fc697853b6ce Mon Sep 17 00:00:00 2001 From: Nero <41307858+nero@users.noreply.github.com> Date: Mon, 5 Apr 2021 18:59:44 +0000 Subject: [PATCH] uartctrl: Implement CP437 to DEC VT character conversion --- Makefile | 4 +- boot/chartab.asm | 66 +++++++++++++++++++++++++ rom/uartctrl.asm | 125 +++++++++++++++++++++++++++++++++++------------ 3 files changed, 163 insertions(+), 32 deletions(-) create mode 100644 boot/chartab.asm diff --git a/Makefile b/Makefile index eab91cb..9a0997a 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/boot/chartab.asm b/boot/chartab.asm new file mode 100644 index 0000000..d587cca --- /dev/null +++ b/boot/chartab.asm @@ -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 diff --git a/rom/uartctrl.asm b/rom/uartctrl.asm index 1a8f70d..b5bd775 100644 --- a/rom/uartctrl.asm +++ b/rom/uartctrl.asm @@ -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 '@'