mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-28 02:30:36 +00:00
127 lines
2.9 KiB
Go
127 lines
2.9 KiB
Go
package izapple2
|
|
|
|
/*
|
|
Brain board II card for Apple II
|
|
|
|
See:
|
|
http://www.willegal.net/appleii/brainboard.htm
|
|
http://www.willegal.net/appleii/bb-v5_3.1.pdf
|
|
https://github.com/Alex-Kw/Brain-Board-II
|
|
|
|
The Brain Board II card has 4 banks instead of the 2 of the
|
|
original Brain Board:
|
|
Bank 0: SS clear, DIP2 OFF (wozaniam)
|
|
Bank 1: SS set, DIP2 OFF (applesoft)
|
|
Bank 2: SS clear, DIP2 ON (wozaniam)
|
|
Bank 3: SS set, DIP2 ON (integer)
|
|
|
|
The card is emulated as having the DIP switches as follows:
|
|
1 - ON: The range F8 can be replaced
|
|
2 - ON: Select the two top banks
|
|
3 - OFF: The motherboard ROM is always replaced
|
|
4 - ON: The softswitch selects low or high bank
|
|
|
|
Softswitches:
|
|
$COsO - SS clear: Low bank selected
|
|
$COs1 - SS set: High bank selected
|
|
|
|
Operation:
|
|
The card boots on wozaniam. Use CAPS LOCK for the commands
|
|
to work. Starts with left arrow.
|
|
To siwtch to Integer BASIC, type:
|
|
1000:AD 91 C0 6C FC FF
|
|
R
|
|
To return to wozaniam, type:
|
|
CALL -151
|
|
1000:AD 90 C0 6C FD FF
|
|
1000G
|
|
*/
|
|
|
|
// CardBrainBoardII represents a Brain Board II card
|
|
type CardBrainBoardII struct {
|
|
cardBase
|
|
highBank bool
|
|
dip2 bool
|
|
rom []uint8
|
|
pages int
|
|
forceBank int
|
|
}
|
|
|
|
const noForceBank = -1
|
|
|
|
func newCardBrainBoardIIBuilder() *cardBuilder {
|
|
return &cardBuilder{
|
|
name: "Brain Board II",
|
|
description: "Firmware card. It has up to four ROM banks",
|
|
defaultParams: &[]paramSpec{
|
|
{"rom", "ROM file to load", "<internal>/ApplesoftInteger.BIN"},
|
|
{"dip2", "Use the upper half of the ROM", "true"},
|
|
{"bank", "Force a ROM bank, 'no' or bank number", "no"}},
|
|
buildFunc: func(params map[string]string) (Card, error) {
|
|
var c CardBrainBoardII
|
|
var err error
|
|
c.highBank = false // Start with wozaniam by default
|
|
c.dip2 = paramsGetBool(params, "dip2")
|
|
c.forceBank, err = paramsGetInt(params, "bank")
|
|
if err != nil {
|
|
c.forceBank = noForceBank
|
|
}
|
|
|
|
// The ROM has:xaa-wozaniam xab-applesoft xac-wozaniam xad-integer
|
|
romFile := paramsGetPath(params, "rom")
|
|
data, _, err := LoadResource(romFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
c.pages = len(data) / 0x4000
|
|
c.rom = data
|
|
c.romCxxx = &c
|
|
return &c, nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func (c *CardBrainBoardII) assign(a *Apple2, slot int) {
|
|
c.addCardSoftSwitchRW(0, func() uint8 {
|
|
c.highBank = false
|
|
return 0x55
|
|
}, "BRAINCLEAR")
|
|
|
|
c.addCardSoftSwitchRW(1, func() uint8 {
|
|
c.highBank = true
|
|
return 0x55
|
|
}, "BRAINSET")
|
|
|
|
c.cardBase.assign(a, slot)
|
|
a.mmu.inhibitROM(c)
|
|
}
|
|
|
|
func (c *CardBrainBoardII) translateAddress(address uint16) uint16 {
|
|
var bank = 0
|
|
if c.forceBank != noForceBank {
|
|
bank = c.forceBank
|
|
} else {
|
|
bank = 0
|
|
if c.highBank {
|
|
bank += 1
|
|
}
|
|
if c.dip2 {
|
|
bank += 2
|
|
}
|
|
}
|
|
return address - 0xc000 + uint16(bank*0x4000)
|
|
}
|
|
|
|
func (c *CardBrainBoardII) peek(address uint16) uint8 {
|
|
return c.rom[c.translateAddress(address)]
|
|
}
|
|
|
|
func (c *CardBrainBoardII) poke(address uint16, value uint8) {
|
|
// Nothing
|
|
}
|
|
|
|
func (c *CardBrainBoardII) setBase(base uint16) {
|
|
// Nothing
|
|
}
|