Keyboard support using STDIN lines

This commit is contained in:
Ivan Izaguirre 2019-02-18 00:01:48 +01:00
parent 3fca4ed170
commit 5f336810aa
2 changed files with 53 additions and 10 deletions

View File

@ -1,10 +1,15 @@
package apple2 package apple2
import "fmt" import (
"bufio"
"fmt"
"os"
)
type ioC0Page struct { type ioC0Page struct {
ioFlags uint64 ioFlags uint64
data [1]uint8 data [1]uint8
keyChannel chan uint8
} }
// See https://www.kreativekorp.com/miscpages/a2info/iomemory.shtml // See https://www.kreativekorp.com/miscpages/a2info/iomemory.shtml
@ -74,13 +79,10 @@ func (p *ioC0Page) access(address uint8, isWrite bool, value uint8) uint8 {
} }
} else { } else {
switch address { switch address {
case 0x00: // keyboard case 0x00: // keyboard (Is this the full range 0x0?)
// TODO: keyboard suppport return p.getKey()
return 0 //128 + 'A' case 0x10: // strobe (Is this the full range 0x1?)
case 0x10: // strobe return p.strobeKeyboard()
result := p.data[ioDataKeyboard]
p.data[ioDataKeyboard] &^= 1 << 7
return result
case 0x30: // spkr case 0x30: // spkr
// TODO: Support sound // TODO: Support sound
default: default:
@ -89,3 +91,43 @@ func (p *ioC0Page) access(address uint8, isWrite bool, value uint8) uint8 {
} }
return 0 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) 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
}
}
return p.data[ioDataKeyboard]
}
func (p *ioC0Page) strobeKeyboard() uint8 {
p.initKeyboard()
result := p.data[ioDataKeyboard]
p.data[ioDataKeyboard] &^= 1 << 7
return result
}

View File

@ -542,6 +542,7 @@ func ExecuteInstruction(s *State, log bool) {
} }
opcode.action(s, line, opcode) opcode.action(s, line, opcode)
if log { if log {
// Warning: this create double accesses and can interfere on memory mapped I/O
value, address, _ := resolve(s, line, opcode) value, address, _ := resolve(s, line, opcode)
fmt.Printf("%v, [%04x:%02x], [%02x]\n", s.Reg, address, value, line) fmt.Printf("%v, [%04x:%02x], [%02x]\n", s.Reg, address, value, line)
} }