/* ************** 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 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_ROM_EMULATOR; 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; } }