Loads ROM, shows APPLE ][ logo. Freezes on . Next to implement the soft switches in page

This commit is contained in:
Ivan Izaguirre 2019-02-15 00:41:56 +01:00
parent 49f2436c7b
commit 1a6e9e006a
3 changed files with 113 additions and 36 deletions

20
main.go
View File

@ -1,21 +1,14 @@
package main package main
import "fmt"
func main() { func main() {
var s state var s state
s.memory.loadBinary("6502_65C02_functional_tests/bin_files/6502_functional_test.bin") var t textPages
s.registers.setPC(0x0400) s.memory.initWithRomAndText("../roms/APPLE2.ROM", &t)
startAddress := s.memory.getWord(0xfffc)
s.registers.setPC(startAddress)
for true { for true {
testCase := s.memory.peek(0x0200) log := true
if testCase >= 240 {
break
}
log := testCase > 43
if log {
fmt.Printf("[ %d ] ", testCase)
}
pc := s.registers.getPC() pc := s.registers.getPC()
executeInstruction(&s, log) executeInstruction(&s, log)
if pc == s.registers.getPC() { if pc == s.registers.getPC() {
@ -23,7 +16,6 @@ func main() {
//s.memory.printPage(0x01) //s.memory.printPage(0x01)
panic("No change in PC") panic("No change in PC")
} }
t.dumpIfDirty()
} }
fmt.Printf("Test completed\n")
} }

View File

@ -9,40 +9,56 @@ import (
type memoryPage interface { type memoryPage interface {
peek(uint8) uint8 peek(uint8) uint8
poke(uint8, uint8) poke(uint8, uint8)
getData() *[256]uint8
} }
type ramPage [256]uint8 type ramPage struct {
type romPage [256]uint8 data [256]uint8
}
type memory [256]memoryPage type romPage struct {
data [256]uint8
}
type memory struct {
data [256]memoryPage
}
func (p *ramPage) peek(address uint8) uint8 { func (p *ramPage) peek(address uint8) uint8 {
return p[address] return p.data[address]
} }
func (p *ramPage) poke(address uint8, value uint8) { func (p *ramPage) poke(address uint8, value uint8) {
p[address] = value p.data[address] = value
}
func (p *ramPage) getData() *[256]uint8 {
return &p.data
} }
func (p *romPage) peek(address uint8) uint8 { func (p *romPage) peek(address uint8) uint8 {
return p[address] return p.data[address]
} }
func (p *romPage) poke(address uint8, value uint8) { func (p *romPage) poke(address uint8, value uint8) {
// Do nothing // Do nothing
} }
func (p *romPage) getData() *[256]uint8 {
return &p.data
}
func (m *memory) peek(address uint16) uint8 { func (m *memory) peek(address uint16) uint8 {
hi := uint8(address >> 8) hi := uint8(address >> 8)
lo := uint8(address) lo := uint8(address)
return m[hi].peek(lo) return m.data[hi].peek(lo)
} }
func (m *memory) poke(address uint16, value uint8) { func (m *memory) poke(address uint16, value uint8) {
hi := uint8(address >> 8) hi := uint8(address >> 8)
lo := uint8(address) lo := uint8(address)
//fmt.Println(hi) //fmt.Println(hi)
m[hi].poke(lo, value) m.data[hi].poke(lo, value)
} }
func (m *memory) getWord(address uint16) uint16 { func (m *memory) getWord(address uint16) uint16 {
@ -56,7 +72,53 @@ func (m *memory) getZeroPageWord(address uint8) uint16 {
func (m *memory) initWithRam() { func (m *memory) initWithRam() {
var ramPages [256]ramPage var ramPages [256]ramPage
for i := 0; i < 256; i++ { for i := 0; i < 256; i++ {
m[i] = &ramPages[i] m.data[i] = &ramPages[i]
}
}
func (m *memory) transformToRom(page uint8) {
var romPage romPage
ramPage := m.data[page]
romPage.data = *ramPage.getData()
m.data[page] = &romPage
}
func (m *memory) initWithRomAndText(filename string, textPages *textPages) {
// Valid for ROMs with size 20480 bytes = 20 KB = 80 pages
// from $B000 to $F000
// Load file
f, err := os.Open(filename)
if err != nil {
panic(err)
}
defer f.Close()
stats, statsErr := f.Stat()
if statsErr != nil {
panic(err)
}
size := stats.Size()
if size != 20480 {
panic("Invalid ROM file size. It must be 20480 bytes")
}
bytes := make([]byte, size)
buf := bufio.NewReader(f)
buf.Read(bytes)
m.initWithRam()
for i, v := range bytes {
m.poke(uint16(i)+0xB000, uint8(v))
}
var i uint8
for i = 217; i != 0; i++ {
m.transformToRom(i)
}
for j := 0; j < 4; j++ {
m.data[4+i] = &textPages.pages[i]
} }
} }
@ -90,7 +152,7 @@ func (m *memory) printPage(page uint8) {
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
fmt.Printf("%#04x: ", address) fmt.Printf("%#04x: ", address)
for j := 0; j < 16; j++ { for j := 0; j < 16; j++ {
fmt.Printf("%02x ", m[address]) fmt.Printf("%02x ", m.data[address])
address++ address++
} }
fmt.Printf("\n") fmt.Printf("\n")

View File

@ -3,13 +3,12 @@ package main
import "fmt" import "fmt"
type textPages struct { type textPages struct {
dirty bool pages [4]textPage
pages *[4]textPage
} }
type textPage struct { type textPage struct {
textPages *textPages dirty bool
data [256]uint8 data [256]uint8
} }
func (p *textPage) peek(address uint8) uint8 { func (p *textPage) peek(address uint8) uint8 {
@ -19,40 +18,64 @@ func (p *textPage) peek(address uint8) uint8 {
func (p *textPage) poke(address uint8, value uint8) { func (p *textPage) poke(address uint8, value uint8) {
p.data[address] = value p.data[address] = value
// Note: we could avoid setting dirty on the 16 blocks of 8 hidden bytes // Note: we could avoid setting dirty on the 16 blocks of 8 hidden bytes
p.textPages.dirty = true p.dirty = true
}
func (p *textPage) getData() *[256]uint8 {
return &p.data
} }
func textMemoryByteToString(value uint8) string { func textMemoryByteToString(value uint8) string {
value = value & 0x7F
if value < ' ' {
return " "
}
return string(value) return string(value)
} }
func textMemoryByteToStringHex(value uint8) string {
return fmt.Sprintf("%02x ", value)
}
func (tp *textPages) dump() { func (tp *textPages) dump() {
// See "Understand the Apple II", page 5-10 // See "Understand the Apple II", page 5-10
// http://www.applelogic.org/files/UNDERSTANDINGTHEAII.pdf // http://www.applelogic.org/files/UNDERSTANDINGTHEAII.pdf
fmt.Println("------------------------------------------")
var i, j, h uint8 var i, j, h uint8
// Top, middle and botton screen // Top, middle and botton screen
for i = 0; i < 128; i = i + 40 { for i = 0; i < 120; i = i + 40 {
// Memory pages // Memory pages
for _, p := range tp.pages { for _, p := range tp.pages {
// The two half pages // The two half pages
for _, h = range []uint8{0, 128} { for _, h = range []uint8{0, 128} {
line := "" line := "|"
for j = i + h; j < i+h+40; j++ { for j = i + h; j < i+h+40; j++ {
line += string(p.peek(j)) line += textMemoryByteToString(p.peek(j))
} }
fmt.Println(line) fmt.Println(line + "|")
} }
} }
} }
fmt.Println("------------------------------------------")
} }
func (tp *textPages) dumpIfDirty() { func (tp *textPages) dumpIfDirty() {
if !tp.dirty { dirty := false
return for i := 0; i < 4; i++ {
if tp.pages[i].dirty {
dirty = true
tp.pages[i].dirty = false
}
} }
tp.dirty = false if !dirty {
return
}
tp.dump() tp.dump()
} }