From 4e9f48630b707023c5f2aee7c6e28d8d9bf8be9d Mon Sep 17 00:00:00 2001 From: steve Date: Sun, 1 Jul 2018 19:57:08 +0100 Subject: [PATCH] o debugger - added SYMBOL command. searches for address label, returns address - fixed disassembly output for ROMs without a symbol file - improved disassembly a little bit. now attempts to disassemble entire of cartridge memory and doesn't bail out of loop at first sign of an unimplemented instruction. cpu package now returns a ProgramCounterCycled error when program counter reads past end of memory o video - tweaked horizontal movement - fixed player vertical delay (tested with Pitfall ROM) - fixed ball enable detection (0x02 not 0x20. doh!) o cpu - implemented LAX command - renamed 3 byte NOP to DOP - added program counter information to unimplemented instruction error o gopher 2600 - error message now returned and displayed in run mode o --- debugger/commands.go | 3 ++ debugger/debugger.go | 15 ++++++ debugger/parser/commands.go | 3 ++ disassembly/disassembly.go | 12 ++--- disassembly/symbols/search.go | 15 ++++++ disassembly/symbols/symbols.go | 5 ++ errors/errors.go | 6 ++- gopher2600.go | 2 +- hardware/cpu/cpu.go | 23 +++++++-- hardware/cpu/definitions/csv/definitions.csv | 5 +- hardware/cpu/definitions/instructions.go | 2 +- hardware/cpu/instruction_result.go | 12 +++-- hardware/tia/hmove.go | 6 +-- hardware/tia/tia.go | 4 +- hardware/tia/video/ball.go | 2 +- hardware/tia/video/player.go | 15 +++--- hardware/tia/video/sprite.go | 3 ++ hardware/tia/video/video.go | 52 +++++++++----------- 18 files changed, 124 insertions(+), 61 deletions(-) create mode 100644 disassembly/symbols/search.go diff --git a/debugger/commands.go b/debugger/commands.go index 3154c9df..f5a0e834 100644 --- a/debugger/commands.go +++ b/debugger/commands.go @@ -7,6 +7,7 @@ import "gopher2600/debugger/parser" const ( KeywordHelp = "HELP" KeywordInsert = "INSERT" + KeywordSymbol = "SYMBOL" KeywordBreak = "BREAK" KeywordTrap = "TRAP" KeywordList = "LIST" @@ -45,6 +46,7 @@ const ( // - the tab completion method for each argument for each command var DebuggerCommands = parser.Commands{ KeywordInsert: parser.CommandArgs{parser.Arg{Typ: parser.ArgFile, Req: true}}, + KeywordSymbol: parser.CommandArgs{parser.Arg{Typ: parser.ArgString, Req: true}}, KeywordBreak: parser.CommandArgs{parser.Arg{Typ: parser.ArgTarget, Req: true}, parser.Arg{Typ: parser.ArgValue, Req: false}}, KeywordTrap: parser.CommandArgs{parser.Arg{Typ: parser.ArgTarget, Req: true}}, KeywordOnHalt: parser.CommandArgs{parser.Arg{Typ: parser.ArgIndeterminate, Req: false}}, @@ -84,6 +86,7 @@ func init() { var Help = map[string]string{ KeywordHelp: "Lists commands and provides help for individual debugger commands", KeywordInsert: "Insert cartridge into emulation (from file)", + KeywordSymbol: "Search for the address label symbol in disassembly. returns address", KeywordBreak: "Cause emulator to halt when conditions are met", KeywordList: "List current entries for BREAKS and TRAPS", KeywordClear: "Clear all entries in BREAKS and TRAPS", diff --git a/debugger/debugger.go b/debugger/debugger.go index 736a7aad..51646e1c 100644 --- a/debugger/debugger.go +++ b/debugger/debugger.go @@ -6,6 +6,7 @@ import ( "gopher2600/debugger/ui" "gopher2600/disassembly" "gopher2600/disassembly/symbols" + "gopher2600/errors" "gopher2600/hardware" "gopher2600/hardware/cpu" "gopher2600/television" @@ -379,6 +380,20 @@ func (dbg *Debugger) parseCommand(input string) (bool, error) { return false, err } + case KeywordSymbol: + address, err := dbg.disasm.Symbols.SearchLocation(parts[1]) + if err != nil { + switch err := err.(type) { + case errors.GopherError: + if err.Errno == errors.UnknownSymbol { + dbg.print(ui.Feedback, "%s -> not found", parts[1]) + return false, nil + } + } + return false, err + } + dbg.print(ui.Feedback, "%s -> %#04x", parts[1], address) + case KeywordBreak: err := dbg.breakpoints.parseBreakpoint(parts) if err != nil { diff --git a/debugger/parser/commands.go b/debugger/parser/commands.go index 4ca3d0a3..6bbbb0d1 100644 --- a/debugger/parser/commands.go +++ b/debugger/parser/commands.go @@ -13,6 +13,7 @@ const ( ArgFile ArgTarget ArgValue + ArgString ArgAddress ArgIndeterminate ) @@ -88,6 +89,8 @@ func (options Commands) CheckCommandInput(input []string) error { return fmt.Errorf("emulation target required for %s", input[0]) case ArgValue: return fmt.Errorf("numeric argument required for %s", input[0]) + case ArgString: + return fmt.Errorf("string argument required for %s", input[0]) default: return fmt.Errorf("too few arguments for %s", input[0]) } diff --git a/disassembly/disassembly.go b/disassembly/disassembly.go index f73c9668..1b219d6f 100644 --- a/disassembly/disassembly.go +++ b/disassembly/disassembly.go @@ -38,7 +38,6 @@ func (dsm *Disassembly) ParseMemory(memory *memory.VCSMemory, symbols *symbols.T mc.NoSideEffects = true mc.LoadPC(hardware.AddressReset) - // loop over memory until we encounter a NullInstruction for { ir, err := mc.ExecuteInstruction(func(ir *cpu.InstructionResult) {}) @@ -47,14 +46,15 @@ func (dsm *Disassembly) ParseMemory(memory *memory.VCSMemory, symbols *symbols.T switch err := err.(type) { case errors.GopherError: switch err.Errno { - case errors.NullInstruction: - // we've encountered a null instruction, which means we've come - // to the end of the program code + case errors.ProgramCounterCycled: + // reached end of memory, exit loop with no errors + // TODO: handle multi-bank ROMS return nil + case errors.NullInstruction: + // we've encountered a null instruction. ignore + continue case errors.UnimplementedInstruction: // ignore unimplemented instructions - // TODO: we need a more sophisticated method of ignoring - // data segments / unreachable code continue default: return err diff --git a/disassembly/symbols/search.go b/disassembly/symbols/search.go new file mode 100644 index 00000000..86f2b04c --- /dev/null +++ b/disassembly/symbols/search.go @@ -0,0 +1,15 @@ +package symbols + +import "gopher2600/errors" + +// SearchLocation return the address of the supplied location label +func (sym *Table) SearchLocation(location string) (uint16, error) { + if sym != nil { + for k, v := range sym.Locations { + if v == location { + return k, nil + } + } + } + return 0, errors.GopherError{errors.UnknownSymbol, errors.Values{location}} +} diff --git a/disassembly/symbols/symbols.go b/disassembly/symbols/symbols.go index fa968177..d62a0be9 100644 --- a/disassembly/symbols/symbols.go +++ b/disassembly/symbols/symbols.go @@ -18,6 +18,8 @@ type Table struct { MaxLocationWidth int MaxSymbolWidth int + + Valid bool } // NewTable is the preferred method of initialisation for Table type @@ -121,5 +123,8 @@ func NewTable(cartridgeFilename string) (*Table, error) { } } + // indicate that symbol table should be used + table.Valid = true + return table, nil } diff --git a/errors/errors.go b/errors/errors.go index 2211f737..ca908f03 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -19,12 +19,14 @@ const ( // Debugger NoSymbolsFile = CategoryDebugger + iota SymbolsFileError + UnknownSymbol // VCS // CPU UnimplementedInstruction = CategoryCPU + iota NullInstruction + ProgramCounterCycled // Memory UnservicedChipWrite = CategoryMemory + iota @@ -45,12 +47,14 @@ var messages = map[int]string{ // Debugger NoSymbolsFile: "no symbols file for %s", SymbolsFileError: "error processing symbols file (%s)", + UnknownSymbol: "unrecognised symbol (%s)", // VCS // CPU - UnimplementedInstruction: "unimplemented instruction (%0#x)", + UnimplementedInstruction: "unimplemented instruction (%0#x) at (%#04x)", NullInstruction: "unimplemented instruction (0xff)", + ProgramCounterCycled: "program counter cycled back to 0x0000", // Memory UnservicedChipWrite: "chip memory write signal has not been serviced since previous write (%s)", diff --git a/gopher2600.go b/gopher2600.go index 49ed54a4..17c576b5 100644 --- a/gopher2600.go +++ b/gopher2600.go @@ -178,7 +178,7 @@ func run(cartridgeFile string) error { for { _, _, err := vcs.Step(hardware.NullVideoCycleCallback) if err != nil { - return nil + return err } } } diff --git a/hardware/cpu/cpu.go b/hardware/cpu/cpu.go index 762aa673..b6d48204 100644 --- a/hardware/cpu/cpu.go +++ b/hardware/cpu/cpu.go @@ -188,7 +188,10 @@ func (mc *CPU) read8BitPC() (uint8, error) { if err != nil { return 0, err } - mc.PC.Add(1, false) + carry, _ := mc.PC.Add(1, false) + if carry { + return 0, errors.GopherError{errors.ProgramCounterCycled, nil} + } return op, nil } @@ -200,7 +203,10 @@ func (mc *CPU) read16BitPC() (uint16, error) { // strictly, PC should be incremented by one after reading the lo byte of // the next instruction but I don't believe this has any side-effects - mc.PC.Add(2, false) + carry, _ := mc.PC.Add(2, false) + if carry { + return 0, errors.GopherError{errors.ProgramCounterCycled, nil} + } return val, nil } @@ -308,7 +314,7 @@ func (mc *CPU) ExecuteInstruction(cycleCallback func(*InstructionResult)) (*Inst if operator == 0xff { return nil, errors.GopherError{errors.NullInstruction, nil} } - return nil, errors.GopherError{errors.UnimplementedInstruction, errors.Values{operator}} + return nil, errors.GopherError{errors.UnimplementedInstruction, errors.Values{operator, mc.PC.ToUint16() - 1}} } result.Defn = defn @@ -1052,6 +1058,17 @@ func (mc *CPU) ExecuteInstruction(cycleCallback func(*InstructionResult)) (*Inst case "RTI": // TODO: implement RTI + // undocumented instructions + + case "dop": + // does nothing + + case "lax": + mc.A.Load(value) + mc.Status.Zero = mc.A.IsZero() + mc.Status.Sign = mc.A.IsNegative() + mc.X.Load(value) + default: // this should never, ever happen log.Fatalf("WTF! unknown mnemonic! (%s)", defn.Mnemonic) diff --git a/hardware/cpu/definitions/csv/definitions.csv b/hardware/cpu/definitions/csv/definitions.csv index b4b2beea..ec4c3673 100644 --- a/hardware/cpu/definitions/csv/definitions.csv +++ b/hardware/cpu/definitions/csv/definitions.csv @@ -36,8 +36,8 @@ # TODO: maybe the number of cycles can be inferred in a similar way # no operation +# (also see the undocuemted instruction, DOP) 0xea, NOP, 2, IMPLIED, False -0x04, NOP, 3, ZERO_PAGE, False # status flags 0x58, CLI, 2, IMPLIED, False @@ -232,3 +232,6 @@ 0x00, BRK, 7, IMPLIED, False 0x40, RTI, 6, IMPLIED, False +# undocumented instructions +0x04, dop, 3, ZERO_PAGE, False +0xa7, lax, 4, ABSOLUTE, False diff --git a/hardware/cpu/definitions/instructions.go b/hardware/cpu/definitions/instructions.go index b4b86ab7..5f104c5f 100644 --- a/hardware/cpu/definitions/instructions.go +++ b/hardware/cpu/definitions/instructions.go @@ -4,5 +4,5 @@ package definitions // GetInstructionDefinitions returns the opcode table for the MC6502 func GetInstructionDefinitions() (map[uint8]InstructionDefinition, error) { -return map[uint8]InstructionDefinition{0x7e:InstructionDefinition{ObjectCode:0x7e, Mnemonic:"ROR", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0xd0:InstructionDefinition{ObjectCode:0xd0, Mnemonic:"BNE", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x40:InstructionDefinition{ObjectCode:0x40, Mnemonic:"RTI", Bytes:1, Cycles:6, AddressingMode:0, PageSensitive:false, Effect:0}, 0x35:InstructionDefinition{ObjectCode:0x35, Mnemonic:"AND", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0xbe:InstructionDefinition{ObjectCode:0xbe, Mnemonic:"LDX", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0xf5:InstructionDefinition{ObjectCode:0xf5, Mnemonic:"SBC", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0x20:InstructionDefinition{ObjectCode:0x20, Mnemonic:"JSR", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:4}, 0x55:InstructionDefinition{ObjectCode:0x55, Mnemonic:"EOR", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0x19:InstructionDefinition{ObjectCode:0x19, Mnemonic:"ORA", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0x1e:InstructionDefinition{ObjectCode:0x1e, Mnemonic:"ASL", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0x71:InstructionDefinition{ObjectCode:0x71, Mnemonic:"ADC", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0xf8:InstructionDefinition{ObjectCode:0xf8, Mnemonic:"SED", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x16:InstructionDefinition{ObjectCode:0x16, Mnemonic:"ASL", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0x45:InstructionDefinition{ObjectCode:0x45, Mnemonic:"EOR", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x7d:InstructionDefinition{ObjectCode:0x7d, Mnemonic:"ADC", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0x61:InstructionDefinition{ObjectCode:0x61, Mnemonic:"ADC", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0x2c:InstructionDefinition{ObjectCode:0x2c, Mnemonic:"BIT", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x95:InstructionDefinition{ObjectCode:0x95, Mnemonic:"STA", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:1}, 0x81:InstructionDefinition{ObjectCode:0x81, Mnemonic:"STA", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:1}, 0xd8:InstructionDefinition{ObjectCode:0xd8, Mnemonic:"CLD", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x28:InstructionDefinition{ObjectCode:0x28, Mnemonic:"PLP", Bytes:1, Cycles:4, AddressingMode:0, PageSensitive:false, Effect:0}, 0x94:InstructionDefinition{ObjectCode:0x94, Mnemonic:"STY", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:1}, 0xe6:InstructionDefinition{ObjectCode:0xe6, Mnemonic:"INC", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0x1d:InstructionDefinition{ObjectCode:0x1d, Mnemonic:"ORA", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0x25:InstructionDefinition{ObjectCode:0x25, Mnemonic:"AND", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x8d:InstructionDefinition{ObjectCode:0x8d, Mnemonic:"STA", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:1}, 0x8e:InstructionDefinition{ObjectCode:0x8e, Mnemonic:"STX", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:1}, 0x49:InstructionDefinition{ObjectCode:0x49, Mnemonic:"EOR", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0x39:InstructionDefinition{ObjectCode:0x39, Mnemonic:"AND", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0xae:InstructionDefinition{ObjectCode:0xae, Mnemonic:"LDX", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0xaa:InstructionDefinition{ObjectCode:0xaa, Mnemonic:"TAX", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x11:InstructionDefinition{ObjectCode:0x11, Mnemonic:"ORA", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0x60:InstructionDefinition{ObjectCode:0x60, Mnemonic:"RTS", Bytes:1, Cycles:6, AddressingMode:0, PageSensitive:false, Effect:4}, 0x66:InstructionDefinition{ObjectCode:0x66, Mnemonic:"ROR", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0xc4:InstructionDefinition{ObjectCode:0xc4, Mnemonic:"CPY", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xb6:InstructionDefinition{ObjectCode:0xb6, Mnemonic:"LDX", Bytes:2, Cycles:4, AddressingMode:11, PageSensitive:false, Effect:0}, 0x9a:InstructionDefinition{ObjectCode:0x9a, Mnemonic:"TXS", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xd:InstructionDefinition{ObjectCode:0xd, Mnemonic:"ORA", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0xa2:InstructionDefinition{ObjectCode:0xa2, Mnemonic:"LDX", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xac:InstructionDefinition{ObjectCode:0xac, Mnemonic:"LDY", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0xc8:InstructionDefinition{ObjectCode:0xc8, Mnemonic:"INY", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x76:InstructionDefinition{ObjectCode:0x76, Mnemonic:"ROR", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0x78:InstructionDefinition{ObjectCode:0x78, Mnemonic:"SEI", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xb8:InstructionDefinition{ObjectCode:0xb8, Mnemonic:"CLV", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x6e:InstructionDefinition{ObjectCode:0x6e, Mnemonic:"ROR", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0x4c:InstructionDefinition{ObjectCode:0x4c, Mnemonic:"JMP", Bytes:3, Cycles:3, AddressingMode:3, PageSensitive:false, Effect:3}, 0xb9:InstructionDefinition{ObjectCode:0xb9, Mnemonic:"LDA", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0x6a:InstructionDefinition{ObjectCode:0x6a, Mnemonic:"ROR", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x3e:InstructionDefinition{ObjectCode:0x3e, Mnemonic:"ROL", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0x84:InstructionDefinition{ObjectCode:0x84, Mnemonic:"STY", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:1}, 0xb0:InstructionDefinition{ObjectCode:0xb0, Mnemonic:"BCS", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x70:InstructionDefinition{ObjectCode:0x70, Mnemonic:"BVS", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x8a:InstructionDefinition{ObjectCode:0x8a, Mnemonic:"TXA", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xa4:InstructionDefinition{ObjectCode:0xa4, Mnemonic:"LDY", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x4d:InstructionDefinition{ObjectCode:0x4d, Mnemonic:"EOR", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x29:InstructionDefinition{ObjectCode:0x29, Mnemonic:"AND", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xcd:InstructionDefinition{ObjectCode:0xcd, Mnemonic:"CMP", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0xf6:InstructionDefinition{ObjectCode:0xf6, Mnemonic:"INC", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0xfe:InstructionDefinition{ObjectCode:0xfe, Mnemonic:"INC", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0xd6:InstructionDefinition{ObjectCode:0xd6, Mnemonic:"DEC", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0xea:InstructionDefinition{ObjectCode:0xea, Mnemonic:"NOP", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x4:InstructionDefinition{ObjectCode:0x4, Mnemonic:"NOP", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x85:InstructionDefinition{ObjectCode:0x85, Mnemonic:"STA", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:1}, 0xee:InstructionDefinition{ObjectCode:0xee, Mnemonic:"INC", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0x90:InstructionDefinition{ObjectCode:0x90, Mnemonic:"BCC", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x1:InstructionDefinition{ObjectCode:0x1, Mnemonic:"ORA", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0xca:InstructionDefinition{ObjectCode:0xca, Mnemonic:"DEX", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x5:InstructionDefinition{ObjectCode:0x5, Mnemonic:"ORA", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x6d:InstructionDefinition{ObjectCode:0x6d, Mnemonic:"ADC", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0xe1:InstructionDefinition{ObjectCode:0xe1, Mnemonic:"SBC", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0x58:InstructionDefinition{ObjectCode:0x58, Mnemonic:"CLI", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x59:InstructionDefinition{ObjectCode:0x59, Mnemonic:"EOR", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0x5e:InstructionDefinition{ObjectCode:0x5e, Mnemonic:"LSR", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0x75:InstructionDefinition{ObjectCode:0x75, Mnemonic:"ADC", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0xc5:InstructionDefinition{ObjectCode:0xc5, Mnemonic:"CMP", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x24:InstructionDefinition{ObjectCode:0x24, Mnemonic:"BIT", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x18:InstructionDefinition{ObjectCode:0x18, Mnemonic:"CLC", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x5d:InstructionDefinition{ObjectCode:0x5d, Mnemonic:"EOR", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0x41:InstructionDefinition{ObjectCode:0x41, Mnemonic:"EOR", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0x15:InstructionDefinition{ObjectCode:0x15, Mnemonic:"ORA", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0xe:InstructionDefinition{ObjectCode:0xe, Mnemonic:"ASL", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0x26:InstructionDefinition{ObjectCode:0x26, Mnemonic:"ROL", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0xdd:InstructionDefinition{ObjectCode:0xdd, Mnemonic:"CMP", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0xd9:InstructionDefinition{ObjectCode:0xd9, Mnemonic:"CMP", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0x48:InstructionDefinition{ObjectCode:0x48, Mnemonic:"PHA", Bytes:1, Cycles:3, AddressingMode:0, PageSensitive:false, Effect:1}, 0xba:InstructionDefinition{ObjectCode:0xba, Mnemonic:"TSX", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xf0:InstructionDefinition{ObjectCode:0xf0, Mnemonic:"BEQ", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0xec:InstructionDefinition{ObjectCode:0xec, Mnemonic:"CPX", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x9d:InstructionDefinition{ObjectCode:0x9d, Mnemonic:"STA", Bytes:3, Cycles:5, AddressingMode:8, PageSensitive:false, Effect:1}, 0x21:InstructionDefinition{ObjectCode:0x21, Mnemonic:"AND", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0xa0:InstructionDefinition{ObjectCode:0xa0, Mnemonic:"LDY", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0x30:InstructionDefinition{ObjectCode:0x30, Mnemonic:"BMI", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x51:InstructionDefinition{ObjectCode:0x51, Mnemonic:"EOR", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0x2d:InstructionDefinition{ObjectCode:0x2d, Mnemonic:"AND", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x88:InstructionDefinition{ObjectCode:0x88, Mnemonic:"DEY", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x86:InstructionDefinition{ObjectCode:0x86, Mnemonic:"STX", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:1}, 0x3d:InstructionDefinition{ObjectCode:0x3d, Mnemonic:"AND", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0x31:InstructionDefinition{ObjectCode:0x31, Mnemonic:"AND", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0x79:InstructionDefinition{ObjectCode:0x79, Mnemonic:"ADC", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0xe8:InstructionDefinition{ObjectCode:0xe8, Mnemonic:"INX", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x56:InstructionDefinition{ObjectCode:0x56, Mnemonic:"LSR", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0xa9:InstructionDefinition{ObjectCode:0xa9, Mnemonic:"LDA", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xbd:InstructionDefinition{ObjectCode:0xbd, Mnemonic:"LDA", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0x2e:InstructionDefinition{ObjectCode:0x2e, Mnemonic:"ROL", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0xcc:InstructionDefinition{ObjectCode:0xcc, Mnemonic:"CPY", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x96:InstructionDefinition{ObjectCode:0x96, Mnemonic:"STX", Bytes:2, Cycles:4, AddressingMode:11, PageSensitive:false, Effect:1}, 0x10:InstructionDefinition{ObjectCode:0x10, Mnemonic:"BPL", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x68:InstructionDefinition{ObjectCode:0x68, Mnemonic:"PLA", Bytes:1, Cycles:4, AddressingMode:0, PageSensitive:false, Effect:0}, 0xa8:InstructionDefinition{ObjectCode:0xa8, Mnemonic:"TAY", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xe4:InstructionDefinition{ObjectCode:0xe4, Mnemonic:"CPX", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xb1:InstructionDefinition{ObjectCode:0xb1, Mnemonic:"LDA", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0x65:InstructionDefinition{ObjectCode:0x65, Mnemonic:"ADC", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xfd:InstructionDefinition{ObjectCode:0xfd, Mnemonic:"SBC", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0x6c:InstructionDefinition{ObjectCode:0x6c, Mnemonic:"JMP", Bytes:3, Cycles:5, AddressingMode:5, PageSensitive:false, Effect:3}, 0xc0:InstructionDefinition{ObjectCode:0xc0, Mnemonic:"CPY", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xc6:InstructionDefinition{ObjectCode:0xc6, Mnemonic:"DEC", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0xed:InstructionDefinition{ObjectCode:0xed, Mnemonic:"SBC", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0xce:InstructionDefinition{ObjectCode:0xce, Mnemonic:"DEC", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0x0:InstructionDefinition{ObjectCode:0x0, Mnemonic:"BRK", Bytes:1, Cycles:7, AddressingMode:0, PageSensitive:false, Effect:0}, 0x6:InstructionDefinition{ObjectCode:0x6, Mnemonic:"ASL", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0x99:InstructionDefinition{ObjectCode:0x99, Mnemonic:"STA", Bytes:3, Cycles:5, AddressingMode:9, PageSensitive:false, Effect:1}, 0xe0:InstructionDefinition{ObjectCode:0xe0, Mnemonic:"CPX", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0x8c:InstructionDefinition{ObjectCode:0x8c, Mnemonic:"STY", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:1}, 0x50:InstructionDefinition{ObjectCode:0x50, Mnemonic:"BVC", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0xbc:InstructionDefinition{ObjectCode:0xbc, Mnemonic:"LDY", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0x4e:InstructionDefinition{ObjectCode:0x4e, Mnemonic:"LSR", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0x4a:InstructionDefinition{ObjectCode:0x4a, Mnemonic:"LSR", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x46:InstructionDefinition{ObjectCode:0x46, Mnemonic:"LSR", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0x69:InstructionDefinition{ObjectCode:0x69, Mnemonic:"ADC", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xe5:InstructionDefinition{ObjectCode:0xe5, Mnemonic:"SBC", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xf9:InstructionDefinition{ObjectCode:0xf9, Mnemonic:"SBC", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0xd5:InstructionDefinition{ObjectCode:0xd5, Mnemonic:"CMP", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0xad:InstructionDefinition{ObjectCode:0xad, Mnemonic:"LDA", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0xa:InstructionDefinition{ObjectCode:0xa, Mnemonic:"ASL", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x91:InstructionDefinition{ObjectCode:0x91, Mnemonic:"STA", Bytes:2, Cycles:6, AddressingMode:7, PageSensitive:false, Effect:1}, 0xde:InstructionDefinition{ObjectCode:0xde, Mnemonic:"DEC", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0x8:InstructionDefinition{ObjectCode:0x8, Mnemonic:"PHP", Bytes:1, Cycles:3, AddressingMode:0, PageSensitive:false, Effect:1}, 0x2a:InstructionDefinition{ObjectCode:0x2a, Mnemonic:"ROL", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x9:InstructionDefinition{ObjectCode:0x9, Mnemonic:"ORA", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xa5:InstructionDefinition{ObjectCode:0xa5, Mnemonic:"LDA", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xf1:InstructionDefinition{ObjectCode:0xf1, Mnemonic:"SBC", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0x36:InstructionDefinition{ObjectCode:0x36, Mnemonic:"ROL", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0xc9:InstructionDefinition{ObjectCode:0xc9, Mnemonic:"CMP", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xd1:InstructionDefinition{ObjectCode:0xd1, Mnemonic:"CMP", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0x38:InstructionDefinition{ObjectCode:0x38, Mnemonic:"SEC", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x98:InstructionDefinition{ObjectCode:0x98, Mnemonic:"TYA", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xa6:InstructionDefinition{ObjectCode:0xa6, Mnemonic:"LDX", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xb4:InstructionDefinition{ObjectCode:0xb4, Mnemonic:"LDY", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0xe9:InstructionDefinition{ObjectCode:0xe9, Mnemonic:"SBC", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xc1:InstructionDefinition{ObjectCode:0xc1, Mnemonic:"CMP", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0xb5:InstructionDefinition{ObjectCode:0xb5, Mnemonic:"LDA", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0xa1:InstructionDefinition{ObjectCode:0xa1, Mnemonic:"LDA", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}}, nil +return map[uint8]InstructionDefinition{0xae:InstructionDefinition{ObjectCode:0xae, Mnemonic:"LDX", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x71:InstructionDefinition{ObjectCode:0x71, Mnemonic:"ADC", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0xf5:InstructionDefinition{ObjectCode:0xf5, Mnemonic:"SBC", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0xc9:InstructionDefinition{ObjectCode:0xc9, Mnemonic:"CMP", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xd1:InstructionDefinition{ObjectCode:0xd1, Mnemonic:"CMP", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0x8a:InstructionDefinition{ObjectCode:0x8a, Mnemonic:"TXA", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x55:InstructionDefinition{ObjectCode:0x55, Mnemonic:"EOR", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0x29:InstructionDefinition{ObjectCode:0x29, Mnemonic:"AND", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xb9:InstructionDefinition{ObjectCode:0xb9, Mnemonic:"LDA", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0xca:InstructionDefinition{ObjectCode:0xca, Mnemonic:"DEX", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x0:InstructionDefinition{ObjectCode:0x0, Mnemonic:"BRK", Bytes:1, Cycles:7, AddressingMode:0, PageSensitive:false, Effect:0}, 0xd8:InstructionDefinition{ObjectCode:0xd8, Mnemonic:"CLD", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xb5:InstructionDefinition{ObjectCode:0xb5, Mnemonic:"LDA", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0x69:InstructionDefinition{ObjectCode:0x69, Mnemonic:"ADC", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0x6a:InstructionDefinition{ObjectCode:0x6a, Mnemonic:"ROR", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x1d:InstructionDefinition{ObjectCode:0x1d, Mnemonic:"ORA", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0x2d:InstructionDefinition{ObjectCode:0x2d, Mnemonic:"AND", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0xb1:InstructionDefinition{ObjectCode:0xb1, Mnemonic:"LDA", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0xa4:InstructionDefinition{ObjectCode:0xa4, Mnemonic:"LDY", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xc1:InstructionDefinition{ObjectCode:0xc1, Mnemonic:"CMP", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0x2c:InstructionDefinition{ObjectCode:0x2c, Mnemonic:"BIT", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x9d:InstructionDefinition{ObjectCode:0x9d, Mnemonic:"STA", Bytes:3, Cycles:5, AddressingMode:8, PageSensitive:false, Effect:1}, 0x40:InstructionDefinition{ObjectCode:0x40, Mnemonic:"RTI", Bytes:1, Cycles:6, AddressingMode:0, PageSensitive:false, Effect:0}, 0x19:InstructionDefinition{ObjectCode:0x19, Mnemonic:"ORA", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0x35:InstructionDefinition{ObjectCode:0x35, Mnemonic:"AND", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0xa9:InstructionDefinition{ObjectCode:0xa9, Mnemonic:"LDA", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0x3e:InstructionDefinition{ObjectCode:0x3e, Mnemonic:"ROL", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0xce:InstructionDefinition{ObjectCode:0xce, Mnemonic:"DEC", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0x6c:InstructionDefinition{ObjectCode:0x6c, Mnemonic:"JMP", Bytes:3, Cycles:5, AddressingMode:5, PageSensitive:false, Effect:3}, 0x10:InstructionDefinition{ObjectCode:0x10, Mnemonic:"BPL", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x98:InstructionDefinition{ObjectCode:0x98, Mnemonic:"TYA", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xc5:InstructionDefinition{ObjectCode:0xc5, Mnemonic:"CMP", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x24:InstructionDefinition{ObjectCode:0x24, Mnemonic:"BIT", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xf6:InstructionDefinition{ObjectCode:0xf6, Mnemonic:"INC", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0x78:InstructionDefinition{ObjectCode:0x78, Mnemonic:"SEI", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x15:InstructionDefinition{ObjectCode:0x15, Mnemonic:"ORA", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0xac:InstructionDefinition{ObjectCode:0xac, Mnemonic:"LDY", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0xe1:InstructionDefinition{ObjectCode:0xe1, Mnemonic:"SBC", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0xdd:InstructionDefinition{ObjectCode:0xdd, Mnemonic:"CMP", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0xc0:InstructionDefinition{ObjectCode:0xc0, Mnemonic:"CPY", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xf8:InstructionDefinition{ObjectCode:0xf8, Mnemonic:"SED", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x8:InstructionDefinition{ObjectCode:0x8, Mnemonic:"PHP", Bytes:1, Cycles:3, AddressingMode:0, PageSensitive:false, Effect:1}, 0xad:InstructionDefinition{ObjectCode:0xad, Mnemonic:"LDA", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x86:InstructionDefinition{ObjectCode:0x86, Mnemonic:"STX", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:1}, 0xa7:InstructionDefinition{ObjectCode:0xa7, Mnemonic:"lax", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x4e:InstructionDefinition{ObjectCode:0x4e, Mnemonic:"LSR", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0x8c:InstructionDefinition{ObjectCode:0x8c, Mnemonic:"STY", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:1}, 0xe6:InstructionDefinition{ObjectCode:0xe6, Mnemonic:"INC", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0xb0:InstructionDefinition{ObjectCode:0xb0, Mnemonic:"BCS", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x6:InstructionDefinition{ObjectCode:0x6, Mnemonic:"ASL", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0x4a:InstructionDefinition{ObjectCode:0x4a, Mnemonic:"LSR", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x46:InstructionDefinition{ObjectCode:0x46, Mnemonic:"LSR", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0xc4:InstructionDefinition{ObjectCode:0xc4, Mnemonic:"CPY", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x95:InstructionDefinition{ObjectCode:0x95, Mnemonic:"STA", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:1}, 0xf0:InstructionDefinition{ObjectCode:0xf0, Mnemonic:"BEQ", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x65:InstructionDefinition{ObjectCode:0x65, Mnemonic:"ADC", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xe5:InstructionDefinition{ObjectCode:0xe5, Mnemonic:"SBC", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x91:InstructionDefinition{ObjectCode:0x91, Mnemonic:"STA", Bytes:2, Cycles:6, AddressingMode:7, PageSensitive:false, Effect:1}, 0x8e:InstructionDefinition{ObjectCode:0x8e, Mnemonic:"STX", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:1}, 0x28:InstructionDefinition{ObjectCode:0x28, Mnemonic:"PLP", Bytes:1, Cycles:4, AddressingMode:0, PageSensitive:false, Effect:0}, 0x11:InstructionDefinition{ObjectCode:0x11, Mnemonic:"ORA", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0x7d:InstructionDefinition{ObjectCode:0x7d, Mnemonic:"ADC", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0xed:InstructionDefinition{ObjectCode:0xed, Mnemonic:"SBC", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x81:InstructionDefinition{ObjectCode:0x81, Mnemonic:"STA", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:1}, 0x20:InstructionDefinition{ObjectCode:0x20, Mnemonic:"JSR", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:4}, 0xea:InstructionDefinition{ObjectCode:0xea, Mnemonic:"NOP", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x9:InstructionDefinition{ObjectCode:0x9, Mnemonic:"ORA", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xe8:InstructionDefinition{ObjectCode:0xe8, Mnemonic:"INX", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x16:InstructionDefinition{ObjectCode:0x16, Mnemonic:"ASL", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0xe:InstructionDefinition{ObjectCode:0xe, Mnemonic:"ASL", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0x99:InstructionDefinition{ObjectCode:0x99, Mnemonic:"STA", Bytes:3, Cycles:5, AddressingMode:9, PageSensitive:false, Effect:1}, 0x79:InstructionDefinition{ObjectCode:0x79, Mnemonic:"ADC", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0x6e:InstructionDefinition{ObjectCode:0x6e, Mnemonic:"ROR", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0xee:InstructionDefinition{ObjectCode:0xee, Mnemonic:"INC", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0x48:InstructionDefinition{ObjectCode:0x48, Mnemonic:"PHA", Bytes:1, Cycles:3, AddressingMode:0, PageSensitive:false, Effect:1}, 0xec:InstructionDefinition{ObjectCode:0xec, Mnemonic:"CPX", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x1:InstructionDefinition{ObjectCode:0x1, Mnemonic:"ORA", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0x7e:InstructionDefinition{ObjectCode:0x7e, Mnemonic:"ROR", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0x39:InstructionDefinition{ObjectCode:0x39, Mnemonic:"AND", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0x31:InstructionDefinition{ObjectCode:0x31, Mnemonic:"AND", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0xa:InstructionDefinition{ObjectCode:0xa, Mnemonic:"ASL", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x26:InstructionDefinition{ObjectCode:0x26, Mnemonic:"ROL", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0x94:InstructionDefinition{ObjectCode:0x94, Mnemonic:"STY", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:1}, 0x68:InstructionDefinition{ObjectCode:0x68, Mnemonic:"PLA", Bytes:1, Cycles:4, AddressingMode:0, PageSensitive:false, Effect:0}, 0xbd:InstructionDefinition{ObjectCode:0xbd, Mnemonic:"LDA", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0xd6:InstructionDefinition{ObjectCode:0xd6, Mnemonic:"DEC", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0xd0:InstructionDefinition{ObjectCode:0xd0, Mnemonic:"BNE", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0xaa:InstructionDefinition{ObjectCode:0xaa, Mnemonic:"TAX", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x4d:InstructionDefinition{ObjectCode:0x4d, Mnemonic:"EOR", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x3d:InstructionDefinition{ObjectCode:0x3d, Mnemonic:"AND", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0xa6:InstructionDefinition{ObjectCode:0xa6, Mnemonic:"LDX", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xb4:InstructionDefinition{ObjectCode:0xb4, Mnemonic:"LDY", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0x1e:InstructionDefinition{ObjectCode:0x1e, Mnemonic:"ASL", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0xe9:InstructionDefinition{ObjectCode:0xe9, Mnemonic:"SBC", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xb8:InstructionDefinition{ObjectCode:0xb8, Mnemonic:"CLV", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x41:InstructionDefinition{ObjectCode:0x41, Mnemonic:"EOR", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0xa5:InstructionDefinition{ObjectCode:0xa5, Mnemonic:"LDA", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x56:InstructionDefinition{ObjectCode:0x56, Mnemonic:"LSR", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0x75:InstructionDefinition{ObjectCode:0x75, Mnemonic:"ADC", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0xa8:InstructionDefinition{ObjectCode:0xa8, Mnemonic:"TAY", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x9a:InstructionDefinition{ObjectCode:0x9a, Mnemonic:"TXS", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x59:InstructionDefinition{ObjectCode:0x59, Mnemonic:"EOR", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0x66:InstructionDefinition{ObjectCode:0x66, Mnemonic:"ROR", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0xd9:InstructionDefinition{ObjectCode:0xd9, Mnemonic:"CMP", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0x96:InstructionDefinition{ObjectCode:0x96, Mnemonic:"STX", Bytes:2, Cycles:4, AddressingMode:11, PageSensitive:false, Effect:1}, 0x18:InstructionDefinition{ObjectCode:0x18, Mnemonic:"CLC", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xbe:InstructionDefinition{ObjectCode:0xbe, Mnemonic:"LDX", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0xbc:InstructionDefinition{ObjectCode:0xbc, Mnemonic:"LDY", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0x76:InstructionDefinition{ObjectCode:0x76, Mnemonic:"ROR", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0x36:InstructionDefinition{ObjectCode:0x36, Mnemonic:"ROL", Bytes:2, Cycles:6, AddressingMode:10, PageSensitive:false, Effect:2}, 0x60:InstructionDefinition{ObjectCode:0x60, Mnemonic:"RTS", Bytes:1, Cycles:6, AddressingMode:0, PageSensitive:false, Effect:4}, 0xcd:InstructionDefinition{ObjectCode:0xcd, Mnemonic:"CMP", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x38:InstructionDefinition{ObjectCode:0x38, Mnemonic:"SEC", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x49:InstructionDefinition{ObjectCode:0x49, Mnemonic:"EOR", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0x45:InstructionDefinition{ObjectCode:0x45, Mnemonic:"EOR", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xa2:InstructionDefinition{ObjectCode:0xa2, Mnemonic:"LDX", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xb6:InstructionDefinition{ObjectCode:0xb6, Mnemonic:"LDX", Bytes:2, Cycles:4, AddressingMode:11, PageSensitive:false, Effect:0}, 0xfd:InstructionDefinition{ObjectCode:0xfd, Mnemonic:"SBC", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0x2e:InstructionDefinition{ObjectCode:0x2e, Mnemonic:"ROL", Bytes:3, Cycles:6, AddressingMode:3, PageSensitive:false, Effect:2}, 0xcc:InstructionDefinition{ObjectCode:0xcc, Mnemonic:"CPY", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x50:InstructionDefinition{ObjectCode:0x50, Mnemonic:"BVC", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0xba:InstructionDefinition{ObjectCode:0xba, Mnemonic:"TSX", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xa1:InstructionDefinition{ObjectCode:0xa1, Mnemonic:"LDA", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0x5e:InstructionDefinition{ObjectCode:0x5e, Mnemonic:"LSR", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0xc6:InstructionDefinition{ObjectCode:0xc6, Mnemonic:"DEC", Bytes:2, Cycles:5, AddressingMode:4, PageSensitive:false, Effect:2}, 0x25:InstructionDefinition{ObjectCode:0x25, Mnemonic:"AND", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x61:InstructionDefinition{ObjectCode:0x61, Mnemonic:"ADC", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0x2a:InstructionDefinition{ObjectCode:0x2a, Mnemonic:"ROL", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x70:InstructionDefinition{ObjectCode:0x70, Mnemonic:"BVS", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x58:InstructionDefinition{ObjectCode:0x58, Mnemonic:"CLI", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x5:InstructionDefinition{ObjectCode:0x5, Mnemonic:"ORA", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x21:InstructionDefinition{ObjectCode:0x21, Mnemonic:"AND", Bytes:2, Cycles:6, AddressingMode:6, PageSensitive:false, Effect:0}, 0xa0:InstructionDefinition{ObjectCode:0xa0, Mnemonic:"LDY", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xde:InstructionDefinition{ObjectCode:0xde, Mnemonic:"DEC", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}, 0x90:InstructionDefinition{ObjectCode:0x90, Mnemonic:"BCC", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x5d:InstructionDefinition{ObjectCode:0x5d, Mnemonic:"EOR", Bytes:3, Cycles:4, AddressingMode:8, PageSensitive:true, Effect:0}, 0xd:InstructionDefinition{ObjectCode:0xd, Mnemonic:"ORA", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0x6d:InstructionDefinition{ObjectCode:0x6d, Mnemonic:"ADC", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:0}, 0xd5:InstructionDefinition{ObjectCode:0xd5, Mnemonic:"CMP", Bytes:2, Cycles:4, AddressingMode:10, PageSensitive:false, Effect:0}, 0x84:InstructionDefinition{ObjectCode:0x84, Mnemonic:"STY", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:1}, 0x30:InstructionDefinition{ObjectCode:0x30, Mnemonic:"BMI", Bytes:2, Cycles:2, AddressingMode:2, PageSensitive:false, Effect:3}, 0x4:InstructionDefinition{ObjectCode:0x4, Mnemonic:"dop", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0xc8:InstructionDefinition{ObjectCode:0xc8, Mnemonic:"INY", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0x4c:InstructionDefinition{ObjectCode:0x4c, Mnemonic:"JMP", Bytes:3, Cycles:3, AddressingMode:3, PageSensitive:false, Effect:3}, 0x8d:InstructionDefinition{ObjectCode:0x8d, Mnemonic:"STA", Bytes:3, Cycles:4, AddressingMode:3, PageSensitive:false, Effect:1}, 0x51:InstructionDefinition{ObjectCode:0x51, Mnemonic:"EOR", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0x88:InstructionDefinition{ObjectCode:0x88, Mnemonic:"DEY", Bytes:1, Cycles:2, AddressingMode:0, PageSensitive:false, Effect:0}, 0xf9:InstructionDefinition{ObjectCode:0xf9, Mnemonic:"SBC", Bytes:3, Cycles:4, AddressingMode:9, PageSensitive:true, Effect:0}, 0xf1:InstructionDefinition{ObjectCode:0xf1, Mnemonic:"SBC", Bytes:2, Cycles:5, AddressingMode:7, PageSensitive:true, Effect:0}, 0xe0:InstructionDefinition{ObjectCode:0xe0, Mnemonic:"CPX", Bytes:2, Cycles:2, AddressingMode:1, PageSensitive:false, Effect:0}, 0xe4:InstructionDefinition{ObjectCode:0xe4, Mnemonic:"CPX", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:0}, 0x85:InstructionDefinition{ObjectCode:0x85, Mnemonic:"STA", Bytes:2, Cycles:3, AddressingMode:4, PageSensitive:false, Effect:1}, 0xfe:InstructionDefinition{ObjectCode:0xfe, Mnemonic:"INC", Bytes:3, Cycles:7, AddressingMode:8, PageSensitive:false, Effect:2}}, nil } \ No newline at end of file diff --git a/hardware/cpu/instruction_result.go b/hardware/cpu/instruction_result.go index bc157474..e0572464 100644 --- a/hardware/cpu/instruction_result.go +++ b/hardware/cpu/instruction_result.go @@ -51,6 +51,8 @@ func (result InstructionResult) GetString(symtable *symbols.Table, style symbols var operator, operand string var notes string + // include instruction address (and label) if this is the final result for + // this particular instruction if result.Final { programCounter = fmt.Sprintf("0x%04x", result.Address) if symtable != nil && style.Has(symbols.StyleFlagLocation) { @@ -67,7 +69,7 @@ func (result InstructionResult) GetString(symtable *symbols.Table, style symbols operator = result.Defn.Mnemonic } - // parse instrution result data ... + // parse instruction result data ... var idx uint16 switch result.InstructionData.(type) { case uint8: @@ -85,7 +87,7 @@ func (result InstructionResult) GetString(symtable *symbols.Table, style symbols } // ... and use assembler symbol for the operand if available/appropriate - if symtable != nil && style.Has(symbols.StyleFlagSymbols) && result.InstructionData != nil && (operand == "" || operand[0] != '?') { + if symtable.Valid && style.Has(symbols.StyleFlagSymbols) && result.InstructionData != nil && (operand == "" || operand[0] != '?') { if result.Defn.AddressingMode != definitions.Immediate { switch result.Defn.Effect { @@ -183,12 +185,12 @@ func (result InstructionResult) GetString(symtable *symbols.Table, style symbols if style.Has(symbols.StyleFlagColumns) { programCounter = columnise(programCounter, 6) operator = columnise(operator, 3) - if symtable != nil { + if symtable.Valid { label = columnise(label, symtable.MaxLocationWidth) operand = columnise(operand, symtable.MaxSymbolWidth) } else { - label = columnise(label, 10) - operand = columnise(operand, 10) + label = columnise(label, 0) + operand = columnise(operand, 7) } } diff --git a/hardware/tia/hmove.go b/hardware/tia/hmove.go index a1f7f83b..0a3499d7 100644 --- a/hardware/tia/hmove.go +++ b/hardware/tia/hmove.go @@ -61,13 +61,13 @@ func (hm *hmove) set() { hm.phase = hm.colorClock.Phase } -func (hm *hmove) tick() int { +func (hm *hmove) tick() (ct int, tick bool) { // if hmove is active, when color clock phase cycles to where it was when // hmove.set() was called reduce the hmove count - ct := 0 if hm.count > 0 && hm.phase == hm.colorClock.Phase { ct = hm.count hm.count-- + tick = true } - return ct + return ct, tick } diff --git a/hardware/tia/tia.go b/hardware/tia/tia.go index 7621f244..26c104c6 100644 --- a/hardware/tia/tia.go +++ b/hardware/tia/tia.go @@ -167,7 +167,9 @@ func (tia *TIA) StepVideoCycle() bool { } // HMOVE clock stuffing - tia.Video.TickSpritesForHMOVE(tia.hmove.tick()) + if ct, ok := tia.hmove.tick(); ok { + tia.Video.TickSpritesForHMOVE(ct) + } // tick all video elements tia.Video.Tick() diff --git a/hardware/tia/video/ball.go b/hardware/tia/video/ball.go index fe4dccb4..81b8bd39 100644 --- a/hardware/tia/video/ball.go +++ b/hardware/tia/video/ball.go @@ -117,5 +117,5 @@ func (bs *ballSprite) scheduleReset(hblank *bool) { } func (bs *ballSprite) scheduleEnable(value uint8) { - bs.futureEnable.schedule(delayEnableBall, value&0x20 == 0x20) + bs.futureEnable.schedule(delayEnableBall, value&0x02 == 0x02) } diff --git a/hardware/tia/video/player.go b/hardware/tia/video/player.go index 340b1776..b05ad888 100644 --- a/hardware/tia/video/player.go +++ b/hardware/tia/video/player.go @@ -13,6 +13,7 @@ type playerSprite struct { color uint8 gfxData uint8 gfxDataPrev uint8 + gfxDataDelay *uint8 size uint8 reflected bool verticalDelay bool @@ -33,8 +34,10 @@ func newPlayerSprite(label string, colorClock *colorclock.ColorClock) *playerSpr func (ps playerSprite) MachineInfoTerse() string { gfxData := ps.gfxData + vdel := "" if ps.verticalDelay { - gfxData = ps.gfxDataPrev + gfxData = *ps.gfxDataDelay + vdel = " v" } ref := " " if ps.reflected { @@ -49,7 +52,7 @@ func (ps playerSprite) MachineInfoTerse() string { visPix++ } - return fmt.Sprintf("%s (vis: %d) gfx: %s %08b", ps.sprite.MachineInfoTerse(), visPix, ref, gfxData) + return fmt.Sprintf("%s (vis: %d, hm: %d) gfx: %s %08b%s", ps.sprite.MachineInfoTerse(), visPix, ps.horizMovement-8, ref, gfxData, vdel) } // MachineInfo returns the missile sprite information in verbose format @@ -103,9 +106,10 @@ func (ps *playerSprite) pixel() (bool, uint8) { // vertical delay gfxData := ps.gfxData if ps.verticalDelay { - gfxData = ps.gfxDataPrev + gfxData = *ps.gfxDataDelay } + // reflection if ps.reflected { gfxData = bits.Reverse8(gfxData) } @@ -132,8 +136,3 @@ func (ps *playerSprite) scheduleReset(hblank *bool) { ps.futureReset.schedule(delayResetPlayer, true) } } - -func (ps *playerSprite) setData(data uint8) { - ps.gfxDataPrev = ps.gfxData - ps.gfxData = data -} diff --git a/hardware/tia/video/sprite.go b/hardware/tia/video/sprite.go index 9bcac597..756ed0b4 100644 --- a/hardware/tia/video/sprite.go +++ b/hardware/tia/video/sprite.go @@ -37,6 +37,9 @@ type sprite struct { drawSigCount int drawSigMax int drawSigOff int + + // the amount of horizontal movement for the sprite + horizMovement uint8 } func newSprite(label string, colorClock *colorclock.ColorClock) *sprite { diff --git a/hardware/tia/video/video.go b/hardware/tia/video/video.go index 2707e229..56dfda95 100644 --- a/hardware/tia/video/video.go +++ b/hardware/tia/video/video.go @@ -18,13 +18,6 @@ type Video struct { Missile0 *missileSprite Missile1 *missileSprite Ball *ballSprite - - // horizontal movement - hmp0 uint8 - hmp1 uint8 - hmm0 uint8 - hmm1 uint8 - hmbl uint8 } // New is the preferred method of initialisation for the Video structure @@ -62,12 +55,9 @@ func New(colorClock *colorclock.ColorClock, hblank *bool) *Video { return nil } - // horizontal movment - vd.hmp0 = 0x08 - vd.hmp1 = 0x08 - vd.hmm0 = 0x08 - vd.hmm1 = 0x08 - vd.hmbl = 0x08 + // connect player 0 and player 1 to each other (via the vertical delay bit) + vd.Player0.gfxDataDelay = &vd.Player1.gfxDataPrev + vd.Player1.gfxDataDelay = &vd.Player0.gfxDataPrev return vd } @@ -90,19 +80,19 @@ func (vd *Video) TickSpritesForHMOVE(count int) { return } - if vd.hmp0 >= uint8(count) { + if vd.Player0.horizMovement >= uint8(count) { vd.Player0.tick() } - if vd.hmp1 >= uint8(count) { + if vd.Player1.horizMovement >= uint8(count) { vd.Player1.tick() } - if vd.hmm0 >= uint8(count) { + if vd.Missile0.horizMovement >= uint8(count) { vd.Missile0.tick() } - if vd.hmm1 >= uint8(count) { + if vd.Missile1.horizMovement >= uint8(count) { vd.Missile1.tick() } - if vd.hmbl >= uint8(count) { + if vd.Ball.horizMovement >= uint8(count) { vd.Ball.tick() } } @@ -236,9 +226,11 @@ func (vd *Video) ReadVideoMemory(register string, value uint8) bool { case "RESBL": vd.Ball.scheduleReset(vd.hblank) case "GRP0": - vd.Player0.setData(value) + vd.Player0.gfxDataPrev = vd.Player1.gfxData + vd.Player0.gfxData = value case "GRP1": - vd.Player1.setData(value) + vd.Player1.gfxDataPrev = vd.Player0.gfxData + vd.Player1.gfxData = value case "ENAM0": vd.Missile0.scheduleEnable(value) case "ENAM1": @@ -246,15 +238,15 @@ func (vd *Video) ReadVideoMemory(register string, value uint8) bool { case "ENABL": vd.Ball.scheduleEnable(value) case "HMP0": - vd.hmp0 = (value ^ 0x80) >> 4 + vd.Player0.horizMovement = (value ^ 0x80) >> 4 case "HMP1": - vd.hmp1 = (value ^ 0x80) >> 4 + vd.Player1.horizMovement = (value ^ 0x80) >> 4 case "HMM0": - vd.hmm0 = (value ^ 0x80) >> 4 + vd.Missile0.horizMovement = (value ^ 0x80) >> 4 case "HMM1": - vd.hmm1 = (value ^ 0x80) >> 4 + vd.Missile1.horizMovement = (value ^ 0x80) >> 4 case "HMBL": - vd.hmbl = (value ^ 0x80) >> 4 + vd.Ball.horizMovement = (value ^ 0x80) >> 4 case "VDELP0": vd.Player0.verticalDelay = value&0x01 == 0x01 case "VDELP1": @@ -264,11 +256,11 @@ func (vd *Video) ReadVideoMemory(register string, value uint8) bool { case "RESMP0": case "RESMP1": case "HMCLR": - vd.hmp0 = 0x08 - vd.hmp1 = 0x08 - vd.hmm0 = 0x08 - vd.hmm1 = 0x08 - vd.hmbl = 0x08 + vd.Player0.horizMovement = 0x08 + vd.Player1.horizMovement = 0x08 + vd.Missile0.horizMovement = 0x08 + vd.Missile1.horizMovement = 0x08 + vd.Ball.horizMovement = 0x08 case "CXCLR": }