GD.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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 VIDEO_MODE 0x2815
  88. #define MODE_800x600_72 0
  89. #define MODE_800x600_60 1
  90. #define SCREENSHOT_Y 0x281e
  91. #define PALETTE16A 0x2840 // 16-color palette RAM A, 32 bytes
  92. #define PALETTE16B 0x2860 // 16-color palette RAM B, 32 bytes
  93. #define PALETTE4A 0x2880 // 4-color palette RAM A, 8 bytes
  94. #define PALETTE4B 0x2888 // 4-color palette RAM A, 8 bytes
  95. #define COMM 0x2890 // Communication buffer
  96. #define COLLISION 0x2900 // Collision detection RAM, 256 bytes
  97. #define VOICES 0x2a00 // Voice controls
  98. #define J1_CODE 0x2b00 // J1 coprocessor microcode RAM
  99. #define SCREENSHOT 0x2c00 // screenshot line RAM
  100. #define RAM_SPR 0x3000 // Sprite Control, 512 x 4 = 2048 bytes
  101. #define RAM_SPRPAL 0x3800 // Sprite Palettes, 4 x 256 = 2048 bytes
  102. #define RAM_SPRIMG 0x4000 // Sprite Image, 64 x 256 = 16384 bytes
  103. #ifndef GET_FAR_ADDRESS // at some point this will become official... https://savannah.nongnu.org/patch/?6352
  104. #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  105. #define GET_FAR_ADDRESS(var) \
  106. ({ \
  107. uint_farptr_t tmp; \
  108. \
  109. __asm__ __volatile__( \
  110. \
  111. "ldi %A0, lo8(%1)" "\n\t" \
  112. "ldi %B0, hi8(%1)" "\n\t" \
  113. "ldi %C0, hh8(%1)" "\n\t" \
  114. "clr %D0" "\n\t" \
  115. : \
  116. "=d" (tmp) \
  117. : \
  118. "p" (&(var)) \
  119. ); \
  120. tmp; \
  121. })
  122. #else
  123. #define GET_FAR_ADDRESS(var) (var)
  124. #endif
  125. #endif
  126. // simple utilities for accessing the asset library in a filesystem-like
  127. // way
  128. // Details of the flash chip:
  129. // http://www.atmel.com/dyn/resources/prod_documents/doc3638.pdf
  130. const int FLASHSEL = 2; // flash SPI select pin
  131. class Asset {
  132. private:
  133. uint32_t addr; // pointer into flash memory
  134. uint16_t remain; // number of remaing unread bytes
  135. byte find_name(const char *name) {
  136. // addr points at a directory, scan for name, if found set addr
  137. // to the entry and return 1, otherwise return 0.
  138. while (true) {
  139. static struct {
  140. char name[12];
  141. uint16_t length;
  142. uint32_t addr;
  143. } de;
  144. read(&de, sizeof(de));
  145. if (de.name[0] == 0)
  146. return 0; // end of dir, no match found
  147. if (strcmp(de.name, name) == 0) {
  148. remain = de.length;
  149. addr = de.addr;
  150. return 1;
  151. }
  152. }
  153. }
  154. public:
  155. int open(const char *d, ...) {
  156. va_list ap;
  157. va_start(ap, d);
  158. addr = 512L * 640;
  159. remain = 1024;
  160. pinMode(FLASHSEL, OUTPUT);
  161. digitalWrite(FLASHSEL, HIGH);
  162. do {
  163. if (!find_name(d))
  164. return 0;
  165. d = va_arg(ap, const char *);
  166. } while (d != NULL);
  167. return 1;
  168. }
  169. int read(void *dst, uint16_t n) {
  170. GD.wr(IOMODE, 'F');
  171. digitalWrite(FLASHSEL, LOW);
  172. SPI.transfer(0x03);
  173. SPI.transfer((byte)(addr >> 16));
  174. SPI.transfer((byte)(addr >> 8));
  175. SPI.transfer((byte)(addr >> 0));
  176. uint16_t actual = min(n, remain); // actual bytes read
  177. byte *bdst = (byte*)dst;
  178. for (uint16_t a = actual; a; a--) {
  179. byte b = SPI.transfer(0);
  180. *bdst++ = b;
  181. addr++;
  182. if ((511 & (uint16_t)addr) == 264)
  183. addr = addr - 264 + 512;
  184. }
  185. remain -= actual;
  186. digitalWrite(FLASHSEL, HIGH);
  187. GD.wr(IOMODE, 0);
  188. return actual;
  189. }
  190. void load(uint16_t dst) {
  191. while (remain) {
  192. byte buf[16];
  193. uint16_t n = min(remain, sizeof(buf));
  194. read(buf, n);
  195. GD.__wstart(dst);
  196. for (byte i = 0; i < n; i++)
  197. SPI.transfer(buf[i]);
  198. GD.__end();
  199. dst += n;
  200. }
  201. }
  202. uint16_t available() {
  203. return remain;
  204. }
  205. };
  206. #endif