Scroll screen; remove volatile.

This commit is contained in:
Lawrence Kesteloot 2018-08-02 18:59:31 -07:00
parent 6d7af284a1
commit 5d453e8f58
5 changed files with 58 additions and 74 deletions

61
main.c
View File

@ -1,3 +1,5 @@
#include <string.h>
#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);

View File

@ -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

View File

@ -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;

View File

@ -1,7 +1,9 @@
#include <string.h>
#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;

View File

@ -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);