apple2a/main.c

163 lines
3.6 KiB
C
Raw Normal View History

2018-07-31 19:02:26 +00:00
#include "platform.h"
2018-07-28 05:30:44 +00:00
char *title = "Apple IIa";
unsigned char title_length = 9;
2018-07-31 19:48:29 +00:00
#define CURSOR_GLYPH 127
#define SCREEN_WIDTH 40
#define SCREEN_STRIDE (3*SCREEN_WIDTH + 8)
// Location of cursor in logical screen space.
unsigned int cursor_x = 0;
unsigned int cursor_y = 0;
// Whether the cursor is being displayed.
unsigned int showing_cursor = 0;
// Character at the cursor location.
unsigned char cursor_ch = 0;
2018-07-31 07:05:22 +00:00
/**
* Delay for a count of "t". 8000 is about one second.
*/
static void delay(int t) {
while (t >= 0) {
t--;
}
}
/**
* Clear the screen with non-reversed spaces.
*/
static void home() {
2018-07-31 19:02:26 +00:00
volatile unsigned char *p = TEXT_PAGE1_BASE;
2018-07-31 07:05:22 +00:00
unsigned char ch = ' ' | 0x80;
int i;
// TODO: Could write these as words, not chars.
2018-07-31 19:48:29 +00:00
for (i = SCREEN_STRIDE*8; i >= 0; i--) {
2018-07-31 07:05:22 +00:00
*p++ = ch;
}
}
2018-07-31 19:48:29 +00:00
/**
* Return the memory location of the cursor.
*/
static volatile unsigned char *cursor_pos() {
int block = cursor_y >> 3;
int line = cursor_y & 0x07;
return TEXT_PAGE1_BASE + line*SCREEN_STRIDE + block*SCREEN_WIDTH + cursor_x;
}
/**
* Shows the cursor. Safe to call if it's already showing.
*/
static void show_cursor() {
if (!showing_cursor) {
volatile unsigned char *pos = cursor_pos();
cursor_ch = *pos;
*pos = CURSOR_GLYPH | 0x80;
showing_cursor = 1;
}
}
/**
* Hides the cursor. Safe to call if it's not already shown.
*/
static void hide_cursor() {
if (showing_cursor) {
volatile unsigned char *pos = cursor_pos();
*pos = cursor_ch;
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(int x, int y) {
hide_cursor();
cursor_x = x;
cursor_y = y;
}
2018-07-28 05:30:44 +00:00
int main(void)
{
2018-07-28 19:12:40 +00:00
int offset = (40 - title_length) / 2;
2018-07-28 05:30:44 +00:00
2018-07-31 19:02:26 +00:00
volatile unsigned char *loc = TEXT_PAGE1_BASE + offset;
2018-07-28 05:30:44 +00:00
int i;
2018-07-31 07:05:22 +00:00
home();
2018-07-28 05:30:44 +00:00
2018-07-31 20:42:21 +00:00
// Display the character set.
for (i = 0; i < 256; i++) {
// Fails with: unhandled instruction B2
move_cursor(i % 16, i >> 4);
// Works.
// move_cursor(i & 0x0F, i >> 4);
loc = cursor_pos();
*loc = i;
}
while(1);
2018-07-31 07:05:22 +00:00
// Title.
2018-07-28 19:12:40 +00:00
for(i = 0; i < title_length; i++) {
2018-07-28 05:30:44 +00:00
loc[i] = title[i] | 0x80;
2018-07-28 19:12:40 +00:00
}
2018-07-28 05:30:44 +00:00
2018-07-31 07:05:22 +00:00
// Prompt.
2018-07-31 19:48:29 +00:00
move_cursor(0, 2);
loc = cursor_pos();
*loc = ']' | 0x80;
move_cursor(cursor_x + 1, cursor_y);
2018-07-31 07:05:22 +00:00
2018-07-31 19:48:29 +00:00
// Keyboard input.
i = 0;
show_cursor();
2018-07-31 07:05:22 +00:00
while(1) {
2018-07-31 19:48:29 +00:00
// Blink cursor.
i += 1;
if (i == 2000) {
if (showing_cursor) {
hide_cursor();
} else {
show_cursor();
}
i = 0;
}
if(keyboard_test()) {
hide_cursor();
while(keyboard_test()) {
unsigned char key;
2018-07-31 19:02:26 +00:00
2018-07-31 19:48:29 +00:00
key = keyboard_get();
if (key == 8) {
// Backspace.
if (cursor_x > 1) {
move_cursor(cursor_x - 1, cursor_y);
}
} else if (key == 13) {
// Return.
move_cursor(0, cursor_y + 1);
loc = cursor_pos();
*loc = ']' | 0x80;
move_cursor(cursor_x + 1, cursor_y);
} else {
volatile unsigned char *loc = cursor_pos();
*loc = key | 0x80;
move_cursor(cursor_x + 1, cursor_y);
}
}
2018-07-31 19:02:26 +00:00
2018-07-31 19:48:29 +00:00
show_cursor();
2018-07-31 19:02:26 +00:00
}
2018-07-31 07:05:22 +00:00
}
return 0;
2018-07-28 05:30:44 +00:00
}