mirror of
https://github.com/bradgrantham/apple2a.git
synced 2024-10-31 23:09:39 +00:00
Break runtime into different C file.
This commit is contained in:
parent
794a9bb121
commit
6d7af284a1
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
tmp.lib
|
||||
main.s
|
||||
platform.s
|
||||
runtime.s
|
||||
*.o
|
||||
*.dbg
|
||||
*.map
|
||||
|
11
Makefile
11
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
|
||||
|
144
main.c
144
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.
|
||||
*/
|
||||
|
147
runtime.c
Normal file
147
runtime.c
Normal file
@ -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.
|
||||
}
|
25
runtime.h
Normal file
25
runtime.h
Normal file
@ -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__
|
Loading…
Reference in New Issue
Block a user