diff --git a/021.calling_c/Makefile b/021.calling_c/Makefile new file mode 100644 index 0000000..eb59ecb --- /dev/null +++ b/021.calling_c/Makefile @@ -0,0 +1,41 @@ +SHRINKLER=0 +INTERLACE=0 +HAM_MODE=1 + +EXAMPLE_NAME=calling_c +MODULE=$(EXAMPLE_NAME).s +OBJS=out/init.o out/utils.o out/c_code.o +IMAGEFILE=../assets/gigi_full.png +SIZED_IMAGEFILE=out/image.png +BASE_ADDRESS=50000 +DECOMPRESS_ADDRESS=10000 +FLOPPY=bin/$(EXAMPLE_NAME).adf + +ifeq ($(HAM_MODE),1) +IMAGEDATA=out/image-palette.s out/image-ham.bin +VASM_EXTRA_ARGS=-DINTERLACE=$(INTERLACE) -DHAM_MODE=$(HAM_MODE) +IMAGECON_ARGS=--use-palette gigi.pal --dither --ham +else +VASM_EXTRA_ARGS=-DINTERLACE=$(INTERLACE) -DHAM_MODE=$(HAM_MODE) +IMAGECON_ARGS=--colors 32 --quantize +IMAGEDATA=out/image-palette.s out/image.bin +endif + +ifeq ($(INTERLACE),1) +FLAGS=--height=512 --interlaced +else +FLAGS=--height=256 +endif + +include ../shared/base.mk + + +$(SIZED_IMAGEFILE): $(IMAGEFILE) $(RESIZE) Makefile + $(RESIZE) --width=320 $(FLAGS) --blur=0.75 --input=$(IMAGEFILE) --output=$(SIZED_IMAGEFILE) + +$(IMAGEDATA): $(IMAGECON) $(SIZED_IMAGEFILE) Makefile + $(IMAGECON) --input $(SIZED_IMAGEFILE) $(IMAGECON_ARGS) --output out/image --output-bitplanes --output-palette-asm --output-palette $(DITHER) + + +out/main.o: $(IMAGEDATA) constants.i Makefile +out/init.o: constants.i Makefile \ No newline at end of file diff --git a/021.calling_c/README.md b/021.calling_c/README.md new file mode 100644 index 0000000..687ad87 --- /dev/null +++ b/021.calling_c/README.md @@ -0,0 +1,7 @@ +calling C code +============== + +try it +------ + * [Download disk image](bin/calling_c.adf?raw=true) + * Run in SAE diff --git a/021.calling_c/bin/calling_c.adf b/021.calling_c/bin/calling_c.adf new file mode 100644 index 0000000..228906a Binary files /dev/null and b/021.calling_c/bin/calling_c.adf differ diff --git a/021.calling_c/c_code.c b/021.calling_c/c_code.c new file mode 100644 index 0000000..bbbae09 --- /dev/null +++ b/021.calling_c/c_code.c @@ -0,0 +1,21 @@ +void +PokeBitplanePointers(unsigned short* copper, unsigned char* bitplanes, unsigned offset, unsigned numBitplanes, unsigned screenWidthBytes) +{ + int i; + copper += offset; + + for (i = 0; i < numBitplanes; i++) { + *(copper+1) = (unsigned)bitplanes; + *(copper+3) = ((unsigned)bitplanes >> 16); + bitplanes += screenWidthBytes; + copper += 4; + } +} + +static unsigned short _copperData; +static unsigned char _bitplaneData; +static void +TestCall() +{ + PokeBitplanePointers(&_copperData, &_bitplaneData, 3, 4, 5); +} diff --git a/021.calling_c/calling_c.s b/021.calling_c/calling_c.s new file mode 100644 index 0000000..772ecec --- /dev/null +++ b/021.calling_c/calling_c.s @@ -0,0 +1,93 @@ + include "includes.i" + + xref InstallColorPalette + ;;xref PokeBitplanePointers + xref copperList + xref copperListAlternate + xref bitplanes + +Entry: + lea CUSTOM,a6 + jsr Init + +.mainLoop: + jsr WaitVerticalBlank + + if INTERLACE == 1 + btst.w #VPOSRLOFBIT,VPOSR(a6) + beq.s .lof + lea copperListAlternate(pc),a0 + move.l a0,COP1LC(a6) + bra .done +.lof: + lea copperList(pc),a0 + move.l a0,COP1LC(a6) +.done + endif ; INTERLACE == 1 + bra .mainLoop + +;=========================================================== + if 0 +PokeBitplanePointers: ; d0 = frame offset in bytes, a0 = BPLP copper list address + movem.l d0-a6,-(sp) + move.l bitplanes,a1 + add.l d0,a1 ; Offset for odd/even frames + moveq #SCREEN_BIT_DEPTH-1,d0 +.bitplaneloop: + move.l a1,d1 + move.w d1,2(a0) + swap d1 + move.w d1,6(a0) + lea SCREEN_WIDTH_BYTES(a1),a1 + addq #8,a0 + dbra d0,.bitplaneloop + movem.l (sp)+,d0-a6 + rts + endif +;=========================================================== + +InstallColorPalette: + include "out/image-palette.s" + rts + + if INTERLACE == 1 +copperListAlternate: + ;; bitplane pointers must be first else poking addresses will be incorrect + dc.w BPL1PTL,0 + dc.w BPL1PTH,0 + dc.w BPL2PTL,0 + dc.w BPL2PTH,0 + dc.w BPL3PTL,0 + dc.w BPL3PTH,0 + dc.w BPL4PTL,0 + dc.w BPL4PTH,0 + dc.w BPL5PTL,0 + dc.w BPL5PTH,0 + dc.w BPL6PTL,0 + dc.w BPL6PTH,0 + dc.l $fffffffe + endif ; INTERLACE == 1 + +copperList: + ;; bitplane pointers must be first else poking addresses will be incorrect + dc.w BPL1PTL,0 + dc.w BPL1PTH,0 + dc.w BPL2PTL,0 + dc.w BPL2PTH,0 + dc.w BPL3PTL,0 + dc.w BPL3PTH,0 + dc.w BPL4PTL,0 + dc.w BPL4PTH,0 + dc.w BPL5PTL,0 + dc.w BPL5PTH,0 + dc.w BPL6PTL,0 + dc.w BPL6PTH,0 + + dc.l $fffffffe + +bitplanes: + if HAM_MODE == 1 + incbin "out/image-ham.bin" + else + incbin "out/image.bin" + endif \ No newline at end of file diff --git a/021.calling_c/constants.i b/021.calling_c/constants.i new file mode 100644 index 0000000..689db18 --- /dev/null +++ b/021.calling_c/constants.i @@ -0,0 +1,13 @@ +SCREEN_WIDTH equ 320 +SCREEN_HEIGHT equ (256+(256*INTERLACE)) +SCREEN_WIDTH_BYTES equ (SCREEN_WIDTH/8) + if HAM_MODE == 1 +SCREEN_BIT_DEPTH equ 6 + else +SCREEN_BIT_DEPTH equ 5 + endif +SCREEN_RES equ 8 ; 8=lo resolution, 4=hi resolution +RASTER_X_START equ $81 ; hard coded coordinates from hardware manual +RASTER_Y_START equ $2c +RASTER_X_STOP equ RASTER_X_START+SCREEN_WIDTH +RASTER_Y_STOP equ RASTER_Y_START+256 diff --git a/021.calling_c/gigi.pal b/021.calling_c/gigi.pal new file mode 100644 index 0000000..90b5e5b --- /dev/null +++ b/021.calling_c/gigi.pal @@ -0,0 +1,16 @@ +875 +532 +ea7 +89a +752 +321 +b74 +565 +fc9 +963 +d95 +9ab +689 +742 +a97 +210 diff --git a/021.calling_c/includes.i b/021.calling_c/includes.i new file mode 100644 index 0000000..e5906ae --- /dev/null +++ b/021.calling_c/includes.i @@ -0,0 +1,7 @@ + include "../include/registers.i" + include "../include/vector.i" + include "../include/beambits.i" + include "../include/bplconbits.i" + include "hardware/dmabits.i" + include "hardware/intbits.i" + include "constants.i" \ No newline at end of file diff --git a/021.calling_c/init.s b/021.calling_c/init.s new file mode 100644 index 0000000..b54d055 --- /dev/null +++ b/021.calling_c/init.s @@ -0,0 +1,61 @@ + + include "includes.i" + + xref Init + + ;; custom chip base globally in a6 +Init: + movem.l d0-a6,-(sp) + move #$7ff,DMACON(a6) ; disable all dma + move #$7fff,INTENA(a6) ; disable all interrupts + + ;; set up default palette + jsr InstallColorPalette + + if INTERLACE == 1 + ;; poke the bitplane pointers for the two copper lists. + move.l #SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH,d0 + lea copperListAlternate,a0 + jsr PokeBitplanePointers + endif + + ;; void PokeBitplanePointers(unsigned short* copper, unsigned char* bitplanes, unsigned offset, unsigned numBitplanes, unsigned screenWidthBytes) + move.l #SCREEN_WIDTH_BYTES,-(sp) + move.l #SCREEN_BIT_DEPTH,-(sp) + move.l #0,-(sp) + pea bitplanes + pea copperList + jsr _PokeBitplanePointers + add.l #20,sp + + ;; set up playfield + move.w #(RASTER_Y_START<<8)|RASTER_X_START,DIWSTRT(a6) + move.w #((RASTER_Y_STOP-256)<<8)|(RASTER_X_STOP-256),DIWSTOP(a6) + + move.w #(RASTER_X_START/2-SCREEN_RES),DDFSTRT(a6) + move.w #(RASTER_X_START/2-SCREEN_RES)+(8*((SCREEN_WIDTH/16)-1)),DDFSTOP(a6) + + if HAM_MODE == 1 +HAMBIT equ HOMOD + else +HAMBIT equ 0 + endif + + if INTERLACE == 1 + move.w #(SCREEN_BIT_DEPTH<<12)|COLOR_ON|HAMBIT|LACE,BPLCON0(a6) + move.w #2*SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES,BPL1MOD(a6) + move.w #2*SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES,BPL2MOD(a6) + else + move.w #(SCREEN_BIT_DEPTH<<12)|COLOR_ON|HAMBIT,BPLCON0(a6) + move.w #SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES,BPL1MOD(a6) + move.w #SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES,BPL2MOD(a6) + endif + + ;; install copper list, then enable dma and selected interrupts + lea copperList,a0 + move.l a0,COP1LC(a6) + move.w COPJMP1(a6),d0 + move.w #(DMAF_BLITTER|DMAF_SETCLR!DMAF_COPPER!DMAF_RASTER!DMAF_MASTER),DMACON(a6) + ;; move.w #(INTF_SETCLR|INTF_VERTB|INTF_INTEN),INTENA(a6) + movem.l (sp)+,d0-a6 + rts \ No newline at end of file diff --git a/021.calling_c/test.c b/021.calling_c/test.c new file mode 100644 index 0000000..0445180 --- /dev/null +++ b/021.calling_c/test.c @@ -0,0 +1,5 @@ +int +GetScreenBitDepth() +{ + return 5; +} diff --git a/021.calling_c/utils.s b/021.calling_c/utils.s new file mode 100644 index 0000000..c539984 --- /dev/null +++ b/021.calling_c/utils.s @@ -0,0 +1,26 @@ + xref WaitVerticalBlank + xref WaitRaster + +WaitVerticalBlank: + movem.l d0-a6,-(sp) +.loop move.l $dff004,d0 + and.l #$1ff00,d0 + cmp.l #303<<8,d0 + bne.b .loop + movem.l (sp)+,d0-a6 + rts + + + +WaitRaster: ;wait for rasterline d0.w. Modifies d0-d2/a0. + movem.l d0-a6,-(sp) + move.l #$1ff00,d2 + lsl.l #8,d0 + and.l d2,d0 + lea $dff004,a0 +.wr: move.l (a0),d1 + and.l d2,d1 + cmp.l d1,d0 + bne.s .wr + movem.l (sp)+,d0-a6 + rts \ No newline at end of file diff --git a/Makefile b/Makefile index 5dc9f13..3199d69 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,8 @@ SUBDIRS=tools/makeadf \ 017.dual_playfield\ 018.vert_scroll\ 019.hori_scroll\ - 020.shrinkler + 020.shrinkler\ + 021.calling_c .PHONY: subdirs $(SUBDIRS) diff --git a/shared/base.mk b/shared/base.mk index ab5d6bd..3a4398d 100644 --- a/shared/base.mk +++ b/shared/base.mk @@ -90,11 +90,14 @@ out/main.o: $(MODULE) $(EXTRA) out/%.o: %.s vasmm68k_mot $(VASM_EXTRA_ARGS) -Fhunk -phxass -opt-fconst -nowarn=62 -quiet $< -o $@ -I/usr/local/amiga/os-include +out/%.o: %.c + vc -O3 -c $< -o $@ + -@vc -O3 -S $< -o out/$*.s > /dev/null 2> /dev/null + out/main.bin: out/main.o $(OBJS) @#-T ../link.script vlink -Ttext 0x$(BASE_ADDRESS) -brawbin1 $< $(OBJS) -o $@ - out/shrunk.bin: $(SHRINKLER_EXE) out/main.bin $(SHRINKLEREXE) -d out/main.bin out/shrunk.bin