-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmos6502.hxx
74 lines (60 loc) · 2.9 KB
/
mos6502.hxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#pragma once
extern uint8_t memory[ 65536 ];
#define OPCODE_HOOK 0x0f // this unused 6502 instruction will call the hook callback
#define OPCODE_HALT 0xff // this unused 6502 instruction will terminate the emulator
#define OPCODE_RTS 0x60 // return from function call
struct MOS_6502
{
// emulator API
uint64_t emulate( uint16_t maxcycles ); // execute up to about maxcycles
void trace_instructions( bool trace ); // enable/disable tracing each instruction
void trace_state( void ); // trace the registers
const char * render_operation( uint16_t address ); // return a string with the disassembled instruction at address
void end_emulation( void ); // the emulator returns at the start of the next instruction
void soft_reset( void ); // sets pc to contents of 0xfffc, the 6502 reset vector
uint8_t a;
uint8_t x;
uint8_t y;
uint8_t sp; // 0x01 is the implicit high byte
uint16_t pc;
uint8_t pf; // NV-BDIZC. State is tracked in bools below and only updated for pf and php
bool fNegative, fOverflow, fUnused, fDecimal, fInterruptDisable, fZero, fCarry;
void power_on()
{
pc = memory[ 0xfffc ] | ( memory[ 0xfffd ] << 8 );
fInterruptDisable = true; // the only flag with a defined value on reset
} //powerOn
const char * render_flags()
{
static char ac[ 10 ] = {0};
size_t next = 0;
ac[ next++ ] = fNegative ? 'N' : 'n';
ac[ next++ ] = fOverflow ? 'V' : 'v';
ac[ next++ ] = fDecimal ? 'D' : 'd';
ac[ next++ ] = fInterruptDisable ? 'I' : 'i';
ac[ next++ ] = fZero ? 'Z' : 'z';
ac[ next++ ] = fCarry ? 'C' : 'c';
ac[ next ] = 0;
return ac;
} //render_flags
private:
void op_pop_pf( void );
void op_bit( uint8_t val );
void op_math( uint8_t math, uint8_t rhs );
void op_bcd_math( uint8_t math, uint8_t rhs );
uint8_t op_rotate( uint8_t rotate, uint8_t val );
void op_cmp( uint8_t lhs, uint8_t rhs );
void op_php();
void set_nz( uint8_t val )
{
fNegative = ( 0 != ( val & 0x80 ) );
fZero = ( 0 == val );
} //set_nz
};
extern MOS_6502 cpu;
// callbacks into hosting app
extern void mos6502_invoke_halt( void ); // called when the OPCODE_HALT instruction is executed
extern uint8_t mos6502_invoke_hook( void ); // called when the OPCODE_HOOK instruction is executed
extern uint8_t mos6502_apple1_load( uint16_t address ); // when 0xd010-0xd013 are used with a load instruction
extern void mos6502_apple1_store( uint16_t address ); // when 0xd010-0xd013 are used with a store instruction
extern void mos6502_hard_exit( const char * perror, uint8_t val ); // called when the emulator executes invalid instructions