include controller code
This commit is contained in:
parent
32c9aa9158
commit
775b36a021
1 changed files with 292 additions and 0 deletions
292
6502-controller/6502-controller.ino
Normal file
292
6502-controller/6502-controller.ino
Normal file
|
@ -0,0 +1,292 @@
|
|||
#define PIN_CLK 13
|
||||
#define PIN_RST A4
|
||||
#define PIN_RW A5
|
||||
#define PIN_CE A3
|
||||
#define PIN_BTN PC13
|
||||
#define CLK_DELAY 100
|
||||
|
||||
#define ROM_SIZE 0x7fff
|
||||
|
||||
const char ADDR[] = { PC4, PB13, PB14, PB15, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14 };
|
||||
const char DATA[] = { PB1, PB2, PB12, PA11, PA12, PC5, PC6, PC8 };
|
||||
|
||||
uint8_t running = 0;
|
||||
uint8_t start = 0;
|
||||
|
||||
PROGMEM static uint8_t rom[ROM_SIZE];
|
||||
uint16_t rom_idx = 0;
|
||||
uint32_t rom_load_start = 0;
|
||||
|
||||
enum states {
|
||||
IDLE,
|
||||
WRITE // write rom to memory
|
||||
};
|
||||
|
||||
enum states state = IDLE;
|
||||
|
||||
uint16_t readAddress() {
|
||||
uint16_t addr = 0;
|
||||
|
||||
for(uint8_t i = 1; i < 16; i++) {
|
||||
addr = (addr << 1) + (digitalRead(ADDR[i]) ? 1 : 0);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
uint16_t readState() {
|
||||
uint8_t bit = 0;
|
||||
uint16_t addr = 0;
|
||||
uint8_t data = 0;
|
||||
uint8_t i = 0;
|
||||
// check chip enable, 0 = enabled; 1 = disabled
|
||||
uint8_t CE = digitalRead(PIN_CE) ? 0 : 1;
|
||||
|
||||
// debugging lines start with D:
|
||||
Serial.print("D: ");
|
||||
|
||||
for(i = 1; i < 16; i++) {
|
||||
bit = digitalRead(ADDR[i]) ? 1 : 0;
|
||||
addr = (addr << 1) + bit;
|
||||
|
||||
Serial.print(bit);
|
||||
}
|
||||
|
||||
Serial.print(" ");
|
||||
|
||||
for(i = 0; i < 8; i++) {
|
||||
pinMode(DATA[i], INPUT);
|
||||
|
||||
bit = digitalRead(DATA[i]) ? 1 : 0;
|
||||
data = (data << 1) + bit;
|
||||
|
||||
Serial.print(bit);
|
||||
|
||||
// set DATA pinMode based on Chip Enable
|
||||
pinMode(DATA[i], CE ? OUTPUT : INPUT);
|
||||
}
|
||||
|
||||
Serial.printf(
|
||||
" %04x %c %02x %s\r\n",
|
||||
addr,
|
||||
(digitalRead(PIN_RW) ? 'r' : 'W'),
|
||||
data,
|
||||
CE ? "CE" : "!CE"
|
||||
);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void resetHigh() {
|
||||
Serial.println("D: Setting reset HIGH");
|
||||
|
||||
pinMode(PIN_RST, OUTPUT);
|
||||
digitalWrite(PIN_RST, HIGH);
|
||||
}
|
||||
|
||||
void resetLow() {
|
||||
Serial.println("D: Setting reset LOW");
|
||||
|
||||
pinMode(PIN_RST, OUTPUT);
|
||||
digitalWrite(PIN_RST, LOW);
|
||||
}
|
||||
|
||||
void startClock() {
|
||||
running = 1;
|
||||
|
||||
Serial.println("D: starting clock");
|
||||
}
|
||||
|
||||
void stopClock() {
|
||||
running = 0;
|
||||
|
||||
Serial.println("D: stoping clock");
|
||||
}
|
||||
|
||||
unsigned int lastUserButton = 0;
|
||||
|
||||
void advanceClock() {
|
||||
//pinMode(PIN_RST, OUTPUT);
|
||||
//digitalWrite(PIN_RST, HIGH);
|
||||
|
||||
digitalWrite(PIN_CLK, !digitalRead(PIN_CLK));
|
||||
delay(CLK_DELAY);
|
||||
|
||||
digitalWrite(PIN_CLK, !digitalRead(PIN_CLK));
|
||||
delay(CLK_DELAY);
|
||||
}
|
||||
|
||||
void onUserButton() {
|
||||
if(millis() - lastUserButton > 100) {
|
||||
readState();
|
||||
|
||||
advanceClock();
|
||||
|
||||
lastUserButton = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void onChipEnable() {
|
||||
uint8_t CE = digitalRead(PIN_CE) ? 0 : 1;
|
||||
|
||||
//Serial.printf("CE: %s\n", CE ? "Disabled" : "Enabled");
|
||||
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
pinMode(DATA[i], CE ? OUTPUT : INPUT);
|
||||
}
|
||||
|
||||
//setOutByte(rom[readAddress()]);
|
||||
}
|
||||
|
||||
void setOutByte(char b) {
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
pinMode(DATA[i], OUTPUT);
|
||||
|
||||
if((b >> (7 - i)) & 1)
|
||||
digitalWrite(DATA[i], HIGH);
|
||||
else
|
||||
digitalWrite(DATA[i], LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {
|
||||
uint8_t CE = digitalRead(PIN_CE) ? 0 : 1;
|
||||
|
||||
// set data pins according to Chip Enable state
|
||||
// 1 = disabled; 0 = enabled
|
||||
for(uint8_t i = 0; i < 8; i++) {
|
||||
pinMode(DATA[i], CE ? OUTPUT : INPUT);
|
||||
digitalWrite(DATA[i], LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void clearProgMem() {
|
||||
uint8_t i = 0;
|
||||
|
||||
// clear rom
|
||||
bzero((void*)&rom, ROM_SIZE);
|
||||
|
||||
Serial.println("D: memory cleared");
|
||||
}
|
||||
|
||||
void onAddressChange() {
|
||||
uint16_t addr = readAddress();
|
||||
uint8_t byt = rom[addr];
|
||||
setOutByte(byt);
|
||||
//Serial.printf("%04x: %02x\r\n", addr, byt);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
uint8_t i = 0;
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
for(i = 0; i < 16; i++) {
|
||||
pinMode(ADDR[i], INPUT);
|
||||
attachInterrupt(digitalPinToInterrupt(ADDR[i]), onAddressChange, CHANGE);
|
||||
}
|
||||
|
||||
reset();
|
||||
|
||||
//setOutByte(0xea);
|
||||
|
||||
pinMode(PIN_CLK, OUTPUT);
|
||||
pinMode(PIN_RST, INPUT);
|
||||
pinMode(PIN_BTN, INPUT);
|
||||
pinMode(PIN_RW, INPUT);
|
||||
pinMode(PIN_CE, INPUT);
|
||||
attachInterrupt(digitalPinToInterrupt(PIN_BTN), onUserButton, FALLING);
|
||||
attachInterrupt(digitalPinToInterrupt(PIN_CE), onChipEnable, CHANGE);
|
||||
|
||||
digitalWrite(PIN_CLK, LOW);
|
||||
digitalWrite(PIN_RST, LOW);
|
||||
|
||||
start = millis();
|
||||
|
||||
Serial.println("D: clearing rom");
|
||||
|
||||
clearProgMem();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if(state == WRITE) {
|
||||
while(true && rom_idx < 0x7ffe && millis() - rom_load_start < 3000) {
|
||||
// freshen the start time
|
||||
if(Serial.available() > 0) rom_load_start = millis();
|
||||
|
||||
while(Serial.available() > 0) {
|
||||
rom[rom_idx++] = Serial.read();
|
||||
}
|
||||
}
|
||||
|
||||
state = IDLE;
|
||||
|
||||
Serial.printf("Read 0x%04X bytes into memory\r\n", rom_idx);
|
||||
Serial.printf("0x7ffc: 0x%02X 0x%02X\r\n", rom[0x7ffc], rom[0x7ffd]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t CE = digitalRead(PIN_CE) ? 0 : 1;
|
||||
|
||||
if(running) {
|
||||
uint16_t addr = readState();
|
||||
|
||||
if(CE) {
|
||||
//setOutByte(rom[addr]);
|
||||
//Serial.printf("Setting output %02X\r\n", rom[addr]);
|
||||
}
|
||||
|
||||
advanceClock();
|
||||
}
|
||||
|
||||
if(Serial.available() > 0) {
|
||||
char c = Serial.read();
|
||||
|
||||
//Serial.print(c);
|
||||
|
||||
if(c == '0') resetHigh();
|
||||
if(c == '1') resetLow();
|
||||
if(c == '3') readState();
|
||||
if(c == '4') startClock();
|
||||
if(c == '5') stopClock();
|
||||
if(c == '6') reset();
|
||||
if(c == '7') clearProgMem();
|
||||
if(c == '8') {
|
||||
for(uint16_t i = 0; i < 0x100; i++) {
|
||||
if(i % 16 == 0) Serial.printf("0x%04X: ", i);
|
||||
|
||||
Serial.printf("%02x", rom[i]);
|
||||
|
||||
if(i % 2 == 1) Serial.print(" ");
|
||||
|
||||
if(i % 16 == 15) Serial.println();
|
||||
}
|
||||
}
|
||||
|
||||
if(c == 'l') {
|
||||
// activate load mode and reset counter
|
||||
state = WRITE;
|
||||
rom_idx = 0;
|
||||
rom_load_start = millis();
|
||||
bzero((void*)&rom, ROM_SIZE);
|
||||
|
||||
Serial.println("D: ready for ROM");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
if(c == '2') {
|
||||
// only leave in for debugging
|
||||
while(!Serial.available()) {};
|
||||
|
||||
char b = Serial.read();
|
||||
|
||||
setOutByte(b);
|
||||
}
|
||||
*/
|
||||
|
||||
// flush serial queue
|
||||
// while(Serial.available() > 0) Serial.read();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue