GD.h 7.7 KB

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