sprite DMA works
authorJohn Tsiombikas <nuclear@member.fsf.org>
Thu, 21 Dec 2023 15:27:11 +0000 (17:27 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 22 Dec 2023 02:06:28 +0000 (04:06 +0200)
.gitignore
Makefile
src/dma.S
src/libc/stdio.c
src/libc/stdlib.c
src/main.c
src/sprite.S
src/sprite.h
src/vdp.h
src/vdp.inc

index 95a7ed6..e34392b 100644 (file)
@@ -5,3 +5,5 @@
 *.elf
 *.map
 *.z80
+tools/pngdump/pngdump
+core
index 4420eb1..b69ecbe 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ csrc = $(wildcard src/*.c) $(wildcard src/libc/*.c)
 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)
@@ -46,16 +46,18 @@ $(elf): $(obj)
 $(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
index b3f9d86..8cec2e3 100644 (file)
--- a/src/dma.S
+++ b/src/dma.S
@@ -3,6 +3,7 @@
 #include "hwregs.h"
 #include "vdp.inc"
 
+
        | dma_systovram(vmem_addr, src, count)
        .globl dma_systovram
 dma_systovram:
@@ -10,6 +11,7 @@ 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
@@ -34,11 +36,10 @@ dma_systovram:
        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:
index 80da880..ce8bf5c 100644 (file)
@@ -1,5 +1,7 @@
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
 #include <ctype.h>
 #include "debug.h"
 
index a6149e9..8a4c8f0 100644 (file)
@@ -72,10 +72,12 @@ long strtol(const char *str, char **endp, int base)
 
 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;
@@ -103,11 +105,41 @@ void itoa(int val, char *buf, int base)
        *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';
        }
index 9b02e61..faa6b9e 100644 (file)
@@ -7,17 +7,20 @@
 #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;
@@ -26,10 +29,31 @@ int main(void)
                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();
index 42e4efd..158aaac 100644 (file)
@@ -8,11 +8,14 @@
 
        .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:
index 78d10b9..17050e9 100644 (file)
@@ -9,7 +9,7 @@ struct hwsprite {
        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))
 
index 628f7b0..64d7798 100644 (file)
--- a/src/vdp.h
+++ b/src/vdp.h
 #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);
 
index 2e00c93..37a0100 100644 (file)
@@ -1,12 +1,23 @@
        .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: