Attempt at an electron emulator (sort of)

User projects written in or related to FreeBASIC.
Post Reply
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Attempt at an electron emulator (sort of)

Post by Stonemonkey »

This is a bit of a strange project, my first computer was an acorn electron and there's something i want to attempt to code on it. I don't have the machine any more but I have the electrem emulator. Unfortunately it's a bit of a clunky system to code on so my plan is to sort of emulate it although I don't need the full system so this is just the CPU instructions and graphics mode 2 emulated. I'm not quite sure how I'm going to edit the code on it yet and it could definitely do with some improvements but it's a start.

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
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Attempt at an electron emulator (sort of)

Post by paul doe »

Stonemonkey wrote:...
I'm not quite sure how I'm going to edit the code on it yet and it could definitely do with some improvements but it's a start.
These are fun projects for a while, indeed. For what is worth, I had to do this a while back too. What I did was to code the VM, the ASM for it, and a simple language and compiler to do work at a little higher level, all at once.

It's no walk in the park, I know, but it is quite instructive nonetheless. I'd say that you write the ASM and the linker/locator along with the VM itself to have something to start building upon. That way, it will be easier to debug the three (otherwise, you'll find yourself staring at long memory dumps, which is no fun).

Bootstrapping this stuff from nothingness is one of those chicken-egg problems, but it can be tackled with a little enthusiasm =D
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Re: Attempt at an electron emulator (sort of)

Post by Stonemonkey »

Hi Paul, thanks for the suggestions. Language wise I was thinking of sticking mostly to the ASM possibly with some sort of additional way to deal with data structures, function calling and loops but that's not really high on my list and I'll just see what comes up as I go on with just an assembler to start off with.
My "emulator" is fine for my purposes at the moment but is lacking more than a few things, a couple of instructions, BRK and RTI are missing and I've got no hardware control or anything and the overflow flag was a bit confusing but hopefully I've got that right, expecting to find some bugs along the way. Not got any timing either although I have put in values for the clock cycles of each instruction (without the addition for crossing page boundaries). At the moment each instruction mostly involves several function calls which slows everything down quite a bit so I'll probably rewrite that stuff a bit and then maybe try to implement better timing.
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Re: Attempt at an electron emulator (sort of)

Post by Stonemonkey »

This is a simple example in FB of a rendering method I came up with, I don't see it having much use these days but i'm attempting to write it for the old Electron.

Arrow keys = left/right/forward

Code: Select all

type gfx_buffer
    wwidth as long
    height as long
    pixels as ulong ptr
    z as single ptr
    c as ulong ptr
end type

type vertex
    x as single
    z as single
    rx as single
    rz as single
    next_vertex as vertex ptr
end type

type player
    x as single
    z as single
    a as single
end type

type wall
    v0 as vertex ptr
    v1 as vertex ptr
    c as ulong
    next_wall as wall ptr
end type

type world
    first_vertex as vertex ptr
    first_wall as wall ptr
    player as player ptr
end type

function create_display(byval w as long,byval h as long)as gfx_buffer ptr
    screenres w,h,32,2
    screenset 0,1
    dim as gfx_buffer ptr buffer=new gfx_buffer
    buffer->wwidth=w
    buffer->height=h
    buffer->pixels=screenptr()
    buffer->z=new single[w]
    buffer->c=new ulong[w]
    return buffer
end function

sub clear_gfx_buffer(byval buffer as gfx_buffer ptr)
    for p as long=0 to (buffer->wwidth*buffer->height shr 1)
        buffer->pixels[p]=&hff
    next
    for p as long=(buffer->wwidth*buffer->height shr 1) to buffer->wwidth*buffer->height
        buffer->pixels[p]=&hff00
    next
end sub

function create_world()as world ptr
    dim as world ptr world=new world
    world->player=new player
    return world
end function

function add_vertex(byval world as world ptr,byval x as single,byval z as single,byval u as single)as vertex ptr
    dim as vertex ptr v=new vertex
    v->x=x
    v->z=z
    v->next_vertex=world->first_vertex
    world->first_vertex=v
    return v
end function

function add_wall(byval world as world ptr,byval v0 as vertex ptr,byval v1 as vertex ptr,byval c as ulong)as wall ptr
    dim as wall ptr w=new wall
    w->v0=v0
    w->v1=v1
    w->c=c
    w->next_wall=world->first_wall
    world->first_wall=w
    return w
end function

sub render_world(byval buffer as gfx_buffer ptr,byval world as world ptr)
    scope
        dim as vertex ptr v=world->first_vertex
        dim as single sn=sin(world->player->a/180.0*3.1415926)
        dim as single cs=cos(world->player->a/180.0*3.1415926)
        dim as single px=world->player->x,pz=world->player->z
        while v<>0
            dim as single x=v->x-px
            dim as single z=v->z-pz
            v->rx=x*cs-z*sn
            v->rz=z*cs+x*sn
            v=v->next_vertex
        wend
    end scope
    scope
        dim as wall ptr w=world->first_wall
        while w<>0
            if (w->v0->rz>0.0)and (w->v1->rz>0.0) then
                dim as single z0=1.0/w->v0->rz
                dim as single z1=1.0/w->v1->rz
                dim as single x0=w->v0->rx*z0*buffer->wwidth+(buffer->wwidth shr 1)
                dim as single x1=w->v1->rx*z1*buffer->wwidth+(buffer->wwidth shr 1)
                if x0>x1 then
                    swap x0,x1
                    swap z0,z1
                end if
                dim as long x_start=x0+.4999,x_end=x1-.4999
                if x_start<0 then x_start=0
                if x_end>=buffer->wwidth then x_end=buffer->wwidth-1
                if x_start<=x_end then
                    dim as single dz=(z1-z0)/(x1-x0)
                    z0+=dz*(x_start-x0)
                    dim as ulong c=w->c
                    for x as long=x_start to x_end
                        if z0>buffer->z[x] then
                            buffer->z[x]=z0
                            buffer->c[x]=c
                        end if
                        z0+=dz
                    next
                end if
            end if
            w=w->next_wall
        wend
    end scope
    scope
        dim as long w=buffer->wwidth
        for x as long=0 to w-1
            if buffer->z[x]>0.0 then
                dim as single h=50.0*buffer->z[x]*w
                dim as ulong c=buffer->c[x]
                dim as long y_start=(buffer->height shr 1)-h
                dim as long y_end=(buffer->height shr 1)+h
                if y_start<0 then y_start=0
                if y_end>=buffer->height then y_end=buffer->height-1
                dim as ulong ptr p=buffer->pixels+y_start*w+x
                for y as long=y_start to y_end
                    *p=c
                    p+=w
                next
                buffer->z[x]=0
            end if
        next
    end scope
end sub

function create_test_world()as world ptr
    dim as world ptr world=create_world()
    for i as long=0 to 100000
        dim as single x=rnd*100000-50000,z=rnd*100000-50000
        dim as single dx=rnd*200-100,dz=rnd*200-100
        dim as vertex ptr v0=add_vertex(world,x,z,0)
        dim as vertex ptr v1=add_vertex(world,x+dx,z+dz,1)
        add_wall(world,v0,v1,rnd*&hffffff)
    next
    return world
end function

sub move_player(byval world as world ptr,byval m as single,byval da as single)
    world->player->x+=sin(world->player->a/180.0*3.1415926)*m
    world->player->z+=cos(world->player->a/180.0*3.1415926)*m
    world->player->a+=da
end sub

sub main
    dim as gfx_buffer ptr display=create_display(800,600)
    dim as world ptr world=create_test_world()

    do
        if multikey(&H48) then move_player(world,10.0,0.0)
        if multikey(&H4B) then move_player(world,0.0,-1.0)
        if multikey(&H4D) then move_player(world,0.0,1.0)
        render_world(display,world)
        flip
        clear_gfx_buffer(display)
        sleep 2
    loop until multikey(&H01)
end sub

main
end
Last edited by Stonemonkey on Aug 09, 2020 22:51, edited 2 times in total.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Attempt at an electron emulator (sort of)

Post by BasicCoder2 »

Although I don't know what statements are available for an Acorn Electron as far as FB and Windows I find multikey using arrow keys nicer to use.

Code: Select all

sub main
    dim as gfx_buffer ptr display=create_display(800,600)
    dim as world ptr world=create_test_world()

    do
        if multikey(&H48) then move_player(world,10.0,0.0)
        if multikey(&H4B) then move_player(world,0.0,-1.0)
        if multikey(&H4D) then move_player(world,0.0,1.0)
        render_world(display,world)
        flip
        clear_gfx_buffer(display)
        sleep 2
    loop until multikey(&H01)
end sub
Last edited by BasicCoder2 on Aug 09, 2020 23:09, edited 1 time in total.
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Re: Attempt at an electron emulator (sort of)

Post by Stonemonkey »

Thanks, yes, much nicer. Edited the code above to use that now.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Attempt at an electron emulator (sort of)

Post by D.J.Peters »

Nice CPU emu and yes oldschool retro stuf is fun.

Joshy
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Attempt at an electron emulator (sort of)

Post by D.J.Peters »

If some of you don't know the Acorn Electron (I never saw one in real) here are on youtube: The Acorn Electron Story

Joshy
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Re: Attempt at an electron emulator (sort of)

Post by Stonemonkey »

I have to agree it was quite a crippled system, probably one of the reasons I want to see if my rendering idea can be made to work on it, it'll be a challenge.
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Re: Attempt at an electron emulator (sort of)

Post by Stonemonkey »

For this project I'm going to need a couple of division routines for perspective and some interpolation, 6502 has no divide or multiply instructions so I'm multiplying using a method with look up tables but I need some way to divide. It's registers are limited to 8 bits too but I'm just looking far a way to divide just now. This is for 256*rx/rz for perspective, rz will always be positive.

This is what I've got so far, any help or suggestions for improving this, or any other way of doing it would be much appreciated, that 24* loop is too long.

EDIT: fixed error with using signed variables and reduced loop by 1 because the sign bit doesnt need to be used.

Code: Select all

randomize timer

function divide(byval t1 as ulong,byval t2 as ulong)as long
    dim as ulong result,sign
    if (t1 and &h80000000) then t1=(t1 xor &hffffffff)+1:sign=1
    t2 shl=15
    for i as long=0 to 22
        t1 shl=1
        result shl=1
        if t1>=t2 then t1-=t2:result or=1
    next
    if sign=1 then result=(result xor &hffffffff)+1
    return result
end function

sub main
    dim as long rx,rz

    for i as long=0 to 9
        
        rx=rnd*65535.0-32768.0
        rz=rnd*abs(rx)
        
        print "256 * ";rx;" / ";rz;" = ";"int:";256*rx\rz;"   fp:";256.0*rx/rz;"   result:";divide(rx,rz)
        print
        
    next
    
end sub

main
sleep
end
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Re: Attempt at an electron emulator (sort of)

Post by Stonemonkey »

I know my routine is really only doing 24bit/16bit division but I'm quite surprised at this, at least on my machine it's slightly faster than using the integer divide in FB.

Code: Select all

randomize timer

function divideFB(byval t1 as ulong,byval t2 as ulong)as long
    dim as ulong result,sign
    if (t1 and &h80000000) then t1=(t1 xor &hffffffff)+1:sign=1
    t2 shl=16
    t1 shl=1
    for i as long=0 to 22
        t1 shl=1
        result shl=1
        if t1>=t2 then t1-=t2:result or=1
    next
    if sign=1 then result=(result xor &hffffffff)+1
    return result
end function

function divideASM(byval t1 as ulong,byval t2 as ulong)as long
    asm
        xor ecx,ecx
        mov ebx,dword ptr[t2]
        mov eax,dword ptr[t1]
        test eax,eax
        jns no_neg1
            not eax
            inc eax
no_neg1:
        shl ebx,16
        shl eax,1
        mov edx,23
div_loop:
            shl eax,1
            shl ecx,1
            cmp eax,ebx
            jb no_add
                sub eax,ebx
                inc ecx
no_add:
            dec edx
        jnz div_loop
        
        mov eax,dword ptr[t1]
        test eax,eax
        jns no_neg2
            not ecx
            inc ecx
no_neg2:

        mov dword ptr[function],ecx
    end asm
    
end function

function divide(byval t1 as long,byval t2 as long)as long
    function=256*t1/t2
end function

sub main
    dim as long r
    
    dim as double t=timer()
    for rz as long=1 to 32767
        for rx as long=-32767 to 32767 step 10
            r=divide(rx,rz)
        next
    next
    print "FB integer division";timer()-t
    
    t=timer()
    for rz as long=1 to 32767
        for rx as long=-32767 to 32767 step 10
            r=divideASM(rx,rz)
        next
    next
    print "ASM division routine";timer()-t
    
    t=timer()
    for rz as long=1 to 32767
        for rx as long=-32767 to 32767 step 10
            r=divideFB(rx,rz)
        next
    next
    print "FB division routine";timer()-t
    print
    print "Done."
end sub

main
sleep
end
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Attempt at an electron emulator (sort of)

Post by D.J.Peters »

Do you can run the binary output of vasm on your 6502 emu ?

viewtopic.php?f=17&t=27915&p=265038

Joshy
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Re: Attempt at an electron emulator (sort of)

Post by Stonemonkey »

I have no idea, I'm working on some stuff just now but on the electrem emulator.
I went to the vasm homepage and my tablet did something really strange, it was asking me to set up a screenlock and went into my settings.
Feel free to give it a go or post some assembled code, like your problem with the z80, I'm not convinced I have the flags being set correctly, in particular the overflow.
Stonemonkey
Posts: 649
Joined: Jun 09, 2005 0:08

Re: Attempt at an electron emulator (sort of)

Post by Stonemonkey »

it seems to manage to run the division routine I'm writing.

Code: Select all

#define flag_C 0'1
#define flag_Z 1'2
#define flag_I 2'4
#define flag_D 3'8
#define flag_V 6'64
#define flag_S 7'128

type opcode
    mne as string
    admode as long
end type

type system6502
    ram as ubyte ptr
    A as ubyte
    X as ubyte
    Y as ubyte
    SP as ubyte
    PS as ubyte
    PC as ushort
    mc(0 to 255) as ulong
    display_timer as double
    cycles as long
    show as long
    opcode(0 to 255) as opcode
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
    restore opcodes
    for i as long=0 to 53
        dim as string mne
        read mne
        for c as long=0 to 11
            dim as long a
            read a
            if a>0 then sys->opcode(a).mne=mne:sys->opcode(a).admode=c
        next
    next
    
    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 process6502b(byval sys as system6502 ptr)
    dim as ubyte mcode=sys->mc(sys->ram[sys->PC])
    sys->PC+=1
    dim as byte ptr a(0 to 2)=any
    for i as integer=0 to 2
        select case (mcode and 31)
        case 01
            a(i)=@sys->A
        case 02
            a(i)=@sys->X
        case 03
            a(i)=@sys->Y
        case 04
            'a(i)=@sys->PC
        case 05
            'a(i)=@sys->SP
        case 06
            'a(i)=@sys->PS
        case 07
            a(i)=@sys->ram[sys->PC]
            sys->PC+=1
        end select
        mcode shr=5
    next
    select case mcode
    case 00
        *a(0)or=*a(1)
        sys->PS=(sys->PS and &h7f)or(*a(0) and &h80)
        if *a(0)=0 then sys->PS or=2 else sys->PS and=&hfd
    end select
    
end sub
'impl,imme,abso,absx,absy,zero,zerx,zery,indi,indx,indy,offs
sub process6502(byval sys as system6502 ptr)
    dim as long t=1
    sys->PC+=1
    print hex$(sys->PC-1);" ";sys->opcode(sys->ram[sys->PC-1]).mne;"  ";
    select case sys->opcode(sys->ram[sys->PC-1]).admode
    case 0
        print "        ";
    case 1
        print "#&";hex$(sys->ram[sys->PC]);"    ";
    case 2
        print "&";hex$(sys->ram[sys->PC] or (sys->ram[sys->PC] shl 8));"  ";
    case 3
        print "&";hex$(sys->ram[sys->PC] or (sys->ram[sys->PC] shl 8));",X";
    case 4
        print "&";hex$(sys->ram[sys->PC] or (sys->ram[sys->PC] shl 8));",Y";
    case 5
        print "&";hex$(sys->ram[sys->PC]);"     ";
    case 6
        print "&";hex$(sys->ram[sys->PC]);",X   ";
    case 7
        print "&";hex$(sys->ram[sys->PC]);",Y  ";
    case 8
        print "(&";hex$(sys->ram[sys->PC] or (sys->ram[sys->PC] shl 8));")";
    case 9
        print "(&";hex$(sys->ram[sys->PC]);",X)";
    case 10
        print "(&";hex$(sys->ram[sys->PC]);"),Y";
    case 11
        print "&";hex$(sys->ram[sys->PC]);"     ";
    end select
    
    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
    sys->cycles+=t
    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+=.02
        end if
    wend
end sub

opcodes:
'          impl,imme,abso,absx,absy,zero,zerx,zery,indi,indx,indy,offs
        data "xxx",&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "ORA",&h00,&h09,&h0D,&h1D,&h19,&h05,&h15,&h00,&h00,&h01,&h11,&h00
        data "ASL",&h0A,&h00,&h0E,&h1E,&h00,&h06,&h16,&h00,&h00,&h00,&h00,&h00
        data "PHP",&h08,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "BPL",&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h10
        data "CLC",&h18,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "JSR",&h00,&h00,&h20,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "AND",&h00,&h29,&h2D,&h3D,&h39,&h25,&h35,&h00,&h00,&h21,&h31,&h00
        data "BIT",&h00,&h00,&h2C,&h00,&h00,&h24,&h00,&h00,&h00,&h00,&h00,&h00
        data "ROL",&h2A,&h00,&h2E,&h3E,&h00,&h26,&h36,&h00,&h00,&h00,&h00,&h00
        data "PLP",&h28,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "BMI",&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h30
        data "SEC",&h38,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "EOR",&h00,&h49,&h4D,&h5D,&h59,&h45,&h55,&h00,&h00,&h41,&h51,&h00
        data "LSR",&h4A,&h00,&h4E,&h5E,&h00,&h46,&h56,&h00,&h00,&h00,&h00,&h00
        data "PHA",&h48,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "JMP",&h00,&h00,&h4C,&h00,&h00,&h00,&h00,&h00,&h6C,&h00,&h00,&h00
        data "BVC",&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h50
        data "CLI",&h58,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "RTS",&h60,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "ADC",&h00,&h69,&h6D,&h7D,&h79,&h65,&h75,&h00,&h00,&h61,&h71,&h00
        data "ROR",&h6A,&h00,&h6E,&h7E,&h00,&h66,&h76,&h00,&h00,&h00,&h00,&h00
        data "PLA",&h68,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "BVS",&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h70
        data "SEI",&h78,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "STA",&h00,&h00,&h8D,&h9D,&h99,&h85,&h95,&h00,&h00,&h81,&h91,&h00
        data "STY",&h00,&h00,&h8C,&h00,&h00,&h84,&h94,&h00,&h00,&h00,&h00,&h00
        data "STX",&h00,&h00,&h8E,&h00,&h00,&h86,&h00,&h96,&h00,&h00,&h00,&h00
        data "DEY",&h88,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "TXA",&h8A,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "BCC",&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h90
        data "TYA",&h98,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "TXS",&h9A,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "LDY",&h00,&hA0,&hAC,&hBC,&h00,&hA4,&hB4,&h00,&h00,&h00,&h00,&h00
        data "LDA",&h00,&hA9,&hAD,&hBD,&hB9,&hA5,&hB5,&h00,&h00,&hA1,&hB1,&h00
        data "LDX",&h00,&hA2,&hAE,&h00,&hBE,&hA6,&h00,&hB6,&h00,&h00,&h00,&h00
        data "TAY",&hA8,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "TAX",&hAA,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "BCS",&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&hB0
        data "CLV",&hB8,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "TSX",&hBA,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "CPY",&h00,&hC0,&hCC,&h00,&h00,&hC4,&h00,&h00,&h00,&h00,&h00,&h00
        data "CMP",&h00,&hC9,&hCD,&hDD,&hD9,&hC5,&hD5,&h00,&h00,&hC1,&hD1,&h00
        data "DEC",&h00,&h00,&hCE,&hDE,&h00,&hC6,&hD6,&h00,&h00,&h00,&h00,&h00
        data "INY",&hC8,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "DEX",&hCA,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "BNE",&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&hD0
        data "CLD",&hD8,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "CPX",&h00,&hE0,&hEC,&h00,&h00,&hE4,&h00,&h00,&h00,&h00,&h00,&h00
        data "SBC",&h00,&hE9,&hED,&hFD,&hF9,&hE5,&hF5,&h00,&h00,&hE1,&hF1,&h00
        data "INC",&h00,&h00,&hEE,&hFE,&h00,&hE6,&hF6,&h00,&h00,&h00,&h00,&h00
        data "INX",&hE8,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "NOP",&hEA,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        data "BEQ",&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&hF0
        data "SED",&hF8,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00,&h00
        '          impl,imme,abso,absx,absy,zero,zerx,zery,indi,indx,indy,offs


divide:
data 57,&h2000,&h2000
data &h38
data &hA9,&h00,&h85,&h76,&h85,&h77,&hE5,&h70
data &h85,&h71,&hA9,&h00,&hE5,&h72,&h85,&h73
data &hA0,&h10,&ha2,&h01,&hA5,&h74,&h18
data &h0A,&h85,&h74,&h26,&h75,&hA5,&h76
data &h2A,&h26,&h77,&h18,&h75,&h70
data &h85,&h76,&hA5,&h77,&h75,&h72,&h85,&h77
data &hA9,&h00,&h2A,&hAA,&h05,&h74
data &h88,&hD0,&hE2,&h85,&h74,&h60

function read_code(byval sys as system6502 ptr)as long
    dim as long bytes,address,entry
    read bytes,address,entry
    for i as long=0 to bytes-1
        read sys->ram[address]
        address+=1
    next
    return entry
end function

sub main
    
'create virtual 6502 system
    dim as system6502 ptr sys=init6502()
    restore divide
    dim as long entry=read_code(sys)
    
'values to test division routine
    dim as ushort dividend=47452
    dim as ushort divisor=27

'poke values into ram
    sys->ram[&h70]=divisor and &hff
    sys->ram[&h72]=divisor shr 8
    sys->ram[&h74]=dividend and &hff
    sys->ram[&h75]=dividend shr 8
    
    'sys->show=1
'run the program
    run6502(sys,entry)

'check results
    print
    print dividend;"/";divisor;"=";dividend\divisor
    print "6502 result: ";sys->ram[&h74] or (sys->ram[&h75] shl 8)
    print
    print sys->cycles;" cycles"
    sleep
    
end sub

main
end
jepalza
Posts: 149
Joined: Feb 24, 2010 10:08
Location: Spain (Bilbao)

Re: Attempt at an electron emulator (sort of)

Post by jepalza »

Post Reply