Reorganized folders, added pal-adapter io device folder

This commit is contained in:
Daniele Verducci su MatissePenguin
2021-01-02 16:33:51 +01:00
parent 55f5d62082
commit 68752e85a7
35 changed files with 327 additions and 1 deletions

View 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);
}

View File

@ -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() {}

View File

@ -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);
}

View 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;
}

View 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();
}
}

View 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;
}
}