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..4263518 --- /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_and_scroll + 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_home + 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 + jr tty_cursor_down_and_scroll + +; 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..dbe0866 100644 --- a/arch/common/utils/tty.lib +++ b/arch/common/utils/tty.lib @@ -2,38 +2,29 @@ ; 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 + 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 --------------------------------- @@ -163,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 @@ -185,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: @@ -201,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) @@ -232,149 +234,13 @@ 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 +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..fa7bbf6 --- /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_and_scroll + +; 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/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 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 ad64eee..ff16a85 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/vt52.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..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 @@ -37,14 +39,22 @@ 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 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) @@ -96,6 +106,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,5 +203,5 @@ kbd_get_next_key: ei ret -.include "keytab.inc" +; vim: sw=4 ts=4 expandtab ft=asm 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 84c76c7..d54738e 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 vt52_init ld hl, str.banner call tty_puts call pcmcia_init @@ -119,3 +121,5 @@ str.loading: str.ready: db "Ready", 10, 13, 0 +; vim: sw=4 ts=4 expandtab ft=asm + 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..5bb68e9 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 vt52 + 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 @@ -197,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 @@ -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. @@ -320,64 +202,6 @@ tty_clear_to_eos: 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 - ; --- Line insertion/removal ------------------------------------------------ tty_insert_line: @@ -409,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 @@ -418,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 @@ -436,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 @@ -444,149 +269,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: @@ -606,65 +288,26 @@ 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 + 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 b, (hl) ; ?????XXX.XX?????? - inc hl - ld a, (hl) - srl b - rra - srl b - rra - srl b - rra call draw_single_scanline - - ld a, (hl) ; ??XXXXX? - add a, a - add a, a call draw_single_scanline - - ld a, (hl) ; ???????X.XXXX???? - srl a - inc hl - ld a, (hl) - rra 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 call draw_single_scanline - - ld a, (hl) ; ?XXXXX?? - add a, a call draw_single_scanline - - ld b, (hl) ; ??????XX.XXX????? - inc hl - ld a, (hl) - srl b - rra - srl b - rra ; 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 @@ -709,20 +352,9 @@ scanline_shift_amount: add hl, bc ld (L_cursor_address), hl - ex de, hl ; put font pointer back in HL + inc de ; advance to next byte of font data ret -; --- Scrolls the screen by one line ---------------------------------------- +; vim: sw=4 ts=4 expandtab ft=asm + -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/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; 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 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 '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 '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' + endif +;; +;FIN: END + +; vim: ts=8 sw=8 et ft=asm + 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 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/ted/termdef.mac b/third_party/ted/termdef.mac index c99b3b6..d3b8718 100644 --- a/third_party/ted/termdef.mac +++ b/third_party/ted/termdef.mac @@ -51,7 +51,6 @@ ifdef VT100 vtname: db 'VT100',0,0,0,0,0,0,0,0,0 -vtsize: db 80,24 ; width, height vclscr: db 6,ESC,'[H',ESC,'[J',0 vcleos: db 3,ESC,'[J',0,0,0,0 vcleol: db 3,ESC,'[K',0,0,0,0 @@ -76,28 +75,27 @@ vscrlrg:db 1,'r',0,0,0,0,0,0 endif ifdef VT52 -vtname: db 'VT52',0,0,0,0,0,0,0,0,0,0 -vtsize: db 80,24 ; width, height -vclscr: db 4,ESC,'H',ESC,'J',0,0,0 -vcleos: db 2,ESC,'J',0,0,0,0,0 -vcleol: db 2,ESC,'K',0,0,0,0,0 -vcurup: db 2,ESC,'A',0,0,0,0,0 -vcurdn: db 2,ESC,'B',0,0,0,0,0 -vcurrgt:db 2,ESC,'C',0,0,0,0,0 -vcurlft:db 2,ESC,'D',0,0,0,0,0 -vhome: db 2,ESC,'H',0,0,0,0,0 -vcurprf:db 2,ESC,'Y',0,0,0,0,0 -vcursep:db 0,0,0,0,0,0,0,0 -vcurpst:db 0,0,0,0,0,0,0,0 +vtname: db 'VT52',0 +vclscr: db 4,ESC,'H',ESC,'J' +vcleos: db 2,ESC,'J' +vcleol: db 2,ESC,'K' +vcurup: db 2,ESC,'A' +vcurdn: db 2,ESC,'B' +vcurrgt:db 2,ESC,'C' +vcurlft:db 2,ESC,'D' +vhome: db 2,ESC,'H' +vcurprf:db 2,ESC,'Y' +vcursep:db 0 +vcurpst:db 0 vcurbcd:db FALSE vcuryof:db 32 vcurxof:db 32 vxfirst:db FALSE -vfwdidx:db 1,LF,0,0,0,0,0,0 -vrevidx:db 2,ESC,'I',0,0,0,0,0 -vinsln: db 0,0,0,0,0,0,0,0 -vdelln: db 0,0,0,0,0,0,0,0 -vscrlrg:db 0,0,0,0,0,0,0,0 +vfwdidx:db 1,LF +vrevidx:db 2,ESC,'I' +vinsln: db 0 +vdelln: db 0 +vscrlrg:db 0 endif ifdef ADM3A 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 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,