package apple2 import ( "fmt" "github.com/ivanizag/apple2/core6502" ) /* Copam BASE64A adaptation. */ // newBase64a instantiates an apple2 func newBase64a() *Apple2 { var a Apple2 a.Name = "Base 64A" a.mmu = newMemoryManager(&a) a.cpu = core6502.NewNMOS6502(a.mmu) a.io = newIoC0Page(&a) addApple2SoftSwitches(a.io) addBase64aSoftSwitches(a.io) return &a } 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("/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 for j := range romBanksBytes { a.mmu.physicalROM[j] = newMemoryRange(0xd000, romBanksBytes[j]) } // Start with first bank active a.mmu.setActiveROMPage(0) return nil } func addBase64aSoftSwitches(io *ioC0Page) { // Other softswitches, not implemented but called from the ROM io.addSoftSwitchW(0x0C, notImplementedSoftSwitchW, "80COLOFF") io.addSoftSwitchW(0x0E, notImplementedSoftSwitchW, "ALTCHARSETOFF") // 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) }, "SPEAKER") // ROM pagination softswitches. They use the annunciator 0 and 1 mmu := io.apple2.mmu io.addSoftSwitchRW(0x58, func(*ioC0Page) uint8 { p := mmu.getActiveROMPage() mmu.setActiveROMPage(p & 2) return 0 }, "ANN0OFF-ROM") io.addSoftSwitchRW(0x59, func(*ioC0Page) uint8 { p := mmu.getActiveROMPage() mmu.setActiveROMPage(p | 1) return 0 }, "ANN0ON-ROM") io.addSoftSwitchRW(0x5A, func(*ioC0Page) uint8 { p := mmu.getActiveROMPage() mmu.setActiveROMPage(p & 1) return 0 }, "ANN1OFF-ROM") io.addSoftSwitchRW(0x5B, func(*ioC0Page) uint8 { p := mmu.getActiveROMPage() mmu.setActiveROMPage(p | 2) return 0 }, "ANN1ON-ROM") } func charGenColumnsMapBase64a(column int) int { bit := column + 2 // Weird positions if column == 6 { bit = 2 } else if column == 0 { bit = 1 } return bit }