From 6d7af284a1cd92f6e4d73feceabfbb0b1ac83223 Mon Sep 17 00:00:00 2001 From: Lawrence Kesteloot Date: Thu, 2 Aug 2018 16:26:42 -0700 Subject: [PATCH] Break runtime into different C file. --- .gitignore | 1 + Makefile | 11 ++-- main.c | 144 +-------------------------------------------------- runtime.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++ runtime.h | 25 +++++++++ 5 files changed, 181 insertions(+), 147 deletions(-) create mode 100644 runtime.c create mode 100644 runtime.h diff --git a/.gitignore b/.gitignore index f8807f3..b1dd852 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ tmp.lib main.s platform.s +runtime.s *.o *.dbg *.map diff --git a/Makefile b/Makefile index f268c84..fa7a9bd 100644 --- a/Makefile +++ b/Makefile @@ -17,14 +17,17 @@ $(ROM): a.out run: $(ROM) $(APPLE2E) -map main.map $(ROM) -a.out: main.o interrupt.o vectors.o exporter.o platform.o apple2rom.cfg $(LIB) - $(CC65)/ld65 -C apple2rom.cfg -m main.map --dbgfile main.dbg interrupt.o vectors.o exporter.o platform.o main.o $(LIB) +a.out: main.o interrupt.o vectors.o exporter.o platform.o runtime.o apple2rom.cfg $(LIB) + $(CC65)/ld65 -C apple2rom.cfg -m main.map --dbgfile main.dbg interrupt.o vectors.o exporter.o platform.o runtime.o main.o $(LIB) awk -f rom_usage.awk < main.map clean: - rm -f *.o *.lst a.out platform.s main.s $(LIB) tmp.lib + rm -f *.o *.lst a.out platform.s runtime.s main.s $(LIB) tmp.lib -main.s: main.c exporter.h platform.h +main.s: main.c exporter.h platform.h runtime.h + $(CC65)/cc65 -t none -O --cpu $(CPU) $< + +runtime.s: runtime.c runtime.h $(CC65)/cc65 -t none -O --cpu $(CPU) $< %.o: %.s diff --git a/main.c b/main.c index 632e445..4c664dd 100644 --- a/main.c +++ b/main.c @@ -1,13 +1,10 @@ #include "exporter.h" #include "platform.h" +#include "runtime.h" uint8_t *title = "Apple IIa"; uint8_t title_length = 9; -#define CURSOR_GLYPH 127 -#define SCREEN_WIDTH 40 -#define SCREEN_STRIDE (3*SCREEN_WIDTH + 8) - // 6502 instructions. #define I_CLC 0x18 #define I_JSR 0x20 @@ -35,13 +32,6 @@ static uint8_t *TOKEN[] = { }; static int16_t TOKEN_COUNT = sizeof(TOKEN)/sizeof(TOKEN[0]); -// Location of cursor in logical screen space. -uint16_t g_cursor_x = 0; -uint16_t g_cursor_y = 0; -// Whether the cursor is being displayed. -uint16_t g_showing_cursor = 0; -// Character at the cursor location. -uint8_t g_cursor_ch = 0; uint8_t g_input_buffer[40]; int16_t g_input_buffer_length = 0; @@ -57,123 +47,6 @@ void (*g_compiled_function)() = (void (*)()) g_compiled; // - Nul. uint8_t g_program[1024]; -/** - * Return the memory location of the cursor. - */ -static volatile uint8_t *cursor_pos() { - int16_t block = g_cursor_y >> 3; - int16_t line = g_cursor_y & 0x07; - - return TEXT_PAGE1_BASE + line*SCREEN_STRIDE + block*SCREEN_WIDTH + g_cursor_x; -} - -/** - * Shows the cursor. Safe to call if it's already showing. - */ -static void show_cursor() { - if (!g_showing_cursor) { - volatile uint8_t *pos = cursor_pos(); - g_cursor_ch = *pos; - *pos = CURSOR_GLYPH | 0x80; - g_showing_cursor = 1; - } -} - -/** - * Hides the cursor. Safe to call if it's not already shown. - */ -static void hide_cursor() { - if (g_showing_cursor) { - volatile uint8_t *pos = cursor_pos(); - *pos = g_cursor_ch; - g_showing_cursor = 0; - } -} - -/** - * Moves the cursor to the specified location, where X - * is 0 to 39 inclusive, Y is 0 to 23 inclusive. - */ -static void move_cursor(int16_t x, int16_t y) { - hide_cursor(); - g_cursor_x = x; - g_cursor_y = y; -} - -/** - * Clear the screen with non-reversed spaces. - */ -static void home() { - volatile uint8_t *p = TEXT_PAGE1_BASE; - uint8_t ch = ' ' | 0x80; - int16_t i; - - // TODO: Could write these as words, not chars. - for (i = SCREEN_STRIDE*8; i >= 0; i--) { - *p++ = ch; - } - - move_cursor(0, 0); -} - -/** - * Prints the character and advances the cursor. Handles newlines. - */ -static void print_char(uint8_t c) { - volatile uint8_t *loc = cursor_pos(); - - if (c == '\n') { - // TODO: Scroll. - move_cursor(0, g_cursor_y + 1); - } else { - // Print character. - *loc = c | 0x80; - move_cursor(g_cursor_x + 1, g_cursor_y); - } -} - -/** - * Print a string at the cursor. - */ -static void print(uint8_t *s) { - while (*s != '\0') { - print_char(*s++); - } -} - -/** - * Print an unsigned integer. - */ -static void print_int(uint16_t i) { - // Is this the best way to do this? I've seen it done backwards, where - // digits are added to a buffer least significant digit first, then reversed, - // but this seems faster. - char printed = 0; - if (i >= 10000) { - int16_t r = i / 10000; - print_char('0' + r); - i -= r*10000; - printed = 1; - } - if (i >= 1000 || printed) { - int16_t r = i / 1000; - print_char('0' + r); - i -= r*1000; - printed = 1; - } - if (i >= 100 || printed) { - int16_t r = i / 100; - print_char('0' + r); - i -= r*100; - printed = 1; - } - if (i >= 10 || printed) { - int16_t r = i / 10; - print_char('0' + r); - i -= r*10; - } - print_char('0' + i); -} /** * Copy a memory buffer. Source and destination may overlap. @@ -265,13 +138,6 @@ static uint8_t *get_end_of_program(uint8_t *line) { return line + 2; } -/** - * Print a single newline. - */ -static void print_newline() { - print_char('\n'); -} - /** * List the stored program. */ @@ -306,14 +172,6 @@ static uint8_t *skip_over(uint8_t *a, uint8_t *b) { return *b == '\0' ? a : 0; } -/** - * Display a syntax error message. - */ -static void syntax_error() { - print("\n?SYNTAX ERROR"); - // No linefeed, assume prompt will do it. -} - /** * Add a function call to the compiled buffer. */ diff --git a/runtime.c b/runtime.c new file mode 100644 index 0000000..855b7d5 --- /dev/null +++ b/runtime.c @@ -0,0 +1,147 @@ + +#include "runtime.h" + +#define CURSOR_GLYPH 127 +#define SCREEN_WIDTH 40 +#define SCREEN_STRIDE (3*SCREEN_WIDTH + 8) + +// Location of cursor in logical screen space. +uint16_t g_cursor_x = 0; +uint16_t g_cursor_y = 0; +// Whether the cursor is being displayed. +uint16_t g_showing_cursor = 0; +// Character at the cursor location. +uint8_t g_cursor_ch = 0; + +/** + * Return the memory location of the cursor. + */ +volatile uint8_t *cursor_pos(void) { + int16_t block = g_cursor_y >> 3; + int16_t line = g_cursor_y & 0x07; + + return TEXT_PAGE1_BASE + line*SCREEN_STRIDE + block*SCREEN_WIDTH + g_cursor_x; +} + +/** + * Shows the cursor. Safe to call if it's already showing. + */ +void show_cursor(void) { + if (!g_showing_cursor) { + volatile uint8_t *pos = cursor_pos(); + g_cursor_ch = *pos; + *pos = CURSOR_GLYPH | 0x80; + g_showing_cursor = 1; + } +} + +/** + * Hides the cursor. Safe to call if it's not already shown. + */ +void hide_cursor(void) { + if (g_showing_cursor) { + volatile uint8_t *pos = cursor_pos(); + *pos = g_cursor_ch; + g_showing_cursor = 0; + } +} + +/** + * Moves the cursor to the specified location, where X + * is 0 to 39 inclusive, Y is 0 to 23 inclusive. + */ +void move_cursor(int16_t x, int16_t y) { + hide_cursor(); + g_cursor_x = x; + g_cursor_y = y; +} + +/** + * Clear the screen with non-reversed spaces. + */ +void home(void) { + volatile uint8_t *p = TEXT_PAGE1_BASE; + uint8_t ch = ' ' | 0x80; + int16_t i; + + // TODO: Could write these as words, not chars. + for (i = SCREEN_STRIDE*8; i >= 0; i--) { + *p++ = ch; + } + + move_cursor(0, 0); +} + +/** + * Prints the character and advances the cursor. Handles newlines. + */ +void print_char(uint8_t c) { + volatile uint8_t *loc = cursor_pos(); + + if (c == '\n') { + // TODO: Scroll. + move_cursor(0, g_cursor_y + 1); + } else { + // Print character. + *loc = c | 0x80; + move_cursor(g_cursor_x + 1, g_cursor_y); + } +} + +/** + * Print a string at the cursor. + */ +void print(uint8_t *s) { + while (*s != '\0') { + print_char(*s++); + } +} + +/** + * Print an unsigned integer. + */ +void print_int(uint16_t i) { + // Is this the best way to do this? I've seen it done backwards, where + // digits are added to a buffer least significant digit first, then reversed, + // but this seems faster. + char printed = 0; + if (i >= 10000) { + int16_t r = i / 10000; + print_char('0' + r); + i -= r*10000; + printed = 1; + } + if (i >= 1000 || printed) { + int16_t r = i / 1000; + print_char('0' + r); + i -= r*1000; + printed = 1; + } + if (i >= 100 || printed) { + int16_t r = i / 100; + print_char('0' + r); + i -= r*100; + printed = 1; + } + if (i >= 10 || printed) { + int16_t r = i / 10; + print_char('0' + r); + i -= r*10; + } + print_char('0' + i); +} + +/** + * Print a single newline. + */ +void print_newline(void) { + print_char('\n'); +} + +/** + * Display a syntax error message. + */ +void syntax_error(void) { + print("\n?SYNTAX ERROR"); + // No linefeed, assume prompt will do it. +} diff --git a/runtime.h b/runtime.h new file mode 100644 index 0000000..fdc1474 --- /dev/null +++ b/runtime.h @@ -0,0 +1,25 @@ +#ifndef __RUNTIME_H__ +#define __RUNTIME_H__ + +#include "platform.h" + +extern uint16_t g_cursor_x; +extern uint16_t g_cursor_y; +extern uint16_t g_showing_cursor; +extern uint8_t g_cursor_ch; + +volatile uint8_t *cursor_pos(void); +void show_cursor(void); +void hide_cursor(void); +void move_cursor(int16_t x, int16_t y); + +void home(void); + +void print(uint8_t *s); +void print_char(uint8_t c); +void print_int(uint16_t i); +void print_newline(void); + +void syntax_error(void); + +#endif // __RUNTIME_H__