Skip to content

Instantly share code, notes, and snippets.

@agrif
Created February 15, 2020 05:29
Show Gist options
  • Save agrif/9097246ea3c2bb5f94c04f8901b4f3ce to your computer and use it in GitHub Desktop.
Save agrif/9097246ea3c2bb5f94c04f8901b4f3ce to your computer and use it in GitHub Desktop.
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "font.h"
__sfr __at 0x50 ioLED;
__sfr __at 0x00 ioID0;
__sfr __at 0x01 ioID1;
__sfr __at 0x02 ioID2;
__sfr __at 0x03 ioID3;
__sfr __at 0x04 ioID4;
__sfr __at 0x05 ioID5;
__sfr __at 0x06 ioID6;
__sfr __at 0x07 ioID7;
__sfr __at 0x08 ioSerialData;
__sfr __at 0x09 ioSerialRValid;
__sfr __at 0x0a ioSerialRAvailL;
__sfr __at 0x0b ioSerialRAvailH;
__sfr __at 0x0c ioSerialEnable;
__sfr __at 0x0d ioSerialInterrupt;
__sfr __at 0x0e ioSerialWSpaceL;
__sfr __at 0x0f ioSerialWSpaceH;
__sfr __at 0x40 ioKEY;
__sfr __at 0x48 ioKEYint;
__sfr __at 0x4c ioKEYedge;
__sfr __at 0x20 ioTimerState;
__sfr __at 0x24 ioTimerConfig; // ???
__sfr __at 0x60 ioXOffsetL;
__sfr __at 0x61 ioXOffsetH;
__sfr __at 0x62 ioYOffsetL;
__sfr __at 0x63 ioYOffsetH;
__at (0x8000) uint8_t tiles[256][8][4];
__at (0xa000) uint8_t screen[64][64];
__at (0xb000) uint8_t pal_r[16];
__at (0xb010) uint8_t pal_g[16];
__at (0xb020) uint8_t pal_b[16];
uint8_t memID[8];
uint8_t interrupt_count[3] = {0};
volatile uint16_t ticks;
void interrupt_0(void) __critical __interrupt(0) {
interrupt_count[0] += 1;
ticks += 1;
ioTimerState = 0;
}
// uart
volatile uint8_t uart_read_next = 0;
volatile uint8_t uart_read_avail = 0;
volatile uint8_t uart_read[128];
void interrupt_1(void) __critical __interrupt(1) {
uint8_t data;
uint8_t valid;
interrupt_count[1] += 1;
while (true) {
data = ioSerialData;
valid = ioSerialRValid;
if (valid & (1 << 7)) {
if (uart_read_avail < 128) {
uint8_t i = uart_read_next + uart_read_avail;
i %= 128;
uart_read[i] = data;
uart_read_avail++;
}
} else {
break;
}
}
}
// key
volatile uint8_t waitkey[2] = {0, 0};
void interrupt_2(void) __critical __interrupt(2) {
uint8_t data;
data = ioKEYedge;
ioKEYedge = 0;
interrupt_count[2] += 1;
if (data & 0b01)
waitkey[0] = 1;
if (data & 0b10)
waitkey[1] = 1;
}
__at (0x0100) void* const interrupt_table[128] = {
interrupt_0,
interrupt_1,
interrupt_2,
};
void wait_for_key(int i) {
while (!waitkey[i]) {
__asm__("halt");
}
waitkey[i] = 0;
}
void putchar(char c) {
ioSerialData = c & 0xff;
}
char getchar(void) {
char c;
while (uart_read_avail == 0) {
__asm__("halt");
}
c = uart_read[uart_read_next];
uart_read_next += 1;
uart_read_next %= 128;
uart_read_avail--;
return c;
}
void sleep_bad(uint8_t amt) {
while (amt > 0) {
uint16_t i = 0xffff;
while (i > 0)
i--;
amt--;
}
}
void sleep(uint16_t ms) {
uint16_t start = ticks;
uint16_t end = start + ms;
if (end < start) {
while (start <= ticks || ticks < end) {
__asm__("halt");
}
} else {
while (start <= ticks && ticks < end) {
__asm__("halt");
}
}
}
void copy_system_id(void) {
memID[0] = ioID0;
memID[1] = ioID1;
memID[2] = ioID2;
memID[3] = ioID3;
memID[4] = ioID4;
memID[5] = ioID5;
memID[6] = ioID6;
memID[7] = ioID7;
}
void main() {
uint8_t flags;
uint16_t offsetx = 0;
uint16_t offsety = 0;
uint16_t t, f;
uint8_t y, x, p, b;
char* msg = "Hello, world!";
copy_system_id();
ioTimerConfig = 0b111;
flags = ioSerialEnable;
ioSerialEnable = flags | 1;
ioKEYint = 0b11;
__asm__("ei");
for (t = 0; t < 256; t++) {
for (y = 0; y < 8; y++) {
for (x = 0; x < 4; x++) {
tiles[t][y][x] = 0;
}
}
}
for (f = 0; f < FONT_PACKED_CHARS; f++) {
for (y = 0; y < FONT_PACKED_LINES; y++) {
t = (FONT_PACKED_START + f) << 1;
t |= y >= 8;
p = font_packed[f][FONT_PACKED_LINES - y - 1];
for (x = 4; x > 0; x--) {
b = 0x00;
if (p & 1)
b |= 0xf0;
if (p & 2)
b |= 0x0f;
tiles[t][y & 0x7][x - 1] = b;
p = p >> 2;
}
}
}
for (y = 0; y < 64; y++) {
for (x = 0; x < 64; x++) {
screen[y][x] = 0;
}
}
for (p = 0; p < 16; p++) {
pal_r[p] = 0;
pal_g[p] = 0;
pal_b[p] = 0;
}
pal_r[0xf] = pal_g[0xf] = pal_b[0xf] = 255;
for (y = 0; y < 8; y++) {
for (x = 0; x < 4; x++) {
if (y % 2)
tiles[1][y][x] = 0x0f;
else
tiles[1][y][x] = 0xf0;
}
}
for (p = 0; p < strlen(msg); p++) {
screen[0][p] = msg[p] << 1;
screen[1][p] = (msg[p] << 1) + 1;
}
screen[0][p + 1] = 1;
screen[1][p + 1] = 1;
ioLED = 0;
while (true) {
//wait_for_key(1);
sleep(50);
offsetx += 3;
offsety += 2;
ioXOffsetL = offsetx & 0xff;
ioXOffsetH = offsetx >> 8;
ioYOffsetL = offsety & 0xff;
ioYOffsetH = offsety >> 8;
ioLED += 1;
//printf("set LEDs to: 0x%02x", ioLED);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment