PPU.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "data.h"
  2. byte tileMapLocation[4];
  3. word characterLocation[4];
  4. void waitForVBlank(void) {
  5. byte Status;
  6. do {
  7. Status = *(byte*)0x4210;
  8. } while (!(Status & 0x80));
  9. }
  10. void setTileMapLocation(word vramDst, byte screenProp, byte bgNumber) {
  11. tileMapLocation[bgNumber] = ((vramDst >> 8) & 0xfc) | ( screenProp & 0x03 );
  12. *(byte*) (0x2107+bgNumber) = tileMapLocation[bgNumber];
  13. }
  14. void restoreTileMapLocation(byte bgNumber) {
  15. *(byte*) (0x2107+bgNumber) = tileMapLocation[bgNumber];
  16. }
  17. void setCharacterLocation(word vramDst, byte bgNumber) {
  18. characterLocation[bgNumber] = vramDst;
  19. if(bgNumber < 2) {
  20. *(byte*) 0x210b = (characterLocation[1] >> 8 & 0xf0 ) + (characterLocation[0] >> 12);
  21. } else {
  22. *(byte*) 0x210c = (characterLocation[3] >> 8 & 0xf0 ) + (characterLocation[2] >> 12);
  23. }
  24. }
  25. void restoreCharacterLocation(byte bgNumber) {
  26. setCharacterLocation(characterLocation[bgNumber], bgNumber);
  27. }
  28. void VRAMByteWrite(byte value, word vramDst) {
  29. *(byte*)0x2115 = 0x80;
  30. *(word*)0x2116 = vramDst;
  31. *(byte*)0x2118 = value;
  32. }
  33. void VRAMLoad(word src, word vramDst, word size) {
  34. // set address in VRam for read or write ($2116) + block size transfer ($2115)
  35. *(byte*)0x2115 = 0x80;
  36. *(word*)0x2116 = vramDst;
  37. *(word*)0x4300 = 0x1801; // set DMA control register (1 word inc)
  38. // and destination ($21xx xx -> 0x18)
  39. *(word*)0x4302 = src; // DMA channel x source address offset
  40. // (low $4302 and high $4303 optimisation)
  41. *(byte*)0x4304 = 0x01; // DMA channel x source address bank
  42. *(word*)0x4305 = size; // DMA channel x transfer size
  43. // (low $4305 and high $4306 optimisation)
  44. // Turn on DMA transfer for this channel
  45. waitForVBlank();
  46. *(byte*)0x2100 = 0x80;
  47. *(byte*)0x420b = 0x01;
  48. *(byte*)0x2100 = 0x00;
  49. }
  50. void CGRAMLoad(word src, byte cgramDst, word size) {
  51. // set address in VRam for read or write + block size
  52. *(byte*)0x2121 = cgramDst;
  53. *(word*)0x4300 = 0x2200; // set DMA control register (1 byte inc)
  54. // and destination ($21xx xx -> 022)
  55. *(word*)0x4302 = src; // DMA channel x source address offset
  56. // (low $4302 and high $4303 optimisation)
  57. *(byte*)0x4304 = 0x01; // DMA channel x source address bank
  58. *(word*)0x4305 = size; // DMA channel x transfer size
  59. // (low $4305 and high $4306 optimisation)
  60. // Turn on DMA transfer for this channel
  61. waitForVBlank();
  62. *(byte*)0x2100 = 0x80;
  63. *(byte*)0x420b = 0x01;
  64. *(byte*)0x2100 = 0x00;
  65. }