December 11th, 2011, 22:07 Posted By: wraggster
For the past week I have been working on the new transfer system for the DSTwo SDK. The current status is that some of the graphics (TEXT, CGA and MCGA) work, AdLib audio works, and keyboard and touchpad handling works using the new transfer system. I am currently working on getting the SoundBlaster digitized audio working, as that is the most challenging data to transfer.
The original transfer system of the SDK is driven by the MIPS side, so that the MIPS side sends an interrupt to the ARM side whenever it has some data to send, and the ARM side then sends commands and requests data from the MIPS side. My new system works in a completely opposite way, the MIPS side does no transfers unless the ARM side requests data from it. The basic idea of the new transfer system is this:
Adding the SB digitized audio into this system is rather difficult, as the audio buffers can be of any length, and they can be either one-shot or looping buffers, and at various sample rates. I am currently trying to add the SB audio transfer to the buffer end command (phase 10 above), so that the digitized audio would get transferred always after the graphics have been transferred.
- Both the ARM and MIPS processors start running their code at about the same time. Both sides perform their initialization work etc.
- The ARM side hooks into IRQ_CARD_LINE interrupt signal and begins waiting for an interrupt on that line.
- The MIPS side sends an interrupt to the ARM side as the last operation of the initialization routine, immediately before it calls the user's main() function. This allows the ARM side to proceed.
- The ARM side sends command 0xC5, which contains the current Real Time Clock values and works just like in the original SDK. The MIPS side receives this command in the cmd_line_interrupt handler and stores the RTC values into variables, for later use.
- The ARM side waits for VBlank interrupt, the MIPS side runs the CPU emulation.
- The ARM side sends command 0xC2 at every other VBlank interrupt (in the future I hope to make this selectable for 15/30/60fps screen refresh rate, but for now it is fixed to 30fps). This command was originally used in the SDK for sending audio data. In my new system the command parameters contain the current key and touchpad status, RTC seconds value, and a flag byte.
- The MIPS side interrupt handler then sends the current palette data, current configuration state, and AdLib buffer data in the first 1024-byte block. It also tells the FPGA to send data_line_interrupt when the FPGA FIFO becomes empty.
- The ARM side reads this whole 1024-byte block (where the configuration status contains the current graphics mode, for example), and goes to the appropriate screen blitting routine to wait for the MIPS side to send the actual graphics data.
- The MIPS side gets a data_line_interrupt interrupt when the ARM side has read the full 1024-byte FIFO buffer, so it can fill the next 1024-byte block with the graphics data.
- The ARM side keeps reading the graphics data until it has received enough for the full screen, at which point it sends command 0xC2 again, with the flag byte telling the MIPS side to stop transferring more graphics data.
- The MIPS side receives this command, clears the FIFO and turns off the data_line_interrupt.
- At this point the MIPS side just runs the CPU emulation, the ARM9 waits for the next VBlank interrupt, and the ARM7 plays AdLib audio, if any. The transfers will continue from the phase 6 above.
With this new system everything related to data transfer on the MIPS side is handled within the cmd_line_interrupt and data_line_interrupt handlers, so that there is never any need to call the update_buf or such functions of the original SDK. I have actually removed most of the unneeded functions, but some of these still remain. I plan to eventually get rid of all the unnecessary overhead.
One additional advantage I got from this change, was that I don't need to allocate a timer interrupt on the MIPS side to emulate the VBlank signal. I can now get the timing from the interrupt the MIPS side receives from the ARM side, so that I can use the free timer for better SoundBlaster IRQ emulation with much more accurate timing.
For more information and downloads, click here!
There are 0 comments - Join In and Discuss Here