Some undocumented NOPs for 6502

This commit is contained in:
Ivan Izaguirre 2021-09-26 18:25:11 +02:00
parent 2a7cf020ae
commit 76f9ae514e
4 changed files with 75 additions and 16 deletions

View File

@ -70,6 +70,7 @@ Portable emulator of an Apple II+ or //e. Written in Go.
- Single file executable with embedded ROMs and DOS 3.3
- Pause (thanks a2geek)
- Passes the [A2AUDIT 1.06](https://github.com/zellyn/a2audit) tests as II+, //e, and //e Enhanced.
- Partial pass ot the [ProcessorTests](https://github.com/TomHarte/ProcessorTests) for 6502 and 65c02. Failing test 6502/v1/20_55_13; flags N anv V issues with ADC; and missing some undocumented 6502 opcodes.
By default the following configuration is launched:

View File

@ -1,5 +1,19 @@
package core6502
/*
Tests from https://github.com/TomHarte/ProcessorTests
Know issues:
- Test 6502/v1/20_55_13
- Not implemented undocumented opcodes for NMOS
- Errors on flags N and V for ADC in BCD mode
The tests are disabled by defaut because they take long to run
and require a huge download.
To enable them, clone the repo https://github.com/TomHarte/ProcessorTests
and change the variables ProcessorTestsEnable and ProcessorTestsPath.
*/
import (
"encoding/json"
"fmt"
@ -7,6 +21,9 @@ import (
"testing"
)
var ProcessorTestsEnable = false
var ProcessorTestsPath = "/home/casa/code/ProcessorTests/"
type scenarioState struct {
Pc uint16
S uint8
@ -24,16 +41,14 @@ type scenario struct {
Cycles [][]interface{}
}
/*
Tests from https://github.com/TomHarte/ProcessorTests/tree/main/6502/v1
more work needed.
*/
func TestHarteNMOS6502(t *testing.T) {
t.Skip("Not ready to be used in CI")
if !ProcessorTestsEnable {
t.Skip("TomHarte/ProcessorTests are not enabled")
}
s := NewNMOS6502(nil) // Use to get the opcodes names
path := "/home/casa/code/ProcessorTests/6502/v1/"
path := ProcessorTestsPath + "6502/v1/"
for i := 0x00; i <= 0xff; i++ {
mnemonic := s.opcodes[i].name
if mnemonic != "" {
@ -54,11 +69,13 @@ func TestHarteNMOS6502(t *testing.T) {
}
func TestHarteCMOS65c02(t *testing.T) {
t.Skip("Not ready to be used in CI")
if !ProcessorTestsEnable {
t.Skip("TomHarte/ProcessorTests are not enabled")
}
s := NewCMOS65c02(nil) // Use to get the opcodes names
path := "/home/casa/code/ProcessorTests/wdc65c02/v1/"
path := ProcessorTestsPath + "wdc65c02/v1/"
for i := 0x00; i <= 0xff; i++ {
mnemonic := s.opcodes[i].name
opcode := fmt.Sprintf("%02x", i)

View File

@ -182,8 +182,51 @@ var opcodesNMOS6502 = [256]opcode{
0xEA: {"NOP", 1, 2, modeImplicit, opNOP},
// Undocumented opcodes, see http://bbc.nvg.org/doc/6502OpList.txt
0x1A: {"NOP", 1, 2, modeImplicit, opNOP}, // INC A in the 65c02
0xC2: {"NOP", 2, 2, modeImplicit, opNOP},
0x02: {"NOP", 1, 3, modeImplicit, opHALT},
/*
Undocumented opcodes,
see http://bbc.nvg.org/doc/6502OpList.txt
see https://www.nesdev.com/undocumented_opcodes.txt
*/
0x1A: {"NOP", 1, 2, modeImplicit, opNOP},
0x3A: {"NOP", 1, 2, modeImplicit, opNOP},
0x5A: {"NOP", 1, 2, modeImplicit, opNOP},
0x7A: {"NOP", 1, 2, modeImplicit, opNOP},
0xDA: {"NOP", 1, 2, modeImplicit, opNOP},
0xFA: {"NOP", 1, 2, modeImplicit, opNOP},
0x04: {"DOP", 2, 3, modeImplicit, opNOP},
0x14: {"DOP", 2, 4, modeImplicit, opNOP},
0x34: {"DOP", 2, 4, modeImplicit, opNOP},
0x44: {"DOP", 2, 3, modeImplicit, opNOP},
0x54: {"DOP", 2, 4, modeImplicit, opNOP},
0x64: {"DOP", 2, 3, modeImplicit, opNOP},
0x74: {"DOP", 2, 4, modeImplicit, opNOP},
0x80: {"DOP", 2, 2, modeImplicit, opNOP},
0x82: {"DOP", 2, 2, modeImplicit, opNOP},
0x89: {"DOP", 2, 2, modeImplicit, opNOP},
0xC2: {"DOP", 2, 2, modeImplicit, opNOP},
0xD4: {"DOP", 2, 4, modeImplicit, opNOP},
0xE2: {"DOP", 2, 2, modeImplicit, opNOP},
0xF4: {"DOP", 2, 4, modeImplicit, opNOP},
0x0C: {"TOP", 3, 3, modeImplicit, opNOP},
0x1C: {"TOP", 3, 4, modeImplicit, opNOP},
0x3C: {"TOP", 3, 4, modeImplicit, opNOP},
0x5C: {"TOP", 3, 4, modeImplicit, opNOP},
0x7C: {"TOP", 3, 4, modeImplicit, opNOP},
0xDC: {"TOP", 3, 4, modeImplicit, opNOP},
0xFC: {"TOP", 3, 4, modeImplicit, opNOP},
0x02: {"KIL", 1, 3, modeImplicit, opHALT},
0x12: {"KIL", 1, 3, modeImplicit, opHALT},
0x22: {"KIL", 1, 3, modeImplicit, opHALT},
0x32: {"KIL", 1, 3, modeImplicit, opHALT},
0x42: {"KIL", 1, 3, modeImplicit, opHALT},
0x52: {"KIL", 1, 3, modeImplicit, opHALT},
0x62: {"KIL", 1, 3, modeImplicit, opHALT},
0x72: {"KIL", 1, 3, modeImplicit, opHALT},
0x92: {"KIL", 1, 3, modeImplicit, opHALT},
0xB2: {"KIL", 1, 3, modeImplicit, opHALT},
0xD2: {"KIL", 1, 3, modeImplicit, opHALT},
0xF2: {"KIL", 1, 3, modeImplicit, opHALT},
}

View File

@ -181,16 +181,14 @@ func opADC(s *State, line []uint8, opcode opcode) {
totalBcd := uint8(totalBcdHi)<<4 + (uint8(totalBcdLo) & 0xf)
s.reg.setA(uint8(totalBcd))
s.reg.updateFlag(flagC, newCarry)
s.reg.updateFlagZN(truncated)
s.reg.updateFlag(flagV, signedTotal < -128 || signedTotal > 127)
} else {
s.reg.setA(truncated)
s.reg.updateFlag(flagC, total > 0xFF)
s.reg.updateFlagZN(truncated)
s.reg.updateFlag(flagV, signedTotal < -128 || signedTotal > 127)
}
// ZNV flags behave for BCD as if the operation was binary?
s.reg.updateFlagZN(truncated)
s.reg.updateFlag(flagV, signedTotal < -128 || signedTotal > 127)
}
func opADCAlt(s *State, line []uint8, opcode opcode) {