From: John Tsiombikas Date: Tue, 19 Dec 2023 15:05:17 +0000 (+0200) Subject: DMA and sprites (not working yet) X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=commitdiff_plain;h=88989dba0a2f0b59d782d25e01227df04452e8d3;p=mdlife DMA and sprites (not working yet) --- diff --git a/Makefile b/Makefile index 8f84751..4420eb1 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ $(elf): $(obj) $(z80bin): $(z80obj) $(Z80LD) -o $@ $(Z80LDFLAGS) $(z80obj) -src/data.o: src/data.s data/font8x8.img +src/data.o: src/data.s data/font8x8.img data/cellspr.img src/z80prog-asm.o: src/z80prog.s $(z80bin) -include $(dep) @@ -55,7 +55,7 @@ src/z80prog-asm.o: src/z80prog.s $(z80bin) $(AS) -o $@ $(ASFLAGS) $< %-asm.o: %.S - $(CC) -o $@ $(ASFLAGS) -c $< + $(CC) -o $@ $(ASFLAGS) -DASM -c $< %.z80: %.asm $(Z80AS) -o $@ $(Z80ASFLAGS) $< >/dev/null diff --git a/doc/vmem b/doc/vmem index 266a06d..efdd934 100644 --- a/doc/vmem +++ b/doc/vmem @@ -1,5 +1,5 @@ 0000 -8000 +8000 sprite tiles b400 font 96 glyphs * 8x8 / 2 = 3072 bytes c000 nametable A (64x32 * 2 = 4096) d000 nametable B diff --git a/src/data.s b/src/data.s index 2c07f8a..4bb94b6 100644 --- a/src/data.s +++ b/src/data.s @@ -2,8 +2,15 @@ .globl font8x8_data .globl font8x8_data_end + .globl cellspr_data + .globl cellspr_data_end font8x8_data: .incbin "data/font8x8.img" font8x8_data_end: + .align 2 +cellspr_data: + .incbin "data/cellspr.img" +cellspr_data_end: + | vi:ft=gas68k: diff --git a/src/dma.S b/src/dma.S new file mode 100644 index 0000000..b3f9d86 --- /dev/null +++ b/src/dma.S @@ -0,0 +1,44 @@ + .text + +#include "hwregs.h" +#include "vdp.inc" + + | dma_systovram(vmem_addr, src, count) + .globl dma_systovram +dma_systovram: + vdp_setreg VDP_REG_MODE2, VDP_M2_INIT + VDP_M2_DISP + VDP_M2_DMA + + | set source address + move.l 8(%sp), %d0 + move.l %d0, %d1 + vdp_setreg_reg VDP_REG_DMASRCL, %d0 + lsr.w #8, %d1 + vdp_setreg_reg VDP_REG_DMASRCM, %d1 + swap %d0 + vdp_setreg_reg VDP_REG_DMASRCH, %d0 + | set count (in words) + move.w 14(%sp), %d0 + move.w %d0, %d1 + vdp_setreg_reg VDP_REG_DMACNTL, %d0 + lsr.w #8, %d1 + vdp_setreg_reg VDP_REG_DMACNTH, %d1 + | set the destination address. + move.w 6(%sp), %d0 + move.w %d0, %d1 + and.w #0x3fff, %d0 + or.w #(VDP_VRAM_DMA >> 16), %d0 + move.w %d0, VDP_CTL_PORT + | 2 upper bits and rest of the type flags + rol.w #2, %d1 + and.w #3, %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 + + | 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: diff --git a/src/dma.h b/src/dma.h new file mode 100644 index 0000000..5e52234 --- /dev/null +++ b/src/dma.h @@ -0,0 +1,14 @@ +#ifndef DMA_H_ +#define DMA_H_ + +#include "vdp.h" + +#define dma_enable() \ + vdp_setreg(VDP_REG_MODE2, VDP_M2_INIT | VDP_M2_DISP | VDP_M2_DMA) + +#define dma_disable() \ + vdp_setreg(VDP_REG_MODE2, VDP_M2_INIT | VDP_M2_DISP) + +void dma_systovram(uint32_t vaddr, void *src, int count); + +#endif /* DMA_H_ */ diff --git a/src/hwregs.h b/src/hwregs.h index c018023..2838026 100644 --- a/src/hwregs.h +++ b/src/hwregs.h @@ -9,6 +9,10 @@ #define VDP_CRAM 0xc0000000 #define VDP_VSRAM 0x40000010 +#define VDP_VRAM_DMA 0x40000080 +#define VDP_CRAM_DMA 0xc0000080 +#define VDP_VSRAM_DMA 0x40000090 + #ifndef ASM #include diff --git a/src/libc/stdio.h b/src/libc/stdio.h index 3b3e905..866ed70 100644 --- a/src/libc/stdio.h +++ b/src/libc/stdio.h @@ -16,6 +16,4 @@ int vsprintf(char *buf, const char *fmt, va_list ap); int snprintf(char *buf, size_t sz, const char *fmt, ...); int vsnprintf(char *buf, size_t sz, const char *fmt, va_list ap); -void perror(const char *s); - #endif /* STDIO_H_ */ diff --git a/src/libc/string.c b/src/libc/string.c index 81aa415..4124df5 100644 --- a/src/libc/string.c +++ b/src/libc/string.c @@ -3,15 +3,18 @@ #include #include +void *memset(void *s, int c, size_t n) +{ + char *ptr = s; + while(n--) *ptr++ = c; + return s; +} + void *memcpy(void *dest, const void *src, size_t n) { - size_t i; char *dptr = dest; const char *sptr = src; - for(i=0; i #include "z80.h" #include "vdp.h" +#include "sprite.h" #include "debug.h" +#define SPRITE_BASE 0x8000 +extern uint16_t cellspr_data[], cellspr_data_end[]; + int main(void) { + uint16_t *src; + int tile; + z80_init(); vdp_init(); dbg_init(); @@ -11,7 +19,21 @@ int main(void) vdp_setcolor(0, 0, 2, 2, 2); vdp_setcolor(0, 15, 15, 15, 15); - dbg_printstr(0, 0, "Mindlapse"); + /* upload sprite tiles */ + src = cellspr_data; + vdp_setup_addr(VDP_VRAM, SPRITE_BASE); + while(src < cellspr_data_end) { + VDP_DATA = *src++; + } + + for(;;) { + spr_begin(); + tile = SPRITE_BASE / 32 + 2; + spr_add(160, 100, VDP_TILENAME(tile, 0, VDP_TILE_FG), SPR_SIZE(1,1)); + + vdp_wait_vblank(); + spr_submit(); + } return 0; } diff --git a/src/sprite.S b/src/sprite.S new file mode 100644 index 0000000..42e4efd --- /dev/null +++ b/src/sprite.S @@ -0,0 +1,18 @@ + .text + +#include "hwregs.h" + + .extern spr_shadow + .extern spr_count + .extern dma_systovram + + .globl spr_submit +spr_submit: + move.l spr_count, -(%sp) + move.l #spr_shadow, -(%sp) + move.l #0x8000, -(%sp) + jsr dma_systovram + add.l #12, %sp + rts + +| vi:ft=gas68k: diff --git a/src/sprite.c b/src/sprite.c new file mode 100644 index 0000000..63305f3 --- /dev/null +++ b/src/sprite.c @@ -0,0 +1,33 @@ +#include +#include "sprite.h" +#include "vdp.h" + +struct hwsprite spr_shadow[MAX_HWSPRITES]; +int spr_count; + +void spr_begin(void) +{ + memset(spr_shadow, 0, sizeof spr_shadow[0]); + spr_count = 0; +} + +void spr_add(int x, int y, unsigned int tile, int sprsz) +{ + int id; + struct hwsprite *spr; + + if(spr_count >= MAX_HWSPRITES) { + return; + } + id = spr_count++; + spr = spr_shadow + id; + if(id > 0) { + spr[-1].next = id; + } + + spr->x = x + 128; + spr->y = y + 128; + spr->sz = sprsz; + spr->tile = tile; + spr->next = 0; +} diff --git a/src/sprite.h b/src/sprite.h new file mode 100644 index 0000000..78d10b9 --- /dev/null +++ b/src/sprite.h @@ -0,0 +1,24 @@ +#ifndef SPRITE_H_ +#define SPRITE_H_ + +#include + +struct hwsprite { + uint16_t y; + uint8_t sz; + uint8_t next; + uint16_t tile; + uint16_t x; +} __attribute__((packed)); + +#define SPR_SIZE(x, y) ((((x) - 1) << 2) | ((y) - 1)) + +#define MAX_HWSPRITES 64 +extern struct hwsprite spr_shadow[MAX_HWSPRITES]; +extern int spr_count; + +void spr_begin(void); +void spr_add(int x, int y, unsigned int tile, int sprsz); +void spr_submit(void); + +#endif /* SPRITE_H_ */ diff --git a/src/vdp.S b/src/vdp.S index b3c6553..1d62565 100644 --- a/src/vdp.S +++ b/src/vdp.S @@ -1,6 +1,5 @@ .text -#define ASM #include "hwregs.h" .globl vdp_init diff --git a/src/vdp.h b/src/vdp.h index 82e6747..628f7b0 100644 --- a/src/vdp.h +++ b/src/vdp.h @@ -9,6 +9,16 @@ #define vdp_setreg(reg, val) \ (VDP_CTL = 0x8000 | ((reg) << 8) | (val)) +#define vdp_wait_vblank() \ + while(!(VDP_STAT & VDP_ST_VBLANK)) + +#define vdp_wait_vblank_end() \ + while((VDP_STAT & VDP_ST_VBLANK)) + +#define vdp_vsync() \ + (vdp_wait_vblank_end(), vdp_wait_vblank()) + + #define VDP_TILE_BG 0 #define VDP_TILE_FG 0x8000 #define VDP_TILE_PAL(x) ((x) << 13) diff --git a/src/vdp.inc b/src/vdp.inc new file mode 100644 index 0000000..2e00c93 --- /dev/null +++ b/src/vdp.inc @@ -0,0 +1,12 @@ + .macro vdp_setreg reg val + move.w #(\val), %d0 + or.w #(0x8000 + (\reg << 8)), %d0 + move.w %d0, VDP_CTL_PORT + .endm + + .macro vdp_setreg_reg reg val + or.w #(0x8000 + (\reg << 8)), \val + move.w \val, VDP_CTL_PORT + .endm + +| vi:ft=gas68k: