From d2c4b6e8b1f34ab755590eafa9f5e5852caa7a70 Mon Sep 17 00:00:00 2001 From: alpine9000 Date: Sun, 20 Mar 2016 21:13:47 +1100 Subject: [PATCH] Slideshow work in progress --- 023.slideshow/Makefile | 49 +++++ 023.slideshow/README.md | 7 + 023.slideshow/alpine_bootblock.s | 346 +++++++++++++++++++++++++++++++ 023.slideshow/constants.i | 13 ++ 023.slideshow/includes.i | 7 + 023.slideshow/init.s | 46 ++++ 023.slideshow/link.script | 26 +++ 023.slideshow/slideshow.s | 307 +++++++++++++++++++++++++++ 023.slideshow/trackloader.s | 221 ++++++++++++++++++++ 023.slideshow/utils.s | 26 +++ 10 files changed, 1048 insertions(+) create mode 100644 023.slideshow/Makefile create mode 100644 023.slideshow/README.md create mode 100644 023.slideshow/alpine_bootblock.s create mode 100644 023.slideshow/constants.i create mode 100644 023.slideshow/includes.i create mode 100644 023.slideshow/init.s create mode 100644 023.slideshow/link.script create mode 100644 023.slideshow/slideshow.s create mode 100644 023.slideshow/trackloader.s create mode 100644 023.slideshow/utils.s diff --git a/023.slideshow/Makefile b/023.slideshow/Makefile new file mode 100644 index 0000000..783b9ef --- /dev/null +++ b/023.slideshow/Makefile @@ -0,0 +1,49 @@ +EXAMPLE_NAME=slideshow + +SHRINKLER=0 +INTERLACE=1 +HAM_MODE=1 + +BOOTBLOCK_ASM=alpine_bootblock.s + +OBJS=out/init.o out/utils.o out/trackloader.o + +IMAGES=mr.png batgirl.png catwoman.png kb.png fe.png ww.png + +USERSTACK_ADDRESS=7fffc +BASE_ADDRESS=10000 +DECOMPRESS_ADDRESS=10000 + +ifeq ($(HAM_MODE),1) +VASM_EXTRA_ARGS=-DINTERLACE=$(INTERLACE) -DHAM_MODE=$(HAM_MODE) +IMAGECON_ARGS= --dither --ham +IMAGEDATA=$(addprefix out/, $(IMAGES:.png=-ham.bin)) +else +VASM_EXTRA_ARGS=-DINTERLACE=$(INTERLACE) -DHAM_MODE=$(HAM_MODE) +IMAGECON_ARGS=--colors 32 --quantize +IMAGEDATA=$(addprefix out/, $(IMAGES:.png=.bin)) +endif + +SIZEDIMAGEDATA=$(addprefix out/, $(IMAGES:.png=.sized.png)) + +ifeq ($(INTERLACE),1) +FLAGS=--height=512 --interlaced +else +FLAGS=--height=256 +endif + +LINK_COMMANDLINE=vlink -T link.script -brawbin1 $< $(OBJS) -M -o $@ +include ../shared/base.mk + +out/%.sized.png: ../assets/%.png + $(RESIZE) --width=320 $(FLAGS) --blur=0.75 --input=$< --output=$@ + +out/%.bin: out/%.sized.png + $(IMAGECON) --input $< $(IMAGECON_ARGS) --output-bitplanes --output-palette-asm --output-palette $(DITHER) --output out/$* + +out/%-ham.bin: out/%.sized.png + echo $(IMAGEDATA) + $(IMAGECON) --input $< $(IMAGECON_ARGS) --output-bitplanes --output-palette-asm --output-palette $(DITHER) --output out/$* + +out/main.o: $(SIZEDIMAGEDATA) $(IMAGEDATA) constants.i Makefile link.script +out/init.o: constants.i Makefile \ No newline at end of file diff --git a/023.slideshow/README.md b/023.slideshow/README.md new file mode 100644 index 0000000..23f37fb --- /dev/null +++ b/023.slideshow/README.md @@ -0,0 +1,7 @@ +photo slideshow +=============== + +try it +------ + * [Download disk image](bin/slideshow.adf?raw=true) + * Run in SAE diff --git a/023.slideshow/alpine_bootblock.s b/023.slideshow/alpine_bootblock.s new file mode 100644 index 0000000..f2da85f --- /dev/null +++ b/023.slideshow/alpine_bootblock.s @@ -0,0 +1,346 @@ +*** hardware trackloader bootblock +*** original BootLoader.S by Photon ;NOTE: PC-relative code is PREFERRED. +*** see http://coppershade.org/asmskool/SOURCES/Photon-snippets/DDE5-BootLoader.S +*** this version hacked by alpine9000 + + include "../include/registers.i" + +LoaderVars equ $100 ;Useful variables, see CPUinfo: +Loader equ $120 ;start of load script + +MyUserStack equ USERSTACK_ADDRESS ;SSP is at a safe place, but set user + ;stack. + +MFMsync equ $4489 ;AmigaDOS standard sync marker. +MFMlen equ 12980 ;Legacy trackdata read length in bytes + +ShortWt:MACRO ;CPU-independent nop;nop replacement + tst.w (a6) + ENDM + + *** Boot Block starts here *** + +Boot: dc.b 'DOS',0 + dc.l 0,880 + +BootCode: ;gathers some data, turns off OS, copies itself to $100 + + *--- Fetch system info ---* + + move.l 4.w,a6 ;execbase (will soon be destroyed) + move.l 294(a6),d4 ;CPUinfo in lowest byte for your use. + sub.l a4,a4 ;VBR will always be 0 when booting + ;from floppy. No GetVBR needed. + *--- Fastmem available? ---* + + move.l #$20004,d1 ;fast+largest + jsr -216(a6) ;AvailMem() + move.l d0,d5 + sub.l #2048,d5 ;leave room for stacks to grow + moveq #4,d1 + jsr -198(a6) ;AllocMem() + and.l #-8,d0 + move.l d0,a5 ;Start Address + + *--- OS off ---* ;you're nice'n all, but now you die. + + lea $dff002,a6 ;Loader uses this custom base addr + + tst.w (a6) ;wait out blitter +.wblit: btst #6,(a6) + bne.s .wblit + + move.l #$7fff7fff,d1 + move.l d1,$9a-2(a6) ;disable interrupts & req + move.w d1,$9c-2(a6) ;play it again Sam + sub.w #$20,d1 ;don't affect Sprite DMA until Vblank + move.w d1,$96-2(a6) ;disable DMA + + lea MyUserStack,a7 ;some safe place compatible with + ;platform requirements + *--- Copy rest of code/data to fixed address ---* + + lea CopyStart(PC),a0 + lea (LoaderVars).w,a1 + moveq #(BootE-CopyStart)/8,d2 +.copyl: move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + dbf d2,.copyl + JMP (Loader).w ;Info from Exec passed in 4 registers + +******************** $100.w ******************** + +CopyStart: + +CPUinfo: dc.l 0 ;$100 +FastMemSize: dc.l 0 ;$104 +SysVBR: dc.l 0 ;$108 +FastMemStart: dc.l 0 ;$10c + +MFMcyl: dc.w 0 +MFMhead: dc.w 0 +MFMdrv: dc.w 0 +MFMchk: dc.l 0 + + dc.w 0 ;padding to $120 + dc.w 0 ; + dc.w 0 ; + +LoadScript: ;At $120, sysinfo in 4 regs, a6=$dff002 + lea CPUinfo(PC),a3 ;Use this for PC-rel in a pinch. + movem.l d4/d5/a4/a5,(a3) + bsr.s WaitEOF + lea NullCop(PC),a0 + move.l a0,$80-2(a6) ;blank copper + move.w #$87d0,$96-2(a6) ;enable DMA (sprites enabled when used) + + *--- load first part ---* + + lea BASE_ADDRESS,a0 ; main entry point + + if 1 + moveq #2,d0 ;from sector 2 + move.w #-1,d1 ;num sectors, - ==Step0 + jsr LoadMFMB + + move.l 4(a0),d1 + add.l #512,d1 + lsr.l #6,d1 + lsr.l #3,d1 + moveq #2,d0 ;from sector 2 + jsr LoadMFMB + + lea $dff000,a6 ;restore plain custombase addr for demo + + move.l (a0),a0 + jmp (a0) ; -> main entry point + + else + + -moveq #2,d0 ;from sector 2 + move.w #-((mainEnd-mainStart)/512),d1;num sectors, - ==Step0 + jsr LoadMFMB + + jmp (a0) ; -> main entry point + + endif + + *** MFMLoader.S by Photon *** ;requires a6=$dff002 + +WaitEOF: + btst #0,5-2(a6) + beq.s WaitEOF +.w1: cmp.b #$37,6-2(a6) + bne.s .w1 +.w2: cmp.b #$37,6-2(a6) ;wait for last PAL line, $138 + beq.s .w2 + rts + +LoadMFMB: ;loadsectors.a0=dst,d0=startsec.W,d1=nrsecs.W(-=Step0) + MOVEM.L D0-D7/A0-A6,-(SP) + lea $bfd100,a4 + bsr MotorOn + tst.w d1 ;if neg length,then Step0 first + bpl.s .NoSt0 + neg.w d1 +.St0: btst #4,$f01(a4) ;head on cyl 0? + beq.s .Rdy0 + bsr.s StepOut + bra.s .St0 +.Rdy0: lea MFMcyl(PC),a1 + clr.w (a1) +.NoSt0: and.l #$ffff,d0 + divu #22,d0 ;startcyl + sub.w MFMcyl(PC),d0 ;delta-step + beq.s .StRdy + bmi.s .StOut + subq.w #1,d0 +.StIn: bsr.s StepIn + dbf d0,.StIn + bra.s .StRdy + not.w d0 ;=neg+sub#1 +.StOut: bsr.s StepOut + dbf d0,.StIn +.StRdy: swap d0 ;startsec within cyl + cmp.w #11,d0 + blt.s .Head0 + sub.w #11,d0 + bra.s .Head1 +.Head0: bset #2,(a4) + lea MFMhead(PC),a1 + clr.w (a1) + bsr LoadTrak ;read track+decode + beq.s .End +.Head1: bclr #2,(a4) ;Head 1 + lea MFMhead(PC),a1 + move.w #1,(a1) + bsr LoadTrak ;read track+decode + beq.s .End + bsr.s StepIn ;1 cyl forward + bra.s .Head0 +.End: bsr.s MotorOff + MOVEM.L (SP)+,D0-D7/A0-A6 + RTS + +StepOut: + bset #1,(a4) + lea MFMcyl(PC),a1 + subq.w #1,(a1) + ShortWt + bclr #0,(a4) + ShortWt + bset #0,(a4) + bsr.s StepWt + RTS + +StepIn: + bclr #1,(a4) + lea MFMcyl(PC),a1 + addq.w #1,(a1) + ShortWt + bclr #0,(a4) + ShortWt + bset #0,(a4) + bsr.s StepWt + RTS + +StepWt: + moveq #67,d6 ;wait >3 ms +LeaveLine: +.loop1: move.b 6-2(a6),d7 +.loop2: cmp.b 6-2(a6),d7 + beq.s .loop2 + dbf d6,.loop1 + RTS + +MotorOn: + move.w MFMdrv(PC),d7 + addq.w #3,d7 + or.b #$78,(a4) + bset d7,(a4) + ShortWt + bclr #7,(a4) ;turns motor on + ShortWt + bclr d7,(a4) + ShortWt +.DiskR: btst #5,$f01(a4) ;wait until motor running + bne.s .DiskR + RTS + +MotorOff: + move.w MFMdrv(PC),d7 + addq.w #3,d7 + bset d7,(a4) + ShortWt + bset #7,(a4) + ShortWt + bclr d7,(a4) + RTS + +LoadTrak: ;loadtrack+decode.a0=dst,d0=secoffs,d1=secsleft + MOVE.W D0,-(SP) + MOVE.W D1,-(SP) + lea (MFMbuf).w,a1 + move.w #2,$9c-2(a6) ;Clr Req + move.l a1,$20-2(a6) + move.w #$8210,$96-2(a6) ;DskEna + move.w #MFMsync,$7e-2(a6) + move.w #$9500,$9e-2(a6) + move.w #$4000,$24-2(a6) + move.w #$8000+MFMlen/2,$24-2(a6);DskLen(12980)+DmaEn + move.w #$8000+MFMlen/2,$24-2(a6);start reading MFMdata +.Wrdy: + btst #1,$1f-2(a6) ;wait until data read + beq.s .Wrdy + move.w d0,d2 + add.w d1,d2 ;highest sec# (d0=lowest) + cmp.w #11,d2 + ble.s .NoOvr + moveq #11,d2 +.NoOvr: sub.w d0,d2 ;nrsecs + move.l #$55555555,d3 ;and-const + move.w d2,d1 + subq.w #1,d1 ;loopctr +.FindS: cmp.w #MFMsync,(a1)+ ;search for a sync word + bne.s .FindS + cmp.b (a1),d3 ;search for 0-nibble + bne.s .FindS + move.l (a1)+,d4 ;decode fmtbyte/trk#,sec#,eow# + move.l (a1)+,d5 + and.w d3,d4 + and.w d3,d5 + add.w d4,d4 + or.w d5,d4 + lsr.w #8,d4 ;sec# + sub.w d0,d4 ;do we want this sec? + bmi.s .Skip + cmp.w d2,d4 + blt.s .DeCode +.Skip: lea 48+1024(a1),a1 ;nope + bra.s .FindS +.DeCode:lea 40(a1),a1 ;found a sec,skip unnecessary data + move.l a1,d6 + lea MFMchk(PC),a1 + clr.l (a1) + move.l d6,a1 + move.l (a1)+,d6 ;decode data chksum.L + move.l (a1)+,d5 + and.l d3,d6 + and.l d3,d5 + add.l d6,d6 + or.l d5,d6 ;chksum + lea 512(a1),a2 + add.w d4,d4 ;x512 + lsl.w #8,d4 + lea (a0,d4.w),a3 ;dest addr for this sec + moveq #127,d7 +.DClup: move.l (a1)+,d4 + move.l (a2)+,d5 + and.l d3,d4 + and.l d3,d5 + eor.l d4,d6 ;EOR with checksum + eor.l d5,d6 ;EOR with checksum + add.l d4,d4 + or.l d5,d4 + move.l d4,(a3)+ + dbf d7,.DClup ;chksum should now be 0 if correct + lea MFMchk(PC),a1 + or.l d6,(a1) ;or with track total chksum + move.l a2,a1 + dbf d1,.FindS ;decode next sec + MOVE.W (SP)+,D1 + MOVE.W (SP)+,D0 + move.l MFMchk(PC),d3 ;track total chksum OK? + bne LoadTrak ;no,retry + moveq #0,d0 ;set to start of track + move.w d2,d3 + add.w d3,d3 + lsl.w #8,d3 + add.w d3,a0 + sub.w d2,d1 ;sub #secs loaded + RTS + +NullCop: + dc.w $1fc,0 + dc.w $100,$0200 + dc.w $96,$0020 ;ensure sprite DMA is off until needed + dc.w $ffdf,$fffe + dc.l -2 +BootE: + + *** Boot Block ends here *** + + dc.b "BootLoader by Photon/Scoopex" + ;pad bootblock to correct size + cnop 0,1024 + +;MFMbuf is placed here after bootblock end, $3c0.w or so when copied. +MFMbuf equ LoaderVars+(BootE-CopyStart) +MFMbufE equ MFMbuf+MFMlen ;lowest free address. $372e for a full bootblock. + +mainStart: + incbin "out/main.bin" + cnop 0,512 +mainEnd: + end + diff --git a/023.slideshow/constants.i b/023.slideshow/constants.i new file mode 100644 index 0000000..689db18 --- /dev/null +++ b/023.slideshow/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/023.slideshow/includes.i b/023.slideshow/includes.i new file mode 100644 index 0000000..e5906ae --- /dev/null +++ b/023.slideshow/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/023.slideshow/init.s b/023.slideshow/init.s new file mode 100644 index 0000000..8c89ead --- /dev/null +++ b/023.slideshow/init.s @@ -0,0 +1,46 @@ + + include "includes.i" + + xref Init + + section CODE + ;; 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 + + lea level3InterruptHandler,a3 + move.l a3,LVL3_INT_VECTOR + + ;; 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/023.slideshow/link.script b/023.slideshow/link.script new file mode 100644 index 0000000..0dc0bce --- /dev/null +++ b/023.slideshow/link.script @@ -0,0 +1,26 @@ +MEMORY +{ +ram: org = 0x10000, len = 0x100000 +} + +SECTIONS +{ +load : { + startCode = .; + *(.text) + *(.bss) + *(.data) + *(CODE) + *(DATA) + . = . + 0x1000; + userstack = .; + endCode = .; + } > ram + +photo ALIGN(512) : { + startData = .; + *(.photo) + endData = .; + } > ram +} + diff --git a/023.slideshow/slideshow.s b/023.slideshow/slideshow.s new file mode 100644 index 0000000..9144445 --- /dev/null +++ b/023.slideshow/slideshow.s @@ -0,0 +1,307 @@ + include "includes.i" + + xref InstallColorPalette + xref PokeBitplanePointers + xref copperList + xref copperListAlternate + xref MFMbuf + xref level3InterruptHandler + +IMAGESIZE equ endbitplanes-InstallColorPalette + +byteMap: + dc.l Entry + dc.l endCode-byteMap + +Entry: + move.l #userstack,a7 + lea CUSTOM,a6 + + lea InstallColorPalette,a1 + bsr LoadImage1 + jsr Init + +.mainLoop: + jsr WaitVerticalBlank + + cmp.l #0,doLoad + beq .updateCounter + +.image1: + cmp.l #0,imageIndex + bne .image2 + lea InstallColorPalette2,a1 + bsr LoadImage2 + +.image2: + cmp.l #1,imageIndex + bne .image3 + lea InstallColorPalette3,a1 + bsr LoadImage1 + +.image3: + cmp.l #2,imageIndex + bne .image4 + lea InstallColorPalette4,a1 + bsr LoadImage2 + +.image4: + cmp.l #3,imageIndex + bne .image5 + lea InstallColorPalette5,a1 + bsr LoadImage1 + +.image5: + cmp.l #4,imageIndex + bne .image6 + lea InstallColorPalette6,a1 + bsr LoadImage2 + +.image6: + cmp.l #5,imageIndex + bne .image7 + lea InstallColorPalette,a1 + bsr LoadImage1 + move.l #0,imageIndex + bra .updateCounter + +.image7: +.incr + add.l #1,imageIndex + +.updateCounter: + move.l #0,doLoad + cmp.l #50*5,counter + beq .display + add.l #1,counter + bra .done + +.display: + move.l #0,counter + move.l #1,doLoad +.done + bra .mainLoop + +doLoad: + dc.l 0 +counter: + dc.l 0 +imageIndex: + dc.l 0 + +level3InterruptHandler: + movem.l d0-a6,-(sp) + lea CUSTOM,a6 +.checkVerticalBlank: + move.w INTREQR(a6),d0 + and.w #INTF_VERTB,d0 + beq.s .checkCopper + +.verticalBlank: + move.w #INTF_VERTB,INTREQ(a6) ; clear interrupt bit + if INTERLACE==1 + btst #VPOSRLOFBIT,VPOSR(a6) + beq.s .lof + lea copperListAlternate,a0 + move.l a0,COP1LC(a6) + bra .done +.lof: + lea copperList,a0 + move.l a0,COP1LC(a6) +.done + endif ; INTERLACE==1 +.checkCopper: + move.w INTREQR(a6),d0 + and.w #INTF_COPER,d0 + beq.s .interruptComplete +.copperInterrupt: + move.w #INTF_COPER,INTREQ(a6) ; clear interrupt bit + +.interruptComplete: + movem.l (sp)+,d0-a6 + rte + +LoadImage1: + ;; a1 - start address + lea InstallColorPalette,a0 + move.l #IMAGESIZE,d0 + bsr DoLoadImage + jsr InstallColorPalette + lea bitplanes,a1 + bsr SetupImage + rts + +LoadImage2: + ;; a1 - start address + lea InstallColorPalette2,a0 + move.l #IMAGESIZE,d0 + bsr DoLoadImage + jsr InstallColorPalette2 + lea bitplanes2,a1 + bsr SetupImage + rts + +SetupImage: + ;; a1 - bitplanes address + movem.l d0-a6,-(sp) + 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 + + moveq.l #0,d0 + lea copperList,a0 + jsr PokeBitplanePointers + movem.l (sp)+,d0-a6 + rts + +DoLoadImage: + ;; a0 - destination address + ;; a1 - start address + ;; d0 - size + movem.l d0-a6,-(sp) + lea $dff002,a6 ;Loader uses this custom base addr + + move.l d0,d1 + + move.l a1,d0 + move.l #startCode,d2 + sub.l d2,d0 ; offset from start of this module + lsr.l #6,d0 ; bytes -> sectors + lsr.l #3,d0 + add.l #2,d0 ; offset for bootblock + + + add.l #512,d1 + lsr.l #6,d1 ; bytes -> sectors + lsr.l #3,d1 + neg.w d1 + jsr LoadMFMB + + movem.l (sp)+,d0-a6 + rts + +PokeBitplanePointers: + ; d0 = frame offset in bytes + ; a0 = BPLP copper list address + ; a1 = bitplanes pointer + movem.l d0-a6,-(sp) + 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 + + 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 + + section .photo +InstallColorPalette: + include "out/mr-palette.s" + rts +bitplanes: + if HAM_MODE==1 + incbin "out/mr-ham.bin" + else + incbin "out/mr.bin" + endif +endbitplanes: + + + cnop 0,512 +InstallColorPalette2: + include "out/catwoman-palette.s" + rts +bitplanes2: + if HAM_MODE==1 + incbin "out/catwoman-ham.bin" + else + incbin "out/catwoman.bin" + endif +endbitplanes2: + + + cnop 0,512 +InstallColorPalette3: + include "out/batgirl-palette.s" + rts + if HAM_MODE==1 + incbin "out/batgirl-ham.bin" + else + incbin "out/batgirl.bin" + endif +endbitplanes3: + + + cnop 0,512 +InstallColorPalette4: + include "out/kb-palette.s" + rts + if HAM_MODE==1 + incbin "out/kb-ham.bin" + else + incbin "out/kb.bin" + endif +endbitplanes4: + + cnop 0,512 +InstallColorPalette5: + include "out/fe-palette.s" + rts + if HAM_MODE==1 + incbin "out/fe-ham.bin" + else + incbin "out/fe.bin" + endif +endbitplanes5: + + cnop 0,512 +InstallColorPalette6: + include "out/ww-palette.s" + rts + if HAM_MODE==1 + incbin "out/ww-ham.bin" + else + incbin "out/ww.bin" + endif +endbitplanes6: \ No newline at end of file diff --git a/023.slideshow/trackloader.s b/023.slideshow/trackloader.s new file mode 100644 index 0000000..d88b373 --- /dev/null +++ b/023.slideshow/trackloader.s @@ -0,0 +1,221 @@ +*** MFMLoader.S by Photon *** ;requires a6=$dff002 + + xref LoadMFMB + +MFMsync equ $4489 ;AmigaDOS standard sync marker. +MFMlen equ 12980 ;Legacy trackdata read length in bytes + +ShortWt:MACRO ;CPU-independent nop;nop replacement + tst.w (a6) + ENDM + +WaitEOF: + btst #0,5-2(a6) + beq.s WaitEOF +.w1: cmp.b #$37,6-2(a6) + bne.s .w1 +.w2: cmp.b #$37,6-2(a6) ;wait for last PAL line, $138 + beq.s .w2 + rts + +MFMcyl: dc.w 0 +MFMhead: dc.w 0 +MFMdrv: dc.w 0 +MFMchk: dc.l 0 + +LoadMFMB: ;loadsectors.a0=dst,d0=startsec.W,d1=nrsecs.W(-=Step0) + MOVEM.L D0-D7/A0-A6,-(SP) + lea $bfd100,a4 + bsr MotorOn + tst.w d1 ;if neg length,then Step0 first + bpl.s .NoSt0 + neg.w d1 +.St0: btst #4,$f01(a4) ;head on cyl 0? + beq.s .Rdy0 + bsr.s StepOut + bra.s .St0 +.Rdy0: lea MFMcyl(PC),a1 + clr.w (a1) +.NoSt0: and.l #$ffff,d0 + divu #22,d0 ;startcyl + sub.w MFMcyl(PC),d0 ;delta-step + beq.s .StRdy + bmi.s .StOut + subq.w #1,d0 +.StIn: bsr.s StepIn + dbf d0,.StIn + bra.s .StRdy + not.w d0 ;=neg+sub#1 +.StOut: bsr.s StepOut + dbf d0,.StIn +.StRdy: swap d0 ;startsec within cyl + cmp.w #11,d0 + blt.s .Head0 + sub.w #11,d0 + bra.s .Head1 +.Head0: bset #2,(a4) + lea MFMhead(PC),a1 + clr.w (a1) + bsr LoadTrak ;read track+decode + beq.s .End +.Head1: bclr #2,(a4) ;Head 1 + lea MFMhead(PC),a1 + move.w #1,(a1) + bsr LoadTrak ;read track+decode + beq.s .End + bsr.s StepIn ;1 cyl forward + bra.s .Head0 +.End: bsr.s MotorOff + MOVEM.L (SP)+,D0-D7/A0-A6 + RTS + +StepOut: + bset #1,(a4) + lea MFMcyl(PC),a1 + subq.w #1,(a1) + ShortWt + bclr #0,(a4) + ShortWt + bset #0,(a4) + bsr.s StepWt + RTS + +StepIn: + bclr #1,(a4) + lea MFMcyl(PC),a1 + addq.w #1,(a1) + ShortWt + bclr #0,(a4) + ShortWt + bset #0,(a4) + bsr.s StepWt + RTS + +StepWt: + moveq #67,d6 ;wait >3 ms +LeaveLine: +.loop1: move.b 6-2(a6),d7 +.loop2: cmp.b 6-2(a6),d7 + beq.s .loop2 + dbf d6,.loop1 + RTS + +MotorOn: + move.w MFMdrv(PC),d7 + addq.w #3,d7 + or.b #$78,(a4) + bset d7,(a4) + ShortWt + bclr #7,(a4) ;turns motor on + ShortWt + bclr d7,(a4) + ShortWt +.DiskR: btst #5,$f01(a4) ;wait until motor running + bne.s .DiskR + RTS + +MotorOff: + move.w MFMdrv(PC),d7 + addq.w #3,d7 + bset d7,(a4) + ShortWt + bset #7,(a4) + ShortWt + bclr d7,(a4) + RTS + +LoadTrak: ;loadtrack+decode.a0=dst,d0=secoffs,d1=secsleft + MOVE.W D0,-(SP) + MOVE.W D1,-(SP) + lea MFMbuf,a1 + move.w #2,$9c-2(a6) ;Clr Req + move.l a1,$20-2(a6) + move.w #$8210,$96-2(a6) ;DskEna + move.w #MFMsync,$7e-2(a6) + move.w #$9500,$9e-2(a6) + move.w #$4000,$24-2(a6) + move.w #$8000+MFMlen/2,$24-2(a6);DskLen(12980)+DmaEn + move.w #$8000+MFMlen/2,$24-2(a6);start reading MFMdata +.Wrdy: + btst #1,$1f-2(a6) ;wait until data read + beq.s .Wrdy + move.w d0,d2 + add.w d1,d2 ;highest sec# (d0=lowest) + cmp.w #11,d2 + ble.s .NoOvr + moveq #11,d2 +.NoOvr: sub.w d0,d2 ;nrsecs + move.l #$55555555,d3 ;and-const + move.w d2,d1 + subq.w #1,d1 ;loopctr +.FindS: cmp.w #MFMsync,(a1)+ ;search for a sync word + bne.s .FindS + cmp.b (a1),d3 ;search for 0-nibble + bne.s .FindS + move.l (a1)+,d4 ;decode fmtbyte/trk#,sec#,eow# + move.l (a1)+,d5 + and.w d3,d4 + and.w d3,d5 + add.w d4,d4 + or.w d5,d4 + lsr.w #8,d4 ;sec# + sub.w d0,d4 ;do we want this sec? + bmi.s .Skip + cmp.w d2,d4 + blt.s .DeCode +.Skip: lea 48+1024(a1),a1 ;nope + bra.s .FindS +.DeCode:lea 40(a1),a1 ;found a sec,skip unnecessary data + move.l a1,d6 + lea MFMchk(PC),a1 + clr.l (a1) + move.l d6,a1 + move.l (a1)+,d6 ;decode data chksum.L + move.l (a1)+,d5 + and.l d3,d6 + and.l d3,d5 + add.l d6,d6 + or.l d5,d6 ;chksum + lea 512(a1),a2 + add.w d4,d4 ;x512 + lsl.w #8,d4 + lea (a0,d4.w),a3 ;dest addr for this sec + moveq #127,d7 +.DClup: move.l (a1)+,d4 + move.l (a2)+,d5 + and.l d3,d4 + and.l d3,d5 + eor.l d4,d6 ;EOR with checksum + eor.l d5,d6 ;EOR with checksum + add.l d4,d4 + or.l d5,d4 + move.l d4,(a3)+ + dbf d7,.DClup ;chksum should now be 0 if correct + lea MFMchk(PC),a1 + or.l d6,(a1) ;or with track total chksum + move.l a2,a1 + dbf d1,.FindS ;decode next sec + MOVE.W (SP)+,D1 + MOVE.W (SP)+,D0 + move.l MFMchk(PC),d3 ;track total chksum OK? + bne LoadTrak ;no,retry + moveq #0,d0 ;set to start of track + move.w d2,d3 + add.w d3,d3 + lsl.w #8,d3 + add.w d3,a0 + sub.w d2,d1 ;sub #secs loaded + RTS + +NullCop: + dc.w $1fc,0 + dc.w $100,$0200 + dc.w $96,$0020 ;ensure sprite DMA is off until needed + dc.w $ffdf,$fffe + dc.l -2 +BootE: + + +;MFMbuf is placed here after bootblock end, $3c0.w or so when copied. +MFMbuf: + dcb.b MFMlen diff --git a/023.slideshow/utils.s b/023.slideshow/utils.s new file mode 100644 index 0000000..c539984 --- /dev/null +++ b/023.slideshow/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