Code: Select all
#define flag_C 0
#define flag_Z 1
#define flag_I 2
#define flag_D 3
#define flag_V 6
#define flag_S 7
type system6502
ram as ubyte ptr
A as ubyte
X as ubyte
Y as ubyte
SP as ubyte
PS as ubyte
PC as ushort
display_timer as double
end type
sub set_flag(byval sys as system6502 ptr,byval bt as ubyte,byval v as ubyte)
sys->PS=(sys->PS and (255-(1 shl bt)))+(v shl bt)
end sub
function get_flag(byval sys as system6502 ptr,byval bt as ubyte)as ubyte
return (sys->PS shr bt)and 1
end function
function init6502()as system6502 ptr
screenres 640,512,32,2
screenset 0,1
dim as system6502 ptr sys=new system6502
sys->ram=new ubyte[65536]
set_flag(sys,5,1)
sys->SP=&hff
return sys
end function
sub store(byval sys as system6502 ptr,byval address as ushort,byval v as ubyte)
'if address<&h8000 then sys->ram[address]=v'for electron emulation ROM is above this address
sys->ram[address]=v
end sub
function immediate(byval sys as system6502 ptr)as ushort
sys->PC+=1
return sys->PC-1
end function
function absolute(byval sys as system6502 ptr)as ushort
sys->PC+=2
return sys->ram[sys->PC-2] or (sys->ram[sys->PC-1]shl 8)
end function
function zero(byval sys as system6502 ptr)as ubyte
sys->PC+=1
return sys->ram[sys->PC-1]
end function
function zero_x(byval sys as system6502 ptr)as ubyte
sys->PC+=1
return sys->ram[sys->PC-1]+sys->X
end function
function zero_y(byval sys as system6502 ptr)as ubyte
sys->PC+=1
return sys->ram[sys->PC-1]+sys->Y
end function
function index_x(byval sys as system6502 ptr)as ushort
sys->PC+=2
return (sys->ram[sys->PC-2] or (sys->ram[sys->PC-1]shl 8))+sys->X
end function
function index_y(byval sys as system6502 ptr)as ushort
sys->PC+=2
return (sys->ram[sys->PC-2] or (sys->ram[sys->PC-1]shl 8))+sys->Y
end function
function indirect_x(byval sys as system6502 ptr)as ushort
sys->PC+=1
dim as ulong address=sys->ram[sys->PC-1]+sys->X
return sys->ram[address] or (sys->ram[address+1] shl 8)
end function
function indirect_y(byval sys as system6502 ptr)as ushort
sys->PC+=1
dim as ulong address=sys->ram[sys->PC-1]
return (sys->ram[address] or (sys->ram[address+1] shl 8))+sys->Y
end function
function indirect(byval sys as system6502 ptr)as ushort
sys->PC+=2
dim as ulong address=(sys->ram[sys->PC-2])or(sys->ram[sys->PC-1] shl 8)
return (sys->ram[address] or (sys->ram[address+1] shl 8))+sys->Y
end function
sub process6502(byval sys as system6502 ptr)
dim as long t=1
sys->PC+=1
select case sys->ram[sys->PC-1]
case &h00
case &h01'ORA indirect_x
sys->A or=sys->ram[indirect_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h02
case &h03
case &h04
case &h05 'ORA zero
sys->A or=sys->ram[zero(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=3
case &h06'ASL zero
dim as ushort address=zero(sys)
set_flag(sys,flag_C,sys->ram[address] shr 7)
sys->ram[address] shl=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5
case &h07
case &h08'PHP
sys->ram[sys->SP+&h100]=sys->PS
sys->SP-=1
t=3
case &h09 'ORA imm
sys->A or=sys->ram[immediate(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h0a'ASL A
set_flag(sys,flag_C,sys->A shr 7)
sys->A shl=1
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h0b
case &h0c
case &h0d'ORA absolute
sys->A or=sys->ram[absolute(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &h0e'ASL absolute
dim as ushort address=absolute(sys)
set_flag(sys,flag_C,sys->ram[address] shr 7)
sys->ram[address] shl=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h0f
case &h10'BPL immediate
dim as byte offset=cast(byte,sys->ram[immediate(sys)])
t=2
if get_flag(sys,flag_S)=0 then
sys->PC+=offset
t+=1'+
end if
case &h11'ORA indirect y
sys->A or=sys->ram[indirect_y(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5'+
case &h12
case &h13
case &h14
case &h15'ORA zero,x
sys->A or=sys->ram[zero_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &h16' ASL zero,x
dim as ushort address=zero_x(sys)
set_flag(sys,flag_C,sys->ram[address] shr 7)
sys->ram[address] shl=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h17
case &h18'CLC
set_flag(sys,flag_C,0)
t=2
case &h19'ORA absolute,y
sys->A or=sys->ram[index_y(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &h1a
case &h1b
case &h1c
case &h1d'ORA absolute,x
sys->A or=sys->ram[index_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &h1e'ASL index x
dim as ushort address=index_x(sys)
set_flag(sys,flag_C,sys->ram[address] shr 7)
sys->ram[address] shl=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=7
case &h1f
case &h20'JSR absolute
sys->ram[sys->SP+&h100]=(sys->PC+1)shr 8
sys->SP-=1
sys->ram[sys->SP+&h100]=(sys->PC+1)and &hff
sys->SP-=1
sys->PC=absolute(sys)
t=6
case &h21'AND indirect x
sys->A and=sys->ram[indirect_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h22
case &h23
case &h24'BIT zero
dim as ubyte v=sys->ram[zero(sys)]
if v and sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
set_flag(sys,flag_S,v shr 7)
set_flag(sys,flag_V,(v shr 6)and 1)
t=3
case &h25' AND A zero
sys->A or=sys->ram[zero(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=3
case &h26'ROL zero
dim as ushort address=zero(sys)
dim as ubyte temp=get_flag(sys,flag_c)
set_flag(sys,flag_c,sys->ram[address] shr 7)
sys->ram[address]=(sys->ram[address] shl 1)or temp
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5
case &h27
case &h28'PLP
sys->SP+=1
sys->PS=sys->ram[sys->SP+&h100]
t=4
case &h29 'AND A immediate
sys->A and=sys->ram[immediate(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h2a'ROL A
dim as ubyte temp=get_flag(sys,flag_c)
set_flag(sys,flag_c,sys->A shr 7)
sys->A=(sys->A shl 1)or temp
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h2b
case &h2c'BIT absolute
dim as ubyte v=sys->ram[absolute(sys)]
if v and sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
set_flag(sys,flag_S,v shr 7)
set_flag(sys,flag_V,(v shr 6)and 1)
t=4
case &h2d'AND A absolute
sys->A and=sys->ram[absolute(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &h2e'ROL absolute
dim as ushort address=absolute(sys)
dim as ubyte temp=get_flag(sys,flag_c)
set_flag(sys,flag_c,sys->ram[address] shr 7)
sys->ram[address]=(sys->ram[address] shl 1)or temp
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h2f
case &h30'BMI immediate
dim as byte offset=cast(byte,sys->ram[immediate(sys)])
t=2
if get_flag(sys,flag_S)=1 then
sys->PC+=offset
t+=1'+
end if
case &h31'AND indirect y
sys->A and=sys->ram[indirect_y(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5'+
case &h32
case &h33
case &h34
case &h35'AND A zero,x
sys->A and=sys->ram[zero_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &h36'ROL zero,x
dim as ushort address=zero_x(sys)
dim as ubyte temp=get_flag(sys,flag_c)
set_flag(sys,flag_c,sys->ram[address] shr 7)
sys->ram[address]=(sys->ram[address] shl 1)or temp
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h37
case &h38'SEC
set_flag(sys,flag_C,1)
t=2
case &h39'AND A index y
sys->A and=sys->ram[index_y(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &h3a
case &h3b
case &h3c
case &h3d'AND A index x
sys->A and=sys->ram[index_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &h3e'ROL absolute,x
dim as ushort address=index_x(sys)
dim as ubyte temp=get_flag(sys,flag_c)
set_flag(sys,flag_c,sys->ram[address] shr 7)
sys->ram[address]=(sys->ram[address] shl 1)or temp
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=7
case &h3f
case &h40
case &h41'EOR indirect x
sys->A xor=sys->ram[indirect_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h42
case &h43
case &h44
case &h45'EOR zero
sys->A xor=sys->ram[zero(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=3
case &h46'LSR zero
dim as short address=zero(sys)
set_flag(sys,flag_c,sys->ram[address] and 1)
sys->ram[address] shr=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5
case &h47
case &h48'PHA
sys->ram[sys->SP+&h100]=sys->A
sys->SP-=1
t=3
case &h49'EOR immediate
sys->A xor=sys->ram[immediate(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h4a'LSR A
set_flag(sys,flag_c,sys->A and 1)
sys->A shr=1
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h4b
case &h4c'JMP absolute
sys->PC=absolute(sys)
t=3
case &h4d'EOR absolute
sys->A xor=sys->ram[absolute(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &h4e'LSR absolute
dim as short address=absolute(sys)
set_flag(sys,flag_c,sys->ram[address] and 1)
sys->ram[address] shr=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h4f
case &h50'BVC immediate
dim as byte offset=cast(byte,sys->ram[immediate(sys)])
t=2
if get_flag(sys,flag_V)=0 then
sys->PC+=offset
t+=1'+
end if
case &h51'EOR indirect y
sys->A xor=sys->ram[indirect_y(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5'+
case &h52
case &h53
case &h54
case &h55'EOR zero,x
sys->A xor=sys->ram[zero_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &h56'LSR zero,x
dim as short address=zero_x(sys)
set_flag(sys,flag_c,sys->ram[address] and 1)
sys->ram[address] shr=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h57
case &h58'CLI
set_flag(sys,flag_I,0)
t=2
case &h59'EOR index y
sys->A xor=sys->ram[index_y(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &h5a
case &h5b
case &h5c
case &h5d'EOR index x
sys->A xor=sys->ram[index_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &h5e'LSR absolute,x
dim as short address=index_x(sys)
set_flag(sys,flag_c,sys->ram[address] and 1)
sys->ram[address] shr=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=7
case &h5f
case &h60'RTS
sys->PC=1+(sys->ram[sys->SP+&h101]or(sys->ram[sys->SP+&h102] shl 8))
sys->SP+=2
case &h61'ADC indirect,x
dim as ubyte ram=sys->ram[indirect_x(sys)]
dim as ubyte v=not(ram xor sys->A)
dim as ushort result=sys->A+get_flag(sys,flag_C)+ram
sys->A=result
set_flag(sys,flag_c,result shr 8)
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,(((ram xor result) and v)shr 7) and 1)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h62
case &h63
case &h64
case &h65'ADC zero
dim as ubyte ram=sys->ram[zero(sys)]
dim as ubyte v=not(ram xor sys->A)
dim as ushort result=sys->A+get_flag(sys,flag_C)+ram
sys->A=result
set_flag(sys,flag_c,result shr 8)
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,(((ram xor result) and v)shr 7) and 1)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=3
case &h66'ROR zero
dim as ushort address=zero(sys)
dim as ubyte temp=get_flag(sys,flag_c)
set_flag(sys,flag_c,sys->ram[address] and 1)
sys->ram[address]=(sys->ram[address] shr 1)or(temp shl 7)
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5
case &h67
case &h68'PLA
sys->SP+=1
sys->A=sys->ram[sys->SP+&h100]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &h69'ADC immediate
dim as ubyte ram=sys->ram[immediate(sys)]
dim as ubyte v=not(ram xor sys->A)
dim as ushort result=sys->A+get_flag(sys,flag_C)+ram
sys->A=result
set_flag(sys,flag_c,result shr 8)
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,(((ram xor result) and v)shr 7) and 1)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h6a'ROR A
dim as ubyte temp=get_flag(sys,flag_c)
set_flag(sys,flag_c,sys->A and 1)
sys->A=(sys->A shr 1)or(temp shl 7)
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h6b
case &h6c'JMP indirect
sys->PC=indirect(sys)
t=5
case &h6d'ADC absolute
dim as ubyte ram=sys->ram[absolute(sys)]
dim as ubyte v=not(ram xor sys->A)
dim as ushort result=sys->A+get_flag(sys,flag_C)+ram
sys->A=result
set_flag(sys,flag_c,result shr 8)
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,(((ram xor result) and v)shr 7) and 1)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &h6e'ROR absolute
dim as ushort address=absolute(sys)
dim as ubyte temp=get_flag(sys,flag_c)
set_flag(sys,flag_c,sys->ram[address] and 1)
sys->ram[address]=(sys->ram[address] shr 1)or(temp shl 7)
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h6f
case &h70'BVS immediate
dim as byte offset=cast(byte,sys->ram[immediate(sys)])
t=2
if get_flag(sys,flag_V)=1 then
sys->PC+=offset
t+=1'+
end if
case &h71'ADC indirect,y
dim as ubyte ram=sys->ram[indirect_y(sys)]
dim as ubyte v=not(ram xor sys->A)
dim as ushort result=sys->A+get_flag(sys,flag_C)+ram
sys->A=result
set_flag(sys,flag_c,result shr 8)
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,(((ram xor result) and v)shr 7) and 1)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5'+
case &h72
case &h73
case &h74
case &h75'ADC zero,x
dim as ubyte ram=sys->ram[zero_x(sys)]
dim as ubyte v=not(ram xor sys->A)
dim as ushort result=sys->A+get_flag(sys,flag_C)+ram
sys->A=result
set_flag(sys,flag_c,result shr 8)
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,(((ram xor result) and v)shr 7) and 1)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &h76'ROR zero,x
dim as ushort address=zero_x(sys)
dim as ubyte temp=get_flag(sys,flag_c)
set_flag(sys,flag_c,sys->ram[address] and 1)
sys->ram[address]=(sys->ram[address] shr 1)or(temp shl 7)
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &h77
case &h78'SEI
set_flag(sys,flag_I,1)
t=2
case &h79'ADC absolute,y
dim as ubyte ram=sys->ram[index_y(sys)]
dim as ubyte v=not(ram xor sys->A)
dim as ushort result=sys->A+get_flag(sys,flag_C)+ram
sys->A=result
set_flag(sys,flag_c,result shr 8)
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,(((ram xor result) and v)shr 7) and 1)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &h7a
case &h7b
case &h7c
case &h7d'ADC absolute,x
dim as ubyte ram=sys->ram[index_x(sys)]
dim as ubyte v=not(ram xor sys->A)
dim as ushort result=sys->A+get_flag(sys,flag_C)+ram
sys->A=result
set_flag(sys,flag_c,result shr 8)
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,(((ram xor result) and v)shr 7) and 1)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &h7e'ROR absolute,x
dim as ushort address=index_x(sys)
dim as ubyte temp=get_flag(sys,flag_c)
set_flag(sys,flag_c,sys->ram[address] and 1)
sys->ram[address]=(sys->ram[address] shr 1)or(temp shl 7)
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=7
case &h7f
case &h80
case &h81'STA indirect,x
store(sys,indirect_x(sys),sys->A)
t=6
case &h82
case &h83
case &h84'STY zero
store(sys,zero(sys),sys->Y)
t=3
case &h85'STA zero
store(sys,zero(sys),sys->A)
t=3
case &h86'STX zero
store(sys,zero(sys),sys->X)
t=3
case &h87
case &h88 'DEY
sys->Y-=1
set_flag(sys,flag_S,sys->Y shr 7)
if sys->Y=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h89
case &h8a 'TXA
sys->A=sys->X
set_flag(sys,flag_S,sys->X shr 7)
if sys->X=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h8b
case &h8c'STY absolute
store(sys,absolute(sys),sys->Y)
t=4
case &h8d'STA absolute
store(sys,absolute(sys),sys->A)
t=4
case &h8e'STX absolute
store(sys,absolute(sys),sys->X)
t=4
case &h8f
case &h90'BCC immediate
dim as byte offset=cast(byte,sys->ram[immediate(sys)])
t=2
if get_flag(sys,flag_C)=0 then
sys->PC+=offset
t+=1'+
end if
case &h91'STA indirect,y
store(sys,indirect_y(sys),sys->A)
t=6
case &h92
case &h93
case &h94'STY zero,x
store(sys,zero_x(sys),sys->Y)
t=4
case &h95'STA zero,x
store(sys,zero_x(sys),sys->A)
t=4
case &h96'STX zero,y
store(sys,zero_y(sys),sys->X)
t=3
case &h97
case &h98 'TYA
sys->A=sys->Y
set_flag(sys,flag_S,sys->Y shr 7)
if sys->Y=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &h99'STA absolute,y
store(sys,index_y(sys),sys->A)
t=5
case &h9a'TXS
sys->SP=sys->X
t=2
case &h9b
case &h9c
case &h9d'STA absolute,x
store(sys,index_x(sys),sys->A)
t=5
case &h9e
case &h9f
case &ha0'LDY immediate
sys->Y=sys->ram[immediate(sys)]
set_flag(sys,flag_S,sys->Y shr 7)
if sys->Y=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &ha1'LDA indirect_x
sys->A=sys->ram[indirect_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &ha2'LDX immediate
sys->X=sys->ram[immediate(sys)]
set_flag(sys,flag_S,sys->X shr 7)
if sys->X=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &ha3
case &ha4'LDY zero
sys->Y=sys->ram[zero(sys)]
set_flag(sys,flag_S,sys->Y shr 7)
if sys->Y=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=3
case &ha5'LDA zero
sys->A=sys->ram[zero(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=3
case &ha6'LDX zero
sys->X=sys->ram[zero(sys)]
set_flag(sys,flag_S,sys->X shr 7)
if sys->X=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=3
case &ha7
case &ha8 'TAY
sys->Y=sys->A
set_flag(sys,flag_S,sys->Y shr 7)
if sys->Y=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &ha9'LDA immediate
sys->A=sys->ram[immediate(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &haa 'TAX
sys->X=sys->A
set_flag(sys,flag_S,sys->X shr 7)
if sys->X=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &hab
case &hac'LDY absolute
sys->Y=sys->ram[absolute(sys)]
set_flag(sys,flag_S,sys->Y shr 7)
if sys->Y=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &had'LDA absolute
sys->A=sys->ram[absolute(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &hae'LDX absolute
sys->X=sys->ram[absolute(sys)]
set_flag(sys,flag_S,sys->X shr 7)
if sys->X=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &haf
case &hb0'BCS immediate
dim as byte offset=cast(byte,sys->ram[immediate(sys)])
t=2
if get_flag(sys,flag_C)=1 then
sys->PC+=offset
t+=1'+
end if
case &hb1'LDA indirect_y
sys->A=sys->ram[indirect_y(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5'+
case &hb2
case &hb3
case &hb4'LDY zero,x
sys->Y=sys->ram[zero_x(sys)]
set_flag(sys,flag_S,sys->Y shr 7)
if sys->Y=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &hb5'LDA zero,x
sys->A=sys->ram[zero_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &hb6'LDX zero,y
sys->X=sys->ram[zero_y(sys)]
set_flag(sys,flag_S,sys->X shr 7)
if sys->X=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &hb7
case &hb8'CLV
set_flag(sys,flag_V,0)
t=2
case &hb9'LDA index y
sys->A=sys->ram[index_y(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &hba'TSX
sys->X=sys->SP
t=2
case &hbb
case &hbc'LDY index x
sys->Y=sys->ram[index_x(sys)]
set_flag(sys,flag_S,sys->Y shr 7)
if sys->Y=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &hbd'LDA index x
sys->A=sys->ram[index_x(sys)]
set_flag(sys,flag_S,sys->A shr 7)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &hbe'LDX index y
sys->X=sys->ram[index_y(sys)]
set_flag(sys,flag_S,sys->X shr 7)
if sys->X=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &hbf
case &hc0'CPY immediate
dim as ubyte v=sys->ram[immediate(sys)]
dim as ubyte result=sys->Y-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->Y then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=2
case &hc1'CMP indirect x
dim as ubyte v=sys->ram[indirect_x(sys)]
dim as ubyte result=sys->A-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->A then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=6'
case &hc2
case &hc3
case &hc4'CPY zero
dim as ubyte v=sys->ram[zero(sys)]
dim as ubyte result=sys->Y-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->Y then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=3
case &hc5'CMP zero
dim as ubyte v=sys->ram[zero(sys)]
dim as ubyte result=sys->A-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->A then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=3
case &hc6'DEC zero
dim as ushort address=zero(sys)
sys->ram[address]-=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5
case &hc7
case &hc8 'INY
sys->Y+=1
set_flag(sys,flag_S,sys->Y shr 7)
if sys->Y=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &hc9'CMP immediate
dim as ubyte v=sys->ram[immediate(sys)]
dim as ubyte result=sys->A-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->A then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=2
case &hca 'DEX
sys->X-=1
set_flag(sys,flag_S,sys->X shr 7)
if sys->X=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &hcb
case &hcc'CPY absolute
dim as ubyte v=sys->ram[absolute(sys)]
dim as ubyte result=sys->Y-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->Y then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=4
case &hcd'CMP absolute
dim as ubyte v=sys->ram[absolute(sys)]
dim as ubyte result=sys->A-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->A then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=4
case &hce'DEC absolute
dim as ushort address=absolute(sys)
sys->ram[address]-=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &hcf
case &hd0'BNE immediate
dim as byte offset=cast(byte,sys->ram[immediate(sys)])
t=2
if get_flag(sys,flag_Z)=0 then
sys->PC+=offset
t+=1'+
end if
case &hd1'CMP indirect y
dim as ubyte v=sys->ram[indirect_y(sys)]
dim as ubyte result=sys->A-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->A then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=5'+
case &hd2
case &hd3
case &hd4
case &hd5'CMP zero,x
dim as ubyte v=sys->ram[zero_x(sys)]
dim as ubyte result=sys->A-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->A then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=4
case &hd6'DEC zero,x
dim as ushort address=zero_x(sys)
sys->ram[address]-=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &hd7
case &hd8'CLD
set_flag(sys,flag_D,0)
t=2
case &hd9'CMP index y
dim as ubyte v=sys->ram[index_y(sys)]
dim as ubyte result=sys->A-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->A then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=4'+
case &hda
case &hdb
case &hdc
case &hdd'CMP index_x
dim as ubyte v=sys->ram[index_x(sys)]
dim as ubyte result=sys->A-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->A then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=4'+
case &hde'DEC index x
dim as ushort address=index_x(sys)
sys->ram[address]-=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=7
case &hdf
case &he0'CPX immediate
dim as ubyte v=sys->ram[immediate(sys)]
dim as ubyte result=sys->X-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->X then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=2
case &he1'SBC indirect x
dim as ubyte ram=sys->ram[indirect_x(sys)]
dim as short result=sys->A-(1-get_flag(sys,flag_C))-ram
dim as ubyte v=((ram xor sys->A)and(result xor sys->A)and &h80)shr 7
sys->A=result
set_flag(sys,flag_c,1-(result shr 8))
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,v)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &he2
case &he3
case &he4'CPX zero
dim as ubyte v=sys->ram[zero(sys)]
dim as ubyte result=sys->X-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->X then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=3
case &he5'SBC zero
dim as ubyte ram=sys->ram[zero(sys)]
dim as short result=sys->A-(1-get_flag(sys,flag_C))-ram
dim as ubyte v=((ram xor sys->A)and(result xor sys->A)and &h80)shr 7
sys->A=result
set_flag(sys,flag_c,1-(result shr 8))
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,v)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=3
case &he6'INC zero
dim as ushort address=zero(sys)
sys->ram[address]+=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5
case &he7
case &he8 'INX
sys->X+=1
set_flag(sys,flag_S,sys->X shr 7)
if sys->X=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &he9'SBC immediate
dim as ubyte ram=sys->ram[immediate(sys)]
dim as short result=sys->A-(1-get_flag(sys,flag_C))-ram
dim as ubyte v=((ram xor sys->A)and(result xor sys->A)and &h80)shr 7
sys->A=result
set_flag(sys,flag_c,1-(result shr 8))
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,v)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=2
case &hea 'NOP
t=2
case &heb
case &hec'CPX absolute
dim as ubyte v=sys->ram[absolute(sys)]
dim as ubyte result=sys->X-v
set_flag(sys,flag_S,result shr 7)
if result=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
if v>sys->X then set_flag(sys,flag_C,1) else set_flag(sys,flag_C,0)
t=4
case &hed'SBC absolute
dim as ubyte ram=sys->ram[absolute(sys)]
dim as short result=sys->A-(1-get_flag(sys,flag_C))-ram
dim as ubyte v=((ram xor sys->A)and(result xor sys->A)and &h80)shr 7
sys->A=result
set_flag(sys,flag_c,1-(result shr 8))
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,v)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &hee'INC absolute
dim as ushort address=absolute(sys)
sys->ram[address]+=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &hef
case &hf0'BEQ immediate
dim as byte offset=cast(byte,sys->ram[immediate(sys)])
t=2
if get_flag(sys,flag_Z)=1 then
sys->PC+=offset
t+=1'+
end if
case &hf1'SBC indirect_y
dim as ubyte ram=sys->ram[indirect_y(sys)]
dim as short result=sys->A-(1-get_flag(sys,flag_C))-ram
dim as ubyte v=((ram xor sys->A)and(result xor sys->A)and &h80)shr 7
sys->A=result
set_flag(sys,flag_c,1-(result shr 8))
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,v)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=5'+
case &hf2
case &hf3
case &hf4
case &hf5'SBC zero,x
dim as ubyte ram=sys->ram[zero_x(sys)]
dim as short result=sys->A-(1-get_flag(sys,flag_C))-ram
dim as ubyte v=((ram xor sys->A)and(result xor sys->A)and &h80)shr 7
sys->A=result
set_flag(sys,flag_c,1-(result shr 8))
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,v)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4
case &hf6'INC zero,x
dim as ushort address=zero_x(sys)
sys->ram[address]+=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=6
case &hf7
case &hf8'SED
set_flag(sys,flag_D,1)
t=2
case &hf9'SBC absolute,y
dim as ubyte ram=sys->ram[index_y(sys)]
dim as short result=sys->A-(1-get_flag(sys,flag_C))-ram
dim as ubyte v=((ram xor sys->A)and(result xor sys->A)and &h80)shr 7
sys->A=result
set_flag(sys,flag_c,1-(result shr 8))
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,v)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &hfa
case &hfb
case &hfc
case &hfd'SBC absolute,x
dim as ubyte ram=sys->ram[index_x(sys)]
dim as short result=sys->A-(1-get_flag(sys,flag_C))-ram
dim as ubyte v=((ram xor sys->A)and(result xor sys->A)and &h80)shr 7
sys->A=result
set_flag(sys,flag_c,1-(result shr 8))
set_flag(sys,flag_S,sys->A shr 7)
set_flag(sys,flag_V,v)
if sys->A=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=4'+
case &hfe'INC index x
dim as ushort address=index_x(sys)
sys->ram[address]+=1
set_flag(sys,flag_S,sys->ram[address] shr 7)
if sys->ram[address]=0 then set_flag(sys,flag_Z,1) else set_flag(sys,flag_Z,0)
t=7
case &hff
end select
print "A:";hex$(sys->A);" X:";hex$(sys->X);" Y:";hex$(sys->Y);" PC:";hex$(sys->PC);" SP:";hex$(sys->SP);" PS:";bin$(sys->PS);
print " C:";sys->PS and 1;" Z:";(sys->PS shr flag_Z)and 1;" V:";(sys->PS shr flag_V)and 1;" S:";(sys->PS shr flag_S)
end sub
sub scan(byval sys as system6502 ptr)
dim as ulong ptr display=screenptr()
dim as integer pitch
screeninfo ,,,,pitch
pitch shr=2
dim as ulong pal(0 to 15)
pal(0)=0
pal(1)=&hff0000
pal(2)=&hff00
pal(3)=&hffff00
pal(4)=&hff
pal(5)=&hff00ff
pal(6)=&hffff
pal(7)=&hffffff
dim as long x=0,y0=0,y1=0
for mem as long=&h3000 to &h7fff
dim as ubyte byt=sys->ram[mem]
dim as ulong c0=any,c1=any
c1=pal((byt and 1)or((byt and 4)shr 1)or((byt and 16)shr 2)or((byt and 64)shr 3))
c0=pal(((byt and 2)shr 1)or((byt and 8)shr 2)or((byt and 32)shr 3)or((byt and 128)shr 4))
dim as ulong ptr padd=display+(x shl 2)+(y0+y1)*2*pitch
*(padd+0)=c0
*(padd+1)=c0
*(padd+2)=c0
*(padd+3)=c0
*(padd+4)=c1
*(padd+5)=c1
*(padd+6)=c1
*(padd+7)=c1
padd=display+(x shl 2)+(((y0+y1)*2)+1)*pitch
*(padd+0)=c0
*(padd+1)=c0
*(padd+2)=c0
*(padd+3)=c0
*(padd+4)=c1
*(padd+5)=c1
*(padd+6)=c1
*(padd+7)=c1
y0=(y0+1)and 7
if y0=0 then x+=2
if x=160 then
x=0
y1+=8
end if
next
flip
end sub
sub run6502(byval sys as system6502 ptr,byval start_address as ushort)
sys->PC=start_address
sys->PS=32:sys->SP=&hff:sys->A=0:sys->X=0:sys->Y=0
'detects when stack pointer wraps back from excess RTS to exit
sys->display_timer=timer()
while sys->SP<>1
process6502(sys)
if timer()-sys->display_timer>.02 then
scan(sys)
sys->display_timer=timer()
end if
wend
end sub
sub main
'create virtual 6502 system
dim as system6502 ptr sys=init6502()
'6502 machine code test program
'writes values &H00-&HFF into addresses &H6000-&H60FF using index addressing
sys->ram[&h70]=&ha2 'LDX #&FF
sys->ram[&h71]=&hff '
sys->ram[&h72]=&h8a '.loop TXA
sys->ram[&h73]=&h9d ' STA &6000,X
sys->ram[&h74]=&h00 '
sys->ram[&h75]=&h60 '
sys->ram[&h76]=&hca ' DEX
sys->ram[&h77]=&hd0 ' BNE loop
sys->ram[&h78]=&hf9 '
sys->ram[&h79]=&h60 'RTS
run6502(sys,&h70)
sleep
end sub
main
end