GD.h 7.3 KB

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