apple2-go/mmu/mmu.go

120 lines
2.4 KiB
Go
Raw Normal View History

package mmu
import (
"fmt"
"io/ioutil"
"mos6502go/system"
)
const RomPath = "apple2e.rom"
const StackPage = 1
var PhysicalMemory struct {
MainMemory [0xc000]uint8
UpperROM [0x3000]uint8
RomC1 [0x1000]uint8
RomC2 [0x1000]uint8
}
var PageTable [0x100][]uint8
2018-05-09 20:25:21 +00:00
var UsingExternalSlotRom bool
func MapFirstHalfOfIO() {
2018-05-09 20:25:21 +00:00
UsingExternalSlotRom = false
for i := 0x1; i < 0x10; i++ {
PageTable[i+0xc0] = PhysicalMemory.RomC1[i*0x100 : i*0x100+0x100]
}
}
func MapSecondHalfOfIO() {
2018-05-09 20:25:21 +00:00
UsingExternalSlotRom = true
for i := 0x1; i < 0x10; i++ {
PageTable[i+0xc0] = PhysicalMemory.RomC2[i*0x100 : i*0x100+0x100]
}
}
// emptySlot zeroes all RAM for a slot
func emptySlot(slot int) {
for i := slot * 0x100; i < (slot+1)*0x100; i++ {
PhysicalMemory.RomC1[i] = 0
PhysicalMemory.RomC2[i] = 0
}
}
func readApple2eROM() {
bytes, err := ioutil.ReadFile(RomPath)
if err != nil {
panic(fmt.Sprintf("Unable to read ROM: %s", err))
}
// Copy both I/O areas over c000-cfff, including unused c000-c0ff
for i := 0x0000; i < 0x1000; i++ {
PhysicalMemory.RomC1[i] = bytes[i]
PhysicalMemory.RomC2[i] = bytes[i+0x4000]
}
// Copy ROM over for 0xd000-0xffff area
for i := 0x0; i < 0x3000; i++ {
PhysicalMemory.UpperROM[i] = bytes[i+0x1000]
}
}
func InitApple2eROM() {
readApple2eROM()
// Map 0xc100-0xcfff
MapFirstHalfOfIO()
// Map 0xd000-0xffff
for i := 0x0; i < 0x30; i++ {
PageTable[i+0xd0] = PhysicalMemory.UpperROM[i*0x100 : i*0x100+0x100]
}
}
func InitRAM() {
// Map main RAM
for i := 0x0; i < 0xc0; i++ {
PageTable[i] = PhysicalMemory.MainMemory[i*0x100 : i*0x100+0x100]
}
2018-05-09 20:25:21 +00:00
UsingExternalSlotRom = true
return
}
func ReadMemory(address uint16) uint8 {
if (address >= 0xc000) && (address < 0xc100) {
2018-05-09 20:25:21 +00:00
return ReadIO(address)
} else {
return PageTable[address>>8][address&0xff]
}
}
func WriteMemory(address uint16, value uint8) {
2018-05-09 20:25:21 +00:00
if (address >= 0xc000) && (address < 0xc100) {
WriteIO(address, value)
return
}
if system.RunningInterruptTests && address == 0xbffc {
oldValue := ReadMemory(address)
system.WriteInterruptTestOpenCollector(address, oldValue, value)
PageTable[uint8(address>>8)][uint8(address&0xff)] = value
return
}
PageTable[uint8(address>>8)][uint8(address&0xff)] = value
if system.RunningFunctionalTests && address == 0x200 {
testNumber := ReadMemory(0x200)
if testNumber == 0xf0 {
fmt.Println("Opcode testing completed")
} else {
fmt.Printf("Test %d OK\n", ReadMemory(0x200))
}
}
}