More comments

This commit is contained in:
Will Angenent 2018-05-28 10:54:36 +01:00
parent dc28e6afe4
commit bf09ca8257
3 changed files with 49 additions and 30 deletions

View File

@ -4,14 +4,14 @@ import (
"github.com/hajimehoshi/ebiten"
)
var ebitenAsciiMap map[ebiten.Key]uint8
var shiftMap map[uint8]uint8
var controlMap map[uint8]uint8
var ebitenAsciiMap map[ebiten.Key]uint8 // ebiten keys mapped to ASCII
var shiftMap map[uint8]uint8 // ebiten keys mapped to ASCII when shift is pressed
var controlMap map[uint8]uint8 // ebiten keys mapped to ASCII when control is pressed
var keyBoardData uint8
var strobe uint8
var previousKeysPressed map[uint8]bool
var capsLock bool
var keyBoardData uint8 // Contents of the $c000 address
var strobe uint8 // Contents of the $c010 address
var previousKeysPressed map[uint8]bool // Keep track of what keys have been pressed in the previous round
var capsLock bool // Is capslock down
// Init the keyboard state and ebiten translation tables
func Init() {
@ -190,12 +190,14 @@ func Init() {
controlMap['~'] = 0x60
}
// Poll queries ebiten's keyboard state and transforms that into apple //e
// values in $c000 and $c010
// Poll queries ebiten's keyboard state and transforms that into ASCII
// values in $c000 and $c010. Keypresses from the previous round have to be
// taken into account in order to detect if a single new key has been pressed.
func Poll() {
allKeysPressed := make(map[uint8]bool)
newKeysPressed := make(map[uint8]bool)
// Query ebiten for all possible keys
for k, v := range ebitenAsciiMap {
if ebiten.IsKeyPressed(k) {
allKeysPressed[v] = true
@ -222,6 +224,8 @@ func Poll() {
}
// Implicit else, one new key has been pressed
// Get the key
keys := []uint8{}
for k := range newKeysPressed {
keys = append(keys, k)
@ -229,11 +233,13 @@ func Poll() {
key := keys[0]
if ebiten.IsKeyPressed(ebiten.KeyControl) && ebiten.IsKeyPressed(ebiten.KeyAlt) && key == 'c' {
// Toggle capslock
capsLock = !capsLock
} else {
// Normal case. Transform the ebiten key into ASCII
shift := ebiten.IsKeyPressed(ebiten.KeyShift)
shift = shift || (capsLock && key >= 'a' && key <= 'z')
if shift {
shiftedKey, present := shiftMap[key]
if present {
@ -247,6 +253,7 @@ func Poll() {
key = controlKey
}
}
keyBoardData = key | 0x80
strobe = keyBoardData
}
@ -254,10 +261,12 @@ func Poll() {
return
}
// Read returns the data and strobe values from set from the Poll() call
func Read() (uint8, uint8) {
return keyBoardData, strobe
}
// ResetStrobe clears the high bit in keyboardData
func ResetStrobe() {
keyBoardData &= 0x7f
}

View File

@ -1,32 +1,36 @@
package system
// The system package is a dumping ground for globals that are shared between
// the packages.
const (
CpuFrequency = 1023000
AudioSampleRate = 44100
CpuFrequency = 1023000 // 6402 CPU frequency in Hz
AudioSampleRate = 44100 // Audio sample rate in Hz
)
var (
PendingInterrupt bool
PendingNMI bool
RunningTests bool
RunningFunctionalTests bool
RunningInterruptTests bool
Cycles uint64
FrameCycles uint64
AudioChannel chan int16
LastAudioValue int16
LastAudioCycles uint64
AudioAttenuationCounter uint64
PendingInterrupt bool // Set when an interrupt has just happened
PendingNMI bool // Set when a non maskable interrupt has just happened
RunningTests bool // For testing
RunningFunctionalTests bool // For testing
RunningInterruptTests bool // For testing
Cycles uint64 // Total CPU cycles executed
FrameCycles uint64 // CPU cycles executed in the current frame
AudioChannel chan int16 // Audio channel
LastAudioValue int16 // + or - value of the current square wave
LastAudioCycles uint64 // Last CPU cycle when audio was sent to the channel
AudioAttenuationCounter uint64 // Counter to keep track of when the audio should be zeroed after inactivity
)
// DriveState has the state of the disk drive
var DriveState struct {
Drive uint8
Spinning bool
Phase int8
Phases uint8
BytePosition int
Q6 bool
Q7 bool
Drive uint8 // What drive we're using. Currently only 1 is implemented
Spinning bool // Is the motor spinning
Phase int8 // Phase of the stepper motor
Phases uint8 // the 4 lowest bits represent the 4 stepper motor magnet on/off states.
BytePosition int // Index of the position on the current track
Q6 bool // Q6 soft switch
Q7 bool // Q7 soft switch
}
// Init initializes the system-wide state

View File

@ -12,6 +12,7 @@ import (
"github.com/freewilll/apple2/system"
)
// ReadMemoryFromGzipFile just reads and uncompresses a gzip file
func ReadMemoryFromGzipFile(filename string) (data []byte, err error) {
f, err := os.Open(filename)
if err != nil {
@ -29,6 +30,7 @@ func ReadMemoryFromGzipFile(filename string) (data []byte, err error) {
return
}
// DecodeCmdLineAddress decodes a 4 byte string hex address
func DecodeCmdLineAddress(s *string) (result *uint16) {
if *s != "" {
breakAddressValue, err := hex.DecodeString(*s)
@ -50,6 +52,9 @@ func DecodeCmdLineAddress(s *string) (result *uint16) {
return result
}
// RunUntilBreakPoint runs the CPU until it either hits a breakpoint or a time
// has expired. An assertion is done at the end to ensure the breakpoint has
// been reached.
func RunUntilBreakPoint(t *testing.T, breakAddress uint16, seconds int, showInstructions bool, message string) {
fmt.Printf("Running until %#04x: %s \n", breakAddress, message)
system.FrameCycles = 0
@ -62,6 +67,7 @@ func RunUntilBreakPoint(t *testing.T, breakAddress uint16, seconds int, showInst
}
}
// Disassemble disassembles and prints the code in memory between start and end
func Disassemble(start uint16, end uint16) {
oldPC := cpu.State.PC