mirror of
https://github.com/zellyn/goapple2.git
synced 2024-10-13 06:23:59 +00:00
78 lines
1.5 KiB
Go
78 lines
1.5 KiB
Go
package goapple2
|
|
|
|
import (
|
|
"github.com/zellyn/go6502/cpu"
|
|
"github.com/zellyn/goapple2/videoscan"
|
|
)
|
|
|
|
// Memory for the tests. Satisfies the cpu.Memory interface.
|
|
type Apple2 struct {
|
|
mem [65536]byte
|
|
cpu cpu.Cpu
|
|
key byte // BUG(zellyn): make reads/writes atomic
|
|
keys chan byte
|
|
plotter videoscan.Plotter
|
|
scanner *videoscan.Scanner
|
|
}
|
|
|
|
// Cycle counter. Satisfies the cpu.Ticker interface.
|
|
type CycleCount uint64
|
|
|
|
func (c *CycleCount) Tick() {
|
|
*c += 1
|
|
}
|
|
|
|
func NewApple2(p videoscan.Plotter, rom []byte) *Apple2 {
|
|
var cc CycleCount
|
|
a2 := Apple2{
|
|
keys: make(chan byte, 16),
|
|
}
|
|
copy(a2.mem[len(a2.mem)-len(rom):len(a2.mem)], rom)
|
|
a2.scanner = videoscan.NewScanner(&a2, p, [2048]byte{})
|
|
a2.cpu = cpu.NewCPU(&a2, &cc, cpu.VERSION_6502)
|
|
a2.cpu.Reset()
|
|
return &a2
|
|
}
|
|
|
|
func (a2 *Apple2) Read(address uint16) byte {
|
|
// Keyboard read
|
|
if address == 0xC000 {
|
|
if a2.key&0x80 == 0 {
|
|
select {
|
|
case key := <-a2.keys:
|
|
a2.key = key
|
|
default:
|
|
}
|
|
}
|
|
return a2.key
|
|
}
|
|
if address == 0xC010 {
|
|
a2.key &= 0x7F
|
|
return 0 // BUG(zellyn): return proper value (keydown on IIe, not sure on II+)
|
|
}
|
|
return a2.mem[address]
|
|
}
|
|
|
|
func (a2 *Apple2) Write(address uint16, value byte) {
|
|
if address >= 0xD000 {
|
|
return
|
|
}
|
|
if address == 0xC010 {
|
|
// Clear keyboard strobe
|
|
a2.key &= 0x7F
|
|
}
|
|
a2.mem[address] = value
|
|
}
|
|
|
|
func (a2 *Apple2) Keypress(key byte) {
|
|
a2.keys <- key
|
|
}
|
|
|
|
func (a2 *Apple2) Step() error {
|
|
if err := a2.cpu.Step(); err != nil {
|
|
return err
|
|
}
|
|
a2.scanner.Scan1()
|
|
return nil
|
|
}
|