diff --git a/apple2/ansiConsoleFrontend.go b/apple2/ansiConsoleFrontend.go new file mode 100644 index 0000000..5ed98c2 --- /dev/null +++ b/apple2/ansiConsoleFrontend.go @@ -0,0 +1,39 @@ +package apple2 + +import ( + "bufio" + "os" +) + +type ansiConsoleFrontend struct { + keyChannel chan uint8 +} + +func _stdinReader(c chan uint8) { + reader := bufio.NewReader(os.Stdin) + for { + byte, err := reader.ReadByte() + if err != nil { + panic(err) + } + c <- byte + } +} + +func (fe *ansiConsoleFrontend) getKey() (key uint8, ok bool) { + if fe.keyChannel == nil { + fe.keyChannel = make(chan uint8, 100) + go _stdinReader(fe.keyChannel) + } + + select { + case key = <-fe.keyChannel: + if key == 10 { + key = 13 + } + ok = true + default: + ok = false + } + return +} diff --git a/apple2/apple2.go b/apple2/apple2.go index 01bd7a7..50895a3 100644 --- a/apple2/apple2.go +++ b/apple2/apple2.go @@ -16,6 +16,9 @@ func Run(romFile string, log bool) { s.Mem.SetPage(uint8(4+j), &(t.pages[j])) } + var fe ansiConsoleFrontend + io.setKeyboardProvider(&fe) + // Start the processor core6502.Reset(&s) t.prepare() diff --git a/apple2/ioC0Page.go b/apple2/ioC0Page.go index dae6856..162a3ae 100644 --- a/apple2/ioC0Page.go +++ b/apple2/ioC0Page.go @@ -1,15 +1,17 @@ package apple2 import ( - "bufio" "fmt" - "os" ) type ioC0Page struct { - ioFlags uint64 - data [1]uint8 - keyChannel chan uint8 + ioFlags uint64 + data [1]uint8 + keyboard keyboardProvider +} + +type keyboardProvider interface { + getKey() (key uint8, ok bool) } // See https://www.kreativekorp.com/miscpages/a2info/iomemory.shtml @@ -92,41 +94,21 @@ func (p *ioC0Page) access(address uint8, isWrite bool, value uint8) uint8 { return 0 } -func (p *ioC0Page) initKeyboard() { - if p.keyChannel == nil { - p.keyChannel = make(chan uint8) - go func(c chan uint8) { - reader := bufio.NewReader(os.Stdin) - for { - ch, err := reader.ReadByte() - if err != nil { - panic(err) - } - c <- ch - } - }(p.keyChannel) - } +func (p *ioC0Page) setKeyboardProvider(kb keyboardProvider) { + p.keyboard = kb } func (p *ioC0Page) getKey() uint8 { - p.initKeyboard() strobed := (p.data[ioDataKeyboard] & (1 << 7)) == 0 - if strobed { - select { - case ch := <-p.keyChannel: - if ch == 10 { - ch = 13 - } - p.data[ioDataKeyboard] = ch + (1 << 7) - default: - // Nothing + if strobed && p.keyboard != nil { + if key, ok := p.keyboard.getKey(); ok { + p.data[ioDataKeyboard] = key + (1 << 7) } } return p.data[ioDataKeyboard] } func (p *ioC0Page) strobeKeyboard() uint8 { - p.initKeyboard() result := p.data[ioDataKeyboard] p.data[ioDataKeyboard] &^= 1 << 7 return result