mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-30 15:30:08 +00:00
Initial Apple 2e enhanced support
This commit is contained in:
parent
1d0a3e0b34
commit
eeebf1bb0f
@ -6,13 +6,39 @@ import (
|
||||
"github.com/ivanizag/apple2/core6502"
|
||||
)
|
||||
|
||||
// NewApple2 instantiates an apple2
|
||||
func NewApple2(clockMhz float64, isColor bool, fastMode bool) *Apple2 {
|
||||
// newApple2 instantiates an apple2
|
||||
func newApple2plus() *Apple2 {
|
||||
|
||||
var a Apple2
|
||||
a.Name = "Apple ][+"
|
||||
a.mmu = newMemoryManager(&a)
|
||||
a.cpu = core6502.NewNMOS6502(a.mmu)
|
||||
|
||||
// Set the io in 0xc000
|
||||
a.io = newIoC0Page(&a)
|
||||
a.mmu.setPages(0xc0, 0xc0, a.io)
|
||||
addApple2SoftSwitches(a.io)
|
||||
|
||||
return &a
|
||||
}
|
||||
|
||||
func newApple2eEnhanced() *Apple2 {
|
||||
|
||||
var a Apple2
|
||||
a.Name = "Apple //e"
|
||||
a.mmu = newMemoryManager(&a)
|
||||
a.cpu = core6502.NewCMOS65c02(a.mmu)
|
||||
|
||||
// Set the io in 0xc000
|
||||
a.io = newIoC0Page(&a)
|
||||
a.mmu.setPages(0xc0, 0xc0, a.io)
|
||||
addApple2SoftSwitches(a.io)
|
||||
addApple2ESoftSwitches(a.io)
|
||||
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a *Apple2) setup(isColor bool, clockMhz float64, fastMode bool) {
|
||||
a.commandChannel = make(chan int, 100)
|
||||
a.isColor = isColor
|
||||
a.fastMode = fastMode
|
||||
@ -23,12 +49,6 @@ func NewApple2(clockMhz float64, isColor bool, fastMode bool) *Apple2 {
|
||||
} else {
|
||||
a.cycleDurationNs = 1000.0 / clockMhz
|
||||
}
|
||||
|
||||
// Set the io in 0xc000
|
||||
a.io = newIoC0Page(&a)
|
||||
a.mmu.setPages(0xc0, 0xc0, a.io)
|
||||
|
||||
return &a
|
||||
}
|
||||
|
||||
func (a *Apple2) insertCard(c card, slot int) {
|
||||
|
@ -5,11 +5,13 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
const defaultInternal = "<default>"
|
||||
|
||||
// MainApple is a device independant main. Video, keyboard and speaker won't be defined
|
||||
func MainApple() *Apple2 {
|
||||
romFile := flag.String(
|
||||
"rom",
|
||||
"<internal>/Apple2_Plus.rom",
|
||||
defaultInternal,
|
||||
"main rom file")
|
||||
disk2RomFile := flag.String(
|
||||
"diskRom",
|
||||
@ -37,7 +39,7 @@ func MainApple() *Apple2 {
|
||||
"cpu speed in Mhz, use 0 for full speed. Use F5 to toggle.")
|
||||
charRomFile := flag.String(
|
||||
"charRom",
|
||||
"<internal>/Apple2rev7CharGen.rom",
|
||||
defaultInternal,
|
||||
"rom file for the character generator")
|
||||
languageCardSlot := flag.Int(
|
||||
"languageCardSlot",
|
||||
@ -81,10 +83,10 @@ func MainApple() *Apple2 {
|
||||
false,
|
||||
"shows the character map",
|
||||
)
|
||||
base64a := flag.Bool(
|
||||
"base64a",
|
||||
false,
|
||||
"setup a Base64A clone",
|
||||
model := flag.String(
|
||||
"model",
|
||||
"2plus",
|
||||
"set base model. Models available 2plus, 2e, base64a",
|
||||
)
|
||||
profile := flag.Bool(
|
||||
"profile",
|
||||
@ -93,29 +95,73 @@ func MainApple() *Apple2 {
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
a := NewApple2(*cpuClock, !*mono, *fastDisk)
|
||||
var a *Apple2
|
||||
var charGenMap charColumnMap
|
||||
initialCharGenPage := 0
|
||||
switch *model {
|
||||
case "2plus":
|
||||
a = newApple2plus()
|
||||
if *romFile == defaultInternal {
|
||||
*romFile = "<internal>/Apple2_Plus.rom"
|
||||
}
|
||||
if *charRomFile == defaultInternal {
|
||||
*charRomFile = "<internal>/Apple2rev7CharGen.rom"
|
||||
}
|
||||
charGenMap = charGenColumnsMap2Plus
|
||||
|
||||
case "2e":
|
||||
a = newApple2eEnhanced()
|
||||
if *romFile == defaultInternal {
|
||||
*romFile = "<internal>/Apple2e_Enhanced.rom"
|
||||
}
|
||||
if *charRomFile == defaultInternal {
|
||||
*charRomFile = "<internal>/Apple IIe Video Enhanced - 342-0265-A - 2732.bin"
|
||||
}
|
||||
a.isApple2e = true
|
||||
charGenMap = charGenColumnsMap2e
|
||||
|
||||
case "base64a":
|
||||
a = newBase64a()
|
||||
if *romFile == defaultInternal {
|
||||
err := loadBase64aRom(a)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
*romFile = ""
|
||||
}
|
||||
if *charRomFile == defaultInternal {
|
||||
*charRomFile = "<internal>/BASE64A_ROM7_CharGen.BIN"
|
||||
initialCharGenPage = 1
|
||||
}
|
||||
charGenMap = charGenColumnsMapBase64a
|
||||
|
||||
default:
|
||||
panic("Model not supported")
|
||||
}
|
||||
|
||||
a.setup(!*mono, *cpuClock, *fastDisk)
|
||||
a.cpu.SetTrace(*traceCPU)
|
||||
a.io.setTrace(*traceSS)
|
||||
a.io.setPanicNotImplemented(*panicSS)
|
||||
a.setProfile(*profile)
|
||||
|
||||
if *charRomFile != "" {
|
||||
cg, err := NewCharacterGenerator(*charRomFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
a.cg = cg
|
||||
}
|
||||
|
||||
if *base64a {
|
||||
NewBase64a(a)
|
||||
} else {
|
||||
// Load ROM if not loaded already
|
||||
if *romFile != "" {
|
||||
err := a.LoadRom(*romFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Load character generator if it loaded already
|
||||
cg, err := newCharacterGenerator(*charRomFile, charGenMap)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cg.setPage(initialCharGenPage)
|
||||
a.cg = cg
|
||||
|
||||
// Externsion cards
|
||||
if *languageCardSlot >= 0 {
|
||||
a.AddLanguageCard(*languageCardSlot)
|
||||
}
|
||||
|
126
base64a.go
126
base64a.go
@ -1,42 +1,43 @@
|
||||
package apple2
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"github.com/ivanizag/apple2/core6502"
|
||||
)
|
||||
|
||||
/*
|
||||
Copam BASE64A adaptation.
|
||||
*/
|
||||
|
||||
// Base64a extends an Apple2
|
||||
type Base64a struct {
|
||||
a *Apple2
|
||||
romBanks [4]*memoryRange
|
||||
romBank uint8
|
||||
}
|
||||
// newBase64a instantiates an apple2
|
||||
func newBase64a() *Apple2 {
|
||||
var a Apple2
|
||||
|
||||
// NewBase64a instantiates an apple2
|
||||
func NewBase64a(a *Apple2) (*Base64a, error) {
|
||||
var b Base64a
|
||||
b.a = a
|
||||
a.Name = "Base 64A"
|
||||
err := b.loadRom()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a.mmu = newMemoryManager(&a)
|
||||
a.cpu = core6502.NewNMOS6502(a.mmu)
|
||||
|
||||
// Configure the character generator
|
||||
if !a.cg.customRom {
|
||||
err := a.cg.load("<internal>/BASE64A_ROM7_CharGen.BIN")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
a.cg.setColumnMap(base64aCharGenColumnsMap)
|
||||
a.cg.setPage(1)
|
||||
// Set the io in 0xc000
|
||||
a.io = newIoC0Page(&a)
|
||||
a.mmu.setPages(0xc0, 0xc0, a.io)
|
||||
addApple2SoftSwitches(a.io)
|
||||
addBase64aSoftSwitches(a.io)
|
||||
|
||||
return &b, nil
|
||||
return &a
|
||||
}
|
||||
|
||||
func base64aCharGenColumnsMap(column int) int {
|
||||
func addBase64aSoftSwitches(io *ioC0Page) {
|
||||
// Other softswitches
|
||||
io.addSoftSwitchW(0x0C, notImplementedSoftSwitchW) // 80 columns off?
|
||||
io.addSoftSwitchW(0x0E, notImplementedSoftSwitchW) // Alt char off?
|
||||
|
||||
// Write on the speaker. That is a double access and should do nothing
|
||||
// but works somehow on the BASE64A
|
||||
io.addSoftSwitchW(0x30, func(io *ioC0Page, value uint8) {
|
||||
speakerSoftSwitch(io)
|
||||
})
|
||||
}
|
||||
|
||||
func charGenColumnsMapBase64a(column int) int {
|
||||
bit := column + 2
|
||||
// Weird positions
|
||||
if column == 6 {
|
||||
@ -46,76 +47,3 @@ func base64aCharGenColumnsMap(column int) int {
|
||||
}
|
||||
return bit
|
||||
}
|
||||
|
||||
const (
|
||||
// There are 6 ROM chips. Each can have 4Kb or 8Kb. They can fill
|
||||
// 2 or 4 banks with 2kb windows.
|
||||
base64aRomBankSize = 12 * 1024
|
||||
base64aRomBankCount = 4
|
||||
base64aRomWindowSize = 2 * 1024
|
||||
base64aRomChipCount = 6
|
||||
)
|
||||
|
||||
func (b *Base64a) loadRom() error {
|
||||
// Load the 6 PROM dumps
|
||||
romBanksBytes := make([][]uint8, base64aRomBankCount)
|
||||
for j := range romBanksBytes {
|
||||
romBanksBytes[j] = make([]uint8, 0, base64aRomBankSize)
|
||||
}
|
||||
|
||||
for i := 0; i < base64aRomChipCount; i++ {
|
||||
filename := fmt.Sprintf("<internal>/BASE64A_%X.BIN", 0xd0+i*0x08)
|
||||
data, err := loadResource(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for j := range romBanksBytes {
|
||||
start := (j * base64aRomWindowSize) % len(data)
|
||||
romBanksBytes[j] = append(romBanksBytes[j], data[start:start+base64aRomWindowSize]...)
|
||||
}
|
||||
}
|
||||
|
||||
for j := range romBanksBytes {
|
||||
b.romBanks[j] = newMemoryRange(0xd000, romBanksBytes[j])
|
||||
}
|
||||
|
||||
// Start with first bank active
|
||||
b.changeRomBank(0)
|
||||
|
||||
// Add rom soft switches. They use the annunciator 0 and 1
|
||||
b.a.io.addSoftSwitchRW(0x58, func(*ioC0Page) uint8 {
|
||||
b.changeRomBank(b.romBank & 2)
|
||||
return 0
|
||||
})
|
||||
b.a.io.addSoftSwitchRW(0x59, func(*ioC0Page) uint8 {
|
||||
b.changeRomBank(b.romBank | 1)
|
||||
return 0
|
||||
})
|
||||
b.a.io.addSoftSwitchRW(0x5A, func(*ioC0Page) uint8 {
|
||||
b.changeRomBank(b.romBank & 1)
|
||||
return 0
|
||||
})
|
||||
b.a.io.addSoftSwitchRW(0x5B, func(*ioC0Page) uint8 {
|
||||
b.changeRomBank(b.romBank | 2)
|
||||
return 0
|
||||
})
|
||||
|
||||
// Other softswitches
|
||||
b.a.io.addSoftSwitchW(0x0C, notImplementedSoftSwitchW) // 80 columns off?
|
||||
b.a.io.addSoftSwitchW(0x0E, notImplementedSoftSwitchW) // Alt char off?
|
||||
|
||||
// Write on the speaker. That is a double access and should do nothing
|
||||
// but works somehow on the BASE64A
|
||||
b.a.io.addSoftSwitchW(0x30, func(io *ioC0Page, value uint8) {
|
||||
speakerSoftSwitch(io)
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Base64a) changeRomBank(bank uint8) {
|
||||
b.romBank = bank
|
||||
//fmt.Printf("Change to ROM bank #%v\n", b.romBank)
|
||||
b.a.mmu.physicalROM = b.romBanks[b.romBank]
|
||||
b.a.mmu.resetRomPaging() // If rom was not active. This is going to far?
|
||||
}
|
||||
|
80
base64aRom.go
Normal file
80
base64aRom.go
Normal file
@ -0,0 +1,80 @@
|
||||
package apple2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
/*
|
||||
Copam BASE64A uses paginated ROM
|
||||
*/
|
||||
|
||||
// Base64aROM Models the paginated ROM on a BASE64A clone
|
||||
type base64aROM struct {
|
||||
romBanks [4]*memoryRange
|
||||
romBank uint8
|
||||
}
|
||||
|
||||
const (
|
||||
// There are 6 ROM chips. Each can have 4Kb or 8Kb. They can fill
|
||||
// 2 or 4 banks with 2kb windows.
|
||||
base64aRomBankSize = 12 * 1024
|
||||
base64aRomBankCount = 4
|
||||
base64aRomWindowSize = 2 * 1024
|
||||
base64aRomChipCount = 6
|
||||
)
|
||||
|
||||
func loadBase64aRom(a *Apple2) error {
|
||||
// Load the 6 PROM dumps
|
||||
romBanksBytes := make([][]uint8, base64aRomBankCount)
|
||||
for j := range romBanksBytes {
|
||||
romBanksBytes[j] = make([]uint8, 0, base64aRomBankSize)
|
||||
}
|
||||
|
||||
for i := 0; i < base64aRomChipCount; i++ {
|
||||
filename := fmt.Sprintf("<internal>/BASE64A_%X.BIN", 0xd0+i*0x08)
|
||||
data, err := loadResource(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for j := range romBanksBytes {
|
||||
start := (j * base64aRomWindowSize) % len(data)
|
||||
romBanksBytes[j] = append(romBanksBytes[j], data[start:start+base64aRomWindowSize]...)
|
||||
}
|
||||
}
|
||||
|
||||
// Create banks
|
||||
var r base64aROM
|
||||
for j := range romBanksBytes {
|
||||
r.romBanks[j] = newMemoryRange(0xd000, romBanksBytes[j])
|
||||
}
|
||||
|
||||
// Start with first bank active
|
||||
r.changeBank(a.mmu, 0)
|
||||
|
||||
// Add rom soft switches. They use the annunciator 0 and 1
|
||||
a.io.addSoftSwitchRW(0x58, func(*ioC0Page) uint8 {
|
||||
r.changeBank(a.mmu, r.romBank&2)
|
||||
return 0
|
||||
})
|
||||
a.io.addSoftSwitchRW(0x59, func(*ioC0Page) uint8 {
|
||||
r.changeBank(a.mmu, r.romBank|1)
|
||||
return 0
|
||||
})
|
||||
a.io.addSoftSwitchRW(0x5A, func(*ioC0Page) uint8 {
|
||||
r.changeBank(a.mmu, r.romBank&1)
|
||||
return 0
|
||||
})
|
||||
a.io.addSoftSwitchRW(0x5B, func(*ioC0Page) uint8 {
|
||||
r.changeBank(a.mmu, r.romBank|2)
|
||||
return 0
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *base64aROM) changeBank(mmu *memoryManager, bank uint8) {
|
||||
r.romBank = bank
|
||||
//fmt.Printf("Change to ROM bank #%v\n", r.romBank)
|
||||
mmu.physicalROM = r.romBanks[r.romBank]
|
||||
mmu.resetRomPaging() // If rom was not active. This is going too far?
|
||||
}
|
@ -7,56 +7,57 @@ import (
|
||||
|
||||
/*
|
||||
See:
|
||||
hhttps://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Companies/Apple/Documentation/Apple%20Technical%20Information%20Library/a2til041.txt
|
||||
https://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Companies/Apple/Documentation/Apple%20Technical%20Information%20Library/a2til041.txt
|
||||
*/
|
||||
|
||||
// CharacterGenerator represents the ROM wth the characters bitmaps
|
||||
type CharacterGenerator struct {
|
||||
data []uint8
|
||||
customRom bool
|
||||
columnMap charColumnMap
|
||||
page int
|
||||
}
|
||||
|
||||
type charColumnMap func(column int) int
|
||||
|
||||
func charGenColumnsMap2Plus(column int) int {
|
||||
return 6 - column
|
||||
}
|
||||
|
||||
func charGenColumnsMap2e(column int) int {
|
||||
return column
|
||||
}
|
||||
|
||||
const (
|
||||
rev7CharGenSize = 2048
|
||||
defaultCharGenROM = "<internal>/Apple2rev7CharGen.rom"
|
||||
charGenPageSize = 2048
|
||||
)
|
||||
|
||||
// NewCharacterGenerator instantiates a new Character Generator with the rom on the file given
|
||||
func NewCharacterGenerator(filename string) (*CharacterGenerator, error) {
|
||||
func newCharacterGenerator(filename string, order charColumnMap) (*CharacterGenerator, error) {
|
||||
var cg CharacterGenerator
|
||||
err := cg.load(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cg.columnMap = order
|
||||
return &cg, nil
|
||||
}
|
||||
|
||||
func (cg *CharacterGenerator) load(filename string) error {
|
||||
cg.customRom = !isInternalResource(filename)
|
||||
bytes, err := loadResource(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
size := len(bytes)
|
||||
if size < rev7CharGenSize {
|
||||
if size < charGenPageSize {
|
||||
return errors.New("Character ROM size not supported")
|
||||
}
|
||||
cg.data = bytes
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cg *CharacterGenerator) setColumnMap(columnMap charColumnMap) {
|
||||
// Regular Apple II uses bits 6 to 0 but some clones have other mappings
|
||||
cg.columnMap = columnMap
|
||||
}
|
||||
|
||||
func (cg *CharacterGenerator) setPage(page int) {
|
||||
// Some clones had a switch to change codepage with extra characters
|
||||
pages := len(cg.data) / rev7CharGenSize
|
||||
pages := len(cg.data) / charGenPageSize
|
||||
cg.page = page % pages
|
||||
}
|
||||
|
||||
@ -65,14 +66,8 @@ func (cg *CharacterGenerator) nextPage() {
|
||||
}
|
||||
|
||||
func (cg *CharacterGenerator) getPixel(char uint8, row int, column int) bool {
|
||||
bits := cg.data[int(char)*8+row+cg.page*rev7CharGenSize]
|
||||
var bit int
|
||||
if cg.columnMap != nil {
|
||||
bit = cg.columnMap(column)
|
||||
} else {
|
||||
// Standard Apple 2 mapping
|
||||
bit = 6 - column
|
||||
}
|
||||
bits := cg.data[int(char)*8+row+cg.page*charGenPageSize]
|
||||
bit := cg.columnMap(column)
|
||||
value := bits >> uint(bit) & 1
|
||||
return value == 1
|
||||
}
|
||||
@ -113,7 +108,7 @@ func (cg *CharacterGenerator) dumpChar(char uint8) {
|
||||
|
||||
// Dump to sdtout all the character maps
|
||||
func (cg *CharacterGenerator) Dump() {
|
||||
pages := len(cg.data) / rev7CharGenSize
|
||||
pages := len(cg.data) / charGenPageSize
|
||||
for p := 0; p < pages; p++ {
|
||||
cg.setPage(p)
|
||||
for i := 0; i < 256; i++ {
|
||||
|
@ -50,12 +50,6 @@ const (
|
||||
func newIoC0Page(a *Apple2) *ioC0Page {
|
||||
var io ioC0Page
|
||||
io.apple2 = a
|
||||
|
||||
addApple2SoftSwitches(&io)
|
||||
if a.isApple2e {
|
||||
addApple2ESoftSwitches(&io)
|
||||
}
|
||||
|
||||
return &io
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -9,24 +9,37 @@ const (
|
||||
)
|
||||
|
||||
func addApple2ESoftSwitches(io *ioC0Page) {
|
||||
|
||||
io.addSoftSwitchW(0x00, getSoftSwitchExt(ioFlag80Store, ssOff, nil))
|
||||
io.addSoftSwitchW(0x01, getSoftSwitchExt(ioFlag80Store, ssOn, nil))
|
||||
// New MMU read softswithes
|
||||
io.addSoftSwitchW(0x06, getSoftSwitchExt(ioFlagIntCxRom, ssOff, softSwitchIntCxRomOff))
|
||||
io.addSoftSwitchW(0x07, getSoftSwitchExt(ioFlagIntCxRom, ssOn, softSwitchIntCxRomOn))
|
||||
io.addSoftSwitchR(0x15, getStatusSoftSwitch(ioFlagIntCxRom))
|
||||
io.addSoftSwitchW(0x0A, getSoftSwitchExt(ioFlagSlotC3Rom, ssOff, softSwitchSlotC3RomOff))
|
||||
io.addSoftSwitchW(0x0B, getSoftSwitchExt(ioFlagSlotC3Rom, ssOn, softSwitchSlotC3RomOn))
|
||||
io.addSoftSwitchR(0x17, getStatusSoftSwitch(ioFlagSlotC3Rom))
|
||||
|
||||
// Previous read softswithes
|
||||
io.addSoftSwitchR(0x1A, getStatusSoftSwitch(ioFlagText))
|
||||
io.addSoftSwitchR(0x1B, getStatusSoftSwitch(ioFlagMixed))
|
||||
io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage))
|
||||
io.addSoftSwitchR(0x1D, getStatusSoftSwitch(ioFlagHiRes))
|
||||
|
||||
// New IOU read softswithes
|
||||
io.addSoftSwitchW(0x00, getSoftSwitchExt(ioFlag80Store, ssOff, nil))
|
||||
io.addSoftSwitchW(0x01, getSoftSwitchExt(ioFlag80Store, ssOn, nil))
|
||||
io.addSoftSwitchR(0x18, getStatusSoftSwitch(ioFlag80Store))
|
||||
io.addSoftSwitchW(0x0C, getSoftSwitchExt(ioFlag80Col, ssOff, nil))
|
||||
io.addSoftSwitchW(0x0D, getSoftSwitchExt(ioFlag80Col, ssOn, nil))
|
||||
io.addSoftSwitchR(0x1F, getStatusSoftSwitch(ioFlag80Col))
|
||||
io.addSoftSwitchW(0x0E, getSoftSwitchExt(ioFlagAltChar, ssOff, nil))
|
||||
io.addSoftSwitchW(0x0F, getSoftSwitchExt(ioFlagAltChar, ssOn, nil))
|
||||
io.softSwitchesData[ioFlagAltChar] = ssOn // Not sure about this.
|
||||
io.addSoftSwitchR(0x1E, getStatusSoftSwitch(ioFlagAltChar))
|
||||
|
||||
// TOOD:
|
||||
// AKD read on 0x10
|
||||
// VBL read on 0x19
|
||||
|
||||
//io.softSwitchesData[ioFlagAltChar] = ssOn // Not sure about this.
|
||||
|
||||
io.addSoftSwitchR(0x15, getStatusSoftSwitch(ioFlagIntCxRom))
|
||||
io.addSoftSwitchR(0x17, getStatusSoftSwitch(ioFlagSlotC3Rom))
|
||||
io.addSoftSwitchR(0x18, getStatusSoftSwitch(ioFlag80Store))
|
||||
io.addSoftSwitchR(0x1C, getStatusSoftSwitch(ioFlagSecondPage))
|
||||
io.addSoftSwitchR(0x1F, getStatusSoftSwitch(ioFlag80Col))
|
||||
}
|
||||
|
||||
type softSwitchExtAction func(io *ioC0Page)
|
||||
|
Loading…
Reference in New Issue
Block a user