#include 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++); } }