From 408bd6c91d5f4ab46c7a52895880b74f13185ba2 Mon Sep 17 00:00:00 2001 From: Ry Date: Sat, 23 Apr 2022 15:01:47 -0700 Subject: [PATCH] monitor: handle shift and caps keys --- monitor/console.asm | 12 +++- monitor/keyboard.asm | 53 ++++++++++++++--- monitor/monitor.asm | 25 ++------ monitor/shell.asm | 136 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 197 insertions(+), 29 deletions(-) create mode 100644 monitor/shell.asm diff --git a/monitor/console.asm b/monitor/console.asm index 54daeec..e8fa9c0 100644 --- a/monitor/console.asm +++ b/monitor/console.asm @@ -14,6 +14,7 @@ print_string_to_monitor_loop: inc r3 cmp.8 [r3], 0x00 ifnz jmp print_string_to_monitor_loop + call redraw_monitor_console_line pop r3 pop r0 ret @@ -30,10 +31,12 @@ print_character_to_monitor: cmp.8 r0, 0 ; null ifz jmp print_character_to_monitor_end - cmp.8 r0, 13 ; carriage return - ifz jmp print_character_to_monitor_cr + cmp.8 r0, 8 ; backspace + ifz jmp print_character_to_monitor_bs cmp.8 r0, 10 ; line feed ifz jmp print_character_to_monitor_lf + cmp.8 r0, 13 ; carriage return + ifz jmp print_character_to_monitor_cr ; check if we are at the end of this line cmp.8 [MONITOR_CONSOLE_X], MONITOR_CONSOLE_X_SIZE @@ -69,6 +72,11 @@ print_character_to_monitor_lf: cmp.8 [MONITOR_CONSOLE_Y], MONITOR_CONSOLE_Y_SIZE ifgteq call scroll_monitor_console call redraw_monitor_console + jmp print_character_to_monitor_end +print_character_to_monitor_bs: + ; go back one character + cmp.8 [MONITOR_CONSOLE_X], 0 + ifnz dec.8 [MONITOR_CONSOLE_X] print_character_to_monitor_end: pop r2 pop r1 diff --git a/monitor/keyboard.asm b/monitor/keyboard.asm index f1300a5..ed9677f 100644 --- a/monitor/keyboard.asm +++ b/monitor/keyboard.asm @@ -6,19 +6,56 @@ ; outputs: ; r0: ASCII character scancode_to_ascii: - add r0, scancode_table + push r1 + + mov r1, scancode_table + bts [MODIFIER_BITMAP], 0 + ifnz mov r1, scancode_table_shift + bts [MODIFIER_BITMAP], 1 + ifnz mov r1, scancode_table_caps + add r0, r1 movz.8 r0, [r0] + pop r1 + ret + +; set bit 0 in the modifier bitmap +; inputs: +; none +; outputs: +; none +shift_pressed: + bse [MODIFIER_BITMAP], 0 + + ret + +; clear bit 0 in the modifier bitmap +; inputs: +; none +; outputs: +; none +shift_released: + bcl [MODIFIER_BITMAP], 0 + + ret + +; toggle bit 1 in the modifier bitmap +; inputs: +; none +; outputs: +; none +caps_pressed: + bts [MODIFIER_BITMAP], 1 + ifz bse [MODIFIER_BITMAP], 1 + ifnz bcl [MODIFIER_BITMAP], 1 + ret ; scancode set 1: ; https://wiki.osdev.org/PS/2_Keyboard#Scan_Code_Set_1 -const LSHIFT_PRESS: 0x2A -const LSHIFT_RELEASE: 0xAA -const RSHIFT_PRESS: 0x36 -const RSHIFT_RELEASE: 0xB6 -const CAPS_PRESS: 0x3A -const CAPS_RELEASE: 0xBA +const LSHIFT: 0x2A +const RSHIFT: 0x36 +const CAPS: 0x3A scancode_table: data.8 0 data.8 27 data.str "1234567890-=" data.8 8 data.8 9 data.str "qwertyuiop[]" data.8 10 data.8 0 @@ -59,4 +96,4 @@ scancode_table_caps: data.8 0 data.8 0 data.8 0 data.8 0 data.8 0 data.8 0 data.8 0 -const MONITOR_MODIFIER_BITMAP: 0x03ED3FDB ; 1 byte +const MODIFIER_BITMAP: 0x03ED36C9 ; 1 byte diff --git a/monitor/monitor.asm b/monitor/monitor.asm index 837e674..696a2fc 100644 --- a/monitor/monitor.asm +++ b/monitor/monitor.asm @@ -2,13 +2,10 @@ invoke_monitor: ; set the vsync handler to our own and reenable interrupts - ; TODO: save the old vsync handler for when the monitor exits!!! + mov [MONITOR_OLD_VSYNC_HANDLER], [0x000003FC] mov [0x000003FC], monitor_vsync_handler ise - ; set text buffer poinrer to the start of the text buffer - mov [MONITOR_TEXT_BUF_PTR], MONITOR_TEXT_BUF_BOTTOM - ; set the X and Y coords of the console text mov.8 [MONITOR_CONSOLE_X], 0 mov.8 [MONITOR_CONSOLE_Y], MONITOR_CONSOLE_Y_SIZE @@ -49,30 +46,20 @@ invoke_monitor: mov r5, 31 call draw_filled_rectangle_to_overlay -monitor_event_loop: - call get_next_event + call monitor_shell_start - ; was a key pressed? - cmp r0, EVENT_TYPE_KEY_DOWN - ifz call key_down_event - - jmp monitor_event_loop - -key_down_event: - mov r0, r1 - call scancode_to_ascii - call print_character_to_monitor - call redraw_monitor_console_line + ; restore the old vsync handler and exit + mov [0x000003FC], [MONITOR_OLD_VSYNC_HANDLER] ret info_str: data.str "fox32rom monitor" data.8 0x00 #include "monitor/console.asm" #include "monitor/keyboard.asm" + #include "monitor/shell.asm" #include "monitor/vsync.asm" -const MONITOR_TEXT_BUF_BOTTOM: 0x03ED3FE0 ; 32 characters -const MONITOR_TEXT_BUF_PTR: 0x03ED3FDC ; 4 bytes +const MONITOR_OLD_VSYNC_HANDLER: 0x03ED36C6 ; 4 bytes const MONITOR_BACKGROUND_COLOR: 0xFF282828 diff --git a/monitor/shell.asm b/monitor/shell.asm new file mode 100644 index 0000000..eb64307 --- /dev/null +++ b/monitor/shell.asm @@ -0,0 +1,136 @@ +; debug monitor shell + +monitor_shell_start: + mov.8 [MODIFIER_BITMAP], 0 + call monitor_shell_clear_buffer + mov r0, monitor_shell_prompt + call print_string_to_monitor + +monitor_shell_event_loop: + call get_next_event + + ; was a key pressed? + cmp r0, EVENT_TYPE_KEY_DOWN + ifz call monitor_shell_key_down_event + + ; was a key released? + cmp r0, EVENT_TYPE_KEY_UP + ifz call monitor_shell_key_up_event + + jmp monitor_shell_event_loop + +monitor_shell_key_down_event: + mov r0, r1 + + cmp.8 r0, LSHIFT + ifz jmp shift_pressed + cmp.8 r0, RSHIFT + ifz jmp shift_pressed + cmp.8 r0, CAPS + ifz jmp caps_pressed + + ; first, check if enter, delete, or backspace was pressed + cmp.8 r0, 0x1C ; enter + ifz jmp monitor_shell_key_down_event_enter + cmp.8 r0, 0x6F ; delete + ifz jmp monitor_shell_key_down_event_backspace + cmp.8 r0, 0x0E ; backspace + ifz jmp monitor_shell_key_down_event_backspace + + ; otherwise, add it to the text buffer and print it to the screen + call scancode_to_ascii + call print_character_to_monitor + call monitor_shell_push_character + call redraw_monitor_console_line + ret +monitor_shell_key_down_event_enter: + mov r0, 10 ; line feed + call print_character_to_monitor + call monitor_shell_parse_line + call monitor_shell_clear_buffer + mov r0, monitor_shell_prompt + call print_string_to_monitor + ret +monitor_shell_key_down_event_backspace: + ; delete the last character from the screen, and pop the last character from the buffer + mov r0, 8 ; backspace character + call print_character_to_monitor + mov r0, ' ' ; space character + call print_character_to_monitor + mov r0, 8 ; backspace character + call print_character_to_monitor + call monitor_shell_delete_character + call redraw_monitor_console_line + ret + +monitor_shell_key_up_event: + mov r0, r1 + + cmp.8 r0, LSHIFT + ifz jmp shift_released + cmp.8 r0, RSHIFT + ifz jmp shift_released + + ret + +monitor_shell_parse_line: + ret + +; push a character to the text buffer +; inputs: +; r0: character +; outputs: +; none +monitor_shell_push_character: + push r1 + + mov r1, [MONITOR_SHELL_TEXT_BUF_PTR] + cmp r1, MONITOR_SHELL_TEXT_BUF_TOP + ifgteq jmp monitor_shell_push_character_end + mov.8 [r1], r0 + inc [MONITOR_SHELL_TEXT_BUF_PTR] +monitor_shell_push_character_end: + pop r1 + ret + +; pop a character from the text buffer and zero it +; inputs: +; none +; outputs: +; r0: character +monitor_shell_delete_character: + push r1 + + mov r1, [MONITOR_SHELL_TEXT_BUF_PTR] + cmp r1, MONITOR_SHELL_TEXT_BUF_BOTTOM + iflteq jmp monitor_shell_pop_character_end + dec [MONITOR_SHELL_TEXT_BUF_PTR] + movz.8 r0, [r1] + mov.8 [r1], 0 +monitor_shell_pop_character_end: + pop r1 + ret + +; mark the text buffer as empty +; inputs: +; none +; outputs: +; none +monitor_shell_clear_buffer: + push r0 + + ; set the text buffer poinrer to the start of the text buffer + mov [MONITOR_SHELL_TEXT_BUF_PTR], MONITOR_SHELL_TEXT_BUF_BOTTOM + + ; set the first character as null + mov r0, [MONITOR_SHELL_TEXT_BUF_PTR] + mov.8 [r0], 0 + + pop r0 + ret + +const MONITOR_SHELL_TEXT_BUF_TOP: 0x03ED4000 +const MONITOR_SHELL_TEXT_BUF_BOTTOM: 0x03ED3FE0 ; 32 characters +const MONITOR_SHELL_TEXT_BUF_PTR: 0x03ED3FDC ; 4 bytes + +monitor_shell_prompt: data.str "> " data.8 0