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