8bitworkshop/presets/williams-z80/skeleton.sdcc

162 lines
4.0 KiB
Plaintext

#include <string.h>
typedef unsigned char byte;
typedef signed char sbyte;
typedef unsigned short word;
typedef enum { false, true } bool;
byte __at (0x0) vidmem[152][256]; // 304x256x4bpp video memory
byte __at (0xc000) palette[16];
volatile byte __at (0xc804) input0;
volatile byte __at (0xc806) input1;
volatile byte __at (0xc80c) input2;
byte __at (0xc80c) sound_pia;
byte __at (0xc900) rom_select;
volatile byte __at (0xcb00) video_counter;
byte __at (0xcbff) watchdog0x39;
byte __at (0xcc00) nvram[0x400];
__sfr __at (0) debug;
// blitter flags
#define SRCSCREEN 0x1
#define DSTSCREEN 0x2
#define ESYNC 0x4
#define FGONLY 0x8
#define SOLID 0x10
#define RSHIFT 0x20
#define EVENONLY 0x40
#define ODDONLY 0x80
struct {
byte flags;
byte solid;
word sstart;
word dstart;
byte width;
byte height;
} __at (0xca00) blitter;
// switch flags
#define UP1 (input0 & 0x1)
#define DOWN1 (input0 & 0x2)
#define LEFT1 (input0 & 0x4)
#define RIGHT1 (input0 & 0x8)
#define START1 (input0 & 0x10)
#define START2 (input0 & 0x20)
#define UP2 (input0 & 0x40)
#define DOWN2 (input0 & 0x80)
#define LEFT2 (input1 & 0x1)
#define RIGHT2 (input1 & 0x2)
#define AUTOUP (input2 & 0x1)
#define ADVANCE (input2 & 0x2)
#define COIN2 (input2 & 0x4)
#define HIGHSCORERESET (input2 & 0x8)
#define COIN1 (input2 & 0x10)
#define COIN3 (input2 & 0x20)
#define TILTSWITCH (input2 & 0x40)
#define SOUNDACK (input2 & 0x80)
#define WATCHDOG watchdog0x39=0x39;
//
void main();
// start routine @ 0x0
// set stack pointer, enable interrupts
void start() {
__asm
LD SP,#0xc000
DI
; copy initialized data
LD BC, #l__INITIALIZER
LD A, B
LD DE, #s__INITIALIZED
LD HL, #s__INITIALIZER
LDIR
__endasm;
main();
}
inline word swapw(word j) {
return ((j << 8) | (j >> 8));
}
// x1: 0-151
// y1: 0-255
inline void blit_solid(byte x1, byte y1, byte w, byte h, byte color) {
blitter.width = w^4;
blitter.height = h^4;
blitter.dstart = x1+y1*256; // swapped
blitter.solid = color;
blitter.flags = DSTSCREEN|SOLID;
}
inline void draw_solid(word x1, byte y1, byte w, byte h, byte color) {
blitter.width = w^4;
blitter.height = h^4;
blitter.dstart = (x1>>1)+y1*256; // swapped
blitter.solid = color;
blitter.flags = (x1&1) ? DSTSCREEN|SOLID|RSHIFT : DSTSCREEN|SOLID;
}
inline void draw_vline(word x1, byte y1, byte h, byte color) {
blitter.width = 1^4;
blitter.height = h^4;
blitter.dstart = (x1>>1)+y1*256; // swapped
blitter.solid = color;
blitter.flags = (x1&1) ? DSTSCREEN|SOLID|ODDONLY : DSTSCREEN|SOLID|EVENONLY;
}
inline void blit_copy_solid(word x, byte y, byte w, byte h, const byte* data, byte solid) {
blitter.width = w^4;
blitter.height = h^4;
blitter.solid = solid;
blitter.sstart = swapw((word)data);
blitter.dstart = (x>>1)+y*256; // swapped
if (solid)
blitter.flags = (x&1) ? DSTSCREEN|FGONLY|SOLID|RSHIFT : DSTSCREEN|FGONLY|SOLID;
else
blitter.flags = (x&1) ? DSTSCREEN|RSHIFT : DSTSCREEN;
}
// bias sprites by +4 pixels
#define XBIAS 2
inline void draw_sprite(const byte* data, byte x, byte y) {
blitter.width = data[0]^4;
blitter.height = data[1]^4;
blitter.sstart = swapw((word)(data+2));
blitter.dstart = (x>>1)+y*256+XBIAS; // swapped
blitter.flags = (x&1) ? DSTSCREEN|FGONLY|RSHIFT : DSTSCREEN|FGONLY;
}
inline void draw_sprite_solid(const byte* data, byte x, byte y, byte color) {
blitter.width = data[0]^4;
blitter.height = data[1]^4;
blitter.sstart = swapw((word)(data+2));
blitter.dstart = (x>>1)+y*256+XBIAS; // swapped
blitter.solid = color;
blitter.flags = (x&1) ? DSTSCREEN|FGONLY|RSHIFT|SOLID : DSTSCREEN|FGONLY|SOLID;
}
void draw_box(word x1, byte y1, word x2, byte y2, byte color) {
draw_solid(x1, y1, (x2-x1)>>1, 1, color);
draw_solid(x1, y2, (x2-x1)>>1, 1, color);
draw_vline(x1, y1, y2-y1, color);
draw_vline(x2, y1, y2-y1, color);
}
static byte frame = 0;
void main() {
palette[0] = 0x88;
memset(vidmem, 0, sizeof(vidmem));
while (1) {
blit_solid(0,0,25,25,frame++);
}
}