testing stuff
authorJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 25 Jul 2018 16:44:52 +0000 (19:44 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 25 Jul 2018 16:44:52 +0000 (19:44 +0300)
12 files changed:
Makefile.amiga
src/amiga/copper.c [new file with mode: 0644]
src/amiga/copper.h [new file with mode: 0644]
src/amiga/gfx.c [new file with mode: 0644]
src/amiga/gfx.h [new file with mode: 0644]
src/amiga/libc/libc_asm.s [new file with mode: 0644]
src/amiga/libc/stdlib.h [new file with mode: 0644]
src/amiga/libc/string.h [new file with mode: 0644]
src/amiga/main.c
src/data_test.h [new file with mode: 0644]
src/game.c [new file with mode: 0644]
src/game.h [new file with mode: 0644]

index 38fe12d..89a02c3 100644 (file)
@@ -1,7 +1,9 @@
 src = $(wildcard src/*.c) \
          $(wildcard src/amiga/*.c)
-asrc = $(wildcard src/amiga/*.s)
+asrc = $(wildcard src/amiga/*.s) \
+          $(wildcard src/amiga/libc/*.s)
 obj = $(src:.c=.o) $(asrc:.s=.o) 
+dep = $(src:.c=.d)
 
 name = retrocrawl
 elf = $(name).elf
@@ -16,8 +18,10 @@ AS = $(tool_prefix)as
 LD = $(tool_prefix)ld
 OBJCOPY = $(tool_prefix)objcopy
 
+inc = -Isrc -Isrc/amiga -Isrc/amiga/libc
+
 ASFLAGS = -m68000
-CFLAGS = -m68000 -ffreestanding -pedantic -Wall -Os
+CFLAGS = -m68000 -ffreestanding -pedantic -Wall -Os $(inc)
 LDFLAGS = -T amiga.ld -print-gc-sections \
                  -L/usr/lib/gcc-cross/m68k-linux-gnu/6 -lgcc
 
@@ -33,10 +37,19 @@ $(elf): $(obj)
 $(bootblock): src/amiga/boot/boot.o
        $(OBJCOPY) -O binary $< $@
 
+-include $(dep)
+
+%.d: %.c
+       @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
+
 .PHONY: clean
 clean:
        rm -f $(obj) src/amiga/boot/boot.o $(bin) $(elf)
 
+.PHONY: cleandep
+cleandep:
+       rm -f $(dep)
+
 .PHONY: run
 run:
        fs-uae
diff --git a/src/amiga/copper.c b/src/amiga/copper.c
new file mode 100644 (file)
index 0000000..2c22d8a
--- /dev/null
@@ -0,0 +1,77 @@
+#include "copper.h"
+#include "hwregs.h"
+
+uint32_t *copperlist, *copperlist_end;
+static uint32_t *copmem, *curlist;
+static int mode, copmem_size;
+
+extern uint32_t **_mem_start;
+
+int init_copper(int maxlist, int nlists)
+{
+       /* allocate and set new copper lists */
+       if(maxlist <= 0) maxlist = 256;
+       mode = nlists >= COPPER_DOUBLE ? COPPER_DOUBLE : COPPER_SINGLE;
+
+       copmem_size = maxlist * 4 * mode;
+       copmem = *_mem_start;
+
+       curlist = copperlist = copmem;
+       *curlist = COPPER_END;
+
+       if(mode == COPPER_DOUBLE) {
+               copperlist = curlist + maxlist;
+               *copperlist = COPPER_END;
+       }
+       copperlist_end = copperlist;
+
+       REG32_COP1LC = (uint32_t)curlist;
+       REG_COPJMP1 = 0;        /* causes copper to read COP1LC */
+       return 0;
+}
+
+void cleanup_copper(void)
+{
+}
+
+void enable_copper(void)
+{
+       REG_DMACON = SETBITS(DMA_COPPER);
+}
+
+void disable_copper(void)
+{
+       REG_DMACON = CLRBITS(DMA_COPPER);
+}
+
+void clear_copper(void)
+{
+       copperlist_end = copperlist;
+       *copperlist_end = COPPER_END;
+}
+
+void add_copper(uint32_t cmd)
+{
+       *copperlist_end++ = cmd;
+}
+
+void sort_copper(void)
+{
+       /* TODO */
+}
+
+void swap_copper(void)
+{
+       if(mode == COPPER_DOUBLE) {
+               uint32_t *tmpptr;
+               tmpptr = curlist;
+               curlist = copperlist;
+               copperlist = copperlist_end = tmpptr;
+
+               REG32_COP1LC = (uint32_t)curlist;
+               REG_COPJMP1 = 0;
+       } else {
+               copperlist_end = curlist;
+       }
+       *copperlist_end = COPPER_END;
+}
diff --git a/src/amiga/copper.h b/src/amiga/copper.h
new file mode 100644 (file)
index 0000000..3e64315
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef COPPER_H_
+#define COPPER_H_
+
+#include "inttypes.h"
+
+#define COPPER_MOVE(reg, data) (((uint32_t)(reg) << 16) | ((uint32_t)(data) & 0xffff))
+#define COPPER_WAIT(x, y) \
+       (0x0001fffe | ((uint32_t)((x) + 0x81) << 16) | ((uint32_t)((y) + 0x2c) << 24))
+#define COPPER_WAIT_OVERSCAN(x, y) \
+       (0x0001fffe | ((uint32_t)(x) << 16) | ((uint32_t)(y) << 24))
+#define COPPER_VWAIT(s)                        (0x0001ff00 | ((uint32_t)((s) + 0x2c) << 24))
+#define COPPER_VWAIT_OVERSCAN(s) \
+       (0x0001ff00 | ((uint32_t)(s) << 24))
+#define COPPER_OVERFLOW                        0xffdffffe
+#define COPPER_END                             0xfffffffe
+
+extern uint32_t *copperlist, *copperlist_end;
+
+enum {
+       COPPER_SINGLE = 1,
+       COPPER_DOUBLE = 2
+};
+
+int init_copper(int maxlist, int nlists);
+void cleanup_copper(void);
+
+/* enables copper DMA */
+void enable_copper(void);
+/* disables copper DMA */
+void disable_copper(void);
+
+void clear_copper(void);
+void add_copper(uint32_t cmd);
+void sort_copper(void);        /* TODO */
+
+void swap_copper(void);
+
+
+#endif /* COPPER_H_ */
diff --git a/src/amiga/gfx.c b/src/amiga/gfx.c
new file mode 100644 (file)
index 0000000..b18e027
--- /dev/null
@@ -0,0 +1,26 @@
+#include "gfx.h"
+#include "hwregs.h"
+
+int init_gfx(void)
+{
+       int i;
+
+       REG_BPLCON0 = BPLCON0_COUNT(NBPL) | BPLCON0_COLOR;
+       REG_BPLCON1 = 0;
+       REG_DIWSTART = 0x2c81;
+       REG_DIWSTOP = 0x2cc1;
+       REG_DDFSTART = 0x38;
+       REG_DDFSTOP = 0xd0;
+
+       for(i=0; i<NBPL; i++) {
+               bplptr[i] = framebuf + SCANSZ * i;
+       }
+       REG_BPL1MOD = SCANSZ * (NBPL - 1);
+       REG_BPL2MOD = SCANSZ * (NBPL - 1);
+
+       for(i=0; i<32; i++) {
+               REG_COLOR_PTR[i] = 0xf0f;
+       }
+
+       return 0;
+}
diff --git a/src/amiga/gfx.h b/src/amiga/gfx.h
new file mode 100644 (file)
index 0000000..f3352fd
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef GFX_H_
+#define GFX_H_
+
+#define SCR_W  320
+#define SCR_H  256
+#define SCANSZ (SCR_W / 8)
+#define BPLSZ  (SCANSZ * SCR_H)
+#define NBPL   5
+
+#define wait_vpos(x) \
+       asm volatile ( \
+               "0: move.l 0xdff004, %%d0\n\t" \
+               "and.l #0x1ff00, %%d0\n\t" \
+               "cmp.l %0, %%d0\n\t" \
+               "bne 0b\n\t" \
+               :: "i"((x) << 8) : "%d0")
+
+#define wait_vblank() wait_vpos(300)
+
+unsigned char framebuf[BPLSZ * NBPL];
+unsigned char *bplptr[NBPL];
+
+int init_gfx(void);
+
+#endif /* GFX_H_ */
diff --git a/src/amiga/libc/libc_asm.s b/src/amiga/libc/libc_asm.s
new file mode 100644 (file)
index 0000000..095c8df
--- /dev/null
@@ -0,0 +1,24 @@
+| vi:filetype=gas68k:
+       .text
+
+       | optimize: transfer words at a time
+       .global memcpy
+memcpy:
+       move.l 4(%sp), %a0
+       move.l 8(%sp), %a1
+       move.l 12(%sp), %d0
+       sub.l #1, %d0
+0:     move.b (%a1)+, (%a0)+
+       dbra %d0, 0b
+       rts
+
+       | optimize: same as above
+       .global memset
+memset:
+       move.l 4(%sp), %a0
+       move.l 8(%sp), %d1
+       move.l 12(%sp), %d0
+       sub.l #1, %d0
+0:     move.b %d1, (%a0)+
+       dbra %d0, 0b
+       rts
diff --git a/src/amiga/libc/stdlib.h b/src/amiga/libc/stdlib.h
new file mode 100644 (file)
index 0000000..e0a11dc
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef AMIGA_LIBC_STDLIB_H_
+#define AMIGA_LIBC_STDLIB_H_
+
+typedef long size_t;
+
+#endif /* AMIGA_LIBC_STDLIB_H_ */
diff --git a/src/amiga/libc/string.h b/src/amiga/libc/string.h
new file mode 100644 (file)
index 0000000..a2e4c74
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef AMIGA_LIBC_STRING_H_
+#define AMIGA_LIBC_STRING_H_
+
+#include <stdlib.h>
+
+void memcpy(void *dest, const void *src, size_t n);
+void memset(void *dest, int c, size_t n);
+
+#endif /* AMIGA_LIBC_STRING_H_ */
index e3cfcd5..83d86d9 100644 (file)
@@ -1,19 +1,46 @@
+#include <string.h>
 #include "hwregs.h"
+#include "copper.h"
+#include "gfx.h"
+#include "game.h"
+
+static uint32_t coplist[32];
 
 int main(void)
 {
-       REG_INTENA = SETBITS(INTEN_VERTB | INTEN_MASTER);
+       int i;
 
+       REG_INTENA = SETBITS(INTEN_VERTB | INTEN_MASTER);
        REG_DMACON = CLRBITS(DMA_ALL);
-       REG_BPLCON0 = BPLCON0_COLOR;
-       REG_BPLCON1 = 0;
-       REG_DIWSTART = 0x2c81;
-       REG_DIWSTOP = 0x2cc1;
-       REG_DDFSTART = 0x38;
-       REG_DDFSTOP = 0xd0;
 
-       REG_COLOR0 = 0x237;
+       init_gfx();
+
+       REG_COLOR0 = 0x111;
+       REG_COLOR1 = 0x23c;
+       REG_COLOR2 = 0xc32;
+       REG_COLOR3 = 0x22c;
+       REG_COLOR4 = 0xcc2;
+
+       wait_vblank();
+
+       uint32_t *copptr = coplist;
+       for(i=0; i<NBPL; i++) {
+               uint32_t addr = (intptr_t)bplptr[i];
+               int reg = REGN_BPL1PTH + i * 4;
+               *copptr++ = COPPER_MOVE(reg, addr >> 16);
+               *copptr++ = COPPER_MOVE(reg + 2, addr);
+       }
+       *copptr = COPPER_END;
+       REG32_COP1LC = (uint32_t)coplist;
+       REG_COPJMP1 = 0;
+
+       REG_DMACON = SETBITS(DMA_BPL | DMA_COPPER | DMA_MASTER);
+
+       game_init();
 
-       for(;;);
+       for(;;) {
+               wait_vblank();
+               game_draw();
+       }
        return 0;
 }
diff --git a/src/data_test.h b/src/data_test.h
new file mode 100644 (file)
index 0000000..a00cb47
--- /dev/null
@@ -0,0 +1,38 @@
+const char test_tiles_cpix[][16][32] = {
+       {
+               "...............#x...............",
+               ".............###xxx.............",
+               "...........x####xxxx#...........",
+               ".........xxx####xxxx###.........",
+               ".......x####xxxx####xxxx#.......",
+               ".....xxx####xxxx####xxxx###.....",
+               "...#xxxx####xxxx####xxxx####x...",
+               ".###xxxx####xxxx####xxxx####xxx.",
+               ".xxx####xxxx####xxxx####xxxx###.",
+               "...x####xxxx####xxxx####xxxx#...",
+               ".....###xxxx####xxxx####xxx.....",
+               ".......#xxxx####xxxx####x.......",
+               ".........###xxxx####xxx.........",
+               "...........#xxxx####x...........",
+               ".............xxx###.............",
+               "...............x#..............."
+       },
+       {
+               "...............@o...............",
+               ".............@@@ooo.............",
+               "...........o@@@@oooo@...........",
+               ".........ooo@@@@oooo@@@.........",
+               ".......o@@@@oooo@@@@oooo@.......",
+               ".....ooo@@@@oooo@@@@oooo@@@.....",
+               "...@oooo@@@@oooo@@@@oooo@@@@o...",
+               ".@@@oooo@@@@oooo@@@@oooo@@@@ooo.",
+               ".ooo@@@@oooo@@@@oooo@@@@oooo@@@.",
+               "...o@@@@oooo@@@@oooo@@@@oooo@...",
+               ".....@@@oooo@@@@oooo@@@@ooo.....",
+               ".......@oooo@@@@oooo@@@@o.......",
+               ".........@@@oooo@@@@ooo.........",
+               "...........@oooo@@@@o...........",
+               ".............ooo@@@.............",
+               "...............o@..............."
+       }
+};
diff --git a/src/game.c b/src/game.c
new file mode 100644 (file)
index 0000000..b4baeca
--- /dev/null
@@ -0,0 +1,90 @@
+#include <string.h>
+#include "game.h"
+#include "data_test.h"
+#include "gfx.h"
+
+#define TILE_W 32
+#define TILE_H 16
+
+void draw_tile(int tid, int x, int y, int light);
+void convert_tile_data(unsigned char *dest, const char *src);
+
+static unsigned char test_tiles[2][TILE_W * TILE_H / 8 * NBPL];
+
+int game_init(void)
+{
+       int i;
+
+       for(i=0; i<2; i++) {
+               convert_tile_data(test_tiles[i], test_tiles_cpix[i][0]);
+       }
+       return 0;
+}
+
+void game_draw(void)
+{
+       draw_tile(0, 32, 16, 0);
+}
+
+
+void draw_tile(int tid, int x, int y, int light)
+{
+       int i;
+
+       unsigned char *dest = bplptr[0] + (y * SCANSZ * NBPL) + x / 8;
+       unsigned char *src = test_tiles[tid];
+
+       for(i=0; i<TILE_H * NBPL; i++) {
+               memcpy(dest, src, TILE_W / 8);
+               dest += SCANSZ;
+               src += TILE_W / 8;
+       }
+}
+
+static inline int charpix_color(char c)
+{
+       switch(c) {
+       case '#':
+               return 1;
+       case 'x':
+               return 2;
+       case '@':
+               return 3;
+       case 'o':
+               return 4;
+       default:
+       case '.':
+               break;
+       }
+       return 0;
+}
+
+#define TILE_SCANSZ    (TILE_W / 8)
+void convert_tile_data(unsigned char *dest, const char *src)
+{
+       int i, j, k;
+       unsigned char *bptr[NBPL];
+
+       for(i=0; i<NBPL; i++) {
+               bptr[i] = dest + TILE_SCANSZ * i;
+       }
+
+       for(i=0; i<TILE_H; i++) {
+               for(j=0; j<TILE_W; j++) {
+                       int col = charpix_color(*src++);
+
+                       for(k=0; k<NBPL; k++) {
+                               *bptr[k] = (*bptr[k] << 1) | (col & 1);
+                               col >>= 1;
+
+                               if((j & 7) == 7) {
+                                       bptr[k]++;
+                               }
+                       }
+               }
+
+               for(j=0; j<NBPL; j++) {
+                       bptr[j] += TILE_SCANSZ * (NBPL - 1);
+               }
+       }
+}
diff --git a/src/game.h b/src/game.h
new file mode 100644 (file)
index 0000000..69c14e8
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef GAME_H_
+#define GAME_H_
+
+int game_init(void);
+void game_draw(void);
+
+#endif /* GAME_H_ */