*.elf
*.map
*.z80
+tools/pngdump/pngdump
+core
asrc = $(wildcard src/*.s)
aSsrc = $(wildcard src/*.S)
obj = $(asrc:.s=-asm.o) $(aSsrc:.S=-asm.o) $(csrc:.c=.o)
-dep = $(csrc:.c=.d)
+dep = $(csrc:.c=.d) $(aSsrc:.S=-asm.d)
z80src = $(wildcard src/z80/*.asm)
z80obj = $(z80src:.asm=.z80)
$(z80bin): $(z80obj)
$(Z80LD) -o $@ $(Z80LDFLAGS) $(z80obj)
-src/data.o: src/data.s data/font8x8.img data/cellspr.img
+src/data-asm.o: src/data.s data/font8x8.img data/cellspr.img
src/z80prog-asm.o: src/z80prog.s $(z80bin)
+data/cellspr.img: data/cellspr.png
+
-include $(dep)
%-asm.o: %.s
$(AS) -o $@ $(ASFLAGS) $<
%-asm.o: %.S
- $(CC) -o $@ $(ASFLAGS) -DASM -c $<
+ $(CC) -o $@ $(ASFLAGS) -DASM -MMD -c $<
%.z80: %.asm
$(Z80AS) -o $@ $(Z80ASFLAGS) $< >/dev/null
#include "hwregs.h"
#include "vdp.inc"
+
| dma_systovram(vmem_addr, src, count)
.globl dma_systovram
dma_systovram:
| set source address
move.l 8(%sp), %d0
+ lsr.l #1, %d0
move.l %d0, %d1
vdp_setreg_reg VDP_REG_DMASRCL, %d0
lsr.w #8, %d1
or.w #(VDP_VRAM_DMA & 0xf0), %d1
| last word needs to come from RAM, so we push it on the stack
move.w %d1, -(%sp)
- move.w (%sp), VDP_CTL_PORT
- add.l #2, %sp
+ move.w (%sp)+, VDP_CTL_PORT
| after DMA ends the cpu can continue, turn DMA off
vdp_setreg VDP_REG_MODE2, VDP_M2_INIT + VDP_M2_DISP
rts
-
+
| vi:ft=gas68k:
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
#include <ctype.h>
#include "debug.h"
void itoa(int val, char *buf, int base)
{
- static char rbuf[16];
+ char rbuf[16];
char *ptr = rbuf;
int neg = 0;
+ if(base <= 0) base = 10;
+
if(val < 0) {
neg = 1;
val = -val;
*buf = 0;
}
+void xtoa(unsigned int val, char *buf)
+{
+ char rbuf[16];
+ char *ptr = rbuf;
+
+ if(val == 0) {
+ *ptr++ = '0';
+ }
+
+ while(val) {
+ unsigned int digit = val & 0xf;
+ *ptr++ = digit < 10 ? (digit + '0') : (digit - 10 + 'a');
+ val >>= 4;
+ }
+
+ ptr--;
+
+ while(ptr >= rbuf) {
+ *buf++ = *ptr--;
+ }
+ *buf = 0;
+}
+
void utoa(unsigned int val, char *buf, int base)
{
static char rbuf[16];
char *ptr = rbuf;
+ if(base == 16) {
+ xtoa(val, buf);
+ return;
+ }
+
+ if(base <= 0) base = 10;
+
if(val == 0) {
*ptr++ = '0';
}
#define SPRITE_BASE 0x8000
extern uint16_t cellspr_data[], cellspr_data_end[];
+uint32_t dbgval[4];
+
int main(void)
{
uint16_t *src;
- int tile;
+ int tile, i;
z80_init();
vdp_init();
dbg_init();
- vdp_setcolor(0, 0, 2, 2, 2);
- vdp_setcolor(0, 15, 15, 15, 15);
+ for(i=0; i<16; i++) {
+ vdp_setcolor(0, i, i, i, i);
+ }
/* upload sprite tiles */
src = cellspr_data;
VDP_DATA = *src++;
}
+ dbg_setcursor(0, 0);
+ printf("xyzzy");
+
for(;;) {
+ dbg_setcursor(32, 0);
+ for(i=0; i<4; i++) {
+ printf("%08x\n", (unsigned int)dbgval[i]);
+ }
spr_begin();
- tile = SPRITE_BASE / 32 + 2;
- spr_add(160, 100, VDP_TILENAME(tile, 0, VDP_TILE_FG), SPR_SIZE(1,1));
+ tile = VDP_ADDR2TILE(SPRITE_BASE);
+ spr_add(160, 50, VDP_TILENAME(tile, 0, VDP_TILE_FG), SPR_SIZE(1,1));
+ tile++;
+ spr_add(160, 60, VDP_TILENAME(tile, 0, VDP_TILE_FG), SPR_SIZE(1,1));
+ tile++;
+ spr_add(160, 75, VDP_TILENAME(tile, 0, VDP_TILE_FG), SPR_SIZE(1,1));
+ tile++;
+ spr_add(156, 90, VDP_TILENAME(tile, 0, VDP_TILE_FG), SPR_SIZE(1,1));
+ spr_add(164, 90, VDP_TILENAME(tile, 0, VDP_TILE_FG | VDP_TILE_HFLIP), SPR_SIZE(1,1));
+ spr_add(156, 98, VDP_TILENAME(tile, 0, VDP_TILE_FG | VDP_TILE_VFLIP), SPR_SIZE(1,1));
+ spr_add(164, 98, VDP_TILENAME(tile, 0, VDP_TILE_FG | VDP_TILE_HVFLIP), SPR_SIZE(1,1));
+ tile++;
+ spr_add(148, 120, VDP_TILENAME(tile, 0, VDP_TILE_FG), SPR_SIZE(2, 2));
+ spr_add(164, 120, VDP_TILENAME(tile, 0, VDP_TILE_FG | VDP_TILE_HFLIP), SPR_SIZE(2, 2));
+ spr_add(148, 136, VDP_TILENAME(tile, 0, VDP_TILE_FG | VDP_TILE_VFLIP), SPR_SIZE(2, 2));
+ spr_add(164, 136, VDP_TILENAME(tile, 0, VDP_TILE_FG | VDP_TILE_HVFLIP), SPR_SIZE(2, 2));
vdp_wait_vblank();
spr_submit();
.globl spr_submit
spr_submit:
- move.l spr_count, -(%sp)
- move.l #spr_shadow, -(%sp)
- move.l #0x8000, -(%sp)
+ move.l spr_count, %d0
+ lsl.l #2, %d0 | 4 words per sprite
+ move.l %d0, -(%sp)
+ pea spr_shadow
+ pea 0xe000.w | we placed the spirte table at e000
jsr dma_systovram
- add.l #12, %sp
+ addq.l #8, %sp
+ addq.l #4, %sp
rts
| vi:ft=gas68k:
uint8_t next;
uint16_t tile;
uint16_t x;
-} __attribute__((packed));
+} __attribute__((packed, aligned(2)));
#define SPR_SIZE(x, y) ((((x) - 1) << 2) | ((y) - 1))
#define VDP_TILE_PAL(x) ((x) << 13)
#define VDP_TILE_VFLIP 0x1000
#define VDP_TILE_HFLIP 0x0800
+#define VDP_TILE_HVFLIP (VDP_TILE_HFLIP | VDP_TILE_VFLIP)
#define VDP_TILENAME(tile, pal, flags) \
((tile) | VDP_TILE_PAL(pal) | (flags))
+#define VDP_ADDR2TILE(x) ((x) >> 5)
+
void vdp_init(void);
void vdp_setcolor(int pal, int cidx, int r, int g, int b);
.macro vdp_setreg reg val
- move.w #(\val), %d0
- or.w #(0x8000 + (\reg << 8)), %d0
- move.w %d0, VDP_CTL_PORT
+ move.w #(0x8000 + ((\reg) << 8) + (\val)), VDP_CTL_PORT
.endm
- .macro vdp_setreg_reg reg val
- or.w #(0x8000 + (\reg << 8)), \val
- move.w \val, VDP_CTL_PORT
+ .macro vdp_setreg_reg vdpreg valreg
+ and.w #0xff, \valreg
+ or.w #(0x8000 + ((\vdpreg) << 8)), \valreg
+ move.w \valreg, VDP_CTL_PORT
+ .endm
+
+ .macro vdp_setup_addr type addr
+ move.l #((\type) + (((\addr) & 0x3fff) << 16) + (((\addr) >> 14) & 3)), VDP_CTL_PORT
+ .endm
+
+ .macro vdp_setup_addr_reg type addr
+ lsl.l #2, \addr
+ lsr.w #2, \addr
+ swap \addr
+ or.l #(\type), \addr
+ move.l \addr, VDP_CTL_PORT
.endm
| vi:ft=gas68k: