mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-08-15 06:27:44 +00:00
More addressing modes for LDA
This commit is contained in:
82
execute.go
82
execute.go
@@ -14,53 +14,15 @@ const modeImmediate = 0
|
|||||||
const modeZeroPage = 1
|
const modeZeroPage = 1
|
||||||
const modeZeroPageX = 3
|
const modeZeroPageX = 3
|
||||||
const modeAbsolute = 2
|
const modeAbsolute = 2
|
||||||
|
const modeAbsoluteX = 4
|
||||||
|
const modeAbsoluteY = 5
|
||||||
|
|
||||||
// https://www.masswerk.at/6502/6502_instruction_set.html
|
// https://www.masswerk.at/6502/6502_instruction_set.html
|
||||||
|
|
||||||
func opLDAimm(s *state, line []uint8) {
|
|
||||||
opLDR(s, line, regA, modeImmediate)
|
|
||||||
}
|
|
||||||
|
|
||||||
func opLDAzpg(s *state, line []uint8) {
|
|
||||||
opLDR(s, line, regA, modeZeroPage)
|
|
||||||
}
|
|
||||||
|
|
||||||
func opLDYimm(s *state, line []uint8) {
|
|
||||||
opLDR(s, line, regY, modeImmediate)
|
|
||||||
}
|
|
||||||
|
|
||||||
func opLDAzpgX(s *state, line []uint8) {
|
|
||||||
opLDR(s, line, regA, modeZeroPageX)
|
|
||||||
}
|
|
||||||
|
|
||||||
func opLDAabs(s *state, line []uint8) {
|
|
||||||
opLDR(s, line, regA, modeAbsolute)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getWordInLine(line []uint8) uint16 {
|
func getWordInLine(line []uint8) uint16 {
|
||||||
return uint16(line[1]) + 0x100*uint16(line[2])
|
return uint16(line[1]) + 0x100*uint16(line[2])
|
||||||
}
|
}
|
||||||
|
|
||||||
func opLDR(s *state, line []uint8, reg int, mode int) {
|
|
||||||
var value uint8
|
|
||||||
switch mode {
|
|
||||||
case modeImmediate:
|
|
||||||
value = line[1]
|
|
||||||
case modeZeroPage:
|
|
||||||
address := line[1]
|
|
||||||
value = s.memory[address]
|
|
||||||
case modeZeroPageX:
|
|
||||||
address := line[1] + s.registers.getRegister(regX)
|
|
||||||
value = s.memory[address]
|
|
||||||
case modeAbsolute:
|
|
||||||
address := getWordInLine(line)
|
|
||||||
value = s.memory[address]
|
|
||||||
}
|
|
||||||
|
|
||||||
s.registers.setRegister(reg, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
type opFunc func(s *state, line []uint8, opcode opcode)
|
|
||||||
type opcode struct {
|
type opcode struct {
|
||||||
name string
|
name string
|
||||||
bytes int
|
bytes int
|
||||||
@@ -70,18 +32,44 @@ type opcode struct {
|
|||||||
action opFunc
|
action opFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type opFunc func(s *state, line []uint8, opcode opcode)
|
||||||
|
|
||||||
func opNOP(s *state, line []uint8, opcode opcode) {}
|
func opNOP(s *state, line []uint8, opcode opcode) {}
|
||||||
func opLDRex(s *state, line []uint8, opcode opcode) {
|
|
||||||
opLDR(s, line, opcode.reg, opcode.mode)
|
func opLDR(s *state, line []uint8, opcode opcode) {
|
||||||
|
var value uint8
|
||||||
|
switch opcode.mode {
|
||||||
|
case modeImmediate:
|
||||||
|
value = line[1]
|
||||||
|
case modeZeroPage:
|
||||||
|
address := line[1]
|
||||||
|
value = s.memory[address]
|
||||||
|
case modeZeroPageX:
|
||||||
|
address := line[1] + s.registers.getX()
|
||||||
|
value = s.memory[address]
|
||||||
|
case modeAbsolute:
|
||||||
|
address := getWordInLine(line)
|
||||||
|
value = s.memory[address]
|
||||||
|
case modeAbsoluteX:
|
||||||
|
address := getWordInLine(line) + uint16(s.registers.getX())
|
||||||
|
value = s.memory[address]
|
||||||
|
case modeAbsoluteY:
|
||||||
|
address := getWordInLine(line) + uint16(s.registers.getY())
|
||||||
|
value = s.memory[address]
|
||||||
|
}
|
||||||
|
|
||||||
|
s.registers.setRegister(opcode.reg, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
var opcodes = [256]opcode{
|
var opcodes = [256]opcode{
|
||||||
0x00: opcode{"BRK", 1, 7, modeImmediate, regNone, opNOP},
|
0x00: opcode{"BRK", 1, 7, modeImmediate, regNone, opNOP},
|
||||||
0xA0: opcode{"LDY", -1, -1, modeImmediate, regY, opLDRex},
|
0xA0: opcode{"LDY", 2, 2, modeImmediate, regY, opLDR},
|
||||||
0xA5: opcode{"LDA", 2, 3, modeZeroPage, regA, opLDRex},
|
0xA5: opcode{"LDA", 2, 3, modeZeroPage, regA, opLDR},
|
||||||
0xB5: opcode{"LDA", 2, 4, modeZeroPageX, regA, opLDRex},
|
0xB5: opcode{"LDA", 2, 4, modeZeroPageX, regA, opLDR},
|
||||||
0xA9: opcode{"LDA", 2, 2, modeImmediate, regA, opLDRex},
|
0xA9: opcode{"LDA", 2, 2, modeImmediate, regA, opLDR},
|
||||||
0xAD: opcode{"LDA", 3, 4, modeAbsolute, regA, opLDRex},
|
0xAD: opcode{"LDA", 3, 4, modeAbsolute, regA, opLDR},
|
||||||
|
0xB9: opcode{"LDA", 3, 4, modeAbsoluteY, regA, opLDR}, // Extra cycles
|
||||||
|
0xBD: opcode{"LDA", 3, 4, modeAbsoluteX, regA, opLDR}, // Extra cycles
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeLine(s *state, line []uint8) {
|
func executeLine(s *state, line []uint8) {
|
||||||
|
@@ -7,47 +7,6 @@ import (
|
|||||||
func TestLDA(t *testing.T) {
|
func TestLDA(t *testing.T) {
|
||||||
var s state
|
var s state
|
||||||
|
|
||||||
opLDAimm(&s, []uint8{0xA9, 0x42})
|
|
||||||
if s.registers.getA() != 0x42 {
|
|
||||||
t.Error("Error in LDA #")
|
|
||||||
}
|
|
||||||
|
|
||||||
opLDYimm(&s, []uint8{0xA0, 0xFE})
|
|
||||||
if s.registers.getY() != 0xFE {
|
|
||||||
t.Error("Error in LDY #")
|
|
||||||
}
|
|
||||||
|
|
||||||
s.memory[0x38] = 0x87
|
|
||||||
opLDAzpg(&s, []uint8{0xA5, 0x38})
|
|
||||||
if s.registers.getA() != 0x87 {
|
|
||||||
t.Error("Error in LDA zpg")
|
|
||||||
}
|
|
||||||
|
|
||||||
s.memory[0x57] = 0x90
|
|
||||||
s.registers.setX(0x10)
|
|
||||||
opLDAzpgX(&s, []uint8{0xB5, 0x47})
|
|
||||||
if s.registers.getA() != 0x90 {
|
|
||||||
t.Error("Error in LDA zpgX")
|
|
||||||
}
|
|
||||||
|
|
||||||
s.memory[0x38] = 0x12
|
|
||||||
s.registers.setX(0x89)
|
|
||||||
opLDAzpgX(&s, []uint8{0xB5, 0xAF})
|
|
||||||
if s.registers.getA() != 0x12 {
|
|
||||||
t.Error("Error in LDA zpgX with sero page overflow")
|
|
||||||
}
|
|
||||||
|
|
||||||
s.memory[0x1234] = 0x67
|
|
||||||
opLDAabs(&s, []uint8{0xAD, 0x34, 0x12})
|
|
||||||
if s.registers.getA() != 0x67 {
|
|
||||||
t.Error("Error in LDA abs")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLDA2(t *testing.T) {
|
|
||||||
var s state
|
|
||||||
|
|
||||||
executeLine(&s, []uint8{0xA9, 0x42})
|
executeLine(&s, []uint8{0xA9, 0x42})
|
||||||
if s.registers.getA() != 0x42 {
|
if s.registers.getA() != 0x42 {
|
||||||
t.Error("Error in LDA #")
|
t.Error("Error in LDA #")
|
||||||
@@ -68,7 +27,7 @@ func TestLDA2(t *testing.T) {
|
|||||||
s.registers.setX(0x10)
|
s.registers.setX(0x10)
|
||||||
executeLine(&s, []uint8{0xB5, 0x47})
|
executeLine(&s, []uint8{0xB5, 0x47})
|
||||||
if s.registers.getA() != 0x90 {
|
if s.registers.getA() != 0x90 {
|
||||||
t.Error("Error in LDA zpgX")
|
t.Error("Error in LDA zpg, X")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.memory[0x38] = 0x12
|
s.memory[0x38] = 0x12
|
||||||
@@ -84,4 +43,18 @@ func TestLDA2(t *testing.T) {
|
|||||||
t.Error("Error in LDA abs")
|
t.Error("Error in LDA abs")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.memory[0xC057] = 0x7E
|
||||||
|
s.registers.setX(0x57)
|
||||||
|
executeLine(&s, []uint8{0xBD, 0x00, 0xC0})
|
||||||
|
if s.registers.getA() != 0x7E {
|
||||||
|
t.Error("Error in LDA abs, X")
|
||||||
|
}
|
||||||
|
|
||||||
|
s.memory[0xD059] = 0x7A
|
||||||
|
s.registers.setY(0x59)
|
||||||
|
executeLine(&s, []uint8{0xB9, 0x00, 0xD0})
|
||||||
|
if s.registers.getA() != 0x7A {
|
||||||
|
t.Error("Error in LDA abs, Y")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user