home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
405.lha
/
AppleII_Emulators_src
/
src-2
/
cpu6502.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-28
|
10KB
|
397 lines
#include <cpu_prog_model.h>
#include <stdio.h>
#include <in_lines_code.h>
#include <cpu6502_addrm.h>
#define FALSE 0
#define TRUE 1
void mem_check();
char * dis_ass(),
take_char();
short dummy;
void reset( code)
PM *code;
{
code->PC = code->Me [0xFFFC] | code->Me [0xFFFD] << 8;
code->Ac = 0x00;
code->Xr = 0x00;
code->Yr = 0x00;
code->Ne = FALSE; code->Ov = FALSE; code->Br = TRUE;
code->De = FALSE; code->In = FALSE; code->Ze = FALSE;
code->Ca = FALSE;
code->Er = FALSE;
code->SP = 0xFF;
}
void
ADC_imm(), ADC_zer(), ADC_zex(), ADC_abs(), ADC_abx(), ADC_aby(),
ADC_inx(), ADC_iny(),
AND_imm(), AND_zer(), AND_zex(), AND_abs(), AND_abx(), AND_aby(),
AND_inx(), AND_iny(),
ASL_acc(), ASL_zer(), ASL_zex(), ASL_abs(), ASL_abx(),
BCC(), BCS(), BEQ(),
BIT_zer(), BIT_abs(),
BMI(), BNE(), BPL(),
BRK(),
BVC(), BVS(),
CLC(), CLD(), CLI(), CLV(),
CMP_imm(), CMP_zer(), CMP_zex(), CMP_abs(), CMP_abx(), CMP_aby(),
CMP_inx(), CMP_iny(),
CPX_imm(), CPX_zer(), CPX_abs(),
CPY_imm(), CPY_zer(), CPY_abs(),
DEC_zer(), DEC_zex(), DEC_abs(), DEC_abx(),
DEX(), DEY(),
EOR_imm(), EOR_zer(), EOR_zex(), EOR_abs(), EOR_abx(), EOR_aby(),
EOR_inx(), EOR_iny(),
INC_zer(), INC_zex(), INC_abs(), INC_abx(),
INX(), INY(),
JSR();
void JMP( code)
PM *code;
{
unsigned short int address;
address = abs_address( code);
code->PC = address;
mem_check( address, &dummy, code, Func_JMP);
}
void JMP_ind( code)
PM *code;
{
unsigned short int address;
address = code->Me [code->Me [code->PC] |
code->Me [code->PC + 1] << 8] |
code->Me [(code->Me [code->PC] |
code->Me [code->PC + 1] << 8) + 1] << 8;
code->PC = address;
mem_check( address, &dummy, code, Func_JMP);
}
void
LDA_imm(), LDA_zer(), LDA_zex(), LDA_abs(), LDA_abx(), LDA_aby(),
LDA_inx(), LDA_iny(),
LDX_imm(), LDX_zer(), LDX_zex(), LDX_abs(), LDX_aby(),
LDY_imm(), LDY_zer(), LDY_zex(), LDY_abs(), LDY_abx(),
LSR_acc(), LSR_zer(), LSR_zex(), LSR_abs(), LSR_abx();
void NOP( code)
PM *code;
{
/* No operation */
}
void
ORA_imm(), ORA_zer(), ORA_zex(), ORA_abs(), ORA_abx(), ORA_aby(),
ORA_inx(), ORA_iny(),
PHA(), PHP(), PLA(), PLP(),
ROL_acc(), ROL_zer(), ROL_zex(), ROL_abs(), ROL_abx(),
ROR_acc(), ROR_zer(), ROR_zex(), ROR_abs(), ROR_abx(),
RTI(), RTS(),
SBC_imm(), SBC_zer(), SBC_zex(), SBC_abs(), SBC_abx(), SBC_aby(),
SBC_inx(), SBC_iny(),
SEC(), SED(), SEI(),
STA_zer(), STA_zex(), STA_abs(), STA_abx(), STA_aby(), STA_inx(),
STA_iny(),
STX_zer(), STX_zex(), STX_abs(),
STY_zer(), STY_zex(), STY_abs(),
TAX(), TAY(), TSX(), TXA(), TXS(), TYA();
Debugg( code)
PM *code;
{
short steps;
unsigned short int current_PC;
code->Qu = TRUE;
code->Mo = Mode_SLOW;
printf("\nInternal signal (DEBUGG)\n\n");
current_PC = code->PC;
code->PC -=0x10;
while (code->PC < current_PC + 0x10)
{
if ( (code->PC > current_PC - 7) && (code->PC < current_PC + 3) )
{
if (code->PC == current_PC - 1)
printf("%s <- ; Debugg ON\n", dis_ass( code, &steps) );
else
printf("%s\n", dis_ass( code, &steps) );
}
else
dis_ass( code, &steps);
code->PC += steps;
}
code->PC = current_PC - 1;
printf("\n$%04x- ", code->PC);
reg_dump( code);
printf("\n");
code->PC = current_PC;
}
void none( code)
PM *code;
{
short steps; /* Dummy */
code->PC--;
printf("Can't Evaluate\n");
printf("\n%s\n", dis_ass( code, &steps) );
code->PC++;
code->Er = TRUE;
code->Qu = TRUE; /* Quit of type ERROR */
}
void (*OP_code[])() = {
/* 00 01 02 03 04 05 06 07 */
/* 08 09 0A 0B 0C 0D 0E 0F */
/* 00 */ BRK, none, none, none, none, ORA_zer, ASL_zer, none,
PHP, ORA_imm, ASL_acc, none, none, ORA_abs, ASL_abs, none,
/* 10 */ BPL, ORA_iny, none, none, none, ORA_zex, ASL_zex, none,
CLC, ORA_aby, none, none, none, ORA_abx, ASL_abx, none,
/* 20 */ JSR, AND_inx, none, none, BIT_zer, AND_zer, ROL_zer, none,
PLP, AND_imm, ROL_acc, none, BIT_abs, AND_abs, ROL_abs, none,
/* 30 */ BMI, AND_iny, none, none, none, AND_zex, none, none,
SEC, AND_aby, none, none, none, AND_abx, ROL_abx, none,
/* 40 */ none, EOR_inx, none, none, none, EOR_zer, LSR_zer, none,
PHA, EOR_imm, LSR_acc, none, JMP, EOR_abs, LSR_abs, none,
/* 50 */ BVC, EOR_iny, none, none, none, EOR_zex, LSR_zex, none,
CLI, EOR_aby, none, none, none, EOR_abx, LSR_abx, none,
/* 60 */ RTS, ADC_inx, none, none, none, ADC_zer, ROR_zer, none,
PLA, ADC_imm, ROR_acc, none, JMP_ind, ADC_abs, ROR_abs, none,
/* 70 */ BVS, ADC_iny, none, none, none, ADC_zex, ROR_zex, none,
SEI, ADC_aby, none, none, none, none, ROR_abx, none,
/* 80 */ none, STA_inx, none, none, STY_zer, STA_zer, STX_zer, none,
DEY, none, TXA, none, STY_abs, STA_abs, STX_abs, none,
/* 90 */ BCC, STA_iny, none, none, STY_zex, STA_zex, STX_zex, none,
TYA, STA_aby, TXS, none, none, STA_abx, none, none,
/* A0 */ LDY_imm, LDA_inx, LDX_imm, none, LDY_zer, LDA_zer, LDX_zer, none,
TAY, LDA_imm, TAX, none, LDY_abs, LDA_abs, LDX_abs, none,
/* B0 */ BCS, LDA_iny, none, none, LDY_zex, LDA_zex, LDX_zex, none,
CLV, LDA_aby, TSX, none, LDY_abx, LDA_abx, LDX_aby, none,
/* C0 */ CPY_imm, CMP_inx, none, none, CPY_zer, CMP_zer, DEC_zer, none,
INY, CMP_imm, DEX, none, CPY_abs, CMP_abs, DEC_abs, none,
/* D0 */ BNE, CMP_iny, none, none, none, none, DEC_zex, none,
CLD, CMP_aby, none, none, none, CMP_abx, DEC_abx, none,
/* E0 */ CPX_imm, SBC_inx, none, none, CPX_zer, SBC_zer, INC_zer, none,
INX, SBC_imm, NOP, none, CPX_abs, SBC_abs, INC_abs, none,
/* F0 */ BEQ, SBC_iny, none, none, none, SBC_zex, INC_zex, none,
none, SBC_aby, none, none, none, SBC_abx, INC_abx, Debugg
};
tracing( code)
PM *code;
{
short tecken;
if (code->Tl == 0,1)
{
char buffer [256];
short steps; /* Dummy */
reg_dump( code);
/*
tecken = getc( stdin);
printf("%d->\n", code->Tl);
*/
tecken = 0xFF;
strcpy( buffer, dis_ass( code, &steps) );
strcat( buffer, " " );
buffer [37] = NULL;
printf( buffer);
}
if (code->Me [code->PC] == 0x20)
code->Tl += 2;
if (code->Me [code->PC] == 0x60)
code->Tl -= 2;
if (code->Tl < code->SP,0) /*qq*/
{
printf("Back from Trace.\n");
code->Tl = code->SP;
break_meny( code);
}
if (tecken == '\b')
code->Tl --;
if (toupper( tecken) == 'N')
code->Tl ++;
if ( toupper( tecken) == 'Q')
{
printf("Quit ?\n");
code->Er = TRUE;
}
if (tecken == '\233')
code->Tr = FALSE;
if (toupper( tecken) == 'M')
code->PC = 0xFF65;
}
break_meny( code)
PM * code;
{
short tecken,
action;
code->Qu = FALSE;
action = FALSE;
while (!action)
{
printf("\n:");
tecken = getc( stdin);
switch( toupper( tecken) )
{
case 'M':
printf(" Monitor.\n");
code->PC = 0xFF65;
code->Me [0x0036] = 0xF0;
code->Me [0x0037] = 0xFD;
code->Me [0x0038] = 0x1B;
code->Me [0x0039] = 0xFD;
refresh();
action = TRUE;
break;
case 'Q':
printf(" Quit.\n");
code->Ex = TRUE;
code->Qu = TRUE;
action = TRUE;
break;
case 'C':
printf(" Continue.\n");
action = TRUE;
break;
case 'T':
printf(" Trace ON\n");
code->Tr = TRUE;
code->Tl = code->SP;
action = TRUE;
break;
case 'O':
printf(" Trace OFF\n");
code->Tr = FALSE;
action = TRUE;
break;
case 'F':
printf(" Fast.\n");
code->Mo = Mode_FAST;
code->Qu = TRUE;
action = TRUE;
break;
case 'S':
printf(" Slow.\n");
code->Mo = Mode_SLOW;
code->Qu = TRUE;
action = TRUE;
break;
default:
printf(" M, Q, C, T, O, F, S");
break;
} /* End of switch (tecken) */
} /* End of while (!action) */
}
quit_check( code)
PM *code;
{
if (code->Qu)
/* Let it pass */
return;
if (char_check() )
{
short tecken;
if ( (tecken = take_char() ) == '\233')
{
short tecken_2;
tecken_2 = take_char();
if (tecken_2 == '\233')
code->Qu = TRUE;
else
char_take_back( tecken_2);
}
else
char_take_back( tecken);
}
}
void slow_cpu( code)
PM *code;
{
char tecken;
do /* Until code->Qu == TRUE */
{
if (code->Qu)
break_meny( code);
else
{
code->Br = TRUE;
(*OP_code [code->Me [(code->PC)++] ])( code);
/* Check Esc-Esc break */
quit_check( code);
}
if (code->Ex)
break;
if (code->Tr)
tracing( code);
} while (!code->Qu);
}
void fast_cpu( code)
PM *code;
{
while (
code->Br = TRUE,
!code->Qu)
(*OP_code [code->Me [(code->PC)++] ])( code);
}