Created
February 15, 2020 05:29
-
-
Save agrif/9097246ea3c2bb5f94c04f8901b4f3ce to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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