GD.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright (C) 2011-2013 by James Bowman <jamesb@excamera.com>
  3. * Gameduino library for arduino.
  4. *
  5. */
  6. #ifndef _GD_H_INCLUDED
  7. #define _GD_H_INCLUDED
  8. // define SS_PIN before including "GD.h" to override this
  9. #ifndef SS_PIN
  10. #define SS_PIN 9
  11. #endif
  12. #ifdef BOARD_maple
  13. #include "wirish.h"
  14. typedef const unsigned char prog_uchar;
  15. #define Serial SerialUSB
  16. #define pgm_read_byte_near(x) (*(prog_uchar*)x)
  17. #define pgm_read_byte(x) (*(prog_uchar*)x)
  18. #define PROGMEM const
  19. extern HardwareSPI SPI;
  20. #include <stdio.h>
  21. #include <stdint.h>
  22. #include <string.h>
  23. #endif
  24. struct sprplot
  25. {
  26. char x, y;
  27. byte image, palette;
  28. };
  29. class GDClass {
  30. public:
  31. static void begin();
  32. static void end();
  33. static void __start(unsigned int addr);
  34. static void __wstart(unsigned int addr);
  35. static void __end(void);
  36. static byte rd(unsigned int addr);
  37. static void wr(unsigned int addr, byte v);
  38. static unsigned int rd16(unsigned int addr);
  39. static void wr16(unsigned int addr, unsigned int v);
  40. static void fill(int addr, byte v, unsigned int count);
  41. static void copy(unsigned int addr, prog_uchar *src, int count);
  42. #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  43. static void copy(unsigned int addr, uint_farptr_t src, int count);
  44. static void microcode(uint_farptr_t src, int count);
  45. static void uncompress(unsigned int addr, uint_farptr_t src);
  46. #endif
  47. static void setpal(int pal, unsigned int rgb);
  48. static void sprite(int spr, int x, int y, byte image, byte palette, byte rot = 0, byte jk = 0);
  49. static void sprite2x2(int spr, int x, int y, byte image, byte palette, byte rot = 0, byte jk = 0);
  50. static void waitvblank();
  51. static void microcode(prog_uchar *src, int count);
  52. static void uncompress(unsigned int addr, prog_uchar *src);
  53. static void voice(int v, byte wave, unsigned int freq, byte lamp, byte ramp);
  54. static void ascii();
  55. static void putstr(int x, int y, const char *s);
  56. static void screenshot(unsigned int frame);
  57. void __wstartspr(unsigned int spr = 0);
  58. void xsprite(int ox, int oy, char x, char y, byte image, byte palette, byte rot = 0, byte jk = 0);
  59. void xhide();
  60. void plots(int ox, int oy, sprplot *psp, byte count, byte rot, byte jk);
  61. byte spr; // Current sprite, incremented by xsprite/xhide above
  62. };
  63. #define GD_HAS_PLOTS 1 // have the 'GD.plots' method
  64. extern GDClass GD;
  65. #define RGB(r,g,b) ((((r) >> 3) << 10) | (((g) >> 3) << 5) | ((b) >> 3))
  66. #define TRANSPARENT (1 << 15) // transparent for chars and sprites
  67. #define RAM_PIC 0x0000 // Screen Picture, 64 x 64 = 4096 bytes
  68. #define RAM_CHR 0x1000 // Screen Characters, 256 x 16 = 4096 bytes
  69. #define RAM_PAL 0x2000 // Screen Character Palette, 256 x 8 = 2048 bytes
  70. #define IDENT 0x2800
  71. #define REV 0x2801
  72. #define FRAME 0x2802
  73. #define VBLANK 0x2803
  74. #define SCROLL_X 0x2804
  75. #define SCROLL_Y 0x2806
  76. #define JK_MODE 0x2808
  77. #define J1_RESET 0x2809
  78. #define SPR_DISABLE 0x280a
  79. #define SPR_PAGE 0x280b
  80. #define IOMODE 0x280c
  81. #define BG_COLOR 0x280e
  82. #define SAMPLE_L 0x2810
  83. #define SAMPLE_R 0x2812
  84. #define MODULATOR 0x2814
  85. #define SCREENSHOT_Y 0x281e
  86. #define PALETTE16A 0x2840 // 16-color palette RAM A, 32 bytes
  87. #define PALETTE16B 0x2860 // 16-color palette RAM B, 32 bytes
  88. #define PALETTE4A 0x2880 // 4-color palette RAM A, 8 bytes
  89. #define PALETTE4B 0x2888 // 4-color palette RAM A, 8 bytes
  90. #define COMM 0x2890 // Communication buffer
  91. #define COLLISION 0x2900 // Collision detection RAM, 256 bytes
  92. #define VOICES 0x2a00 // Voice controls
  93. #define J1_CODE 0x2b00 // J1 coprocessor microcode RAM
  94. #define SCREENSHOT 0x2c00 // screenshot line RAM
  95. #define RAM_SPR 0x3000 // Sprite Control, 512 x 4 = 2048 bytes
  96. #define RAM_SPRPAL 0x3800 // Sprite Palettes, 4 x 256 = 2048 bytes
  97. #define RAM_SPRIMG 0x4000 // Sprite Image, 64 x 256 = 16384 bytes
  98. #ifndef GET_FAR_ADDRESS // at some point this will become official... https://savannah.nongnu.org/patch/?6352
  99. #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  100. #define GET_FAR_ADDRESS(var) \
  101. ({ \
  102. uint_farptr_t tmp; \
  103. \
  104. __asm__ __volatile__( \
  105. \
  106. "ldi %A0, lo8(%1)" "\n\t" \
  107. "ldi %B0, hi8(%1)" "\n\t" \
  108. "ldi %C0, hh8(%1)" "\n\t" \
  109. "clr %D0" "\n\t" \
  110. : \
  111. "=d" (tmp) \
  112. : \
  113. "p" (&(var)) \
  114. ); \
  115. tmp; \
  116. })
  117. #else
  118. #define GET_FAR_ADDRESS(var) (var)
  119. #endif
  120. #endif
  121. // simple utilities for accessing the asset library in a filesystem-like
  122. // way
  123. // Details of the flash chip:
  124. // http://www.atmel.com/dyn/resources/prod_documents/doc3638.pdf
  125. const int FLASHSEL = 2; // flash SPI select pin
  126. class Asset {
  127. private:
  128. uint32_t addr; // pointer into flash memory
  129. uint16_t remain; // number of remaing unread bytes
  130. byte find_name(const char *name) {
  131. // addr points at a directory, scan for name, if found set addr
  132. // to the entry and return 1, otherwise return 0.
  133. while (true) {
  134. static struct {
  135. char name[12];
  136. uint16_t length;
  137. uint32_t addr;
  138. } de;
  139. read(&de, sizeof(de));
  140. if (de.name[0] == 0)
  141. return 0; // end of dir, no match found
  142. if (strcmp(de.name, name) == 0) {
  143. remain = de.length;
  144. addr = de.addr;
  145. return 1;
  146. }
  147. }
  148. }
  149. public:
  150. int open(const char *d, ...) {
  151. va_list ap;
  152. va_start(ap, d);
  153. addr = 512L * 640;
  154. remain = 1024;
  155. pinMode(FLASHSEL, OUTPUT);
  156. digitalWrite(FLASHSEL, HIGH);
  157. do {
  158. if (!find_name(d))
  159. return 0;
  160. d = va_arg(ap, const char *);
  161. } while (d != NULL);
  162. return 1;
  163. }
  164. int read(void *dst, uint16_t n) {
  165. GD.wr(IOMODE, 'F');
  166. digitalWrite(FLASHSEL, LOW);
  167. SPI.transfer(0x03);
  168. SPI.transfer((byte)(addr >> 16));
  169. SPI.transfer((byte)(addr >> 8));
  170. SPI.transfer((byte)(addr >> 0));
  171. uint16_t actual = min(n, remain); // actual bytes read
  172. byte *bdst = (byte*)dst;
  173. for (uint16_t a = actual; a; a--) {
  174. byte b = SPI.transfer(0);
  175. *bdst++ = b;
  176. addr++;
  177. if ((511 & (uint16_t)addr) == 264)
  178. addr = addr - 264 + 512;
  179. }
  180. remain -= actual;
  181. digitalWrite(FLASHSEL, HIGH);
  182. GD.wr(IOMODE, 0);
  183. return actual;
  184. }
  185. void load(uint16_t dst) {
  186. while (remain) {
  187. byte buf[16];
  188. uint16_t n = min(remain, sizeof(buf));
  189. read(buf, n);
  190. GD.__wstart(dst);
  191. for (byte i = 0; i < n; i++)
  192. SPI.transfer(buf[i]);
  193. GD.__end();
  194. dst += n;
  195. }
  196. }
  197. uint16_t available() {
  198. return remain;
  199. }
  200. };
  201. #endif