init
This commit is contained in:
commit
19c923ce69
3
.clang-format
Normal file
3
.clang-format
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# clang format config
|
||||||
|
BasedOnStyle: Google
|
||||||
|
IndentWidth: 4
|
||||||
4
.clang-tidy
Normal file
4
.clang-tidy
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# clang tidy config
|
||||||
|
Checks: 'clang-diagnostic-*,clang-analyzer-*,bugprone-*'
|
||||||
|
WarningsAsErrors: 'true'
|
||||||
|
HeaderFilterRegex: 'include/\*\.h'
|
||||||
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# git ignores
|
||||||
|
*~
|
||||||
|
build
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/settings.json
|
||||||
25
.vscode/launch.json
vendored
Normal file
25
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "vice",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch Vice",
|
||||||
|
"preLaunchTask": "${defaultBuildTask}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "vice",
|
||||||
|
"request": "attach",
|
||||||
|
"name": "Attach Vice",
|
||||||
|
"hostname": "localhost",
|
||||||
|
"port": 6502,
|
||||||
|
"preLaunchTask": "${defaultBuildTask}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "6502",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch 6502",
|
||||||
|
"preLaunchTask": "${defaultBuildTask}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
13
.vscode/tasks.json
vendored
Normal file
13
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "vs64",
|
||||||
|
"action": "build",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"label": "build project"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
disk/userport_tester.d64
Normal file
BIN
disk/userport_tester.d64
Normal file
Binary file not shown.
153
nano/sketch_sep20a/sketch_sep20a.ino
Normal file
153
nano/sketch_sep20a/sketch_sep20a.ino
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
#define DP_0 2
|
||||||
|
#define DP_1 3
|
||||||
|
#define DP_2 4
|
||||||
|
#define DP_3 5
|
||||||
|
#define AR 6
|
||||||
|
#define CR 7
|
||||||
|
|
||||||
|
#define STANDBY 0
|
||||||
|
#define READ 1
|
||||||
|
#define WRITE 2
|
||||||
|
|
||||||
|
|
||||||
|
char count = 0;
|
||||||
|
char delayAmount = 100;
|
||||||
|
char textToSent[] = "Hallo vom Arduino Nano!";
|
||||||
|
|
||||||
|
char mode;
|
||||||
|
|
||||||
|
char getScreenCode(char c) {
|
||||||
|
if (c >= 32 && c <= 63) {
|
||||||
|
return c;
|
||||||
|
} else if (c == 64) {
|
||||||
|
return 0;
|
||||||
|
} else if (c >= 65 && c <= 90) {
|
||||||
|
return c;
|
||||||
|
} else if (c == 91 || c == 93) {
|
||||||
|
return c - 64;
|
||||||
|
} else if (c == 95) {
|
||||||
|
return 111;
|
||||||
|
} else if (c >= 97 && c <= 122) {
|
||||||
|
return c - 96;
|
||||||
|
} else if (c == 124) {
|
||||||
|
return 93;
|
||||||
|
} else {
|
||||||
|
return 63;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initMode(char mode) {
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case WRITE:
|
||||||
|
pinMode(DP_0, OUTPUT);
|
||||||
|
pinMode(DP_1, OUTPUT);
|
||||||
|
pinMode(DP_2, OUTPUT);
|
||||||
|
pinMode(DP_3, OUTPUT);
|
||||||
|
break;
|
||||||
|
case STANDBY:
|
||||||
|
default:
|
||||||
|
pinMode(DP_0, INPUT);
|
||||||
|
pinMode(DP_1, INPUT);
|
||||||
|
pinMode(DP_2, INPUT);
|
||||||
|
pinMode(DP_3, INPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
pinMode(AR, OUTPUT);
|
||||||
|
pinMode(CR, INPUT);
|
||||||
|
|
||||||
|
digitalWrite(DP_0, LOW);
|
||||||
|
digitalWrite(DP_1, LOW);
|
||||||
|
digitalWrite(DP_2, LOW);
|
||||||
|
digitalWrite(DP_3, LOW);
|
||||||
|
digitalWrite(AR, LOW);
|
||||||
|
digitalWrite(CR, LOW);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
delay(2000);
|
||||||
|
mode = STANDBY;
|
||||||
|
initMode(mode);
|
||||||
|
|
||||||
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void send4Bit(char c) {
|
||||||
|
|
||||||
|
for (char i = 3; i >= 0; i--) {
|
||||||
|
char d = c >> i & 1;
|
||||||
|
Serial.print(d, DEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (char i = 0; i < 4; i++) {
|
||||||
|
char d = c >> i & 1;
|
||||||
|
digitalWrite(i+2, d);
|
||||||
|
}
|
||||||
|
Serial.print(" ");
|
||||||
|
digitalWrite(AR, HIGH);
|
||||||
|
|
||||||
|
while (digitalRead(CR) == LOW) {}
|
||||||
|
|
||||||
|
while (digitalRead(CR) == HIGH) {}
|
||||||
|
digitalWrite(AR, LOW);
|
||||||
|
|
||||||
|
//delay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendByte(char a, char byte) {
|
||||||
|
char upper = byte >> 4;
|
||||||
|
char lower = byte & 0b00001111;
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(a);
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(a, DEC);
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(byte, DEC);
|
||||||
|
Serial.print(" ");
|
||||||
|
send4Bit(upper);
|
||||||
|
send4Bit(lower);
|
||||||
|
}
|
||||||
|
|
||||||
|
void startWrite() {
|
||||||
|
Serial.print("start\n");
|
||||||
|
mode = WRITE;
|
||||||
|
initMode(mode);
|
||||||
|
digitalWrite(AR, LOW);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
char c, sc;
|
||||||
|
do {
|
||||||
|
c = textToSent[i];
|
||||||
|
sc = getScreenCode(c);
|
||||||
|
i++;
|
||||||
|
sendByte(c, sc);
|
||||||
|
//Serial.print(c, DEC);
|
||||||
|
} while (c != 0);
|
||||||
|
|
||||||
|
Serial.print("\n");
|
||||||
|
|
||||||
|
for (char i = 2; i < 8; i++) {
|
||||||
|
digitalWrite(i, LOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = STANDBY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
if (mode == WRITE) {
|
||||||
|
|
||||||
|
} else if (mode == READ) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
startWrite();
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("\nAAAAAAAA\n");
|
||||||
|
|
||||||
|
delay(20000);
|
||||||
|
|
||||||
|
}
|
||||||
15
project-config.json
Normal file
15
project-config.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "c64_c_userport",
|
||||||
|
"description": "Project c64_c_userport",
|
||||||
|
"toolkit": "cc65",
|
||||||
|
"sources": [
|
||||||
|
"src/main.c",
|
||||||
|
"src/menu/menu.c",
|
||||||
|
"src/input.c"
|
||||||
|
],
|
||||||
|
"build": "debug",
|
||||||
|
"definitions": [],
|
||||||
|
"includes": [],
|
||||||
|
"args": [],
|
||||||
|
"compiler": ""
|
||||||
|
}
|
||||||
52
src/input.c
Normal file
52
src/input.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
unsigned short* PEVIOUS_KEY_MATRIX_CODE_PTR = (unsigned short*)0x00C5;
|
||||||
|
unsigned short* CURRENT_KEY_MATRIX_CODE_PTR = (unsigned short*)0x00CB;
|
||||||
|
unsigned char C_64_KEYBOARD_MATRIX[8][8] = {
|
||||||
|
{20 /*DEL*/, 13 /*RETURN*/, 29 /*CURSOR RIGHT*/, 136 /*F7*/, 133 /*F1*/, 134 /*F3*/, 135 /*F5*/, 145 /*CURSOR UP*/},
|
||||||
|
{'3' , 'w' , 'a', '4', 'z', 's', 'e', 255 /*LEFT SHIFT*/},
|
||||||
|
{'5' , 'r' , 'd', '6', 'c', 'f', 't', 'x'},
|
||||||
|
{'7' , 'y' , 'g', '8', 'b', 'h', 'u', 'v'},
|
||||||
|
{'9' , 'i' , 'j', '0', 'm', 'k', 'o', 'n'},
|
||||||
|
{'+' , 'p' , 'l', '-', '.', ':', '@', ','},
|
||||||
|
{92 /*₤*/ , '*' , ';', 147 /*CLR*/, 255 /*RIGHT SHIFT*/, '=', 94 /*↑*/, '/'},
|
||||||
|
{'1' , 95 /*←*/ , 255 /*CTRL*/, '2', ' ', 255 /*COMODORE*/, 'q', 3 /*RUN / STOP*/},
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned char getCurrentKeyMatrixCode() {
|
||||||
|
return *CURRENT_KEY_MATRIX_CODE_PTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char getPreviousKeyMatrixCode() {
|
||||||
|
return *PEVIOUS_KEY_MATRIX_CODE_PTR;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char matrixCodeToPetscii(unsigned char code) {
|
||||||
|
char x, y;
|
||||||
|
|
||||||
|
if (code == 64)
|
||||||
|
return 32;
|
||||||
|
|
||||||
|
x = code % 8;
|
||||||
|
y = code / 8;
|
||||||
|
|
||||||
|
return C_64_KEYBOARD_MATRIX[y][x];
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char getInputChar() {
|
||||||
|
char code = getCurrentKeyMatrixCode();
|
||||||
|
|
||||||
|
// wait until no key is pressed
|
||||||
|
while (code != KEY_NONE)
|
||||||
|
{
|
||||||
|
code = getCurrentKeyMatrixCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait until key is pressed
|
||||||
|
while (code == KEY_NONE)
|
||||||
|
{
|
||||||
|
code = getCurrentKeyMatrixCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
16
src/input.h
Normal file
16
src/input.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#define KEY_RETURN 1
|
||||||
|
#define KEY_W 9
|
||||||
|
#define KEY_S 13
|
||||||
|
#define KEY_PLUS 40
|
||||||
|
#define KEY_MINUS 43
|
||||||
|
#define KEY_SPACE 60
|
||||||
|
#define KEY_NONE 64
|
||||||
|
|
||||||
|
extern unsigned short* PEVIOUS_KEY_MATRIX_CODE_PTR;
|
||||||
|
extern unsigned short* CURRENT_KEY_MATRIX_CODE_PTR;
|
||||||
|
extern unsigned char C_64_KEYBOARD_MATRIX[8][8];
|
||||||
|
|
||||||
|
extern unsigned char getCurrentKeyMatrixCode();
|
||||||
|
extern unsigned char getPreviousKeyMatrixCode();
|
||||||
|
extern unsigned char matrixCodeToPetscii(unsigned char code);
|
||||||
|
extern unsigned char getInputChar();
|
||||||
358
src/main.c
Normal file
358
src/main.c
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <conio.h>
|
||||||
|
#include <c64.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "input.h"
|
||||||
|
#include "menu/menu.h"
|
||||||
|
|
||||||
|
#define DATA_ADDR 0xdd01
|
||||||
|
#define DIR_ADDR 0xdd03
|
||||||
|
#define SCREEN_ADDR 0x0400
|
||||||
|
#define COLOR_ADDR 0xD800
|
||||||
|
|
||||||
|
signed char NOT_STOP = 1;
|
||||||
|
char mode = 0;
|
||||||
|
char itr = 0;
|
||||||
|
|
||||||
|
volatile char* dataPtr = (volatile char*)DATA_ADDR;
|
||||||
|
volatile char* dirPtr = (volatile char*)DIR_ADDR;
|
||||||
|
|
||||||
|
|
||||||
|
char* version = "0.5";
|
||||||
|
char* creator = "Christian Werner";
|
||||||
|
unsigned char original_background_color, original_border_color, original_text_color = 0;
|
||||||
|
|
||||||
|
|
||||||
|
char* menu_items[] = {
|
||||||
|
"Output",
|
||||||
|
"Input"
|
||||||
|
};
|
||||||
|
|
||||||
|
char menu_items_len = sizeof(menu_items)/sizeof(menu_items[0]);
|
||||||
|
|
||||||
|
char dirBuff[8];
|
||||||
|
char dataBuff[8];
|
||||||
|
|
||||||
|
char dataState = 255;
|
||||||
|
char previousKey = 0;
|
||||||
|
|
||||||
|
void writeToScreen(char x, char y, char c, char color) {
|
||||||
|
unsigned short offset = y * 40 + x;
|
||||||
|
*(char*)(SCREEN_ADDR + offset) = c;
|
||||||
|
*(char*)(COLOR_ADDR + offset) = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getNumber(char* promt, int min, int max) {
|
||||||
|
int n;
|
||||||
|
printf("%s [%d-%d]: ", promt, min, max);
|
||||||
|
cursor(1);
|
||||||
|
cscanf("%d", &n);
|
||||||
|
cursor(0);
|
||||||
|
|
||||||
|
if (n > max) {
|
||||||
|
n = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n < min) {
|
||||||
|
n = min;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetScreen() {
|
||||||
|
clrscr();
|
||||||
|
textcolor(COLOR_GRAY1);
|
||||||
|
printf("Userport Playground v%s\ncreated by ", version);
|
||||||
|
textcolor(COLOR_LIGHTBLUE);
|
||||||
|
printf("%s\n", creator);
|
||||||
|
textcolor(COLOR_GRAY1);
|
||||||
|
chline(40);
|
||||||
|
textcolor(COLOR_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void toBinaryArray(char *buff , char value) {
|
||||||
|
char mask = 1;
|
||||||
|
char i;
|
||||||
|
for(i = 0; i < 8; i++) {
|
||||||
|
buff[i] = value & mask;
|
||||||
|
value = value >> 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawBinary(char low, char high, char* buff, char x, char y, char c_low, char c_high) {
|
||||||
|
char i;
|
||||||
|
char c;
|
||||||
|
char col;
|
||||||
|
|
||||||
|
for(i = 0; i < 8; i++) {
|
||||||
|
if (buff[i] == 0) {
|
||||||
|
c = low;
|
||||||
|
col = c_low;
|
||||||
|
} else {
|
||||||
|
c = high;
|
||||||
|
col = c_high;
|
||||||
|
}
|
||||||
|
writeToScreen(x + i * 2, y, c, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void userport() {
|
||||||
|
char direction = *(char*)0xdd03;
|
||||||
|
char data = *(char*)0xdd01;
|
||||||
|
char key_cur, key_prev, pet_code, p_c, p_p, x, y;
|
||||||
|
|
||||||
|
toBinaryArray(dirBuff, direction);
|
||||||
|
toBinaryArray(dataBuff, data);
|
||||||
|
|
||||||
|
gotoxy(0,3);
|
||||||
|
printf("dir: %03d ", direction);
|
||||||
|
drawBinary(73+128, 79+128, dirBuff, 10, 3, COLOR_ORANGE, COLOR_GREEN);
|
||||||
|
|
||||||
|
gotoxy(0,5);
|
||||||
|
printf("data: %03d ", data);
|
||||||
|
drawBinary(160, 160, dataBuff, 10, 5, COLOR_GRAY1, COLOR_RED);
|
||||||
|
|
||||||
|
key_cur = getCurrentKeyMatrixCode();
|
||||||
|
key_prev = getPreviousKeyMatrixCode();
|
||||||
|
|
||||||
|
p_c = matrixCodeToPetscii(key_cur);
|
||||||
|
p_p = matrixCodeToPetscii(key_prev);
|
||||||
|
|
||||||
|
|
||||||
|
writeToScreen(5,10, p_c, COLOR_GREEN);
|
||||||
|
gotoxy(7,10);
|
||||||
|
printf("%02d, %03d", key_cur, p_c);
|
||||||
|
|
||||||
|
x = key_cur % 8;
|
||||||
|
y = key_cur / 8;
|
||||||
|
|
||||||
|
printf(" %02d, %02d", x, y);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
original_background_color = bgcolor(COLOR_BLACK);
|
||||||
|
original_border_color = bordercolor(COLOR_BLACK);
|
||||||
|
original_text_color = textcolor(COLOR_GRAY1);
|
||||||
|
resetScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
int menu() {
|
||||||
|
char i;
|
||||||
|
int index;
|
||||||
|
resetScreen();
|
||||||
|
for(i = 0; i < menu_items_len; i++) {
|
||||||
|
printf("%d. %s\n", i+1, menu_items[i]);
|
||||||
|
}
|
||||||
|
index = getNumber("Pick mode", 1, menu_items_len) - 1;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void restore() {
|
||||||
|
bgcolor(original_background_color);
|
||||||
|
bordercolor(original_border_color);
|
||||||
|
textcolor(original_text_color);
|
||||||
|
clrscr();
|
||||||
|
// set char set to upper case
|
||||||
|
*(char*)0xd018 = 0x14;
|
||||||
|
*(char*)DIR_ADDR = 255;
|
||||||
|
*(char*)DATA_ADDR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void defaultLoop() {
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
char key = matrixCodeToPetscii(getCurrentKeyMatrixCode());
|
||||||
|
|
||||||
|
if (key == 3) {
|
||||||
|
mode = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == 95) {
|
||||||
|
mode = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousKey != key && key > '0' && key < '9') {
|
||||||
|
dataState = dataState ^ (1 << key - 49);
|
||||||
|
*(char*)0xdd03 = dataState;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(char*)0xdd01 = itr;
|
||||||
|
userport();
|
||||||
|
itr++;
|
||||||
|
previousKey = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fast() {
|
||||||
|
while(1) {
|
||||||
|
char key = matrixCodeToPetscii(getCurrentKeyMatrixCode());
|
||||||
|
|
||||||
|
if (key == 3) {
|
||||||
|
mode = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == 95) {
|
||||||
|
mode = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousKey != key && key > '0' && key < '9') {
|
||||||
|
dataState = dataState ^ (1 << key - 49);
|
||||||
|
*(char*)0xdd03 = dataState;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(char*)0xdd01 = itr;
|
||||||
|
itr++;
|
||||||
|
previousKey = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dod(char* title) {
|
||||||
|
char i = 0;
|
||||||
|
*(char*)0xdd03 = dataState;
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
defaultLoop();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
fast();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mode = 0;
|
||||||
|
dataState = 255;
|
||||||
|
itr = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeAllCharsToScreen() {
|
||||||
|
char x, y, c;
|
||||||
|
|
||||||
|
for (y = 0; y < 7; y++) {
|
||||||
|
for (x = 0; x < 40; x++) {
|
||||||
|
c = y * 40 + x;
|
||||||
|
writeToScreen(x, y, c, COLOR_GREEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void notImplemented(char* title) {
|
||||||
|
char origCol;
|
||||||
|
origCol = textcolor(COLOR_YELLOW);
|
||||||
|
printf("\"%s\" is not implemented :(", title);
|
||||||
|
textcolor(origCol);
|
||||||
|
printf("\nPress any key to continiue...");
|
||||||
|
getInputChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void exitProgram(char* title) {
|
||||||
|
NOT_STOP = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void recieveTest(char* title) {
|
||||||
|
unsigned short screenStart = SCREEN_ADDR + 40 * 3 ;
|
||||||
|
volatile char* screen = (volatile char*)screenStart;
|
||||||
|
unsigned short screenEnd = SCREEN_ADDR + 40*25;
|
||||||
|
char d, isArduinoReady, buff;
|
||||||
|
char lower, upper, fullByte;
|
||||||
|
short i = 0;
|
||||||
|
lower = 16;
|
||||||
|
upper = 16;
|
||||||
|
|
||||||
|
*dirPtr = 0b11110000;
|
||||||
|
*dataPtr = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
char key = matrixCodeToPetscii(getCurrentKeyMatrixCode());
|
||||||
|
|
||||||
|
if (key == 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
d = *dataPtr;
|
||||||
|
|
||||||
|
isArduinoReady = (d >> 4) & 1;
|
||||||
|
buff = d & 15;
|
||||||
|
|
||||||
|
if (isArduinoReady) {
|
||||||
|
if (upper == 16) {
|
||||||
|
upper = buff;
|
||||||
|
} else if (lower == 16)
|
||||||
|
{
|
||||||
|
lower = buff;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upper != 16 && lower != 16) {
|
||||||
|
fullByte = (upper << 4) + lower;
|
||||||
|
if (fullByte > 0) {
|
||||||
|
*screen = fullByte;
|
||||||
|
screen++;
|
||||||
|
}
|
||||||
|
if (screen == screenEnd) {
|
||||||
|
screen = (volatile char*)screenStart;
|
||||||
|
}
|
||||||
|
upper = 16;
|
||||||
|
lower = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set comodore ready
|
||||||
|
for (i = 0; i < 100; i++) {}
|
||||||
|
*dataPtr = d | 0b00100000;
|
||||||
|
|
||||||
|
for (i = 0; i < 100; i++) {}
|
||||||
|
*dataPtr = d & 0b11011111;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// int selection;
|
||||||
|
char huh;
|
||||||
|
|
||||||
|
Menu* menu = createMenu(4, "Main Menu", COLOR_LIGHTGREEN, 0, 3);
|
||||||
|
addMenuEntry(menu, "Userport Test", 0, dod);
|
||||||
|
addMenuEntry(menu, "Recieve Test", 1, recieveTest);
|
||||||
|
addMenuEntry(menu, "Test", 2, notImplemented);
|
||||||
|
addMenuEntry(menu, "EXIT", 3, exitProgram);
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
while (NOT_STOP)
|
||||||
|
{
|
||||||
|
awaitMenuSelect(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
//selection = menu();
|
||||||
|
// selection = 1;
|
||||||
|
// resetScreen();
|
||||||
|
|
||||||
|
// if (selection == 0) {
|
||||||
|
// userport();
|
||||||
|
// } else {
|
||||||
|
// userport();
|
||||||
|
// }
|
||||||
|
|
||||||
|
//*(char*)0xd018 = 0x14;
|
||||||
|
|
||||||
|
// dod();
|
||||||
|
|
||||||
|
free(menu);
|
||||||
|
restore();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
159
src/menu/menu.c
Normal file
159
src/menu/menu.c
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
#include "menu.h"
|
||||||
|
#include "../input.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <c64.h>
|
||||||
|
#include <conio.h>
|
||||||
|
|
||||||
|
struct MenuEntry {
|
||||||
|
char* name;
|
||||||
|
void (*callback)(char*);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Menu {
|
||||||
|
char* title;
|
||||||
|
unsigned char size;
|
||||||
|
short selected_index;
|
||||||
|
unsigned char selected_color;
|
||||||
|
char posX;
|
||||||
|
char posY;
|
||||||
|
MenuEntry entries[];
|
||||||
|
};
|
||||||
|
|
||||||
|
short MENU_ENTRY_SIZE = sizeof(MenuEntry);
|
||||||
|
short MENU_SIZE = sizeof(Menu);
|
||||||
|
|
||||||
|
Menu* createMenu(char size, char* title, char selected_color, char x, char y) {
|
||||||
|
|
||||||
|
Menu* menu = malloc(MENU_SIZE + size * MENU_ENTRY_SIZE);
|
||||||
|
|
||||||
|
if (!menu) return NULL;
|
||||||
|
|
||||||
|
menu->selected_index = 0;
|
||||||
|
menu->title = title;
|
||||||
|
menu->size = size;
|
||||||
|
menu->selected_color = selected_color;
|
||||||
|
menu->posX = x;
|
||||||
|
menu->posY = y;
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addMenuEntry(Menu* menu, char* name, char index, void (*callback)(char*)) {
|
||||||
|
menu->entries[index].name = name;
|
||||||
|
menu->entries[index].callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawMenuEntires(Menu* menu) {
|
||||||
|
char i;
|
||||||
|
MenuEntry e;
|
||||||
|
for (i = 1; i < menu->size + 1; i++)
|
||||||
|
{
|
||||||
|
gotoxy(menu->posX, menu->posY + i);
|
||||||
|
e = menu->entries[i-1];
|
||||||
|
|
||||||
|
if (i == menu->selected_index + 1) {
|
||||||
|
textcolor(menu->selected_color);
|
||||||
|
printf("%s", e.name);
|
||||||
|
textcolor(COLOR_WHITE);
|
||||||
|
} else {
|
||||||
|
printf("%s", e.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawMenu(Menu* menu) {
|
||||||
|
unsigned char origtextColor;
|
||||||
|
|
||||||
|
origtextColor = textcolor(COLOR_WHITE);
|
||||||
|
|
||||||
|
gotoxy(menu->posX, menu->posY);
|
||||||
|
printf("[%s]", menu->title);
|
||||||
|
|
||||||
|
drawMenuEntires(menu);
|
||||||
|
|
||||||
|
gotoxy(menu->posX, 21);
|
||||||
|
textcolor(COLOR_GRAY1);
|
||||||
|
chline(40);
|
||||||
|
gotoxy(40 - 10, 21);
|
||||||
|
printf("Controls");
|
||||||
|
textcolor(COLOR_WHITE);
|
||||||
|
|
||||||
|
gotoxy(menu->posX, 22);
|
||||||
|
printf("<W>: Up\n");
|
||||||
|
printf("<S>: Down\n");
|
||||||
|
printf("<SPACE>: Select");
|
||||||
|
|
||||||
|
gotoxy(menu->posX, menu->posY);
|
||||||
|
|
||||||
|
textcolor(origtextColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unDrawMenu(Menu* menu) {
|
||||||
|
unsigned char i;
|
||||||
|
for (i = 0; i < 25 - menu->posY; i++)
|
||||||
|
{
|
||||||
|
gotoxy(menu->posX, menu->posY + i);
|
||||||
|
cclear(40 - menu->posX);
|
||||||
|
}
|
||||||
|
gotoxy(menu->posX, menu->posY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
unsigned char i;
|
||||||
|
for (i = 3; i < 25; i++)
|
||||||
|
{
|
||||||
|
gotoxy(0, i);
|
||||||
|
cclear(40);
|
||||||
|
}
|
||||||
|
gotoxy(0, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void awaitMenuSelect(Menu* menu) {
|
||||||
|
char current_key;
|
||||||
|
signed short pressedKey;
|
||||||
|
MenuEntry slectedEntry;
|
||||||
|
|
||||||
|
clear();
|
||||||
|
drawMenu(menu);
|
||||||
|
pressedKey = -1;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
current_key = getCurrentKeyMatrixCode();
|
||||||
|
|
||||||
|
if (pressedKey == KEY_SPACE && current_key == KEY_NONE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressedKey == KEY_W && current_key == KEY_NONE) {
|
||||||
|
|
||||||
|
menu->selected_index--;
|
||||||
|
if (menu->selected_index < 0) {
|
||||||
|
menu->selected_index = menu->size -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawMenuEntires(menu);
|
||||||
|
pressedKey = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pressedKey == KEY_S && current_key == KEY_NONE) {
|
||||||
|
|
||||||
|
menu->selected_index++;
|
||||||
|
if (menu->selected_index > menu->size -1) {
|
||||||
|
menu->selected_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawMenuEntires(menu);
|
||||||
|
pressedKey = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_key != KEY_NONE) {
|
||||||
|
pressedKey = current_key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unDrawMenu(menu);
|
||||||
|
|
||||||
|
slectedEntry = menu->entries[menu->selected_index];
|
||||||
|
slectedEntry.callback(slectedEntry.name);
|
||||||
|
}
|
||||||
7
src/menu/menu.h
Normal file
7
src/menu/menu.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
typedef struct Menu Menu;
|
||||||
|
typedef struct MenuEntry MenuEntry;
|
||||||
|
|
||||||
|
|
||||||
|
extern Menu* createMenu(char size, char* title, char selected_color, char x, char y);
|
||||||
|
extern void addMenuEntry(Menu* menu, char* name, char index, void (*callback)(char*));
|
||||||
|
extern void awaitMenuSelect(Menu* menu);
|
||||||
Loading…
x
Reference in New Issue
Block a user