PPU.c 2.6 KB

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