50 Commits

Author SHA1 Message Date
b9577f5b01 Updated XPM_T65 to 0.998
Change-Id: I3152215ec4d3d2148c23a4ecb1a6eefcd79329af
2022-02-12 15:07:00 +00:00
786132998a Update firmware version to 0.998
Change-Id: Ice975615820bbfae47037799865807e71144e6ab
2021-11-25 20:17:44 +00:00
220f96bff8 6502: Treak BRK as a 2-byte opcode
Change-Id: I10251803b3d57652ffdb9684cafb3ebf38903064
2021-11-25 20:15:49 +00:00
b96fa11de5 Update firmware version to 0.997
Change-Id: I97065b1c75499b27782de1e472d75a202bd60678
2021-11-18 15:12:32 +00:00
08116e5f21 Routed four test signals to J5
Change-Id: Ife39830dc193486c4af66bd49bc5680cab285108
2021-11-18 15:12:12 +00:00
3e7bda697c Replace special command with x interrupt control commands
Change-Id: I991171d6923cdc928dd9dbb9823c43aee71661be
2021-11-18 14:45:05 +00:00
1244eaf607 .gitignore only
Change-Id: Ifb58b10773ee6a520c6c75fabc1445252761dfbf
2021-11-18 12:59:19 +00:00
bf4bef3892 Merge branch 'z80_newcore' into dev
Change-Id: I1bb098ffba4593f048fda4a5aa97fdcc89fc6184
2021-11-18 12:58:29 +00:00
1b0c0624ff Updated release script to include .bin files
Change-Id: Ic09c51f721a3c517a43282b053dbdf9a55fba902
2021-09-21 13:20:32 +01:00
58978d3e05 Update build scripts to generate .bin files for programming using OpenOCD on a Pi
Change-Id: I39909acc3a1fe4504d5e4c2d20d11b23e3878058
2021-09-21 10:57:25 +01:00
ca285abfaf Update firmware version to 0.996
Change-Id: Ibe3fb93ec5f4320c64511649ca25d847ed25fc3a
2021-07-04 19:31:53 +01:00
78423708c5 Z80: Ignore machine state in disasseble command
Change-Id: I28b67a53ec8936bb9172aa10ca6548fe0d9e6460
2021-07-04 19:31:13 +01:00
0d837de8a6 Z80: fix display of int/nmi/halted state
Change-Id: I3e790598d6d2f1520e1ba4df3b79beaf3c8736f2
2021-07-04 19:20:25 +01:00
4b3ed52454 Z80: Ignore wait during internal machine cycles
Change-Id: I2fdeebe9706a868e9757089f1aed544e702146d8
2021-07-04 19:03:52 +01:00
246cb88e72 Update firmware version to 0.994
Change-Id: I9ef936cb741d78fd57cd51a06ea7882a24185429
2021-06-30 19:45:39 +01:00
785f15c038 Update firmware version to 0.995
Change-Id: I4f340d876b603fdc27db4b9c9c75280f122705ed
2021-06-30 19:45:39 +01:00
db014b0e56 Eliminate a divide from hwCmd
Change-Id: I85284e3709679d66a11e7f1c00cbd8db4a25da51
2021-06-30 19:45:39 +01:00
4ecd60065e Z80: Revert T80a wrapper to previous version
Change-Id: I856a39c51305e99c3d8b32efe5be1f8ed8b2583f
2021-06-30 19:45:39 +01:00
e65951cfbb Z80: Daves's fixes to T80 for ICE-Z80
Change-Id: Id1530b7c3f433ff2ff2b6f7966e3c93657058761
2021-06-30 19:45:39 +01:00
670328574b Z80: T80: whitespace
Change-Id: If8617f1a93dd9bb0fc1ff94b2d72924f6db34483
2021-06-30 19:45:39 +01:00
8e83d6e21f Z80: Update T80 core to latest from Mister on 30/6/2021
Change-Id: I6c007617ab03796dcd864c0f84d5663e0f4bece9
2021-06-30 19:45:39 +01:00
2773dd97b1 Update firmware version to 0.993
Change-Id: I5e261ecca2bf7c15a6fc4b05f5b90e5b5625a295
2021-04-10 16:15:39 +01:00
944f951b18 Added timeout command to change the memory timeout
Change-Id: I1e5401356200f20be814ad58f9e7ae7b34fc0a68
2021-04-10 16:15:20 +01:00
8f0536c2e9 Update firmware version to 0.992
Change-Id: If0a587272bd6576fc92f23178b33992ba36978bf
2021-03-21 17:44:04 +00:00
dc2db74cc3 Z80: Sample IM2 vector at start of T3, not middle
Change-Id: I902d5993e35da092b8b702fc21b3fbcbef4cc8c3
2021-03-21 17:43:51 +00:00
6abb27cfbe Update firmware version to 0.991
Change-Id: Id10c3abf34a83666be72d2432bfb1ac4b812b5ca
2021-03-20 17:23:30 +00:00
a7cb67c469 Z80: Rd/Wr Mem/IO breakpoint/watchpoint sampled in middle of T3
Change-Id: I9dcca58f121da9e443bd18da8f13a099cfbc2056
2021-03-20 17:22:53 +00:00
0e6a31360f Z80: IO Breakpoint/watchpoint mask defaults to 0xFF
Change-Id: Ifbe37871ad9cee29fedc81f967149dc058ab3648
2021-03-20 17:21:03 +00:00
97a1e9ad74 Add std=c99 to Makefile.inc
Change-Id: I0b0f74c25117ecf18fd479d55fdf818e205d6be8
2021-03-20 17:20:23 +00:00
d218caa40b Updated XPM_T65 to 0.990
Change-Id: Iab134b0375322c226c4d8f3f6f9a4360e933891f
2021-03-13 14:33:45 +00:00
530f9118f8 Update firmware version to 0.990
Change-Id: Idc210b311081fa1dffaf0023e6efb0dd2cdc211f
2021-03-13 14:21:13 +00:00
6b67360bf3 R65C02: correct cycle counts of JMP (ind) and JMP (ind,x) to 6
Change-Id: I3f7659b0db8d9c6a62577cb5b17052267a0b4154
2021-03-13 14:19:45 +00:00
c184b6466a R65C02: fix warnings
Change-Id: I0578e4afcdc0817046bafe2b78fecbfe82102f05
2021-03-13 12:30:59 +00:00
839d510af9 R65C02: Whitespace only
Change-Id: I19aa6962d48206dc0eb75cabfa9f230e8872822d
2021-03-13 11:23:31 +00:00
709c73999b Updated XPM_T65 to 0.989
Change-Id: I99176656af754985e986c8b2a8bff2a509839c4a
2021-03-11 20:00:41 +00:00
ed4d0662ba Update firmware version to 0.989
Change-Id: I2f05fbf43e9b1094f082c70aafd8f4acf30511cb
2021-03-11 19:21:42 +00:00
340f7e33f9 65C02: Implement single cycle NOPs
Change-Id: I9e37b42dcce4ee57359e5d3298f38f2eb70663af
2021-03-11 19:02:10 +00:00
0aa58bb25c Whitespace only
Change-Id: Ie59536f97544885673000f2a383efd1a1338792b
2021-03-11 19:01:46 +00:00
b23bb1d9ce Update firmware version to 0.988
Change-Id: I58b3200646d0272d9f76f70ff2e9d888d6c327a9
2020-06-22 20:40:02 +01:00
b708ec59a8 lx9_dave: update WatchEvents from 512x72 to 4096x72
Change-Id: I6b1fac95150592244cd5662c502ff34fbb885d10
2020-06-22 20:39:08 +01:00
a2e2f7c1d1 Updated XPM_T65 to 0.987
Change-Id: I4689fa344f47b976b10e249ac0b7f908e2ff291c
2020-06-21 15:22:51 +01:00
68b34da5ba Update firmware version to 0.987
Change-Id: I755c8cfac46978f3a2c7f061ba332f36874d0072
2020-06-21 15:08:18 +01:00
ca40fe81b3 Extend TimerMode command with prescale and reset address
Change-Id: Ia958ea97175469b642b4a70579f080dd0ff148cc
2020-06-21 15:07:45 +01:00
c0275ff059 Make commands 6-bits, add Special and TimerMode commands
Change-Id: I8862fba0cf4c1e54ee831a547bf3337bbe7cf973
2020-06-21 14:12:33 +01:00
ddc2ff358c Updated XPM_T65 to 0.986
Change-Id: I8d18dae89123a84ddbbbf7fe34a5fafbddfc0142
2020-06-20 13:14:49 +01:00
41afa8edeb Update firmware version to 0.986
Change-Id: I475d10f1481279acbdc55a69bb33ebb39a69d25b
2020-06-17 17:18:11 +01:00
e931e93dff 6502: fix duplicate break/watchpoints when Rdy in use
Change-Id: Idc566462c4496290d4d0a8e14fe568c05907a508
2020-06-17 17:14:00 +01:00
d38ae01d6f Update firmware version to 0.985
Change-Id: Id50f4f2b2e23cd8ab5e23862cf51e2428c56c40c
2020-06-09 19:10:28 +01:00
b07b86195c Firmware: add optional address to next command
Change-Id: I5378e5bb8ec767f6504823d190b774c8f523c879
2020-06-09 19:10:28 +01:00
2de5c382a7 6809: fix a bug with write watchpoints seeing data as 0xFF
Change-Id: Id5ca15ad95a5f5bbee242368ca8bb9b2c0cf7364
2020-06-09 18:55:06 +01:00
48 changed files with 5214 additions and 4535 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ nohup.out
target/**/*.o
target/**/*.bit
target/**/*.mcs
target/**/*.bin
target/**/avr_progmem.*
target/*/ipcore/WatchEvents.asy
target/*/ipcore/WatchEvents.gise

View File

@ -14,16 +14,35 @@
* VERSION and NAME are used in the start-up message
********************************************************/
#define VERSION "0.984"
#define VERSION "0.998"
// The X commands allows the various interrupt inputs to be overridded
// They are named after the data sheet pin name
#if defined(CPU_Z80)
#define NAME "ICE-Z80"
#define XCMD0 "xbusrq"
#define XCMD1 "xint"
#define XCMD2 "xnmi"
#define XCMD3 "xres"
#elif defined(CPU_6502)
#define NAME "ICE-6502"
#define XCMD0 "xirq"
#define XCMD1 "xnmi"
#define XCMD2 "xres"
#define XCMD3 "xso "
#elif defined(CPU_65C02)
#define NAME "ICE-65C02"
#define XCMD0 "xirq"
#define XCMD1 "xnmi"
#define XCMD2 "xres"
#define XCMD3 "xso "
#elif defined(CPU_6809)
#define NAME "ICE-6809"
#define XCMD0 "xfiq"
#define XCMD1 "xirq"
#define XCMD2 "xnmi"
#define XCMD3 "xres"
#else
#error "Unsupported CPU type"
#endif
@ -70,7 +89,6 @@ char *cmdStrings[] = {
"load",
"save",
"srec",
"special",
"reset",
"trace",
"blist",
@ -87,7 +105,13 @@ char *cmdStrings[] = {
"watcho",
#endif
"clear",
"trigger"
"trigger",
"timermode",
"timeout",
XCMD0,
XCMD1,
XCMD2,
XCMD3
};
// Must be kept in step with cmdStrings (just above)
@ -123,7 +147,6 @@ void (*cmdFuncs[])(char *params) = {
doCmdLoad,
doCmdSave,
doCmdSRec,
doCmdSpecial,
doCmdReset,
doCmdTrace,
doCmdList,
@ -140,7 +163,13 @@ void (*cmdFuncs[])(char *params) = {
doCmdWatchWrIO,
#endif
doCmdClear,
doCmdTrigger
doCmdTrigger,
doCmdTimerMode,
doCmdTimeout,
doCmdXCmd0,
doCmdXCmd1,
doCmdXCmd2,
doCmdXCmd3
};
#if defined(EXTENDED_HELP)
@ -162,6 +191,8 @@ static const char ARGS13[] PROGMEM = "<start> <end> <to>";
static const char ARGS14[] PROGMEM = "[ <value> ]";
static const char ARGS15[] PROGMEM = "[ <command> ]";
static const char ARGS16[] PROGMEM = "<op1> [ <op2> [ <op3> ] ]";
static const char ARGS17[] PROGMEM = "[ <source> [ <prescale> [ <reset address> ] ] ]";
static const char ARGS18[] PROGMEM = "e|c|d|f";
static const char * const argsStrings[] PROGMEM = {
ARGS00,
@ -180,7 +211,9 @@ static const char * const argsStrings[] PROGMEM = {
ARGS13,
ARGS14,
ARGS15,
ARGS16
ARGS16,
ARGS17,
ARGS18
};
// Must be kept in step with cmdStrings (just above)
@ -190,8 +223,8 @@ static const uint8_t helpMeta[] PROGMEM = {
#endif
17, 15, // help
9, 8, // continue
24, 7, // next
32, 6, // step
24, 1, // next
31, 6, // step
27, 7, // regs
12, 10, // dis
16, 7, // flush
@ -201,7 +234,7 @@ static const uint8_t helpMeta[] PROGMEM = {
8, 13, // compare
22, 1, // mem
26, 2, // rd
41, 3, // wr
42, 3, // wr
#if defined(CPU_Z80)
20, 1, // io
19, 2, // in
@ -212,28 +245,33 @@ static const uint8_t helpMeta[] PROGMEM = {
15, 16, // exec
23, 14, // mode
#endif
33, 12, // test
32, 12, // test
21, 0, // load
29, 9, // save
31, 7, // srec
30, 14, // special
30, 7, // srec
28, 7, // reset
34, 6, // trace
35, 6, // trace
1, 7, // blist
6, 4, // breakx
40, 4, // watchx
41, 4, // watchx
4, 4, // breakr
38, 4, // watchr
39, 4, // watchr
5, 4, // breakw
39, 4, // watchw
40, 4, // watchw
#if defined(CPU_Z80)
2, 4, // breaki
36, 4, // watchi
37, 4, // watchi
3, 4, // breako
37, 4, // watcho
38, 4, // watcho
#endif
7, 0, // clear
35, 5, // trigger
36, 5, // trigger
34, 17, // timermode
33, 14, // timeout
43, 18, // xcmd0
44, 18, // xcmd1
45, 18, // xcmd2
46, 18, // xcmd3
0, 0
};
@ -248,42 +286,42 @@ static const uint8_t helpMeta[] PROGMEM = {
#define CTRL_DDR DDRB
#define CTRL_DIN PINB
// A 0->1 transition on bit 5 actually sends a command
#define CMD_EDGE 0x20
// A 0->1 transition on bit 6 actually sends a command
#define CMD_EDGE 0x40
// Commands are placed on bits 4..0
#define CMD_MASK 0x1F
// Bits 7..6 are the special function output bits
// On the 6502, these are used to mask IRQ and NMI
#define SPECIAL_0 6
#define SPECIAL_1 7
#define SPECIAL_MASK ((1<<SPECIAL_0) | (1<<SPECIAL_1))
// Commands are placed on bits 5..0
#define CMD_MASK 0x3F
// Hardware Commands:
//
// 0000x Enable/Disable single strpping
// 0001x Enable/Disable breakpoints / watches
// 0010x Load breakpoint / watch register
// 0011x Reset CPU
// 01000 Singe Step CPU
// 01001 Read FIFO
// 01010 Reset FIFO
// 01011 Unused
// 0110x Load address/data register
// 0111x Unused
// 10000 Read Memory
// 10001 Read Memory and Auto Inc Address
// 10010 Write Memory
// 10011 Write Memory and Auto Inc Address
// 10100 Read IO
// 10101 Read IO and Auto Inc Address
// 10110 Write IO
// 10111 Write IO and Auto Inc Address
// 11000 Exec Go
// 11xx1 Unused
// 11x1x Unused
// 111xx Unused
// 00000x Enable/Disable single strpping
// 00001x Enable/Disable breakpoints / watches
// 00010x Load breakpoint / watch register
// 00011x Reset CPU
// 001000 Singe Step CPU
// 001001 Read FIFO
// 001010 Reset FIFO
// 001011 Unused
// 00110x Load address/data register
// 00111x Unused
// 010000 Read Memory
// 010001 Read Memory and Auto Inc Address
// 010010 Write Memory
// 010011 Write Memory and Auto Inc Address
// 010100 Read IO
// 010101 Read IO and Auto Inc Address
// 010110 Write IO
// 010111 Write IO and Auto Inc Address
// 011000 Exec Go
// 011xx1 Unused
// 011x1x Unused
// 0111xx Unused
// 10xxxx Int Ctrl
// 1100xx Timer Mode
// 00 - count cpu cycles where clken = 1 and CountCycle = 1
// 01 - count cpu cycles where clken = 1 (ignoring CountCycle)
// 10 - free running timer, using busmon_clk as the source
// 11 - free running timer, using trig0 as the source
#define CMD_SINGLE_ENABLE 0x00
#define CMD_BRKPT_ENABLE 0x02
@ -302,6 +340,8 @@ static const uint8_t helpMeta[] PROGMEM = {
#define CMD_WR_IO 0x16
#define CMD_WR_IO_INC 0x17
#define CMD_EXEC_GO 0x18
#define CMD_INT_CTRL 0x20
#define CMD_TIMER_MODE 0x30
/********************************************************
* AVR Status Register Definitions
@ -446,6 +486,10 @@ modes_t modes[MAXBKPTS];
#define WATCH_EXEC 9
#define TRANSIENT 10
// Mask to test if the breakpoint/watchpoint is a Z80 IO
#if defined(CPU_Z80)
#define MASK_IO ((1 << BRKPT_IO_READ) | (1 << WATCH_IO_READ) | (1 << BRKPT_IO_WRITE) | (1 << WATCH_IO_WRITE))
#endif
static const char MODE0[] PROGMEM = "Mem Rd Brkpt";
static const char MODE1[] PROGMEM = "Mem Rd Watch";
@ -474,6 +518,21 @@ static const char *modeStrings[NUM_MODES] = {
MODE10
};
// The number of different timer sources
#define NUM_TIMERS 4
static const char TIMER0[] PROGMEM = "Normal Cycles";
static const char TIMER1[] PROGMEM = "All Cycles";
static const char TIMER2[] PROGMEM = "Internal Timer";
static const char TIMER3[] PROGMEM = "External Timer";
static const char *timerStrings[NUM_TIMERS] = {
TIMER0,
TIMER1,
TIMER2,
TIMER3
};
// For convenience, several masks are defined that group similar types of breakpoint/watch
// Mask for all breakpoint types
@ -580,6 +639,24 @@ static const char * triggerStrings[NUM_TRIGGERS] = {
#define TRIGGER_UNDEFINED 31
/********************************************************
* Interrupt controls
********************************************************/
static const uint8_t cmd_map[] = { 1, 3, 0, 2 };
static const char INTCTRL0[] PROGMEM = "Enabled";
static const char INTCTRL1[] PROGMEM = "Conditional";
static const char INTCTRL2[] PROGMEM = "Forced";
static const char INTCTRL3[] PROGMEM = "Disabled";
static const char *int_ctrl_strings[] = {
INTCTRL0,
INTCTRL1,
INTCTRL2,
INTCTRL3
};
/********************************************************
* Other global variables
********************************************************/
@ -587,6 +664,9 @@ static const char * triggerStrings[NUM_TRIGGERS] = {
// The current memory address (e.g. used when disassembling)
addr_t memAddr = 0;
// The current memory timeout value, in microseconds.
uint16_t memTimeout = 0x1000;
// The address of the next instruction
addr_t nextAddr = 0;
@ -605,6 +685,16 @@ uint8_t cmd_id = 0xff;
#define MASK_CLOCK_ERROR 1
#define MASK_TIMEOUT_ERROR 2
// Current timer mode setting
uint8_t timer_mode = 0x00;
uint8_t timer_prescale = 0x01;
addr_t timer_resetaddr = 0xffff;
unsigned long timer_offset = 0;
// Current interrupts controls
uint8_t int_ctrl = 0;
/********************************************************
* User Command Processor
********************************************************/
@ -746,9 +836,13 @@ uint8_t checkargs(char *params) {
********************************************************/
// Send a single hardware command
//
void hwCmd(cmd_t cmd, cmd_t param) {
uint8_t status = STATUS_DIN;
uint16_t timeout = 10000;
// An interation of the inner loop with a 32-bit loop variable
// is 9 instructions. So use F_CPU to scale to the timeout
// value is approx microseconds.
uint32_t timeout = ((uint32_t) memTimeout) * ((F_CPU / 1000000) / 9);
cmd |= param;
CTRL_PORT &= ~CMD_MASK;
CTRL_PORT ^= cmd | CMD_EDGE;
@ -877,7 +971,7 @@ void writeIOByteInc() {
addr_t disMem(addr_t addr) {
loadAddr(addr);
return disassemble(addr);
return disassemble(addr, MODE_NORMAL);
}
void genericDump(char *params, data_t (*readFunc)()) {
@ -957,8 +1051,9 @@ void genericRead(char *params, data_t (*readFunc)()) {
* Logging Helpers
********************************************************/
void logCycleCount(int offsetLow, int offsetHigh) {
unsigned long count = (((unsigned long) hwRead8(offsetHigh)) << 16) | hwRead16(offsetLow);
void logCycleCount(int offsetLow, int offsetHigh, uint8_t clear) {
unsigned long original_count = (((unsigned long) hwRead8(offsetHigh)) << 16) | hwRead16(offsetLow);
unsigned long count = ((original_count - timer_offset) & 0xFFFFFF) / timer_prescale;
char buffer[16];
uint8_t i;
// count is 24 bits so a maximum of 16777215
@ -976,6 +1071,11 @@ void logCycleCount(int offsetLow, int offsetHigh) {
}
}
logs(" : ");
// Deal with clearing the counter
if (clear) {
logs("\n00.000000 : ");
timer_offset = original_count;
}
}
void logMode(modes_t mode) {
@ -1012,6 +1112,8 @@ uint8_t logDetails() {
// Process the dropped counter
uint8_t dropped = mode >> 4;
// Whether to clear timer
uint8_t clear = i_addr == timer_resetaddr;
if (dropped) {
logstr(" : ");
if (dropped == 15) {
@ -1030,7 +1132,7 @@ uint8_t logDetails() {
// Update the serial console
if (mode & W_MASK) {
logCycleCount(OFFSET_BW_CNTL, OFFSET_BW_CNTH);
logCycleCount(OFFSET_BW_CNTL, OFFSET_BW_CNTH, clear);
}
logMode(mode);
logstr(" hit at ");
@ -1046,7 +1148,7 @@ uint8_t logDetails() {
logc('\n');
if (mode & B_RDWR_MASK) {
// It's only safe to do this for brkpts, as it makes memory accesses
logCycleCount(OFFSET_BW_CNTL, OFFSET_BW_CNTH);
logCycleCount(OFFSET_BW_CNTL, OFFSET_BW_CNTH, clear);
disMem(i_addr);
}
return watch;
@ -1058,7 +1160,7 @@ void logAddr() {
Delay_us(100);
memAddr = hwRead16(OFFSET_IAL);
// Update the serial console
logCycleCount(OFFSET_CNTL, OFFSET_CNTH);
logCycleCount(OFFSET_CNTL, OFFSET_CNTH, memAddr == timer_resetaddr);
nextAddr = disMem(memAddr);
return;
}
@ -1189,7 +1291,11 @@ void clearBreakpoint(bknum_t n) {
void genericBreakpoint(char *params, unsigned int mode) {
bknum_t i;
addr_t addr;
#if defined(CPU_Z80)
addr_t mask = (mode & MASK_IO) ? 0xFF : 0xFFFF;
#else
addr_t mask = 0xFFFF;
#endif
trigger_t trigger = TRIGGER_UNDEFINED;
params = parsehex4required(params, &addr);
if (checkargs(params)) {
@ -1366,7 +1472,7 @@ void helpForCommand(uint8_t i) {
logstr(" ");
logs(cmdStrings[i]);
tmp = strlen(cmdStrings[i]);
while (tmp++ < 9) {
while (tmp++ < 10) {
logc(' ');
}
while ((tmp = pgm_read_byte(ip++))) {
@ -1469,7 +1575,7 @@ void doCmdDis(char *params) {
memAddr = startAddr;
loadAddr(memAddr);
do {
memAddr = disassemble(memAddr);
memAddr = disassemble(memAddr, MODE_DIS_CMD);
i++;
} while ((!endAddr && i < 10) || (endAddr && memAddr > startAddr && memAddr <= endAddr));
}
@ -1975,23 +2081,89 @@ void doCmdSRec(char *params) {
}
}
void logSpecial(char *function, uint8_t value) {
logs(function);
if (value) {
logstr(" inhibited\n");
void set_int_ctrl(uint8_t offset, char *params) {
// (C) 01 Conditional
// (D) 11 Disabled
// (E) 00 Enabled
// (F) 10 Forced
while (*params == ' ') {
params++;
}
if (!*params) {
uint8_t tmp = int_ctrl;
for (int i = 0; i < 4; i++) {
logs(cmdStrings[NUM_CMDS - 4 + i]);
logstr(" = ");
logpgmstr(int_ctrl_strings[tmp & 3]);
logc('\n');
tmp >>= 2;
}
} else {
logstr(" enabled\n");
*params &= 0xdf;
if (*params >= 'C' && *params <= 'F') {
uint8_t val = cmd_map[*params - 'C'];
hwCmd(CMD_INT_CTRL, (offset << 1) | val);
int_ctrl &= (0x03 << offset) ^ 0xFF;
int_ctrl |= (val << offset);
} else {
logstr("Illegal option\n");
}
}
}
void doCmdSpecial(char *params) {
uint8_t special = 0xff;
parsehex2(params, &special);
if (special <= 3) {
CTRL_PORT = (CTRL_PORT & ~SPECIAL_MASK) | (special << SPECIAL_0);
void doCmdXCmd0(char *params) {
set_int_ctrl(0, params);
}
logSpecial("NMI", CTRL_PORT & (1 << SPECIAL_1));
logSpecial("IRQ", CTRL_PORT & (1 << SPECIAL_0));
void doCmdXCmd1(char *params) {
set_int_ctrl(2, params);
}
void doCmdXCmd2(char *params) {
set_int_ctrl(4, params);
}
void doCmdXCmd3(char *params) {
set_int_ctrl(6, params);
}
void doCmdTimerMode(char *params) {
uint8_t mode = 0xff;
uint8_t prescale = 0xff;
addr_t addr = 0xffff;
params = parsehex2(params, &mode);
params = parsehex2(params, &prescale);
params = parsehex4(params, &addr);
if (mode <= NUM_TIMERS) {
timer_mode = mode;
hwCmd(CMD_TIMER_MODE, timer_mode);
}
if (prescale < 0xff) {
timer_prescale = prescale;
}
if (addr < 0xffff) {
timer_resetaddr = addr;
}
logstr("mode: ");
logpgmstr(timerStrings[timer_mode]);
logstr("; prescale=");
loghex4(timer_prescale);
logstr("; reset address=");
loghex4(timer_resetaddr);
logstr("\n");
}
void doCmdTimeout(char *params) {
parsehex4(params, &memTimeout);
// Small timeouts values cause bogus timeout errors, so enforce a minimum
// of 16us, which is less much than one character time at 115,200 (86us)
if (memTimeout < 0x10) {
memTimeout = 0x10;
}
logstr("timeout=");
loghex4(memTimeout);
logstr(" microseconds (hex)\n");
}
void doCmdTrace(char *params) {
@ -2113,8 +2285,13 @@ void doCmdNext(char *params) {
logTooManyBreakpoints();
return;
}
addr_t addr = 0xFFFF;
params = parsehex4(params, &addr);
if (addr == 0xFFFF) {
addr = nextAddr;
}
numbkpts++;
setBreakpoint(numbkpts - 1, nextAddr, 0xffff, (1 << BRKPT_EXEC) | (1 << TRANSIENT), TRIGGER_ALWAYS);
setBreakpoint(numbkpts - 1, addr, 0xffff, (1 << BRKPT_EXEC) | (1 << TRANSIENT), TRIGGER_ALWAYS);
doCmdContinue(params);
}

View File

@ -76,7 +76,8 @@ void doCmdStep(char *params);
void doCmdTest(char *params);
void doCmdSave(char *params);
void doCmdSRec(char *params);
void doCmdSpecial(char *params);
void doCmdTimerMode(char *params);
void doCmdTimeout(char *params);
void doCmdTrace(char *params);
void doCmdTrigger(char *params);
void doCmdWatchI(char *params);
@ -86,5 +87,9 @@ void doCmdWatchWrIO(char *params);
void doCmdWatchWrMem(char *params);
void doCmdWriteIO(char *params);
void doCmdWriteMem(char *params);
void doCmdXCmd0(char *params);
void doCmdXCmd1(char *params);
void doCmdXCmd2(char *params);
void doCmdXCmd3(char *params);
#endif

View File

@ -6,6 +6,10 @@
#define PDC_DDR DDRA
#define PDC_DIN PINA
addr_t disassemble(addr_t addr);
#define MODE_NORMAL 0
#define MODE_DIS_CMD 1
addr_t disassemble(addr_t addr, uint8_t m);
#endif

View File

@ -149,7 +149,7 @@ static const unsigned char dopname[256] PROGMEM =
static const unsigned char dopaddr[256] PROGMEM =
{
/*00*/ IMP, INDX, IMP, IMP, IMP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, IMP, ABS, ABS, IMP,
/*00*/ IMM, INDX, IMP, IMP, IMP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, IMP, ABS, ABS, IMP,
/*10*/ BRA, INDY, IMP, IMP, IMP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, IMP, ABSX, ABSX, IMP,
/*20*/ ABS, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
/*30*/ BRA, INDY, IMP, IMP, IMP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, IMP, ABSX, ABSX, IMP,
@ -167,7 +167,7 @@ static const unsigned char dopaddr[256] PROGMEM =
/*F0*/ BRA, INDY, IMP, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP
};
addr_t disassemble(addr_t addr)
addr_t disassemble(addr_t addr, uint8_t m)
{
char buffer[40];

View File

@ -169,7 +169,7 @@ static const unsigned char dopname[256] PROGMEM =
static const unsigned char dopaddr[256] PROGMEM =
{
/*00*/ IMP, INDX, IMP, IMP, ZP, ZP, ZP, IMP, IMP, IMM, IMPA, IMP, ABS, ABS, ABS, IMP,
/*00*/ IMM, 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,
@ -187,7 +187,7 @@ static const unsigned char dopaddr[256] PROGMEM =
/*F0*/ BRA, INDY, IND, IMP, ZP, ZPX, ZPX, IMP, IMP, ABSY, IMP, IMP, ABS, ABSX, ABSX, IMP
};
addr_t disassemble(addr_t addr)
addr_t disassemble(addr_t addr, uint8_t m)
{
char buffer[40];

View File

@ -647,7 +647,7 @@ static char *strcc(char *ptr, uint8_t val) {
/* disassemble one instruction at address addr and return the address of the next instruction */
addr_t disassemble(addr_t addr) {
addr_t disassemble(addr_t addr, uint8_t m) {
uint8_t d = get_memb(addr);
uint8_t s;
int8_t i;

View File

@ -530,9 +530,9 @@ static const unsigned char cmd_ED40[192] PROGMEM = {
NOP,0,0
};
static const char word_EX_HALT[] PROGMEM = "**HALT**";
static const char word_EX_INT[] PROGMEM = "**INT**";
static const char word_EX_NMI[] PROGMEM = "**NMI**";
static const char msg_HALT[] PROGMEM = "**HALT**\n";
static const char msg_INT[] PROGMEM = "**INT**\n";
static const char msg_NMI[] PROGMEM = "**NMI**\n";
unsigned char cmd_halt[] = { HALT,0,0 };
unsigned char cmd_nop[] = { NOP,0,0 };
@ -887,12 +887,15 @@ char * disassem (char *ptr, unsigned int *ip) {
return ptr;
}
addr_t disassemble(addr_t addr) {
addr_t disassemble(addr_t addr, uint8_t m) {
static char buffer[64];
char *ptr;
addr_t addr2 = addr;
// Ignore the current CPU state in the disassemble connamd
uint8_t pdc = (m == MODE_DIS_CMD) ? 0 : PDC_DIN;
// 0123456789012345678901234567890123456789
// AAAA : HH HH HH HH : LD RR,($XXXX)
@ -905,17 +908,18 @@ addr_t disassemble(addr_t addr) {
// Opcode
ptr = buffer + 21;
if (PDC_DIN & 0x80) {
strcpy_P(ptr, PSTR("**HALT**"));
} else if (PDC_DIN & 0x40) {
strcpy(ptr, PSTR("**NMI**"));
} else if (PDC_DIN & 0x20) {
strcpy(ptr, PSTR("**INT**"));
if (pdc & 0x80) {
strcpy_P(ptr, msg_HALT);
} else if (pdc & 0x40) {
strcpy(ptr, msg_NMI);
} else if (pdc & 0x20) {
strcpy(ptr, msg_INT);
} else {
ptr = disassem(ptr, &addr2);
}
*ptr++ = '\n';
*ptr++ = '\0';
}
// Hex
loadAddr(addr);

View File

@ -16,8 +16,9 @@ pushd target
make clean
make
cp --parents */*/*.bit ../${DIR}
cp --parents */*/*.mcs ../${DIR}
cp --parents */*/ice*.bit ../${DIR}
cp --parents */*/ice*.bin ../${DIR}
cp --parents */*/ice*.mcs ../${DIR}
popd
@ -27,5 +28,3 @@ popd
echo "Built release in: "${DIR}
unzip -l releases/${NAME}.zip

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,6 @@ use ieee.numeric_std.ALL;
entity R65C02 is
port (
reset : in std_logic;
clk : in std_logic;
enable : in std_logic;
@ -41,16 +40,14 @@ end R65C02;
-- Rts (6) => fetch, cycle2, cycle3, cycleRead, cycleJump, cycleIncrEnd
-- Rti (6) => fetch, cycle2, stack1, stack2, stack3, cycleJump
-- Jsr (6) => fetch, cycle2, .. cycle5, cycle6, cycleJump
-- Jmp abs (-) => fetch, cycle2, .., cycleJump
-- Jmp (ind) (-) => fetch, cycle2, .., cycleJump
-- Brk / irq (6) => fetch, cycle2, stack2, stack3, stack4
-- Jmp abs (3) => fetch, cycle2, cycleJump
-- Jmp (ind) (6) => fetch, cycle2, cycle3, cycleRead, cycleRead2, cycleJump
-- Jmp (ind,x) (6) => fetch, cycle2, cycle3, cycleRead, cycleRead2, cycleJump
-- Brk (7) => fetch, cycle2, stack2, stack3, stack4, cycleRead2, cycleJump
-- -----------------------------------------------------------------------
architecture Behavioral of R65C02 is
-- signal counter : unsigned(27 downto 0);
-- signal mask_irq : std_logic;
-- signal mask_enable : std_logic;
-- Statemachine
type cpuCycles is (
@ -74,6 +71,7 @@ architecture Behavioral of R65C02 is
cycleJump, -- Last cycle of Jsr, Jmp. Next fetch address is target addr.
cycleEnd
);
signal theCpuCycle : cpuCycles;
signal nextCpuCycle : cpuCycles;
signal updateRegisters : boolean;
@ -84,6 +82,7 @@ architecture Behavioral of R65C02 is
signal soReg : std_logic; -- SO pin edge detection
-- Opcode decoding
constant opcUpdateA : integer := 0;
constant opcUpdateX : integer := 1;
constant opcUpdateY : integer := 2;
@ -112,7 +111,6 @@ architecture Behavioral of R65C02 is
constant opcRti : integer := 24;
constant opcIRQ : integer := 25;
constant opcInA : integer := 26;
constant opcInBrk : integer := 27;
constant opcInX : integer := 28;
@ -129,7 +127,7 @@ architecture Behavioral of R65C02 is
constant aluMode2From : integer := 38;
--
constant aluMode2To : integer := 40;
--
constant opcInCmp : integer := 41;
constant opcInCpx : integer := 42;
constant opcInCpy : integer := 43;
@ -200,8 +198,6 @@ architecture Behavioral of R65C02 is
constant rts : addrDef := "0000101000100100";
constant rti : addrDef := "0000111000100010";
constant brk : addrDef := "1000111000000001";
-- constant irq : addrDef := "0000111000000001";
-- constant : unsigned(0 to 0) := "0";
constant xxxxxxxx : addrDef := "----------0---00";
-- A = accu
@ -259,9 +255,7 @@ architecture Behavioral of R65C02 is
constant aluModeOra : aluMode2 := "101";
constant aluModeEor : aluMode2 := "110";
constant aluModeNoF : aluMode2 := "111";
--aluModeBRK
--constant aluBrk : aluMode := aluModeBRK & aluModePss & "---";
--constant aluFix : aluMode := aluModeInp & aluModeNoF & "---";
constant aluInp : aluMode := aluModeInp & aluModePss & "---";
constant aluP : aluMode := aluModeP & aluModePss & "---";
constant aluInc : aluMode := aluModeInc & aluModePss & "---";
@ -285,14 +279,15 @@ architecture Behavioral of R65C02 is
constant aluXXX : aluMode := (others => '-');
-- Stack operations. Push/Pop/None
constant stackInc : unsigned(0 to 0) := "0";
constant stackDec : unsigned(0 to 0) := "1";
constant stackXXX : unsigned(0 to 0) := "-";
subtype decodedBitsDef is unsigned(0 to 43);
type opcodeInfoTableDef is array(0 to 255) of decodedBitsDef;
constant opcodeInfoTable : opcodeInfoTableDef := (
-- +------- Update register A
-- |+------ Update register X
@ -571,7 +566,6 @@ architecture Behavioral of R65C02 is
);
signal opcInfo : decodedBitsDef;
signal nextOpcInfo : decodedBitsDef; -- Next opcode (decoded)
signal nextOpcInfoReg : decodedBitsDef; -- Next opcode (decoded) pipelined
signal theOpcode : unsigned(7 downto 0);
signal nextOpcode : unsigned(7 downto 0);
@ -595,6 +589,7 @@ architecture Behavioral of R65C02 is
nextAddrStack,
nextAddrRelative
);
signal nextAddr : nextAddrDef;
signal myAddr : unsigned(15 downto 0);
signal myAddrIncr : unsigned(15 downto 0);
@ -632,11 +627,12 @@ architecture Behavioral of R65C02 is
signal aluZ : std_logic;
signal aluV : std_logic;
signal aluN : std_logic;
-- Indexing
signal indexOut : unsigned(8 downto 0);
signal realbrk : std_logic;
begin
processAluInput: process(clk, opcInfo, A, X, Y, T, S)
variable temp : unsigned(7 downto 0);
begin
@ -704,7 +700,7 @@ processCmpInput: process(clk, opcInfo, A, X, Y)
--hardware interrupts IRQ & NMI will push the B flag as being 0.
processAlu: process(clk, opcInfo, aluInput, aluCmpInput, A, T, irqActive, N, V, D, I, Z, C)
processAlu: process(clk, opcInfo, aluInput, aluCmpInput, A, T, irqActive, N, V, D, I, Z, C, R)
variable lowBits : unsigned(5 downto 0);
variable nineBits : unsigned(8 downto 0);
variable rmwBits : unsigned(8 downto 0);
@ -720,7 +716,7 @@ processAlu: process(clk, opcInfo, aluInput, aluCmpInput, A, T, irqActive, N, V,
rmwBits := (others => '-');
tsxBits := (others => '-');
R <= '1';
B <= '0';
-- Shift unit
case opcInfo(aluMode1From to aluMode1To) is
@ -754,10 +750,8 @@ processAlu: process(clk, opcInfo, aluInput, aluCmpInput, A, T, irqActive, N, V,
when others => ninebits := rmwBits;
end case;
varV := aluInput(6); -- Default for BIT / PLP / RTI
if (opcInfo(aluMode1From to aluMode1To) = aluModeFlg) then
varZ := rmwBits(1);
elsif (opcInfo(aluMode1From to aluMode1To) = aluModeTSB) or (opcInfo(aluMode1From to aluMode1To) = aluModeTRB) then
@ -786,7 +780,6 @@ processAlu: process(clk, opcInfo, aluInput, aluCmpInput, A, T, irqActive, N, V,
-- v Set if signed overflow; cleared if valid signed result.
-- z Set if result is zero; else cleared.
-- c Set if unsigned overflow; cleared if valid unsigned result
when aluModeAdc =>
-- decimal mode low bits correction, is done after setting Z flag.
if D = '1' then
@ -797,7 +790,8 @@ processAlu: process(clk, opcInfo, aluInput, aluCmpInput, A, T, irqActive, N, V,
end if;
end if;
end if;
when others => null;
when others =>
null;
end case;
case opcInfo(aluMode2From to aluMode2To) is
@ -823,7 +817,8 @@ processAlu: process(clk, opcInfo, aluInput, aluCmpInput, A, T, irqActive, N, V,
ninebits(8 downto 4) := ninebits(8 downto 4) - 6;
end if;
end if;
when others => null;
when others =>
null;
end case;
-- fix n and z flag for 65c02 adc sbc instructions in decimal mode
@ -846,7 +841,8 @@ processAlu: process(clk, opcInfo, aluInput, aluCmpInput, A, T, irqActive, N, V,
end if;
varN := ninebits(7);
end if;
when others => null;
when others =>
null;
end case;
-- DMB Remove Pipelining
@ -911,14 +907,6 @@ calcNextOpcode: process(clk, di, reset, processIrq)
nextOpcInfo <= opcodeInfoTable(to_integer(nextOpcode));
-- DMB Remove Pipelining
-- process(clk)
-- begin
-- if rising_edge(clk) then
nextOpcInfoReg <= nextOpcInfo;
-- end if;
-- end process;
-- Read bits and flags from opcodeInfoTable and store in opcInfo.
-- This info is used to control the execution of the opcode.
calcOpcInfo: process(clk)
@ -979,13 +967,23 @@ calcTheOpcode: process(clk)
-- Determine the next cpu cycle. After the last cycle we always
-- go to opcodeFetch to get the next opcode.
calcNextCpuCycle: process(theCpuCycle, opcInfo, theOpcode, indexOut, T, N, V, C, Z)
calcNextCpuCycle: process(theCpuCycle, opcInfo, theOpcode, nextOpcode, indexOut, T, N, V, C, Z)
begin
nextCpuCycle <= opcodeFetch;
case theCpuCycle is
when opcodeFetch => nextCpuCycle <= cycle2;
when cycle2 => if opcInfo(opcBranch) = '1' then
when opcodeFetch =>
-- DMB: Implement single cycle NOPs (columns 3,7,B,F) by
-- looking ahead at opcode (bypassing the normal decoding)
if nextOpcode(1 downto 0) = "11" then
nextCpuCycle <= opcodeFetch;
else
nextCpuCycle <= cycle2;
end if;
when cycle2 =>
if opcInfo(opcBranch) = '1' then
if (N = theOpcode(5) and theOpcode(7 downto 6) = "00")
or (V = theOpcode(5) and theOpcode(7 downto 6) = "01")
or (C = theOpcode(5) and theOpcode(7 downto 6) = "10")
@ -1026,7 +1024,9 @@ calcNextCpuCycle: process(theCpuCycle, opcInfo, theOpcode, indexOut, T, N, V, C,
elsif opcInfo(opcJump) = '1' then
nextCpuCycle <= cycleJump;
end if;
when cycle3 => nextCpuCycle <= cycleRead;
when cycle3 =>
nextCpuCycle <= cycleRead;
if opcInfo(opcWrite) = '1' then
if (opcInfo(indexX) = '1') or (opcInfo(indexY) = '1') then
nextCpuCycle <= cyclePreWrite;
@ -1041,18 +1041,24 @@ calcNextCpuCycle: process(theCpuCycle, opcInfo, theOpcode, indexOut, T, N, V, C,
nextCpuCycle <= cycleRead2;
end if;
end if;
when cyclePreIndirect => nextCpuCycle <= cycleIndirect;
when cycleIndirect => nextCpuCycle <= cycle3;
when cycleBranchTaken => if indexOut(8) /= T(7) then
when cyclePreIndirect =>
nextCpuCycle <= cycleIndirect;
when cycleIndirect =>
nextCpuCycle <= cycle3;
when cycleBranchTaken =>
if indexOut(8) /= T(7) then
nextCpuCycle <= cycleBranchPage;
end if;
when cyclePreRead => if opcInfo(opcZeroPage) = '1' then
when cyclePreRead =>
if opcInfo(opcZeroPage) = '1' then
nextCpuCycle <= cycleRead2;
end if;
when cycleRead =>
if opcInfo(opcJump) = '1' then
nextCpuCycle <= cycleJump;
elsif indexOut(8) = '1' then
if opcInfo(opcJump) = '1' or indexOut(8) = '1' then
nextCpuCycle <= cycleRead2;
elsif opcInfo(opcRmw) = '1' then
nextCpuCycle <= cycleRmw;
@ -1060,33 +1066,53 @@ calcNextCpuCycle: process(theCpuCycle, opcInfo, theOpcode, indexOut, T, N, V, C,
nextCpuCycle <= cycleRead2;
end if;
end if;
when cycleRead2 => if opcInfo(opcRmw) = '1' then
when cycleRead2 =>
if opcInfo(opcJump) = '1' then
nextCpuCycle <= cycleJump;
elsif opcInfo(opcRmw) = '1' then
nextCpuCycle <= cycleRmw;
end if;
when cycleRmw => nextCpuCycle <= cycleWrite;
when cyclePreWrite => nextCpuCycle <= cycleWrite;
when cycleStack1 => nextCpuCycle <= cycleRead;
when cycleRmw =>
nextCpuCycle <= cycleWrite;
when cyclePreWrite =>
nextCpuCycle <= cycleWrite;
when cycleStack1 =>
nextCpuCycle <= cycleRead;
if opcInfo(opcStackAddr) = '1' then
nextCpuCycle <= cycleStack2;
end if;
when cycleStack2 => nextCpuCycle <= cycleStack3;
when cycleStack2 =>
nextCpuCycle <= cycleStack3;
if opcInfo(opcRti) = '1' then
nextCpuCycle <= cycleRead;
end if;
if opcInfo(opcStackData) = '0' and opcInfo(opcStackUp) = '1' then
nextCpuCycle <= cycleJump;
end if;
when cycleStack3 => nextCpuCycle <= cycleRead;
when cycleStack3 =>
nextCpuCycle <= cycleRead;
if opcInfo(opcStackData) = '0' or opcInfo(opcStackUp) = '1' then
nextCpuCycle <= cycleJump;
elsif opcInfo(opcStackAddr) = '1' then
nextCpuCycle <= cycleStack4;
end if;
when cycleStack4 => nextCpuCycle <= cycleRead;
when cycleJump => if opcInfo(opcIncrAfter) = '1' then
when cycleStack4 =>
nextCpuCycle <= cycleRead2;
when cycleJump =>
if opcInfo(opcIncrAfter) = '1' then
nextCpuCycle <= cycleEnd;
end if;
when others => null;
when others =>
null;
end case;
end process;
@ -1098,7 +1124,8 @@ calcT: process(clk)
if rising_edge(clk) then
if enable = '1' then
case theCpuCycle is
when cycle2 => T <= di;
when cycle2 =>
T <= di;
when cycleStack1 | cycleStack2 =>
if opcInfo(opcStackUp) = '1' then
if theOpcode = x"28" or theOpcode = x"40" then -- plp or rti pulling the flags off the stack
@ -1107,8 +1134,10 @@ calcT: process(clk)
T <= di;
end if;
end if;
when cycleIndirect | cycleRead | cycleRead2 => T <= di;
when others => null;
when cycleIndirect | cycleRead | cycleRead2 =>
T <= di;
when others =>
null;
end case;
end if;
end if;
@ -1199,6 +1228,7 @@ calcT: process(clk)
end if;
end if;
end process;
-- -----------------------------------------------------------------------
-- D flag
-- -----------------------------------------------------------------------
@ -1266,16 +1296,22 @@ calcT: process(clk)
updateFlag := true;
end if;
when cycleStack2 => updateFlag := true;
when cycleStack3 => updateFlag := true;
when cycleStack4 => updateFlag := true;
when cycleRead => if opcInfo(opcRti) = '1' then
when cycleStack2 =>
updateFlag := true;
when cycleStack3 =>
updateFlag := true;
when cycleStack4 =>
updateFlag := true;
when cycleRead =>
if opcInfo(opcRti) = '1' then
updateFlag := true;
end if;
when cycleWrite => if opcInfo(opcStackData) = '1' then
when cycleWrite =>
if opcInfo(opcStackData) = '1' then
updateFlag := true;
end if;
when others => null;
when others =>
null;
end case;
if updateFlag then
@ -1302,22 +1338,25 @@ calcDo: process(clk)
if enable = '1' then
doReg <= aluRmwOut;
case nextCpuCycle is
when cycleStack2 => if opcInfo(opcIRQ) = '1' and irqActive = '0' then
when cycleStack2 =>
if opcInfo(opcIRQ) = '1' and irqActive = '0' then
doReg <= myAddrIncr(15 downto 8);
else
doReg <= PC(15 downto 8);
end if;
when cycleStack3 => doReg <= PC(7 downto 0);
when cycleRmw => doReg <= di; -- Read-modify-write write old value first.
when others => null;
when cycleStack3 =>
doReg <= PC(7 downto 0);
when cycleRmw =>
doReg <= di; -- Read-modify-write write old value first.
when others =>
null;
end case;
end if;
end if;
end process;
do <= doReg;
-- -----------------------------------------------------------------------
-- Write enable
-- -----------------------------------------------------------------------
@ -1335,9 +1374,12 @@ calcWe: process(clk)
if opcInfo(opcStackUp) = '0' then
theWe <= '0';
end if;
when cycleRmw => theWe <= '0';
when cycleWrite => theWe <= '0';
when others => null;
when cycleRmw =>
theWe <= '0';
when cycleWrite =>
theWe <= '0';
when others =>
null;
end case;
end if;
end if;
@ -1353,18 +1395,22 @@ calcPC: process(clk)
if rising_edge(clk) then
if enable = '1' then
case theCpuCycle is
when opcodeFetch => PC <= myAddr;
when cycle2 => if irqActive = '0' then
when opcodeFetch =>
PC <= myAddr;
when cycle2 =>
if irqActive = '0' then
if opcInfo(opcSecondByte) = '1' then
PC <= myAddrIncr;
else
PC <= myAddr;
end if;
end if;
when cycle3 => if opcInfo(opcAbsolute) = '1' then
when cycle3 =>
if opcInfo(opcAbsolute) = '1' then
PC <= myAddrIncr;
end if;
when others => null;
when others =>
null;
end case;
end if;
end if;
@ -1378,7 +1424,8 @@ calcNextAddr: process(theCpuCycle, opcInfo, indexOut, T, reset)
begin
nextAddr <= nextAddrIncr;
case theCpuCycle is
when cycle2 => if opcInfo(opcStackAddr) = '1' or opcInfo(opcStackData) = '1' then
when cycle2 =>
if opcInfo(opcStackAddr) = '1' or opcInfo(opcStackData) = '1' then
nextAddr <= nextAddrStack;
elsif opcInfo(opcAbsolute) = '1' then
nextAddr <= nextAddrIncr;
@ -1391,67 +1438,72 @@ calcNextAddr: process(theCpuCycle, opcInfo, indexOut, T, reset)
else
nextAddr <= nextAddrHold;
end if;
when cycle3 => if (opcInfo(opcIndirect) = '1') and (opcInfo(indexX) = '1') then
when cycle3 =>
if (opcInfo(opcIndirect) = '1') and (opcInfo(indexX) = '1') then
nextAddr <= nextAddrAbs;
else
nextAddr <= nextAddrAbsIndexed;
end if;
when cyclePreIndirect => nextAddr <= nextAddrZPIndexed;
when cycleIndirect => nextAddr <= nextAddrIncrL;
when cycleBranchTaken => nextAddr <= nextAddrRelative;
when cycleBranchPage => if T(7) = '0' then
when cyclePreIndirect =>
nextAddr <= nextAddrZPIndexed;
when cycleIndirect =>
nextAddr <= nextAddrIncrL;
when cycleBranchTaken =>
nextAddr <= nextAddrRelative;
when cycleBranchPage =>
if T(7) = '0' then
nextAddr <= nextAddrIncrH;
else
nextAddr <= nextAddrDecrH;
end if;
when cyclePreRead => nextAddr <= nextAddrZPIndexed;
when cycleRead => nextAddr <= nextAddrPc;
if opcInfo(opcJump) = '1' then
-- Emulate 6510 bug, jmp(xxFF) fetches from same page.
-- Replace with nextAddrIncr if emulating 65C02 or later cpu.
nextAddr <= nextAddrIncr;
--nextAddr <= nextAddrIncrL;
elsif indexOut(8) = '1' then
when cyclePreRead =>
nextAddr <= nextAddrZPIndexed;
when cycleRead =>
nextAddr <= nextAddrPc;
if indexOut(8) = '1' then
nextAddr <= nextAddrIncrH;
elsif opcInfo(opcRmw) = '1' or opcInfo(opcJump) = '1' then
nextAddr <= nextAddrHold;
end if;
when cycleRead2 =>
nextAddr <= nextAddrPc;
if opcInfo(opcJump) = '1' then
nextAddr <= nextAddrIncr;
elsif opcInfo(opcRmw) = '1' then
nextAddr <= nextAddrHold;
end if;
when cycleRead2 => nextAddr <= nextAddrPc;
if opcInfo(opcRmw) = '1' then
when cycleRmw =>
nextAddr <= nextAddrHold;
when cyclePreWrite =>
nextAddr <= nextAddrHold;
end if;
when cycleRmw => nextAddr <= nextAddrHold;
when cyclePreWrite => nextAddr <= nextAddrHold;
if opcInfo(opcZeroPage) = '1' then
nextAddr <= nextAddrZPIndexed;
elsif indexOut(8) = '1' then
nextAddr <= nextAddrIncrH;
end if;
when cycleWrite => nextAddr <= nextAddrPc;
when cycleStack1 => nextAddr <= nextAddrStack;
when cycleStack2 => nextAddr <= nextAddrStack;
when cycleStack3 => nextAddr <= nextAddrStack;
when cycleWrite =>
nextAddr <= nextAddrPc;
when cycleStack1 =>
nextAddr <= nextAddrStack;
when cycleStack2 =>
nextAddr <= nextAddrStack;
when cycleStack3 =>
nextAddr <= nextAddrStack;
if opcInfo(opcStackData) = '0' then
nextAddr <= nextAddrPc;
end if;
when cycleStack4 => nextAddr <= nextAddrIrq;
when cycleJump => nextAddr <= nextAddrAbs;
when others => null;
when cycleStack4 =>
nextAddr <= nextAddrIrq;
when cycleJump =>
nextAddr <= nextAddrAbs;
when others =>
null;
end case;
if reset = '0' then
nextAddr <= nextAddrReset;
end if;
end process;
indexAlu: process(opcInfo, myAddr, T, X, Y)
begin
if opcInfo(indexX) = '1' then
@ -1470,28 +1522,37 @@ calcAddr: process(clk)
if rising_edge(clk) then
if enable = '1' then
case nextAddr is
when nextAddrIncr => myAddr <= myAddrIncr;
when nextAddrIncrL => myAddr(7 downto 0) <= myAddrIncr(7 downto 0);
when nextAddrIncrH => myAddr(15 downto 8) <= myAddrIncrH;
when nextAddrDecrH => myAddr(15 downto 8) <= myAddrDecrH;
when nextAddrPc => myAddr <= PC;
when nextAddrIrq =>myAddr <= X"FFFE";
when nextAddrIncr =>
myAddr <= myAddrIncr;
when nextAddrIncrL =>
myAddr(7 downto 0) <= myAddrIncr(7 downto 0);
when nextAddrIncrH =>
myAddr(15 downto 8) <= myAddrIncrH;
when nextAddrDecrH =>
myAddr(15 downto 8) <= myAddrDecrH;
when nextAddrPc =>
myAddr <= PC;
when nextAddrIrq =>
myAddr <= X"FFFE";
if nmiReg = '0' then
myAddr <= X"FFFA";
end if;
when nextAddrReset => myAddr <= X"FFFC";
when nextAddrAbs => myAddr <= di & T;
when nextAddrAbsIndexed =>--myAddr <= di & indexOut(7 downto 0);
if theOpcode = x"7C" then
myAddr <= (di & T) + (x"00"& X);
else
when nextAddrReset =>
myAddr <= X"FFFC";
when nextAddrAbs =>
myAddr <= di & T;
when nextAddrAbsIndexed =>
myAddr <= di & indexOut(7 downto 0);
end if;
when nextAddrZeroPage => myAddr <= "00000000" & di;
when nextAddrZPIndexed => myAddr <= "00000000" & indexOut(7 downto 0);
when nextAddrStack => myAddr <= "00000001" & S;
when nextAddrRelative => myAddr(7 downto 0) <= indexOut(7 downto 0);
when others => null;
when nextAddrZeroPage =>
myAddr <= "00000000" & di;
when nextAddrZPIndexed =>
myAddr <= "00000000" & indexOut(7 downto 0);
when nextAddrStack =>
myAddr <= "00000001" & S;
when nextAddrRelative =>
myAddr(7 downto 0) <= indexOut(7 downto 0);
when others =>
null;
end case;
end if;
end if;
@ -1506,11 +1567,12 @@ calcAddr: process(clk)
--
-- calcsync: process(clk)
-- begin
--
-- if enable = '1' then
-- case theCpuCycle is
-- when opcodeFetch => sync <= '1';
-- when others => sync <= '0';
-- when opcodeFetch =>
-- sync <= '1';
-- when others =>
-- sync <= '0';
-- end case;
-- end if;
-- end process;
@ -1527,5 +1589,3 @@ calcAddr: process(clk)
std_logic_vector(A);
end architecture;

View File

@ -71,8 +71,8 @@ entity BusMonCore is
DataIn : in std_logic_vector(7 downto 0);
Done : in std_logic;
-- Special outputs (function is CPU specific)
Special : out std_logic_vector(1 downto 0);
-- External Interrupt Control
int_ctrl : out std_logic_vector(7 downto 0) := x"00";
-- Single Step interface
SS_Single : out std_logic;
@ -124,15 +124,18 @@ architecture behavioral of BusMonCore is
signal cmd_ack : std_logic;
signal cmd_ack1 : std_logic;
signal cmd_ack2 : std_logic;
signal cmd : std_logic_vector(4 downto 0);
signal cmd : std_logic_vector(5 downto 0);
signal addr_sync : std_logic_vector(15 downto 0);
signal addr_inst : std_logic_vector(15 downto 0);
signal Addr1 : std_logic_vector(15 downto 0);
signal Data1 : std_logic_vector(7 downto 0);
signal ext_clk : std_logic;
signal timer0Count : std_logic_vector(23 downto 0);
signal timer1Count : std_logic_vector(23 downto 0);
signal cycleCount : std_logic_vector(23 downto 0);
signal cycleCount_inst : std_logic_vector(23 downto 0);
signal instrCount : std_logic_vector(23 downto 0);
signal single : std_logic;
signal reset : std_logic;
@ -181,6 +184,8 @@ architecture behavioral of BusMonCore is
signal dropped_counter : std_logic_vector(3 downto 0);
signal timer_mode : std_logic_vector(1 downto 0);
begin
inst_oho_dy1 : entity work.Oho_Dy1 port map (
@ -224,9 +229,9 @@ begin
portbout(2) => cmd(2),
portbout(3) => cmd(3),
portbout(4) => cmd(4),
portbout(5) => cmd_edge,
portbout(6) => Special(0),
portbout(7) => Special(1),
portbout(5) => cmd(5),
portbout(6) => cmd_edge,
portbout(7) => open,
-- Status Port
portdin(0) => '0',
@ -289,7 +294,7 @@ begin
-- DataWr1 is the data being written delayed by 1 cycle
-- DataRd is the data being read, that is already one cycle late
-- bw_state1(1) is 1 for writes, and 0 for reads
fifo_din <= cycleCount_inst & dropped_counter & bw_status1 & Data1 & Addr1 & addr_inst;
fifo_din <= instrCount & dropped_counter & bw_status1 & Data1 & Addr1 & addr_inst;
-- Implement a 4-bit saturating counter of the number of dropped events
process (busmon_clk)
@ -325,9 +330,9 @@ begin
mux <= addr_inst(7 downto 0) when muxsel = 0 else
addr_inst(15 downto 8) when muxsel = 1 else
din_reg when muxsel = 2 else
cycleCount(23 downto 16) when muxsel = 3 else
cycleCount(7 downto 0) when muxsel = 4 else
cycleCount(15 downto 8) when muxsel = 5 else
instrCount(23 downto 16) when muxsel = 3 else
instrCount(7 downto 0) when muxsel = 4 else
instrCount(15 downto 8) when muxsel = 5 else
fifo_dout(7 downto 0) when muxsel = 6 else
fifo_dout(15 downto 8) when muxsel = 7 else
@ -432,40 +437,55 @@ begin
end process;
-- CPU Control Commands
-- 0000x Enable/Disable single stepping
-- 0001x Enable/Disable breakpoints / watches
-- 0010x Load breakpoint / watch register
-- 0011x Reset CPU
-- 01000 Singe Step CPU
-- 01001 Read FIFO
-- 01010 Reset FIFO
-- 01011 Unused
-- 0110x Load address/data register
-- 0111x Unused
-- 10000 Read Memory
-- 10001 Read Memory and Auto Inc Address
-- 10010 Write Memory
-- 10011 Write Memory and Auto Inc Address
-- 10100 Read IO
-- 10101 Read IO and Auto Inc Address
-- 10110 Write IO
-- 10111 Write IO and Auto Inc Address
-- 11000 Execute 6502 instruction
-- 111xx Unused
-- 11x1x Unused
-- 11xx1 Unused
-- 00000x Enable/Disable single stepping
-- 00001x Enable/Disable breakpoints / watches
-- 00010x Load breakpoint / watch register
-- 00011x Reset CPU
-- 001000 Singe Step CPU
-- 001001 Read FIFO
-- 001010 Reset FIFO
-- 001011 Unused
-- 00110x Load address/data register
-- 00111x Unused
-- 010000 Read Memory
-- 010001 Read Memory and Auto Inc Address
-- 010010 Write Memory
-- 010011 Write Memory and Auto Inc Address
-- 010100 Read IO
-- 010101 Read IO and Auto Inc Address
-- 010110 Write IO
-- 010111 Write IO and Auto Inc Address
-- 011000 Execute 6502 instruction
-- 0111xx Unused
-- 011x1x Unused
-- 011xx1 Unused
-- 10xxxx Int Ctrl
-- 1100xx Timer Mode
-- 00 - count cpu cycles where clken = 1 and CountCycle = 1
-- 01 - count cpu cycles where clken = 1 (ignoring CountCycle)
-- 10 - free running timer, using busmon_clk as the source
-- 11 - free running timer, using trig0 as the source
-- Use trig0 to drive a free running counter for absolute timings
ext_clk <= trig(0);
timer1Process: process (ext_clk)
begin
if rising_edge(ext_clk) then
timer1Count <= timer1Count + 1;
end if;
end process;
cpuProcess: process (busmon_clk)
begin
if rising_edge(busmon_clk) then
timer0Count <= timer0Count + 1;
if busmon_clken = '1' then
-- Cycle counter, wraps every 16s at 1MHz
-- Cycle counter
if (cpu_reset_n = '0') then
cycleCount <= (others => '0');
elsif (CountCycle = '1') then
elsif (CountCycle = '1' or timer_mode(0) = '1') then
cycleCount <= cycleCount + 1;
end if;
-- Command processing
cmd_edge1 <= cmd_edge;
cmd_edge2 <= cmd_edge1;
@ -479,60 +499,68 @@ begin
exec <= '0';
SS_Step <= '0';
if (cmd_edge2 /= cmd_edge1) then
if (cmd(4 downto 1) = "0000") then
if (cmd(5 downto 1) = "00000") then
single <= cmd(0);
end if;
if (cmd(4 downto 1) = "0001") then
if (cmd(5 downto 1) = "00001") then
brkpt_enable <= cmd(0);
end if;
if (cmd(4 downto 1) = "0010") then
if (cmd(5 downto 1) = "00010") then
brkpt_reg <= cmd(0) & brkpt_reg(brkpt_reg'length - 1 downto 1);
end if;
if (cmd(4 downto 1) = "0110") then
if (cmd(5 downto 1) = "00110") then
addr_dout_reg <= cmd(0) & addr_dout_reg(addr_dout_reg'length - 1 downto 1);
end if;
if (cmd(4 downto 1) = "0011") then
if (cmd(5 downto 1) = "00011") then
reset <= cmd(0);
end if;
if (cmd(4 downto 0) = "01001") then
if (cmd(5 downto 0) = "01001") then
fifo_rd <= '1';
end if;
if (cmd(4 downto 0) = "01010") then
if (cmd(5 downto 0) = "01010") then
fifo_rst <= '1';
end if;
if (cmd(4 downto 1) = "1000") then
if (cmd(5 downto 1) = "01000") then
memory_rd <= '1';
auto_inc <= cmd(0);
end if;
if (cmd(4 downto 1) = "1001") then
if (cmd(5 downto 1) = "01001") then
memory_wr <= '1';
auto_inc <= cmd(0);
end if;
if (cmd(4 downto 1) = "1010") then
if (cmd(5 downto 1) = "01010") then
io_rd <= '1';
auto_inc <= cmd(0);
end if;
if (cmd(4 downto 1) = "1011") then
if (cmd(5 downto 1) = "01011") then
io_wr <= '1';
auto_inc <= cmd(0);
end if;
if (cmd(4 downto 0) = "11000") then
if (cmd(5 downto 0) = "011000") then
exec <= '1';
end if;
if (cmd(5 downto 4) = "10") then
int_ctrl(to_integer(unsigned(cmd(3 downto 2))) * 2 + 1 downto to_integer(unsigned(cmd(3 downto 2))) * 2) <= cmd(1 downto 0);
end if;
if (cmd(5 downto 2) = "1100") then
timer_mode <= cmd(1 downto 0);
end if;
-- Acknowlege certain commands immediately
if cmd(4) = '0' then
if cmd(5 downto 4) /= "01" then
cmd_ack <= not cmd_ack;
end if;
@ -552,7 +580,7 @@ begin
single <= '1';
end if;
if ((single = '0') or (cmd_edge2 /= cmd_edge1 and cmd = "01000")) then
if ((single = '0') or (cmd_edge2 /= cmd_edge1 and cmd = "001000")) then
Rdy_int <= (not brkpt_active);
SS_Step <= (not brkpt_active);
else
@ -562,7 +590,13 @@ begin
-- Latch instruction address for the whole cycle
if (Sync = '1') then
addr_inst <= Addr;
cycleCount_inst <= cycleCount;
if timer_mode = "10" then
instrCount <= timer0Count;
elsif timer_mode = "11" then
instrCount <= timer1Count;
else
instrCount <= cycleCount;
end if;
end if;
-- Breakpoints and Watches written to the FIFO

View File

@ -101,6 +101,7 @@ architecture behavioral of MC6809CpuMon is
signal Addr_int : std_logic_vector(15 downto 0);
signal Din : std_logic_vector(7 downto 0);
signal Dout : std_logic_vector(7 downto 0);
signal Dbusmon : std_logic_vector(7 downto 0);
signal Sync_int : std_logic;
signal hold : std_logic;
@ -123,7 +124,7 @@ architecture behavioral of MC6809CpuMon is
signal SS_Single : std_logic;
signal SS_Step : std_logic;
signal CountCycle : std_logic;
signal special : std_logic_vector(1 downto 0);
signal int_ctrl : std_logic_vector(7 downto 0);
signal LIC_int : std_logic;
@ -139,9 +140,10 @@ architecture behavioral of MC6809CpuMon is
signal data_wr : std_logic;
signal nRSTout : std_logic;
signal NMI_n_masked : std_logic;
signal IRQ_n_masked : std_logic;
signal FIRQ_n_masked : std_logic;
signal IRQ_n_masked : std_logic;
signal NMI_n_masked : std_logic;
signal RES_n_masked : std_logic;
begin
@ -176,14 +178,14 @@ begin
cpu_clk => cpu_clk,
cpu_clken => '1',
Addr => Addr_int,
Data => Data,
Data => Dbusmon,
Rd_n => not R_W_n_int,
Wr_n => R_W_n_int,
RdIO_n => '1',
WrIO_n => '1',
Sync => Sync_int,
Rdy => open,
nRSTin => RES_n,
nRSTin => RES_n_masked,
nRSTout => cpu_reset_n,
CountCycle => CountCycle,
trig => trig,
@ -206,14 +208,28 @@ begin
DataOut => memory_dout,
DataIn => memory_din,
Done => memory_done,
Special => special,
int_ctrl => int_ctrl,
SS_Step => SS_Step,
SS_Single => SS_Single
);
NMI_n_masked <= NMI_n or special(1);
FIRQ_n_masked <= FIRQ_n or special(1);
IRQ_n_masked <= IRQ_n or special(0);
-- The two int control bits work as follows
-- 00 -> IRQ_n (enabled)
-- 01 -> IRQ_n or SS_Single (enabled when free-running)
-- 10 -> 0 (forced)
-- 11 -> 1 (disabled)
FIRQ_n_masked <= int_ctrl(0) when int_ctrl(1) = '1' else
FIRQ_n or (int_ctrl(0) and SS_single);
IRQ_n_masked <= int_ctrl(2) when int_ctrl(3) = '1' else
IRQ_n or (int_ctrl(2) and SS_single);
NMI_n_masked <= int_ctrl(4) when int_ctrl(5) = '1' else
NMI_n or (int_ctrl(4) and SS_single);
RES_n_masked <= int_ctrl(6) when int_ctrl(7) = '1' else
RES_n or (int_ctrl(6) and SS_single);
-- The CPU is slightly pipelined and the register update of the last
-- instruction overlaps with the opcode fetch of the next instruction.
@ -339,6 +355,13 @@ begin
Dout when TSC = '0' and data_wr = '1' and R_W_n_int = '0' and memory_rd1 = '0' else
(others => 'Z');
-- Version of data seen by the Bus Mon need to use Din rather than the
-- external bus value as by the rising edge of cpu_clk we will have stopped driving
-- the external bus. On the ALS version we get away way this, but on the GODIL
-- version, due to the pullups, we don't. So all write watch breakpoints see
-- the data bus as 0xFF.
Dbusmon <= Din when R_W_n_int = '1' else Dout;
memory_done <= memory_rd1 or memory_wr1;
-- Delayed/Deglitched version of the E clock

View File

@ -69,7 +69,10 @@ entity MOS6502CpuMon is
-- OHO_DY1 connected to test connector
tmosi : out std_logic;
tdin : out std_logic;
tcclk : out std_logic
tcclk : out std_logic;
-- Test connector signals
test : inout std_logic_vector(3 downto 0)
);
end MOS6502CpuMon;
@ -141,7 +144,8 @@ begin
led_trig1 => led_trig1,
tmosi => tmosi,
tdin => tdin,
tcclk => tcclk
tcclk => tcclk,
test => test
);
sync_gen : process(cpu_clk)

View File

@ -90,7 +90,10 @@ entity MOS6502CpuMonALS is
-- OHO_DY1 LED display
tmosi : out std_logic;
tdin : out std_logic;
tcclk : out std_logic
tcclk : out std_logic;
-- Test connector signals
test : inout std_logic_vector(3 downto 0)
);
end MOS6502CpuMonALS;
@ -166,7 +169,10 @@ begin
-- OHO_DY1 LED display
tmosi => tmosi,
tdin => tdin,
tcclk => tcclk
tcclk => tcclk,
-- Test signals
test => test
);
-- 6502 Outputs

View File

@ -67,7 +67,10 @@ entity MOS6502CpuMonCore is
-- OHO_DY1 connected to test connector
tmosi : out std_logic;
tdin : out std_logic;
tcclk : out std_logic
tcclk : out std_logic;
-- Test connector signals
test : inout std_logic_vector(3 downto 0)
);
end MOS6502CpuMonCore;
@ -82,8 +85,10 @@ architecture behavioral of MOS6502CpuMonCore is
signal Din_int : std_logic_vector(7 downto 0);
signal Dout_int : std_logic_vector(7 downto 0);
signal R_W_n_int : std_logic;
signal Rd_n_int : std_logic;
signal Wr_n_int : std_logic;
signal Rd_n_mon : std_logic;
signal Wr_n_mon : std_logic;
signal Sync_mon : std_logic;
signal Done_mon : std_logic;
signal Sync_int : std_logic;
signal Addr_int : std_logic_vector(23 downto 0);
@ -98,7 +103,7 @@ architecture behavioral of MOS6502CpuMonCore is
signal SS_Step : std_logic;
signal SS_Step_held : std_logic;
signal CountCycle : std_logic;
signal special : std_logic_vector(1 downto 0);
signal int_ctrl : std_logic_vector(7 downto 0);
signal memory_rd : std_logic;
signal memory_rd1 : std_logic;
@ -109,8 +114,11 @@ architecture behavioral of MOS6502CpuMonCore is
signal memory_din : std_logic_vector(7 downto 0);
signal memory_done : std_logic;
signal NMI_n_masked : std_logic;
signal IRQ_n_masked : std_logic;
signal NMI_n_masked : std_logic;
signal Res_n_masked : std_logic;
signal SO_n_masked : std_logic;
signal exec : std_logic;
signal exec_held : std_logic;
@ -131,13 +139,13 @@ begin
cpu_clken => cpu_clken,
Addr => Addr_int(15 downto 0),
Data => Data,
Rd_n => Rd_n_int,
Wr_n => Wr_n_int,
Rd_n => Rd_n_mon,
Wr_n => Wr_n_mon,
RdIO_n => '1',
WrIO_n => '1',
Sync => Sync_int,
Sync => Sync_mon,
Rdy => open,
nRSTin => Res_n,
nRSTin => Res_n_masked,
nRSTout => cpu_reset_n,
CountCycle => CountCycle,
trig => trig,
@ -160,16 +168,35 @@ begin
AddrOut => memory_addr,
DataOut => memory_dout,
DataIn => memory_din,
Done => memory_done,
Special => special,
Done => Done_mon,
int_ctrl => int_ctrl,
SS_Step => SS_Step,
SS_Single => SS_Single
);
Wr_n_int <= R_W_n_int;
Rd_n_int <= not R_W_n_int;
Wr_n_mon <= Rdy and R_W_n_int;
Rd_n_mon <= Rdy and not R_W_n_int;
Sync_mon <= Rdy and Sync_int;
Done_mon <= Rdy and memory_done;
Data <= Din when R_W_n_int = '1' else Dout_int;
NMI_n_masked <= NMI_n or special(1);
IRQ_n_masked <= IRQ_n or special(0);
-- The two int control bits work as follows
-- 00 -> IRQ_n (enabled)
-- 01 -> IRQ_n or SS_Single (enabled when free-running)
-- 10 -> 0 (forced)
-- 11 -> 1 (disabled)
IRQ_n_masked <= int_ctrl(0) when int_ctrl(1) = '1' else
IRQ_n or (int_ctrl(0) and SS_single);
NMI_n_masked <= int_ctrl(2) when int_ctrl(3) = '1' else
NMI_n or (int_ctrl(2) and SS_single);
Res_n_masked <= int_ctrl(4) when int_ctrl(5) = '1' else
Res_n or (int_ctrl(4) and SS_single);
SO_n_masked <= int_ctrl(6) when int_ctrl(7) = '1' else
SO_n or (int_ctrl(6) and SS_single);
-- The CPU is slightly pipelined and the register update of the last
-- instruction overlaps with the opcode fetch of the next instruction.
@ -204,7 +231,7 @@ begin
inst_t65: entity work.T65 port map (
mode => "00",
Abort_n => '1',
SO_n => SO_n,
SO_n => SO_n_masked,
Res_n => cpu_reset_n,
Enable => cpu_clken_ss,
Clk => cpu_clk,
@ -367,4 +394,10 @@ begin
memory_din <= Din;
-- Test outputs
test(0) <= SS_Single; -- GODIL J5 pin 1 (46)
test(1) <= 'Z'; -- GODIL J5 pin 2 (47)
test(2) <= 'Z'; -- GODIL J5 pin 3 (48)
test(3) <= 'Z'; -- GODIL J5 pin 4 (56)
end behavioral;

View File

@ -21,7 +21,7 @@
-- ****
-- Z80 compatible microprocessor core
--
-- Version : 0247
-- Version : 0250
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
-- All rights reserved
--
@ -73,14 +73,14 @@
-- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode
-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM
-- 0247 : Fixed bus req/ack cycle
-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use work.all;
use work.T80_Pack.all;
entity T80 is
generic(
@ -120,6 +120,7 @@ entity T80 is
NMICycle_n : out std_logic;
IntE : out std_logic;
Stop : out std_logic;
R800_mode : in std_logic := '0';
out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
@ -129,136 +130,6 @@ entity T80 is
end T80;
architecture rtl of T80 is
component T80_MCode
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
IR : in std_logic_vector(7 downto 0);
ISet : in std_logic_vector(1 downto 0);
MCycle : in std_logic_vector(2 downto 0);
F : in std_logic_vector(7 downto 0);
NMICycle : in std_logic;
IntCycle : in std_logic;
XY_State : in std_logic_vector(1 downto 0);
MCycles : out std_logic_vector(2 downto 0);
TStates : out std_logic_vector(2 downto 0);
Prefix : out std_logic_vector(1 downto 0); -- None,CB,ED,DD/FD
Inc_PC : out std_logic;
Inc_WZ : out std_logic;
IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
Read_To_Reg : out std_logic;
Read_To_Acc : out std_logic;
Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
ALU_Op : out std_logic_vector(3 downto 0);
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
Save_ALU : out std_logic;
PreserveC : out std_logic;
Arith16 : out std_logic;
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
IORQ : out std_logic;
Jump : out std_logic;
JumpE : out std_logic;
JumpXY : out std_logic;
Call : out std_logic;
RstP : out std_logic;
LDZ : out std_logic;
LDW : out std_logic;
LDSPHL : out std_logic;
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
ExchangeDH : out std_logic;
ExchangeRp : out std_logic;
ExchangeAF : out std_logic;
ExchangeRS : out std_logic;
I_DJNZ : out std_logic;
I_CPL : out std_logic;
I_CCF : out std_logic;
I_SCF : out std_logic;
I_RETN : out std_logic;
I_BT : out std_logic;
I_BC : out std_logic;
I_BTR : out std_logic;
I_RLD : out std_logic;
I_RRD : out std_logic;
I_INRC : out std_logic;
SetWZ : out std_logic_vector(1 downto 0);
SetDI : out std_logic;
SetEI : out std_logic;
IMode : out std_logic_vector(1 downto 0);
Halt : out std_logic;
NoRead : out std_logic;
Write : out std_logic;
XYbit_undoc : out std_logic
);
end component;
component T80_ALU
generic(
Mode : integer := 0;
Flag_C : integer := 0;
Flag_N : integer := 1;
Flag_P : integer := 2;
Flag_X : integer := 3;
Flag_H : integer := 4;
Flag_Y : integer := 5;
Flag_Z : integer := 6;
Flag_S : integer := 7
);
port(
Arith16 : in std_logic;
Z16 : in std_logic;
WZ : in std_logic_vector(15 downto 0);
XY_State : in std_logic_vector(1 downto 0);
ALU_Op : in std_logic_vector(3 downto 0);
IR : in std_logic_vector(5 downto 0);
ISet : in std_logic_vector(1 downto 0);
BusA : in std_logic_vector(7 downto 0);
BusB : in std_logic_vector(7 downto 0);
F_In : in std_logic_vector(7 downto 0);
Q : out std_logic_vector(7 downto 0);
F_Out : out std_logic_vector(7 downto 0)
);
end component;
component T80_Reg
port(
Clk : in std_logic;
CEN : in std_logic;
WEH : in std_logic;
WEL : in std_logic;
AddrA : in std_logic_vector(2 downto 0);
AddrB : in std_logic_vector(2 downto 0);
AddrC : in std_logic_vector(2 downto 0);
DIH : in std_logic_vector(7 downto 0);
DIL : in std_logic_vector(7 downto 0);
DOAH : out std_logic_vector(7 downto 0);
DOAL : out std_logic_vector(7 downto 0);
DOBH : out std_logic_vector(7 downto 0);
DOBL : out std_logic_vector(7 downto 0);
DOCH : out std_logic_vector(7 downto 0);
DOCL : out std_logic_vector(7 downto 0);
DOR : out std_logic_vector(127 downto 0);
DIRSet : in std_logic;
DIR : in std_logic_vector(127 downto 0)
);
end component;
constant aNone : std_logic_vector(2 downto 0) := "111";
constant aBC : std_logic_vector(2 downto 0) := "000";
constant aDE : std_logic_vector(2 downto 0) := "001";
constant aXY : std_logic_vector(2 downto 0) := "010";
constant aIOA : std_logic_vector(2 downto 0) := "100";
constant aSP : std_logic_vector(2 downto 0) := "101";
constant aZI : std_logic_vector(2 downto 0) := "110";
-- Registers
signal ACC, F : std_logic_vector(7 downto 0);
@ -283,9 +154,13 @@ architecture rtl of T80 is
-- Help Registers
signal WZ : std_logic_vector(15 downto 0); -- MEMPTR register
signal TmpAddr2 : std_logic_vector(15 downto 0); -- Temporary address register
signal IR : std_logic_vector(7 downto 0); -- Instruction register
signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector
signal RegBusA_r : std_logic_vector(15 downto 0);
signal MULU_Prod32 : std_logic_vector(31 downto 0);
signal MULU_tmp : std_logic_vector(31 downto 0);
signal MULU_Fakt1 : std_logic_vector(15 downto 0);
signal ID16 : signed(15 downto 0);
signal Save_Mux : std_logic_vector(7 downto 0);
@ -295,8 +170,8 @@ architecture rtl of T80 is
signal IntE_FF1 : std_logic;
signal IntE_FF2 : std_logic;
signal Halt_FF : std_logic;
signal BusReq_s : std_logic;
signal BusAck : std_logic;
signal BusReq_s : std_logic := '0';
signal BusAck : std_logic := '0';
signal ClkEn : std_logic;
signal NMI_s : std_logic;
signal IStatus : std_logic_vector(1 downto 0);
@ -344,6 +219,7 @@ architecture rtl of T80 is
signal Set_BusA_To : std_logic_vector(3 downto 0);
signal ALU_Op : std_logic_vector(3 downto 0);
signal Save_ALU : std_logic;
signal Rot_Akku : std_logic;
signal PreserveC : std_logic;
signal Arith16 : std_logic;
signal Set_Addr_To : std_logic_vector(2 downto 0);
@ -355,6 +231,8 @@ architecture rtl of T80 is
signal LDZ : std_logic;
signal LDW : std_logic;
signal LDSPHL : std_logic;
signal LDHLSP : std_logic;
signal ADDSPdd : std_logic;
signal IORQ_i : std_logic;
signal Special_LD : std_logic_vector(2 downto 0);
signal ExchangeDH : std_logic;
@ -373,12 +251,15 @@ architecture rtl of T80 is
signal I_RRD : std_logic;
signal I_RXDD : std_logic;
signal I_INRC : std_logic;
signal I_MULUB : std_logic;
signal I_MULU : std_logic;
signal SetWZ : std_logic_vector(1 downto 0);
signal SetDI : std_logic;
signal SetEI : std_logic;
signal IMode : std_logic_vector(1 downto 0);
signal Halt : std_logic;
signal XYbit_undoc : std_logic;
signal No_PC : std_logic;
signal DOR : std_logic_vector(127 downto 0);
begin
@ -418,6 +299,7 @@ begin
Set_BusA_To => Set_BusA_To,
ALU_Op => ALU_Op,
Save_ALU => Save_ALU,
Rot_Akku => Rot_Akku,
PreserveC => PreserveC,
Arith16 => Arith16,
Set_Addr_To => Set_Addr_To,
@ -430,6 +312,8 @@ begin
LDZ => LDZ,
LDW => LDW,
LDSPHL => LDSPHL,
LDHLSP => LDHLSP,
ADDSPdd => ADDSPdd,
Special_LD => Special_LD,
ExchangeDH => ExchangeDH,
ExchangeRp => ExchangeRp,
@ -446,6 +330,8 @@ begin
I_RLD => I_RLD,
I_RRD => I_RRD,
I_INRC => I_INRC,
I_MULUB => I_MULUB,
I_MULU => I_MULU,
SetWZ => SetWZ,
SetDI => SetDI,
SetEI => SetEI,
@ -453,6 +339,8 @@ begin
Halt => Halt,
NoRead => NoRead,
Write => Write,
R800_mode => R800_mode,
No_PC => No_PC,
XYbit_undoc => XYbit_undoc);
alu : T80_ALU
@ -472,6 +360,7 @@ begin
WZ => WZ,
XY_State=> XY_State,
ALU_Op => ALU_Op_r,
Rot_Akku => Rot_Akku,
IR => IR(5 downto 0),
ISet => ISet,
BusA => BusA,
@ -496,6 +385,8 @@ begin
process (RESET_n, CLK_n)
variable n : std_logic_vector(7 downto 0);
variable ioq : std_logic_vector(8 downto 0);
variable temp_c : unsigned(8 downto 0);
variable temp_h : unsigned(4 downto 0);
begin
if RESET_n = '0' then
PC <= (others => '0'); -- Program Counter
@ -510,6 +401,11 @@ begin
ACC <= (others => '1');
F <= (others => '1');
if Mode = 3 then
ACC <= (others => '0');
F <= "11110000";
end if;
Ap <= (others => '1');
Fp <= (others => '1');
I <= (others => '0');
@ -548,7 +444,27 @@ begin
MCycles <= MCycles_d;
if IMode /= "11" then
if LDHLSP = '1' and MCycle = "011" and TState = 1 then
temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux);
temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0));
F(Flag_Z) <= '0';
F(Flag_N) <= '0';
F(Flag_H) <= temp_h(4);
F(Flag_C) <= temp_c(8);
end if;
if ADDSPdd = '1' and TState = 1 then
temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux);
temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0));
F(Flag_Z) <= '0';
F(Flag_N) <= '0';
F(Flag_H) <= temp_h(4);
F(Flag_C) <= temp_c(8);
end if;
if Mode = 3 then
IStatus <= "10";
elsif IMode /= "11" then
IStatus <= IMode;
end if;
@ -582,6 +498,11 @@ begin
IR <= DInst;
end if;
if Mode <= 1 and IntCycle = '1' and IStatus = "10" then
-- IM2 vector address low byte from bus
WZ(7 downto 0) <= DInst;
end if;
ISet <= "00";
if Prefix /= "00" then
if Prefix = "11" then
@ -629,7 +550,8 @@ begin
elsif MCycle = MCycles and NMICycle = '1' then
A <= "0000000001100110";
PC <= "0000000001100110";
elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then
elsif ((Mode /= 3 and MCycle = "011") or (Mode = 3 and MCycle = "100"))
and IntCycle = '1' and IStatus = "10" then
A(15 downto 8) <= I;
A(7 downto 0) <= WZ(7 downto 0);
PC(15 downto 8) <= unsigned(I);
@ -693,7 +615,12 @@ begin
end if;
end if;
when others =>
if ISet = "10" and IR(7 downto 4) = x"B" and IR(2 downto 1) = "01" and MCycle = 3 and No_BTR = '0' then
-- INIR, INDR, OTIR, OTDR
A <= RegBusA_r;
elsif No_PC = '0' or No_BTR = '1' or (I_DJNZ = '1' and IncDecZ = '1') or Mode > 1 then
A <= std_logic_vector(PC);
end if;
end case;
end if;
@ -704,6 +631,26 @@ begin
Save_ALU_r <= Save_ALU;
ALU_Op_r <= ALU_Op;
if Mode = 3 then
if I_CPL = '1' then
-- CPL
ACC <= not ACC;
F(Flag_H) <= '1';
F(Flag_N) <= '1';
end if;
if I_CCF = '1' then
-- CCF
F(Flag_C) <= not F(Flag_C);
F(Flag_H) <= '0';
F(Flag_N) <= '0';
end if;
if I_SCF = '1' then
-- SCF
F(Flag_C) <= '1';
F(Flag_H) <= '0';
F(Flag_N) <= '0';
end if;
else
if I_CPL = '1' then
-- CPL
ACC <= not ACC;
@ -729,6 +676,7 @@ begin
F(Flag_N) <= '0';
end if;
end if;
end if;
if (TState = 2 and I_BTR = '1' and IR(0) = '1') or (TState = 1 and I_BTR = '1' and IR(0) = '0') then
ioq := ('0' & DI_Reg) + ('0' & std_logic_vector(ID16(7 downto 0)));
@ -777,6 +725,11 @@ begin
end if;
end if;
if ADDSPdd = '1' and TState = 2 then
WZ <= std_logic_vector(SP);
SP <= unsigned(signed(SP)+signed(Save_Mux));
end if;
if LDSPHL = '1' then
SP <= unsigned(RegBusC);
end if;
@ -924,7 +877,12 @@ begin
when "11001" =>
SP(15 downto 8) <= unsigned(Save_Mux);
when "11011" =>
if Mode = 3 then
F(7 downto 4) <= Save_Mux(7 downto 4);
F(3 downto 0) <= "0000"; -- bit 3 to 0 always return 0
else
F <= Save_Mux;
end if;
when others =>
end case;
if XYbit_undoc='1' then
@ -935,6 +893,42 @@ begin
end if;
end process;
---------------------------------------------------------------------------
--
-- Multiply
--
---------------------------------------------------------------------------
process (CLK_n, ACC, RegBusB, MULU_tmp, MULU_Fakt1, MULU_Prod32)
begin
MULU_tmp(31 downto 12) <= std_logic_vector((unsigned(MULU_Fakt1)*unsigned(MULU_Prod32(3 downto 0)))+unsigned("0000"&MULU_Prod32(31 downto 16)));
MULU_tmp(11 downto 0) <= MULU_Prod32(15 downto 4);
if rising_edge(CLK_n) then
if ClkEn = '1' then
if T_Res='1' then
if I_MULUB='1' then
MULU_Prod32(7 downto 0) <= ACC;
MULU_Prod32(15 downto 8) <= "--------";
MULU_Prod32(31 downto 16) <= X"0000";
MULU_Fakt1(7 downto 0) <= "00000000";
if Set_BusB_To(0) = '1' then
MULU_Fakt1(15 downto 8) <= RegBusB(7 downto 0);
else
MULU_Fakt1(15 downto 8) <= RegBusB(15 downto 8);
end if;
else
MULU_Prod32(15 downto 0) <= RegBusA;
MULU_Prod32(31 downto 16) <= X"0000";
MULU_Fakt1 <= RegBusB;
end if;
else
MULU_Prod32 <= MULU_tmp;
end if;
end if;
end if;
end process;
---------------------------------------------------------------------------
--
-- BC('), DE('), HL('), IX and IY
@ -990,7 +984,9 @@ begin
(TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else
-- EX HL,DL
Alternate & "10" when ExchangeDH = '1' and TState = 3 else
Alternate & "01" when ExchangeDH = '1' and TState = 4 else
Alternate & "01" when (ExchangeDH = '1' or I_MULU = '1') and TState = 4 else
-- LDHLSP
"010" when LDHLSP = '1' and TState = 4 else
-- Bus A / Write
RegAddrA_r;
@ -1003,8 +999,8 @@ begin
ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else
signed(RegBusA) + 1;
process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r,
ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, I_MULU, T_Res,
ExchangeDH, IncDec_16, MCycle, TState, Wait_n, LDHLSP)
begin
RegWEH <= '0';
RegWEL <= '0';
@ -1018,11 +1014,21 @@ begin
end case;
end if;
if I_MULU = '1' and (T_Res = '1' or TState = 4) then -- TState = 4 DE write
RegWEH <= '1';
RegWEL <= '1';
end if;
if ExchangeDH = '1' and (TState = 3 or TState = 4) then
RegWEH <= '1';
RegWEL <= '1';
end if;
if LDHLSP = '1' and MCycle = "010" and TState = 4 then
RegWEH <= '1';
RegWEL <= '1';
end if;
if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then
case IncDec_16(1 downto 0) is
when "00" | "01" | "10" =>
@ -1033,12 +1039,29 @@ begin
end if;
end process;
process (Save_Mux, RegBusB, RegBusA_r, ID16,
ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
TmpAddr2 <= std_logic_vector(unsigned(signed(SP) + signed(Save_Mux)));
process (Save_Mux, RegBusB, RegBusA_r, ID16, I_MULU, MULU_Prod32, MULU_tmp, T_Res,
ExchangeDH, IncDec_16, MCycle, TState, Wait_n, LDHLSP, TmpAddr2)
begin
RegDIH <= Save_Mux;
RegDIL <= Save_Mux;
if I_MULU = '1' then
if T_Res = '1' then
RegDIH <= MULU_Prod32(31 downto 24);
RegDIL <= MULU_Prod32(23 downto 16);
else
RegDIH <= MULU_tmp(15 downto 8); -- TState = 4 DE write
RegDIL <= MULU_tmp(7 downto 0);
end if;
end if;
if LDHLSP = '1' and MCycle = "010" and TState = 4 then
RegDIH <= TmpAddr2(15 downto 8);
RegDIL <= TmpAddr2(7 downto 0);
end if;
if ExchangeDH = '1' and TState = 3 then
RegDIH <= RegBusB(15 downto 8);
RegDIL <= RegBusB(7 downto 0);
@ -1169,13 +1192,12 @@ begin
TS <= std_logic_vector(TState);
DI_Reg <= DI;
HALT_n <= not Halt_FF;
BUSAK_n <= not BusAck;
BUSAK_n <= not (BusAck and RESET_n);
IntCycle_n <= not IntCycle;
NMICycle_n <= not NMICycle;
IntE <= IntE_FF1;
IORQ <= IORQ_i;
Stop <= I_DJNZ;
-------------------------------------------------------------------------
--
-- Main state machine
@ -1189,7 +1211,7 @@ begin
TState <= "000";
Pre_XY_F_M <= "000";
Halt_FF <= '0';
BusAck <= '0';
--BusAck <= '0';
NMICycle <= '0';
IntCycle <= '0';
IntE_FF1 <= '0';
@ -1198,10 +1220,9 @@ begin
Auto_Wait_t1 <= '0';
Auto_Wait_t2 <= '0';
M1_n <= '1';
BusReq_s <= '0';
--BusReq_s <= '0';
NMI_s <= '0';
elsif rising_edge(CLK_n) then
if DIRSet = '1' then
IntE_FF2 <= DIR(211);
IntE_FF1 <= DIR(210);
@ -1249,13 +1270,20 @@ begin
BusAck <= '0';
if TState = 2 and Wait_n = '0' then
elsif T_Res = '1' then
if Halt = '1' then
if Halt = '1' and ( not(Mode = 3 and INT_n = '0' and IntE_FF1 = '0')) then -- halt bug when Mode = 3 , INT_n = '0' and IME=0
Halt_FF <= '1';
end if;
if BusReq_s = '1' then
BusAck <= '1';
else
TState <= "001";
if (IntCycle = '1' and Mode = 3) then -- GB: read interrupt at MCycle 3
if (MCycle = "010") then
M1_n <= '0';
else
M1_n <= '1';
end if;
end if;
if NextIs_XY_Fetch = '1' then
MCycle <= "110";
Pre_XY_F_M <= MCycle;
@ -1277,6 +1305,8 @@ begin
IntCycle <= '1';
IntE_FF1 <= '0';
IntE_FF2 <= '0';
elsif (Halt_FF = '1' and INT_n = '0' and Mode = 3) then
Halt_FF <= '0';
end if;
else
MCycle <= std_logic_vector(unsigned(MCycle) + 1);

View File

@ -89,6 +89,7 @@ entity T80_ALU is
WZ : in std_logic_vector(15 downto 0);
XY_State : in std_logic_vector(1 downto 0);
ALU_Op : in std_logic_vector(3 downto 0);
Rot_Akku : in std_logic;
IR : in std_logic_vector(5 downto 0);
ISet : in std_logic_vector(1 downto 0);
BusA : in std_logic_vector(7 downto 0);
@ -158,7 +159,7 @@ begin
end if;
end process;
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, WZ, XY_State)
process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, Rot_Akku, WZ, XY_State)
variable Q_t : std_logic_vector(7 downto 0);
variable DAA_Q : unsigned(8 downto 0);
begin
@ -220,6 +221,34 @@ begin
end if;
when "1100" =>
-- DAA
if Mode = 3 then
F_Out(Flag_H) <= '0';
F_Out(Flag_C) <= F_In(Flag_C);
DAA_Q(7 downto 0) := unsigned(BusA);
DAA_Q(8) := '0';
if F_In(Flag_N) = '0' then
-- After addition
-- Alow > 9 or H = 1
if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then
DAA_Q := DAA_Q + 6;
end if;
-- new Ahigh > 9 or C = 1
if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then
DAA_Q := DAA_Q + 96; -- 0x60
end if;
else
-- After subtraction
if F_In(Flag_H) = '1' then
DAA_Q := DAA_Q - 6;
if F_In(Flag_C) = '0' then
DAA_Q(8) := '0';
end if;
end if;
if F_In(Flag_C) = '1' then
DAA_Q := DAA_Q - 96; -- 0x60
end if;
end if;
else
F_Out(Flag_H) <= F_In(Flag_H);
F_Out(Flag_C) <= F_In(Flag_C);
DAA_Q(7 downto 0) := unsigned(BusA);
@ -251,6 +280,7 @@ begin
DAA_Q := DAA_Q - 352; -- 0x160
end if;
end if;
end if;
F_Out(Flag_X) <= DAA_Q(3);
F_Out(Flag_Y) <= DAA_Q(5);
F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8);
@ -368,6 +398,9 @@ begin
F_Out(Flag_S) <= F_In(Flag_S);
F_Out(Flag_Z) <= F_In(Flag_Z);
end if;
if Mode = 3 and Rot_Akku = '1' then
F_Out(Flag_Z) <= '0';
end if;
when others =>
null;
end case;

View File

@ -19,7 +19,7 @@
-- ****
-- Z80 compatible microprocessor core
--
-- Version : 0242
-- Version : 0250
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
-- All rights reserved
--
@ -69,11 +69,13 @@
-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes
-- 0240mj1 fix for HL inc/dec for INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR
-- 0242 : Fixed I/O instruction timing, cleanup
-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.T80_Pack.all;
entity T80_MCode is
generic(
@ -108,6 +110,7 @@ entity T80_MCode is
ALU_Op : out std_logic_vector(3 downto 0);
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
Save_ALU : out std_logic;
Rot_Akku : out std_logic;
PreserveC : out std_logic;
Arith16 : out std_logic;
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
@ -120,6 +123,8 @@ entity T80_MCode is
LDZ : out std_logic;
LDW : out std_logic;
LDSPHL : out std_logic;
LDHLSP : out std_logic;
ADDSPdd : out std_logic;
Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
ExchangeDH : out std_logic;
ExchangeRp : out std_logic;
@ -136,6 +141,8 @@ entity T80_MCode is
I_RLD : out std_logic;
I_RRD : out std_logic;
I_INRC : out std_logic;
I_MULUB : out std_logic;
I_MULU : out std_logic;
SetWZ : out std_logic_vector(1 downto 0);
SetDI : out std_logic;
SetEI : out std_logic;
@ -143,20 +150,14 @@ entity T80_MCode is
Halt : out std_logic;
NoRead : out std_logic;
Write : out std_logic;
R800_mode : in std_logic;
No_PC : out std_logic;
XYbit_undoc : out std_logic
);
end T80_MCode;
architecture rtl of T80_MCode is
constant aNone : std_logic_vector(2 downto 0) := "111";
constant aBC : std_logic_vector(2 downto 0) := "000";
constant aDE : std_logic_vector(2 downto 0) := "001";
constant aXY : std_logic_vector(2 downto 0) := "010";
constant aIOA : std_logic_vector(2 downto 0) := "100";
constant aSP : std_logic_vector(2 downto 0) := "101";
constant aZI : std_logic_vector(2 downto 0) := "110";
function is_cc_true(
F : std_logic_vector(7 downto 0);
cc : bit_vector(2 downto 0)
@ -164,10 +165,10 @@ architecture rtl of T80_MCode is
begin
if Mode = 3 then
case cc is
when "000" => return F(Flag_S) = '0'; -- NZ
when "001" => return F(Flag_S) = '1'; -- Z
when "010" => return F(Flag_H) = '0'; -- NC
when "011" => return F(Flag_H) = '1'; -- C
when "000" => return F(Flag_Z) = '0'; -- NZ
when "001" => return F(Flag_Z) = '1'; -- Z
when "010" => return F(Flag_C) = '0'; -- NC
when "011" => return F(Flag_C) = '1'; -- C
when "100" => return false;
when "101" => return false;
when "110" => return false;
@ -189,7 +190,7 @@ architecture rtl of T80_MCode is
begin
process (IR, ISet, MCycle, F, NMICycle, IntCycle, XY_State)
process (IR, ISet, MCycle, F, NMICycle, IntCycle, XY_State, R800_mode)
variable DDD : std_logic_vector(2 downto 0);
variable SSS : std_logic_vector(2 downto 0);
variable DPair : std_logic_vector(1 downto 0);
@ -216,6 +217,7 @@ begin
Set_BusA_To <= "0000";
ALU_Op <= "0" & IR(5 downto 3);
Save_ALU <= '0';
Rot_Akku <= '0';
PreserveC <= '0';
Arith16 <= '0';
IORQ <= '0';
@ -228,6 +230,8 @@ begin
LDZ <= '0';
LDW <= '0';
LDSPHL <= '0';
LDHLSP <= '0';
ADDSPdd <= '0';
Special_LD <= "000";
ExchangeDH <= '0';
ExchangeRp <= '0';
@ -244,12 +248,15 @@ begin
I_RLD <= '0';
I_RRD <= '0';
I_INRC <= '0';
I_MULUB <= '0';
I_MULU <= '0';
SetDI <= '0';
SetEI <= '0';
IMode <= "11";
Halt <= '0';
NoRead <= '0';
Write <= '0';
No_PC <= '0';
XYbit_undoc <= '0';
SetWZ <= "00";
@ -520,10 +527,47 @@ begin
end if;
when "11111001" =>
-- LD SP,HL
if Mode = 3 then
MCycles <= "010";
if MCycle = "010" then
LDSPHL <= '1';
end if;
else
TStates <= "110";
LDSPHL <= '1';
end if;
when "11000101"|"11010101"|"11100101"|"11110101" =>
-- PUSH qq
if Mode = 3 then
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_TO <= aSP;
if DPAIR = "11" then
Set_BusB_To <= "0111";
else
Set_BusB_To(2 downto 1) <= DPAIR;
Set_BusB_To(0) <= '0';
Set_BusB_To(3) <= '0';
end if;
when 3 =>
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
if DPAIR = "11" then
Set_BusB_To <= "1011";
else
Set_BusB_To(2 downto 1) <= DPAIR;
Set_BusB_To(0) <= '1';
Set_BusB_To(3) <= '0';
end if;
Write <= '1';
when 4 =>
Write <= '1';
when others => null;
end case;
else
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
@ -552,6 +596,7 @@ begin
Write <= '1';
when others => null;
end case;
end if;
when "11000001"|"11010001"|"11100001"|"11110001" =>
-- POP qq
MCycles <= "011";
@ -615,7 +660,7 @@ begin
when "11011001" =>
if Mode = 3 then
-- RETI
MCycles <= "011";
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_TO <= aSP;
@ -626,7 +671,7 @@ begin
when 3 =>
Jump <= '1';
IncDec_16 <= "0111";
I_RETN <= '1';
--I_RETN <= '1';
SetEI <= '1';
when others => null;
end case;
@ -643,82 +688,29 @@ begin
Set_Addr_To <= aSP;
when 2 =>
Read_To_Reg <= '1';
Set_BusA_To <= "0101"; -- L, target of Read_To_Reg
Set_BusB_To <= "0101"; -- L, input of ALU
Set_BusA_To <= "0101";
Set_BusB_To <= "0101";
Set_Addr_To <= aSP;
LDZ <= '1'; -- also load Z
LDZ <= '1';
when 3 =>
IncDec_16 <= "0111"; -- Increment SP
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
TStates <= "100";
Write <= '1';
when 4 =>
Read_To_Reg <= '1';
Set_BusA_To <= "0100"; -- H, target of Read_To_Reg
Set_BusB_To <= "0100"; -- H, input of ALU
Set_BusA_To <= "0100";
Set_BusB_To <= "0100";
Set_Addr_To <= aSP;
LDW <= '1'; -- also load Z
LDW <= '1';
when 5 =>
IncDec_16 <= "1111"; -- Decrement SP
IncDec_16 <= "1111";
TStates <= "101";
Write <= '1';
when others => null;
end case;
end if;
-- The T80 implementation does:
--
-- (4) M1 fetch
-- (3) M2 Read (SP) -> L, Z
-- L -> ALU
-- (4) M3 Write ALU result -> (SP)
-- SP++
-- (3) M4 Read (SP) -> H, W
-- H -> ALU
-- (5) M5 Write ALU result -> (SP)
-- SP--
--
-- The Z80 does
-- (4) M1 fetch
-- (3) M2 Read (SP) -> Z
-- SP++
-- (4) M3 Read (SP) -> W
-- (3) M4 Write H -> (SP)
-- SP--
-- (5) M5 Write L -> (SP)
--
-- and somehow WZ -> HL at the end!
--
-- Attempt at a new version.
--
-- case to_integer(unsigned(MCycle)) is
-- when 1 =>
-- Set_Addr_To <= aSP;
-- when 2 =>
-- IncDec_16 <= "0111";
-- Read_To_Reg <= '1';
-- Set_BusA_To <= "0101";
-- Set_BusB_To <= "0101";
-- Set_Addr_To <= aSP;
-- LDZ <= '1';
-- when 3 =>
-- Read_To_Reg <= '1';
-- Set_BusA_To <= "0100";
-- Set_BusB_To <= "0100";
-- Set_Addr_To <= aSP;
-- TStates <= "100";
-- LDW <= '1';
-- when 4 =>
-- IncDec_16 <= "1111";
-- Set_Addr_To <= aSP;
-- Write <= '1';
-- when 5 =>
-- TStates <= "101";
-- Write <= '1';
-- when others => null;
-- end case;
-- end if;
-- 8 BIT ARITHMETIC AND LOGICAL GROUP
when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111"
|"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111"
@ -869,10 +861,29 @@ begin
end case;
elsif IntCycle = '1' then
-- INT (IM 2)
if Mode = 3 then
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 1 =>
TStates <= "110";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 2 =>
Write <= '1';
when 3 => -- GB: interrupt is acknowledged on MCycle 3
LDZ <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 4 =>
Write <= '1';
when others => null;
end case;
else
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 1 =>
LDZ <= '1';
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
@ -893,6 +904,7 @@ begin
Jump <= '1';
when others => null;
end case;
end if;
else
-- NOP
end if;
@ -909,8 +921,45 @@ begin
-- 16 BIT ARITHMETIC GROUP
when "00001001"|"00011001"|"00101001"|"00111001" =>
-- ADD HL,ss
if Mode = 3 then
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
NoRead <= '1';
ALU_Op <= "0000";
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_BusA_To(2 downto 0) <= "101";
case to_integer(unsigned(IR(5 downto 4))) is
when 0|1|2 =>
Set_BusB_To(2 downto 1) <= IR(5 downto 4);
Set_BusB_To(0) <= '1';
when others =>
Set_BusB_To <= "1000";
end case;
TStates <= "100";
Arith16 <= '1';
SetWZ <= "11";
when 2 =>
NoRead <= '1';
Read_To_Reg <= '1';
Save_ALU <= '1';
ALU_Op <= "0001";
Set_BusA_To(2 downto 0) <= "100";
case to_integer(unsigned(IR(5 downto 4))) is
when 0|1|2 =>
Set_BusB_To(2 downto 1) <= IR(5 downto 4);
when others =>
Set_BusB_To <= "1001";
end case;
Arith16 <= '1';
when others =>
end case;
else
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
No_PC <= '1';
when 2 =>
NoRead <= '1';
ALU_Op <= "0000";
@ -927,6 +976,7 @@ begin
TStates <= "100";
Arith16 <= '1';
SetWZ <= "11";
No_PC <= '1';
when 3 =>
NoRead <= '1';
Read_To_Reg <= '1';
@ -942,16 +992,37 @@ begin
Arith16 <= '1';
when others =>
end case;
end if;
when "00000011"|"00010011"|"00100011"|"00110011" =>
-- INC ss
if Mode = 3 then
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 2 =>
IncDec_16(3 downto 2) <= "01";
IncDec_16(1 downto 0) <= DPair;
when others =>
end case;
else
TStates <= "110";
IncDec_16(3 downto 2) <= "01";
IncDec_16(1 downto 0) <= DPair;
end if;
when "00001011"|"00011011"|"00101011"|"00111011" =>
-- DEC ss
if Mode = 3 then
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 2 =>
IncDec_16(3 downto 2) <= "11";
IncDec_16(1 downto 0) <= DPair;
when others =>
end case;
else
TStates <= "110";
IncDec_16(3 downto 2) <= "11";
IncDec_16(1 downto 0) <= DPair;
end if;
-- ROTATE AND SHIFT GROUP
when "00000111"
@ -965,12 +1036,17 @@ begin
Set_BusA_To(2 downto 0) <= "111";
ALU_Op <= "1000";
Read_To_Reg <= '1';
Rot_Akku <= '1';
Save_ALU <= '1';
-- JUMP GROUP
when "11000011" =>
-- JP nn
if Mode = 3 then
MCycles <= "100";
else
MCycles <= "011";
end if;
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
@ -978,7 +1054,9 @@ begin
when 3 =>
Inc_PC <= '1';
Jump <= '1';
if Mode /= 3 then
LDW <= '1';
end if;
when others => null;
end case;
when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" =>
@ -991,9 +1069,9 @@ begin
when 1 =>
Set_Addr_To <= aBC;
Set_BusB_To <= "0111";
IORQ <= '1'; --TH must be earlier to be stable when address is generated
when 2 =>
Write <= '1';
IORQ <= '1';
when others =>
end case;
when "01" =>
@ -1017,9 +1095,9 @@ begin
case to_integer(unsigned(MCycle)) is
when 1 =>
Set_Addr_To <= aBC;
IORQ <= '1'; --TH must be earlier to be stable when address is generated
when 2 =>
Read_To_Acc <= '1';
IORQ <= '1';
when others =>
end case;
when "11" =>
@ -1039,16 +1117,24 @@ begin
end case;
else
-- JP cc,nn
if Mode = 3 then
MCycles <= "100";
else
MCycles <= "011";
end if;
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
if Mode /= 3 then
LDW <= '1';
end if;
Inc_PC <= '1';
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
Jump <= '1';
elsif Mode = 3 then
MCycles <= "011";
end if;
when others => null;
end case;
@ -1060,6 +1146,7 @@ begin
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
No_PC <= '1';
when 3 =>
NoRead <= '1';
JumpE <= '1';
@ -1076,6 +1163,8 @@ begin
Inc_PC <= '1';
if F(Flag_C) = '0' then
MCycles <= "010";
else
No_PC <= '1';
end if;
when 3 =>
NoRead <= '1';
@ -1093,6 +1182,8 @@ begin
Inc_PC <= '1';
if F(Flag_C) = '1' then
MCycles <= "010";
else
No_PC <= '1';
end if;
when 3 =>
NoRead <= '1';
@ -1110,6 +1201,8 @@ begin
Inc_PC <= '1';
if F(Flag_Z) = '0' then
MCycles <= "010";
else
No_PC <= '1';
end if;
when 3 =>
NoRead <= '1';
@ -1127,6 +1220,8 @@ begin
Inc_PC <= '1';
if F(Flag_Z) = '1' then
MCycles <= "010";
else
No_PC <= '1';
end if;
when 3 =>
NoRead <= '1';
@ -1139,8 +1234,14 @@ begin
-- JP (HL)
JumpXY <= '1';
when "00010000" =>
if Mode = 3 then
if Mode = 3 then -- STOP and skip next byte
MCycles <= "010";
I_DJNZ <= '1';
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
when others => null;
end case;
elsif Mode < 2 then
-- DJNZ,e
MCycles <= "011";
@ -1156,6 +1257,7 @@ begin
when 2 =>
I_DJNZ <= '1';
Inc_PC <= '1';
No_PC <= '1';
when 3 =>
NoRead <= '1';
JumpE <= '1';
@ -1167,7 +1269,11 @@ begin
-- CALL AND RETURN GROUP
when "11001101" =>
-- CALL nn
if Mode = 3 then
MCycles <= "110";
else
MCycles <= "101";
end if;
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
@ -1192,7 +1298,11 @@ begin
when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" =>
if IR(5) = '0' or Mode /= 3 then
-- CALL cc,nn
if Mode = 3 then
MCycles <= "110";
else
MCycles <= "101";
end if;
case to_integer(unsigned(MCycle)) is
when 2 =>
Inc_PC <= '1';
@ -1221,6 +1331,21 @@ begin
end if;
when "11001001" =>
-- RET
if Mode = 3 then
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
Set_Addr_TO <= aSP;
when 3 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
LDZ <= '1';
when 4 =>
Jump <= '1';
IncDec_16 <= "0111";
when others => null;
end case;
else
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
@ -1235,6 +1360,7 @@ begin
IncDec_16 <= "0111";
when others => null;
end case;
end if;
when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" =>
if IR(5) = '1' and Mode = 3 then
case IRB(4 downto 3) is
@ -1252,22 +1378,11 @@ begin
end case;
when "01" =>
-- ADD SP,n
MCycles <= "011";
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
ALU_Op <= "0000";
Inc_PC <= '1';
Read_To_Reg <= '1';
Save_ALU <= '1';
Set_BusA_To <= "1000";
Set_BusB_To <= "0110";
when 3 =>
NoRead <= '1';
Read_To_Reg <= '1';
Save_ALU <= '1';
ALU_Op <= "0001";
Set_BusA_To <= "1001";
Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!!
Inc_PC <= '1';
ADDSPdd <= '1';
when others =>
end case;
when "10" =>
@ -1282,29 +1397,41 @@ begin
when others => null;
end case;
when "11" =>
-- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!!
MCycles <= "101";
-- LD HL,SP+n
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
Inc_PC <= '1';
when 2 =>
LDHLSP <= '1';
Inc_PC <= '1';
LDZ <= '1';
when 3 =>
Set_Addr_To <= aZI;
Inc_PC <= '1';
LDW <= '1';
when 4 =>
Set_BusA_To(2 downto 0) <= "101"; -- L
Read_To_Reg <= '1';
Inc_WZ <= '1';
Set_Addr_To <= aZI;
when 5 =>
Set_BusA_To(2 downto 0) <= "100"; -- H
Read_To_Reg <= '1';
LDHLSP <= '1';
when others => null;
end case;
end case;
else
-- RET cc
if Mode = 3 then
MCycles <= "101";
case to_integer(unsigned(MCycle)) is
when 2 =>
if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
Set_Addr_TO <= aSP;
else
MCycles <= "010";
end if;
TStates <= "101";
when 3 =>
IncDec_16 <= "0111";
Set_Addr_To <= aSP;
LDZ <= '1';
when 4 =>
Jump <= '1';
IncDec_16 <= "0111";
when others => null;
end case;
else
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
@ -1324,8 +1451,28 @@ begin
when others => null;
end case;
end if;
end if;
when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" =>
-- RST p
if Mode = 3 then
MCycles <= "100";
case to_integer(unsigned(MCycle)) is
when 2 =>
TStates <= "101";
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1101";
when 3 =>
Write <= '1';
IncDec_16 <= "1111";
Set_Addr_To <= aSP;
Set_BusB_To <= "1100";
when 4 =>
Write <= '1';
RstP <= '1';
when others => null;
end case;
else
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
@ -1343,6 +1490,7 @@ begin
RstP <= '1';
when others => null;
end case;
end if;
-- INPUT AND OUTPUT GROUP
when "11011011" =>
@ -1642,16 +1790,16 @@ begin
| "10101100"|"10101101"|"10101110"|"10101111"
| "10110100"|"10110101"|"10110110"|"10110111"
| "10111100"|"10111101"|"10111110"|"10111111"
|"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111"
|"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111"
|"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111"
|"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111"
|"11000000"| "11000010" |"11000100"|"11000101"|"11000110"|"11000111"
|"11001000"| "11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111"
|"11010000"| "11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111"
|"11011000"| "11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111"
|"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111"
|"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111"
|"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111"
|"11110000"|"11110001"|"11110010" |"11110100"|"11110101"|"11110110"|"11110111"
|"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" =>
null; -- NOP, undocumented
when "01111110"|"01111111" =>
when "01110111"|"01111111" =>
-- NOP, undocumented
null;
-- 8 BIT LOAD GROUP
@ -1762,6 +1910,7 @@ begin
else
IncDec_16 <= "1101";
end if;
No_PC <= '1';
when 4 =>
NoRead <= '1';
TStates <= "101";
@ -1785,10 +1934,12 @@ begin
else
IncDec_16 <= "1110";
end if;
No_PC <= '1';
when 3 =>
NoRead <= '1';
I_BC <= '1';
TStates <= "101";
No_PC <= '1';
when 4 =>
NoRead <= '1';
TStates <= "101";
@ -1807,7 +1958,7 @@ begin
when "01010110"|"01110110" =>
-- IM 1
IMode <= "01";
when "01011110"|"01110111" =>
when "01011110"|"01111110" =>
-- IM 2
IMode <= "10";
-- 16 bit arithmetic
@ -1815,6 +1966,8 @@ begin
-- ADC HL,ss
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
No_PC <= '1';
when 2 =>
NoRead <= '1';
ALU_Op <= "0001";
@ -1830,6 +1983,7 @@ begin
end case;
TStates <= "100";
SetWZ <= "11";
No_PC <= '1';
when 3 =>
NoRead <= '1';
Read_To_Reg <= '1';
@ -1849,6 +2003,8 @@ begin
-- SBC HL,ss
MCycles <= "011";
case to_integer(unsigned(MCycle)) is
when 1 =>
No_PC <= '1';
when 2 =>
NoRead <= '1';
ALU_Op <= "0011";
@ -1864,6 +2020,7 @@ begin
end case;
TStates <= "100";
SetWZ <= "11";
No_PC <= '1';
when 3 =>
NoRead <= '1';
ALU_Op <= "0011";
@ -1890,6 +2047,7 @@ begin
Set_BusA_To(2 downto 0) <= "111";
ALU_Op <= "1101";
Save_ALU <= '1';
No_PC <= '1';
when 3 =>
TStates <= "100";
I_RLD <= '1';
@ -1911,6 +2069,7 @@ begin
Set_BusA_To(2 downto 0) <= "111";
ALU_Op <= "1110";
Save_ALU <= '1';
No_PC <= '1';
when 3 =>
TStates <= "100";
I_RRD <= '1';
@ -2032,6 +2191,46 @@ begin
TStates <= "101";
when others => null;
end case;
when "11000001"|"11001001"|"11010001"|"11011001" =>
--R800 MULUB
if R800_mode = '1' then
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
NoRead <= '1';
I_MULUB <= '1';
Set_BusB_To(2 downto 0) <= IR(5 downto 3);
Set_BusB_To(3) <= '0';
when 2 =>
NoRead <= '1';
I_MULU <= '1';
Set_BusA_To(2 downto 0) <= "100";
when others => null;
end case;
end if;
when "11000011"|"11110011" =>
--R800 MULUW
if R800_mode = '1' then
MCycles <= "010";
case to_integer(unsigned(MCycle)) is
when 1 =>
NoRead <= '1';
if DPAIR = "11" then
Set_BusB_To(3 downto 0) <= "1000";
else
Set_BusB_To(2 downto 1) <= DPAIR;
Set_BusB_To(0) <= '0';
Set_BusB_To(3) <= '0';
end if;
Set_BusA_To(2 downto 0) <= "100";
when 2 =>
TStates <= "101";
NoRead <= '1';
I_MULU <= '1';
Set_BusA_To(2 downto 0) <= "100";
when others => null;
end case;
end if;
end case;
end case;
@ -2064,6 +2263,9 @@ begin
if IRB = "00110110" or IRB = "11001011" then
Set_Addr_To <= aNone;
end if;
if not (IRB = "00110110" or ISet = "01") then
No_PC <= '1';
end if;
end if;
if MCycle = "111" then
if Mode = 0 then

View File

@ -11,7 +11,7 @@
--
-- Z80 compatible microprocessor core
--
-- Version : 0242
-- Version : 0250
--
-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
--
@ -106,6 +106,8 @@ package T80_Pack is
NMICycle_n : out std_logic;
IntE : out std_logic;
Stop : out std_logic;
R800_mode : in std_logic := '0';
out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
DIRSet : in std_logic := '0';
DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
@ -168,6 +170,7 @@ package T80_Pack is
ALU_Op : out std_logic_vector(3 downto 0);
-- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
Save_ALU : out std_logic;
Rot_Akku : out std_logic;
PreserveC : out std_logic;
Arith16 : out std_logic;
Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
@ -198,12 +201,17 @@ package T80_Pack is
I_RLD : out std_logic;
I_RRD : out std_logic;
I_INRC : out std_logic;
I_MULUB : out std_logic;
I_MULU : out std_logic;
SetWZ : out std_logic_vector(1 downto 0);
SetDI : out std_logic;
SetEI : out std_logic;
IMode : out std_logic_vector(1 downto 0);
Halt : out std_logic;
NoRead : out std_logic;
Write : out std_logic;
R800_mode : in std_logic;
No_PC : out std_logic;
XYbit_undoc : out std_logic
);
end component;
@ -223,7 +231,10 @@ package T80_Pack is
port(
Arith16 : in std_logic;
Z16 : in std_logic;
WZ : in std_logic_vector(15 downto 0);
XY_State : in std_logic_vector(1 downto 0);
ALU_Op : in std_logic_vector(3 downto 0);
Rot_Akku : in std_logic;
IR : in std_logic_vector(5 downto 0);
ISet : in std_logic_vector(1 downto 0);
BusA : in std_logic_vector(7 downto 0);

View File

@ -203,7 +203,7 @@ begin
begin
if CLK_n'event and CLK_n = '0' then
if CEN = '1' then
Wait_s <= WAIT_n;
Wait_s <= WAIT_n or (IORQ_n_i and MREQ_n_i);
if TState = "011" and BUSAK_n_i = '1' then
DI_Reg <= to_x01(Din);
end if;

View File

@ -110,15 +110,13 @@ type state_type is (idle, nop_t1, nop_t2, nop_t3, nop_t4, rd_t1, rd_wa, rd_t2, r
signal RFSH_n_int : std_logic;
signal M1_n_int : std_logic;
signal BUSAK_n_int : std_logic;
signal BUSAK_n_comb : std_logic;
signal WAIT_n_latched : std_logic;
signal TState : std_logic_vector(2 downto 0);
signal TState1 : std_logic_vector(2 downto 0);
signal SS_Single : std_logic;
signal SS_Step : std_logic;
signal SS_Step_held : std_logic;
signal CountCycle : std_logic;
signal special : std_logic_vector(1 downto 0);
signal int_ctrl : std_logic_vector(7 downto 0);
signal skipNextOpcode : std_logic;
signal Regs : std_logic_vector(255 downto 0);
@ -152,24 +150,19 @@ type state_type is (idle, nop_t1, nop_t2, nop_t3, nop_t4, rd_t1, rd_wa, rd_t2, r
signal BUSRQ_n_sync : std_logic;
signal INT_n_sync : std_logic;
signal NMI_n_sync : std_logic;
signal RESET_n_sync : std_logic;
signal Rdy : std_logic;
signal Read_n : std_logic;
signal Read_n0 : std_logic;
signal Read_n1 : std_logic;
signal Write_n : std_logic;
signal Write_n0 : std_logic;
signal ReadIO_n : std_logic;
signal ReadIO_n0 : std_logic;
signal ReadIO_n1 : std_logic;
signal WriteIO_n : std_logic;
signal WriteIO_n0 : std_logic;
signal Sync : std_logic;
signal Sync0 : std_logic;
signal Sync1 : std_logic;
signal Mem_IO_n : std_logic;
signal MemState : std_logic_vector(2 downto 0);
signal Din : std_logic_vector(7 downto 0);
signal Dout : std_logic_vector(7 downto 0);
@ -226,7 +219,7 @@ begin
WrIO_n => WriteIO_n,
Sync => Sync,
Rdy => open,
nRSTin => RESET_n,
nRSTin => RESET_n_sync,
nRSTout => cpu_reset_n,
CountCycle => CountCycle,
trig => trig,
@ -250,7 +243,7 @@ begin
DataOut => memory_dout,
DataIn => memory_din,
Done => memory_done,
Special => special,
int_ctrl => int_ctrl,
SS_Single => SS_Single,
SS_Step => SS_Step
);
@ -291,9 +284,31 @@ begin
int_gen : process(CLK_n)
begin
if rising_edge(CLK_n) then
BUSRQ_n_sync <= BUSRQ_n;
NMI_n_sync <= NMI_n or special(1);
INT_n_sync <= INT_n or special(0);
if int_ctrl(1) = '1' then
BUSRQ_n_sync <= int_ctrl(0);
else
BUSRQ_n_sync <= BUSRQ_n or (int_ctrl(0) and SS_single);
end if;
if int_ctrl(3) = '1' then
INT_n_sync <= int_ctrl(2);
else
INT_n_sync <= INT_n or (int_ctrl(2) and SS_single);
end if;
if int_ctrl(5) = '1' then
NMI_n_sync <= int_ctrl(4);
else
NMI_n_sync <= NMI_n or (int_ctrl(4) and SS_single);
end if;
if int_ctrl(7) = '1' then
RESET_n_sync <= int_ctrl(6);
else
RESET_n_sync <= RESET_n or (int_ctrl(6) and SS_single);
end if;
end if;
end process;
@ -327,40 +342,32 @@ begin
-- really care about the data (it's re-read from memory by the disassembler).
Sync0 <= '1' when WAIT_n = '1' and M1_n_int = '0' and TState = "010" and skipNextOpcode = '0' else '0';
-- For memory reads/write breakpoints we make the monitoring decision in the middle of T2
-- but only if WAIT_n is '1' so we catch the right data.
Read_n0 <= not (WAIT_n and (not RD_n_int) and (not MREQ_n_int) and (M1_n_int)) when TState = "010" else '1';
Write_n0 <= not (WAIT_n and ( RD_n_int) and (not MREQ_n_int) and (M1_n_int)) when TState = "010" else '1';
-- For IO reads/writes we make the monitoring decision in the middle of the second T2 cycle
-- but only if WAIT_n is '1' so we catch the right data.
-- This one cycle delay accounts for the forced wait state
ReadIO_n0 <= not (WAIT_n and (not RD_n_int) and (not IORQ_n_int) and (M1_n_int)) when TState1 = "010" else '1';
WriteIO_n0 <= not (WAIT_n and ( RD_n_int) and (not IORQ_n_int) and (M1_n_int)) when TState1 = "010" else '1';
-- For reads/write breakpoints we make the monitoring decision in the middle of T3
Read_n0 <= not ((not RD_n_int) and (not MREQ_n_int) and (M1_n_int)) when TState = "011" else '1';
Write_n0 <= not (( RD_n_int) and (not MREQ_n_int) and (M1_n_int)) when TState = "011" else '1';
ReadIO_n0 <= not ((not RD_n_int) and (not IORQ_n_int) and (M1_n_int)) when TState = "011" else '1';
WriteIO_n0 <= not (( RD_n_int) and (not IORQ_n_int) and (M1_n_int)) when TState = "011" else '1';
-- Hold the monitoring decision so it is valid on the rising edge of the clock
-- For instruction fetches and writes, the monitor sees these at the start of T3
-- For reads, the data can arrive in the middle of T3 so delay until end of T3
-- For instruction fetches the monitor sees these at the end of T2
-- For reads and writes, the data is sampled in the middle of T3 so delay until end of T3
watch_gen : process(CLK_n)
begin
if falling_edge(CLK_n) then
Sync <= Sync0;
Read_n1 <= Read_n0;
Read_n <= Read_n1;
Read_n <= Read_n0;
Write_n <= Write_n0;
ReadIO_n1 <= ReadIO_n0;
ReadIO_n <= ReadIO_n1;
ReadIO_n <= ReadIO_n0;
WriteIO_n <= WriteIO_n0;
-- Latch wait seen by T80 on the falling edge, for use on the next rising edge
WAIT_n_latched <= WAIT_n;
end if;
end process;
-- Register the exec data on the rising at the end of T2
-- Register the exec data on the rising edge of the clock at the end of T2
ex_data_latch : process(CLK_n)
begin
if rising_edge(CLK_n) then
TState1 <= TState;
if Sync = '1' then
ex_data <= Data;
end if;
@ -371,14 +378,14 @@ begin
rd_data_latch : process(CLK_n)
begin
if falling_edge(CLK_n) then
if Read_n1 = '0' or ReadIO_n1 = '0' then
if Read_n0 = '0' or ReadIO_n0 = '0' then
rd_data <= Data;
end if;
memory_din <= Data;
end if;
end process;
-- Register the write data on the falling edge in the middle of T2
-- Register the read data on the falling edge of clock in the middle of T3
wr_data_latch : process(CLK_n)
begin
if falling_edge(CLK_n) then
@ -417,7 +424,7 @@ begin
BUSAK_n <= BUSAK_n_int when state = idle else mon_busak_n;
-- Force the address and databus to tristate when reset is asserted
tristate_ad_n <= '0' when RESET_n = '0' else
tristate_ad_n <= '0' when RESET_n_sync = '0' else
BUSAK_n_int when state = idle else
mon_busak_n1;

View File

@ -22,7 +22,7 @@ OBJCOPY=avr-objcopy
PROG = avr_progmem
CFLAGS=$(CPU_CFLAGS) -DF_CPU=${F_CPU}UL -DBAUD=${BAUD} -mmcu=$(MCU) -Wall -Os -mcall-prologues
CFLAGS=$(CPU_CFLAGS) -DF_CPU=${F_CPU}UL -DBAUD=${BAUD} -std=c99 -mmcu=$(MCU) -Wall -Os -mcall-prologues
OBJECTS=AtomBusMon.o status.o $(CPU_OBJECTS)
@ -30,6 +30,7 @@ build: $(TARGET).mcs
$(TARGET).mcs: $(TARGET).bit
promgen -u 0 $(TARGET).bit -o $(TARGET).mcs -p mcs -w -spi -s 8192
promgen -u 0 $(TARGET).bit -o $(TARGET).bin -p bin -w -spi -s 8192
rm -f $(TARGET).cfi $(TARGET).prm
working/$(PROJECT).bit:

View File

@ -3,6 +3,8 @@ NET "CLK_n" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock49" CLOCK_DEDICATED_ROUTE = FALSE;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock49" LOC="P89" | IOSTANDARD = LVCMOS33 | PERIOD = 20.35ns ; # 49.152 MHz Oscillator
NET "Addr<11>" LOC="P16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # Z80 pin 1

View File

@ -4,6 +4,8 @@ TIMESPEC TS_clk_period_49 = PERIOD "clk_period_grp_49" 20.345ns HIGH;
NET "Phi0" TNM_NET = clk_period_grp_phi0;
TIMESPEC TS_clk_period_phi0 = PERIOD "clk_period_grp_phi0" 125ns LOW;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock49" LOC="P89" | IOSTANDARD = LVCMOS33 ; # 49.152 MHz Oscillator
#NET "VSS" LOC="P16" | IOSTANDARD = LVCMOS33 ; # 6502 pin 1
NET "Rdy" LOC="P95" | IOSTANDARD = LVCMOS33 ; # 6502 pin 2

View File

@ -4,6 +4,8 @@ TIMESPEC TS_clk_period_49 = PERIOD "clk_period_grp_49" 20.345ns HIGH;
NET "Phi0" TNM_NET = clk_period_grp_phi0;
TIMESPEC TS_clk_period_phi0 = PERIOD "clk_period_grp_phi0" 125ns LOW;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock49" LOC="P89" | IOSTANDARD = LVCMOS33 ; # 49.152 MHz Oscillator
#NET "VSS" LOC="P16" | IOSTANDARD = LVCMOS33 ; # 6502 pin 1
NET "Rdy" LOC="P95" | IOSTANDARD = LVCMOS33 ; # 6502 pin 2

View File

@ -3,6 +3,8 @@ NET "clock49" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock49" LOC="P89" | IOSTANDARD = LVCMOS33 | PERIOD = 20.35ns ; # 49.152 MHz Oscillator
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
#NET "VSS" LOC="P16" | IOSTANDARD = LVCMOS33 ; # 6809 pin 1
NET "NMI_n" LOC="P95" | IOSTANDARD = LVCMOS33 ; # 6809 pin 2
NET "IRQ_n" LOC="P18" | IOSTANDARD = LVCMOS33 ; # 6809 pin 3

View File

@ -4,6 +4,8 @@ TIMESPEC TS_clk_period_49 = PERIOD "clk_period_grp_49" 20.345ns HIGH;
NET "Phi0" TNM_NET = clk_period_grp_phi0;
TIMESPEC TS_clk_period_phi0 = PERIOD "clk_period_grp_phi0" 125ns LOW;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock49" LOC="P89" | IOSTANDARD = LVCMOS33 ; # 49.152 MHz Oscillator
#NET "VSS" LOC="P16" | IOSTANDARD = LVCMOS33 ; # 6502 pin 1
NET "Rdy" LOC="P95" | IOSTANDARD = LVCMOS33 ; # 6502 pin 2

View File

@ -4,6 +4,8 @@ TIMESPEC TS_clk_period_49 = PERIOD "clk_period_grp_49" 20.345ns HIGH;
NET "Phi0" TNM_NET = clk_period_grp_phi0;
TIMESPEC TS_clk_period_phi0 = PERIOD "clk_period_grp_phi0" 125ns LOW;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock49" LOC="P89" | IOSTANDARD = LVCMOS33 ; # 49.152 MHz Oscillator
#NET "VSS" LOC="P16" | IOSTANDARD = LVCMOS33 ; # 6502 pin 1
NET "Rdy" LOC="P95" | IOSTANDARD = LVCMOS33 ; # 6502 pin 2

View File

@ -3,6 +3,8 @@ NET "clock49" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock49" LOC="P89" | IOSTANDARD = LVCMOS33 | PERIOD = 20.35ns ; # 49.152 MHz Oscillator
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
#NET "VSS" LOC="P16" | IOSTANDARD = LVCMOS33 ; # 6809 pin 1
NET "NMI_n" LOC="P95" | IOSTANDARD = LVCMOS33 ; # 6809 pin 2
NET "IRQ_n" LOC="P18" | IOSTANDARD = LVCMOS33 ; # 6809 pin 3

View File

@ -5,6 +5,8 @@ NET "clock49" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock49" LOC="P89" | IOSTANDARD = LVCMOS33 | PERIOD = 20.35ns ; # 49.152 MHz Oscillator
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "Addr<11>" LOC="P16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # Z80 pin 1
NET "Addr<12>" LOC="P95" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # Z80 pin 2
NET "Addr<13>" LOC="P18" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # Z80 pin 3

View File

@ -16,6 +16,9 @@ NAME=${DIR}/icemulti
mkdir -p ${DIR}
for FORMAT in mcs bin
do
promgen \
-u 0 loader/MultiBootLoader.bit \
-u 54000 unknown/UnknownAdapter.bit \
@ -23,6 +26,8 @@ promgen \
-u FC000 icez80/icez80.bit \
-u 150000 ice65c02/ice65c02.bit \
-u 1A4000 ice6809/ice6809.bit \
-o $NAME.mcs -p mcs -w -spi -s 8192
-o $NAME.$FORMAT -p $FORMAT -w -spi -s 8192
done
rm -f $NAME.cfi $NAME.prm

View File

@ -6,6 +6,8 @@ TIMESPEC TS_clk_period_phi = PERIOD "clk_period_grp_phi" 250ns LOW;
NET "PhiIn" CLOCK_DEDICATED_ROUTE = FALSE;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
NET "VP_n" LOC="P35" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1
@ -86,7 +88,7 @@ NET "tdin" LOC="P61" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "tcclk" LOC="P62" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
# Test outputs (connect to J5 on FPGA board)
#NET "test1" LOC="P46" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "test2" LOC="P48" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "test3" LOC="P57" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "test4" LOC="P59" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "test<0>" LOC="P46" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "test<1>" LOC="P47" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "test<2>" LOC="P48" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "test<3>" LOC="P56" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;

View File

@ -6,6 +6,8 @@ TIMESPEC TS_clk_period_phi = PERIOD "clk_period_grp_phi" 250ns LOW;
NET "PhiIn" CLOCK_DEDICATED_ROUTE = FALSE;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
NET "VP_n" LOC="P35" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1
@ -86,7 +88,7 @@ NET "tdin" LOC="P61" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "tcclk" LOC="P62" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
# Test outputs (connect to J5 on FPGA board)
#NET "test1" LOC="P46" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "test2" LOC="P48" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "test3" LOC="P57" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
#NET "test4" LOC="P59" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "test<0>" LOC="P46" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "test<1>" LOC="P47" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "test<2>" LOC="P48" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;
NET "test<3>" LOC="P56" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ;

View File

@ -3,6 +3,8 @@ TIMESPEC TS_clk_period_50 = PERIOD "clk_period_grp_50" 20.00ns HIGH;
NET "E" CLOCK_DEDICATED_ROUTE = FALSE;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
#NET "VSS" LOC="P" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1

View File

@ -4,6 +4,8 @@ TIMESPEC TS_clk_period_clk_n = PERIOD "clk_period_grp_clk_n" 125ns LOW;
NET "CLK_n" CLOCK_DEDICATED_ROUTE = FALSE;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
NET "Addr<11>" LOC="P43" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1

File diff suppressed because one or more lines are too long

View File

@ -22,7 +22,7 @@
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2017 Xilinx, Inc. --
-- (c) Copyright 1995-2020 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
@ -96,7 +96,7 @@ END COMPONENT;
c_axis_type => 0,
c_common_clock => 1,
c_count_type => 0,
c_data_count_width => 10,
c_data_count_width => 13,
c_default_value => "BlankString",
c_din_width => 72,
c_din_width_axis => 1,
@ -179,7 +179,7 @@ END COMPONENT;
c_overflow_low => 0,
c_preload_latency => 0,
c_preload_regs => 1,
c_prim_fifo_type => "512x72",
c_prim_fifo_type => "4kx9",
c_prog_empty_thresh_assert_val => 4,
c_prog_empty_thresh_assert_val_axis => 1022,
c_prog_empty_thresh_assert_val_rach => 1022,
@ -195,14 +195,14 @@ END COMPONENT;
c_prog_empty_type_wach => 0,
c_prog_empty_type_wdch => 0,
c_prog_empty_type_wrch => 0,
c_prog_full_thresh_assert_val => 511,
c_prog_full_thresh_assert_val => 4095,
c_prog_full_thresh_assert_val_axis => 1023,
c_prog_full_thresh_assert_val_rach => 1023,
c_prog_full_thresh_assert_val_rdch => 1023,
c_prog_full_thresh_assert_val_wach => 1023,
c_prog_full_thresh_assert_val_wdch => 1023,
c_prog_full_thresh_assert_val_wrch => 1023,
c_prog_full_thresh_negate_val => 510,
c_prog_full_thresh_negate_val => 4094,
c_prog_full_type => 0,
c_prog_full_type_axis => 0,
c_prog_full_type_rach => 0,
@ -211,10 +211,10 @@ END COMPONENT;
c_prog_full_type_wdch => 0,
c_prog_full_type_wrch => 0,
c_rach_type => 0,
c_rd_data_count_width => 10,
c_rd_depth => 512,
c_rd_data_count_width => 13,
c_rd_depth => 4096,
c_rd_freq => 1,
c_rd_pntr_width => 9,
c_rd_pntr_width => 12,
c_rdch_type => 0,
c_reg_slice_mode_axis => 0,
c_reg_slice_mode_rach => 0,
@ -242,8 +242,8 @@ END COMPONENT;
c_wach_type => 0,
c_wdch_type => 0,
c_wr_ack_low => 0,
c_wr_data_count_width => 10,
c_wr_depth => 512,
c_wr_data_count_width => 13,
c_wr_depth => 4096,
c_wr_depth_axis => 1024,
c_wr_depth_rach => 16,
c_wr_depth_rdch => 1024,
@ -251,7 +251,7 @@ END COMPONENT;
c_wr_depth_wdch => 1024,
c_wr_depth_wrch => 16,
c_wr_freq => 1,
c_wr_pntr_width => 9,
c_wr_pntr_width => 12,
c_wr_pntr_width_axis => 10,
c_wr_pntr_width_rach => 4,
c_wr_pntr_width_rdch => 10,

View File

@ -1,7 +1,7 @@
##############################################################
#
# Xilinx Core Generator version 14.7
# Date: Tue Jul 25 16:17:25 2017
# Date: Mon Jun 22 18:58:13 2020
#
##############################################################
#
@ -53,7 +53,7 @@ CSET clock_enable_type=Slave_Interface_Clock_Enable
CSET clock_type_axi=Common_Clock
CSET component_name=WatchEvents
CSET data_count=false
CSET data_count_width=10
CSET data_count_width=13
CSET disable_timing_violations=false
CSET disable_timing_violations_axi=false
CSET dout_reset_value=0
@ -111,14 +111,14 @@ CSET fifo_implementation_wach=Common_Clock_Block_RAM
CSET fifo_implementation_wdch=Common_Clock_Block_RAM
CSET fifo_implementation_wrch=Common_Clock_Block_RAM
CSET full_flags_reset_value=0
CSET full_threshold_assert_value=511
CSET full_threshold_assert_value=4095
CSET full_threshold_assert_value_axis=1023
CSET full_threshold_assert_value_rach=1023
CSET full_threshold_assert_value_rdch=1023
CSET full_threshold_assert_value_wach=1023
CSET full_threshold_assert_value_wdch=1023
CSET full_threshold_assert_value_wrch=1023
CSET full_threshold_negate_value=510
CSET full_threshold_negate_value=4094
CSET id_width=4
CSET inject_dbit_error=false
CSET inject_dbit_error_axis=false
@ -135,7 +135,7 @@ CSET inject_sbit_error_wach=false
CSET inject_sbit_error_wdch=false
CSET inject_sbit_error_wrch=false
CSET input_data_width=72
CSET input_depth=512
CSET input_depth=4096
CSET input_depth_axis=1024
CSET input_depth_rach=16
CSET input_depth_rdch=1024
@ -144,7 +144,7 @@ CSET input_depth_wdch=1024
CSET input_depth_wrch=16
CSET interface_type=Native
CSET output_data_width=72
CSET output_depth=512
CSET output_depth=4096
CSET overflow_flag=false
CSET overflow_flag_axi=false
CSET overflow_sense=Active_High
@ -168,7 +168,7 @@ CSET rach_type=FIFO
CSET rdch_type=FIFO
CSET read_clock_frequency=1
CSET read_data_count=false
CSET read_data_count_width=10
CSET read_data_count_width=13
CSET register_slice_mode_axis=Fully_Registered
CSET register_slice_mode_rach=Fully_Registered
CSET register_slice_mode_rdch=Fully_Registered
@ -203,11 +203,11 @@ CSET write_acknowledge_flag=false
CSET write_acknowledge_sense=Active_High
CSET write_clock_frequency=1
CSET write_data_count=false
CSET write_data_count_width=10
CSET write_data_count_width=13
CSET wuser_width=1
# END Parameters
# BEGIN Extra information
MISC pkg_timestamp=2012-11-19T12:39:56Z
# END Extra information
GENERATE
# CRC: 3745e82a
# CRC: ae9d5adb

View File

@ -30,6 +30,7 @@
<properties>
<property xil_pn:name="Auto Implementation Top" xil_pn:value="false" xil_pn:valueState="non-default"/>
<property xil_pn:name="Compile EDK Simulation Library" xil_pn:value="true" xil_pn:valueState="non-default"/>
<property xil_pn:name="Device" xil_pn:value="xc6slx9" xil_pn:valueState="non-default"/>
<property xil_pn:name="Device Family" xil_pn:value="Spartan6" xil_pn:valueState="non-default"/>
<property xil_pn:name="Enable Internal Done Pipe" xil_pn:value="true" xil_pn:valueState="non-default"/>
@ -51,8 +52,8 @@
<!-- -->
<property xil_pn:name="PROP_DesignName" xil_pn:value="WatchEvents" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="spartan6" xil_pn:valueState="default"/>
<property xil_pn:name="PROP_intProjectCreationTimestamp" xil_pn:value="2017-07-25T17:19:37" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWbtProjectID" xil_pn:value="374CFF28879B2146EB9160793669CDAF" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intProjectCreationTimestamp" xil_pn:value="2020-06-22T19:59:58" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWbtProjectID" xil_pn:value="8443B0C0597663D41E40C7503B5D1699" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWorkingDirLocWRTProjDir" xil_pn:value="Same" xil_pn:valueState="non-default"/>
<property xil_pn:name="PROP_intWorkingDirUsed" xil_pn:value="No" xil_pn:valueState="non-default"/>
</properties>

View File

@ -6,6 +6,8 @@ TIMESPEC TS_clk_period_phi0 = PERIOD "clk_period_grp_phi0" 125ns LOW;
NET "Phi0" CLOCK_DEDICATED_ROUTE = FALSE;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
#NET "VSS" LOC="P94" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1

View File

@ -6,6 +6,8 @@ TIMESPEC TS_clk_period_phi0 = PERIOD "clk_period_grp_phi0" 125ns LOW;
NET "Phi0" CLOCK_DEDICATED_ROUTE = FALSE;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
#NET "VSS" LOC="P94" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1

View File

@ -6,6 +6,8 @@ PIN "inst_dcm1/CLKFX_BUFG_INST.O" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
#NET "VSS" LOC="P94" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1
NET "NMI_n" LOC="P95" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 2
NET "IRQ_n" LOC="P98" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 3

View File

@ -6,6 +6,8 @@ NET "CLK_n" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "Addr<11>" LOC="P94" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1
NET "Addr<12>" LOC="P95" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 2
NET "Addr<13>" LOC="P98" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 3

View File

@ -6,6 +6,8 @@ TIMESPEC TS_clk_period_phi0 = PERIOD "clk_period_grp_phi0" 125ns LOW;
NET "Phi0" CLOCK_DEDICATED_ROUTE = FALSE;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
#NET "VSS" LOC="P16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1

View File

@ -6,6 +6,8 @@ TIMESPEC TS_clk_period_phi0 = PERIOD "clk_period_grp_phi0" 125ns LOW;
NET "Phi0" CLOCK_DEDICATED_ROUTE = FALSE;
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
#NET "VSS" LOC="P16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1

View File

@ -6,6 +6,8 @@ PIN "inst_dcm1/CLKFX_BUFG_INST.O" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
#NET "VSS" LOC="P16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1
NET "NMI_n" LOC="P15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 2
NET "IRQ_n" LOC="P17" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 3

View File

@ -6,6 +6,8 @@ NET "CLK_n" CLOCK_DEDICATED_ROUTE = FALSE;
NET "clock" LOC="P50" | IOSTANDARD = LVCMOS33 | PERIOD = 20.00ns ; # 50.00 MHz Oscillator
NET "trig<0>" CLOCK_DEDICATED_ROUTE = FALSE;
NET "Addr<11>" LOC="P16" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 1
NET "Addr<12>" LOC="P15" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 2
NET "Addr<13>" LOC="P17" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8 ; # dip pin 3