O4S - The replayer
The fundamentals
- It is fundamental to abuse the Z80 stack for this to work.
- The SP (Stack Pointer) points to our stream and serves as the stream head.
- We utilise these characteristics of the stack:
- The stack operates upside down - it grows downwards when pushing on to it and it shrinks upwards when you are popping from it.
- RET - When this command executes, the PC register jumps to the address pointed to by SP on the stack, and advances SP by two bytes. In 11 cycles only.
- POP DE - We fetch two bytes from the stream and advance the SP by two bytes. In 11 cycles only.
- The replayer assumes data to work with one play-call per frame. In practise in Go Figure, we use OPL Timer to control this and for 60Hz we use the OPL timer frequency set to 49 in the MS2 tool (50Hz is 9).
- It is tailored towards Z80 normal MSX frequency and there is no need for spending time on querying for ready state on the chip (except when we load wave headers).
Pseudo code for the replayer
Hooks aka commands
Blocks of unrolled code
REG_WRITES_BLOCKs are blocks of unrolled macros which ends with a final RET command.- Example: Assume this block is placed at 0xD000, and if the encoder wants to encode 36 reg-writes for FM1, it will place 0xD0C on the stream. If the length of reg-writes is 2, the value will be 0xD0D8.
The WAIT_FRAMES_BLOCK is similar. Note that it sorted backwards just like REG_WRITES, but it does not need to be, as there are no fall through here. Also note that the macro in this block does not end with RET, as we are not going to stream any longer at this point.
- The reg write arrays have a max length of 38 (excluding ret) for each of the 3 ports. It could be higher, but 38 was chosen as a middle ground between performance and space. Size of each: 38 * 6 bytes = 228 bytes. The encoder needs to be aware of this, and if longer sequences are identified, they must be split up. The intro music track in Go Figure has a peak frame of 90 sequential reg-writes, where the biggest chunk of 63 are for the WAV port. 61 of these come in sequence, thus, are split in two REG_WRITE commands.
- Similarly, the wait block has a length. It is 64 in Go Figure and is just a chosen number.
Comments
Post a Comment