Reorganized folders, added pal-adapter io device folder
This commit is contained in:
94
prototiping-with-arduino/SN76489-test/SN76489-test.ino
Normal file
94
prototiping-with-arduino/SN76489-test/SN76489-test.ino
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* SN76489 sound chip test
|
||||
*
|
||||
* DATA BUS IS: 2, 3, 4, 5, 6, 7, 8, 9 (NOTE: 2 is D0, but D0 is the MSB)
|
||||
* WE 10 (Active low)
|
||||
*/
|
||||
|
||||
const byte DATA_BUS[] = {9, 8, 7, 6, 5, 4, 3, 2};
|
||||
const byte WE = 10;
|
||||
|
||||
void setup() {
|
||||
// Setup pins
|
||||
for(int pin=0; pin < 8; pin++) {
|
||||
pinMode(DATA_BUS[pin], OUTPUT);
|
||||
}
|
||||
pinMode(WE, OUTPUT);
|
||||
digitalWrite(WE, HIGH);
|
||||
|
||||
/* Init device (silence all channels)
|
||||
* Bits meaning:
|
||||
* 1 R0 R1 R2 A0 A1 A2 A3
|
||||
* Bit0 is 1
|
||||
* Bit1,2,3 select the channel: 001, 011, 101, 111(noise)
|
||||
* Bit4,5,6,7 selecy the attenuation (0000=full volume, 1111=silent)
|
||||
*/
|
||||
SendByte(B10011111); // Sil ch 1
|
||||
SendByte(B10111111); // Sil ch 2
|
||||
SendByte(B11011111); // Sil ch 3
|
||||
SendByte(B11111111); // Sil noise
|
||||
|
||||
delay(1000);
|
||||
|
||||
// Channel 1 to max volume
|
||||
SendByte(B10010000);
|
||||
|
||||
/* Play note on channel 1
|
||||
* Requires sending 2 bytes.
|
||||
* Bits meaning:
|
||||
* 1 R0 R1 R2 F6 F7 F8 F9 0 0 F0 F1 F2 F3 F4 F5
|
||||
* First bit: 1=low byte (first sent), 0=high byte (last sent)
|
||||
* R0,1,2: select the channel: 000, 010, 100, 110(noise)
|
||||
* F0..9: frequency value calculated as:
|
||||
* f = REF_CLK / 32 * n
|
||||
* Where f is the resulting frequency in HZ, REF_CLK is the reference clock on pin 14 in HZ and n is F0..9
|
||||
*/
|
||||
SendByte(B10000000); SendByte(B00100000);
|
||||
delay(500);
|
||||
SendByte(B10000000); SendByte(B00010000);
|
||||
delay(500);
|
||||
SendByte(B10000000); SendByte(B00001000);
|
||||
delay(500);
|
||||
|
||||
SendByte(B10011111); // Sil ch 1
|
||||
|
||||
delay(1000);
|
||||
|
||||
// Play notes on channel 1,2,3
|
||||
SendByte(B10010000); // Channel 1 vol max (0000)
|
||||
SendByte(B10000000); SendByte(B00100000); // Note on ch1
|
||||
delay(500);
|
||||
SendByte(B10110010); // Channel 2 vol 0010
|
||||
SendByte(B10100000); SendByte(B00010000); // Note on ch2
|
||||
delay(500);
|
||||
SendByte(B11010100); // Channel 3 vol 0100
|
||||
SendByte(B11000000); SendByte(B00001000); // Note on ch3
|
||||
delay(500);
|
||||
|
||||
SendByte(B10011111); // Sil ch 1
|
||||
SendByte(B10111111); // Sil ch 2
|
||||
SendByte(B11011111); // Sil ch 3
|
||||
|
||||
delay(1000);
|
||||
/*
|
||||
* Play noise on channel 4
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void loop() {}
|
||||
|
||||
void SendByte(byte b) {
|
||||
digitalWrite(DATA_BUS[0], (b&1)?HIGH:LOW);
|
||||
digitalWrite(DATA_BUS[1], (b&2)?HIGH:LOW);
|
||||
digitalWrite(DATA_BUS[2], (b&4)?HIGH:LOW);
|
||||
digitalWrite(DATA_BUS[3], (b&8)?HIGH:LOW);
|
||||
digitalWrite(DATA_BUS[4], (b&16)?HIGH:LOW);
|
||||
digitalWrite(DATA_BUS[5], (b&32)?HIGH:LOW);
|
||||
digitalWrite(DATA_BUS[6], (b&64)?HIGH:LOW);
|
||||
digitalWrite(DATA_BUS[7], (b&128)?HIGH:LOW);
|
||||
delay(1);
|
||||
digitalWrite(WE, LOW);
|
||||
delay(1);
|
||||
digitalWrite(WE, HIGH);
|
||||
}
|
@ -0,0 +1,175 @@
|
||||
/* ************** EEPROM PROGRAMMER ******************
|
||||
|
||||
HARDWARE:
|
||||
|
||||
CORRISPONDENZA PIN EEPROM Atmel AT28C64B -> ARDUINO MEGA 2560
|
||||
(Compatibile con eeprom fino a 16 bit di address bus. In caso di altre eeprom collegare secondo datasheet)
|
||||
NB: Nel caso della eeprom da 8k, ci sono solo 12 address bus, quindi gli altri 4 pin provenienti dall'Arduino
|
||||
vengono lasciati disconnessi
|
||||
|
||||
Arduino VCC 11 38 40 44 10 42 12 9 8 7 6 5
|
||||
Eeprom 28 27 26 25 24 23 22 21 20 19 18 17 16 15
|
||||
____________________________________________________________________
|
||||
| |
|
||||
| |
|
||||
|_ |
|
||||
|_) Atmel AT28C64B |
|
||||
| |
|
||||
| |
|
||||
|____________________________________________________________________|
|
||||
|
||||
Eeprom 1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
||||
Arduino 46 36 34 32 30 28 26 24 22 2 3 4 GND
|
||||
|
||||
|
||||
|
||||
|
||||
CORRISPONDENZA FUNZIONALE:
|
||||
|
||||
Address bus (A0...A15): 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52
|
||||
|
||||
Data bus (D0...D7): 2, 3, 4, 5, 6, 7, 8, 9
|
||||
|
||||
Control bus:
|
||||
/OE 10
|
||||
/WE 11
|
||||
/CE 12
|
||||
|
||||
*/
|
||||
|
||||
const byte ROM_DATA[] = {0x76, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00};
|
||||
|
||||
|
||||
const byte ADDR_BUS[] = {52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22};
|
||||
const byte DATA_BUS[] = {9, 8, 7, 6, 5, 4, 3, 2};
|
||||
const byte CTRL_BUS_OE = 10;
|
||||
const byte CTRL_BUS_WE = 11;
|
||||
const byte CTRL_BUS_CE = 12;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(57600);
|
||||
for(int pin=0; pin < 16; pin++) {
|
||||
pinMode(ADDR_BUS[pin], OUTPUT);
|
||||
}
|
||||
setDataBusAs(INPUT);
|
||||
pinMode(CTRL_BUS_OE, OUTPUT);
|
||||
pinMode(CTRL_BUS_WE, OUTPUT);
|
||||
pinMode(CTRL_BUS_CE, OUTPUT);
|
||||
digitalWrite(CTRL_BUS_OE, HIGH); //Active low
|
||||
digitalWrite(CTRL_BUS_WE, HIGH); //Active low
|
||||
digitalWrite(CTRL_BUS_CE, HIGH); //Active low
|
||||
|
||||
delay(1000);
|
||||
|
||||
//readRom(8192);
|
||||
writeRom();
|
||||
verifyRom();
|
||||
}
|
||||
|
||||
void writeRom() {
|
||||
digitalWrite(CTRL_BUS_OE, HIGH);
|
||||
setDataBusAs(OUTPUT);
|
||||
Serial.print("Starting to write ROM... ");
|
||||
for (int i=0; i<sizeof(ROM_DATA); i++) {
|
||||
writeIntToAddressBus(i);
|
||||
delayMicroseconds(5); // Address hold time (tAH)
|
||||
digitalWrite(CTRL_BUS_CE, LOW);
|
||||
digitalWrite(CTRL_BUS_WE, LOW);
|
||||
writeByteToDataBus(ROM_DATA[i]);
|
||||
delayMicroseconds(5); // Data setup time (tDS)
|
||||
digitalWrite(CTRL_BUS_WE, HIGH);
|
||||
digitalWrite(CTRL_BUS_CE, HIGH); //Active low
|
||||
delayMicroseconds(5); // Data hold time (tDH)
|
||||
}
|
||||
setDataBusAs(INPUT);
|
||||
Serial.println("Done.");
|
||||
}
|
||||
|
||||
void verifyRom() {
|
||||
Serial.print("Starting to verify ROM... ");
|
||||
digitalWrite(CTRL_BUS_WE, HIGH); //Active low
|
||||
char output[50] = {};
|
||||
for (int i=0; i<sizeof(ROM_DATA); i++) {
|
||||
writeIntToAddressBus(i);
|
||||
delayMicroseconds(5);
|
||||
digitalWrite(CTRL_BUS_OE, LOW); //Active low
|
||||
digitalWrite(CTRL_BUS_CE, LOW); //Active low
|
||||
delayMicroseconds(5);
|
||||
byte readData = getData();
|
||||
if(readData != ROM_DATA[i]) {
|
||||
sprintf(output, "Error at addr %04x: expected %02x, found %02x", i, ROM_DATA[i], readData);
|
||||
Serial.println(output);
|
||||
}
|
||||
|
||||
while(true){}
|
||||
digitalWrite(CTRL_BUS_OE, HIGH); //Active low
|
||||
digitalWrite(CTRL_BUS_CE, HIGH); //Active low
|
||||
delayMicroseconds(5);
|
||||
}
|
||||
Serial.println("Done.");
|
||||
}
|
||||
|
||||
void readRom(int bytes) {
|
||||
digitalWrite(CTRL_BUS_WE, HIGH); //Active low
|
||||
char output[50] = {};
|
||||
for (int i=0; i<bytes; i++) {
|
||||
writeIntToAddressBus(i);
|
||||
delayMicroseconds(5);
|
||||
digitalWrite(CTRL_BUS_OE, LOW); //Active low
|
||||
digitalWrite(CTRL_BUS_CE, LOW); //Active low
|
||||
delayMicroseconds(5);
|
||||
byte readData = getData();
|
||||
sprintf(output, "0x%02x ", readData);
|
||||
Serial.print(output);
|
||||
digitalWrite(CTRL_BUS_OE, HIGH); //Active low
|
||||
digitalWrite(CTRL_BUS_CE, HIGH); //Active low
|
||||
delayMicroseconds(5);
|
||||
}
|
||||
Serial.println("Done.");
|
||||
}
|
||||
|
||||
unsigned int getData() {
|
||||
setDataBusAs(INPUT);
|
||||
unsigned int data = 0;
|
||||
for(int pin=0; pin < 8; pin++) {
|
||||
byte b = digitalRead(DATA_BUS[pin]) ? 1 : 0;
|
||||
data = (data << 1) + b; // Shifta di 1 e aggiunge il bit corrente. Serve per ricostruire il numero da binario
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void setDataBusAs(byte mode){
|
||||
for(int pin=0; pin < 8; pin++) {
|
||||
pinMode(DATA_BUS[pin], mode);
|
||||
}
|
||||
}
|
||||
|
||||
void writeByteToDataBus(byte j) {
|
||||
setDataBusAs(OUTPUT);
|
||||
for (int n=0; n<8; n++)
|
||||
{
|
||||
if((0x01&j) < 0x01)
|
||||
{
|
||||
digitalWrite(DATA_BUS[n],LOW);
|
||||
} else {
|
||||
digitalWrite(DATA_BUS[n],HIGH);
|
||||
}
|
||||
j>>=1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void writeIntToAddressBus(int j) {
|
||||
for (int n=0; n<16; n++)
|
||||
{
|
||||
if((0x01&j) < 0x01)
|
||||
{
|
||||
digitalWrite(ADDR_BUS[n],LOW);
|
||||
} else {
|
||||
digitalWrite(ADDR_BUS[n],HIGH);
|
||||
}
|
||||
j>>=1;
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {}
|
@ -0,0 +1,35 @@
|
||||
/* HD44780 Character display debugger */
|
||||
|
||||
#define EN 2
|
||||
const byte DATA_BUS[] = {10, 9, 8, 7, 6, 5, 4, 3};
|
||||
|
||||
void setup() {
|
||||
pinMode(EN, INPUT_PULLUP);
|
||||
for(int pin=0; pin < 8; pin++) {
|
||||
pinMode(DATA_BUS[pin], INPUT);
|
||||
}
|
||||
|
||||
Serial.begin(57600);
|
||||
Serial.println("HD44780 debugger");
|
||||
Serial.println("DATA BUS HEX EN");
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(EN), onClk, FALLING);
|
||||
}
|
||||
|
||||
void loop() {}
|
||||
|
||||
void onClk() {
|
||||
unsigned int data = 0;
|
||||
for(int pin=0; pin < 8; pin++) {
|
||||
byte b = digitalRead(DATA_BUS[pin]) ? 1 : 0;
|
||||
Serial.print(b);
|
||||
data = (data << 1) + b; // Shifta di 1 e aggiunge il bit corrente. Serve per ricostruire il numero da binario
|
||||
}
|
||||
|
||||
char output[50] = {};
|
||||
sprintf(output, " 0x%02x %c",
|
||||
data,
|
||||
digitalRead(EN) ? 'D' : 'I'
|
||||
);
|
||||
Serial.println(output);
|
||||
}
|
67
prototiping-with-arduino/pal_adapter/pal_adapter.ino
Normal file
67
prototiping-with-arduino/pal_adapter/pal_adapter.ino
Normal file
@ -0,0 +1,67 @@
|
||||
#include <TVout.h>
|
||||
#include <TVoutfonts/fontALL.h>
|
||||
TVout TV;
|
||||
|
||||
// Pins
|
||||
#define RS 5
|
||||
#define EN 4
|
||||
const byte DATA [] = {A5, A4, A3, A2, 13, 12, 11, 10};
|
||||
|
||||
|
||||
bool clkState = false;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(57600);
|
||||
Serial.println("PAL debugger");
|
||||
|
||||
// Init comm pins
|
||||
pinMode(EN, INPUT);
|
||||
pinMode(RS, INPUT);
|
||||
for(int pin = 0; pin < 8; pin++) {
|
||||
pinMode(DATA[pin], INPUT);
|
||||
}
|
||||
|
||||
// Init VGA
|
||||
TV.begin(PAL,120,96);
|
||||
TV.select_font(font4x6);
|
||||
|
||||
TV.println("TV init");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
bool newClkState = digitalRead(EN);
|
||||
if (newClkState == false && clkState == true) {
|
||||
// Falling edge: read data from bus
|
||||
onClk();
|
||||
}
|
||||
clkState = newClkState;
|
||||
}
|
||||
|
||||
void onClk() {
|
||||
bool isCommand = digitalRead(RS);
|
||||
if (isCommand) {
|
||||
//onCommandReceived();
|
||||
onDataReceived();
|
||||
} else {
|
||||
onDataReceived();
|
||||
}
|
||||
}
|
||||
|
||||
void onCommandReceived() {
|
||||
|
||||
}
|
||||
|
||||
void onDataReceived() {
|
||||
char ch = readByte();
|
||||
TV.print(ch);
|
||||
Serial.println(ch);
|
||||
}
|
||||
|
||||
byte readByte() {
|
||||
unsigned int data = 0;
|
||||
for(int pin=0; pin < 8; pin++) {
|
||||
byte b = digitalRead(DATA[pin]) ? 1 : 0;
|
||||
data = (data << 1) + b; // Shifta di 1 e aggiunge il bit corrente. Serve per ricostruire il numero da binario
|
||||
}
|
||||
return data;
|
||||
}
|
113
prototiping-with-arduino/sdcard-test/sdcard-test.ino
Normal file
113
prototiping-with-arduino/sdcard-test/sdcard-test.ino
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* SPI SD-Card test sketch
|
||||
* Reads the first 128 bytes from cf and prints it out as ascii characters in serial monitor at 9200 baud
|
||||
*
|
||||
* Implementation of the specification at http://elm-chan.org/docs/mmc/mmc_e.html
|
||||
*/
|
||||
|
||||
#define CS 5 // aka CAT3
|
||||
#define MOSI 4 // aka DI or CMD
|
||||
#define SCK 3 // aka CAT3
|
||||
#define MISO 2 // aka DAT0
|
||||
|
||||
void setup() {
|
||||
pinMode(CS, OUTPUT);
|
||||
pinMode(MOSI, OUTPUT);
|
||||
pinMode(SCK, OUTPUT);
|
||||
pinMode(MISO, INPUT);
|
||||
|
||||
Serial.begin(9600);
|
||||
|
||||
/***** Init sequence *******/
|
||||
|
||||
// Wait 1ms
|
||||
delay(1);
|
||||
|
||||
Serial.println("Init card...");
|
||||
|
||||
|
||||
// >= 75 clocks with CS and DI high
|
||||
digitalWrite(CS, HIGH);
|
||||
digitalWrite(MOSI, HIGH);
|
||||
for (byte i=0; i<80; i++) {
|
||||
clk();
|
||||
}
|
||||
|
||||
// CMD0 with CS low (Software reset). Means "Leave native mode and enter SPI mode"
|
||||
digitalWrite(CS, LOW);
|
||||
sendCommand(B01000000); // First two bits are always 01. Command is 0 (000000).
|
||||
byte resp = receiveResponse();
|
||||
Serial.println("Card response:");
|
||||
Serial.println(resp, HEX);
|
||||
digitalWrite(CS, HIGH);
|
||||
|
||||
}
|
||||
|
||||
void loop() {}
|
||||
|
||||
/**
|
||||
* Sends a clock cycle
|
||||
*/
|
||||
void clk() {
|
||||
digitalWrite(SCK, HIGH);
|
||||
//delayMicroseconds(1);
|
||||
digitalWrite(SCK, LOW);
|
||||
//delayMicroseconds(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a command to card.
|
||||
* The sent CRC field is valid for the CMD0 message.
|
||||
* This is ok, since the CRC field will not be checked in SPI mode.
|
||||
* @param index: the command index byte. First two bytes are the sync bytes "01".
|
||||
*/
|
||||
void sendCommand(byte index) {
|
||||
// Send command index (2+6=8 bits)
|
||||
sendByte(index);
|
||||
// Send argument (32 bit)
|
||||
for(byte i=0; i<4; i++) {
|
||||
sendByte(0);
|
||||
}
|
||||
// Send CRC with final stop bit (7+1=8 bits)
|
||||
sendByte(B10010101); // We send always the CMD0 CRC, because is not checked in SPI mode
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a byte to the card. The two MSB must be 01 as per specification.
|
||||
* Byte is sent MSB first.
|
||||
*/
|
||||
void sendByte(byte b) {
|
||||
for (byte i=0; i<8; i++) {
|
||||
// If last bit is 1 set MOSI HIGH, else LOW
|
||||
digitalWrite(MOSI, (b & B10000000) == B10000000 ? HIGH : LOW);
|
||||
clk();
|
||||
// Shift byte to have, in the next cycle, the next bit in last position
|
||||
b = b << 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives the response from card
|
||||
* MSB first.
|
||||
*/
|
||||
byte receiveResponse() {
|
||||
digitalWrite(CS, LOW);
|
||||
digitalWrite(MOSI, HIGH);
|
||||
|
||||
// continuously toggle the SD CLK signal and observe the MISO line for data:
|
||||
// message response starts with 0
|
||||
while (digitalRead(MISO)) {
|
||||
clk();
|
||||
} // Wait for first 0
|
||||
|
||||
byte resp = 0;
|
||||
// Read 8 bits
|
||||
for (byte i=0; i<8; i++) {
|
||||
if (digitalRead(MISO)) {
|
||||
resp = resp | B00000001;
|
||||
}
|
||||
resp = resp << 1;
|
||||
clk();
|
||||
}
|
||||
|
||||
}
|
221
prototiping-with-arduino/z80_debugger/z80_debugger.ino
Normal file
221
prototiping-with-arduino/z80_debugger/z80_debugger.ino
Normal file
@ -0,0 +1,221 @@
|
||||
/* ************** DEBUGGER Zilog Z80 ******************
|
||||
|
||||
HARDWARE:
|
||||
|
||||
CORRISPONDENZA PIN CPU -> ARDUINO MEGA 2560
|
||||
|
||||
Arduino A12 A15 A14 53 51 49 47 45 43 41 39 37 35 33 31 29 27 25 23 20
|
||||
Cpu 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21
|
||||
__________________________________________________________________________________________________
|
||||
| |
|
||||
| |
|
||||
|_ |
|
||||
|_) Zilog Z80 |
|
||||
| |
|
||||
| |
|
||||
|__________________________________________________________________________________________________|
|
||||
|
||||
Cpu 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
||||
Arduino A8 A9 A11 52 50 21 46 44 42 40 38 36 34 32 30 28 26 24 22 A13
|
||||
|
||||
|
||||
|
||||
|
||||
CORRISPONDENZA FUNZIONALE:
|
||||
Address bus (A0...A15): 39, 41, 43, 45, 47, 49, 51, 53, A14, A15, A12, A8, A9, A11, 52, 50
|
||||
Data bus (D0...D7): 32, 30, 36, 44, 46, 42, 40, 34
|
||||
Control bus:
|
||||
CLK 21
|
||||
INT 28
|
||||
NMI 26
|
||||
HALT 24
|
||||
MREQ 22
|
||||
IORQ A13
|
||||
RFSH 35
|
||||
RD 20
|
||||
WR 23
|
||||
BUSACK 25
|
||||
WAIT 27
|
||||
BUSREQ 29
|
||||
RESET 31
|
||||
M1 33
|
||||
Other
|
||||
GND 37, GND
|
||||
Vcc 38
|
||||
|
||||
*/
|
||||
|
||||
|
||||
const byte MODE_DEBUGGER = 0;
|
||||
const byte MODE_ROM_EMULATOR = 1;
|
||||
const byte MODE_ROM_RAM_EMULATOR = 2;
|
||||
|
||||
const byte ADDR_BUS[] = {50, 52, A11, A9, A8, A12, A15, A14, 53, 51, 49, 47, 45, 43, 41, 39};
|
||||
//const byte DATA_BUS[] = {34, 40, 42, 44, 46, 36, 30, 32};
|
||||
const byte DATA_BUS[] = {3, 4, 5, 6, 7, 8, 9,10};
|
||||
//const byte CTRL_BUS_RD = 20;
|
||||
const byte CTRL_BUS_RD = 3;
|
||||
const byte CTRL_BUS_WR = 23;
|
||||
const byte CTRL_BUS_BUSACK = 25;
|
||||
const byte CTRL_BUS_WAIT = 27;
|
||||
const byte CTRL_BUS_BUSREQ = 29;
|
||||
const byte CTRL_BUS_RESET = 31;
|
||||
const byte CTRL_BUS_M1 = 33;
|
||||
const byte CTRL_BUS_REFRESH = 35;
|
||||
const byte CTRL_BUS_IORQ = A13;
|
||||
const byte CTRL_BUS_MREQ = 22;
|
||||
const byte CTRL_BUS_HALT = 24;
|
||||
const byte CTRL_BUS_NMI = 26;
|
||||
//const byte CTRL_BUS_CLK= 21;
|
||||
const byte CTRL_BUS_CLK= 2;
|
||||
const byte CTRL_BUS_INT = 28;
|
||||
const byte PWR_GND = 37;
|
||||
const byte PWR_VCC = 38;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* SETUP
|
||||
* Mode:
|
||||
* MODE_DEBUGGER = Debugger (stays in high impedance mode listening to inputs/outputs on data, address and control buses)
|
||||
* MODE_ROM_EMULATOR = Emulates rom with the contents of ROM_DATA
|
||||
* MODE_ROM_RAM_EMULATOR = Emulates ram
|
||||
*/
|
||||
const byte MODE = MODE_DEBUGGER;
|
||||
|
||||
const byte ROM_DATA[] = {0x00, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00};
|
||||
//const byte ROM_DATA[] = {0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(57600);
|
||||
Serial.print("Started in mode ");
|
||||
switch(MODE) {
|
||||
case MODE_DEBUGGER:
|
||||
Serial.println("debugger");
|
||||
break;
|
||||
case MODE_ROM_EMULATOR:
|
||||
Serial.println("rom emulator");
|
||||
break;
|
||||
case MODE_ROM_RAM_EMULATOR:
|
||||
Serial.println("rom/ram emulator");
|
||||
break;
|
||||
}
|
||||
for(int pin=0; pin < 16; pin++) {
|
||||
pinMode(ADDR_BUS[pin], INPUT);
|
||||
}
|
||||
setDataBusAs(INPUT);
|
||||
pinMode(CTRL_BUS_RD, INPUT);
|
||||
pinMode(CTRL_BUS_WR, INPUT);
|
||||
pinMode(CTRL_BUS_BUSACK, INPUT);
|
||||
pinMode(CTRL_BUS_WAIT, INPUT);
|
||||
pinMode(CTRL_BUS_BUSREQ, INPUT);
|
||||
pinMode(CTRL_BUS_RESET, INPUT);
|
||||
pinMode(CTRL_BUS_M1, INPUT);
|
||||
pinMode(CTRL_BUS_REFRESH, INPUT);
|
||||
pinMode(CTRL_BUS_IORQ, INPUT);
|
||||
pinMode(CTRL_BUS_MREQ, INPUT);
|
||||
pinMode(CTRL_BUS_HALT, INPUT);
|
||||
pinMode(CTRL_BUS_NMI, INPUT);
|
||||
pinMode(CTRL_BUS_CLK, INPUT);
|
||||
pinMode(CTRL_BUS_INT, INPUT);
|
||||
|
||||
// Set power pins to high impedance, even if we aren't going to read them, to avoid shorts
|
||||
pinMode(PWR_GND, INPUT);
|
||||
pinMode(PWR_VCC, INPUT);
|
||||
|
||||
attachInterrupt(digitalPinToInterrupt(CTRL_BUS_CLK), onClk, RISING);
|
||||
|
||||
}
|
||||
|
||||
void onClk() {
|
||||
setDataBusAs(INPUT);
|
||||
|
||||
switch (MODE) {
|
||||
case MODE_DEBUGGER:
|
||||
debugCycle();
|
||||
break;
|
||||
case MODE_ROM_EMULATOR:
|
||||
emulateRomCycle();
|
||||
break;
|
||||
default:
|
||||
Serial.println("Unimplemented mode");
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {}
|
||||
|
||||
void debugCycle() {
|
||||
if (!digitalRead(CTRL_BUS_RD) || !digitalRead(CTRL_BUS_WR)) { //RD e WR are active-low
|
||||
unsigned int address = getAddress();
|
||||
unsigned int data = getData();
|
||||
|
||||
char output[30] = {};
|
||||
sprintf(output, "%04x %c%c %02x %s", address, digitalRead(CTRL_BUS_RD) ? '-' : 'r', digitalRead(CTRL_BUS_WR) ? '-' : 'w', data, digitalRead(CTRL_BUS_RESET) ? "" : "reset");
|
||||
Serial.println(output);
|
||||
}
|
||||
}
|
||||
|
||||
void emulateRomCycle() {
|
||||
if (!digitalRead(CTRL_BUS_RD)) { //RD e WR are active-low
|
||||
unsigned int addr = getAddress();
|
||||
if (addr < sizeof(ROM_DATA)) {
|
||||
unsigned int data = ROM_DATA[addr];
|
||||
writeByteToDataBus(data);
|
||||
|
||||
char output[30] = {};
|
||||
sprintf(output, "%04x r- %02x Emu ROM read", addr, data);
|
||||
Serial.println(output);
|
||||
}
|
||||
}
|
||||
if (!digitalRead(CTRL_BUS_WR)) {
|
||||
debugCycle();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int getAddress() {
|
||||
unsigned int address = 0;
|
||||
for(int pin=0; pin < 16; pin++) {
|
||||
byte b = digitalRead(ADDR_BUS[pin]) ? 1 : 0;
|
||||
//Serial.print(b);
|
||||
address = (address << 1) + b; // Shifta di 1 e aggiunge il bit corrente. Serve per ricostruire il numero da binario
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
unsigned int getData() {
|
||||
unsigned int data = 0;
|
||||
for(int pin=0; pin < 8; pin++) {
|
||||
byte b = digitalRead(DATA_BUS[pin]) ? 1 : 0;
|
||||
//Serial.print(b);
|
||||
data = (data << 1) + b; // Shifta di 1 e aggiunge il bit corrente. Serve per ricostruire il numero da binario
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void setDataBusAs(byte mode){
|
||||
for(int pin=0; pin < 8; pin++) {
|
||||
pinMode(DATA_BUS[pin], mode);
|
||||
}
|
||||
}
|
||||
|
||||
void writeByteToDataBus(byte j) {
|
||||
setDataBusAs(OUTPUT);
|
||||
for (int n=0; n<8; n++)
|
||||
{
|
||||
if((0x01&j) < 0x01)
|
||||
{
|
||||
digitalWrite(DATA_BUS[n],LOW);
|
||||
} else {
|
||||
digitalWrite(DATA_BUS[n],HIGH);
|
||||
}
|
||||
j>>=1;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user