From f79c2b9f240614e06baf61a7e57ea13526add9ea Mon Sep 17 00:00:00 2001 From: David Given Date: Fri, 18 Sep 2020 22:21:09 +0200 Subject: [PATCH 01/10] Split up tty.lib into tty.lib (for the primitives) and adm3a.lib (for the state machine). Fix the nc200 port to actually use these rather than its home grown version. Also, discover that dseg is dangerous; stop using it. --- arch/brotherop2/tty.z80 | 3 +- arch/common/utils/adm3a.lib | 163 +++++++++++++ arch/common/utils/build.lua | 1 + arch/common/utils/tty.lib | 164 +------------ arch/nc200/supervisor/build.lua | 4 +- arch/nc200/supervisor/keyboard.inc | 6 +- arch/nc200/supervisor/startup.inc | 4 +- arch/nc200/supervisor/supervisor.z80 | 2 + arch/nc200/supervisor/tty.inc | 347 +-------------------------- arch/nc200/supervisor/variables.z80 | 6 + arch/wp2450ds/tty.z80 | 3 +- third_party/ld80/build.lua | 4 +- 12 files changed, 197 insertions(+), 510 deletions(-) create mode 100644 arch/common/utils/adm3a.lib diff --git a/arch/brotherop2/tty.z80 b/arch/brotherop2/tty.z80 index 79a9838..9a0a87f 100644 --- a/arch/brotherop2/tty.z80 +++ b/arch/brotherop2/tty.z80 @@ -22,8 +22,9 @@ EMULATE_CLEAR_TO_EOL = 1 EMULATE_CLEAR_TO_EOS = 1 maclib tty + maclib adm3a -TTYINIT equ tty_init +TTYINIT equ adm3a_init TTYPUTC equ tty_putc TTYPUT8 equ tty_puthex8 TTYPUT16 equ tty_puthex16 diff --git a/arch/common/utils/adm3a.lib b/arch/common/utils/adm3a.lib new file mode 100644 index 0000000..76d5841 --- /dev/null +++ b/arch/common/utils/adm3a.lib @@ -0,0 +1,163 @@ +; cpmish BIOS © 2019 David Given +; This file is distributable under the terms of the 2-clause BSD license. +; See COPYING.cpmish in the distribution root directory for more information. + +; This is a general purpose ADM3a state machine. It provides tty_putc and calls +; out to tty.lib. + +commandlen: db 0 +commandgot: db 0 +commandbuf: ds 3 + +; --- Clears (and initialises) the screen ----------------------------------- + +adm3a_init: + xra a + ld (commandlen), a + jp tty_init + +; --- Prints the character in A --------------------------------------------- + +; Helper routine: called from tty_putc if this is a non-printable control +; character. The character is in A. +controlcharacter: + cp 0x08 + jp z, tty_cursor_left + cp 0x0c + jp z, tty_cursor_right + cp 0x0a + jp z, tty_cursor_down + cp 0x0b + jp z, tty_cursor_up + cp 0x1e + jp z, tty_home_cursor + cp 0x0d + jp z, tty_carriagereturn + cp 0x18 + jp z, tty_clear_to_eol + cp 0x17 + jp z, tty_clear_to_eos + cp 0x1a + jp z, tty_clear_screen + cp 0x1b + ret nz ; give up if not an escape character + + ; Escape characters need parameters, starting with one. + xor a + ld (commandgot), a + inc a + ld (commandlen), a + ret + +; Helper routine: deal with command bytes (passed in C). +queue_command_byte: + ; Write the byte to the buffer. + + ld hl, commandgot + ld d, 0 + ld e, (hl) + inc (hl) + + ld hl, commandbuf + add hl, de + ld (hl), c + + ; Have we reached the end of the buffer? + + ld hl, commandlen + ld a, (commandgot) + cp (hl) + ret nz ; no, go back for more bytes. + xor a + ld (hl), a ; end of command + + ; Process a command. + + ld a, (commandbuf+0) + cp 'B' + jr z, setresetattr + cp 'C' + jr z, setresetattr + cp 'E' + jp z, tty_insert_line + cp 'R' + jp z, tty_delete_line + cp '=' + jr z, gotoxy + ret + +; Helper routine: handles set/reset tty_attributes. +setresetattr: + ld a, (commandgot) ; B, C takes parameters + cp 2 ; do we have enough bytes? + jr z, .1 ; yes, execute command + ld a, 2 ; not enough bytes read yet + ld (commandlen), a + ret +.1: + ld a, (commandbuf+1) + cp '0' ; reverse intensity + ret nz ; don't support anything else + ld a, (commandbuf+0) ; B=on, C=off + ld hl, tty_attributes + res 0, (hl) + bit 0, a + ret nz + set 0, (hl) + ret + +; Helper routine: handles ESC = (gotoxy). +gotoxy: + ld a, (commandgot) ; = takes parameters + cp 3 ; do we have enough bytes? + jr z, .1 ; yes, execute command + ld a, 3 ; not enough bytes read yet + ld (commandlen), a + ret +.1: + ld hl, commandbuf+1 ; got enough bytes; process command + ld a, (hl) + sub 32 + ld c, a ; Y + inc hl + ld a, (hl) + sub 32 + ld b, a ; X + jp tty_goto_xy + +tty_putc: + ; Check to see if there's a pending command. + + ld c, a + ld a, (commandlen) + or a + jr nz, queue_command_byte + + ; Handle special characters. + + ld a, c + cp 32 + jp c, controlcharacter + + ; This is a printable character, so print it. + + call tty_rawwrite + + ; Now we've drawn a character, advance the cursor. + + ld hl, tty_cursorx + ld a, (hl) + inc a + ld (hl), a + cp SCREEN_WIDTH + ret nz + + ; Reached the end of the line? Advance to the next one and go back to + ; the margin. + + xor a + ld (hl), a + jp tty_cursor_down + +; vim: sw=4 ts=4 expandtab ft=asm + diff --git a/arch/common/utils/build.lua b/arch/common/utils/build.lua index fb41581..4a221c0 100644 --- a/arch/common/utils/build.lua +++ b/arch/common/utils/build.lua @@ -19,3 +19,4 @@ for _, n in pairs(deblocker_tests) do } } end + diff --git a/arch/common/utils/tty.lib b/arch/common/utils/tty.lib index 0c8593f..875c983 100644 --- a/arch/common/utils/tty.lib +++ b/arch/common/utils/tty.lib @@ -2,28 +2,20 @@ ; This file is distributable under the terms of the 2-clause BSD license. ; See COPYING.cpmish in the distribution root directory for more information. -; This is a general purpose TTY core, providing ADM-3a/Kaypro IIish escape -; sequences. It's intended to be loaded with maclib so that various -; options can be provided. It provides the state machine for parsing the -; input stream, tracking the cursor position, etc, before calling out to -; supplied low-level routines to do the actual work. +; This is a general purpose TTY core, providing both the various primitives +; needed by the terminal emulator, and various helpers which wrap tty_putc. It +; takes care of tracking the cursor position, current attributes, etc. It +; expects tty_putc and tty_rawwrite to be provided. It's intended to be loaded +; with maclib so that various options can be provided. - dseg tty_cursorx: db 0 tty_cursory: db 0 ; must be immediately after tty_cursory tty_attributes: db 0 -commandlen: db 0 -commandgot: db 0 -commandbuf: ds 3 - - cseg - ; --- Clears (and initialises) the screen ----------------------------------- tty_init: xra a - ld (commandlen), a ld (tty_attributes), a ; fall through tty_clear_screen: @@ -232,149 +224,3 @@ tty_goto_xy: ld (tty_cursory), a ret -; --- Prints the character in A --------------------------------------------- -; (also tty_newline) - -; Helper routine: called from tty_putc if this is a non-printable control -; character. The character is in A. -controlcharacter: - cp 0x08 - jp z, tty_cursor_left - cp 0x0c - jr z, tty_cursor_right - cp 0x0a - jr z, tty_cursor_down - cp 0x0b - jp z, tty_cursor_up - cp 0x1e - jp z, tty_home_cursor - cp 0x0d - jp z, tty_carriagereturn - cp 0x18 - jp z, tty_clear_to_eol - cp 0x17 - jp z, tty_clear_to_eos - cp 0x1a - jp z, tty_clear_screen - cp 0x1b - ret nz ; give up if not an escape character - - ; Escape characters need parameters, starting with one. - xor a - ld (commandgot), a - inc a - ld (commandlen), a - ret - -; Helper routine: deal with command bytes (passed in C). -queue_command_byte: - ; Write the byte to the buffer. - - ld hl, commandgot - ld d, 0 - ld e, (hl) - inc (hl) - - ld hl, commandbuf - add hl, de - ld (hl), c - - ; Have we reached the end of the buffer? - - ld hl, commandlen - ld a, (commandgot) - cp (hl) - ret nz ; no, go back for more bytes. - xor a - ld (hl), a ; end of command - - ; Process a command. - - ld a, (commandbuf+0) - cp 'B' - jr z, setresetattr - cp 'C' - jr z, setresetattr - cp 'E' - jp z, tty_insert_line - cp 'R' - jp z, tty_delete_line - cp '=' - jr z, gotoxy - ret - -; Helper routine: handles set/reset tty_attributes. -setresetattr: - ld a, (commandgot) ; B, C takes parameters - cp 2 ; do we have enough bytes? - jr z, .1 ; yes, execute command - ld a, 2 ; not enough bytes read yet - ld (commandlen), a - ret -.1: - ld a, (commandbuf+1) - cp '0' ; reverse intensity - ret nz ; don't support anything else - ld a, (commandbuf+0) ; B=on, C=off - ld hl, tty_attributes - res 0, (hl) - bit 0, a - ret nz - set 0, (hl) - ret - -; Helper routine: handles ESC = (gotoxy). -gotoxy: - ld a, (commandgot) ; = takes parameters - cp 3 ; do we have enough bytes? - jr z, .1 ; yes, execute command - ld a, 3 ; not enough bytes read yet - ld (commandlen), a - ret -.1: - ld hl, commandbuf+1 ; got enough bytes; process command - ld a, (hl) - sub 32 - ld c, a ; Y - inc hl - ld a, (hl) - sub 32 - ld b, a ; X - jp tty_goto_xy - -tty_putc: - ; Check to see if there's a pending command. - - ld c, a - ld a, (commandlen) - or a - jr nz, queue_command_byte - - ; Handle special characters. - - ld a, c - cp 32 - jp c, controlcharacter - - ; This is a printable character, so print it. - - call tty_rawwrite - - ; Now we've drawn a character, advance the cursor. - - ld hl, tty_cursorx - ld a, (hl) - inc a - ld (hl), a - cp SCREEN_WIDTH - ret nz - - ; Reached the end of the line? Advance to the next one and go back to - ; the margin. - - xor a - ld (hl), a - jp tty_cursor_down - -; vim: sw=4 ts=4 expandtab ft=asm - diff --git a/arch/nc200/supervisor/build.lua b/arch/nc200/supervisor/build.lua index ad64eee..c57226f 100644 --- a/arch/nc200/supervisor/build.lua +++ b/arch/nc200/supervisor/build.lua @@ -28,11 +28,10 @@ zmac { "include/*.lib", "arch/common/utils/deblocker.lib", "arch/common/utils/tty.lib", + "arch/common/utils/adm3a.lib", "arch/nc200/include/*.lib", "arch/nc200+addresses_lib", "./*.inc", - "+keytab_inc", - "+font_inc", }, } @@ -43,5 +42,6 @@ zmac { "include/*.lib", "arch/nc200/include/*.lib", "+font_inc", + "+keytab_inc", }, } diff --git a/arch/nc200/supervisor/keyboard.inc b/arch/nc200/supervisor/keyboard.inc index 2d921b8..76d5ebf 100644 --- a/arch/nc200/supervisor/keyboard.inc +++ b/arch/nc200/supervisor/keyboard.inc @@ -41,10 +41,10 @@ process_keyboard_event: ld b, 0 ld c, a ld a, (keyboard_modifiers) - ld hl, keyboard_normal_map + ld hl, KEYNORM bit MODIFIER_BIT_SHIFT, a jr z, .2 - ld hl, keyboard_shifted_map + ld hl, KEYSHIFT .2: add hl, bc ld a, (hl) @@ -170,5 +170,3 @@ kbd_get_next_key: ei ret -.include "keytab.inc" - diff --git a/arch/nc200/supervisor/startup.inc b/arch/nc200/supervisor/startup.inc index 84c76c7..976dcca 100644 --- a/arch/nc200/supervisor/startup.inc +++ b/arch/nc200/supervisor/startup.inc @@ -8,7 +8,9 @@ label STARTUP ld sp, SYSSTK call init_interrupts - call tty_init + ld a, VIDEORAM_BASE>>8 + out (PORT_DISPLAY_MEMORY_ADDR), a ; set base address of video RAM + call adm3a_init ld hl, str.banner call tty_puts call pcmcia_init diff --git a/arch/nc200/supervisor/supervisor.z80 b/arch/nc200/supervisor/supervisor.z80 index c347cc4..5262c9e 100644 --- a/arch/nc200/supervisor/supervisor.z80 +++ b/arch/nc200/supervisor/supervisor.z80 @@ -19,6 +19,8 @@ extern DRVBDPB extern FDBUF extern FONT + extern KEYNORM + extern KEYSHIFT extern PBAUD extern SYSOUT extern SYSSTK diff --git a/arch/nc200/supervisor/tty.inc b/arch/nc200/supervisor/tty.inc index 3798ffc..a498f05 100644 --- a/arch/nc200/supervisor/tty.inc +++ b/arch/nc200/supervisor/tty.inc @@ -12,108 +12,19 @@ BYTES_PER_LINE equ BYTES_PER_SCANLINE * FONT_HEIGHT LAST_LINE equ VIDEORAM_BASE + (SCREEN_HEIGHT-1) * BYTES_PER_LINE VIDEORAM_END equ LAST_LINE + BYTES_PER_LINE -cursorx: db 0 -cursory: db 0 cursor_shown: db 0 -commandlen: db 0 -commandgot: db 0 -commandbuf: ds 3 - -tty_init: - ld a, VIDEORAM_BASE>>8 - out (PORT_DISPLAY_MEMORY_ADDR), a ; set base address of video RAM - call tty_clear_screen - ret - -; --- Prints a zero-terminated string in HL --------------------------------- - -; Prints a zero-terminated string in hl. -tty_puts: - ld a, (hl) - or a - ret z - inc hl - push hl - call tty_putc - pop hl - jr tty_puts - -; --- Prints the hex bytes in HL or A --------------------------------------- - -; prints HL -tty_puthex16: - ld a, h - call tty_puthex8 - ld a, l -tty_puthex8: - ld c, a - rra - rra - rra - rra - call tty_puthex8_conv - ld a, c -tty_puthex8_conv: - and 15 - add a, 0x90 - daa - adc a, 0x40 - daa - push hl - push bc - call tty_putc - pop bc - pop hl - ret - -; --- Prints the decimal number in HL --------------------------------------- - -tty_putdec16: - ld d, 0 ; suppress zeroes - ld bc, -10000 - call .1 - ld bc, -1000 - call .1 - ld bc, -100 - call .1 - ld bc, -10 - call .1 - dec d ; don't suppress this zero - ld bc, -1 -.1 ; loop which prints one digit - ld a, '0'-1 -.2 - inc a - add hl, bc - jr c, .2 ; keep subtracting bc to get one digit - sbc hl, bc ; under last subtraction (carry is known to be clear) - - ; Did we get a zero? - cp '0' - jr z, .3 - ; Not a zero. - dec d ; don't suppress zeroes any more -.4 - push hl ; print the digit - push de - call tty_putc - pop de - pop hl - ret - - ; We got a zero. -.3 - bit 7, d ; are we suppressing zeroes? - ret z ; yes. - jr .4 ; no, so print it anyway. +EMULATE_CLEAR_TO_EOL = 1 +EMULATE_CLEAR_TO_EOS = 0 + maclib adm3a + maclib tty ; --- Calculates the address of the cursor ---------------------------------- ; Sets cursor_screen_address to the address of the current char. tty_calculate_screen_address: - ld a, (cursory) + ld a, (tty_cursory) add a, a ld de, line_address_table ld h, 0 @@ -128,7 +39,7 @@ tty_calculate_screen_address: ; character is at; this is the same as cursorx*3/4, which will also ; fit in a byte (80*3 == 240). - ld a, (cursorx) + ld a, (tty_cursorx) ld b, a add a, a ; a = cursorx*2 add a, b ; a = cursorx*2 + cursorx = cursorx*3 @@ -264,37 +175,8 @@ tty_draw_cursor_loop: pop af ret -; --- Clears (and initialises) the screen ----------------------------------- - -tty_clear_screen: - call tty_home_cursor - jr tty_clear_to_eos - -tty_home_cursor: - xor a - ld (cursorx), a - ld (cursory), a - ret - ; --- Screen clearing ------------------------------------------------------- -tty_clear_to_eol: - ld a, (cursorx) - push af -.1: - ld a, (cursorx) - cp SCREEN_WIDTH - jr z, .2 - ld a, ' ' - call tty_rawwrite - ld hl, cursorx - inc (hl) - jr .1 -.2: - pop af - ld (cursorx), a - ret - tty_clear_to_eos: ; Compute the start of the area to clear. @@ -318,65 +200,7 @@ tty_clear_to_eos: ld (hl), 0 ldir - jr tty_clear_to_eol ; we haven't cleared the rest of this line - -; --- Performs a carriage return -------------------------------------------- - -tty_newline: - call tty_cursor_down - ; fall through -tty_carriagereturn: - xor a - ld (cursorx), a - ret - -; --- Move the cursor ------------------------------------------------------- - -tty_cursor_left: - ld hl, cursorx - dec (hl) - ret p - inc (hl) - ret - -tty_cursor_up: - ld hl, cursory - dec (hl) - ret p - inc (hl) - ret - -tty_cursor_right: - ld hl, cursorx - ld a, (hl) - inc a - cp SCREEN_WIDTH - ret z - ld (hl), a - ret - -tty_cursor_down: - ld hl, cursory - ld a, (hl) - inc a - ld (hl), a - cp SCREEN_HEIGHT - ret nz - dec (hl) ; oops, don't go the next line after all - jp tty_scroll - -; Move to (B, C). -tty_goto_xy: - ld a, b - cp SCREEN_WIDTH - ret nc - ld (cursorx), a - - ld a, c - cp SCREEN_HEIGHT - ret nc - ld (cursory), a - ret + jp tty_clear_to_eol ; we haven't cleared the rest of this line ; --- Line insertion/removal ------------------------------------------------ @@ -444,149 +268,6 @@ calculate_insert_delete_size: ex de, hl ret -; --- Prints the character in A --------------------------------------------- -; (also tty_newline) - -; Helper routine: called from tty_putc if this is a non-printable control -; character. The character is in A. -controlcharacter: - cp 0x08 - jp z, tty_cursor_left - cp 0x0c - jr z, tty_cursor_right - cp 0x0a - jr z, tty_cursor_down - cp 0x0b - jp z, tty_cursor_up - cp 0x1e - jp z, tty_home_cursor - cp 0x0d - jp z, tty_carriagereturn - cp 0x18 - jp z, tty_clear_to_eol - cp 0x17 - jp z, tty_clear_to_eos - cp 0x1a - jp z, tty_clear_screen - cp 0x1b - ret nz ; give up if not an escape character - - ; Escape characters need parameters, starting with one. - xor a - ld (commandgot), a - inc a - ld (commandlen), a - ret - -; Helper routine: deal with command bytes (passed in C). -queue_command_byte: - ; Write the byte to the buffer. - - ld hl, commandgot - ld d, 0 - ld e, (hl) - inc (hl) - - ld hl, commandbuf - add hl, de - ld (hl), c - - ; Have we reached the end of the buffer? - - ld hl, commandlen - ld a, (commandgot) - cp (hl) - ret nz ; no, go back for more bytes. - xor a - ld (hl), a ; end of command - - ; Process a command. - - ld a, (commandbuf+0) - cp 'B' - jr z, setresetattr - cp 'C' - jr z, setresetattr - cp 'E' - jp z, tty_insert_line - cp 'R' - jp z, tty_delete_line - cp '=' - jr z, gotoxy - ret - -; Helper routine: handles set/reset attributes. -setresetattr: - ld a, (commandgot) ; B, C takes parameters - cp 2 ; do we have enough bytes? - jr z, .1 ; yes, execute command - ld a, 2 ; not enough bytes read yet - ld (commandlen), a - ret -.1: -; ld a, (commandbuf+1) -; cp '0' ; reverse intensity -; ret nz ; don't support anything else -; ld a, (commandbuf+0) -; cp 'C' ; B=on, C=off -; ld hl, font_xor_value -; ld (hl), 0 -; ret z -; dec (hl) - ret - -; Helper routine: handles ESC = (gotoxy). -gotoxy: - ld a, (commandgot) ; = takes parameters - cp 3 ; do we have enough bytes? - jr z, .1 ; yes, execute command - ld a, 3 ; not enough bytes read yet - ld (commandlen), a - ret -.1: - ld hl, commandbuf+1 ; got enough bytes; process command - ld a, (hl) - sub 32 - ld c, a ; Y - inc hl - ld a, (hl) - sub 32 - ld b, a ; X - jp tty_goto_xy - -tty_putc: - ; Check to see if there's a pending command. - - ld c, a - ld a, (commandlen) - or a - jr nz, queue_command_byte - - ; Handle special characters. - - ld a, c - cp 32 - jp c, controlcharacter - - ; This is a printable character, so print it. - - call tty_rawwrite - - ; Now we've drawn a character, advance the cursor. - - ld hl, cursorx - ld a, (hl) - inc a - ld (hl), a - cp SCREEN_WIDTH - ret nz - - ; Reached the end of the line? Advance to the next one. - - xor a - ld (hl), a - jp tty_cursor_down - ; Writes A to the current cursor location, without advancing the cursor. tty_rawwrite: @@ -712,17 +393,3 @@ scanline_shift_amount: ex de, hl ; put font pointer back in HL ret -; --- Scrolls the screen by one line ---------------------------------------- - -tty_scroll: - ld de, VIDEORAM_BASE - ld hl, VIDEORAM_BASE + BYTES_PER_LINE - ld bc, LAST_LINE - VIDEORAM_BASE - ldir - ld h, d - ld l, e - inc de - ld bc, BYTES_PER_LINE - 1 - ld (hl), 0 - ldir - ret diff --git a/arch/nc200/supervisor/variables.z80 b/arch/nc200/supervisor/variables.z80 index b285cb5..4d9b39c 100644 --- a/arch/nc200/supervisor/variables.z80 +++ b/arch/nc200/supervisor/variables.z80 @@ -38,6 +38,12 @@ label PBAUD label FONT include "font.inc" + global KEYNORM +KEYNORM equ keyboard_normal_map + global KEYSHIFT +KEYSHIFT equ keyboard_shifted_map + include "keytab.inc" + supervisor_stack: ds 64 label SYSSTK diff --git a/arch/wp2450ds/tty.z80 b/arch/wp2450ds/tty.z80 index ab98024..137c0ca 100644 --- a/arch/wp2450ds/tty.z80 +++ b/arch/wp2450ds/tty.z80 @@ -25,8 +25,9 @@ EMULATE_CLEAR_TO_EOL = 1 EMULATE_CLEAR_TO_EOS = 0 maclib tty + maclib adm3a -TTYINIT equ tty_init +TTYINIT equ adm3a_init TTYPUTC equ tty_putc TTYPUT8 equ tty_puthex8 TTYPUT16 equ tty_puthex16 diff --git a/third_party/ld80/build.lua b/third_party/ld80/build.lua index 1cdcbeb..ee22467 100644 --- a/third_party/ld80/build.lua +++ b/third_party/ld80/build.lua @@ -51,9 +51,9 @@ definerule("bintocom", srcs = { type="table" }, }, function (e) - return binrule { + return binslice { name = e.name, - src = { e.ins[1] }, + src = { e.srcs[1] }, start = 0x100 } end From 4fc3607b4a75e605ad67f65be10a3ed463c3eff9 Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 19 Sep 2020 23:44:50 +0200 Subject: [PATCH 02/10] Add the VT52 state machine and all the support machinery needed for it. Find a fix a whole slew of bugs in the NC200 tty. There's no keyboard support yet. --- arch/common/utils/adm3a.lib | 4 +- arch/common/utils/tty.lib | 46 +++++--- arch/common/utils/vt52.lib | 171 +++++++++++++++++++++++++++++ arch/nc200/build.lua | 2 +- arch/nc200/supervisor/build.lua | 2 +- arch/nc200/supervisor/startup.inc | 2 +- arch/nc200/supervisor/tty.inc | 22 ++-- arch/wp2450ds/build.lua | 2 +- cpmtools/libcuss/libcuss.h | 2 +- third_party/bbcbasic/build.lua | 1 + third_party/bbcbasic/vt52/boot.z80 | 133 ++++++++++++++++++++++ third_party/ted/nc200/config.inc | 2 +- third_party/zmac/build.lua | 2 +- 13 files changed, 360 insertions(+), 31 deletions(-) create mode 100644 arch/common/utils/vt52.lib create mode 100644 third_party/bbcbasic/vt52/boot.z80 diff --git a/arch/common/utils/adm3a.lib b/arch/common/utils/adm3a.lib index 76d5841..e2e9a42 100644 --- a/arch/common/utils/adm3a.lib +++ b/arch/common/utils/adm3a.lib @@ -26,7 +26,7 @@ controlcharacter: cp 0x0c jp z, tty_cursor_right cp 0x0a - jp z, tty_cursor_down + jp z, tty_cursor_down_and_scroll cp 0x0b jp z, tty_cursor_up cp 0x1e @@ -38,7 +38,7 @@ controlcharacter: cp 0x17 jp z, tty_clear_to_eos cp 0x1a - jp z, tty_clear_screen + jp z, tty_clear_home cp 0x1b ret nz ; give up if not an escape character diff --git a/arch/common/utils/tty.lib b/arch/common/utils/tty.lib index 875c983..dbe0866 100644 --- a/arch/common/utils/tty.lib +++ b/arch/common/utils/tty.lib @@ -15,17 +15,16 @@ tty_attributes: db 0 ; --- Clears (and initialises) the screen ----------------------------------- tty_init: - xra a + xor a ld (tty_attributes), a ; fall through -tty_clear_screen: +tty_clear_home: call tty_home_cursor - jp tty_clear_to_eos + jr tty_clear_to_eos tty_home_cursor: - xor a - ld (tty_cursorx), a - ld (tty_cursory), a + ld hl, 0 + ld (tty_cursorx), hl ret ; --- Prints a zero-terminated string in HL --------------------------------- @@ -155,13 +154,13 @@ tty_clear_to_eos: .2 pop hl ld (tty_cursorx), hl - jp tty_clear_to_eol + jr tty_clear_to_eol endif ; --- Performs a carriage return -------------------------------------------- tty_newline: - call tty_cursor_down + call tty_cursor_down_and_scroll ; fall through tty_carriagereturn: xor a @@ -177,11 +176,17 @@ tty_cursor_left: inc (hl) ret +tty_cursor_up_and_scroll: + call tty_cursor_up + ret p + jr tty_insert_line + +; Returns m if we were on the top line. tty_cursor_up: ld hl, tty_cursory dec (hl) ret p - inc (hl) + ld (hl), 0 ret tty_cursor_right: @@ -193,14 +198,19 @@ tty_cursor_right: ld (hl), a ret +; Returns z if we were on the top line. tty_cursor_down: ld hl, tty_cursory - ld a, (hl) - inc a - ld (hl), a + inc (hl) + ld a, (hl) cp SCREEN_HEIGHT ret nz - dec (hl) ; oops, don't go the next line after all + ld (hl), SCREEN_HEIGHT-1; oops, don't go the next line after all + ret + +tty_cursor_down_and_scroll: + call tty_cursor_down + ret nz tty_scroll: ld hl, tty_cursory ld a, (hl) @@ -224,3 +234,13 @@ tty_goto_xy: ld (tty_cursory), a ret +tty_tab: + ld a, 32 + call tty_putc + ld a, (tty_cursorx) + and 0xf8 + jr nz, tty_tab + ret + +; vim: sw=4 ts=4 expandtab ft=asm + diff --git a/arch/common/utils/vt52.lib b/arch/common/utils/vt52.lib new file mode 100644 index 0000000..eb26ed0 --- /dev/null +++ b/arch/common/utils/vt52.lib @@ -0,0 +1,171 @@ +; cpmish BIOS © 2020 David Given +; This file is distributable under the terms of the 2-clause BSD license. +; See COPYING.cpmish in the distribution root directory for more information. + +; This is a general purpose VT52 state machine. It provides tty_putc and calls +; out to tty.lib. + +commandlen: db 0 +commandgot: db 0 +commandbuf: ds 4 + +; --- Clears (and initialises) the screen ----------------------------------- + +vt52_init: + xor a + ld (commandlen), a + jr tty_init + +; --- Prints the character in A --------------------------------------------- + +tty_putc: + ; Check to see if there's a pending command. + + ld c, a + ld a, (commandlen) + or a + jr nz, queue_command_byte + + ; Handle special characters. + + ld a, c + cp 32 + jr c, controlcharacter + + ; This is a printable character, so print it. + + call tty_rawwrite + + ; Now we've drawn a character, advance the cursor. + + ld hl, tty_cursorx + ld a, (hl) + inc a + ld (hl), a + cp SCREEN_WIDTH + ret nz + + ; Reached the end of the line? Advance to the next one and go back to + ; the margin. + + xor a + ld (hl), a + jr tty_cursor_down + +; Helper routine: deal with command bytes (passed in C). +queue_command_byte: + ; Write the byte to the buffer. + + ld hl, commandgot + ld d, 0 + ld e, (hl) + inc (hl) + + ld hl, commandbuf + add hl, de + ld (hl), c + + ; Have we reached the end of the buffer? + + ld hl, commandlen + ld a, (commandgot) + cp (hl) + ret nz ; no, go back for more bytes. + xor a + ld (hl), a ; end of command + + ; Process a command. + + ld a, (commandbuf+0) + cp 'A' + jr z, tty_cursor_up + cp 'B' + jr z, tty_cursor_down + cp 'C' + jr z, tty_cursor_right + cp 'D' + jr z, tty_cursor_left + cp 'E' + jr z, tty_clear_screen + cp 'H' + jr z, tty_home_cursor + cp 'I' + jr z, tty_cursor_up_and_scroll + cp 'J' + jr z, tty_clear_to_eos + cp 'K' + jr z, tty_clear_to_eol + cp 'L' + jr z, tty_insert_line + cp 'M' + jr z, tty_delete_line + cp 'p' + jr z, revonoff + cp 'q' + jr z, revonoff + cp 'Y' + jr z, gotoxy + ret + +; The command character is in a. 'p'=0x70 is on, 'q'=0x71 is off. +revonoff: + ld hl, tty_attributes + res 0, (hl) + bit 0, a + ret nz + set 0, (hl) + ret + +; Helper routine: called from tty_putc if this is a non-printable control +; character. The character is in A. +controlcharacter: + cp 0x08 + jr z, tty_cursor_left + cp 0x09 + jr z, tty_tab + cp 0x0a + jr z, tty_cursor_down_and_scroll + cp 0x0d + jr z, tty_carriagereturn + cp 0x1b + ret nz ; give up if not an escape character + + ; Escape characters need parameters, starting with one. + xor a + ld (commandgot), a + inc a + ld (commandlen), a + ret + +; Handles both the initial parsing of the command (when we just see the Y) and +; the final parsing (when we see the parameters). +gotoxy: + ld a, (commandgot) ; Y takes parameters + cp 3 ; do we have enough bytes? + jr z, .1 ; yes, execute command + ld a, 3 ; not enough bytes read yet + ld (commandlen), a + ret +.1: + ld hl, commandbuf+1 ; got enough bytes; process command + ld a, (hl) + sub 32 + ld c, a ; Y + inc hl + ld a, (hl) + sub 32 + ld b, a ; X + jr tty_goto_xy + +; Clears the screen without homing. +tty_clear_screen: + ld hl, (tty_cursorx) + push hl + call tty_clear_home + pop hl + ld (tty_cursorx), hl + ret + +; vim: sw=4 ts=4 expandtab ft=asm + + diff --git a/arch/nc200/build.lua b/arch/nc200/build.lua index b6db0d4..adddada 100644 --- a/arch/nc200/build.lua +++ b/arch/nc200/build.lua @@ -148,7 +148,7 @@ diskimage { ["asm.com"] = "cpmtools+asm", ["copy.com"] = "cpmtools+copy", ["submit.com"] = "cpmtools+submit", - ["bbcbasic.com"] = "third_party/bbcbasic+bbcbasic_ADM3A", + ["bbcbasic.com"] = "third_party/bbcbasic+bbcbasic_VT52", ["qe.com"] = "cpmtools+qe_NC200", ["flash.com"] = "arch/nc200/tools+flash", ["flipdisk.com"] = "arch/nc200/tools+flipdisk", diff --git a/arch/nc200/supervisor/build.lua b/arch/nc200/supervisor/build.lua index c57226f..ff16a85 100644 --- a/arch/nc200/supervisor/build.lua +++ b/arch/nc200/supervisor/build.lua @@ -28,7 +28,7 @@ zmac { "include/*.lib", "arch/common/utils/deblocker.lib", "arch/common/utils/tty.lib", - "arch/common/utils/adm3a.lib", + "arch/common/utils/vt52.lib", "arch/nc200/include/*.lib", "arch/nc200+addresses_lib", "./*.inc", diff --git a/arch/nc200/supervisor/startup.inc b/arch/nc200/supervisor/startup.inc index 976dcca..dcec3e4 100644 --- a/arch/nc200/supervisor/startup.inc +++ b/arch/nc200/supervisor/startup.inc @@ -10,7 +10,7 @@ label STARTUP call init_interrupts ld a, VIDEORAM_BASE>>8 out (PORT_DISPLAY_MEMORY_ADDR), a ; set base address of video RAM - call adm3a_init + call vt52_init ld hl, str.banner call tty_puts call pcmcia_init diff --git a/arch/nc200/supervisor/tty.inc b/arch/nc200/supervisor/tty.inc index a498f05..9dc11e4 100644 --- a/arch/nc200/supervisor/tty.inc +++ b/arch/nc200/supervisor/tty.inc @@ -16,7 +16,7 @@ cursor_shown: db 0 EMULATE_CLEAR_TO_EOL = 1 EMULATE_CLEAR_TO_EOS = 0 - maclib adm3a + maclib vt52 maclib tty ; --- Calculates the address of the cursor ---------------------------------- @@ -108,11 +108,11 @@ tty_calculate_screen_address_of_line: ; Returns z if we're on the last line of the screen. tty_calculate_screen_address_of_next_line: call tty_calculate_screen_address_of_line - ld bc, 64 + ld bc, BYTES_PER_LINE add hl, bc ; get address of start of *next* line ld (L_cursor_address), hl ld bc, VIDEORAM_END - or a + and a sbc hl, bc add hl, bc ret @@ -200,7 +200,7 @@ tty_clear_to_eos: ld (hl), 0 ldir - jp tty_clear_to_eol ; we haven't cleared the rest of this line + jr tty_clear_to_eol ; we haven't cleared the rest of this line ; --- Line insertion/removal ------------------------------------------------ @@ -233,7 +233,7 @@ _clear_current_line: tty_delete_line: call tty_calculate_screen_address_of_next_line - jr z, _clear_current_line ; if we're on the last line, just clear it + jr z, .1 ; if we're on the last line, just clear it ; Compute the size of the area to move call calculate_insert_delete_size @@ -242,13 +242,14 @@ tty_delete_line: push hl ld de, -BYTES_PER_LINE - add hl, de ; Start of *current* line, source - pop de ; Start of *next* line, dest - ex de, hl ; Copy from next line to current line + add hl, de ; Start of *current* line + ex de, hl ; -> de, dest + pop hl ; Start of *next* line, src ldir ; Clear the last line. +.1: ld hl, LAST_LINE ld de, LAST_LINE + 1 ld bc, BYTES_PER_LINE - 1 @@ -260,7 +261,7 @@ tty_delete_line: ; On exit: HL is preserved; BC contains the amount to move. calculate_insert_delete_size: ex de, hl ; stash start address in DE - ld hl, VIDEORAM_END - 1 + ld hl, VIDEORAM_END and a ; clear carry flag sbc hl, de ; HL is amount to clear ld b, h @@ -393,3 +394,6 @@ scanline_shift_amount: ex de, hl ; put font pointer back in HL ret +; vim: sw=4 ts=4 expandtab ft=asm + + diff --git a/arch/wp2450ds/build.lua b/arch/wp2450ds/build.lua index 2275bca..97f22f3 100644 --- a/arch/wp2450ds/build.lua +++ b/arch/wp2450ds/build.lua @@ -7,7 +7,7 @@ include "utils/build.lua" -- Configure the BIOS size here; this will then emit an addresses.lib file -- which contains the position of the BDOS and CCP. -local BIOS_SIZE = 0x0f00 +local BIOS_SIZE = 0x1000 local BDOS_SIZE = 3584 -- fixed local CCP_SIZE = 2048 -- fixed local BBASE = 0x10000 - BIOS_SIZE diff --git a/cpmtools/libcuss/libcuss.h b/cpmtools/libcuss/libcuss.h index 89f2c0e..579b5b5 100644 --- a/cpmtools/libcuss/libcuss.h +++ b/cpmtools/libcuss/libcuss.h @@ -28,7 +28,7 @@ extern void con_revoff(void); #elif defined LIBCUSS_NC200 #define SCREENWIDTH 80 #define SCREENHEIGHT 18 - #define LIBCUSS_ADM3 + #define LIBCUSS_VT52 #elif defined LIBCUSS_BROTHEROP2 #define SCREENWIDTH 80 #define SCREENHEIGHT 14 diff --git a/third_party/bbcbasic/build.lua b/third_party/bbcbasic/build.lua index 3d35e25..03c2bea 100644 --- a/third_party/bbcbasic/build.lua +++ b/third_party/bbcbasic/build.lua @@ -3,6 +3,7 @@ include "third_party/zmac/build.lua" local VERSIONS = { "ADM3A", + "VT52", } local srcs = {"cmos", "eval", "exec", "fpp", "main", "ram", "sorry"} diff --git a/third_party/bbcbasic/vt52/boot.z80 b/third_party/bbcbasic/vt52/boot.z80 new file mode 100644 index 0000000..3353397 --- /dev/null +++ b/third_party/bbcbasic/vt52/boot.z80 @@ -0,0 +1,133 @@ +; This is a completely generic VT52 machine. + + + aseg + org 0x100 + + extrn START + +BDOS equ 5 + +; Initial startup. + + jp START + +; BYE: exit to CP/M + + global BYE +BYE equ 0 + +; Helper tool: prints A. +putc: + ld c, 2 + ld e, a + jp BDOS + +; Helper tool: prints ESC, A +putesc: + push af + ld a, 27 + call putc + pop af + jp putc + +; CLRSCN: clears the screen. + + global CLRSCN +CLRSCN: + push bc + ld a, 'H' + call putesc ; home + ld a, 'J' + call putesc ; clear to EOS + pop bc + ret + +; PUTIME: set current time to DE:HL, in centiseconds. + + global PUTIME +PUTIME: + ret + +; GETIME: return current time in DE:HL, in centiseconds. + + global GETIME +GETIME: + ld de, 0 + ld hl, 0 + ret + +; PUTCSR: move to cursor to x=DE, y=HL + + global PUTCSR +PUTCSR: + push bc + push de + push hl + ld a, 'Y' + call putesc ; goto Y, X + pop hl + ld a, 32 + add l + call putc + pop hl + ld a, 32 + add l + call putc + pop bc + ret + +; GETCSR: return cursor position in x=DE, y=HL + + global GETCSR +GETCSR: + ld de, 0 + ld hl, 0 + ret + +; GETKEY: return key with timeout +; HL = time to wait in centiseconds +; Returns C if character recieved, with character in A +; Returns !C if timeout + + global GETKEY +GETKEY: + push bc +.1 + ld c, 6 ; poll character + ld e, 0xff + call BDOS + or a + jr z, .1 ; repeat if no character + scf ; set carry + pop bc + ret + +; Edit key table, which must be at 0x01F4 + + if $ > 0x1f4 + error 'Insufficient space in boot block' + endif + + org 0x01f4 + defb 80 ;WIDTH + defb 11 ;CURSOR UP + defb 10 ;CURSOR DOWN + defb 'A' and 1FH ;START OF LINE + defb 'E' and 1FH ;END OF LINE + defb 'C' and 1FH ;DELETE TO END OF LINE + defb 7FH ;BACKSPACE & DELETE + defb 'U' AND 1FH ;CANCEL LINE + defb 8 ;CURSOR LEFT + defb 12 ;CURSOR RIGHT + defb 'D' AND 1FH ;DELETE CHARACTER + defb 'F' AND 1FH ;INSERT CHARACTER + + if $ != 0x200 + error 'Edit block wrong length' + endif +;; +;FIN: END + +; vim: ts=8 sw=8 et ft=asm + diff --git a/third_party/ted/nc200/config.inc b/third_party/ted/nc200/config.inc index 3d24b30..a61f073 100644 --- a/third_party/ted/nc200/config.inc +++ b/third_party/ted/nc200/config.inc @@ -1,4 +1,4 @@ HSIZE equ 80 VSIZE equ 18 -ADM3A equ TRUE +VT52 equ TRUE diff --git a/third_party/zmac/build.lua b/third_party/zmac/build.lua index 80505bc..9a7b3a4 100644 --- a/third_party/zmac/build.lua +++ b/third_party/zmac/build.lua @@ -46,7 +46,7 @@ definerule("zmac", outleaves = { e.name..ext, e.name..".lst" }, deps = e.deps, commands = { - "%{ins[1]} --zmac -m "..relflag.." "..archflag.." -o %{outs[1]} -o %{outs[2]} %{hdrpaths} %{ins[2]}" + "%{ins[1]} --zmac -j -m "..relflag.." "..archflag.." -o %{outs[1]} -o %{outs[2]} %{hdrpaths} %{ins[2]}" }, vars = { hdrpaths = hdrpaths, From 96b00c22c38010aec24ad52175883f80fbc87226 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 20 Sep 2020 00:05:31 +0200 Subject: [PATCH 03/10] Add support for generating VT52 cursor key sequences from the NC200 BIOS. libcuss can't handle them, though. --- arch/common/utils/vt52.lib | 2 +- arch/nc200/supervisor/keyboard.inc | 33 +++++++++++++++++++++++++++ arch/nc200/utils/mkkeytab.c | 8 +++---- third_party/ted/termdef.mac | 36 ++++++++++++++---------------- 4 files changed, 55 insertions(+), 24 deletions(-) diff --git a/arch/common/utils/vt52.lib b/arch/common/utils/vt52.lib index eb26ed0..c4f413f 100644 --- a/arch/common/utils/vt52.lib +++ b/arch/common/utils/vt52.lib @@ -107,7 +107,7 @@ queue_command_byte: jr z, gotoxy ret -; The command character is in a. 'p'=0x70 is on, 'q'=0x71 is off. +; The command character is in A. 'p'=0x70 is on, 'q'=0x71 is off. revonoff: ld hl, tty_attributes res 0, (hl) diff --git a/arch/nc200/supervisor/keyboard.inc b/arch/nc200/supervisor/keyboard.inc index 76d5ebf..af84709 100644 --- a/arch/nc200/supervisor/keyboard.inc +++ b/arch/nc200/supervisor/keyboard.inc @@ -37,6 +37,14 @@ process_keyboard_event: cp 0x10 ; caps lock key jr z, caps_change + cp 0x3b + jr z, cursor_up + cp 0x33 + jr z, cursor_right + cp 0x31 + jr z, cursor_down + cp 0x03 + jr z, cursor_left ld b, 0 ld c, a @@ -96,6 +104,29 @@ caps_change: ld (hl), a ret +cursor_up: + ld a, 'A' + jr push_cursor_key + +cursor_right: + ld a, 'C' + jr push_cursor_key + +cursor_down: + ld a, 'B' + jr push_cursor_key + +cursor_left: + ld a, 'D' + ; fall through +; Pushes 27, A. +push_cursor_key: + push af + ld a, 27 + call queue_key + pop af + jr queue_key + keyboard_modifiers: db 0 @@ -170,3 +201,5 @@ kbd_get_next_key: ei ret +; vim: sw=4 ts=4 expandtab ft=asm + diff --git a/arch/nc200/utils/mkkeytab.c b/arch/nc200/utils/mkkeytab.c index 6bea497..aeba39e 100644 --- a/arch/nc200/utils/mkkeytab.c +++ b/arch/nc200/utils/mkkeytab.c @@ -73,7 +73,7 @@ int main(int argc, const char* argv[]) key(0x4f, '.', '>'); key(0x35, '/', '?'); key(0x01, 0, 0); // right shift - key(0x3b, 11, 11); // cursor up + key(0x3b, 1, 1); // cursor up key(0x08, 0, 0); // yellow key(0x09, 0, 0); // ctrl @@ -81,9 +81,9 @@ int main(int argc, const char* argv[]) key(0x0b, ' ', ' '); key(0x3a, 92, '|'); key(0x3c, 0, 0); // menu - key(0x03, 8, 8); // cursor left - key(0x33, 12, 12); // cursor right - key(0x31, 10, 10); // cursor down + key(0x03, 1, 1); // cursor left + key(0x33, 1, 1); // cursor right + key(0x31, 1, 1); // cursor down printf("keyboard_normal_map:\n"); for (int i=0; i Date: Sun, 20 Sep 2020 00:35:25 +0200 Subject: [PATCH 04/10] libcuss now knows about VT52 cursor keys... at the expense of no longer being 8-bit safe. --- cpmtools/libcuss/getc.c | 20 +++++++++++++++++++- cpmtools/libcuss/libcuss.h | 12 ++++-------- cpmtools/qe.c | 2 +- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/cpmtools/libcuss/getc.c b/cpmtools/libcuss/getc.c index b691690..cc828b2 100644 --- a/cpmtools/libcuss/getc.c +++ b/cpmtools/libcuss/getc.c @@ -8,7 +8,25 @@ uint8_t con_getc(void) { - return cpm_bios_conin(); + #if defined LIBCUSS_VT52 + uint16_t i; + uint8_t c = cpm_bios_conin(); + if (c != 27) + return c; + + i = 1000; + while (--i) + { + c = cpm_bios_const(); + if (c == 0xff) + break; + } + if (c == 0) + return 27; + return cpm_bios_conin() | 0x80; + #else + return cpm_bios_conin(); + #endif } diff --git a/cpmtools/libcuss/libcuss.h b/cpmtools/libcuss/libcuss.h index 579b5b5..fa2699e 100644 --- a/cpmtools/libcuss/libcuss.h +++ b/cpmtools/libcuss/libcuss.h @@ -71,14 +71,10 @@ extern void con_revoff(void); #define LIBCUSS_REVON "\033p" #define LIBCUSS_REVOFF "\033q" - #define LIBCUSS_KEY_LEFT "\010" - #define LIBCUSS_KEY_DOWN "\012" - #define LIBCUSS_KEY_UP "\013" - #define LIBCUSS_KEY_RIGHT "\014" - //#define LIBCUSS_KEY_LEFT "\033[D" - //#define LIBCUSS_KEY_DOWN "\033[B" - //#define LIBCUSS_KEY_UP "\033[A" - //#define LIBCUSS_KEY_RIGHT "\033[C" + #define LIBCUSS_KEY_LEFT "\304" + #define LIBCUSS_KEY_DOWN "\302" + #define LIBCUSS_KEY_UP "\301" + #define LIBCUSS_KEY_RIGHT "\303" #endif #if defined LIBCUSS_ANSI diff --git a/cpmtools/qe.c b/cpmtools/qe.c index 3075488..46d548e 100644 --- a/cpmtools/qe.c +++ b/cpmtools/qe.c @@ -125,7 +125,7 @@ void set_status_line(const char* message) con_revoff(); while (length < status_line_length) { - cpm_bios_conout(' '); + con_putc(' '); length++; } status_line_length = length; From 13710b9628b2fb2b00d745f863748981a57d1d94 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 20 Sep 2020 00:41:23 +0200 Subject: [PATCH 05/10] Hack BBC Basic to use sort-of WordStar keys, because it can't handle VT52 cursor keys. --- third_party/bbcbasic/vt52/boot.z80 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/third_party/bbcbasic/vt52/boot.z80 b/third_party/bbcbasic/vt52/boot.z80 index 3353397..bd7a096 100644 --- a/third_party/bbcbasic/vt52/boot.z80 +++ b/third_party/bbcbasic/vt52/boot.z80 @@ -114,14 +114,14 @@ GETKEY: defb 11 ;CURSOR UP defb 10 ;CURSOR DOWN defb 'A' and 1FH ;START OF LINE - defb 'E' and 1FH ;END OF LINE + defb 'F' and 1FH ;END OF LINE defb 'C' and 1FH ;DELETE TO END OF LINE defb 7FH ;BACKSPACE & DELETE defb 'U' AND 1FH ;CANCEL LINE - defb 8 ;CURSOR LEFT - defb 12 ;CURSOR RIGHT - defb 'D' AND 1FH ;DELETE CHARACTER - defb 'F' AND 1FH ;INSERT CHARACTER + defb 'S' AND 1FH ;CURSOR LEFT + defb 'D' AND 1FH ;CURSOR RIGHT + defb 'G' AND 1FH ;DELETE CHARACTER + defb 'H' AND 1FH ;INSERT CHARACTER if $ != 0x200 error 'Edit block wrong length' From 4cd594a72c4f24c4f94d772958e790501cda0795 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 20 Sep 2020 00:45:40 +0200 Subject: [PATCH 06/10] Document NC200 change to VT52. --- arch/nc200/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/nc200/README.md b/arch/nc200/README.md index 72faf5b..c6597bf 100644 --- a/arch/nc200/README.md +++ b/arch/nc200/README.md @@ -18,7 +18,7 @@ What you get with this port: - support for a hard drive of up to 32MB on a Compact Flash card (note: not SRAM) - CCP and BDOS cached in RAM for instant warm reboots -- most of an ADM-3a / Kaypro II terminal emulator supporting 80x18 text +- most of an VT52 terminal emulator supporting 80x18 text - a gigantic 60kB TPA - an interrupt-driven keyboard - parallel printer support From c55de460400ada4be2c5f7eba2d5f562c24feb8b Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 20 Sep 2020 00:50:31 +0200 Subject: [PATCH 07/10] Fix Z8E to work with the NC200's VT52. --- third_party/z8e/nc200/config.inc | 2 +- third_party/z8e/src/vt52.tty | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/third_party/z8e/nc200/config.inc b/third_party/z8e/nc200/config.inc index 0845392..099fc81 100644 --- a/third_party/z8e/nc200/config.inc +++ b/third_party/z8e/nc200/config.inc @@ -1,5 +1,5 @@ z180 equ false -conterm equ adm3a +conterm equ vt52 auxterm equ none CPM3 equ false SCRHT equ 18 diff --git a/third_party/z8e/src/vt52.tty b/third_party/z8e/src/vt52.tty index e4c5603..fba20fa 100644 --- a/third_party/z8e/src/vt52.tty +++ b/third_party/z8e/src/vt52.tty @@ -150,13 +150,6 @@ mxy0: call ttyo ; Send character to terminal dec e ; Count down jr nz,mxy0 ; Loop until all sent - ld a,(mrow4) ; Row first or column first? - and a - jr nz,mxy1 ; Skip if row first - ld a,b ; x,y addressing, interchange row and column - ld b,c - ld c,a -mxy1: ld a,b ; Send first coordinate call ttyo ld a,c ; Send second coordinate From fff8e21a4b9459d38521433a16bc6e7e5ea807d9 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 20 Sep 2020 11:46:04 +0200 Subject: [PATCH 08/10] Treat the yellow key like a control key. --- arch/nc200/supervisor/keyboard.inc | 2 ++ arch/nc200/supervisor/pcmcia.inc | 3 +++ arch/nc200/supervisor/startup.inc | 2 ++ 3 files changed, 7 insertions(+) diff --git a/arch/nc200/supervisor/keyboard.inc b/arch/nc200/supervisor/keyboard.inc index af84709..cbdae37 100644 --- a/arch/nc200/supervisor/keyboard.inc +++ b/arch/nc200/supervisor/keyboard.inc @@ -27,6 +27,8 @@ process_keyboard_event: and 0x7f cp 0x09 ; control key jr z, ctrl_change + cp 0x08 ; yellow key + jr z, ctrl_change and 0x7e jr z, shift_change diff --git a/arch/nc200/supervisor/pcmcia.inc b/arch/nc200/supervisor/pcmcia.inc index 50e368a..9014528 100644 --- a/arch/nc200/supervisor/pcmcia.inc +++ b/arch/nc200/supervisor/pcmcia.inc @@ -332,3 +332,6 @@ str.ide_error: db "IDE error: ", 0 str.ata_card: db "PCMCIA card found: ", 0 str.not_ata: db "Card is not ATA", 13, 10, 0 str.no_card: db "No PCMCIA card found", 13, 10, 0 + +; vim: sw=4 ts=4 expandtab ft=asm + diff --git a/arch/nc200/supervisor/startup.inc b/arch/nc200/supervisor/startup.inc index dcec3e4..d54738e 100644 --- a/arch/nc200/supervisor/startup.inc +++ b/arch/nc200/supervisor/startup.inc @@ -121,3 +121,5 @@ str.loading: str.ready: db "Ready", 10, 13, 0 +; vim: sw=4 ts=4 expandtab ft=asm + From 17e2354519ca3df2ff1070385e9981097e13b788 Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 20 Sep 2020 12:10:25 +0200 Subject: [PATCH 09/10] Marginally speed up the tty, but using eight-bit aligned font data rather than trying to pack it cleverly. Doesn't appear to make a noticeable difference in real life, sadly. --- arch/nc200/supervisor/tty.inc | 50 ++++++---------------------------- arch/nc200/utils/fontconvert.c | 27 ++++-------------- 2 files changed, 15 insertions(+), 62 deletions(-) diff --git a/arch/nc200/supervisor/tty.inc b/arch/nc200/supervisor/tty.inc index 9dc11e4..fb922dd 100644 --- a/arch/nc200/supervisor/tty.inc +++ b/arch/nc200/supervisor/tty.inc @@ -288,6 +288,8 @@ tty_rawwrite: ld e, a ld d, 0 add hl, de ; hl = a*4 + a = a*5 + add hl, de ; hl = a*5 + a = a*6 + add hl, de ; hl = a*6 + a = a*7 ld de, FONT add hl, de ; hl points at font data @@ -296,53 +298,18 @@ tty_rawwrite: ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - - ld b, (hl) ; ?????XXX.XX?????? - inc hl - ld a, (hl) - srl b - rra - srl b - rra - srl b - rra + ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - - ld a, (hl) ; ??XXXXX? - add a, a - add a, a + ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - - ld a, (hl) ; ???????X.XXXX???? - srl a - inc hl - ld a, (hl) - rra + ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - - ld a, (hl) ; ????XXXX.X??????? - inc hl - ld b, (hl) - sll b - rla - add a, a - add a, a - add a, a + ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - - ld a, (hl) ; ?XXXXX?? - add a, a + ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - - ld b, (hl) ; ??????XX.XXX????? - inc hl - ld a, (hl) - srl b - rra - srl b - rra + ld a, (hl) ; XXXXX???.???????? ; fall through - ; On entry, the font data is in A, left justified. ; Font pointer is in HL. draw_single_scanline: @@ -392,6 +359,7 @@ scanline_shift_amount: ld (L_cursor_address), hl ex de, hl ; put font pointer back in HL + inc hl ; advance to next byte of font data ret ; vim: sw=4 ts=4 expandtab ft=asm diff --git a/arch/nc200/utils/fontconvert.c b/arch/nc200/utils/fontconvert.c index e8c6b94..fc8adfa 100644 --- a/arch/nc200/utils/fontconvert.c +++ b/arch/nc200/utils/fontconvert.c @@ -37,33 +37,18 @@ int main(int argc, const char* argv[]) /* The glyph data is a 7-element array of bytes. Each byte contains * one scanline, left justified. */ - uint64_t mask = 0; - const uint8_t* p = glyph->data; - + printf("\tdb "); int yy = 0; + const uint8_t* p = glyph->data; while (yy < LINEHEIGHT) { - /* We assume the right-most column is blank, and so only store five bits. */ - - mask = (mask << 5) | ((*p >> 3) & 0x1f); + if (yy != 0) + printf(", "); + printf("0x%02x", *p); p++; yy++; } - - /* The encoding expects 8 5-bit values in five bytes, *left* justified. */ - while (yy < 8) - { - mask <<= 5; - yy++; - } - - printf("\tdb 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x ; char %d\n", - (uint32_t)((mask >> 32) & 0xff), - (uint32_t)((mask >> 24) & 0xff), - (uint32_t)((mask >> 16) & 0xff), - (uint32_t)((mask >> 8) & 0xff), - (uint32_t)(mask & 0xff), - c); + printf(" ; char %d\n", c); } return 0; From b990203e7b1d8aa632a19e940114cf892e24801b Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 20 Sep 2020 13:00:54 +0200 Subject: [PATCH 10/10] Minor fixes and cycle shaving. --- arch/common/utils/adm3a.lib | 2 +- arch/common/utils/vt52.lib | 2 +- arch/nc200/supervisor/tty.inc | 15 ++++----------- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/arch/common/utils/adm3a.lib b/arch/common/utils/adm3a.lib index e2e9a42..4263518 100644 --- a/arch/common/utils/adm3a.lib +++ b/arch/common/utils/adm3a.lib @@ -157,7 +157,7 @@ tty_putc: xor a ld (hl), a - jp tty_cursor_down + jr tty_cursor_down_and_scroll ; vim: sw=4 ts=4 expandtab ft=asm diff --git a/arch/common/utils/vt52.lib b/arch/common/utils/vt52.lib index c4f413f..fa7bbf6 100644 --- a/arch/common/utils/vt52.lib +++ b/arch/common/utils/vt52.lib @@ -50,7 +50,7 @@ tty_putc: xor a ld (hl), a - jr tty_cursor_down + jr tty_cursor_down_and_scroll ; Helper routine: deal with command bytes (passed in C). queue_command_byte: diff --git a/arch/nc200/supervisor/tty.inc b/arch/nc200/supervisor/tty.inc index fb922dd..5bb68e9 100644 --- a/arch/nc200/supervisor/tty.inc +++ b/arch/nc200/supervisor/tty.inc @@ -292,28 +292,22 @@ tty_rawwrite: add hl, de ; hl = a*6 + a = a*7 ld de, FONT add hl, de - ; hl points at font data + ex de, hl + ; de points at font data ; We are now *finally* ready to start drawing. - ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - ld a, (hl) ; XXXXX???.???????? call draw_single_scanline - ld a, (hl) ; XXXXX???.???????? ; fall through ; On entry, the font data is in A, left justified. ; Font pointer is in HL. draw_single_scanline: - ex de, hl ; save font pointer in DE + ld a, (de) and 0xf8 ld l, a ld h, 0 @@ -358,8 +352,7 @@ scanline_shift_amount: add hl, bc ld (L_cursor_address), hl - ex de, hl ; put font pointer back in HL - inc hl ; advance to next byte of font data + inc de ; advance to next byte of font data ret ; vim: sw=4 ts=4 expandtab ft=asm