GD.h 7.3 KB

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