diff --git a/keyboard.asm b/keyboard.asm index 81b60ee..c086911 100644 --- a/keyboard.asm +++ b/keyboard.asm @@ -8,6 +8,10 @@ keyboard_update: cmp r0, 0 ifz jmp keyboard_update_end + ; invoke the debug monitor if F12 was pressed + cmp r0, 0x58 + ifz call invoke_monitor + ; check if this is a make or break scancode bts r0, 7 ifnz jmp keyboard_update_break_scancode diff --git a/main.asm b/main.asm index 5917afd..c327389 100644 --- a/main.asm +++ b/main.asm @@ -150,6 +150,7 @@ get_rom_version: #include "memory.asm" #include "menu.asm" #include "menu_bar.asm" + #include "monitor/monitor.asm" #include "mouse.asm" #include "overlay.asm" #include "panic.asm" @@ -261,7 +262,7 @@ const MENU_POSITION_Y: 0x02137186 ; 2 bytes const MENU_FRAMEBUFFER_PTR: 0x0213718A ; 4 bytes const MENU_FRAMEBUFFER: 0x0213718E -startup_str: data.str "fox32 - ROM version %u.%u.%u - insert boot disk" data.8 0 +startup_str: data.str "fox32 - ROM version %u.%u.%u - insert boot disk - F12 for monitor" data.8 0 menu_items_root: data.8 1 ; number of menus diff --git a/monitor/console.asm b/monitor/console.asm new file mode 100644 index 0000000..97e5812 --- /dev/null +++ b/monitor/console.asm @@ -0,0 +1,243 @@ +; debug monitor console routines + +; print a string to the monitor +; inputs: +; r0: pointer to null-terminated string +; r1: foreground color +; r2: background color +; outputs: +print_string_to_monitor: + push r0 + push r3 + mov r3, r0 +print_string_to_monitor_loop: + movz.8 r0, [r3] + call print_character_to_monitor + inc r3 + cmp.8 [r3], 0x00 + ifnz jmp print_string_to_monitor_loop + pop r3 + pop r0 + ret + +; print a single character to the monitor +; inputs: +; r0: character +; r1: foreground color +; r2: background color +; outputs: +; none +print_character_to_monitor: + push r0 + push r1 + push r2 + push r3 + push r4 + push r5 + + mov r3, r1 + mov r4, r2 + + 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, 10 ; line feed + ifz jmp print_character_to_monitor_lf + + ; check if we are at the end of this line + cmp.8 [MONITOR_CONSOLE_X], MONITOR_CONSOLE_X_SIZE + ; if so, increment to the next line + ifgteq mov.8 [MONITOR_CONSOLE_X], 0 + ifgteq inc.8 [MONITOR_CONSOLE_Y] + + ; check if we need to scroll the display + cmp.8 [MONITOR_CONSOLE_Y], MONITOR_CONSOLE_Y_SIZE + ifgteq call scroll_monitor_console + + ; calculate coords for character... + movz.8 r1, [MONITOR_CONSOLE_X] + movz.8 r2, [MONITOR_CONSOLE_Y] + mul r2, MONITOR_CONSOLE_X_SIZE + add r1, r2 + add r1, MONITOR_CONSOLE_TEXT_BUF + + ; ...and print!! + mov.8 [r1], r0 + inc.8 [MONITOR_CONSOLE_X] + jmp print_character_to_monitor_end +print_character_to_monitor_cr: + ; return to the beginning of the line + mov.8 [MONITOR_CONSOLE_X], 0 + call redraw_monitor_console + jmp print_character_to_monitor_end +print_character_to_monitor_lf: + ; return to the beginning of the line and increment the line + mov.8 [MONITOR_CONSOLE_X], 0 + inc.8 [MONITOR_CONSOLE_Y] + ; scroll the display if needed + cmp.8 [MONITOR_CONSOLE_Y], MONITOR_CONSOLE_Y_SIZE + ifgteq call scroll_monitor_console + call redraw_monitor_console +print_character_to_monitor_end: + pop r5 + pop r4 + pop r3 + pop r2 + pop r1 + pop r0 + ret + +; scroll the console +; inputs: +; none +; outputs: +; none +; FIXME: this shouldnt have hard coded values +; also this is extremely slow and bad +scroll_monitor_console: + push r0 + push r1 + push r2 + push r31 + + ; source + mov r0, MONITOR_CONSOLE_TEXT_BUF + add r0, MONITOR_CONSOLE_X_SIZE + + ; destination + mov r1, MONITOR_CONSOLE_TEXT_BUF + + ; size + mov r2, MONITOR_CONSOLE_X_SIZE + mul r2, 28 + + call copy_memory_bytes + + mov.8 [MONITOR_CONSOLE_X], 0 + mov.8 [MONITOR_CONSOLE_Y], 28 + + ; clear the last line + mov r0, MONITOR_CONSOLE_TEXT_BUF + add r0, 2240 ; 80 * 28 + mov r31, MONITOR_CONSOLE_X_SIZE +scroll_monitor_console_clear_loop: + mov.8 [r0], 0 + inc r0 + loop scroll_monitor_console_clear_loop + + ; redraw the screen + call redraw_monitor_console + + pop r31 + pop r2 + pop r1 + pop r0 + ret + +; redraw the whole console +; inputs: +; none +; outputs: +; none +redraw_monitor_console: + push r0 + push r1 + push r2 + push r3 + push r4 + push r5 + push r6 + push r31 + + mov r0, MONITOR_CONSOLE_TEXT_BUF + mov r1, 0 + mov r2, 16 + mov r3, TEXT_COLOR + mov r4, MONITOR_BACKGROUND_COLOR + mov r5, 31 + mov r31, MONITOR_CONSOLE_Y_SIZE +redraw_monitor_console_loop_y: + push r31 + mov r1, 0 + mov r31, MONITOR_CONSOLE_X_SIZE +redraw_monitor_console_loop_x: + push r0 + movz.8 r0, [r0] + call draw_font_tile_to_overlay + movz.8 r0, [standard_font_width] + add r1, r0 + pop r0 + inc r0 + loop redraw_monitor_console_loop_x + pop r31 + movz.8 r6, [standard_font_height] + add r2, r6 + loop redraw_monitor_console_loop_y + + pop r31 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r1 + pop r0 + ret + +; redraw only the current line +; inputs: +; none +; outputs: +; none +redraw_monitor_console_line: + push r0 + push r1 + push r2 + push r3 + push r4 + push r5 + push r6 + push r31 + + movz.8 r0, [MONITOR_CONSOLE_Y] + mul r0, MONITOR_CONSOLE_X_SIZE + add r0, MONITOR_CONSOLE_TEXT_BUF + + movz.8 r1, [MONITOR_CONSOLE_Y] + mov r2, 16 + mul r2, r1 + add r2, 16 + + mov r1, 0 + mov r3, TEXT_COLOR + mov r4, MONITOR_BACKGROUND_COLOR + mov r5, 31 + + mov r1, 0 + mov r31, MONITOR_CONSOLE_X_SIZE +redraw_monitor_console_line_loop_x: + push r0 + movz.8 r0, [r0] + call draw_font_tile_to_overlay + movz.8 r0, [standard_font_width] + add r1, r0 + pop r0 + inc r0 + loop redraw_monitor_console_line_loop_x + + pop r31 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r1 + pop r0 + ret + +const MONITOR_CONSOLE_X: 0x03ED3FDB ; 1 byte +const MONITOR_CONSOLE_Y: 0x03ED3FDA ; 1 byte +const MONITOR_CONSOLE_TEXT_BUF: 0x03ED36CA ; 2320 bytes (80x29) +const MONITOR_CONSOLE_X_SIZE: 80 +const MONITOR_CONSOLE_Y_SIZE: 29 diff --git a/monitor/keyboard.asm b/monitor/keyboard.asm new file mode 100644 index 0000000..f1300a5 --- /dev/null +++ b/monitor/keyboard.asm @@ -0,0 +1,62 @@ +; debug monitor keyboard routines + +; convert a make scancode to an ASCII character +; inputs: +; r0: make scancode +; outputs: +; r0: ASCII character +scancode_to_ascii: + add r0, scancode_table + movz.8 r0, [r0] + + 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 +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 + data.str "asdfghjkl;'`" data.8 0 data.8 92 + data.str "zxcvbnm,./" data.8 0 data.str "*" data.8 0 data.str " " + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.str "-" data.8 0 data.8 0 data.8 0 data.str "+" + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 +scancode_table_shift: + data.8 0 data.8 27 data.str "!@#$%^&*()_+" data.8 8 + data.8 9 data.str "QWERTYUIOP{}" data.8 10 data.8 0 + data.str "ASDFGHJKL:" data.8 34 data.str "~" data.8 0 data.str "|" + data.str "ZXCVBNM<>?" data.8 0 data.str "*" data.8 0 data.str " " + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.str "-" data.8 0 data.8 0 data.8 0 data.str "+" + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 +scancode_table_caps: + data.8 0 data.8 27 data.str "1234567890-=" data.8 8 + data.8 9 data.str "QWERTYUIOP[]" data.8 10 data.8 0 + data.str "ASDFGHJKL;'`" data.8 0 data.8 92 + data.str "ZXCVBNM,./" data.8 0 data.str "*" data.8 0 data.str " " + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.8 0 data.8 0 data.8 0 data.8 0 + data.str "-" data.8 0 data.8 0 data.8 0 data.str "+" + data.8 0 data.8 0 data.8 0 data.8 0 + 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 diff --git a/monitor/monitor.asm b/monitor/monitor.asm new file mode 100644 index 0000000..d763187 --- /dev/null +++ b/monitor/monitor.asm @@ -0,0 +1,85 @@ +; debug monitor + +invoke_monitor: + ; set the vsync handler to our own and reenable interrupts + ; TODO: save the old vsync handler for when the monitor exits!!! + 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 + dec.8 [MONITOR_CONSOLE_Y] + + ; set properties of overlay 31 + mov r0, 0x8000001F ; overlay 31: position + mov.16 r1, MONITOR_POSITION_Y + sla r1, 16 + mov.16 r1, MONITOR_POSITION_X + out r0, r1 + mov r0, 0x8000011F ; overlay 31: size + mov.16 r1, MONITOR_HEIGHT + sla r1, 16 + mov.16 r1, MONITOR_WIDTH + out r0, r1 + mov r0, 0x8000021F ; overlay 31: framebuffer pointer + mov r1, MONITOR_FRAMEBUFFER_PTR + out r0, r1 + + mov r0, MONITOR_BACKGROUND_COLOR + mov r1, 31 + call fill_overlay + + mov r0, info_str + mov r1, 256 + mov r2, 0 + mov r3, TEXT_COLOR + mov r4, 0x00000000 + mov r5, 31 + call draw_str_to_overlay + + mov r0, 0 + mov r1, 15 + mov r2, 640 + mov r3, 1 + mov r4, TEXT_COLOR + mov r5, 31 + call draw_filled_rectangle_to_overlay + +monitor_event_loop: + call get_next_event + + ; 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 + mov r1, TEXT_COLOR + mov r2, 0x00000000 + call print_character_to_monitor + call redraw_monitor_console_line + ret + +info_str: data.str "fox32rom monitor" data.8 0x00 + + #include "monitor/console.asm" + #include "monitor/keyboard.asm" + #include "monitor/vsync.asm" + +const MONITOR_TEXT_BUF_BOTTOM: 0x03ED3FE0 ; 32 characters +const MONITOR_TEXT_BUF_PTR: 0x03ED3FDC ; 4 bytes + +const MONITOR_BACKGROUND_COLOR: 0xFF282828 + +const MONITOR_WIDTH: 640 +const MONITOR_HEIGHT: 480 +const MONITOR_POSITION_X: 0 +const MONITOR_POSITION_Y: 0 +const MONITOR_FRAMEBUFFER_PTR: 0x03ED4000 diff --git a/monitor/vsync.asm b/monitor/vsync.asm new file mode 100644 index 0000000..b03a622 --- /dev/null +++ b/monitor/vsync.asm @@ -0,0 +1,23 @@ +; debug monitor vsync routine + +monitor_vsync_handler: + push r0 + push r1 + push r2 + push r3 + push r4 + push r5 + push r6 + push r7 + + call keyboard_update + + pop r7 + pop r6 + pop r5 + pop r4 + pop r3 + pop r2 + pop r1 + pop r0 + reti