mirror of
https://github.com/mist64/perfect6502.git
synced 2024-12-27 20:29:43 +00:00
huh, missing file?
This commit is contained in:
parent
a2ad35412c
commit
9318b580e4
313
emu.c
Normal file
313
emu.c
Normal file
@ -0,0 +1,313 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
|
||||
typedef uint8_t BOOL;
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
typedef uint8_t step_t;
|
||||
|
||||
static step_t t; /* step inside the instruction */
|
||||
static uint8_t ir; /* instruction register */
|
||||
static uint8_t operand;
|
||||
static uint16_t PC;
|
||||
static uint8_t A, X, Y, S, P;
|
||||
static uint8_t temp_lo, temp_hi;
|
||||
|
||||
#define TEMP16 (temp_lo | temp_hi << 8)
|
||||
|
||||
static uint16_t AB;
|
||||
static uint8_t DB;
|
||||
static BOOL RW;
|
||||
extern uint8_t memory[65536];
|
||||
|
||||
#define RW_WRITE 0
|
||||
#define RW_READ 1
|
||||
|
||||
uint8_t
|
||||
LOAD(uint16_t a)
|
||||
{
|
||||
return memory[a];
|
||||
}
|
||||
|
||||
#define T1 (1<<0)
|
||||
#define T2 (1<<1)
|
||||
#define T3 (1<<2)
|
||||
#define T4 (1<<3)
|
||||
#define T5 (1<<4)
|
||||
#define T6 (1<<5)
|
||||
#define T7 (1<<6)
|
||||
|
||||
#define IS_T1 (t & T1)
|
||||
#define IS_T2 (t & T2)
|
||||
#define IS_T3 (t & T3)
|
||||
#define IS_T4 (t & T4)
|
||||
#define IS_T5 (t & T5)
|
||||
#define IS_T6 (t & T6)
|
||||
#define IS_T7 (t & T7)
|
||||
|
||||
void
|
||||
IFETCH()
|
||||
{
|
||||
AB = PC;
|
||||
RW = RW_READ;
|
||||
t = T1;
|
||||
}
|
||||
|
||||
void
|
||||
init()
|
||||
{
|
||||
t = T1;
|
||||
ir = 0;
|
||||
PC = 0;
|
||||
A = 0;
|
||||
X = 0;
|
||||
Y = 0;
|
||||
S = 0;
|
||||
P = 0;
|
||||
IFETCH();
|
||||
}
|
||||
|
||||
void
|
||||
EOI_INCPC_READPC()
|
||||
{
|
||||
PC++;
|
||||
t <<= 1;
|
||||
AB = PC;
|
||||
RW = RW_READ;
|
||||
}
|
||||
|
||||
void
|
||||
DB_TO_ADDRLO()
|
||||
{
|
||||
temp_lo = DB;
|
||||
}
|
||||
void
|
||||
DB_TO_ADDRHI()
|
||||
{
|
||||
temp_hi = DB;
|
||||
}
|
||||
|
||||
void
|
||||
EOI()
|
||||
{
|
||||
t <<= 1;
|
||||
}
|
||||
|
||||
void
|
||||
EOI_INCPC()
|
||||
{
|
||||
PC++;
|
||||
EOI();
|
||||
}
|
||||
|
||||
void
|
||||
EOI_INCPC_READADDR()
|
||||
{
|
||||
EOI_INCPC();
|
||||
AB = TEMP16;
|
||||
RW = RW_READ;
|
||||
}
|
||||
|
||||
void
|
||||
EOI_INCPC_WRITEADDR()
|
||||
{
|
||||
EOI_INCPC();
|
||||
AB = TEMP16;
|
||||
RW = RW_WRITE;
|
||||
}
|
||||
|
||||
void
|
||||
pha()
|
||||
{
|
||||
printf("%s",__func__);
|
||||
if (IS_T2) {
|
||||
S--;
|
||||
EOI();
|
||||
} else if (IS_T3) {
|
||||
AB = 0x0100 + S;
|
||||
DB = A;
|
||||
RW = RW_WRITE;
|
||||
S++;
|
||||
EOI();
|
||||
} else if (IS_T4) {
|
||||
IFETCH();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
plp()
|
||||
{
|
||||
printf("%s",__func__);
|
||||
if (IS_T2) {
|
||||
EOI();
|
||||
} else if (IS_T3) {
|
||||
temp_lo = S;
|
||||
temp_hi = 0x01;
|
||||
AB = TEMP16;
|
||||
RW = RW_READ;
|
||||
S++;
|
||||
EOI();
|
||||
} else if (IS_T4) {
|
||||
temp_lo = S;
|
||||
AB = TEMP16;
|
||||
RW = RW_READ;
|
||||
EOI();
|
||||
} else if (IS_T5) {
|
||||
P = DB;
|
||||
IFETCH();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
txs()
|
||||
{
|
||||
printf("%s",__func__);
|
||||
/* T2 */
|
||||
S = X;
|
||||
IFETCH();
|
||||
}
|
||||
|
||||
void
|
||||
lda_imm()
|
||||
{
|
||||
printf("%s",__func__);
|
||||
/* T2 */
|
||||
A = DB;
|
||||
PC++;
|
||||
IFETCH();
|
||||
}
|
||||
|
||||
void
|
||||
ldx_imm()
|
||||
{
|
||||
printf("%s",__func__);
|
||||
/* T2 */
|
||||
X = DB;
|
||||
PC++;
|
||||
IFETCH();
|
||||
}
|
||||
|
||||
void
|
||||
ldy_imm()
|
||||
{
|
||||
printf("%s",__func__);
|
||||
/* T2 */
|
||||
Y = DB;
|
||||
PC++;
|
||||
IFETCH();
|
||||
}
|
||||
|
||||
void
|
||||
lda_abs()
|
||||
{
|
||||
printf("%s",__func__);
|
||||
if (IS_T2) {
|
||||
DB_TO_ADDRLO();
|
||||
EOI_INCPC_READPC();
|
||||
} else if (IS_T3) {
|
||||
DB_TO_ADDRHI();
|
||||
EOI_INCPC_READADDR();
|
||||
} else if (IS_T4) {
|
||||
A = DB;
|
||||
IFETCH();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sta_abs()
|
||||
{
|
||||
printf("%s",__func__);
|
||||
if (IS_T2) {
|
||||
DB_TO_ADDRLO();
|
||||
EOI_INCPC_READPC();
|
||||
} else if (IS_T3) {
|
||||
DB_TO_ADDRHI();
|
||||
DB = A;
|
||||
EOI_INCPC_WRITEADDR();
|
||||
} else if (IS_T4) {
|
||||
IFETCH();
|
||||
}
|
||||
}
|
||||
|
||||
static int cycle = 0;
|
||||
|
||||
void
|
||||
emulate_step()
|
||||
{
|
||||
/* memory */
|
||||
if (RW == RW_READ) {
|
||||
printf("PEEK(%04X)=%02X ", AB, memory[AB]);
|
||||
DB = memory[AB];
|
||||
} else {
|
||||
printf("POKE %04X, %02X ", AB, DB);
|
||||
memory[AB] = DB;
|
||||
}
|
||||
|
||||
//printf("T%d PC=%04X ", t, PC);
|
||||
if (IS_T1) { /* T0: get result of IFETCH */
|
||||
printf("fetch");
|
||||
ir = DB;
|
||||
EOI_INCPC_READPC();
|
||||
} else {
|
||||
//printf ("IR: %02X ", ir);
|
||||
switch (ir) {
|
||||
case 0x28: plp(); break;
|
||||
case 0x48: pha(); break;
|
||||
case 0x8D: sta_abs(); break;
|
||||
case 0x9A: txs(); break;
|
||||
case 0xA0: ldy_imm(); break;
|
||||
case 0xA2: ldx_imm(); break;
|
||||
case 0xA9: lda_imm(); break;
|
||||
case 0xAD: lda_abs(); break;
|
||||
default:
|
||||
printf("unimplemented opcode: %02X\n", ir);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\ncycle:%d phi0:1 AB:%04X D:%02X RnW:%d PC:%04X A:%02X X:%02X Y:%02X SP:%02X P:%02X IR:%02X",
|
||||
cycle,
|
||||
AB,
|
||||
DB,
|
||||
RW,
|
||||
PC,
|
||||
A,
|
||||
X,
|
||||
Y,
|
||||
S,
|
||||
P,
|
||||
ir);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
setup_emu()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void
|
||||
reset_emu()
|
||||
{
|
||||
init();
|
||||
PC = memory[0xFFFC] | memory[0xFFFD] << 8;
|
||||
printf("PC %x\n", PC);
|
||||
IFETCH();
|
||||
}
|
||||
|
||||
int
|
||||
emu_measure_instruction()
|
||||
{
|
||||
|
||||
for (;;) {
|
||||
printf("cycle %d: ", cycle);
|
||||
emulate_step();
|
||||
printf("\n");
|
||||
cycle++;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user