mirror of
https://github.com/freewilll/apple2-go.git
synced 2025-01-22 23:30:46 +00:00
100c44cb11
With this, DOS3.3 is booting
120 lines
2.4 KiB
Go
120 lines
2.4 KiB
Go
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
|
|
|
|
var UsingExternalSlotRom bool
|
|
|
|
func MapFirstHalfOfIO() {
|
|
UsingExternalSlotRom = false
|
|
|
|
for i := 0x1; i < 0x10; i++ {
|
|
PageTable[i+0xc0] = PhysicalMemory.RomC1[i*0x100 : i*0x100+0x100]
|
|
}
|
|
}
|
|
|
|
func MapSecondHalfOfIO() {
|
|
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]
|
|
}
|
|
|
|
UsingExternalSlotRom = true
|
|
|
|
return
|
|
}
|
|
|
|
func ReadMemory(address uint16) uint8 {
|
|
if (address >= 0xc000) && (address < 0xc100) {
|
|
return ReadIO(address)
|
|
} else {
|
|
return PageTable[address>>8][address&0xff]
|
|
}
|
|
}
|
|
|
|
func WriteMemory(address uint16, value uint8) {
|
|
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))
|
|
}
|
|
}
|
|
}
|