1
0
mirror of https://frontier.innolan.net/github/AmigaExamples.git synced 2026-01-12 04:39:06 +00:00

Slideshow work in progress

This commit is contained in:
alpine9000
2016-03-20 21:13:47 +11:00
parent 2da8e747dc
commit d2c4b6e8b1
10 changed files with 1048 additions and 0 deletions

49
023.slideshow/Makefile Normal file
View File

@ -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

7
023.slideshow/README.md Normal file
View File

@ -0,0 +1,7 @@
photo slideshow
===============
try it
------
* [Download disk image](bin/slideshow.adf?raw=true)
* <a href="http://alpine9000.github.io/ScriptedAmigaEmulator/#amiga_examples/slideshow.adf" target="_blank">Run in SAE</a>

View File

@ -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

13
023.slideshow/constants.i Normal file
View File

@ -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

7
023.slideshow/includes.i Normal file
View File

@ -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"

46
023.slideshow/init.s Normal file
View File

@ -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

26
023.slideshow/link.script Normal file
View File

@ -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
}

307
023.slideshow/slideshow.s Normal file
View File

@ -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:

221
023.slideshow/trackloader.s Normal file
View File

@ -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

26
023.slideshow/utils.s Normal file
View File

@ -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