mirror of
https://github.com/mist64/perfect6502.git
synced 2024-06-25 20:29:40 +00:00
code to test instructions
This commit is contained in:
parent
e292c84c3a
commit
5b43898aae
169
perfect6502.c
169
perfect6502.c
|
@ -24,6 +24,7 @@ int verbose = 1;
|
||||||
|
|
||||||
//#define TEST
|
//#define TEST
|
||||||
//#define BROKEN_TRANSISTORS
|
//#define BROKEN_TRANSISTORS
|
||||||
|
#define TEST_ALL
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
*
|
*
|
||||||
|
@ -789,10 +790,14 @@ chipStatus()
|
||||||
BOOL clk = isNodeHigh(clk0);
|
BOOL clk = isNodeHigh(clk0);
|
||||||
uint16_t a = readAddressBus();
|
uint16_t a = readAddressBus();
|
||||||
uint8_t d = readDataBus();
|
uint8_t d = readDataBus();
|
||||||
if (clk && isNodeHigh(rw))
|
if (clk)
|
||||||
printf(" R$%04X=$%02X\n", a, memory[a]);
|
printf(" !");
|
||||||
else if (clk && !isNodeHigh(rw))
|
else
|
||||||
printf(" W$%04X=$%02X\n", a, d);
|
printf(" ");
|
||||||
|
if (isNodeHigh(rw))
|
||||||
|
printf("R$%04X=$%02X\n", a, memory[a]);
|
||||||
|
else if (!isNodeHigh(rw))
|
||||||
|
printf("W$%04X=$%02X\n", a, d);
|
||||||
else
|
else
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -1022,6 +1027,9 @@ initChip()
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
step();
|
step();
|
||||||
|
|
||||||
|
/* one more to get clk = 1 */
|
||||||
|
step();
|
||||||
|
|
||||||
/* release RESET */
|
/* release RESET */
|
||||||
setHigh(res);
|
setHigh(res);
|
||||||
|
|
||||||
|
@ -1643,6 +1651,159 @@ main()
|
||||||
printf("PASS\n");
|
printf("PASS\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(TEST_ALL)
|
||||||
|
|
||||||
|
void
|
||||||
|
full_step(uint16_t *a, uint8_t *d, BOOL *r_w)
|
||||||
|
{
|
||||||
|
step();
|
||||||
|
step();
|
||||||
|
|
||||||
|
*a = readAddressBus();
|
||||||
|
*d = readDataBus();
|
||||||
|
*r_w = isNodeHigh(rw);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RESET 0xF000
|
||||||
|
#define A_OUT 0xF100
|
||||||
|
#define X_OUT 0xF101
|
||||||
|
#define Y_OUT 0xF102
|
||||||
|
#define S_OUT 0xF103
|
||||||
|
#define P_OUT 0xF104
|
||||||
|
|
||||||
|
#define TRIGGER1 0x5555
|
||||||
|
uint16_t trigger2;
|
||||||
|
#define TRIGGER3 0xAAAA
|
||||||
|
|
||||||
|
void
|
||||||
|
setup_memory(int length, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t A, uint8_t X, uint8_t Y, uint8_t S, uint8_t P)
|
||||||
|
{
|
||||||
|
bzero(memory, 65536);
|
||||||
|
|
||||||
|
memory[0xFFFC] = RESET & 0xFF;
|
||||||
|
memory[0xFFFD] = RESET >> 8;
|
||||||
|
memory[RESET + 0x00] = 0xA2; /* LDA #S */
|
||||||
|
memory[RESET + 0x01] = S;
|
||||||
|
memory[RESET + 0x02] = 0x9A; /* TXS */
|
||||||
|
memory[RESET + 0x03] = 0xA9; /* LDA #P */
|
||||||
|
memory[RESET + 0x04] = P;
|
||||||
|
memory[RESET + 0x05] = 0x48; /* PHA */
|
||||||
|
memory[RESET + 0x06] = 0xA9; /* LHA #A */
|
||||||
|
memory[RESET + 0x07] = A;
|
||||||
|
memory[RESET + 0x08] = 0xA2; /* LDX #X */
|
||||||
|
memory[RESET + 0x09] = X;
|
||||||
|
memory[RESET + 0x0A] = 0xA0; /* LDY #Y */
|
||||||
|
memory[RESET + 0x0B] = Y;
|
||||||
|
memory[RESET + 0x0C] = 0x28; /* PLP */
|
||||||
|
memory[RESET + 0x0D] = 0x8D; /* STA TRIGGER1 */
|
||||||
|
memory[RESET + 0x0E] = TRIGGER1 & 0xFF;
|
||||||
|
memory[RESET + 0x0F] = TRIGGER1 >> 8;
|
||||||
|
memory[RESET + 0x10] = b1;
|
||||||
|
uint16_t addr = RESET + 0x11;
|
||||||
|
if (length >= 2)
|
||||||
|
memory[addr++] = b2;
|
||||||
|
if (length >= 3)
|
||||||
|
memory[addr++] = b3;
|
||||||
|
trigger2 = addr;
|
||||||
|
memory[addr++] = 0x08; /* PHP */
|
||||||
|
memory[addr++] = 0x8D; /* STA A_OUT */
|
||||||
|
memory[addr++] = A_OUT & 0xFF;
|
||||||
|
memory[addr++] = A_OUT >> 8;
|
||||||
|
memory[addr++] = 0x8E; /* STX X_OUT */
|
||||||
|
memory[addr++] = X_OUT & 0xFF;
|
||||||
|
memory[addr++] = X_OUT >> 8;
|
||||||
|
memory[addr++] = 0x8C; /* STY Y_OUT */
|
||||||
|
memory[addr++] = Y_OUT & 0xFF;
|
||||||
|
memory[addr++] = Y_OUT >> 8;
|
||||||
|
memory[addr++] = 0x68; /* PLA */
|
||||||
|
memory[addr++] = 0x8D; /* STA P_OUT */
|
||||||
|
memory[addr++] = P_OUT & 0xFF;
|
||||||
|
memory[addr++] = P_OUT >> 8;
|
||||||
|
memory[addr++] = 0xBA; /* TSX */
|
||||||
|
memory[addr++] = 0x8E; /* STX S_OUT */
|
||||||
|
memory[addr++] = S_OUT & 0xFF;
|
||||||
|
memory[addr++] = S_OUT >> 8;
|
||||||
|
memory[addr++] = 0x8D; /* STA TRIGGER3 */
|
||||||
|
memory[addr++] = TRIGGER3 & 0xFF;
|
||||||
|
memory[addr++] = TRIGGER3 >> 8;
|
||||||
|
memory[addr++] = 0xA9; /* LDA #$00 */
|
||||||
|
memory[addr++] = 0x00;
|
||||||
|
memory[addr++] = 0xF0; /* BEQ . */
|
||||||
|
memory[addr++] = 0xFE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IS_READ_CYCLE (isNodeHigh(clk0) && isNodeHigh(rw))
|
||||||
|
#define IS_WRITE_CYCLE (isNodeHigh(clk0) && !isNodeHigh(rw))
|
||||||
|
#define IS_READING(a) (IS_READ_CYCLE && readAddressBus() == (a))
|
||||||
|
|
||||||
|
#define MAX_CYCLES 100
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STATE_BEFORE_INSTRUCTION,
|
||||||
|
STATE_DURING_INSTRUCTION,
|
||||||
|
STATE_FIRST_FETCH
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
setupNodesAndTransistors();
|
||||||
|
|
||||||
|
verbose = 0;
|
||||||
|
|
||||||
|
// printf("$%02X: ", opcode);
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* find out length of instruction in bytes
|
||||||
|
**************************************************/
|
||||||
|
setup_memory(1, 0xEA, 0x00, 0x00, 0, 0, 0, 0, 0);
|
||||||
|
// setup_memory(2, 0xA9, 0x00, 0x00, 0, 0, 0, 0, 0);
|
||||||
|
// setup_memory(3, 0xFE, 0x00, 0x10, 0, 0, 0, 0, 0);
|
||||||
|
initChip();
|
||||||
|
int state = STATE_BEFORE_INSTRUCTION;
|
||||||
|
uint16_t instr_ab[10];
|
||||||
|
uint8_t instr_db[10];
|
||||||
|
BOOL instr_rw[10];
|
||||||
|
int c = 0;
|
||||||
|
for (int i = 0; i < MAX_CYCLES; i++) {
|
||||||
|
uint16_t ab;
|
||||||
|
uint8_t db;
|
||||||
|
BOOL r_w;
|
||||||
|
full_step(&ab, &db, &r_w);
|
||||||
|
|
||||||
|
if (state == STATE_DURING_INSTRUCTION && ab > trigger2) {
|
||||||
|
/*
|
||||||
|
* we see the FIRST fetch of the next instruction,
|
||||||
|
* the test instruction MIGHT be done
|
||||||
|
*/
|
||||||
|
state = STATE_FIRST_FETCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == STATE_DURING_INSTRUCTION) {
|
||||||
|
instr_rw[c] = r_w;
|
||||||
|
instr_ab[c] = ab;
|
||||||
|
instr_db[c] = db;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ab == TRIGGER1) {
|
||||||
|
state = STATE_DURING_INSTRUCTION; /* we're done writing the trigger value; now comes the instruction! */
|
||||||
|
}
|
||||||
|
if (ab == TRIGGER3) {
|
||||||
|
break; /* we're done dumping the CPU state */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int instr_cycles = c - 1;
|
||||||
|
for (c = 0; c < instr_cycles; c++ ) {
|
||||||
|
printf("%d T%d ", state, c);
|
||||||
|
if (instr_rw[c])
|
||||||
|
printf("R $%04X\n", instr_ab[c]);
|
||||||
|
else
|
||||||
|
printf("W $%04X = $%02X\n", instr_ab[c], instr_db[c]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user