mirror of
https://github.com/ivanizag/izapple2.git
synced 2025-01-28 23:33:57 +00:00
Automatic fast mode while disks are spinning
This commit is contained in:
parent
e449ccd907
commit
23ba372a25
@ -10,17 +10,19 @@ import (
|
||||
|
||||
// Apple2 represents all the components and state of the emulated machine
|
||||
type Apple2 struct {
|
||||
cpu *core6502.State
|
||||
mmu *memoryManager
|
||||
io *ioC0Page
|
||||
cg *CharacterGenerator
|
||||
cards []cardBase
|
||||
isApple2e bool
|
||||
panicSS bool
|
||||
activeSlot int // Slot that has the addressing 0xc800 to 0ccfff
|
||||
commandChannel chan int
|
||||
cycleDurationNs float64 // Inverse of the cpu clock in Ghz
|
||||
isColor bool
|
||||
cpu *core6502.State
|
||||
mmu *memoryManager
|
||||
io *ioC0Page
|
||||
cg *CharacterGenerator
|
||||
cards []cardBase
|
||||
isApple2e bool
|
||||
panicSS bool
|
||||
activeSlot int // Slot that has the addressing 0xc800 to 0ccfff
|
||||
commandChannel chan int
|
||||
cycleDurationNs float64 // Inverse of the cpu clock in Ghz
|
||||
isColor bool
|
||||
fastMode bool
|
||||
fastRequestsCounter int
|
||||
}
|
||||
|
||||
const (
|
||||
@ -30,7 +32,8 @@ const (
|
||||
)
|
||||
|
||||
// NewApple2 instantiates an apple2
|
||||
func NewApple2(romFile string, charRomFile string, clockMhz float64, isColor bool, panicSS bool) *Apple2 {
|
||||
func NewApple2(romFile string, charRomFile string, clockMhz float64,
|
||||
isColor bool, fastMode bool, panicSS bool) *Apple2 {
|
||||
var a Apple2
|
||||
a.mmu = newMemoryManager(&a)
|
||||
a.cpu = core6502.NewNMOS6502(a.mmu)
|
||||
@ -41,6 +44,7 @@ func NewApple2(romFile string, charRomFile string, clockMhz float64, isColor boo
|
||||
a.mmu.resetRomPaging()
|
||||
a.commandChannel = make(chan int, 100)
|
||||
a.isColor = isColor
|
||||
a.fastMode = fastMode
|
||||
a.panicSS = panicSS
|
||||
|
||||
if clockMhz <= 0 {
|
||||
@ -122,6 +126,8 @@ func (a *Apple2) executeCommand(command int) {
|
||||
}
|
||||
}
|
||||
|
||||
const maxWaitDuration = 100 * time.Millisecond
|
||||
|
||||
// Run starts the Apple2 emulation
|
||||
func (a *Apple2) Run(log bool) {
|
||||
// Start the processor
|
||||
@ -142,12 +148,12 @@ func (a *Apple2) Run(log bool) {
|
||||
}
|
||||
}
|
||||
|
||||
if a.cycleDurationNs != 0 {
|
||||
if a.cycleDurationNs != 0 && a.fastRequestsCounter <= 0 {
|
||||
// Wait until next 6502 step has to run
|
||||
clockDuration := time.Since(referenceTime)
|
||||
simulatedDuration := time.Duration(float64(a.cpu.GetCycles()) * a.cycleDurationNs)
|
||||
waitDuration := simulatedDuration - clockDuration
|
||||
if waitDuration > 1*time.Second {
|
||||
if waitDuration > maxWaitDuration {
|
||||
// We have to wait too long. Let's fast forward
|
||||
referenceTime = referenceTime.Add(-waitDuration)
|
||||
waitDuration = 0
|
||||
@ -165,6 +171,19 @@ const (
|
||||
apple2eRomSize = 16 * 1024
|
||||
)
|
||||
|
||||
func (a *Apple2) requestFastMode() {
|
||||
// Note: if the fastMode is shorter than maxWaitDuration, there won't be any gain.
|
||||
if a.fastMode {
|
||||
a.fastRequestsCounter++
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Apple2) releaseFastMode() {
|
||||
if a.fastMode {
|
||||
a.fastRequestsCounter--
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Apple2) loadRom(filename string) {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package apple2
|
||||
|
||||
type cardBase struct {
|
||||
a *Apple2
|
||||
rom []memoryPage
|
||||
slot int
|
||||
ssr [16]softSwitchR
|
||||
@ -8,6 +9,7 @@ type cardBase struct {
|
||||
}
|
||||
|
||||
func (c *cardBase) insert(a *Apple2, slot int) {
|
||||
c.a = a
|
||||
c.slot = slot
|
||||
if slot != 0 && c.rom[0] != nil {
|
||||
a.mmu.setPage(uint8(0xC0+slot), c.rom[0])
|
||||
|
@ -31,8 +31,6 @@ type cardDisk2Drive struct {
|
||||
position int
|
||||
}
|
||||
|
||||
// type softSwitchR func(io *ioC0Page) uint8
|
||||
|
||||
func newCardDisk2(filename string) *cardDisk2 {
|
||||
var c cardDisk2
|
||||
c.rom = loadCardRom(filename)
|
||||
@ -75,13 +73,19 @@ func newCardDisk2(filename string) *cardDisk2 {
|
||||
|
||||
// Other soft switches
|
||||
c.ssr[0x8] = func(_ *ioC0Page) uint8 {
|
||||
c.drive[c.selected].power = false
|
||||
//fmt.Printf("DISKII: Disk %v is off\n", c.selected)
|
||||
if c.drive[c.selected].power {
|
||||
c.drive[c.selected].power = false
|
||||
c.a.releaseFastMode()
|
||||
//fmt.Printf("DISKII: Disk %v is off for %v\n", c.selected, x)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
c.ssr[0x9] = func(_ *ioC0Page) uint8 {
|
||||
c.drive[c.selected].power = true
|
||||
//fmt.Printf("DISKII: Disk %v is on\n", c.selected)
|
||||
if !c.drive[c.selected].power {
|
||||
c.drive[c.selected].power = true
|
||||
c.a.requestFastMode()
|
||||
//fmt.Printf("DISKII: Disk %v is on\n", c.selected)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
c.ssr[0xA] = func(_ *ioC0Page) uint8 {
|
||||
|
@ -6,8 +6,8 @@ void SpeakerCallback(void *userdata, Uint8 *stream, int len);
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"go6502/apple2"
|
||||
"log"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
@ -135,7 +135,7 @@ func SpeakerCallback(userdata unsafe.Pointer, stream *C.Uint8, length C.int) {
|
||||
func (s *sdlSpeaker) start() {
|
||||
err := sdl.Init(sdl.INIT_AUDIO)
|
||||
if err != nil {
|
||||
log.Printf("Error starting SDL audio: %v.\n", err)
|
||||
fmt.Printf("Error starting SDL audio: %v.\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ func (s *sdlSpeaker) start() {
|
||||
}
|
||||
|
||||
if err := sdl.OpenAudio(spec, nil); err != nil {
|
||||
log.Printf("Error opening the SDL audio channel: %v.\n", err)
|
||||
fmt.Printf("Error opening the SDL audio channel: %v.\n", err)
|
||||
return
|
||||
}
|
||||
sdl.PauseAudio(false)
|
||||
|
8
main.go
8
main.go
@ -44,6 +44,12 @@ func main() {
|
||||
false,
|
||||
"emulate a green phosphor monitor instead of a NTSC color TV. Use F6 to toggle.",
|
||||
)
|
||||
fastDisk := flag.Bool(
|
||||
"fastDisk",
|
||||
true,
|
||||
"set fast mode when the disks are spinning",
|
||||
)
|
||||
|
||||
panicSS := flag.Bool(
|
||||
"panicss",
|
||||
false,
|
||||
@ -62,7 +68,7 @@ func main() {
|
||||
}
|
||||
|
||||
log := false
|
||||
a := apple2.NewApple2(*romFile, *charRomFile, *cpuClock, !*mono, *panicSS)
|
||||
a := apple2.NewApple2(*romFile, *charRomFile, *cpuClock, !*mono, *fastDisk, *panicSS)
|
||||
if *disk2Slot > 0 {
|
||||
a.AddDisk2(*disk2Slot, *disk2RomFile, *diskImage)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user