From d1b939414c3dbc0f82ccfbaf17985ec7dddc6062 Mon Sep 17 00:00:00 2001 From: Lawrence Kesteloot Date: Fri, 3 Aug 2018 18:57:30 -0700 Subject: [PATCH] Add GR and TEXT commands. --- main.c | 10 ++++++++++ runtime.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- runtime.h | 3 +++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index f62dc25..611040c 100644 --- a/main.c +++ b/main.c @@ -45,6 +45,8 @@ uint8_t title_length = 9; #define T_GOTO 0x90 #define T_IF 0x91 #define T_THEN 0x92 +#define T_GR 0x93 +#define T_TEXT 0x94 // Operators. These encode both the operator (high nybble) and the precedence // (low nybble). Lower precedence has a lower low nybble value. For example, @@ -113,6 +115,8 @@ static uint8_t *TOKEN[] = { "GOTO", "IF", "THEN", + "GR", + "TEXT", }; static int16_t TOKEN_COUNT = sizeof(TOKEN)/sizeof(TOKEN[0]); @@ -761,6 +765,12 @@ static void compile_buffer(uint8_t *buffer, uint16_t line_number) { g_compiled_length = saved_compiled_length; error = 1; } + } else if (*s == T_GR) { + s += 1; + add_call(gr_statement); + } else if (*s == T_TEXT) { + s += 1; + add_call(text_statement); } else { error = 1; } diff --git a/runtime.c b/runtime.c index 9f6ed92..73ab6ef 100644 --- a/runtime.c +++ b/runtime.c @@ -6,6 +6,8 @@ #define SCREEN_HEIGHT 24 #define SCREEN_WIDTH 40 #define SCREEN_STRIDE (3*SCREEN_WIDTH + 8) +#define MIXED_TEXT_HEIGHT 4 +#define MIXED_GRAPHICS_HEIGHT (SCREEN_HEIGHT - MIXED_TEXT_HEIGHT) #define CLEAR_CHAR (' ' | 0x80) // Location of cursor in logical screen space. @@ -16,6 +18,9 @@ uint16_t g_showing_cursor = 0; // Character at the cursor location. uint8_t g_cursor_ch = 0; +// Whether in low-res graphics mode. +uint8_t g_gr_mode = 0; + // List of variable names, two bytes each, in the same order they are // in the zero page (starting at FIRST_VARIABLE). Two nuls means an unused // slot. One-letter variable names have a nul for the second character. @@ -103,17 +108,17 @@ void home(void) { */ static void scroll_up(void) { int i; + int first_line = g_gr_mode ? MIXED_GRAPHICS_HEIGHT : 0; uint8_t *previous_line = 0; - for (i = 0; i < SCREEN_HEIGHT; i++) { + for (i = first_line; i < SCREEN_HEIGHT; i++) { uint8_t *this_line = screen_pos(0, i); - if (i > 0) { + if (i > first_line) { memmove(previous_line, this_line, SCREEN_WIDTH); } previous_line = this_line; } - // This is provided by cc65: memset(previous_line, CLEAR_CHAR, SCREEN_WIDTH); } @@ -206,3 +211,42 @@ void syntax_error_in_line(uint16_t line_number) { // No linefeed, assume prompt will do it. } + +/** + * Switch to graphics mode. + */ +void gr_statement(void) { + int i; + uint8_t *p = (uint8_t *) 49235U; + + hide_cursor(); + + // Mixed text and lo-res graphics mode. + *p = 0; + + // Clear the graphics area. + for (i = 0; i < MIXED_GRAPHICS_HEIGHT; i++) { + memset(screen_pos(0, i), 0, SCREEN_WIDTH); + } + + // Move the cursor to the text window. + if (g_cursor_y < MIXED_GRAPHICS_HEIGHT) { + move_cursor(0, MIXED_GRAPHICS_HEIGHT); + } + + g_gr_mode = 1; +} + +/** + * Switch to text mode. + */ +void text_statement(void) { + uint8_t *p = (uint8_t *) 49233U; + + hide_cursor(); + + // Mixed text and lo-res graphics mode. + *p = 0; + + g_gr_mode = 0; +} diff --git a/runtime.h b/runtime.h index 5b72e04..66c186c 100644 --- a/runtime.h +++ b/runtime.h @@ -36,4 +36,7 @@ void print_newline(void); void syntax_error(void); void syntax_error_in_line(uint16_t line_number); +void gr_statement(void); +void text_statement(void); + #endif // __RUNTIME_H__