package izapple2 import ( "bufio" "fmt" "os" ) /* In out card experiment to interface with the emulator host. See: "Apple II Monitors peeled." http://mysite.du.edu/~etuttle/math/acia.htm PR#n stores Cn00 in CSWL and CSWH IN#n stores Cn00 in KSWL and KSWH */ // CardInOut is an experimental card to bridge with the host console type CardInOut struct { cardBase reader *bufio.Reader } func newCardInOutBuilder() *cardBuilder { return &cardBuilder{ name: "InOut test card", description: "Card to test I/O", buildFunc: func(params map[string]string) (Card, error) { return &CardInOut{}, nil }, } } func (c *CardInOut) assign(a *Apple2, slot int) { c.addCardSoftSwitchR(0, func() uint8 { if c.reader == nil { c.reader = bufio.NewReader(os.Stdin) } value, err := c.reader.ReadByte() if err != nil { panic(err) } value += 0x80 if value&0x7f == 10 { value = 13 + 0x80 } //fmt.Printf("[cardInOut] Read access to softswith 0x%x for slot %v, value %x.\n", 0, slot, value) return value }, "INOUTR") c.addCardSoftSwitchW(1, func(value uint8) { //fmt.Printf("[cardInOut] Write access to softswith 0x%x for slot %v, value 0x%x: %v, %v.\n", 1, slot, value, value&0x7f, string(value&0x7f)) if value&0x7f == 13 { fmt.Printf("\n") } else { fmt.Printf("%v", string(value&0x7f)) } }, "INOUTW") data := buildBaseInOutRom(slot) c.romCsxx = newMemoryRangeROM(0xC200, data[:], "InOUt card") c.cardBase.assign(a, slot) } func buildBaseInOutRom(slot int) []uint8 { data := [256]uint8{ // Register 0x4c, 0x40, 0xc2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x48, 0xA5, 0x38, 0xD0, 0x11, 0xA9, 0xC2, 0xC5, 0x39, 0xD0, 0x0B, 0xAD, 0x4F, 0x85, 0x38, 0x68, 0x91, 0x28, 0xAD, 0xA0, 0xC0, 0x60, 0x68, 0x8D, 0xA1, 0xC0, 0x60, } // Fix slot dependant addresses data[0x02] = uint8(0xc0 + slot) data[0x46] = uint8(0xc0 + slot) data[0x53] = uint8(0x80 + slot<<4) data[0x58] = uint8(0x81 + slot<<4) return data[:] } /* The ROM code was assembled using https://www.masswerk.at/6502/assembler.html We will have $Cn00 as the entry point for CSWL/H. But before doing anything we have to check that we are not in $Cn00 because of an IN#. To da that we check id KSWL/H is $Cn00, it is it we wif it to INEntry. src: BASL = $28 KSWL = $38 KSWH = $39 * = $C200 Entry: JMP SkipHeader * = $C240 SkipHeader: PHA LDA *KSWL BNE PREntry LDA #$C2 CMP *KSWH BNE PREntry FixKSWL: LDA #