2020-10-03 21:38:26 +00:00
|
|
|
package izapple2
|
2019-06-09 15:36:29 +00:00
|
|
|
|
2019-10-12 19:37:37 +00:00
|
|
|
import (
|
2019-11-03 23:23:03 +00:00
|
|
|
"fmt"
|
|
|
|
|
2022-01-28 17:09:59 +00:00
|
|
|
"github.com/ivanizag/iz6502"
|
2019-10-12 19:37:37 +00:00
|
|
|
)
|
2019-06-09 15:36:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
Copam BASE64A adaptation.
|
|
|
|
*/
|
|
|
|
|
2020-08-30 19:11:43 +00:00
|
|
|
func setBase64a(a *Apple2) {
|
2019-06-09 21:54:27 +00:00
|
|
|
a.Name = "Base 64A"
|
2022-01-28 17:09:59 +00:00
|
|
|
a.cpu = iz6502.NewNMOS6502(a.mmu)
|
2019-10-12 19:37:37 +00:00
|
|
|
addApple2SoftSwitches(a.io)
|
|
|
|
addBase64aSoftSwitches(a.io)
|
2019-06-09 15:36:29 +00:00
|
|
|
}
|
|
|
|
|
2019-11-03 23:23:03 +00:00
|
|
|
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)
|
2022-01-28 18:25:52 +00:00
|
|
|
data, _, err := LoadResource(filename)
|
2019-11-03 23:23:03 +00:00
|
|
|
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
|
|
|
|
for j := range romBanksBytes {
|
2020-09-23 16:19:15 +00:00
|
|
|
a.mmu.physicalROM[j] = newMemoryRange(0xd000, romBanksBytes[j], fmt.Sprintf("Base64 ROM page %v", j))
|
2019-11-03 23:23:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Start with first bank active
|
|
|
|
a.mmu.setActiveROMPage(0)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-10-12 19:37:37 +00:00
|
|
|
func addBase64aSoftSwitches(io *ioC0Page) {
|
2019-10-20 22:00:42 +00:00
|
|
|
// Other softswitches, not implemented but called from the ROM
|
2022-08-05 17:43:17 +00:00
|
|
|
io.addSoftSwitchW(0x0C, buildNotImplementedSoftSwitchW(io), "80COLOFF")
|
|
|
|
io.addSoftSwitchW(0x0E, buildNotImplementedSoftSwitchW(io), "ALTCHARSETOFF")
|
2019-11-03 23:23:03 +00:00
|
|
|
|
|
|
|
// ROM pagination softswitches. They use the annunciator 0 and 1
|
|
|
|
mmu := io.apple2.mmu
|
2022-08-05 17:43:17 +00:00
|
|
|
io.addSoftSwitchRW(0x58, func() uint8 {
|
2019-11-03 23:23:03 +00:00
|
|
|
p := mmu.getActiveROMPage()
|
|
|
|
mmu.setActiveROMPage(p & 2)
|
|
|
|
return 0
|
|
|
|
}, "ANN0OFF-ROM")
|
2022-08-05 17:43:17 +00:00
|
|
|
io.addSoftSwitchRW(0x59, func() uint8 {
|
2019-11-03 23:23:03 +00:00
|
|
|
p := mmu.getActiveROMPage()
|
|
|
|
mmu.setActiveROMPage(p | 1)
|
|
|
|
return 0
|
|
|
|
}, "ANN0ON-ROM")
|
2022-08-05 17:43:17 +00:00
|
|
|
io.addSoftSwitchRW(0x5A, func() uint8 {
|
2019-11-03 23:23:03 +00:00
|
|
|
p := mmu.getActiveROMPage()
|
|
|
|
mmu.setActiveROMPage(p & 1)
|
|
|
|
return 0
|
|
|
|
}, "ANN1OFF-ROM")
|
2022-08-05 17:43:17 +00:00
|
|
|
io.addSoftSwitchRW(0x5B, func() uint8 {
|
2019-11-03 23:23:03 +00:00
|
|
|
p := mmu.getActiveROMPage()
|
|
|
|
mmu.setActiveROMPage(p | 2)
|
|
|
|
return 0
|
|
|
|
}, "ANN1ON-ROM")
|
|
|
|
|
2019-06-09 15:36:29 +00:00
|
|
|
}
|
|
|
|
|
2019-10-12 19:37:37 +00:00
|
|
|
func charGenColumnsMapBase64a(column int) int {
|
|
|
|
bit := column + 2
|
|
|
|
// Weird positions
|
|
|
|
if column == 6 {
|
|
|
|
bit = 2
|
|
|
|
} else if column == 0 {
|
|
|
|
bit = 1
|
|
|
|
}
|
|
|
|
return bit
|
2019-06-09 15:36:29 +00:00
|
|
|
}
|