From 5d453e8f58fc7511cd59be1e691ff6e10a0c2ce7 Mon Sep 17 00:00:00 2001 From: Lawrence Kesteloot Date: Thu, 2 Aug 2018 18:59:31 -0700 Subject: [PATCH] Scroll screen; remove volatile. --- main.c | 61 ++++++++---------------------------------------------- platform.c | 4 ++-- platform.h | 4 ++-- runtime.c | 61 +++++++++++++++++++++++++++++++++++++++--------------- runtime.h | 2 +- 5 files changed, 58 insertions(+), 74 deletions(-) diff --git a/main.c b/main.c index 4c664dd..3398cbf 100644 --- a/main.c +++ b/main.c @@ -1,3 +1,5 @@ +#include + #include "exporter.h" #include "platform.h" #include "runtime.h" @@ -47,40 +49,6 @@ void (*g_compiled_function)() = (void (*)()) g_compiled; // - Nul. uint8_t g_program[1024]; - -/** - * Copy a memory buffer. Source and destination may overlap. - */ -static void memmove(uint8_t *dest, uint8_t *src, uint16_t count) { - // See if we overlap. - if (dest > src && dest < src + count) { - // Overlapping with src before dest, we have to copy backward. - dest += count; - src += count; - while (count-- > 0) { - *--dest = *--src; - } - } else { - // No overlap, or dest before src, which is fine. - while (count-- > 0) { - *dest++ = *src++; - } - } -} - -/** - * Get the length of a nul-terminated string. - */ -static int16_t strlen(uint8_t *s) { - uint8_t *original = s; - - while (*s != '\0') { - s += 1; - } - - return s - original; -} - /** * Print the tokenized string, with tokens displayed as their full text. * Prints a newline at the end. @@ -190,20 +158,6 @@ static void add_return() { g_compiled[g_compiled_length++] = I_RTS; } -/** - * Advance s over whitespace, which is just a space, returning - * the new pointer. - */ -/* Unused. -static uint8_t *skip_whitespace(uint8_t *s) { - while (*s == ' ') { - s += 1; - } - - return s; -} -*/ - /** * Parse an unsigned integer, returning the value and moving the pointer * past the end of the number. The pointer must already be at the beginning @@ -421,7 +375,7 @@ static void process_input_buffer() { // Dump compiled buffer to the terminal. { int i; - volatile uint8_t *debug_port = (uint8_t *) 0xBFFE; + uint8_t *debug_port = (uint8_t *) 0xBFFE; debug_port[0] = g_compiled_length; for (i = 0; i < g_compiled_length; i++) { debug_port[1] = g_compiled[i]; @@ -522,7 +476,7 @@ int16_t main(void) if (1) { int16_t i; for (i = 0; i < 256; i++) { - volatile uint8_t *loc; + uint8_t *loc; // Fails with: unhandled instruction B2 move_cursor(i % 16, i >> 4); // Works. @@ -540,6 +494,9 @@ int16_t main(void) // Prompt. print("\n\n]"); + // TODO crashes 6502. Delete: + // asm("ldy #1"); + // asm("sta $FFFF,y"); // Keyboard input. blink = 0; @@ -572,7 +529,7 @@ int16_t main(void) } } else if (key == 13) { // Return. - move_cursor(0, g_cursor_y + 1); + print_char('\n'); process_input_buffer(); @@ -580,7 +537,7 @@ int16_t main(void) g_input_buffer_length = 0; } else { if (g_input_buffer_length < sizeof(g_input_buffer) - 1) { - volatile uint8_t *loc = cursor_pos(); + uint8_t *loc = cursor_pos(); *loc = key | 0x80; move_cursor(g_cursor_x + 1, g_cursor_y); diff --git a/platform.c b/platform.c index 9bb7f83..b7b8e13 100644 --- a/platform.c +++ b/platform.c @@ -1,7 +1,7 @@ #include "platform.h" -#define KBD_STATUS_OR_KEY ((volatile unsigned char *)0xC000) -#define KBD_CLEAR_CURRENT_KEY ((volatile unsigned char *)0xC010) +#define KBD_STATUS_OR_KEY ((unsigned char *)0xC000) +#define KBD_CLEAR_CURRENT_KEY ((unsigned char *)0xC010) #define KEY_READY_MASK 0x80 #define KEY_VALUE_MASK 0x7F diff --git a/platform.h b/platform.h index 02f0833..ee3d192 100644 --- a/platform.h +++ b/platform.h @@ -1,8 +1,8 @@ #ifndef __PLATFORM_H__ #define __PLATFORM_H__ -#define TEXT_PAGE1_BASE ((volatile unsigned char *)0x400) -#define TEXT_PAGE2_BASE ((volatile unsigned char *)0x800) +#define TEXT_PAGE1_BASE ((unsigned char *)0x400) +#define TEXT_PAGE2_BASE ((unsigned char *)0x800) // Standard types. typedef signed char int8_t; diff --git a/runtime.c b/runtime.c index 855b7d5..6b657b9 100644 --- a/runtime.c +++ b/runtime.c @@ -1,7 +1,9 @@ +#include #include "runtime.h" #define CURSOR_GLYPH 127 +#define SCREEN_HEIGHT 24 #define SCREEN_WIDTH 40 #define SCREEN_STRIDE (3*SCREEN_WIDTH + 8) @@ -13,14 +15,21 @@ uint16_t g_showing_cursor = 0; // Character at the cursor location. uint8_t g_cursor_ch = 0; +/** + * Return the memory location of the zero-based (x,y) position on the screen. + */ +static uint8_t *screen_pos(uint16_t x, uint16_t y) { + int16_t block = y >> 3; + int16_t line = y & 0x07; + + return TEXT_PAGE1_BASE + line*SCREEN_STRIDE + block*SCREEN_WIDTH + x; +} + /** * 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; +uint8_t *cursor_pos(void) { + return screen_pos(g_cursor_x, g_cursor_y); } /** @@ -28,7 +37,7 @@ volatile uint8_t *cursor_pos(void) { */ void show_cursor(void) { if (!g_showing_cursor) { - volatile uint8_t *pos = cursor_pos(); + uint8_t *pos = cursor_pos(); g_cursor_ch = *pos; *pos = CURSOR_GLYPH | 0x80; g_showing_cursor = 1; @@ -40,7 +49,7 @@ void show_cursor(void) { */ void hide_cursor(void) { if (g_showing_cursor) { - volatile uint8_t *pos = cursor_pos(); + uint8_t *pos = cursor_pos(); *pos = g_cursor_ch; g_showing_cursor = 0; } @@ -60,27 +69,45 @@ void move_cursor(int16_t x, int16_t 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; + memset(TEXT_PAGE1_BASE, ' ' | 0x80, SCREEN_STRIDE*8); + move_cursor(0, 0); +} - // TODO: Could write these as words, not chars. - for (i = SCREEN_STRIDE*8; i >= 0; i--) { - *p++ = ch; +/** + * Screen the screen up one line, blanking out the bottom + * row. Does not affect the cursor. + */ +static void scroll_up(void) { + int i; + uint8_t *previous_line = 0; + + for (i = 0; i < SCREEN_HEIGHT; i++) { + uint8_t *this_line = screen_pos(0, i); + if (i > 0) { + memmove(previous_line, this_line, SCREEN_WIDTH); + } + previous_line = this_line; } - move_cursor(0, 0); + // This is provided by cc65: + memset(previous_line, ' ' | 0x80, SCREEN_WIDTH); } /** * Prints the character and advances the cursor. Handles newlines. */ void print_char(uint8_t c) { - volatile uint8_t *loc = cursor_pos(); + uint8_t *loc = cursor_pos(); if (c == '\n') { - // TODO: Scroll. - move_cursor(0, g_cursor_y + 1); + if (g_cursor_y == SCREEN_HEIGHT - 1) { + // Scroll. + hide_cursor(); + scroll_up(); + move_cursor(0, g_cursor_y); + } else { + move_cursor(0, g_cursor_y + 1); + } } else { // Print character. *loc = c | 0x80; diff --git a/runtime.h b/runtime.h index fdc1474..53b9a0c 100644 --- a/runtime.h +++ b/runtime.h @@ -8,7 +8,7 @@ extern uint16_t g_cursor_y; extern uint16_t g_showing_cursor; extern uint8_t g_cursor_ch; -volatile uint8_t *cursor_pos(void); +uint8_t *cursor_pos(void); void show_cursor(void); void hide_cursor(void); void move_cursor(int16_t x, int16_t y);