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