Working Z80 memory access and disassembler in the small GODIL, incremented version to 0.44

Change-Id: I718be7476ec330743c206e737389856fc4b41fc8
This commit is contained in:
David Banks 2015-06-28 19:42:25 +01:00
parent e4e0f864df
commit 0c0fde6a32
14 changed files with 1442 additions and 693 deletions

View File

@ -4,9 +4,7 @@
#include <ctype.h>
#include <avr/pgmspace.h>
#include "hd44780.h"
#include "status.h"
#include "AtomBusMon.h"
#if (CPU == Z80)
#define NAME "ICE-T80"
@ -14,198 +12,7 @@
#define NAME "ICE-T65"
#endif
#ifdef CPUEMBEDDED
unsigned int disMem(unsigned int addr);
enum
{
IMP, IMPA, MARK2, BRA, IMM, ZP, ZPX, ZPY, INDX, INDY, IND, MARK3, ABS, ABSX, ABSY, IND16, IND1X
};
enum
{
I_ADC,
I_AND,
I_ASL,
I_BCC,
I_BCS,
I_BEQ,
I_BIT,
I_BMI,
I_BNE,
I_BPL,
I_BRA,
I_BRK,
I_BVC,
I_BVS,
I_CLC,
I_CLD,
I_CLI,
I_CLV,
I_CMP,
I_CPX,
I_CPY,
I_DEC,
I_DEX,
I_DEY,
I_EOR,
I_INC,
I_INX,
I_INY,
I_JMP,
I_JSR,
I_LDA,
I_LDX,
I_LDY,
I_LSR,
I_NOP,
I_ORA,
I_PHA,
I_PHP,
I_PHX,
I_PHY,
I_PLA,
I_PLP,
I_PLX,
I_PLY,
I_ROL,
I_ROR,
I_RTI,
I_RTS,
I_SBC,
I_SEC,
I_SED,
I_SEI,
I_STA,
I_STP,
I_STX,
I_STY,
I_STZ,
I_TAX,
I_TAY,
I_TRB,
I_TSB,
I_TSX,
I_TXA,
I_TXS,
I_TYA,
I_WAI,
I_XXX
};
char *opStrings[67] = {
"ADC",
"AND",
"ASL",
"BCC",
"BCS",
"BEQ",
"BIT",
"BMI",
"BNE",
"BPL",
"BRA",
"BRK",
"BVC",
"BVS",
"CLC",
"CLD",
"CLI",
"CLV",
"CMP",
"CPX",
"CPY",
"DEC",
"DEX",
"DEY",
"EOR",
"INC",
"INX",
"INY",
"JMP",
"JSR",
"LDA",
"LDX",
"LDY",
"LSR",
"NOP",
"ORA",
"PHA",
"PHP",
"PHX",
"PHY",
"PLA",
"PLP",
"PLX",
"PLY",
"ROL",
"ROR",
"RTI",
"RTS",
"SBC",
"SEC",
"SED",
"SEI",
"STA",
"STP",
"STX",
"STY",
"STZ",
"TAX",
"TAY",
"TRB",
"TSB",
"TSX",
"TXA",
"TXS",
"TYA",
"WAI",
"---"
};
unsigned char dopname[256] =
{
/*00*/ I_BRK, I_ORA, I_XXX, I_XXX, I_TSB, I_ORA, I_ASL, I_XXX, I_PHP, I_ORA, I_ASL, I_XXX, I_TSB, I_ORA, I_ASL, I_XXX,
/*10*/ I_BPL, I_ORA, I_ORA, I_XXX, I_TRB, I_ORA, I_ASL, I_XXX, I_CLC, I_ORA, I_INC, I_XXX, I_TRB, I_ORA, I_ASL, I_XXX,
/*20*/ I_JSR, I_AND, I_XXX, I_XXX, I_BIT, I_AND, I_ROL, I_XXX, I_PLP, I_AND, I_ROL, I_XXX, I_BIT, I_AND, I_ROL, I_XXX,
/*30*/ I_BMI, I_AND, I_AND, I_XXX, I_BIT, I_AND, I_ROL, I_XXX, I_SEC, I_AND, I_DEC, I_XXX, I_BIT, I_AND, I_ROL, I_XXX,
/*40*/ I_RTI, I_EOR, I_XXX, I_XXX, I_XXX, I_EOR, I_LSR, I_XXX, I_PHA, I_EOR, I_LSR, I_XXX, I_JMP, I_EOR, I_LSR, I_XXX,
/*50*/ I_BVC, I_EOR, I_EOR, I_XXX, I_XXX, I_EOR, I_LSR, I_XXX, I_CLI, I_EOR, I_PHY, I_XXX, I_XXX, I_EOR, I_LSR, I_XXX,
/*60*/ I_RTS, I_ADC, I_XXX, I_XXX, I_STZ, I_ADC, I_ROR, I_XXX, I_PLA, I_ADC, I_ROR, I_XXX, I_JMP, I_ADC, I_ROR, I_XXX,
/*70*/ I_BVS, I_ADC, I_ADC, I_XXX, I_STZ, I_ADC, I_ROR, I_XXX, I_SEI, I_ADC, I_PLY, I_XXX, I_JMP, I_ADC, I_ROR, I_XXX,
/*80*/ I_BRA, I_STA, I_XXX, I_XXX, I_STY, I_STA, I_STX, I_XXX, I_DEY, I_BIT, I_TXA, I_XXX, I_STY, I_STA, I_STX, I_XXX,
/*90*/ I_BCC, I_STA, I_STA, I_XXX, I_STY, I_STA, I_STX, I_XXX, I_TYA, I_STA, I_TXS, I_XXX, I_STZ, I_STA, I_STZ, I_XXX,
/*A0*/ I_LDY, I_LDA, I_LDX, I_XXX, I_LDY, I_LDA, I_LDX, I_XXX, I_TAY, I_LDA, I_TAX, I_XXX, I_LDY, I_LDA, I_LDX, I_XXX,
/*B0*/ I_BCS, I_LDA, I_LDA, I_XXX, I_LDY, I_LDA, I_LDX, I_XXX, I_CLV, I_LDA, I_TSX, I_XXX, I_LDY, I_LDA, I_LDX, I_XXX,
/*C0*/ I_CPY, I_CMP, I_XXX, I_XXX, I_CPY, I_CMP, I_DEC, I_XXX, I_INY, I_CMP, I_DEX, I_WAI, I_CPY, I_CMP, I_DEC, I_XXX,
/*D0*/ I_BNE, I_CMP, I_CMP, I_XXX, I_XXX, I_CMP, I_DEC, I_XXX, I_CLD, I_CMP, I_PHX, I_STP, I_XXX, I_CMP, I_DEC, I_XXX,
/*E0*/ I_CPX, I_SBC, I_XXX, I_XXX, I_CPX, I_SBC, I_INC, I_XXX, I_INX, I_SBC, I_NOP, I_XXX, I_CPX, I_SBC, I_INC, I_XXX,
/*F0*/ I_BEQ, I_SBC, I_SBC, I_XXX, I_XXX, I_SBC, I_INC, I_XXX, I_SED, I_SBC, I_PLX, I_XXX, I_XXX, I_SBC, I_INC, I_XXX
};
unsigned char dopaddr[256] =
{
/*00*/ IMP, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
/*10*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMPA, IMP, ABS, ABSX, ABSX, IMP,
/*20*/ ABS, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
/*30*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPX, IMP, IMP, ABSY, IMPA, IMP, ABSX, ABSX, ABSX, IMP,
/*40*/ IMP, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
/*50*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP,
/*60*/ IMP, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, IND16, ABS, ABS, IMP,
/*70*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, IND1X, ABSX, ABSX, IMP,
/*80*/ BRA, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
/*90*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPY, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP,
/*A0*/ IMM, INDX, IMM, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
/*B0*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPY, IMP, IMP, ABSY, IMP, IMP, ABSX, ABSX, ABSY, IMP,
/*C0*/ IMM, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
/*D0*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP,
/*E0*/ IMM, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
/*F0*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP
};
#endif
#define CRC_POLY 0x002d
#define CRC_POLY 0x002d
#define CTRL_PORT PORTB
#define CTRL_DDR DDRB
@ -242,20 +49,29 @@ unsigned char dopaddr[256] =
// Processor registers
#if (CPU == Z80)
#define OFFSET_REG_F 16
#define OFFSET_REG_A 17
#define OFFSET_REG_Fp 18
#define OFFSET_REG_Ap 19
#define OFFSET_REG_BC 32
#define OFFSET_REG_DE 34
#define OFFSET_REG_HL 36
#define OFFSET_REG_IX 38
#define OFFSET_REG_BCp 40
#define OFFSET_REG_DEp 42
#define OFFSET_REG_HLp 44
#define OFFSET_REG_IY 46
#define OFFSET_REG_AF 48
#define OFFSET_REG_AFp 50
#define OFFSET_REG_SP 52
#define OFFSET_REG_PC 54
#define OFFSET_REG_I 56
#define OFFSET_REG_R 57
#define OFFSET_REG_IFF 58
#else
#define OFFSET_REG_A 16
#define OFFSET_REG_X 17
#define OFFSET_REG_Y 18
#define OFFSET_REG_P 19
#define OFFSET_REG_A 32
#define OFFSET_REG_X 33
#define OFFSET_REG_Y 34
#define OFFSET_REG_P 35
#define OFFSET_REG_SP 36
#define OFFSET_REG_PC 38
#endif
#define OFFSET_REG_SPL 20
#define OFFSET_REG_SPH 21
#define OFFSET_REG_PCL 22
#define OFFSET_REG_PCH 23
// Commands
// 000x Enable/Disable single strpping
@ -280,7 +96,7 @@ unsigned char dopaddr[256] =
// Control bits
#define CMD_MASK 0x3F
#define CMD_EDGE 0x20
#define MUXSEL_MASK 0x1F
#define MUXSEL_MASK 0x3F
#define MUXSEL_BIT 0
// Status bits
@ -344,17 +160,18 @@ char *triggerStrings[NUM_TRIGGERS] = {
};
#define VERSION "0.43"
#define VERSION "0.44"
#ifdef CPUEMBEDDED
#define NUM_CMDS 22
#if (CPU != Z80)
#define NUM_CMDS 22
#else
#define NUM_CMDS 21
#endif
#else
#define NUM_CMDS 14
#define NUM_CMDS 14
#endif
#define MAXBKPTS 8
int numbkpts = 0;
long trace;
long instructions = 1;
@ -367,58 +184,18 @@ char statusString[8] = "SZIH-P-C";
char statusString[8] = "NV-BDIZC";
#endif
unsigned int breakpoints[MAXBKPTS] = {
#if (CPU != Z80)
0,
0,
0,
0,
0,
0,
0,
#endif
0
};
int numbkpts = 0;
unsigned int masks[MAXBKPTS] = {
#if (CPU != Z80)
0,
0,
0,
0,
0,
0,
0,
#if (CPU == Z80)
#define MAXBKPTS 4
#else
#define MAXBKPTS 8
#endif
0
};
unsigned int modes[MAXBKPTS] = {
#if (CPU != Z80)
0,
0,
0,
0,
0,
0,
0,
#endif
0
};
int triggers[MAXBKPTS] = {
#if (CPU != Z80)
0,
0,
0,
0,
0,
0,
0,
#endif
0
};
unsigned int breakpoints[MAXBKPTS];
unsigned int masks[MAXBKPTS];
unsigned int modes[MAXBKPTS];
int triggers[MAXBKPTS];
char *cmdStrings[NUM_CMDS] = {
"help",
@ -431,7 +208,9 @@ char *cmdStrings[NUM_CMDS] = {
"write",
"fill",
"crc",
#if (CPU != Z80)
"test",
#endif
#endif
"reset",
"step",
@ -687,81 +466,6 @@ void writeByteInc() {
hwCmd(CMD_WR_MEM_INC, 0);
}
unsigned int disassemble(unsigned int addr)
{
unsigned int temp;
unsigned int op = readByteInc();
int mode = dopaddr[op];
unsigned int p1 = (mode > MARK2) ? readByteInc() : 0;
unsigned int p2 = (mode > MARK3) ? readByteInc() : 0;
log0("%04X : %s ", addr, opStrings[dopname[op]]);
switch (mode)
{
case IMP:
log0(" ");
break;
case IMPA:
log0("A ");
break;
case BRA:
temp = addr + 2 + (signed char)p1;
log0("%04X ", temp);
addr++;
break;
case IMM:
log0("#%02X ", p1);
addr++;
break;
case ZP:
log0("%02X ", p1);
addr++;
break;
case ZPX:
log0("%02X,X ", p1);
addr++;
break;
case ZPY:
log0("%02X,Y ", p1);
addr++;
break;
case IND:
log0("(%02X) ", p1);
addr++;
break;
case INDX:
log0("(%02X,X) ", p1);
addr++;
break;
case INDY:
log0("(%02X),Y ", p1);
addr++;
break;
case ABS:
log0("%02X%02X ", p2, p1);
addr += 2;
break;
case ABSX:
log0("%02X%02X,X ", p2, p1);
addr += 2;
break;
case ABSY:
log0("%02X%02X,Y ", p2, p1);
addr += 2;
break;
case IND16:
log0("(%02X%02X) ", p2, p1);
addr += 2;
break;
case IND1X:
log0("(%02X%02X,X)", p2, p1);
addr += 2;
break;
}
log0("\n");
addr++;
return addr;
}
unsigned int disMem(unsigned int addr) {
loadAddr(addr);
@ -838,20 +542,34 @@ void doCmdReset(char *params) {
void doCmdRegs(char *params) {
int i;
#if (CPU == Z80)
unsigned int p = hwRead16(OFFSET_REG_F);
log0("Z80 Registers:\n AF=%04X AF'=%04X SP=%04X PC=%04X\n",
unsigned int p = hwRead16(OFFSET_REG_AF);
log0("Z80 Registers:\n");
log0(" AF=%04X BC=%04X DE=%04X HL=%04X\n",
p,
hwRead16(OFFSET_REG_Fp),
hwRead16(OFFSET_REG_SPL),
hwRead16(OFFSET_REG_PCL));
hwRead16(OFFSET_REG_BC),
hwRead16(OFFSET_REG_DE),
hwRead16(OFFSET_REG_HL));
log0(" 'AF=%04X 'BC=%04X 'DE=%04X 'HL=%04X\n",
hwRead16(OFFSET_REG_AFp),
hwRead16(OFFSET_REG_BCp),
hwRead16(OFFSET_REG_DEp),
hwRead16(OFFSET_REG_HLp));
log0(" IX=%04X IY=%04X PC=%04X SP=%04X I=%02X R=%02X IFF=%02X\n",
hwRead16(OFFSET_REG_IX),
hwRead16(OFFSET_REG_IY),
hwRead16(OFFSET_REG_PC),
hwRead16(OFFSET_REG_SP),
hwRead8(OFFSET_REG_I),
hwRead8(OFFSET_REG_R),
hwRead8(OFFSET_REG_IFF));
#else
unsigned int p = hwRead8(OFFSET_REG_P);
log0("6502 Registers:\n A=%02X X=%02X Y=%02X SP=%04X PC=%04X\n",
hwRead8(OFFSET_REG_A),
hwRead8(OFFSET_REG_X),
hwRead8(OFFSET_REG_Y),
hwRead16(OFFSET_REG_SPL),
hwRead16(OFFSET_REG_PCL));
hwRead16(OFFSET_REG_SP),
hwRead16(OFFSET_REG_PC));
#endif
char *sp = statusString;
log0(" Status: ");
@ -965,6 +683,7 @@ void doCmdCrc(char *params) {
log0("crc: %04X\n", crc);
}
#if (CPU != Z80)
unsigned int getData(unsigned int addr, int data) {
if (data == -1) {
// checkerboard
@ -1049,6 +768,8 @@ void doCmdTest(char *params) {
#endif
#endif
void doCmdTrace(char *params) {
long i;
sscanf(params, "%ld", &i);
@ -1304,7 +1025,9 @@ void (*cmdFuncs[NUM_CMDS])(char *params) = {
doCmdWrite,
doCmdFill,
doCmdCrc,
#if (CPU != Z80)
doCmdTest,
#endif
#endif
doCmdReset,
doCmdStep,

22
firmware/AtomBusMon.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef __ATOMBUSMON_DEFINES__
#define __ATOMBUSMON_DEFINES__
#include "status.h"
#include "dis.h"
#ifdef LCD
#include "hd44780.h"
#endif
#ifdef CPUEMBEDDED
unsigned int disMem(unsigned int addr);
void loadData(unsigned int data);
void loadAddr(unsigned int addr);
unsigned int readByte();
unsigned int readByteInc();
void writeByte();
void writeByteInc();
unsigned int disMem(unsigned int addr);
#endif
#endif

View File

@ -25,7 +25,7 @@ OBJCOPY=avr-objcopy
CFLAGS=-DCPU=6502 -DCPUEMBEDDED -DF_CPU=${F_CPU}UL -DSERIAL_STATUS -DCOOKED_SERIAL -DNOUSART1 -mmcu=$(MCU) -Wall -Os -mcall-prologues
OBJECTS=AtomBusMon.o hd44780.o status.o
OBJECTS=AtomBusMon.o dis6502.o status.o
build: avr6502cpu.bit

View File

@ -25,7 +25,7 @@ OBJCOPY=avr-objcopy
CFLAGS=-DCPU=Z80 -DCPUEMBEDDED -DF_CPU=${F_CPU}UL -DSERIAL_STATUS -DCOOKED_SERIAL -DNOUSART1 -mmcu=$(MCU) -Wall -Os -mcall-prologues
OBJECTS=AtomBusMon.o hd44780.o status.o
OBJECTS=AtomBusMon.o disz80.o status.o
build: avrz80cpu.bit

6
firmware/dis.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __DIS_DEFINES__
#define __DIS_DEFINES__
unsigned int disassemble(unsigned int addr);
#endif

263
firmware/dis6502.c Normal file
View File

@ -0,0 +1,263 @@
#include "AtomBusMon.h"
enum
{
IMP, IMPA, MARK2, BRA, IMM, ZP, ZPX, ZPY, INDX, INDY, IND, MARK3, ABS, ABSX, ABSY, IND16, IND1X
};
enum
{
I_ADC,
I_AND,
I_ASL,
I_BCC,
I_BCS,
I_BEQ,
I_BIT,
I_BMI,
I_BNE,
I_BPL,
I_BRA,
I_BRK,
I_BVC,
I_BVS,
I_CLC,
I_CLD,
I_CLI,
I_CLV,
I_CMP,
I_CPX,
I_CPY,
I_DEC,
I_DEX,
I_DEY,
I_EOR,
I_INC,
I_INX,
I_INY,
I_JMP,
I_JSR,
I_LDA,
I_LDX,
I_LDY,
I_LSR,
I_NOP,
I_ORA,
I_PHA,
I_PHP,
I_PHX,
I_PHY,
I_PLA,
I_PLP,
I_PLX,
I_PLY,
I_ROL,
I_ROR,
I_RTI,
I_RTS,
I_SBC,
I_SEC,
I_SED,
I_SEI,
I_STA,
I_STP,
I_STX,
I_STY,
I_STZ,
I_TAX,
I_TAY,
I_TRB,
I_TSB,
I_TSX,
I_TXA,
I_TXS,
I_TYA,
I_WAI,
I_XXX
};
char *opStrings[67] = {
"ADC",
"AND",
"ASL",
"BCC",
"BCS",
"BEQ",
"BIT",
"BMI",
"BNE",
"BPL",
"BRA",
"BRK",
"BVC",
"BVS",
"CLC",
"CLD",
"CLI",
"CLV",
"CMP",
"CPX",
"CPY",
"DEC",
"DEX",
"DEY",
"EOR",
"INC",
"INX",
"INY",
"JMP",
"JSR",
"LDA",
"LDX",
"LDY",
"LSR",
"NOP",
"ORA",
"PHA",
"PHP",
"PHX",
"PHY",
"PLA",
"PLP",
"PLX",
"PLY",
"ROL",
"ROR",
"RTI",
"RTS",
"SBC",
"SEC",
"SED",
"SEI",
"STA",
"STP",
"STX",
"STY",
"STZ",
"TAX",
"TAY",
"TRB",
"TSB",
"TSX",
"TXA",
"TXS",
"TYA",
"WAI",
"---"
};
unsigned char dopname[256] =
{
/*00*/ I_BRK, I_ORA, I_XXX, I_XXX, I_TSB, I_ORA, I_ASL, I_XXX, I_PHP, I_ORA, I_ASL, I_XXX, I_TSB, I_ORA, I_ASL, I_XXX,
/*10*/ I_BPL, I_ORA, I_ORA, I_XXX, I_TRB, I_ORA, I_ASL, I_XXX, I_CLC, I_ORA, I_INC, I_XXX, I_TRB, I_ORA, I_ASL, I_XXX,
/*20*/ I_JSR, I_AND, I_XXX, I_XXX, I_BIT, I_AND, I_ROL, I_XXX, I_PLP, I_AND, I_ROL, I_XXX, I_BIT, I_AND, I_ROL, I_XXX,
/*30*/ I_BMI, I_AND, I_AND, I_XXX, I_BIT, I_AND, I_ROL, I_XXX, I_SEC, I_AND, I_DEC, I_XXX, I_BIT, I_AND, I_ROL, I_XXX,
/*40*/ I_RTI, I_EOR, I_XXX, I_XXX, I_XXX, I_EOR, I_LSR, I_XXX, I_PHA, I_EOR, I_LSR, I_XXX, I_JMP, I_EOR, I_LSR, I_XXX,
/*50*/ I_BVC, I_EOR, I_EOR, I_XXX, I_XXX, I_EOR, I_LSR, I_XXX, I_CLI, I_EOR, I_PHY, I_XXX, I_XXX, I_EOR, I_LSR, I_XXX,
/*60*/ I_RTS, I_ADC, I_XXX, I_XXX, I_STZ, I_ADC, I_ROR, I_XXX, I_PLA, I_ADC, I_ROR, I_XXX, I_JMP, I_ADC, I_ROR, I_XXX,
/*70*/ I_BVS, I_ADC, I_ADC, I_XXX, I_STZ, I_ADC, I_ROR, I_XXX, I_SEI, I_ADC, I_PLY, I_XXX, I_JMP, I_ADC, I_ROR, I_XXX,
/*80*/ I_BRA, I_STA, I_XXX, I_XXX, I_STY, I_STA, I_STX, I_XXX, I_DEY, I_BIT, I_TXA, I_XXX, I_STY, I_STA, I_STX, I_XXX,
/*90*/ I_BCC, I_STA, I_STA, I_XXX, I_STY, I_STA, I_STX, I_XXX, I_TYA, I_STA, I_TXS, I_XXX, I_STZ, I_STA, I_STZ, I_XXX,
/*A0*/ I_LDY, I_LDA, I_LDX, I_XXX, I_LDY, I_LDA, I_LDX, I_XXX, I_TAY, I_LDA, I_TAX, I_XXX, I_LDY, I_LDA, I_LDX, I_XXX,
/*B0*/ I_BCS, I_LDA, I_LDA, I_XXX, I_LDY, I_LDA, I_LDX, I_XXX, I_CLV, I_LDA, I_TSX, I_XXX, I_LDY, I_LDA, I_LDX, I_XXX,
/*C0*/ I_CPY, I_CMP, I_XXX, I_XXX, I_CPY, I_CMP, I_DEC, I_XXX, I_INY, I_CMP, I_DEX, I_WAI, I_CPY, I_CMP, I_DEC, I_XXX,
/*D0*/ I_BNE, I_CMP, I_CMP, I_XXX, I_XXX, I_CMP, I_DEC, I_XXX, I_CLD, I_CMP, I_PHX, I_STP, I_XXX, I_CMP, I_DEC, I_XXX,
/*E0*/ I_CPX, I_SBC, I_XXX, I_XXX, I_CPX, I_SBC, I_INC, I_XXX, I_INX, I_SBC, I_NOP, I_XXX, I_CPX, I_SBC, I_INC, I_XXX,
/*F0*/ I_BEQ, I_SBC, I_SBC, I_XXX, I_XXX, I_SBC, I_INC, I_XXX, I_SED, I_SBC, I_PLX, I_XXX, I_XXX, I_SBC, I_INC, I_XXX
};
unsigned char dopaddr[256] =
{
/*00*/ IMP, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
/*10*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMPA, IMP, ABS, ABSX, ABSX, IMP,
/*20*/ ABS, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
/*30*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPX, IMP, IMP, ABSY, IMPA, IMP, ABSX, ABSX, ABSX, IMP,
/*40*/ IMP, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
/*50*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP,
/*60*/ IMP, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, IND16, ABS, ABS, IMP,
/*70*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, IND1X, ABSX, ABSX, IMP,
/*80*/ BRA, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
/*90*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPY, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP,
/*A0*/ IMM, INDX, IMM, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
/*B0*/ BRA, INDY, IND, IMP, ZPX, ZPX, ZPY, IMP, IMP, ABSY, IMP, IMP, ABSX, ABSX, ABSY, IMP,
/*C0*/ IMM, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
/*D0*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP,
/*E0*/ IMM, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP,
/*F0*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP
};
unsigned int disassemble(unsigned int addr)
{
unsigned int temp;
unsigned int op = readByteInc();
int mode = dopaddr[op];
unsigned int p1 = (mode > MARK2) ? readByteInc() : 0;
unsigned int p2 = (mode > MARK3) ? readByteInc() : 0;
log0("%04X : %s ", addr, opStrings[dopname[op]]);
switch (mode)
{
case IMP:
log0(" ");
break;
case IMPA:
log0("A ");
break;
case BRA:
temp = addr + 2 + (signed char)p1;
log0("%04X ", temp);
addr++;
break;
case IMM:
log0("#%02X ", p1);
addr++;
break;
case ZP:
log0("%02X ", p1);
addr++;
break;
case ZPX:
log0("%02X,X ", p1);
addr++;
break;
case ZPY:
log0("%02X,Y ", p1);
addr++;
break;
case IND:
log0("(%02X) ", p1);
addr++;
break;
case INDX:
log0("(%02X,X) ", p1);
addr++;
break;
case INDY:
log0("(%02X),Y ", p1);
addr++;
break;
case ABS:
log0("%02X%02X ", p2, p1);
addr += 2;
break;
case ABSX:
log0("%02X%02X,X ", p2, p1);
addr += 2;
break;
case ABSY:
log0("%02X%02X,Y ", p2, p1);
addr += 2;
break;
case IND16:
log0("(%02X%02X) ", p2, p1);
addr += 2;
break;
case IND1X:
log0("(%02X%02X,X)", p2, p1);
addr += 2;
break;
}
log0("\n");
addr++;
return addr;
}

624
firmware/disz80.c Normal file
View File

@ -0,0 +1,624 @@
/* Z80 disassembler
*** Copyright: 1994-1996 Günter Woigk
mailto:kio@little-bat.de
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Permission to use, copy, modify, distribute, and sell this software and
its documentation for any purpose is hereby granted without fee, provided
that the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of the copyright holder not be used
in advertising or publicity pertaining to distribution of the software
without specific, written prior permission. The copyright holder makes no
representations about the suitability of this software for any purpose.
It is provided "as is" without express or implied warranty.
THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
30.Jan.95: Started work on disassembler stuff KIO !
02.Jun.95: Reworked completely KIO !
20.Oct.01 revised for CW7Pro and ANSI C compliance hdusel@bnv-gz.de
*/
#include <string.h>
#include "AtomBusMon.h"
#define legal 0
#define illegal 1
#define weird 2
#undef RR
#undef IM
#undef RH
#undef RL
#undef BC
#undef DE
#undef HL
#undef IX
#undef IY
#undef SP
#undef PC
#undef XH
#undef XL
#undef YH
#undef YL
#undef ADC
// ---- opcode definitions ------------------------------------------------------------------
enum {
NIX, NOP, LD, INC, DEC, RLCA, EX, ADD,
RRCA, DJNZ, RLA, JR, RRA, DAA, CPL, HALT,
SCF, CCF, RLC, RRC, RL, RR, SLA, SRA,
SLL, SRL, IN, OUT, SBC, NEG, RETN, IM,
ADC, RETI, RRD, RLD, SUB, AND, XOR,
OR, CP, BIT, RES, SET, LDI, CPI, INI,
OUTI, LDD, CPD, IND, OUTD, LDIR, CPIR, INIR,
OTIR, LDDR, CPDR, INDR, OTDR, RET, POP, JP,
CALL, PUSH, RST, PFX, EXX, DI, EI,
BC, DE, HL, IX, IY, SP, AF, AF2,
B, C, D, E, H, L, XHL, A, // <- KEEP THIS ORDER!
XBC, XDE, R, I, XC, XSP, PC, F,
N0, N1, N2, N3, N4, N5, N6, N7,
Z, NZ, NC, PO, PE, M, P,
N, NN, XNN, XN, DIS, CB, ED,
XH, XL, YH, YL, XIX, XIY
};
char* word[] =
{ "", "NOP", "LD", "INC", "DEC", "RLCA", "EX", "ADD",
"RRCA", "DJNZ", "RLA", "JR", "RRA", "DAA", "CPL", "HALT",
"SCF", "CCF", "RLC", "RRC", "RL", "RR", "SLA", "SRA",
"SLL", "SRL", "IN", "OUT", "SBC", "NEG", "RETN", "IM",
"ADC", "RETI", "RRD", "RLD", "SUB", "AND", "XOR",
"OR", "CP", "BIT", "RES", "SET", "LDI", "CPI", "INI",
"OUTI", "LDD", "CPD", "IND", "OUTD", "LDIR", "CPIR", "INIR",
"OTIR", "LDDR", "CPDR", "INDR", "OTDR", "RET", "POP", "JP",
"CALL", "PUSH", "RST", "PREFIX", "EXX", "DI", "EI",
"BC", "DE", "HL", "IX", "IY", "SP", "AF", "AF'",
"B", "C", "D", "E", "H", "L", "(HL)", "A",
"(BC)", "(DE)", "R", "I", "(C)", "(SP)", "PC", "F",
"0", "1", "2", "3", "4", "5", "6", "7",
"Z", "NZ", "NC", "PO", "PE", "M", "P",
"N", "NN", "XNN", "XN", "DIS", "CB", "ED",
"XH", "XL", "YH", "YL", "DIS(IX)","DIS(IY)"
};
unsigned char cmd_00[64][3] =
{
{NOP,0,0},
{LD,BC,NN},
{LD,XBC,A},
{INC,BC,0},
{INC,B,0},
{DEC,B,0},
{LD,B,N},
{RLCA,0,0},
{EX,AF,AF2},
{ADD,HL,BC},
{LD,A,XBC},
{DEC,BC,0},
{INC,C,0},
{DEC,C,0},
{LD,C,N},
{RRCA,0,0},
{DJNZ,DIS,0},
{LD,DE,NN},
{LD,XDE,A},
{INC,DE,0},
{INC,D,0},
{DEC,D,0},
{LD,D,N},
{RLA,0,0},
{JR,DIS,0},
{ADD,HL,DE},
{LD,A,XDE},
{DEC,DE,0},
{INC,E,0},
{DEC,E,0},
{LD,E,N},
{RRA,0,0},
{JR,NZ,DIS},
{LD,HL,NN},
{LD,XNN,HL},
{INC,HL,0},
{INC,H,0},
{DEC,H,0},
{LD,H,N},
{DAA,0,0},
{JR,Z,DIS},
{ADD,HL,HL},
{LD,HL,XNN},
{DEC,HL,0},
{INC,L,0},
{DEC,L,0},
{LD,L,N},
{CPL,0,0},
{JR,NC,DIS},
{LD,SP,NN},
{LD,XNN,A},
{INC,SP,0},
{INC,XHL,0},
{DEC,XHL,0},
{LD,XHL,N},
{SCF,0,0},
{JR,C,N},
{ADD,HL,SP},
{LD,A,XNN},
{DEC,SP,0},
{INC,A,0},
{DEC,A,0},
{LD,A,N},
{CCF,0,0}
};
unsigned char cmd_C0[64][3] =
{
{RET,NZ,0},
{POP,BC,0},
{JP,NZ,NN},
{JP,NN,0},
{CALL,NZ,NN},
{PUSH,BC,0},
{ADD,A,N},
{RST,N0,0},
{RET,Z,0},
{RET,0,0},
{JP,Z,NN},
{PFX,CB,0},
{CALL,Z,NN},
{CALL,NN,0},
{ADC,A,N},
{RST,N1,0},
{RET,NC,0},
{POP,DE,0},
{JP,NC,NN},
{OUT,XN,A},
{CALL,NC,NN},
{PUSH,DE,0},
{SUB,A,N},
{RST,N2,0},
{RET,C,0},
{EXX,0,0},
{JP,C,NN},
{IN,A,XN},
{CALL,C,NN},
{PFX,IX,0},
{SBC,A,N},
{RST,N3,0},
{RET,PO,0},
{POP,HL,0},
{JP,PO,NN},
{EX,HL,XSP},
{CALL,PO,NN},
{PUSH,HL,0},
{AND,A,N},
{RST,N4,0},
{RET,PE,0},
{LD,PC,HL},
{JP,PE,NN},
{EX,DE,HL},
{CALL,PE,NN},
{PFX,ED,0},
{XOR,A,N},
{RST,N5,0},
{RET,P,0},
{POP,AF,0},
{JP,P,NN},
{DI,0,0},
{CALL,P,NN},
{PUSH,AF,0},
{OR,A,N},
{RST,N6,0},
{RET,M,0},
{LD,SP,HL},
{JP,M,NN},
{EI,0,0},
{CALL,M,NN},
{PFX,IY,0},
{CP,A,N},
{RST,N7,0}
};
unsigned char cmd_ED40[64][3] =
{
{IN,B,XC},
{OUT,XC,B},
{SBC,HL,BC},
{LD,XNN,BC},
{NEG,0,0},
{RETN,0,0},
{IM,N0,0},
{LD,I,A},
{IN,C,XC},
{OUT,XC,C},
{ADC,HL,BC},
{LD,BC,XNN},
{NEG,0,0},
{RETI,0,0},
{IM,N0,0},
{LD,R,A},
{IN,D,XC},
{OUT,XC,D},
{SBC,HL,DE},
{LD,XNN,DE},
{NEG,0,0},
{RETN,0,0},
{IM,N1,0},
{LD,A,I},
{IN,E,XC},
{OUT,XC,E},
{ADC,HL,DE},
{LD,DE,XNN},
{NEG,0,0},
{RETI,0,0},
{IM,N2,0},
{LD,A,R},
{IN,H,XC},
{OUT,XC,H},
{SBC,HL,HL},
{LD,XNN,HL},
{NEG,0,0},
{RETN,0,0},
{IM,N0,0},
{RRD,0,0},
{IN,L,XC},
{OUT,XC,L},
{ADC,HL,HL},
{LD,HL,XNN},
{NEG,0,0},
{RETI,0,0},
{IM,N0,0},
{RLD,0,0},
{IN,F,XC},
{OUT,XC,N0},
{SBC,HL,SP},
{LD,XNN,SP},
{NEG,0,0},
{RETN,0,0},
{IM,N1,0},
{NOP,0,0},
{IN,A,XC},
{OUT,XC,A},
{ADC,HL,SP},
{LD,SP,XNN},
{NEG,0,0},
{RETI,0,0},
{IM,N2,0},
{NOP,0,0}
};
unsigned char cmd_halt[] = { HALT,0,0 };
unsigned char cmd_nop[] = { NOP,0,0 };
unsigned char c_ari[] = { ADD,ADC,SUB,SBC,AND,XOR,OR,CP };
unsigned char c_blk[] = { LDI,CPI,INI,OUTI,0,0,0,0,LDD,CPD,IND,OUTD,0,0,0,0,
LDIR,CPIR,INIR,OTIR,0,0,0,0,LDDR,CPDR,INDR,OTDR };
unsigned char c_sh[] = { RLC,RRC,RL,RR,SLA,SRA,SLL,SRL };
// ============================================================================================
unsigned char Peek(unsigned int addr) {
loadAddr(addr);
return readByte();
}
// ---- return mnenonic descriptor for normal instructions
// note: for immediate use only, returned result becomes invalid with next call!
unsigned char* mnemo(unsigned char op) {
static unsigned char cl[3]={LD,A,A};
static unsigned char ca[3]={ADD,A,A};
switch (op>>6)
{
case 0: return cmd_00[op];
case 1: if (op==0x76) return cmd_halt;
cl[1] = B + ((op>>3)&0x07);
cl[2] = B + (op&0x07);
return cl;
case 2: ca[0] = c_ari[(op>>3)&0x07];
ca[2] = B + (op&0x07);
return ca;
case 3: return cmd_C0[op&0x3f];
}
return NULL;
}
// ---- return mnenonic descriptor for CB instructions
// note: for immediate use only!
unsigned char* mnemoCB(unsigned char op) {
static unsigned char cmd[3];
switch (op>>6)
{
case 0: cmd[0] = c_sh[(op>>3)&0x07];
cmd[1] = B + (op&0x07);
cmd[2] = 0;
return cmd;
case 1: cmd[0] = BIT; break;
case 2: cmd[0] = RES; break;
case 3: cmd[0] = SET; break;
}
cmd[1] = N0 + ((op>>3)&0x07);
cmd[2] = B + (op&0x07);
return cmd;
}
// ---- return mnenonic descriptor for IXCB instructions
// note: for immediate use only!
unsigned char* mnemoIXCB(unsigned char op) {
unsigned char *c;
c = mnemoCB(op);
if (c[1]==XHL) c[1]=XIX; // this is only allowed, because mnemo() doesn't
if (c[2]==XHL) c[2]=XIX; // retrieve a pointer but creates mnemo descr ad hoc
return c;
}
// ---- return mnenonic descriptor for IYCB instructions
// note: for immediate use only!
unsigned char* mnemoIYCB(unsigned char op) {
unsigned char *c;
c = mnemoCB(op);
if (c[1]==XHL) c[1]=XIY; // this is only allowed, because mnemo() doesn't
if (c[2]==XHL) c[2]=XIY; // retrieve a pointer but creates mnemo descr ad hoc
return c;
}
// ---- return mnenonic descriptor for ED instructions
// note: for immediate use only!
unsigned char* mnemoED(unsigned char op) {
static unsigned char cmd[3]={0,0,0};
if (op<0x40) return cmd_nop;
if (op>=0x080)
{ if ((op&0xE4)!=0xA0) return cmd_nop;
cmd[0] = c_blk[op&0x1B];
return cmd;
};
return cmd_ED40[op-0x40];
}
// ---- return mnenonic descriptor for IX instructions
// note: for immediate use only!
unsigned char* mnemoIX (unsigned char op) {
static unsigned char cmd[3];
memcpy (cmd, mnemo(op), 3);
if (cmd[1]==XHL) { cmd[1]=XIX; return cmd; }
if (cmd[2]==XHL) { cmd[2]=XIX; return cmd; }
if (cmd[1]==HL) { cmd[1]=IX; return cmd; }
if (cmd[2]==HL) { cmd[2]=IX; return cmd; }
if (cmd[1]==H) cmd[1]=XH;
if (cmd[1]==L) cmd[1]=XL;
if (cmd[2]==H) cmd[2]=XH;
if (cmd[2]==L) cmd[2]=XL;
return cmd;
}
// ---- return mnenonic descriptor for IY instructions
// note: for immediate use only!
unsigned char* mnemoIY (unsigned char op) {
static unsigned char cmd[3];
memcpy (cmd, mnemo(op), 3);
if (cmd[1]==XHL) { cmd[1]=XIY; return cmd; }
if (cmd[2]==XHL) { cmd[2]=XIY; return cmd; }
if (cmd[1]==HL) { cmd[1]=IY; return cmd; }
if (cmd[2]==HL) { cmd[2]=IY; return cmd; }
if (cmd[1]==H) cmd[1]=YH;
if (cmd[1]==L) cmd[1]=YL;
if (cmd[2]==H) cmd[2]=YH;
if (cmd[2]==L) cmd[2]=YL;
return cmd;
}
// ---- get legal state of CB instruction --------------------------------------
// all instructions legal except: sll is illegal
int IllegalCB (unsigned char op) {
return op>=0x30 && op<0x38 ? illegal : legal;
}
// ---- get legal state of IXCB/IYCB instruction ----------------------------------
// all instructions which do not use IX are weird
// instructions using IX are legal except: sll is illegal
int IllegalXXCB (unsigned char op) {
if ((op&0x07)!=6) return weird;
return op>=0x30 && op<0x38 ? illegal : legal;
}
// ---- get legal state of ED instruction --------------------------------------
// 0x00-0x3F and 0x80-0xFF weird except block instructions
// 0x40-0x7F legal or weird
// in f,(c) is legal; out (c),0 is weird
int IllegalED (unsigned char op) {
char *il = "1111111111110101111100111111001111110001111100011011000011110000";
if ((op>>6)==1) return il[op-0x40]-'0' ? weird : legal;
return *mnemoED(op)==NOP ? weird : legal;
}
// ---- get legal state of IX/IY instruction --------------------------------------
// all illegal instructions, which use XH or XL are illegal
// all illegal instructions, which don't use XH or XL are weird
// prefixes are legal
int IllegalXX (unsigned char op) {
unsigned char *c;
c = mnemo(op);
if (*c==PFX || c[1]==XHL || c[2]==XHL) return legal;
if (c[1]==H||c[1]==L||c[2]==H||c[2]==L) return illegal;
return weird;
}
// ---- Calculate length of instruction 30.jun.95 KIO !
// op2 is only used if op1 is a prefix instruction
// IX/IY before IX/IY/ed have no effect and are reported as length 1
int OpcodeLength (unsigned char op1, unsigned char op2) {
static char* len0 = "1311112111111121231111212111112123311121213111212331112121311121"; // 0x00 - 0x3F
static char* len3 = "1133312111303321113231211132302111313121113130211131312111313021"; // 0xC0 - 0xFF; prefixes are 0
switch (op1>>6)
{
case 0: return len0[op1]-'0'; // 0x00 - 0x3F: various length
case 1: // 0x40 - 0x7F: ld r,r: all 1
case 2: return 1; // 0x80 - 0xBF: arithmetics/logics op a,r: all 1
}
switch (op1) // test for prefix
{
case 0xcb: return 2;
case 0xed: if (/* op2<0x40 || op2>=0x80 || ((op2&7)!=3) */ (op2&0xc7)!=0x43) return 2; else return 4;
case 0xdd:
case 0xfd:
switch (op2>>6)
{
case 0: return len0[op2]-'0'+1 + (op2>=0x34&&op2<=0x36); // inc(hl); dec(hl); ld(hl),N: add displacement
case 1:
case 2: if (((op2&0x07)==6) == ((op2&0x0F8)==0x70)) return 2; else return 3;
}
if (op2==0xcb) return 4;
return len3[op2&0x3F]-'0'+1; // note: entries for prefixes are 0 giving a total of 1, just to skip the useless prefix
}
return len3[op1&0x3F]-'0'; // 0xC0 - 0xFF: no prefix: various length
}
// ===================================================================================
void xword (unsigned char n, unsigned int *ip) {
unsigned int nn;
switch (n)
{
case DIS:
n = Peek((*ip)++);
log0("$%04X", *ip+(char)n,4); // branch destination
break;
case N:
n = Peek((*ip)++);
log0("$%02X", n);
break;
case NN:
n = Peek((*ip)++);
nn = n+256*Peek((*ip)++);
log0("$%04X", nn);
break;
case XNN:
n = Peek((*ip)++);
nn = n+256*Peek((*ip)++);
log0("($%04X)", nn);
break;
case XN:
n = Peek((*ip)++);
log0("($%02X)", n);
break;
case XIX:
n = Peek((*ip)++);
if (n&0x80) {
log0("(IX-$%02X)", 256-n);
} else {
log0("(IX+$%02X)", n);
}
break;
case XIY:
n = Peek((*ip)++);
if (n&0x80) {
log0("(IY-$%02X)", 256-n);
} else {
log0("(IY+$%02X)", n);
}
break;
default:
log0("%s", word[n]);
break;
}
}
// ---- expand 3-char descriptor m[3] to mnemonic with arguments via pc
void disass (unsigned char *m, unsigned int *ip) {
log0("%-5s", word[*m++]);
if (*m) {
xword(*m++,ip);
}
if (*m) {
log0(",");
xword(*m,ip);
}
}
void disassem (unsigned int *ip) {
unsigned char op;
op = Peek((*ip)++);
switch (op)
{
case 0xcb:
disass (mnemoCB(Peek((*ip)++)), ip);
break;
case 0xed:
disass (mnemoED(Peek((*ip)++)), ip);
break;
case 0xdd:
op = Peek((*ip)++);
if (op!=0xCB) {
disass (mnemoIX(op), ip);
} else {
disass (mnemoIXCB(Peek((*ip)+1)), ip);
(*ip)++;
}
break;
case 0xfd:
op = Peek((*ip)++);
if (op!=0xCB) {
disass (mnemoIY(op), ip);
} else {
disass (mnemoIYCB(Peek((*ip)+1)), ip);
(*ip)++;
}
break;
default:
disass (mnemo(op),ip);
break;
}
}
unsigned int disassemble(unsigned int addr) {
log0("%04X : ", addr);
disassem(&addr);
log0("\n");
return addr;
}

View File

@ -126,12 +126,14 @@ begin
tmosi => tmosi,
tdin => tdin,
tcclk => tcclk,
Regs => Regs,
Regs(63 downto 0) => Regs,
Regs(255 downto 64) => (others <= '0'),
RdOut => memory_rd,
WrOut => memory_wr,
AddrOut => memory_addr,
DataOut => memory_dout,
DataIn => memory_din,
Done => memory_rd,
SS_Step => open,
SS_Single => open
);

View File

@ -44,7 +44,7 @@ entity BusMonCore is
-- 6502 Registers
-- unused in pure bus monitor mode
Regs : in std_logic_vector(63 downto 0);
Regs : in std_logic_vector(255 downto 0);
-- 6502 Memory Read/Write
-- unused in pure bus monitor mode
@ -53,6 +53,7 @@ entity BusMonCore is
AddrOut : out std_logic_vector(15 downto 0);
DataOut : out std_logic_vector(7 downto 0);
DataIn : in std_logic_vector(7 downto 0);
Done : in std_logic;
-- Single Step interface
SS_Single : out std_logic;
@ -98,7 +99,7 @@ architecture behavioral of BusMonCore is
signal dy_data : y2d_type ;
signal mux : std_logic_vector(7 downto 0);
signal muxsel : std_logic_vector(4 downto 0);
signal muxsel : std_logic_vector(5 downto 0);
signal cmd_edge : std_logic;
signal cmd_edge1 : std_logic;
signal cmd_edge2 : std_logic;
@ -221,7 +222,7 @@ begin
portdout(2) => muxsel(2),
portdout(3) => muxsel(3),
portdout(4) => muxsel(4),
portdout(5) => open,
portdout(5) => muxsel(5),
portdout(6) => open,
portdout(7) => open,
@ -287,15 +288,42 @@ begin
fifo_dout(63 downto 56) when muxsel = 13 else
fifo_dout(71 downto 64) when muxsel = 14 else
Regs(7 downto 0) when muxsel = 16 else
Regs(15 downto 8) when muxsel = 17 else
Regs(23 downto 16) when muxsel = 18 else
Regs(31 downto 24) when muxsel = 19 else
Regs(39 downto 32) when muxsel = 20 else
Regs(47 downto 40) when muxsel = 21 else
Regs(55 downto 48) when muxsel = 22 else
Regs(63 downto 56) when muxsel = 23 else
"10101010";
Regs(8 * to_integer(unsigned(muxsel(4 downto 0))) + 7 downto 8 * to_integer(unsigned(muxsel(4 downto 0))));
-- Regs( 15 downto 8) when muxsel = 33 else
-- Regs( 23 downto 16) when muxsel = 34 else
-- Regs( 31 downto 24) when muxsel = 35 else
-- Regs( 39 downto 32) when muxsel = 36 else
-- Regs( 47 downto 40) when muxsel = 37 else
-- Regs( 55 downto 48) when muxsel = 38 else
-- Regs( 63 downto 56) when muxsel = 39 else
-- Regs( 7 downto 64) when muxsel = 40 else
-- Regs( 15 downto 72) when muxsel = 41 else
-- Regs( 23 downto 80) when muxsel = 42 else
-- Regs( 31 downto 88) when muxsel = 43 else
-- Regs( 39 downto 96) when muxsel = 44 else
-- Regs( 47 downto 104) when muxsel = 45 else
-- Regs( 55 downto 112) when muxsel = 46 else
-- Regs( 63 downto 120) when muxsel = 47 else
-- Regs( 7 downto 128) when muxsel = 48 else
-- Regs( 15 downto 136) when muxsel = 49 else
-- Regs( 23 downto 144) when muxsel = 50 else
-- Regs( 31 downto 24) when muxsel = 51 else
-- Regs( 39 downto 32) when muxsel = 52 else
-- Regs( 47 downto 40) when muxsel = 53 else
-- Regs( 55 downto 48) when muxsel = 54 else
-- Regs( 63 downto 56) when muxsel = 55 else
-- Regs( 7 downto 0) when muxsel = 56 else
-- Regs( 15 downto 8) when muxsel = 57 else
-- Regs( 23 downto 16) when muxsel = 58 else
-- Regs( 31 downto 24) when muxsel = 59 else
-- Regs( 39 downto 32) when muxsel = 60 else
-- Regs( 47 downto 40) when muxsel = 61 else
-- Regs( 55 downto 48) when muxsel = 62 else
-- Regs( 63 downto 56) when muxsel = 63 else
--
--
-- "10101010";
-- Combinatorial set of comparators to decode breakpoint/watch addresses
brkpt_active_process: process (brkpt_reg, brkpt_enable, Addr, Sync)
@ -402,7 +430,6 @@ begin
fifo_rst <= '0';
memory_rd <= '0';
memory_wr <= '0';
auto_inc <= '0';
SS_Step <= '0';
if (cmd_edge2 = '0' and cmd_edge1 = '1') then
if (cmd(4 downto 1) = "0000") then
@ -446,7 +473,7 @@ begin
end if;
-- Auto increment the memory address reg the cycle after a rd/wr
if (auto_inc = '1' and (memory_rd = '1' or memory_wr = '1')) then
if (auto_inc = '1' and Done = '1') then
addr_dout_reg(23 downto 8) <= addr_dout_reg(23 downto 8) + 1;
end if;
@ -492,7 +519,7 @@ begin
-- Latch the data bus for use in watches
Data1 <= Data;
-- Latch memory read in response to a read command
if (memory_rd = '1') then
if (Done = '1') then
din_reg <= DataIn;
end if;
end if;

View File

@ -122,8 +122,7 @@ entity T80 is
IntCycle_n : out std_logic;
IntE : out std_logic;
Stop : out std_logic;
Regs : out std_logic_vector(63 downto 0)
Regs : out std_logic_vector(255 downto 0)
);
end T80;
@ -251,10 +250,13 @@ architecture rtl of T80 is
begin
Regs(31 downto 0) <= Ap & Fp & ACC & F;
-- Regs(31 downto 0) <= RegFileData(31 downto 0);
Regs(47 downto 32) <= std_logic_vector(SP);
Regs(63 downto 48) <= std_logic_vector(PC);
Regs(127 downto 0) <= RegFileData;
Regs(159 downto 128) <= Ap & Fp & ACC & F;
Regs(175 downto 160) <= std_logic_vector(SP);
Regs(191 downto 176) <= std_logic_vector(PC);
Regs(199 downto 192) <= I;
Regs(207 downto 200) <= std_logic_vector(R);
Regs(215 downto 208) <= "000000" & IntE_FF2 & IntE_FF1;
mcode : T80_MCode

View File

@ -105,7 +105,7 @@ package T80_Pack is
IntCycle_n : out std_logic;
IntE : out std_logic;
Stop : out std_logic;
Regs : out std_logic_vector(63 downto 0)
Regs : out std_logic_vector(255 downto 0)
);
end component;

View File

@ -92,21 +92,20 @@ architecture rtl of T80_Reg is
begin
RegFileData( 7 downto 0) <= RegsL(0);
RegFileData( 15 downto 8) <= RegsL(1);
RegFileData( 23 downto 16) <= RegsL(2);
RegFileData( 31 downto 24) <= RegsL(3);
RegFileData( 39 downto 32) <= RegsL(4);
RegFileData( 47 downto 40) <= RegsL(5);
RegFileData( 55 downto 48) <= RegsL(6);
RegFileData( 63 downto 56) <= RegsL(7);
RegFileData( 71 downto 64) <= RegsH(0);
RegFileData( 79 downto 72) <= RegsH(1);
RegFileData( 87 downto 80) <= RegsH(2);
RegFileData( 95 downto 88) <= RegsH(3);
RegFileData(103 downto 96) <= RegsH(4);
RegFileData(111 downto 104) <= RegsH(5);
RegFileData(119 downto 112) <= RegsH(6);
RegFileData( 15 downto 8) <= RegsH(0);
RegFileData( 23 downto 16) <= RegsL(1);
RegFileData( 31 downto 24) <= RegsH(1);
RegFileData( 39 downto 32) <= RegsL(2);
RegFileData( 47 downto 40) <= RegsH(2);
RegFileData( 55 downto 48) <= RegsL(3);
RegFileData( 63 downto 56) <= RegsH(3);
RegFileData( 71 downto 64) <= RegsL(4);
RegFileData( 79 downto 72) <= RegsH(4);
RegFileData( 87 downto 80) <= RegsL(5);
RegFileData( 95 downto 88) <= RegsH(5);
RegFileData(103 downto 96) <= RegsL(6);
RegFileData(111 downto 104) <= RegsH(6);
RegFileData(119 downto 112) <= RegsL(7);
RegFileData(127 downto 120) <= RegsH(7);
process (Clk)

View File

@ -1,282 +1,286 @@
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- Z80 compatible microprocessor core, asynchronous top level
--
-- Version : 0247
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0208 : First complete release
--
-- 0211 : Fixed interrupt cycle
--
-- 0235 : Updated for T80 interface change
--
-- 0238 : Updated for T80 interface change
--
-- 0240 : Updated for T80 interface change
--
-- 0242 : Updated for T80 interface change
--
-- 0247 : Fixed bus req/ack cycle
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
entity T80a is
generic(
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
);
port(
-- Additions
TS : out std_logic_vector(2 downto 0);
Regs : out std_logic_vector(63 downto 0);
-- Original Signals
RESET_n : in std_logic;
CLK_n : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
MREQ_n : out std_logic;
IORQ_n : out std_logic;
RD_n : out std_logic;
WR_n : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
D : inout std_logic_vector(7 downto 0)
);
end T80a;
architecture rtl of T80a is
signal CEN : std_logic;
signal Reset_s : std_logic;
signal IntCycle_n : std_logic;
signal IORQ : std_logic;
signal NoRead : std_logic;
signal Write : std_logic;
signal MREQ : std_logic;
signal MReq_Inhibit : std_logic;
signal Req_Inhibit : std_logic;
signal RD : std_logic;
signal MREQ_n_i : std_logic;
signal IORQ_n_i : std_logic;
signal RD_n_i : std_logic;
signal WR_n_i : std_logic;
signal RFSH_n_i : std_logic;
signal BUSAK_n_i : std_logic;
signal A_i : std_logic_vector(15 downto 0);
signal DO : std_logic_vector(7 downto 0);
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
signal Wait_s : std_logic;
signal MCycle : std_logic_vector(2 downto 0);
signal TState : std_logic_vector(2 downto 0);
begin
CEN <= '1';
BUSAK_n <= BUSAK_n_i;
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
RD_n_i <= not RD or Req_Inhibit;
MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z';
IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z';
RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z';
RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z';
A <= A_i when BUSAK_n_i = '1' else (others => 'Z');
D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z');
process (RESET_n, CLK_n)
begin
if RESET_n = '0' then
Reset_s <= '0';
elsif CLK_n'event and CLK_n = '1' then
Reset_s <= '1';
end if;
end process;
u0 : T80
generic map(
Mode => Mode,
IOWait => 1)
port map(
CEN => CEN,
M1_n => M1_n,
IORQ => IORQ,
NoRead => NoRead,
Write => Write,
RFSH_n => RFSH_n_i,
HALT_n => HALT_n,
WAIT_n => Wait_s,
INT_n => INT_n,
NMI_n => NMI_n,
RESET_n => Reset_s,
BUSRQ_n => BUSRQ_n,
BUSAK_n => BUSAK_n_i,
CLK_n => CLK_n,
A => A_i,
DInst => D,
DI => DI_Reg,
DO => DO,
MC => MCycle,
TS => TState,
IntCycle_n => IntCycle_n,
Regs => Regs
);
process (CLK_n)
begin
if CLK_n'event and CLK_n = '0' then
Wait_s <= WAIT_n;
if TState = "011" and BUSAK_n_i = '1' then
DI_Reg <= to_x01(D);
end if;
end if;
end process;
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
WR_n_i <= '1';
elsif CLK_n'event and CLK_n = '1' then
WR_n_i <= '1';
if TState = "001" or (TState = "010" and Wait_s = '0') then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
WR_n_i <= not Write;
end if;
end if;
end process;
-- ****
-- T80(b) core. In an effort to merge and maintain bug fixes ....
--
--
-- Ver 300 started tidyup
-- MikeJ March 2005
-- Latest version from www.fpgaarcade.com (original www.opencores.org)
--
-- ****
--
-- Z80 compatible microprocessor core, asynchronous top level
--
-- Version : 0247
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
-- All rights reserved
--
-- Redistribution and use in source and synthezised forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- Redistributions in synthesized form must reproduce the above copyright
-- notice, this list of conditions and the following disclaimer in the
-- documentation and/or other materials provided with the distribution.
--
-- Neither the name of the author nor the names of other contributors may
-- be used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-- POSSIBILITY OF SUCH DAMAGE.
--
-- Please report bugs to the author, but before you do so, please
-- make sure that this is not a derivative work and that
-- you have the latest version of this file.
--
-- The latest version of this file can be found at:
-- http://www.opencores.org/cvsweb.shtml/t80/
--
-- Limitations :
--
-- File history :
--
-- 0208 : First complete release
--
-- 0211 : Fixed interrupt cycle
--
-- 0235 : Updated for T80 interface change
--
-- 0238 : Updated for T80 interface change
--
-- 0240 : Updated for T80 interface change
--
-- 0242 : Updated for T80 interface change
--
-- 0247 : Fixed bus req/ack cycle
--
-- process (Reset_s,CLK_n)
-- begin
-- if Reset_s = '0' then
-- WR_n_i <= '1';
-- elsif CLK_n'event and CLK_n = '0' then
-- WR_n_i <= '1';
-- if TState = "010" then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
-- WR_n_i <= not Write;
-- end if;
-- end if;
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
entity T80a is
generic(
Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
);
port(
-- Additions
TS : out std_logic_vector(2 downto 0);
Regs : out std_logic_vector(255 downto 0);
-- Original Signals
RESET_n : in std_logic;
CLK_n : in std_logic;
WAIT_n : in std_logic;
INT_n : in std_logic;
NMI_n : in std_logic;
BUSRQ_n : in std_logic;
M1_n : out std_logic;
MREQ_n : out std_logic;
IORQ_n : out std_logic;
RD_n : out std_logic;
WR_n : out std_logic;
RFSH_n : out std_logic;
HALT_n : out std_logic;
BUSAK_n : out std_logic;
A : out std_logic_vector(15 downto 0);
Din : in std_logic_vector(7 downto 0);
Dout : out std_logic_vector(7 downto 0);
Den : out std_logic
);
end T80a;
architecture rtl of T80a is
signal CEN : std_logic;
signal Reset_s : std_logic;
signal IntCycle_n : std_logic;
signal IORQ : std_logic;
signal NoRead : std_logic;
signal Write : std_logic;
signal MREQ : std_logic;
signal MReq_Inhibit : std_logic;
signal Req_Inhibit : std_logic;
signal RD : std_logic;
signal MREQ_n_i : std_logic;
signal IORQ_n_i : std_logic;
signal RD_n_i : std_logic;
signal WR_n_i : std_logic;
signal RFSH_n_i : std_logic;
signal BUSAK_n_i : std_logic;
signal A_i : std_logic_vector(15 downto 0);
signal DO : std_logic_vector(7 downto 0);
signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser
signal Wait_s : std_logic;
signal MCycle : std_logic_vector(2 downto 0);
signal TState : std_logic_vector(2 downto 0);
begin
CEN <= '1';
BUSAK_n <= BUSAK_n_i;
MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit);
RD_n_i <= not RD or Req_Inhibit;
MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z';
IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z';
RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z';
RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z';
A <= A_i when BUSAK_n_i = '1' else (others => 'Z');
Dout <= DO;
Den <= Write and BUSAK_n_i;
process (RESET_n, CLK_n)
begin
if RESET_n = '0' then
Reset_s <= '0';
elsif CLK_n'event and CLK_n = '1' then
Reset_s <= '1';
end if;
end process;
u0 : T80
generic map(
Mode => Mode,
IOWait => 1)
port map(
CEN => CEN,
M1_n => M1_n,
IORQ => IORQ,
NoRead => NoRead,
Write => Write,
RFSH_n => RFSH_n_i,
HALT_n => HALT_n,
WAIT_n => Wait_s,
INT_n => INT_n,
NMI_n => NMI_n,
RESET_n => Reset_s,
BUSRQ_n => BUSRQ_n,
BUSAK_n => BUSAK_n_i,
CLK_n => CLK_n,
A => A_i,
DInst => Din,
DI => DI_Reg,
DO => DO,
MC => MCycle,
TS => TState,
IntCycle_n => IntCycle_n,
Regs => Regs
);
process (CLK_n)
begin
if CLK_n'event and CLK_n = '0' then
Wait_s <= WAIT_n;
if TState = "011" and BUSAK_n_i = '1' then
DI_Reg <= to_x01(Din);
end if;
end if;
end process;
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
WR_n_i <= '1';
elsif CLK_n'event and CLK_n = '1' then
WR_n_i <= '1';
if TState = "001" or (TState = "010" and Wait_s = '0') then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
WR_n_i <= not Write;
end if;
end if;
end process;
-- process (Reset_s,CLK_n)
-- begin
-- if Reset_s = '0' then
-- WR_n_i <= '1';
-- elsif CLK_n'event and CLK_n = '0' then
-- WR_n_i <= '1';
-- if TState = "010" then -- To short for IO writes !!!!!!!!!!!!!!!!!!!
-- WR_n_i <= not Write;
-- end if;
-- end if;
-- end process;
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
Req_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '1' then
if MCycle = "001" and TState = "010" and Wait_s = '1' then
Req_Inhibit <= '1';
else
Req_Inhibit <= '0';
end if;
end if;
end process;
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
MReq_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '0' then
if MCycle = "001" and TState = "010" then
MReq_Inhibit <= '1';
else
MReq_Inhibit <= '0';
end if;
end if;
end process;
process(Reset_s,CLK_n)
begin
if Reset_s = '0' then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
elsif CLK_n'event and CLK_n = '0' then
if MCycle = "001" then
if TState = "001" then
RD <= IntCycle_n;
MREQ <= IntCycle_n;
IORQ_n_i <= IntCycle_n;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '1';
end if;
if TState = "100" then
MREQ <= '0';
end if;
else
if TState = "001" and NoRead = '0' then
RD <= not Write;
IORQ_n_i <= not IORQ;
MREQ <= not IORQ;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
end if;
end if;
end if;
end process;
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
Req_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '1' then
if MCycle = "001" and TState = "010" and Wait_s = '1' then
Req_Inhibit <= '1';
else
Req_Inhibit <= '0';
end if;
end if;
end process;
process (Reset_s,CLK_n)
begin
if Reset_s = '0' then
MReq_Inhibit <= '0';
elsif CLK_n'event and CLK_n = '0' then
if MCycle = "001" and TState = "010" then
MReq_Inhibit <= '1';
else
MReq_Inhibit <= '0';
end if;
end if;
end process;
process(Reset_s,CLK_n)
begin
if Reset_s = '0' then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
elsif CLK_n'event and CLK_n = '0' then
if MCycle = "001" then
if TState = "001" then
RD <= IntCycle_n;
MREQ <= IntCycle_n;
IORQ_n_i <= IntCycle_n;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '1';
end if;
if TState = "100" then
MREQ <= '0';
end if;
else
if TState = "001" and NoRead = '0' then
RD <= not Write;
IORQ_n_i <= not IORQ;
MREQ <= not IORQ;
end if;
if TState = "011" then
RD <= '0';
IORQ_n_i <= '1';
MREQ <= '0';
end if;
end if;
end if;
end process;
TS <= TState;
end;
end;

View File

@ -78,6 +78,10 @@ end Z80CpuMon;
architecture behavioral of Z80CpuMon is
type state_type is (idle, rd_init, rd_setup, rd, rd_hold, wr_init, wr_setup, wr, wr_hold, release);
signal state : state_type;
signal RESET_n_int : std_logic;
signal cpu_clk : std_logic;
signal busmon_clk : std_logic;
@ -94,8 +98,13 @@ signal SS_Single : std_logic;
signal SS_Step : std_logic;
signal SS_Step_held : std_logic;
signal Regs : std_logic_vector(63 downto 0);
signal Write : std_logic;
signal Regs : std_logic_vector(255 downto 0);
signal memory_rd : std_logic;
signal memory_wr : std_logic;
signal memory_addr : std_logic_vector(15 downto 0);
signal memory_dout : std_logic_vector(7 downto 0);
signal memory_din : std_logic_vector(7 downto 0);
signal memory_done : std_logic;
signal INT_n_sync : std_logic;
signal NMI_n_sync : std_logic;
@ -110,15 +119,20 @@ signal Sync : std_logic;
signal Sync0 : std_logic;
signal nRST : std_logic;
signal ex_data : std_logic_vector(7 downto 0);
signal rd_data : std_logic_vector(7 downto 0);
signal mon_data : std_logic_vector(7 downto 0);
signal MemState : std_logic_vector(2 downto 0);
signal Din : std_logic_vector(7 downto 0);
signal Dout : std_logic_vector(7 downto 0);
signal Den : std_logic;
signal ex_data : std_logic_vector(7 downto 0);
signal rd_data : std_logic_vector(7 downto 0);
signal mon_data : std_logic_vector(7 downto 0);
begin
mon : entity work.BusMonCore
generic map (
num_comparators => 8
num_comparators => 4
)
port map (
clock49 => clock49,
@ -129,10 +143,8 @@ begin
Wr_n => Write_n,
Sync => Sync,
Rdy => Rdy,
SS_Single => SS_Single,
SS_Step => SS_Step,
nRSTin => RESET_n_int,
nRSTout => nRST,
nRSTin => RESET_n_int,
nRSTout => nRST,
trig => trig,
lcd_rs => open,
lcd_rw => open,
@ -148,12 +160,15 @@ begin
tmosi => tmosi,
tdin => tdin,
tcclk => tcclk,
Regs => Regs(63 downto 0),
RdOut => open,
WrOut => open,
AddrOut => open,
DataOut => open,
DataIn => (others => '0')
Regs => Regs,
RdOut => memory_rd,
WrOut => memory_wr,
AddrOut => memory_addr,
DataOut => memory_dout,
DataIn => memory_din,
Done => memory_done,
SS_Single => SS_Single,
SS_Step => SS_Step
);
GenT80Core: if UseT80Core generate
@ -175,14 +190,15 @@ begin
HALT_n => HALT_n,
BUSAK_n => BUSAK_n,
A => Addr_int,
D => Data
Din => Din,
Dout => Dout,
DEn => Den
);
end generate;
WAIT_n_int <= WAIT_n when SS_Single = '0'
else WAIT_n and SS_Step_held;
WAIT_n_int <= WAIT_n when SS_Single = '0' else
WAIT_n and SS_Step_held;
sync_gen : process(CLK_n, RESET_n_int)
begin
if RESET_n_int = '0' then
@ -218,9 +234,9 @@ begin
watch_gen : process(CLK_n)
begin
if falling_edge(CLK_n) then
Sync <= Sync0;
Sync <= Sync0;
Read_n1 <= Read_n0;
Read_n <= Read_n1;
Read_n <= Read_n1;
Write_n <= Write_n0;
end if;
end process;
@ -242,18 +258,79 @@ begin
if (Read_n1 = '0') then
rd_data <= Data;
end if;
memory_din <= Data;
end if;
end process;
-- Mux the data seen by the bus monitor appropriately
mon_data <= rd_data when Read_n <= '0' else ex_data;
Addr <= Addr_int;
WR_n <= WR_n_int;
RD_n <= RD_n_int;
MREQ_n <= MREQ_n_int;
IORQ_n <= IORQ_n_int;
M1_n <= M1_n_int;
-- Memory access
Addr <= memory_addr when (state /= idle) else Addr_int;
MREQ_n <= '1' when (state = rd_init or state = wr_init or state = release) else
'0' when (state /= idle) else MREQ_n_int;
IORQ_n <= '1' when (state /= idle) else IORQ_n_int;
WR_n <= '0' when (state = wr) else
'1' when (state /= idle) else WR_n_int;
RD_n <= '0' when (state = rd_setup or state = rd or state = rd_hold) else
'1' when (state /= idle) else RD_n_int;
M1_n <= '1' when (state /= idle) else M1_n_int;
memory_done <= '1' when (state = rd_hold or state = wr_hold) else '0';
-- TODO: Also need to take account of BUSRQ_n/BUSAK_n
Data <= memory_dout when state = wr_setup or state = wr or state = wr_hold else
Dout when state = idle and Den = '1' else
(others => 'Z');
Din <= Data;
-- TODO: Add refresh generation into idle loop
men_access_machine : process(CLK_n)
begin
if (RESET_n = '0') then
state <= idle;
elsif falling_edge(CLK_n) then
case state IS
when idle =>
if (memory_wr = '1') then
state <= wr_init;
elsif (memory_rd = '1') then
state <= rd_init;
end if;
when rd_init =>
state <= rd_setup;
when rd_setup =>
if (WAIT_n = '1') then
state <= rd;
end if;
when rd =>
state <= rd_hold;
when rd_hold =>
state <= idle;
when wr_init =>
state <= wr_setup;
when wr_setup =>
if (WAIT_n = '1') then
state <= wr;
end if;
when wr =>
state <= wr_hold;
when wr_hold =>
state <= release;
when release =>
state <= idle;
end case;
end if;
end process;
RESET_n_int <= RESET_n and (not sw1) and nRST;
test1 <= TState(0);