3.5 KiB
- problems
- possible changes
- —- old notes —-
- hardware updates take place at regular intervals:
- emulator itself has to process SDL events at around 60 hz.
- the way this often is handled
- alternate approach: alter system clock so 60 hz divides cleanly
- alternate approach: accept that any event might be a bit off and pick better divisors
- other thoughts
hardware updates
problems
32 bit timestamps (cycle counts)
- we use unsigned 32 bit ints for timestamps.
- "timestamps" are misnomers, they're cycle counts.
- a 32 bit int has a max value of 4,294,967,295 cycles. at 8 Mhz, this is equivalent to 536.87 seconds, or just under 9 minutes.
- a 64 bit unsigned int has a max value of 18,446,744,073,709,551,615 at 8 Mhz, this is equivalent to 2305843009213.69 seconds, which we'll never see.
E_UPDATE(v) -> EMUL_hardwareUpdate(v) is confusing
- dispatch::doUpdate() calls EMUL_hardwareUpdate() based on cpu_update_period.
- cpu_update_period is a number of cycles, and roughly gives us our update resolution.
- since instructions take anywhere from 2-8 cycles, this can be slightly off.
Need to handle timing, i.e. lock to 8 Mhz.
- VICE updates timing every video frame (60 hz.)
- We need to update our per-cycle loop based on
possible changes
- change the naming of 'timestamp' to 'cyclecount'.
- move to 'uint64_t' instead of 'word32' for timestamp/cyclecount -> will want to hunt down all uses of word32 to make sure of what we have.
- get rid of E_UPDATE macro. Consider renaming EMUL_hardwareUpdate to just hardwareUpdate.
—- old notes —-
hardware updates take place at regular intervals:
- screen refresh (60 hz)
- system timer (100 hz)
emulator itself has to process SDL events at around 60 hz.
- this could be handled separately from the cpu loop.
the way this often is handled
- we know our clock speed, 8 Mhz.
- something synchronizes the emulated clock speed to keep it at 8 Mhz.
-
all events happen at certain clock intervals
- each clock cycle is 125 ns.
example: screen refresh
-
100 hz timer with 1 msec resolution.
- need to update the timer value every 1 msec 1 msec = 1,000,000 ns 1 msec = 1,000,000 ns / 125 ns per cycle = 8000 cycles
- after 100,000 updates, the timer fires an IRQ
problems
- instructions take varying numbers of cycles
- updates could be delayed or slightly irregular
hardware update (event) table. gets updated as events occur.
event | freq | last update | next update | notes |
———— | —— | ———– | ———– | —————– |
100 hz timer | 8000 | 0 | 8000 | 1 msec resolution |
60 hz timer | 133333 | 0 | 133333 | 60 hz resolution |
60 hz timer, assuming all 2 cycle instructions, will update
alternate approach: alter system clock so 60 hz divides cleanly
idea Could get around this by altering the system clock enough to at least make the 60 hz timer work correctly. i.e. so that we have an exact number of clock cycles.
alternate approach: accept that any event might be a bit off and pick better divisors
idea make the timer 60 hz timer 50 hz instead. in that case, 50 hz = 20,000,000 ns / 125 ns = 160000 cycles.
compare to 60 hz = 16,666,666.66 ns / 125 ns = 133333.33 cycles.
^– sticks with the cycle-timed approach, but gets us better accuracy. that kind of means that anything that doesn't fit the cycle time is going to be a bit off, but that might be true anyway.
other thoughts
- smallest instruction is 2 cycles, or 300 ns.
- largest instruction is 8 cycles, or 1000 ns. -> effectively, our resolution can only be as good as 1000 ns.
- 60 hz is 16.66 msec, or 133333.33 cycles