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
import "fmt"
func main() {
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 {
testCase := s.memory.peek(0x0200)
if testCase >= 240 {
break
}
log := testCase > 43
if log {
fmt.Printf("[ %d ] ", testCase)
}
log := true
pc := s.registers.getPC()
executeInstruction(&s, log)
if pc == s.registers.getPC() {
@ -23,7 +16,6 @@ func main() {
//s.memory.printPage(0x01)
panic("No change in PC")
}
t.dumpIfDirty()
}
fmt.Printf("Test completed\n")
}

View File

@ -9,40 +9,56 @@ import (
type memoryPage interface {
peek(uint8) uint8
poke(uint8, uint8)
getData() *[256]uint8
}
type ramPage [256]uint8
type romPage [256]uint8
type ramPage struct {
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 {
return p[address]
return p.data[address]
}
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 {
return p[address]
return p.data[address]
}
func (p *romPage) poke(address uint8, value uint8) {
// Do nothing
}
func (p *romPage) getData() *[256]uint8 {
return &p.data
}
func (m *memory) peek(address uint16) uint8 {
hi := uint8(address >> 8)
lo := uint8(address)
return m[hi].peek(lo)
return m.data[hi].peek(lo)
}
func (m *memory) poke(address uint16, value uint8) {
hi := uint8(address >> 8)
lo := uint8(address)
//fmt.Println(hi)
m[hi].poke(lo, value)
m.data[hi].poke(lo, value)
}
func (m *memory) getWord(address uint16) uint16 {
@ -56,7 +72,53 @@ func (m *memory) getZeroPageWord(address uint8) uint16 {
func (m *memory) initWithRam() {
var ramPages [256]ramPage
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++ {
fmt.Printf("%#04x: ", address)
for j := 0; j < 16; j++ {
fmt.Printf("%02x ", m[address])
fmt.Printf("%02x ", m.data[address])
address++
}
fmt.Printf("\n")

View File

@ -3,13 +3,12 @@ package main
import "fmt"
type textPages struct {
dirty bool
pages *[4]textPage
pages [4]textPage
}
type textPage struct {
textPages *textPages
data [256]uint8
dirty bool
data [256]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) {
p.data[address] = value
// 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 {
value = value & 0x7F
if value < ' ' {
return " "
}
return string(value)
}
func textMemoryByteToStringHex(value uint8) string {
return fmt.Sprintf("%02x ", value)
}
func (tp *textPages) dump() {
// See "Understand the Apple II", page 5-10
// http://www.applelogic.org/files/UNDERSTANDINGTHEAII.pdf
fmt.Println("------------------------------------------")
var i, j, h uint8
// Top, middle and botton screen
for i = 0; i < 128; i = i + 40 {
for i = 0; i < 120; i = i + 40 {
// Memory pages
for _, p := range tp.pages {
// The two half pages
for _, h = range []uint8{0, 128} {
line := ""
line := "|"
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() {
if !tp.dirty {
return
dirty := false
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()
}