This commit is contained in:
Chris Hodges 2023-05-22 16:17:35 +02:00
parent c3cdc41948
commit 51277c8049
238 changed files with 61285 additions and 2 deletions

View File

@ -1,2 +1,50 @@
# Hamazing
Sourcecode of Hamazing and PLatOS demoframework
# Hamazing by Desire
This is the source code of Hamazing and PLatOS demo framework.
It's supposed to build on a Windows machine (sorry).
Some of the stuff was originally part of
[Axis' Planet Rocklobster framework](https://github.com/AxisOxy/Planet-Rocklobster)
and that may show in structure and some of the tools used.
## Building
Go into the `source/hamazing` directory and type `build.bat`.
Each part can be run as a standalone executable for testing by entering
the part's source directory and running `assemble.bat`.
Note that you need to supply Kickstart roms for WinUAE in the
`source/winuae/Roms` directory. AROS rom replacement _may_ work, but
your milage may vary. It doesn't run the trackmo for unknown reasons.
## Third party stuff
This software uses or provides binaries of
- LightSpeedPlayer, LSPConvert - https://github.com/arnaud-carre/LSPlayer
- Raspberry Casket Pretracker Replayer - https://github.com/chrisly42/PretrackerRaspberryCasket
- KingCon
- DevIl - http://openil.sourceforge.net
- WinUAE - http://www.winuae.net
- VASM - http://sun.hasenbraten.de/vasm
- Shrinkler - https://github.com/askeksa/Shrinkler
- LZ4 - https://github.com/lz4/lz4
- ZX0 - https://github.com/einar-saukas/ZX0
- Salvador - https://github.com/emmanuel-marty/salvador
- Doynamite68k
## Make your own demos!
You can use the framework to make your own demos or intros.
There is documentation inside the source code.
Right now, I'm not quite motivated to write more than necessary.
You can look at the effects to see how things are done.
But only lamers will copy code verbatim.
Give credits where credits are due.
And now go and have some fun. Use the Blitter, Luke! Make Amiga Great Again!
Signing off, Chris 'platon42' Hodges

30
source/blend/aga.bat Normal file
View File

@ -0,0 +1,30 @@
del blend.exe
del "..\winuae\hd0\blend.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -O2 -notmpfile -nostdlib -o "blend.exe" "blend.asm"
@if %ERRORLEVEL% NEQ 0 goto failed
copy blend.exe "..\winuae\hd0"
copy blend.exe "..\winuae\hd0\a"
@echo /|set /p =blend.exe>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a1200_hrt.uae" -log -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg
@goto ok
rem ############ ERROR HANDLER ############
:failed
@echo error in directory "%CD%"
@echo !!!!!!!!! oh no !!!!!!!!!!!!
@pause
del vc.cfg
:ok

43
source/blend/assemble.bat Normal file
View File

@ -0,0 +1,43 @@
del blend.exe
del "..\winuae\hd0\blend.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
pushd ..
tools\KingCon.exe @data/blend/assets.txt
@if %ERRORLEVEL% NEQ 0 goto failed
tools\juggler data/blend/juggle.txt
@if %ERRORLEVEL% NEQ 0 goto failed
tools\LSPConvert.exe data\music\dsr_68k_tune_2_v11.mod -setpos -v
@if %ERRORLEVEL% NEQ 0 goto failed
popd
vc -O2 -notmpfile -nostdlib -o "blend.exe" "blend.asm"
@if %ERRORLEVEL% NEQ 0 goto failed
copy blend.exe "..\winuae\hd0"
copy blend.exe "..\winuae\hd0\a"
@echo /|set /p =blend.exe>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a500_hrt_more_mem.uae" -log -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg
@goto ok
rem ############ ERROR HANDLER ############
:failed
@echo error in directory "%CD%"
@echo !!!!!!!!! oh no !!!!!!!!!!!!
@pause
del vc.cfg
:ok

5749
source/blend/blend.asm Normal file

File diff suppressed because it is too large Load Diff

480
source/blend/circleinfo.asm Normal file
View File

@ -0,0 +1,480 @@
; Radius 3
dc.w 87
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 4
dc.w 86
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 5
dc.w 85
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 6
dc.w 84
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 7
dc.w 83
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 8
dc.w 82
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 9
dc.w 81
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 10
dc.w 80
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 11
dc.w 79
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 12
dc.w 78
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 13
dc.w 77
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 14
dc.w 76
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 15
dc.w 75
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 2,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 16
dc.w 74
dc.w 0,0,0 ; no top
dc.w 0,0 ; no left
dc.w 3,18
dc.w 0,0,0 ; no inner
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 17
dc.w 83
dc.w 2,10,18
dc.w 1,16
dc.w 1,22
dc.w $1683,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 18
dc.w 81
dc.w 2,9,18
dc.w 1,16
dc.w 1,22
dc.w $1c83,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 19
dc.w 79
dc.w 2,8,18
dc.w 1,16
dc.w 1,22
dc.w $2283,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 20
dc.w 78
dc.w 2,8,18
dc.w 1,16
dc.w 1,22
dc.w $2583,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 21
dc.w 76
dc.w 2,7,18
dc.w 1,16
dc.w 1,22
dc.w $2b83,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 22
dc.w 75
dc.w 2,7,18
dc.w 1,16
dc.w 1,22
dc.w $2e83,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 23
dc.w 73
dc.w 2,6,18
dc.w 1,16
dc.w 1,22
dc.w $3483,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 24
dc.w 72
dc.w 2,6,18
dc.w 1,16
dc.w 1,22
dc.w $3783,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 25
dc.w 71
dc.w 2,6,18
dc.w 1,16
dc.w 1,22
dc.w $3a83,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 26
dc.w 69
dc.w 2,5,18
dc.w 1,16
dc.w 1,22
dc.w $4083,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 27
dc.w 68
dc.w 2,5,18
dc.w 1,16
dc.w 1,22
dc.w $4383,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 28
dc.w 67
dc.w 2,5,18
dc.w 1,16
dc.w 1,22
dc.w $4683,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 29
dc.w 66
dc.w 2,5,18
dc.w 1,16
dc.w 1,22
dc.w $4983,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 30
dc.w 64
dc.w 2,4,18
dc.w 1,16
dc.w 1,22
dc.w $4f83,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 31
dc.w 63
dc.w 2,4,18
dc.w 1,16
dc.w 1,22
dc.w $5283,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 32
dc.w 82
dc.w 4,24,16
dc.w 1,16
dc.w 2,22
dc.w $1983,$0012,$0022
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 33
dc.w 80
dc.w 4,23,16
dc.w 1,14
dc.w 1,24
dc.w $1f85,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 34
dc.w 77
dc.w 4,21,16
dc.w 1,14
dc.w 1,24
dc.w $2885,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 35
dc.w 75
dc.w 4,20,16
dc.w 1,14
dc.w 1,24
dc.w $2e85,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 36
dc.w 73
dc.w 4,19,16
dc.w 1,14
dc.w 1,24
dc.w $3485,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 37
dc.w 71
dc.w 4,18,16
dc.w 1,14
dc.w 1,24
dc.w $3a85,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 38
dc.w 69
dc.w 4,17,16
dc.w 1,14
dc.w 1,24
dc.w $4085,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 39
dc.w 67
dc.w 4,16,16
dc.w 1,14
dc.w 1,24
dc.w $4685,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 40
dc.w 66
dc.w 4,16,16
dc.w 1,14
dc.w 1,24
dc.w $4985,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 41
dc.w 64
dc.w 4,15,16
dc.w 1,14
dc.w 1,24
dc.w $4f85,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 42
dc.w 63
dc.w 4,15,16
dc.w 1,14
dc.w 1,24
dc.w $5285,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 43
dc.w 61
dc.w 4,14,16
dc.w 1,14
dc.w 1,24
dc.w $5885,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 44
dc.w 60
dc.w 4,14,16
dc.w 1,14
dc.w 1,24
dc.w $5b85,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 45
dc.w 58
dc.w 4,13,16
dc.w 1,14
dc.w 1,24
dc.w $6185,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 46
dc.w 57
dc.w 4,13,16
dc.w 1,14
dc.w 1,24
dc.w $6485,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 47
dc.w 55
dc.w 4,12,16
dc.w 1,14
dc.w 1,24
dc.w $6a85,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 48
dc.w 54
dc.w 4,12,16
dc.w 1,14
dc.w 2,24
dc.w $6d85,$0010,$001e
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 49
dc.w 77
dc.w 6,36,14
dc.w 1,12
dc.w 1,26
dc.w $2887,$000e,$001a
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc
; Radius 50
dc.w 74
dc.w 6,34,14
dc.w 1,12
dc.w 1,26
dc.w $3187,$000e,$001a
dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0
dc.l 0,0,0 ; mask ptrs
dc.l 0,0,0,0,0,0 ; smc

View File

@ -0,0 +1,22 @@
dc.b 3,3,3,4,6,7,9,10,12,14,15,16,17,18,19,20
dc.b 21,22,22,22,22,22,22,22,22,22,22,22,22,21,21,20
dc.b 20,19,18,17,17,16,15,14,13,13,12,11,11,10,9,8
dc.b 8,8,7,6,6,6,6,5,6,6,6,6,6,6,6,6
dc.b 7,8,8,8,9,10,10,10,11,12,12,12,13,14,14,14
dc.b 15,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23
dc.b 24,25,25,25,26,27,27,27,28,28,29,29,30,30,30,30
dc.b 31,31,31,31,32,32,32,32,33,33,33,33,34,34,34,34
dc.b 34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34
dc.b 34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,35
dc.b 36,36,36,36,37,37,37,37,38,38,38,38,39,39,40,40
dc.b 41,41,41,42,43,43,43,44,45,45,45,46,47,47,48,48
dc.b 48,48,49,49,49,49,49,50,50,50,50,50,50,50,50,50
dc.b 50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50
dc.b 50,49,49,49,49,48,48,48,48,47,47,47,47,46,46,46
dc.b 46,45,45,45,45,45,44,44,44,44,44,44,44,44,44,44
dc.b 44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44
dc.b 45,45,45,45,46,46,46,46,47,47,47,47,48,48,48,48
dc.b 49,49,49,49,50,50,50,50,50,50,50,50,50,50,50,50
dc.l 0

View File

@ -0,0 +1,19 @@
dc.b 3,3,3,3,3,4,6,7,8,9,10,11,12,13,14,15
dc.b 15,16,17,17,18,18,19,19,20,20,20,20,20,20,20,20
dc.b 19,19,19,19,19,18,18,17,17,17,16,16,16,15,15,15
dc.b 15,15,15,15,15,15,15,14,14,14,14,14,14,14,14,14
dc.b 15,15,15,15,15,16,16,16,16,17,17,17,17,17,17,18
dc.b 18,18,18,18,18,18,18,18,18,18,18,18,18,17,17,17
dc.b 17,17,16,16,15,14,15,15,15,14,13,12,13,13,13,13
dc.b 13,12,13,13,13,13,13,13,14,15,15,15,15,15,16,17
dc.b 17,17,18,18,19,20,20,21,21,22,23,24,24,24,25,25
dc.b 26,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28
dc.b 28,28,28,28,27,27,27,26,26,25,25,24,24,23,23,23
dc.b 22,22,21,21,21,20,20,20,20,20,20,20,20,20,20,20
dc.b 20,20,20,20,20,20,21,21,21,22,22,23,23,24,24,25
dc.b 25,25,26,26,27,27,27,28,28,28,28,28,28,28,28,28
dc.b 28,28,28,28,28,28,28,28,27,27,27,26,26,25,25,24
dc.b 24,24,23,23,22,22,21,21,21,21,20,20,20,20,20,20
dc.l 0

View File

@ -0,0 +1,9 @@
dc.b 3,4,5,6,7,8,8,9,9,9,10,10,10,11,11,11
dc.b 12,12,12,13,13,13,14,14,14,14,15,15,15,15,16,16
dc.b 18,18,18,18,17,17,17,16,16,16,15,15,15,14,14,14
dc.b 14,14,14,13,13,13,13,13,13,13,13,12,12,12,12,12
dc.b 12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15
dc.b 15,15,16,16,16,16,16,17,17,17,17,17,18,18,18,18
dc.l 0

9
source/blend/compile.bat Normal file
View File

@ -0,0 +1,9 @@
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -O2 -notmpfile -nostdlib -o "blend.exe" "blend.asm"

21
source/blend/debug.bat Normal file
View File

@ -0,0 +1,21 @@
del blend.exe
del "..\winuae\hd0\blend.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -g -hunkdebug -O2 -notmpfile -nostdlib -o "blend.exe" "blend.asm"
copy blend.exe "..\winuae\hd0"
copy blend.exe "..\winuae\hd0\a"
copy "..\winuae\hd0\s\debug-sequence" "..\winuae\hd0\s\startup-sequence"
@echo /|set /p =blend.exe >>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a500_debug.uae" -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg

30
source/blend/record.bat Normal file
View File

@ -0,0 +1,30 @@
del blend.exe
del "..\winuae\hd0\blend.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -O2 -notmpfile -nostdlib -o "blend.exe" "blend.asm"
@if %ERRORLEVEL% NEQ 0 goto failed
copy blend.exe "..\winuae\hd0"
copy blend.exe "..\winuae\hd0\a.exe"
@echo /|set /p =blend.exe>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a500_rec.uae" -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg
@goto ok
rem ############ ERROR HANDLER ############
:failed
@echo error in directory "%CD%"
@echo !!!!!!!!! oh no !!!!!!!!!!!!
@pause
del vc.cfg
:ok

30
source/bulb/aga.bat Normal file
View File

@ -0,0 +1,30 @@
del bulb.exe
del "..\winuae\hd0\bulb.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -O2 -notmpfile -nostdlib -o "bulb.exe" "bulb.asm"
@if %ERRORLEVEL% NEQ 0 goto failed
copy bulb.exe "..\winuae\hd0"
copy bulb.exe "..\winuae\hd0\a"
@echo /|set /p =bulb.exe>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a1200_hrt.uae" -log -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg
@goto ok
rem ############ ERROR HANDLER ############
:failed
@echo error in directory "%CD%"
@echo !!!!!!!!! oh no !!!!!!!!!!!!
@pause
del vc.cfg
:ok

40
source/bulb/assemble.bat Normal file
View File

@ -0,0 +1,40 @@
del bulb.exe
del "..\winuae\hd0\bulb.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
pushd ..
tools\KingCon.exe @data/bulb/assets.txt
@if %ERRORLEVEL% NEQ 0 goto failed
tools\ZCP data/bulb/lamp_48x32x16.BPL data/bulb/lamp_48x32x16.zcp 48 32 -c data/bulb/lamp_48x32x16.chk
@if %ERRORLEVEL% NEQ 0 goto failed
popd
vc -O2 -notmpfile -nostdlib -o "bulb.exe" "bulb.asm"
@if %ERRORLEVEL% NEQ 0 goto failed
copy bulb.exe "..\winuae\hd0"
copy bulb.exe "..\winuae\hd0\a"
@echo /|set /p =bulb.exe>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a500_hrt.uae" -log -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg
@goto ok
rem ############ ERROR HANDLER ############
:failed
@echo error in directory "%CD%"
@echo !!!!!!!!! oh no !!!!!!!!!!!!
@pause
del vc.cfg
:ok

View File

@ -0,0 +1,132 @@
;----------------------------------------------------------------------------------
; Draw regular blitter line
;
; The routine will exit with the blitter active
;
; in d0.w x0
; d1.w y0
; d2.w x1
; d3.w y1
; d4.w bytes per row in bitplane
; a0 bitplane
; a5 $dff000
; a0/d0-d5 trashed
blb_blitter_line_init_bq:
ADD_TO_BLITTER_QUEUE a4,a0
clr.l (a4)+
lea .bq_init(pc),a0
move.l a0,(a4)+
move.w d4,(a4)+
rts
.bq_init
PUTMSG 50,<"Line Init">
moveq.l #-1,d0
move.w #BLTCON1F_LINE,bltcon1(a5)
move.w #$8000,bltadat(a5)
move.l d0,bltafwm(a5)
move.w d0,bltbdat(a5)
move.w (a0)+,bltcmod(a5)
BLTHOGON
moveq.l #0,d0
rts
;----------------------------------------------------------------------------------
; Draw regular blitter line to blitter queue
;
; in d0.w x0
; d1.w y0
; d2.w x1
; d3.w y1
; d4.w bytes per row in bitplane
; a0 bitplane
; a4 blitterqueue struct
blb_draw_blitter_line_bq:
cmp.w d1,d3
bge.s .downward
exg d0,d2
exg d1,d3
.downward
mulu d1,d4
lea (a0,d4.w),a1
moveq.l #-16,d4
and.w d0,d4
lsr.w #3,d4
adda.w d4,a1
moveq.l #15,d4
and.w d0,d4
ror.w #4,d4
or.w d5,d4
or.w #BLTCON0F_USEA|BLTCON0F_USEC|BLTCON0F_USED,d4
swap d4
sub.w d0,d2
bpl.s .positiveDX
neg.w d2
addq.w #1,d4
.positiveDX
sub.w d1,d3
cmp.w d2,d3
bls.s .absDyLessThanAbsDx
exg d2,d3
addq.w #4,d4
.absDyLessThanAbsDx
move.b .octants(pc,d4.w),d4
add.w d3,d3 ; 2 * dy
move.w d3,d5
sub.w d2,d5 ; 2 * dy - dx
bpl.s .positiveGradient
or.w #BLTCON1F_SIGN,d4
.positiveGradient
add.w d5,d5 ; 4 * dy - 2 * dx
add.w d2,d2 ; 2 * dx
add.w d2,d2 ; 4 * dx
add.w d3,d3 ; 4 * dy
move.w d3,d0
sub.w d2,d3 ; 4 * (dy - dx)
addq.w #4,d2 ; extra word height
lsl.w #4,d2
addq.w #2,d2 ; width == 2
moveq.l #0,d1
move.l a4,a0
move.l d1,(a4)+
move.l #.bq_routine,(a4)+
move.l d4,(a4)+ ; bql_BltCon01
move.l a1,(a4)+ ; bql_BltCPt
move.w d0,(a4)+ ; bql_BltBMod, 4 * dy
move.w d3,(a4)+ ; bql_BltAMod, 4 * (dy - dx)
move.w d5,(a4)+ ; bql_BltAPtLo, 4 * dy - 2 * dx
;move.l #blitter_temp_output_word,(a4)+ ; bql_BltDPt
move.l a1,(a4)+ ; bql_BltDPt
move.w d2,(a4)+ ; bql_BltSize
CALLFW AddToBlitterQueue
rts
.octants
dc.b BLTCON1F_LINE|BLTCON1F_SUD ; octant 7
dc.b BLTCON1F_LINE|BLTCON1F_SUD|BLTCON1F_AUL ; octant 4
dc.b BLTCON1F_LINE|BLTCON1F_SUD|BLTCON1F_SUL ; octant 0
dc.b BLTCON1F_LINE|BLTCON1F_SUD|BLTCON1F_SUL|BLTCON1F_AUL ; octant 3
dc.b BLTCON1F_LINE|0 ; octant 6
dc.b BLTCON1F_LINE|BLTCON1F_SUL ; octant 5
dc.b BLTCON1F_LINE|BLTCON1F_AUL ; octant 1
dc.b BLTCON1F_LINE|BLTCON1F_SUL|BLTCON1F_AUL ; octant 2
even
.bq_routine
PUTMSG 50,<"LineDraw %p">,a0
move.l (a0)+,bltcon0(a5)
move.l (a0)+,bltcpt(a5)
move.l (a0)+,bltbmod(a5)
move.l (a0)+,bltapt+2(a5)
move.l (a0)+,bltdpt+2(a5)
rts

3620
source/bulb/bulb.asm Normal file

File diff suppressed because it is too large Load Diff

9
source/bulb/compile.bat Normal file
View File

@ -0,0 +1,9 @@
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -O2 -notmpfile -nostdlib -o "bulb.exe" "bulb.asm"

21
source/bulb/debug.bat Normal file
View File

@ -0,0 +1,21 @@
del bulb.exe
del "..\winuae\hd0\bulb.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -g -hunkdebug -O2 -notmpfile -nostdlib -o "bulb.exe" "bulb.asm"
copy bulb.exe "..\winuae\hd0"
copy bulb.exe "..\winuae\hd0\a"
copy "..\winuae\hd0\s\debug-sequence" "..\winuae\hd0\s\startup-sequence"
@echo /|set /p =bulb.exe >>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a500_debug.uae" -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg

View File

@ -0,0 +1,129 @@
; Lamp positions
dc.b $cd,$05,$cd,$05,$cd,$05,$cd,$05
dc.b $cd,$05,$cd,$05,$cd,$05,$cd,$05
dc.b $cd,$05,$cd,$05,$cd,$05,$cd,$05
dc.b $cd,$05,$cd,$05,$cd,$05,$cd,$05
dc.b $cc,$05,$cc,$05,$cc,$05,$cc,$05
dc.b $cc,$05,$cc,$05,$cc,$05,$cc,$06
dc.b $cb,$06,$cb,$06,$cb,$06,$cb,$06
dc.b $cb,$06,$cb,$06,$ca,$06,$ca,$06
dc.b $ca,$06,$ca,$06,$ca,$06,$c9,$07
dc.b $c9,$07,$c9,$07,$c9,$07,$c9,$07
dc.b $c8,$07,$c8,$07,$c8,$07,$c8,$07
dc.b $c7,$08,$c7,$08,$c7,$08,$c6,$08
dc.b $c6,$08,$c6,$08,$c6,$08,$c5,$09
dc.b $c5,$09,$c5,$09,$c4,$09,$c4,$09
dc.b $c4,$09,$c3,$09,$c3,$09,$c3,$0a
dc.b $c2,$0a,$c2,$0a,$c1,$0a,$c1,$0a
dc.b $c1,$0a,$c0,$0a,$c0,$0b,$bf,$0b
dc.b $bf,$0b,$bf,$0b,$be,$0b,$be,$0b
dc.b $bd,$0b,$bd,$0c,$bd,$0c,$bc,$0c
dc.b $bc,$0c,$bb,$0c,$bb,$0c,$ba,$0c
dc.b $ba,$0c,$b9,$0d,$b9,$0d,$b8,$0d
dc.b $b8,$0d,$b7,$0d,$b7,$0d,$b7,$0d
dc.b $b6,$0d,$b6,$0e,$b5,$0e,$b5,$0e
dc.b $b4,$0e,$b3,$0e,$b3,$0e,$b2,$0e
dc.b $b2,$0e,$b1,$0e,$b1,$0f,$b0,$0f
dc.b $b0,$0f,$af,$0f,$af,$0f,$ae,$0f
dc.b $ae,$0f,$ad,$0f,$ad,$0f,$ac,$0f
dc.b $ab,$0f,$ab,$0f,$aa,$0f,$aa,$10
dc.b $a9,$10,$a9,$10,$a8,$10,$a7,$10
dc.b $a7,$10,$a6,$10,$a6,$10,$a5,$10
dc.b $a5,$10,$a4,$10,$a3,$10,$a3,$10
dc.b $a2,$10,$a2,$10,$a1,$10,$a1,$10
dc.b $a0,$10,$9f,$10,$9f,$10,$9e,$10
dc.b $9e,$10,$9d,$10,$9d,$10,$9c,$10
dc.b $9b,$10,$9b,$10,$9a,$10,$9a,$10
dc.b $99,$10,$99,$10,$98,$10,$97,$10
dc.b $97,$10,$96,$10,$96,$0f,$95,$0f
dc.b $95,$0f,$94,$0f,$93,$0f,$93,$0f
dc.b $92,$0f,$92,$0f,$91,$0f,$91,$0f
dc.b $90,$0f,$90,$0f,$8f,$0f,$8f,$0e
dc.b $8e,$0e,$8e,$0e,$8d,$0e,$8d,$0e
dc.b $8c,$0e,$8b,$0e,$8b,$0e,$8a,$0e
dc.b $8a,$0d,$89,$0d,$89,$0d,$89,$0d
dc.b $88,$0d,$88,$0d,$87,$0d,$87,$0d
dc.b $86,$0c,$86,$0c,$85,$0c,$85,$0c
dc.b $84,$0c,$84,$0c,$83,$0c,$83,$0c
dc.b $83,$0b,$82,$0b,$82,$0b,$81,$0b
dc.b $81,$0b,$81,$0b,$80,$0b,$80,$0a
dc.b $7f,$0a,$7f,$0a,$7f,$0a,$7e,$0a
dc.b $7e,$0a,$7d,$0a,$7d,$09,$7d,$09
dc.b $7c,$09,$7c,$09,$7c,$09,$7b,$09
dc.b $7b,$09,$7b,$09,$7a,$08,$7a,$08
dc.b $7a,$08,$7a,$08,$79,$08,$79,$08
dc.b $79,$08,$78,$07,$78,$07,$78,$07
dc.b $78,$07,$77,$07,$77,$07,$77,$07
dc.b $77,$07,$77,$07,$76,$06,$76,$06
dc.b $76,$06,$76,$06,$76,$06,$75,$06
dc.b $75,$06,$75,$06,$75,$06,$75,$06
dc.b $75,$06,$74,$06,$74,$05,$74,$05
dc.b $74,$05,$74,$05,$74,$05,$74,$05
dc.b $74,$05,$73,$05,$73,$05,$73,$05
dc.b $73,$05,$73,$05,$73,$05,$73,$05
dc.b $73,$05,$73,$05,$73,$05,$73,$05
dc.b $73,$05,$73,$05,$73,$05,$73,$05
dc.b $73,$05,$73,$05,$73,$05,$73,$05
dc.b $73,$05,$73,$05,$73,$05,$73,$05
dc.b $73,$05,$73,$05,$73,$05,$73,$05
dc.b $73,$05,$73,$05,$73,$05,$73,$05
dc.b $74,$05,$74,$05,$74,$05,$74,$05
dc.b $74,$05,$74,$05,$74,$05,$74,$06
dc.b $75,$06,$75,$06,$75,$06,$75,$06
dc.b $75,$06,$75,$06,$76,$06,$76,$06
dc.b $76,$06,$76,$06,$76,$06,$77,$07
dc.b $77,$07,$77,$07,$77,$07,$77,$07
dc.b $78,$07,$78,$07,$78,$07,$78,$07
dc.b $79,$08,$79,$08,$79,$08,$7a,$08
dc.b $7a,$08,$7a,$08,$7a,$08,$7b,$09
dc.b $7b,$09,$7b,$09,$7c,$09,$7c,$09
dc.b $7c,$09,$7d,$09,$7d,$09,$7d,$0a
dc.b $7e,$0a,$7e,$0a,$7f,$0a,$7f,$0a
dc.b $7f,$0a,$80,$0a,$80,$0b,$81,$0b
dc.b $81,$0b,$81,$0b,$82,$0b,$82,$0b
dc.b $83,$0b,$83,$0c,$83,$0c,$84,$0c
dc.b $84,$0c,$85,$0c,$85,$0c,$86,$0c
dc.b $86,$0c,$87,$0d,$87,$0d,$88,$0d
dc.b $88,$0d,$89,$0d,$89,$0d,$89,$0d
dc.b $8a,$0d,$8a,$0e,$8b,$0e,$8b,$0e
dc.b $8c,$0e,$8d,$0e,$8d,$0e,$8e,$0e
dc.b $8e,$0e,$8f,$0e,$8f,$0f,$90,$0f
dc.b $90,$0f,$91,$0f,$91,$0f,$92,$0f
dc.b $92,$0f,$93,$0f,$93,$0f,$94,$0f
dc.b $95,$0f,$95,$0f,$96,$0f,$96,$10
dc.b $97,$10,$97,$10,$98,$10,$99,$10
dc.b $99,$10,$9a,$10,$9a,$10,$9b,$10
dc.b $9b,$10,$9c,$10,$9d,$10,$9d,$10
dc.b $9e,$10,$9e,$10,$9f,$10,$9f,$10
dc.b $a0,$10,$a1,$10,$a1,$10,$a2,$10
dc.b $a2,$10,$a3,$10,$a3,$10,$a4,$10
dc.b $a5,$10,$a5,$10,$a6,$10,$a6,$10
dc.b $a7,$10,$a7,$10,$a8,$10,$a9,$10
dc.b $a9,$10,$aa,$10,$aa,$0f,$ab,$0f
dc.b $ab,$0f,$ac,$0f,$ad,$0f,$ad,$0f
dc.b $ae,$0f,$ae,$0f,$af,$0f,$af,$0f
dc.b $b0,$0f,$b0,$0f,$b1,$0f,$b1,$0e
dc.b $b2,$0e,$b2,$0e,$b3,$0e,$b3,$0e
dc.b $b4,$0e,$b5,$0e,$b5,$0e,$b6,$0e
dc.b $b6,$0d,$b7,$0d,$b7,$0d,$b7,$0d
dc.b $b8,$0d,$b8,$0d,$b9,$0d,$b9,$0d
dc.b $ba,$0c,$ba,$0c,$bb,$0c,$bb,$0c
dc.b $bc,$0c,$bc,$0c,$bd,$0c,$bd,$0c
dc.b $bd,$0b,$be,$0b,$be,$0b,$bf,$0b
dc.b $bf,$0b,$bf,$0b,$c0,$0b,$c0,$0a
dc.b $c1,$0a,$c1,$0a,$c1,$0a,$c2,$0a
dc.b $c2,$0a,$c3,$0a,$c3,$09,$c3,$09
dc.b $c4,$09,$c4,$09,$c4,$09,$c5,$09
dc.b $c5,$09,$c5,$09,$c6,$08,$c6,$08
dc.b $c6,$08,$c6,$08,$c7,$08,$c7,$08
dc.b $c7,$08,$c8,$07,$c8,$07,$c8,$07
dc.b $c8,$07,$c9,$07,$c9,$07,$c9,$07
dc.b $c9,$07,$c9,$07,$ca,$06,$ca,$06
dc.b $ca,$06,$ca,$06,$ca,$06,$cb,$06
dc.b $cb,$06,$cb,$06,$cb,$06,$cb,$06
dc.b $cb,$06,$cc,$06,$cc,$05,$cc,$05
dc.b $cc,$05,$cc,$05,$cc,$05,$cc,$05
dc.b $cc,$05,$cd,$05,$cd,$05,$cd,$05
dc.b $cd,$05,$cd,$05,$cd,$05,$cd,$05
dc.b $cd,$05,$cd,$05,$cd,$05,$cd,$05
dc.b $cd,$05,$cd,$05,$cd,$05,$cd,$05

View File

@ -0,0 +1,65 @@
; Lamp angle table
dc.b $ec,$ec,$ec,$ec,$ec,$ec,$ec,$ec
dc.b $ec,$ec,$ec,$ec,$ec,$ec,$ec,$ec
dc.b $ec,$ec,$ec,$ed,$ed,$ed,$ed,$ed
dc.b $ed,$ed,$ed,$ed,$ed,$ed,$ed,$ed
dc.b $ee,$ee,$ee,$ee,$ee,$ee,$ee,$ee
dc.b $ee,$ee,$ef,$ef,$ef,$ef,$ef,$ef
dc.b $ef,$f0,$f0,$f0,$f0,$f0,$f0,$f0
dc.b $f1,$f1,$f1,$f1,$f1,$f1,$f2,$f2
dc.b $f2,$f2,$f2,$f2,$f3,$f3,$f3,$f3
dc.b $f3,$f4,$f4,$f4,$f4,$f4,$f4,$f5
dc.b $f5,$f5,$f5,$f6,$f6,$f6,$f6,$f6
dc.b $f7,$f7,$f7,$f7,$f7,$f8,$f8,$f8
dc.b $f8,$f9,$f9,$f9,$f9,$f9,$fa,$fa
dc.b $fa,$fa,$fb,$fb,$fb,$fb,$fc,$fc
dc.b $fc,$fc,$fd,$fd,$fd,$fd,$fe,$fe
dc.b $fe,$fe,$ff,$ff,$ff,$ff,$00,$00
dc.b $00,$00,$00,$01,$01,$01,$01,$02
dc.b $02,$02,$02,$03,$03,$03,$03,$04
dc.b $04,$04,$04,$05,$05,$05,$05,$06
dc.b $06,$06,$06,$07,$07,$07,$07,$07
dc.b $08,$08,$08,$08,$09,$09,$09,$09
dc.b $09,$0a,$0a,$0a,$0a,$0a,$0b,$0b
dc.b $0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c
dc.b $0d,$0d,$0d,$0d,$0d,$0e,$0e,$0e
dc.b $0e,$0e,$0e,$0f,$0f,$0f,$0f,$0f
dc.b $0f,$10,$10,$10,$10,$10,$10,$10
dc.b $11,$11,$11,$11,$11,$11,$11,$12
dc.b $12,$12,$12,$12,$12,$12,$12,$12
dc.b $12,$13,$13,$13,$13,$13,$13,$13
dc.b $13,$13,$13,$13,$13,$13,$14,$14
dc.b $14,$14,$14,$14,$14,$14,$14,$14
dc.b $14,$14,$14,$14,$14,$14,$14,$14
dc.b $14,$14,$14,$14,$14,$14,$14,$14
dc.b $14,$14,$14,$14,$14,$14,$14,$14
dc.b $14,$14,$14,$13,$13,$13,$13,$13
dc.b $13,$13,$13,$13,$13,$13,$13,$13
dc.b $12,$12,$12,$12,$12,$12,$12,$12
dc.b $12,$12,$11,$11,$11,$11,$11,$11
dc.b $11,$10,$10,$10,$10,$10,$10,$10
dc.b $0f,$0f,$0f,$0f,$0f,$0f,$0e,$0e
dc.b $0e,$0e,$0e,$0e,$0d,$0d,$0d,$0d
dc.b $0d,$0c,$0c,$0c,$0c,$0c,$0c,$0b
dc.b $0b,$0b,$0b,$0a,$0a,$0a,$0a,$0a
dc.b $09,$09,$09,$09,$09,$08,$08,$08
dc.b $08,$07,$07,$07,$07,$07,$06,$06
dc.b $06,$06,$05,$05,$05,$05,$04,$04
dc.b $04,$04,$03,$03,$03,$03,$02,$02
dc.b $02,$02,$01,$01,$01,$01,$00,$00
dc.b $00,$00,$00,$ff,$ff,$ff,$ff,$fe
dc.b $fe,$fe,$fe,$fd,$fd,$fd,$fd,$fc
dc.b $fc,$fc,$fc,$fb,$fb,$fb,$fb,$fa
dc.b $fa,$fa,$fa,$f9,$f9,$f9,$f9,$f9
dc.b $f8,$f8,$f8,$f8,$f7,$f7,$f7,$f7
dc.b $f7,$f6,$f6,$f6,$f6,$f6,$f5,$f5
dc.b $f5,$f5,$f4,$f4,$f4,$f4,$f4,$f4
dc.b $f3,$f3,$f3,$f3,$f3,$f2,$f2,$f2
dc.b $f2,$f2,$f2,$f1,$f1,$f1,$f1,$f1
dc.b $f1,$f0,$f0,$f0,$f0,$f0,$f0,$f0
dc.b $ef,$ef,$ef,$ef,$ef,$ef,$ef,$ee
dc.b $ee,$ee,$ee,$ee,$ee,$ee,$ee,$ee
dc.b $ee,$ed,$ed,$ed,$ed,$ed,$ed,$ed
dc.b $ed,$ed,$ed,$ed,$ed,$ed,$ec,$ec
dc.b $ec,$ec,$ec,$ec,$ec,$ec,$ec,$ec
dc.b $ec,$ec,$ec,$ec,$ec,$ec,$ec,$ec

4729
source/bulb/paint2.asm Normal file

File diff suppressed because it is too large Load Diff

30
source/bulb/record.bat Normal file
View File

@ -0,0 +1,30 @@
del bulb.exe
del "..\winuae\hd0\bulb.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -O2 -notmpfile -nostdlib -o "bulb.exe" "bulb.asm"
@if %ERRORLEVEL% NEQ 0 goto failed
copy bulb.exe "..\winuae\hd0"
copy bulb.exe "..\winuae\hd0\a.exe"
@echo /|set /p =bulb.exe>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a500_rec.uae" -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg
@goto ok
rem ############ ERROR HANDLER ############
:failed
@echo error in directory "%CD%"
@echo !!!!!!!!! oh no !!!!!!!!!!!!
@pause
del vc.cfg
:ok

4
source/bulb/sintable.asm Normal file
View File

@ -0,0 +1,4 @@
; Sin table
dc.w $0000,$0648,$0c90,$12d5,$1918,$1f56,$2590,$2bc4
dc.w $31f1,$3817,$3e34,$4447,$4a50,$504d,$563e,$5c22
dc.w $61f8,$67be,$6d74,$731a,$78ad

2736
source/bulb/swing2.asm Normal file

File diff suppressed because it is too large Load Diff

4
source/bulb/tantable.asm Normal file
View File

@ -0,0 +1,4 @@
; Tan table
dc.w $0000,$0324,$0649,$096e,$0c94,$0fba,$12e2,$160c
dc.w $1937,$1c64,$1f93,$22c5,$25f9,$2931,$2c6c,$2faa
dc.w $32ec,$3632,$397d,$3ccc,$4020

897
source/bulb/textpaint.asm Normal file
View File

@ -0,0 +1,897 @@
; 0 (0 passes, 0 height)
dc.w 0
; 1 (0 passes, 0 height)
dc.w 0
; 2 (0 passes, 0 height)
dc.w 0
; 3 (0 passes, 0 height)
dc.w 0
; 4 (1 passes, 2 height)
dc.w $0081,$08dc,$000e,$001a,0
; 5 (1 passes, 4 height)
dc.w $0101,$08dc,$000e,$001a,0
; 6 (1 passes, 4 height)
dc.w $0201,$08dc,$0000,$0000,0
; 7 (1 passes, 4 height)
dc.w $0201,$08dc,$0000,$0000,0
; 8 (0 passes, 0 height)
dc.w 0
; 9 (0 passes, 0 height)
dc.w 0
; 10 (1 passes, 12 height)
dc.w $0301,$08dc,$000e,$001a,0
; 11 (1 passes, 14 height)
dc.w $0381,$08dc,$000e,$001a,0
; 12 (1 passes, 17 height)
dc.w $0441,$08dc,$000e,$001a,0
; 13 (1 passes, 21 height)
dc.w $0541,$08dc,$000e,$001a,0
; 14 (1 passes, 23 height)
dc.w $05c1,$08dc,$000e,$001a,0
; 15 (1 passes, 26 height)
dc.w $0681,$08dc,$000e,$001a,0
; 16 (1 passes, 30 height)
dc.w $0781,$08dc,$000e,$001a,0
; 17 (1 passes, 30 height)
dc.w $0f01,$08dc,$0000,$0000,0
; 18 (1 passes, 30 height)
dc.w $0f01,$08dc,$0000,$0000,0
; 19 (1 passes, 44 height)
dc.w $0b01,$08dc,$000e,$001a,0
; 20 (1 passes, 52 height)
dc.w $0d01,$08dc,$000e,$001a,0
; 21 (1 passes, 55 height)
dc.w $0dc1,$08dc,$000e,$001a,0
; 22 (1 passes, 64 height)
dc.w $1001,$08dc,$000e,$001a,0
; 23 (1 passes, 73 height)
dc.w $1241,$08dc,$000e,$001a,0
; 24 (1 passes, 78 height)
dc.w $1381,$08dc,$000e,$001a,0
; 25 (1 passes, 80 height)
dc.w $1401,$08dc,$000e,$001a,0
; 26 (3 passes, 91 height)
dc.w $02c1,$0798,$000c,$0018
dc.w $0581,$08dc,$000e,$0000
dc.w $1141,$0908,$016e,$0dda,0
; 27 (3 passes, 97 height)
dc.w $0441,$0798,$000c,$0018
dc.w $0881,$08dc,$000e,$0000
dc.w $0fc1,$0920,$022e,$155a,0
; 28 (3 passes, 93 height)
dc.w $0681,$0908,$016e,$0000
dc.w $0601,$0798,$000c,$0018,$0e01,$093c,$030e,$1e1a,0
; 29 (3 passes, 98 height)
dc.w $0901,$0920,$022e,$0000
dc.w $08c1,$0798,$000c,$0018,$0b41,$0968,$046e,$2bda,0
; 30 (3 passes, 108 height)
dc.w $0e01,$093c,$030e,$0000
dc.w $0701,$09ac,$068e,$411a,$0d01,$0798,$000c,$0018,0
; 31 (3 passes, 110 height)
dc.w $03c1,$09e0,$082e,$515a
dc.w $0f01,$0968,$046e,$0000
dc.w $1041,$0798,$000c,$0018,0
; 32 (3 passes, 107 height)
dc.w $0041,$0a18,$09ee,$62da
dc.w $0d81,$09ac,$068e,$0000
dc.w $13c1,$0798,$000c,$0018,0
; 33 (2 passes, 95 height)
dc.w $0781,$09e0,$082e,$0000
dc.w $1401,$0798,$000c,$0018,0
; 34 (2 passes, 81 height)
dc.w $0081,$0a18,$09ee,$0000
dc.w $1401,$0798,$000c,$0018,0
; 35 (1 passes, 80 height)
dc.w $1401,$0798,$000c,$0018,0
; 36 (1 passes, 80 height)
dc.w $1401,$0798,$000c,$0018,0
; 37 (3 passes, 102 height)
dc.w $0581,$0654,$000a,$0016
dc.w $0b01,$0798,$000c,$0000
dc.w $0e81,$07f0,$02cc,$1b98,0
; 38 (3 passes, 102 height)
dc.w $0b01,$0654,$0000,$0000,$0b01,$0798,$0000,$0000,$1d01,$07f0,$0000,$0000,0
; 39 (2 passes, 80 height)
dc.w $0b01,$0654,$0000,$0000,$1d01,$07f0,$0000,$0000,0
; 40 (0 passes, 0 height)
dc.w 0
; 41 (0 passes, 0 height)
dc.w 0
; 42 (0 passes, 0 height)
dc.w 0
; 43 (2 passes, 138 height)
dc.w $1d01,$07f0,$02cc,$0000
dc.w $1401,$0654,$000a,$0016,0
; 44 (2 passes, 138 height)
dc.w $1d01,$07f0,$02cc,$0000
dc.w $1401,$0654,$000a,$0016,0
; 45 (2 passes, 160 height)
dc.w $1401,$0510,$0008,$0014
dc.w $2801,$0654,$000a,$0000,0
; 46 (2 passes, 160 height)
dc.w $1401,$0510,$0008,$0014
dc.w $2801,$0654,$000a,$0000,0
; 47 (1 passes, 80 height)
dc.w $1401,$0510,$0008,$0014,0
; 48 (1 passes, 80 height)
dc.w $1401,$0510,$0008,$0014,0
; 49 (1 passes, 80 height)
dc.w $1401,$0510,$0008,$0014,0
; 50 (1 passes, 80 height)
dc.w $1401,$0510,$0008,$0014,0
; 51 (3 passes, 99 height)
dc.w $04c1,$04c0,$07a6,$4c52
dc.w $0981,$0604,$07a8,$0000
dc.w $0f41,$0510,$0008,$0014,0
; 52 (3 passes, 120 height)
dc.w $0a01,$046c,$0506,$3212,$0a01,$0510,$0008,$0014
dc.w $1401,$05b0,$0508,$0000,0
; 53 (3 passes, 125 height)
dc.w $0401,$0510,$0008,$0014
dc.w $1681,$0550,$0208,$0000
dc.w $1001,$040c,$0206,$1412,0
; 54 (2 passes, 120 height)
dc.w $1401,$0510,$0008,$0000
dc.w $1401,$03cc,$0006,$0012,0
; 55 (2 passes, 96 height)
dc.w $0801,$0510,$0008,$0000
dc.w $1401,$03cc,$0006,$0012,0
; 56 (1 passes, 80 height)
dc.w $1401,$03cc,$0006,$0012,0
; 57 (3 passes, 99 height)
dc.w $04c1,$037c,$07a4,$4c50
dc.w $0981,$04c0,$07a6,$0000
dc.w $0f41,$03cc,$0006,$0012,0
; 58 (3 passes, 115 height)
dc.w $08c1,$033c,$05a4,$3850
dc.w $1181,$0480,$05a6,$0000
dc.w $0b41,$03cc,$0006,$0012,0
; 59 (3 passes, 110 height)
dc.w $0f01,$0448,$03e6,$0000
dc.w $07c1,$03cc,$0006,$0012,$0c41,$0304,$03e4,$26d0,0
; 60 (3 passes, 111 height)
dc.w $0381,$03cc,$0006,$0012
dc.w $0f81,$0404,$01c6,$0000
dc.w $1081,$02c0,$01c4,$1190,0
; 61 (3 passes, 107 height)
dc.w $0101,$03cc,$0006,$0012
dc.w $0d81,$03dc,$0086,$0000
dc.w $1301,$0298,$0084,$0510,0
; 62 (4 passes, 104 height)
dc.w $0281,$025c,$08c2,$578e
dc.w $0501,$03a0,$08c4,$0000,$0701,$03cc,$0006,$0000
dc.w $1181,$0288,$0004,$0010,0
; 63 (4 passes, 106 height)
dc.w $0201,$03cc,$0006,$0000
dc.w $0581,$022c,$0742,$488e
dc.w $0b01,$0370,$0744,$0000
dc.w $0e81,$0288,$0004,$0010,0
; 64 (3 passes, 102 height)
dc.w $0b01,$0348,$0604,$0000
dc.w $0801,$0204,$0602,$3c0e,$0c01,$0288,$0004,$0010,0
; 65 (3 passes, 105 height)
dc.w $0c81,$030c,$0424,$0000
dc.w $0841,$0288,$0004,$0010,$0bc1,$01c8,$0422,$294e,0
; 66 (3 passes, 103 height)
dc.w $0b81,$02ec,$0324,$0000
dc.w $0641,$0288,$0004,$0010,$0dc1,$01a8,$0322,$1f4e,0
; 67 (5 passes, 101 height)
dc.w $0141,$012c,$0960,$5dcc
dc.w $0281,$0270,$0962,$0000,$0801,$02cc,$0224,$0000
dc.w $0441,$0288,$0004,$0010,$0e81,$0188,$0222,$154e,0
; 68 (5 passes, 110 height)
dc.w $0281,$0288,$0004,$0010,$03c1,$0104,$0820,$514c
dc.w $0781,$0248,$0822,$0000,$0781,$02b0,$0144,$0000
dc.w $0dc1,$016c,$0142,$0c8e,0
; 69 (4 passes, 119 height)
dc.w $0881,$0288,$0004,$0000,$0b01,$0218,$06a2,$0000
dc.w $06c1,$00d4,$06a0,$424c,$0d41,$0144,$0002,$000e,0
; 70 (4 passes, 110 height)
dc.w $0501,$0288,$0004,$0000,$0a01,$01f8,$05a2,$0000
dc.w $08c1,$00b4,$05a0,$384c,$0b41,$0144,$0002,$000e,0
; 71 (3 passes, 95 height)
dc.w $0781,$01dc,$04c2,$0000
dc.w $0981,$0144,$0002,$000e,$0a81,$0098,$04c0,$2f8c,0
; 72 (3 passes, 87 height)
dc.w $0381,$01dc,$0000,$0000,$1301,$0144,$0000,$0000,$1501,$0098,$0000,$0000,0
; 73 (2 passes, 80 height)
dc.w $1301,$0144,$0000,$0000,$1501,$0098,$0000,$0000,0
; 74 (0 passes, 0 height)
dc.w 0
; 75 (0 passes, 0 height)
dc.w 0
; 76 (0 passes, 0 height)
dc.w 0
; 77 (3 passes, 118 height)
dc.w $0941,$0000,$0000,$000c
dc.w $1301,$0144,$0002,$0000,$1581,$0094,$04a0,$0000,0
; 78 (3 passes, 118 height)
dc.w $07c1,$0000,$0000,$000c
dc.w $1301,$0144,$0002,$0000,$1881,$007c,$03e0,$0000,0
; 79 (2 passes, 37 height)
dc.w $0581,$0068,$0340,$0000
dc.w $0681,$0000,$0000,$000c,0
; 80 (2 passes, 31 height)
dc.w $0581,$0050,$0280,$0000
dc.w $0501,$0000,$0000,$000c,0
; 81 (2 passes, 26 height)
dc.w $0581,$003c,$01e0,$0000
dc.w $03c1,$0000,$0000,$000c,0
; 82 (2 passes, 20 height)
dc.w $0281,$0000,$0000,$000c
dc.w $0501,$0028,$0140,$0000,0
; 83 (2 passes, 15 height)
dc.w $0181,$0000,$0000,$000c
dc.w $0481,$0018,$00c0,$0000,0
; 84 (2 passes, 10 height)
dc.w $0081,$0000,$0000,$000c
dc.w $0401,$0008,$0040,$0000,0
; 85 (1 passes, 6 height)
dc.w $0301,$0000,$0000,$0000,0
; 86 (1 passes, 2 height)
dc.w $0101,$0000,$0000,$0000,0
; 87 (0 passes, 0 height)
dc.w 0
; 88 (0 passes, 0 height)
dc.w 0
; 89 (0 passes, 0 height)
dc.w 0
; 90 (0 passes, 0 height)
dc.w 0
; 91 (0 passes, 0 height)
dc.w 0
; 92 (0 passes, 0 height)
dc.w 0
; 93 (0 passes, 0 height)
dc.w 0
; 94 (0 passes, 0 height)
dc.w 0
; 95 (0 passes, 0 height)
dc.w 0
; 96 (0 passes, 0 height)
dc.w 0
; 97 (0 passes, 0 height)
dc.w 0
; 98 (0 passes, 0 height)
dc.w 0
; 99 (0 passes, 0 height)
dc.w 0
; 100 (0 passes, 0 height)
dc.w 0
; 101 (0 passes, 0 height)
dc.w 0
; 102 (0 passes, 0 height)
dc.w 0
; 103 (0 passes, 0 height)
dc.w 0
; 104 (0 passes, 0 height)
dc.w 0
; 105 (0 passes, 0 height)
dc.w 0
; 106 (0 passes, 0 height)
dc.w 0
; 107 (0 passes, 0 height)
dc.w 0
; 108 (0 passes, 0 height)
dc.w 0
; 109 (0 passes, 0 height)
dc.w 0
; 110 (0 passes, 0 height)
dc.w 0
; 111 (0 passes, 0 height)
dc.w 0
; 112 (0 passes, 0 height)
dc.w 0
; 113 (0 passes, 0 height)
dc.w 0
; 114 (0 passes, 0 height)
dc.w 0
; 115 (0 passes, 0 height)
dc.w 0
; 116 (0 passes, 0 height)
dc.w 0
; 117 (0 passes, 0 height)
dc.w 0
; 118 (0 passes, 0 height)
dc.w 0
; 119 (0 passes, 0 height)
dc.w 0
; 120 (0 passes, 0 height)
dc.w 0
; 121 (0 passes, 0 height)
dc.w 0
; 122 (0 passes, 0 height)
dc.w 0
; 123 (0 passes, 0 height)
dc.w 0
; 124 (0 passes, 0 height)
dc.w 0
; 125 (0 passes, 0 height)
dc.w 0
; 126 (0 passes, 0 height)
dc.w 0
; 127 (0 passes, 0 height)
dc.w 0
; 128 (0 passes, 0 height)
dc.w 0
; 129 (0 passes, 0 height)
dc.w 0
; 130 (0 passes, 0 height)
dc.w 0
; 131 (0 passes, 0 height)
dc.w 0
; 132 (1 passes, 4 height)
dc.w $0101,$0000,$0000,$000c,0
; 133 (1 passes, 4 height)
dc.w $0101,$0000,$0000,$000c,0
; 134 (1 passes, 4 height)
dc.w $0101,$0000,$0000,$000c,0
; 135 (1 passes, 6 height)
dc.w $0181,$0000,$0000,$000c,0
; 136 (1 passes, 6 height)
dc.w $0181,$0000,$0000,$000c,0
; 137 (1 passes, 8 height)
dc.w $0201,$0000,$0000,$000c,0
; 138 (1 passes, 12 height)
dc.w $0301,$0000,$0000,$000c,0
; 139 (1 passes, 14 height)
dc.w $0381,$0000,$0000,$000c,0
; 140 (1 passes, 17 height)
dc.w $0441,$0000,$0000,$000c,0
; 141 (1 passes, 21 height)
dc.w $0541,$0000,$0000,$000c,0
; 142 (1 passes, 23 height)
dc.w $05c1,$0000,$0000,$000c,0
; 143 (1 passes, 26 height)
dc.w $0681,$0000,$0000,$000c,0
; 144 (1 passes, 30 height)
dc.w $0781,$0000,$0000,$000c,0
; 145 (1 passes, 36 height)
dc.w $0901,$0000,$0000,$000c,0
; 146 (1 passes, 40 height)
dc.w $0a01,$0000,$0000,$000c,0
; 147 (1 passes, 44 height)
dc.w $0b01,$0000,$0000,$000c,0
; 148 (1 passes, 52 height)
dc.w $0d01,$0000,$0000,$000c,0
; 149 (1 passes, 55 height)
dc.w $0dc1,$0000,$0000,$000c,0
; 150 (1 passes, 69 height)
dc.w $1141,$0000,$0000,$000c,0
; 151 (1 passes, 73 height)
dc.w $1241,$0000,$0000,$000c,0
; 152 (1 passes, 80 height)
dc.w $1401,$0000,$0000,$000c,0
; 153 (1 passes, 80 height)
dc.w $1401,$0000,$0000,$000c,0
; 154 (3 passes, 91 height)
dc.w $0581,$0000,$0000,$0000
dc.w $02c1,$0144,$0002,$000e,$1141,$002c,$0160,$0dcc,0
; 155 (3 passes, 97 height)
dc.w $0881,$0000,$0000,$0000
dc.w $0441,$0144,$0002,$000e,$0fc1,$0044,$0220,$154c,0
; 156 (3 passes, 93 height)
dc.w $0681,$002c,$0160,$0000
dc.w $0601,$0144,$0002,$000e,$0e01,$0060,$0300,$1e0c,0
; 157 (3 passes, 103 height)
dc.w $0b81,$0044,$0220,$0000
dc.w $0a01,$00a0,$0500,$320c,$0a01,$0144,$0002,$000e,0
; 158 (3 passes, 108 height)
dc.w $0e01,$0060,$0300,$0000
dc.w $0701,$00d0,$0680,$410c,$0d01,$0144,$0002,$000e,0
; 159 (3 passes, 105 height)
dc.w $03c1,$0104,$0820,$514c
dc.w $0c81,$00a0,$0500,$0000
dc.w $1041,$0144,$0002,$000e,0
; 160 (3 passes, 107 height)
dc.w $0041,$013c,$09e0,$62cc
dc.w $0d81,$00d0,$0680,$0000
dc.w $13c1,$0144,$0002,$000e,0
; 161 (2 passes, 95 height)
dc.w $0781,$0104,$0820,$0000
dc.w $1401,$0144,$0002,$000e,0
; 162 (2 passes, 81 height)
dc.w $0081,$013c,$09e0,$0000
dc.w $1401,$0144,$0002,$000e,0
; 163 (1 passes, 80 height)
dc.w $1401,$0144,$0002,$000e,0
; 164 (1 passes, 80 height)
dc.w $1401,$0144,$0002,$000e,0
; 165 (3 passes, 102 height)
dc.w $0b01,$0144,$0002,$0000
dc.w $0581,$0288,$0004,$0010,$0e81,$019c,$02c2,$1b8e,0
; 166 (3 passes, 134 height)
dc.w $0681,$021c,$06c2,$438e
dc.w $1b01,$0144,$0002,$0000
dc.w $0d81,$0288,$0004,$0010,0
; 167 (2 passes, 138 height)
dc.w $1d01,$019c,$02c2,$0000
dc.w $1401,$0288,$0004,$0010,0
; 168 (2 passes, 106 height)
dc.w $0d01,$021c,$06c2,$0000
dc.w $1401,$0288,$0004,$0010,0
; 169 (1 passes, 80 height)
dc.w $1401,$0288,$0004,$0010,0
; 170 (1 passes, 80 height)
dc.w $1401,$0288,$0004,$0010,0
; 171 (1 passes, 80 height)
dc.w $1401,$0288,$0004,$0010,0
; 172 (1 passes, 80 height)
dc.w $1401,$0288,$0004,$0010,0
; 173 (2 passes, 160 height)
dc.w $2801,$0288,$0004,$0000
dc.w $1401,$03cc,$0006,$0012,0
; 174 (2 passes, 160 height)
dc.w $2801,$0288,$0004,$0000
dc.w $1401,$03cc,$0006,$0012,0
; 175 (1 passes, 80 height)
dc.w $1401,$03cc,$0006,$0012,0
; 176 (1 passes, 80 height)
dc.w $1401,$03cc,$0006,$0012,0
; 177 (1 passes, 80 height)
dc.w $1401,$03cc,$0006,$0012,0
; 178 (1 passes, 80 height)
dc.w $1401,$03cc,$0006,$0012,0
; 179 (3 passes, 99 height)
dc.w $0981,$04c0,$07a6,$0000
dc.w $04c1,$0604,$07a8,$4c54,$0f41,$03cc,$0006,$0012,0
; 180 (3 passes, 120 height)
dc.w $0a01,$03cc,$0006,$0012
dc.w $1401,$046c,$0506,$0000
dc.w $0a01,$05b0,$0508,$3214,0
; 181 (3 passes, 125 height)
dc.w $0401,$03cc,$0006,$0012
dc.w $1681,$040c,$0206,$0000
dc.w $1001,$0550,$0208,$1414,0
; 182 (2 passes, 120 height)
dc.w $1401,$03cc,$0006,$0000
dc.w $1401,$0510,$0008,$0014,0
; 183 (2 passes, 96 height)
dc.w $0801,$03cc,$0006,$0000
dc.w $1401,$0510,$0008,$0014,0
; 184 (1 passes, 80 height)
dc.w $2801,$0510,$0000,$0000,0
; 185 (1 passes, 80 height)
dc.w $2801,$0510,$0000,$0000,0
; 186 (0 passes, 0 height)
dc.w 0
; 187 (3 passes, 129 height)
dc.w $07c1,$0510,$0008,$0014
dc.w $1881,$058c,$03e8,$0000
dc.w $0c41,$06d0,$03ea,$26d6,0
; 188 (3 passes, 146 height)
dc.w $0381,$0510,$0008,$0014
dc.w $2101,$0548,$01c8,$0000
dc.w $1081,$068c,$01ca,$1196,0
; 189 (3 passes, 105 height)
dc.w $0181,$0510,$0008,$0014
dc.w $0c81,$0528,$00c8,$0000
dc.w $1281,$066c,$00ca,$0796,0
; 190 (4 passes, 104 height)
dc.w $0501,$076c,$08ca,$0000
dc.w $0281,$08b0,$08cc,$5798
dc.w $0701,$0510,$0008,$0000
dc.w $1181,$0654,$000a,$0016,0
; 191 (4 passes, 108 height)
dc.w $0301,$0510,$0008,$0000,$0b01,$073c,$074a,$0000
dc.w $0581,$0880,$074c,$4898,$0e81,$0654,$000a,$0016,0
; 192 (3 passes, 104 height)
dc.w $0c01,$070c,$05ca,$0000
dc.w $0881,$0850,$05cc,$3998,$0b81,$0654,$000a,$0016,0
; 193 (3 passes, 102 height)
dc.w $0b01,$06e4,$048a,$0000
dc.w $0901,$0654,$000a,$0016,$0b01,$0828,$048c,$2d18,0
; 194 (3 passes, 99 height)
dc.w $0981,$06c0,$036a,$0000
dc.w $06c1,$0654,$000a,$0016,$0d41,$0804,$036c,$21d8,0
; 195 (5 passes, 104 height)
dc.w $0281,$08c4,$096c,$0000
dc.w $0141,$0a08,$096e,$5dda,$0441,$0654,$000a,$0016
dc.w $0981,$0698,$022a,$0000
dc.w $0e81,$07dc,$022c,$1558,0
; 196 (5 passes, 112 height)
dc.w $0281,$0654,$000a,$0016
dc.w $0781,$089c,$082c,$0000
dc.w $03c1,$09e0,$082e,$515a
dc.w $0881,$067c,$014a,$0000
dc.w $0dc1,$07c0,$014c,$0c98,0
; 197 (4 passes, 119 height)
dc.w $0881,$0654,$000a,$0000,$0b01,$086c,$06ac,$0000
dc.w $06c1,$09b0,$06ae,$425a,$0d41,$0798,$000c,$0018,0
; 198 (4 passes, 110 height)
dc.w $0501,$0654,$000a,$0000,$0a01,$084c,$05ac,$0000
dc.w $08c1,$0990,$05ae,$385a,$0b41,$0798,$000c,$0018,0
; 199 (3 passes, 95 height)
dc.w $0781,$0830,$04cc,$0000
dc.w $0981,$0798,$000c,$0018,$0a81,$0974,$04ce,$2f9a,0
; 200 (4 passes, 94 height)
dc.w $0101,$0a14,$09ce,$0000,$0701,$0814,$03ec,$0000
dc.w $07c1,$0798,$000c,$0018,$0bc1,$0958,$03ee,$26da,0
; 201 (4 passes, 94 height)
dc.w $0501,$09f4,$08ce,$0000,$0701,$07f8,$030c,$0000
dc.w $0601,$0798,$000c,$0018,$0b81,$093c,$030e,$1e1a,0
; 202 (4 passes, 92 height)
dc.w $0701,$07dc,$022c,$0000
dc.w $0441,$0798,$000c,$0018
dc.w $0901,$09cc,$078e,$0000
dc.w $0ac1,$0920,$022e,$155a,0
; 203 (4 passes, 84 height)
dc.w $0281,$0798,$000c,$0018
dc.w $0701,$07c0,$014c,$0000,$0881,$09b0,$06ae,$0000
dc.w $0ac1,$0904,$014e,$0c9a,0
; 204 (4 passes, 74 height)
dc.w $00c1,$0798,$000c,$0018
dc.w $0701,$07a4,$006c,$0000,$0801,$098c,$058e,$0000
dc.w $0a41,$08e8,$006e,$03da,0
; 205 (3 passes, 63 height)
dc.w $0501,$0798,$000c,$0000,$0781,$0974,$04ce,$0000
dc.w $0981,$08dc,$000e,$001a,0
; 206 (3 passes, 47 height)
dc.w $0181,$0798,$000c,$0000,$0681,$0958,$03ee,$0000
dc.w $07c1,$08dc,$000e,$001a,0
; 207 (2 passes, 38 height)
dc.w $0601,$0944,$034e,$0000
dc.w $0681,$08dc,$000e,$001a,0
; 208 (2 passes, 31 height)
dc.w $0501,$0930,$02ae,$0000
dc.w $0541,$08dc,$000e,$001a,0
; 209 (2 passes, 26 height)
dc.w $0581,$0918,$01ee,$0000
dc.w $03c1,$08dc,$000e,$001a,0
; 210 (2 passes, 21 height)
dc.w $0481,$090c,$018e,$0000
dc.w $0301,$08dc,$000e,$001a,0
; 211 (2 passes, 15 height)
dc.w $0181,$08dc,$000e,$001a
dc.w $0481,$08f4,$00ce,$0000,0
; 212 (2 passes, 12 height)
dc.w $0081,$08dc,$000e,$001a
dc.w $0501,$08e4,$004e,$0000,0
; 213 (1 passes, 6 height)
dc.w $0301,$08dc,$000e,$0000,0
; 214 (1 passes, 2 height)
dc.w $0101,$08dc,$000e,$0000,0
; 215 (0 passes, 0 height)
dc.w 0
; 216 (0 passes, 0 height)
dc.w 0
; 217 (0 passes, 0 height)
dc.w 0
; 218 (0 passes, 0 height)
dc.w 0
; 219 (0 passes, 0 height)
dc.w 0
; 220 (0 passes, 0 height)
dc.w 0
; 221 (0 passes, 0 height)
dc.w 0
; 222 (0 passes, 0 height)
dc.w 0
; 223 (0 passes, 0 height)
dc.w 0
; 224 (0 passes, 0 height)
dc.w 0
; 225 (0 passes, 0 height)
dc.w 0
; 226 (0 passes, 0 height)
dc.w 0
; 227 (0 passes, 0 height)
dc.w 0
; 228 (0 passes, 0 height)
dc.w 0
; 229 (0 passes, 0 height)
dc.w 0
; 230 (0 passes, 0 height)
dc.w 0
; 231 (0 passes, 0 height)
dc.w 0
; 232 (0 passes, 0 height)
dc.w 0
; 233 (0 passes, 0 height)
dc.w 0
; 234 (0 passes, 0 height)
dc.w 0
; 235 (0 passes, 0 height)
dc.w 0
; 236 (0 passes, 0 height)
dc.w 0
; 237 (0 passes, 0 height)
dc.w 0
; 238 (0 passes, 0 height)
dc.w 0
; 239 (0 passes, 0 height)
dc.w 0
; 240 (0 passes, 0 height)
dc.w 0
; 241 (0 passes, 0 height)
dc.w 0
; 242 (0 passes, 0 height)
dc.w 0
; 243 (0 passes, 0 height)
dc.w 0
; 244 (0 passes, 0 height)
dc.w 0
; 245 (0 passes, 0 height)
dc.w 0
; 246 (0 passes, 0 height)
dc.w 0
; 247 (0 passes, 0 height)
dc.w 0
; 248 (0 passes, 0 height)
dc.w 0
; 249 (0 passes, 0 height)
dc.w 0
; 250 (0 passes, 0 height)
dc.w 0
; 251 (0 passes, 0 height)
dc.w 0
; 252 (0 passes, 0 height)
dc.w 0
; 253 (0 passes, 0 height)
dc.w 0
; 254 (0 passes, 0 height)
dc.w 0
; 255 (0 passes, 0 height)
dc.w 0
; 256 (0 passes, 0 height)
dc.w 0
; 257 (0 passes, 0 height)
dc.w 0

View File

@ -0,0 +1,3 @@
; Palette for C:\Users\platon42\Documents\Projects\Amiga\hameager2\data\blend\PLT_DSRLogo01c_ham.ppm
dc.w $0000,$0111,$0012,$0212,$0122,$0313,$0223,$0225
dc.w $0324,$0627,$0e42,$0f52,$0f73,$0f93,$0fb4,$0fc8

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1 @@
data/blend/PLT_andyou.png data/blend/andyou_128x92x2 -X=0 -Y=0 -width=128 -height=96 -format=1

View File

@ -0,0 +1,131 @@
; Palette for /Users/chodges/Projects/Amiga/hameager2/data/blend/fiveimg_ham.ppm
dc.w $0000,$0222,$0444,$0999,$01be,$0ccc,$0fff
dc.w $0543,$0643,$0643,$0653,$0543,$0543,$0433
dc.w $0322,$0322,$0322,$0433,$0543,$0644,$0654
dc.w $0754,$0653,$0754,$0654,$0654,$0754,$0754
dc.w $0754,$0654,$0754,$0654,$0754,$0754,$0754
dc.w $0754,$0754,$0754,$0654,$0753,$0654,$0754
dc.w $0654,$0754,$0754,$0754,$0654,$0754,$0654
dc.w $0754,$0654,$0754,$0654,$0754,$0654,$0754
dc.w $0654,$0754,$0654,$0754,$0653,$0754,$0654
dc.w $0753,$0654,$0753,$0654,$0753,$0654,$0754
dc.w $0653,$0654,$0654,$0754,$0653,$0754,$0654
dc.w $0754,$0653,$0653,$0654,$0643,$0643,$0543
dc.w $0433,$0432,$0332,$0332,$0433,$0432,$0533
dc.w $0543,$0543,$0653,$0643,$0754,$0653,$0654
dc.w $0643,$0543,$0533,$0433,$0333,$0323,$0333
dc.w $0323,$0333,$0323,$0333,$0323,$0333,$0323
dc.w $0222,$0322,$0332,$0333,$0432,$0533,$0543
dc.w $0643,$0643,$0643,$0643,$0643,$0643,$0643
dc.w $0643,$0643,$0643,$0643,$0643,$0643,$0643
dc.w $0643,$0643,$0643,$0653,$0643,$0643,$0643
dc.w $0653,$0643,$0653,$0643,$0653,$0643,$0753
dc.w $0643,$0653,$0643,$0653,$0643,$0653,$0653
dc.w $0643,$0643,$0643,$0643,$0543,$0543,$0532
dc.w $0432,$0432,$0433,$0532,$0543,$0543,$0643
dc.w $0653,$0643,$0653,$0653,$0753,$0653,$0643
dc.w $0653,$0653,$0643,$0653,$0643,$0653,$0643
dc.w $0653,$0643,$0653,$0643,$0643,$0764,$0764
dc.w $0764,$0765,$0764,$0764,$0764,$0765,$0874
dc.w $0765,$0764,$0765,$0864,$0775,$0864,$0764
dc.w $0764,$0764,$0764,$0864,$0764,$0765,$0764
dc.w $0764,$0864,$0764,$0764,$0864,$0764,$0874
dc.w $0865,$0764,$0864,$0874,$0864,$0874,$0864
dc.w $0874,$0864,$0864,$0865,$0764,$0874,$0864
dc.w $0864,$0764,$0864,$0764,$0864,$0764,$0864
dc.w $0764,$0864,$0764,$0764,$0864,$0764,$0864
dc.w $0764,$0764,$0764,$0764,$0864,$0764,$0764
dc.w $0764,$0864,$0764,$0764,$0764,$0864,$0764
dc.w $0764,$0764,$0764,$0764,$0764,$0764,$0764
dc.w $0764,$0765,$0764,$0764,$0764,$0764,$0764
dc.w $0764,$0764,$0764,$0764,$0764,$0764,$0764
dc.w $0765,$0775,$0765,$0765,$0764,$0764,$0764
dc.w $0764,$0664,$0764,$0764,$0764,$0764,$0765
dc.w $0764,$0765,$0764,$0765,$0764,$0764,$0764
dc.w $0765,$0764,$0775,$0764,$0875,$0765,$0875
dc.w $0875,$0875,$0875,$0875,$0975,$0975,$0985
dc.w $0985,$0986,$0985,$0986,$0a86,$0a86,$0a86
dc.w $0a86,$0a96,$0a86,$0a96,$0a86,$0a96,$0a86
dc.w $0a96,$0a96,$0a96,$0b86,$0a96,$0a86,$0b96
dc.w $0a96,$0b96,$0a86,$0b96,$0a96,$0b96,$0a86
dc.w $0b96,$0a96,$0b96,$0b96,$0b96,$0b96,$0a96
dc.w $0b96,$0b97,$0b96,$0b97,$0b96,$0ca7,$0ca7
dc.w $0ca7,$0ca7,$0ca7,$0ca8,$0da8,$0ca8,$0da8
dc.w $0db8,$0db8,$0db8,$0fb8,$0ea7,$0ea8,$0a76
dc.w $0432,$0210,$0000,$0110,$0000,$0322,$0322
dc.w $0100,$0000,$0111,$0755,$0766,$0866,$0867
dc.w $0866,$0221,$0000,$0211,$0853,$0000,$0221
dc.w $0642,$0000,$0100,$0010,$0433,$0866,$0877
dc.w $0866,$0866,$0433,$0756,$0866,$0866,$0866
dc.w $0755,$0222,$0210,$0101,$0110,$0100,$0100
dc.w $0100,$0100,$0100,$0321,$0742,$0532,$0100
dc.w $0311,$0321,$0431,$0953,$0e85,$0c75,$0433
dc.w $0222,$0323,$0223,$0323,$0222,$0223,$0222
dc.w $0333,$0323,$0222,$0223,$0333,$0333,$0323
dc.w $0222,$0333,$0333,$0333,$0333,$0333,$0323
dc.w $0434,$0444,$0434,$0333,$0333,$0433,$0655
dc.w $0434,$0434,$0233,$0434,$0444,$0544,$0333
dc.w $0545,$0555,$0323,$0544,$0444,$0434,$0333
dc.w $0434,$0655,$0333,$0333,$0444,$0545,$0766
dc.w $0755,$0544,$0444,$0444,$0444,$0333,$0223
dc.w $0333,$0445,$0544,$0555,$0544,$0444,$0334
dc.w $0333,$0334,$0444,$0445,$0766,$0656,$0223
dc.w $0212,$0111,$0111,$0000,$0111,$0111,$0222
dc.w $0111,$0111,$0000,$0100,$0000,$0111,$0112
dc.w $0111,$0101,$0111,$0111,$0111,$0000,$0000
dc.w $0111,$0212,$0111,$0000,$0222,$0444,$0655
dc.w $0654,$0655,$0654,$0655,$0655,$0655,$0655
dc.w $0654,$0654,$0332,$0544,$0544,$0544,$0655
dc.w $0654,$0654,$0544,$0544,$0654,$0443,$0432
dc.w $0431,$0234,$0234,$0233,$0244,$0233,$0244
dc.w $0144,$0144,$0244,$0255,$0244,$0244,$0344
dc.w $0233,$0234,$0233,$0122,$0122,$0233,$0244
dc.w $0233,$0133,$0233,$0223,$0233,$0122,$0143
dc.w $0254,$0144,$0154,$0066,$0067,$0055,$0243
dc.w $0243,$0443,$0653,$0853,$0963,$0963,$0952
dc.w $0a53,$0a52,$0853,$0554,$0354,$0266,$0498
dc.w $0277,$0166,$0166,$0265,$0244,$0133,$0133
dc.w $0233,$0243,$0243,$0344,$0254,$0354,$0144
dc.w $0144,$0144,$0254,$0143,$0244,$0254,$0266
dc.w $0266,$0233,$0122,$0354,$0687,$0697,$0687
dc.w $0686,$0687,$0587,$0487,$0387,$0376,$0365
dc.w $0344,$0344,$0333,$0222,$0233,$0344,$0233
dc.w $0333,$0233,$0343,$0555,$0333,$0233,$0343
dc.w $0455,$0444,$0322,$0333,$0333,$0232,$0554
dc.w $0454,$0554,$0343,$0455,$0343,$0554,$0444
dc.w $0111,$0222,$0322,$0221,$0100,$0322,$0633
dc.w $0843,$0832,$0842,$0732,$0643,$0222,$0110
dc.w $0532,$0853,$0853,$0653,$0764,$0764,$0532
dc.w $0753,$0654,$0553,$0a98,$0997,$0a98,$0545
dc.w $0843,$0f97,$0d52,$0d63,$0d63,$0d63,$0d63
dc.w $0d63,$0d63,$0e63,$0d74,$0d64,$0d63,$0d63
dc.w $0fa7,$0744,$0366,$05aa,$0388,$07ba,$0576
dc.w $0653,$0b96,$0b75,$0b86,$0a65,$0b86,$0744
dc.w $0422,$0422,$0221,$0100,$0111,$0111,$0211
dc.w $0423,$0623,$0623,$0623,$0523,$0523,$0222
dc.w $0122,$0222,$0222,$0222,$0222,$0123,$0222
dc.w $0233,$0233,$0233,$0233,$0223,$0222,$0223
dc.w $0222,$0233,$0222,$0233,$0223,$0233,$0223
dc.w $0233,$0222,$0233,$0222,$0232,$0223,$0222
dc.w $0223,$0222,$0233,$0222,$0222,$0222,$0222
dc.w $0222,$0223,$0233,$0233,$0233,$0233,$0222
dc.w $0233,$0233,$0233,$0222,$0223,$0233,$0233
dc.w $0233,$0233,$0233,$0233,$0233,$0233,$0233
dc.w $0233,$0233,$0233,$0233,$0233,$0233,$0233
dc.w $0233,$0233,$0233,$0233,$0233,$0233,$0233
dc.w $0232,$0233,$0223,$0122,$0111,$0222,$0222
dc.w $0222,$0222,$0223,$0222,$0222,$0122,$0223
dc.w $0222,$0223,$0122,$0222,$0222,$0223,$0122
dc.w $0223,$0222,$0223,$0232,$0223,$0122,$0112
dc.w $0122,$0122,$0122,$0222,$0222,$0112,$0122
dc.w $0133,$0133,$0233,$0133,$0133,$0122,$0011
dc.w $0122,$0222,$0122,$0111,$0011,$0122,$0222
dc.w $0122,$0122,$0122,$0122,$0112,$0121,$0112
dc.w $0121,$0112,$0122,$0111,$0111,$0111,$0122
dc.w $0222,$0122,$0122,$0122,$0111,$0011,$0122
dc.w $0022,$0012,$0144,$0144,$0145,$0144,$0155
dc.w $0255,$0144,$0033,$0043,$0043,$0044,$0155
dc.w $0166,$0256,$0266,$0166,$0055,$0033,$0133
dc.w $0122,$0332,$0787,$0687,$0797,$0897,$09bb
dc.w $05aa,$06a9,$07a9,$0565,$0aa9,$0998,$09a8
dc.w $0898,$0ab9,$0887,$0896

Binary file not shown.

View File

@ -0,0 +1,10 @@
load data/blend/fiveimg_ham.raw
save data/blend/fiveimg1_ham.raw -l 43200 -n 0
save data/blend/fiveimg2_ham.raw -l 43200 -n 1
save data/blend/fiveimg3_ham.raw -l 43200 -n 2
save data/blend/fiveimg4_ham.raw -l 43200 -n 3
save data/blend/fiveimg5_ham.raw -l 43200 -n 4
clear
load data/blend/leavestc.raw
reorganize 180 -w 10 -l 2 -um 62
save data/blend/leavestc_10.raw

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,3 @@
; Palette for /Users/chodges/Projects/Amiga/hameager2/data/bulb/PLT_Lampscene_ham.ppm
dc.w $0000,$0111,$0332,$0322,$0665,$0764,$0542,$0654
dc.w $0ddb,$0ec9,$0a85,$0cb8

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -0,0 +1,8 @@
data/bulb/PLT_lamp_01c.png data/bulb/lamp_64x32x16 -rawpalette -X=0 -Y=0 -width=64 -height=32 -format=a
data/bulb/PLT_lamp_02e.png data/bulb/lamp_off_64x32x16 -rawpalette -X=32 -Y=0 -width=64 -height=32 -format=a
data/bulb/68k-inside-logo_128x80c.png data/bulb/text2 -X=0 -Y=0 -width=128 -height=80 -interleaved -format=2
data/bulb/PLT_textsprites02.png data/bulb/text1 -X=0 -Y=0 -width=128 -height=80 -interleaved -format=2
data/bulb/PLT_textsprites02.png data/bulb/text3 -X=128 -Y=0 -width=128 -height=80 -interleaved -format=2
data/bulb/PLT_textsprites02.png data/bulb/text4 -X=256 -Y=0 -width=128 -height=80 -interleaved -format=2
data/bulb/PLT_textsprites02.png data/bulb/text5 -X=384 -Y=0 -width=128 -height=80 -interleaved -format=2
data/bulb/PLT_lamp_01c.png data/bulb/lamp_48x32x16 -X=8 -Y=0 -width=48 -height=32 -format=4

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,2 @@
data/endpart/PJZ_font_8x16x4.png data/endpart/PJZ_font_8x16x4 -format=2 -interleaved
data/endpart/screenshots_rightpal.png data/endpart/screenshots_320x1620 -format=2 -interleaved

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -0,0 +1,6 @@
data/gotham/texts.png data/gotham/meanwhile320x18x4 -format=2 -Y=23 -height=18
data/gotham/texts.png data/gotham/gothamcity320x23x4 -format=2 -Y=78 -height=23
data/gotham/texts.png data/gotham/hameelinna320x23x4 -format=2 -Y=102 -height=23
data/gotham/texts.png data/gotham/gotham320x23x4 -format=2 -Y=126 -height=23
data/gotham/texts.png data/gotham/ham320x23x4 -format=2 -Y=150 -height=23
data/gotham/texts.png data/gotham/hamtechnology320x13x4 -format=2 -Y=176 -height=13

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1 @@
data/gouraud/PLT_bendit_sprite.png data/gouraud/bendit128x128x4 -format=s -width=128 -height=128

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,2 @@
data/hexagon/hexagon.png data/hexagon/hexagon_reg16x254 -rawpalette -ftpalette=dc.w -format=e -interleaved -width=16 -height=254
data/hexagon/PLT_winners_sprite02b.png data/hexagon/winners128x128x4 -format=s -width=128 -height=128

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,7 @@
data/kaleidoscope/PLT_Fairyanim_01c.png data/kaleidoscope/fairy1_48x51x16 -format=4 -interleaved -X=0 -Y=5 -width=48 -height=51 -rawpalette
data/kaleidoscope/PLT_Fairyanim_01c.png data/kaleidoscope/fairy2_48x51x16 -format=4 -interleaved -X=64 -Y=5 -width=48 -height=51
data/kaleidoscope/PLT_Fairyanim_01c.png data/kaleidoscope/fairy3_48x51x16 -format=4 -interleaved -X=128 -Y=5 -width=48 -height=51
data/kaleidoscope/PLT_Fairyanim_01c.png data/kaleidoscope/puff1_32x15x16 -format=4 -interleaved -X=32 -Y=83 -width=32 -height=15
data/kaleidoscope/PLT_Fairyanim_01c.png data/kaleidoscope/puff2_32x15x16 -format=4 -interleaved -X=96 -Y=83 -width=32 -height=15
data/kaleidoscope/PLT_Fairyanim_01c.png data/kaleidoscope/puff3_32x15x16 -format=4 -interleaved -X=160 -Y=83 -width=32 -height=15
data/kaleidoscope/PLT_Fairyanim_01c.png data/kaleidoscope/puff4_32x15x16 -format=4 -interleaved -X=224 -Y=83 -width=32 -height=15

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,3 @@
; Palette for /Users/chodges/Projects/Amiga/hameager2/data/stham/PLT_HAMph_path_2_test08b_ham.ppm
dc.w $0000,$0101,$0011,$0212,$0311,$0123,$0410,$0413
dc.w $0134,$0613,$0145,$0724,$0166,$0177,$0972,$0595

Binary file not shown.

View File

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,4 @@
data/virgillbars/PLT_Lolcat_01c_WIP_64x128.png data/virgillbars/PLT_Lolcat64x128x16 -rawpalette -format=a -width=64 -height=128
data/virgillbars/PLT_addition_sprite.png data/virgillbars/additionsprite96x112x4 -format=s -width=96 -height=112
data/virgillbars/PLT_breakthrough_sprite.png data/virgillbars/lightbreak128x128x4 -format=s -width=128 -height=128
data/virgillbars/PLT_breakthrough_sprite.png data/virgillbars/staybroken128x128x4 -format=s -X=144 -width=128 -height=128

Binary file not shown.

30
source/endpart/aga.bat Normal file
View File

@ -0,0 +1,30 @@
del endpart.exe
del "..\winuae\hd0\endpart.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -O2 -notmpfile -nostdlib -o "endpart.exe" "endpart.asm"
@if %ERRORLEVEL% NEQ 0 goto failed
copy endpart.exe "..\winuae\hd0"
copy endpart.exe "..\winuae\hd0\a"
@echo /|set /p =endpart.exe>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a1200_hrt.uae" -log -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg
@goto ok
rem ############ ERROR HANDLER ############
:failed
@echo error in directory "%CD%"
@echo !!!!!!!!! oh no !!!!!!!!!!!!
@pause
del vc.cfg
:ok

View File

@ -0,0 +1,40 @@
del endpart.exe
del "..\winuae\hd0\endpart.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
pushd ..
tools\KingCon.exe @data/endpart/assets.txt
@if %ERRORLEVEL% NEQ 0 goto failed
tools\LSPConvert.exe data\music\desire_68k_tune3_v2.mod -setpos -v
@if %ERRORLEVEL% NEQ 0 goto failed
popd
vc -O2 -notmpfile -nostdlib -o "endpart.exe" "endpart.asm"
@if %ERRORLEVEL% NEQ 0 goto failed
copy endpart.exe "..\winuae\hd0"
copy endpart.exe "..\winuae\hd0\a"
@echo /|set /p =endpart.exe>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a500_hrt.uae" -log -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg
@goto ok
rem ############ ERROR HANDLER ############
:failed
@echo error in directory "%CD%"
@echo !!!!!!!!! oh no !!!!!!!!!!!!
@pause
del vc.cfg
:ok

View File

@ -0,0 +1,9 @@
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -O2 -notmpfile -nostdlib -o "endpart.exe" "endpart.asm"

21
source/endpart/debug.bat Normal file
View File

@ -0,0 +1,21 @@
del endpart.exe
del "..\winuae\hd0\endpart.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -g -hunkdebug -O2 -notmpfile -nostdlib -o "endpart.exe" "endpart.asm"
copy endpart.exe "..\winuae\hd0"
copy endpart.exe "..\winuae\hd0\a"
copy "..\winuae\hd0\s\debug-sequence" "..\winuae\hd0\s\startup-sequence"
@echo /|set /p =endpart.exe >>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a500_debug.uae" -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg

1077
source/endpart/endpart.asm Normal file

File diff suppressed because it is too large Load Diff

30
source/endpart/record.bat Normal file
View File

@ -0,0 +1,30 @@
del endpart.exe
del "..\winuae\hd0\endpart.exe"
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
copy "..\tools\vc.cfg" %~dp0
vc -O2 -notmpfile -nostdlib -o "endpart.exe" "endpart.asm"
@if %ERRORLEVEL% NEQ 0 goto failed
copy endpart.exe "..\winuae\hd0"
copy endpart.exe "..\winuae\hd0\a.exe"
@echo /|set /p =endpart.exe>"..\winuae\hd0\s\startup-sequence"
"..\winuae\winuae64" -config="configs\a500_rec.uae" -s use_gui=no -s filesystem2=rw,hd0:test:%~dp0\..\winuae\hd0,0
del vc.cfg
@goto ok
rem ############ ERROR HANDLER ############
:failed
@echo error in directory "%CD%"
@echo !!!!!!!!! oh no !!!!!!!!!!!!
@pause
del vc.cfg
:ok

View File

@ -0,0 +1,10 @@
del bootblock
@if X%VBCC%==X%~dp0 goto AlreadySet
@set VBCC=%~dp0
@set PATH=%VBCC%\..\tools;%PATH%
:AlreadySet
..\tools\vasmm68k_mot -m68010 -Fbin -o bootblock -I"%~dp0/../includes" bootblock.asm
pause

View File

@ -0,0 +1,83 @@
; Bootblock by Chris 'platon42' Hodges.
opt p+,o+
DEBUG_DETAIL set 0
FW_DIRECTORY_ENTRIES_OFFSET = 512
include "exec/execbase.i"
include "exec/io.i"
include "exec/memory.i"
include "exec/macros.i"
include "hardware/adkbits.i"
include "hardware/cia.i"
include "hardware/custom.i"
include "hardware/dmabits.i"
include "hardware/intbits.i"
include "lvo/lvo.i"
_start:
dc.b 'D','O','S',0 ; disk type
dc.l 0 ; checksum 'PLAT'
dc.b 'ON42' ; root block 'ON42'
_entrypoint:
; Because this is a bootblock, we will have ExecBase in a6 here
; a1 is IO-Request
PUSHM d2/a2-a3 ; keep registers safe, otherwise bootstrap will crash
move.l a1,a3
lea _start+FW_DIRECTORY_ENTRIES_OFFSET+20(pc),a2 ; de_MemorySize
move.l (a2)+,d0
PUTMSG 10,<"Alloc %ld bytes">,d0
moveq.l #MEMF_ANY,d1
CALL AllocMem
move.l d0,-(sp)
beq.s .error
move.l (a2)+,IO_OFFSET(a3) ; de_DiskOffset
move.l (a2)+,d0 ; de_DiskLength
add.w #511,d0
and.w #-512,d0 ; round to 512 block size
move.l d0,IO_LENGTH(a3)
moveq.l #MEMF_CHIP,d1
CALL AllocMem
move.l d0,-(sp)
bne.s .good
.error move.w #$f00,$dff180
bra.s .error
.good
PUTMSG 10,<"Loading %ld from offset %ld to %p">,IO_LENGTH(a3),IO_OFFSET(a3),d0
move.l d0,IO_DATA(a3)
move.l a3,a1
CALL DoIO
tst.l d0
bne.s .error
move.l (sp)+,a0
move.l (sp),a1
PUTMSG 10,<"Decrunching %p to %p">,a0,a1
bsr.s zx0_decompress ; a3 not trashed
PUTMSG 10,<"FreeMem %p">,a1
move.l IO_DATA(a3),a1
move.l IO_LENGTH(a3),d0
CALL FreeMem
cmp.w #37,LIB_VERSION(a6)
blo.s .lameos
CALL CacheClearU
.lameos
.execute
move.l (sp)+,a0 ; execute this!
PUTMSG 10,<"Returning %p for execution">,a0
POPM
moveq.l #0,d0 ; no error
rts
include "unpackers/zx0.asm"

View File

@ -0,0 +1,108 @@
; PLaTOS 2.0 (22-May-23) by Chris 'platon42' Hodges (unless stated).
; link all parts together depending on the settings
include "../framework/framework.i"
IF FW_STANDALONE_FILE_MODE
include "../framework/os_startupcode.asm"
ELSE
include "../framework/trackmo_startupcode.asm"
ENDC
include "../framework/framework_misc.asm"
IF FW_MULTITASKING_SUPPORT
include "../framework/framework_tasks.asm"
ENDC
IF FW_BLITTERQUEUE_SUPPORT
include "../framework/framework_blitterqueue.asm"
ENDC
IF FW_DYNAMIC_MEMORY_SUPPORT
include "../framework/framework_memory.asm"
ENDC
IF FW_MUSIC_SUPPORT
include "../framework/framework_music.asm"
ENDC
IF FW_MULTIPART_SUPPORT
include "../framework/framework_multipart.asm"
ENDC
IF FW_SINETABLE_SUPPORT
include "../framework/framework_sinetable.asm"
ENDC
IF FW_SCRIPTING_SUPPORT
include "../framework/framework_scripting.asm"
ENDC
IF FW_PALETTE_LERP_SUPPORT
include "../framework/framework_palettelerp.asm"
ENDC
IFEQ FW_STANDALONE_FILE_MODE
include "../framework/framework_trackloader.asm"
include "../framework/framework_dos.asm"
ELSE
IF FW_HD_TRACKMO_MODE
include "../framework/framework_hdloader.asm"
include "../framework/framework_dos.asm"
ENDC
ENDC
IF FW_MUSIC_SUPPORT
IFNE FW_MUSIC_PLAYER_CHOICE==0
include "../framework/musicplayers/player_none.asm"
ENDC
IFNE FW_MUSIC_PLAYER_CHOICE==1
include "../framework/musicplayers/player_lsp_vbl.asm"
ENDC
IFNE FW_MUSIC_PLAYER_CHOICE==2
include "../framework/musicplayers/player_lsp_cia.asm"
ENDC
IFNE FW_MUSIC_PLAYER_CHOICE==3
fail "Sorry, P61 not ported to this framework (yet). Use LSP instead."
ENDC
IFNE (FW_MUSIC_PLAYER_CHOICE==4)|(FW_MUSIC_PLAYER_CHOICE==5)
;include "../framework/musicplayers/player_pretracker_std.asm"
include "../framework/musicplayers/player_raspberry_casket.asm"
ENDC
ENDC
IF FW_LZ4_SUPPORT
fw_DecompressLZ4:
include "../framework/unpackers/lz4_normal.asm"
ENDC
IF FW_ZX0_SUPPORT
fw_DecompressZX0:
;include "../framework/unpackers/zx0.asm"
include "../framework/unpackers/zx0_faster.asm"
ENDC
IF FW_DOYNAX_SUPPORT
fw_DecompressDoynax:
include "../framework/unpackers/doynax.asm"
ENDC
include "../framework/framework_chip_section.asm"
IF FW_STANDALONE_FILE_MODE
; framework structure is allocated from RAM and pointer is placed here
; for IRQ routines to access it.
fw_BasePtr:
dc.l 0
ELSE
; framework structure is stored here with a minimal LVO table.
; Pointer to base is stored here for IRQ routines to access it.
fw_BasePtr:
dc.l 0
bra.w fw_InitPart ; make init part reachable from base framework
nop
fw_Base:
ds.b fw_SIZEOF
ENDC

View File

@ -0,0 +1,306 @@
IFND FRAMEWORK_I
FRAMEWORK_I SET 1
include "../includes/hardware/custom.i"
include "../includes/hardware/copper.i"
include "../includes/hardware/cia.i"
include "../includes/hardware/intbits.i"
include "../includes/hardware/dmabits.i"
include "../includes/hardware/adkbits.i"
include "../includes/hardware/blitbits.i"
include "../includes/exec/types.i"
include "../includes/exec/nodes.i"
include "../includes/exec/lists.i"
include "../includes/exec/macros.i"
include "../includes/exec/execbase.i"
include "../includes/dos/doshunks.i"
include "../includes/lvo/lvo.i"
include "../framework/framework_macros.i"
FWGENLVOTABLE SET 0
include "../framework/framework_lvos.i"
; error color codes
ERROR_OUTOFMEMORY = $0f00 ; one of the memory stacks ran out of memory
ERROR_MEMORYWRONGPOP = $0f80 ; nothing to pop the current direction
ERROR_INVALID_PARAMS = $0ff0 ; one of the api functions was called with invalid parameters
ERROR_TOOMANYHUNKS = $00f0 ; the executable has too many hunks. see: MAX_HUNKS
ERROR_HUNKBROKEN = $000f ; one of the executables hunks is broken (e.g. header or compressed hunk).
ERROR_DISK = $00ff ; error loading via trackloader
ERROR_FILE_NOT_FOUND = $0088 ; expected file not found
DEFB_MORE_HUNKS = 15 ; must be sign bit
DEFF_MORE_HUNKS = (1<<DEFB_MORE_HUNKS)
DEFB_CHIPMEM = 7 ; must be sign bit
DEFF_CHIPMEM = (1<<DEFB_CHIPMEM)
DEFS_TYPE = 0
DEFM_TYPE = (7<<DEFS_TYPE)
DEFF_DATAFILE = (0<<DEFS_TYPE)
DEFF_HUNK_CODE = (1<<DEFS_TYPE)
DEFF_HUNK_DATA = (2<<DEFS_TYPE)
DEFF_HUNK_BSS = (3<<DEFS_TYPE)
DEFF_HUNK_RELOC = (4<<DEFS_TYPE)
DEFS_PACKMODE = 4
DEFM_PACKMODE = (7<<DEFS_PACKMODE)
DEFF_UNPACKED = (0<<DEFS_PACKMODE)
DEFF_LZ4 = (1<<DEFS_PACKMODE) ; allows parallel loading/decrunching
DEFF_DOYNAX = (2<<DEFS_PACKMODE) ; needs to be loaded to fastmem
DEFF_ZX0 = (3<<DEFS_PACKMODE) ; needs to be loaded to fastmem
DEFF_ZSTANDARD = (4<<DEFS_PACKMODE) ; not implemented
DEFS_DELTAMODE = 8
DEFM_DELTAMODE = (3<<DEFS_DELTAMODE)
DEFF_NODELTA = (0<<DEFS_DELTAMODE)
DEFF_DELTA8 = (1<<DEFS_DELTAMODE)
DEFF_DELTA16 = (2<<DEFS_DELTAMODE) ; not implemented
DEFF_DELTA32 = (3<<DEFS_DELTAMODE) ; not implemented
DEFB_IN_PLACE = 11
DEFF_IN_PLACE = (1<<DEFB_IN_PLACE)
IF (FW_STANDALONE_FILE_MODE==0)|FW_HD_TRACKMO_MODE
FW_DIRECTORY_ENTRIES_OFFSET = 512
STRUCTURE DirEntry,0
STRUCT de_Name,16
LABEL de_NextHunk
UWORD de_Flags ; see above
UBYTE de_HunkNum
UBYTE de_NumHunks ; >0 -> LoadSeg, otherwise simple data file
ULONG de_MemorySize ; memory needed
ULONG de_DiskOffset ; offset on disk (or 0 if BSS)
ULONG de_DiskLength ; load size
LABEL de_SIZEOF ; 32 -> up to 16 files per block
ENDC
IF FW_BLITTERQUEUE_SUPPORT
STRUCTURE BlitterQueueNode,0
APTR bq_Next
APTR bq_Routine
LABEL bq_Data
LABEL bq_SIZEOF
ENDC
IF FW_MULTITASKING_SUPPORT
STRUCTURE FrameworkTask,LN_SIZE
APTR ft_USP
IF FW_TOP_BOTTOM_MEM_SECTIONS
UWORD ft_MemDirection
ENDC
LABEL ft_StackStart
STRUCT ft_Stack,512-ft_StackStart
LABEL ft_StackEnd
LABEL ft_SIZEOF
ENDC
IF FW_DYNAMIC_MEMORY_SUPPORT
STRUCTURE MemTopBottom,0
APTR mtb_CurrLevelPtr ; Top (from $80000 down) or Bottom (from $400 up) pointer
APTR mtb_MinLevelPtr ; Min Top or Bottom pointer on free all
LABEL mtb_SIZEOF
STRUCTURE ChipFastMemState,0
STRUCT cf_ChipMemLevel,mtb_SIZEOF
STRUCT cf_FastMemLevel,mtb_SIZEOF
LABEL cf_SIZEOF
ENDC
IF FW_PALETTE_LERP_SUPPORT
STRUCTURE Lerp,0 ; don't change order!
WORD le_Add
UWORD le_Current
LABEL le_SIZEOF
STRUCTURE ColorLerp,0 ; don't change order!
UWORD cl_Color
WORD cl_Steps ; negative in first entry means fading done
STRUCT cl_Red,le_SIZEOF
STRUCT cl_Green,le_SIZEOF
STRUCT cl_Blue,le_SIZEOF
LABEL cl_SIZEOF
ENDC
STRUCTURE FrameWork,0
UWORD fw_FrameCounterLong
UWORD fw_FrameCounter
APTR fw_PartFwBase
APTR fw_PrimaryFwBase
ULONG fw_PartDataSize
APTR fw_GlobalUserData ; you can use this for your custom trackloading global data area
IF FW_DYNAMIC_MEMORY_SUPPORT
IF FW_TOP_BOTTOM_MEM_SECTIONS
UWORD fw_MainMemDirection
ENDC
STRUCT fw_MemBottomStack,cf_SIZEOF*FW_MAX_MEMORY_STATES
STRUCT fw_MemTopStack,cf_SIZEOF*FW_MAX_MEMORY_STATES
ULONG fw_MaxChipUsed
ULONG fw_MaxFastUsed
UWORD fw_CurrMemBottomLevel
UWORD fw_CurrMemTopLevel
ENDC
APTR fw_ChipMemStack
APTR fw_ChipMemStackEnd
APTR fw_FastMemStack
APTR fw_FastMemStackEnd
APTR fw_EmptySprite
APTR fw_BaseCopperlist
APTR fw_VBR
APTR fw_DemoAbortStackPointer
BOOL fw_AgaChipset
IF FW_STANDALONE_FILE_MODE
APTR fw_OrigBaseMemAllocAddr
ULONG fw_OrigBaseMemAllocLength
APTR fw_OrigChipMemAllocAddr
ULONG fw_OrigChipMemAllocLength
APTR fw_OrigFastMemAllocAddr
ULONG fw_OrigFastMemAllocLength
APTR fw_WBMessage
APTR fw_OldGfxView
APTR fw_DosBase
APTR fw_GfxBase
STRUCT fw_OldControls,2*4 ; intena, intreq, dmacon, adkcon
APTR fw_OldSystemVBlankIRQ
APTR fw_OldCiaIRQ
APTR fw_CiaBResource
STRUCT fw_SysFriendlyInterrupt,IS_SIZE
ENDC
STRUCT fw_EmptyRegs,4*16
IF (FW_STANDALONE_FILE_MODE==0)|FW_HD_TRACKMO_MODE
APTR fw_DirBuffer
APTR fw_TrackBuffer
IF FW_MULTITASKING_SUPPORT
APTR fw_TrackloaderTask
ENDC
ENDC
IFEQ FW_STANDALONE_FILE_MODE
ULONG fw_ExpectedFirstFileID
APTR fw_MfmTrackBuffer
UWORD fw_CurrentCylinder
UWORD fw_CurrentHead
UWORD fw_CurrentDrive
UWORD fw_LastMfmTrack
UWORD fw_LastTrack
UWORD fw_MfmDoPrefetch
BOOL fw_MfmReadingTriggered
BOOL fw_MfmReadingDone
BOOL fw_DriveMotorOn
ULONG fw_DriveSettleTime
ULONG fw_TrackChecksum
UWORD fw_TrackloaderIdle
IF FW_TRACKMO_LZ4_SUPPORT|FW_TRACKMO_LZ4_DLT8_SUPPORT
UWORD fw_TrackLz4State
UWORD fw_TrackLz4LiteralLength ; if we have literals >64 KB, we're f*cked anyway
UWORD fw_TrackLz4MatchLength ; duplicating >64 KB is also very improbable
ULONG fw_TrackLz4Offset
UBYTE fw_TrackLz4Delta8Value
ALIGNWORD
ENDC
ENDC
APTR fw_DefaultIRQ
IF FW_VBL_IRQ_SUPPORT
APTR fw_VBlankIRQ
ENDC
IF FW_COPPER_IRQ_SUPPORT
APTR fw_CopperIRQ
ENDC
IF FW_MULTITASKING_SUPPORT
STRUCT fw_Tasks,MLH_SIZE
UWORD fw_MainCurrentFrame
APTR fw_BackgroundTask
APTR fw_MultitaskingIRQ
APTR fw_BlitterTaskIRQ
APTR fw_PrimaryUSP
APTR fw_BackgroundTaskUSP
ENDC
IF FW_BLITTERQUEUE_SUPPORT
APTR fw_BlitterQueueIRQ
APTR fw_BlitterQueueWritePtr ; don't change order
APTR fw_BlitterQueueHeadPtr ; don't change order
APTR fw_BlitterQueueReadPtr ; don't change order
ENDC
IF (FW_STANDALONE_FILE_MODE==0)|FW_HD_TRACKMO_MODE
STRUCT fw_HunkPointers,4*FW_MAX_DOS_HUNKS
STRUCT fw_PreloadHunkPointers,4*FW_MAX_DOS_HUNKS
STRUCT fw_PreloadRelocHunkPointers,4*FW_MAX_DOS_HUNKS
APTR fw_LastLoadedPart
APTR fw_PrePartLaunchHook
APTR fw_PrepNextPartHook
ENDC
IF FW_SINETABLE_SUPPORT
APTR fw_SinTable
APTR fw_CosTable
ENDC
IF FW_SCRIPTING_SUPPORT
APTR fw_ScriptPointer
UWORD fw_ScriptFrameOffset
IF FW_MUSIC_SUPPORT
APTR fw_MusicScriptPointer
ENDC
ENDC
IF FW_MUSIC_SUPPORT
BOOL fw_MusicEnabled
APTR fw_MusicData
APTR fw_MusicSamples
UWORD fw_MusicFrameCount
UWORD fw_MusicPatternRow
BOOL fw_MusicPatternNewRow
IF (FW_MUSIC_PLAYER_CHOICE==1)|(FW_MUSIC_PLAYER_CHOICE==2)
APTR fw_LspDmaConPatch ; patch address
APTR fw_LspCodeTableAddr ; code table addr
; do not reorder!
UWORD fw_LspCurrentBpm ; current BPM
APTR fw_LspInstruments ; LSP instruments table addr
UWORD fw_LspEscCodeRewind
UWORD fw_LspEscCodeSetBpm
UWORD fw_LspEscCodeGetPos
ULONG fw_LspMusicLength ; music len in frame ticks
UWORD fw_LspSeqCount
APTR fw_LspSeqTable
UWORD fw_LspCurrentSeq
APTR fw_LspStreamBase ; start of stream info
APTR fw_LspByteStream ; byte stream
APTR fw_LspWordStream ; word stream
APTR fw_LspByteStreamLoop ; byte stream loop point
APTR fw_LspWordStreamLoop ; word stream loop point
; END of fixed ordering
STRUCT fw_LspResetv,4*4 ; Loop loading data ptr
IF FW_MUSIC_PLAYER_CHOICE==2
UWORD fw_LspLastCiaBpm
ULONG fw_LspCiaClock
ENDC
ENDC
IF (FW_MUSIC_PLAYER_CHOICE==4)||(FW_MUSIC_PLAYER_CHOICE==5)
APTR fw_PretrackerMyPlayer
APTR fw_PretrackerMySong
ULONG fw_PretrackerProgress
APTR fw_PretrackerCopperlist
ENDC
ENDC
IFD gbd_SIZEOF
STRUCT fw_GlobalBonusData,gbd_SIZEOF
ENDC
ALIGNLONG
LABEL fw_SIZEOF
ENDC ; FRAMEWORK_I

View File

@ -0,0 +1,382 @@
;--------------------------------------------------------------------
; Interrupt-driven Blitter Queue
;
; Blitter queues may not be an optimal solution but they add a tool
; to the various ways of intertwining CPU and blitter activity.
;
; As there may be a rather large penalty for interrupt context
; switches (less so if FW_A5_A6_UNTOUCHED is activated),
; this implementation tries to reduce the overhead to a minimum.
;
; There are four basic ways to use the Blitter Queue:
;
; 1) Create and process blits in the same frame:
; - [AddToBlitterQueue]*
; - TerminateBlitterQueue
; - TriggerBlitterQueue
; - Do more CPU based stuff
; - JoinBlitterQueue
; - VSyncWithTask
;
; 2) Create stuff for the next frame, no queue double buffering:
; - TriggerBlitterQueue
; - Do CPU based stuff
; - JoinBlitterQueue
; - [AddToBlitterQueue]*
; - TerminateBlitterQueue
; - VSyncWithTask
;
; 3) Create stuff for the next frame, double buffered queue:
; - TriggerBlitterQueue (the last one)
; - [AddToBlitterQueue]* (the current one)
; - TerminateBlitterQueue (the current one)
; - Do more CPU based stuff
; - JoinBlitterQueue
; - VSyncWithTask
;
; 4) Create and run stuff in parallel with the current frame:
; - [AppendToRunningBlitterQueue, do more CPU based stuff]*
; - TerminateBlitterQueue
; - JoinBlitterQueue
; - VSyncWithTask
;
; 5) Create and run stuff in parallel with the current frame (alternate):
; - [AddToBlitterQueue]* (makes sense if there is not much to prepare)
; - TriggerBlitterQueue
; - [AppendToRunningBlitterQueue, do more CPU based stuff]*
; - TerminateBlitterQueue
; - JoinBlitterQueue
; - VSyncWithTask
;
; Each blit is stored in a BlitterQueueNode with consists of a
; linking pointer (singly linked list) and the pointer to routine
; for setting up the next blit.
; Optional parameters should follow after this field and are
; available to the callee via a0.
;
; When called, a5/a6 are filled with standard values ($dff000 and
; framework base address). a0 points to bq_Data,
; a1 holds the address of the routine stored in bq_Routine.
;
; Your routine may trash a0/a1/d0, all other registers must be
; preserved! The Z flag at exit determines whether the blit should
; be executed synchronously (blitter hogging will be activated).
; This makes sense if the blit is very short and a context switch
; is not reasonable. Except for a blit of 1024x1024 pixels,
; setting bltsize as a last instruction before RTS will clear Z
; and make the routine asynchronous. If you want it synchroneously,
; the last instruction before RTS could be a moveq.l #0,d0.
; In this case you must ensure the blitter is NOT running when
; your routine exits (e.g. with a blitter wait).
;
; Usually your routine MUST start the blitter -- the only exception
; is when setting the Z condition code at the exit of the routine.
; This can be used e.g. for common setup (like for line drawing)
; to reduce the amount of work done in a series of blits.
; You can also issue a BLTWAIT as the last "instruction" of your
; routine to make it a synchronous blit (no context switch).
;
; If you are absolutely sure that no routine of your main code loop
; will modify a5 or a6 while the blitter queue is running, you may
; turn on the FW_A5_A6_UNTOUCHED switch, which will reduce the
; context switch time even further by not saving/loading/restoring
; these two registers during the interrupt.
; (Otherwise, disabling interrupts for the periods where you need to
; modify a5/a6 may be an option, if the routines don't take too long)
;
; Amiga effects are supposed to be one-frame :) Your blitter queue
; must start its last blit before the vertical blank. Otherwise,
; havoc will happen.
; If you plan to use blitter queues that span several frames,
; please be aware that you need to call SetBlitterQueueMultiFrame,
; which is slightly slower because it will check which interrupt
; occurred. Otherwise please call SetBlitterQueueSingleFrame once.
;
; Blitter queues may NOT be combined with Blitter tasks for obvious
; reasons, but having background tasks and calling VSyncWithTask
; is perfectly fine, IF you make sure that you have joined the queue
; with JoinBlitterQueue before calling VSyncWithTask.
;
; To start a new blit, it takes around 3/4 of a raster line in ideal
; conditions. Calculate with an overhead of one rasterline per blit.
;
; Advanced use:
; You can modify fw_BlitterQueueReadPtr(a6) within a routine for
; branching and looping etc. by changing the next queue node to be
; executed. If you want to terminate the queue, don't set it to
; zero directly, but point it to a node with bq_Next set to zero
; and an empty (not null!) routine. Note that this only works
; reliably for blitter queues that are not extended while running!
;--------------------------------------------------------------------
; Adds a node to blitter queue
;
; This call will not start (trigger) the queue!
; If the queue is already being processed, it should append the
; node for later execution -- however, due to race conditions
; it is better to use AppendToBlitterQueue, which will also
; again trigger the queue if it ran out of blits.
;
; Each BlitterQueueNode should be entered with an empty bq_Next
; field (bq_Next may be random if at least the LAST node has it
; set to zero and the queue is not yet running!) and
; a bq_Routine pointer to a routine to be called.
;
; Note: there is also a macro ADD_TO_BLITTER_QUEUE to inline the
; adding for even more speed, but in this case the queue
; must not be empty!
;
; In: a0 = BlitterQueueNode
; Trashes: a1
;
fw_AddToBlitterQueue:
lea fw_BlitterQueueWritePtr(a6),a1
tst.l (a1)
beq.s .first
move.l (a1),a1
PUTMSG 50,<"Add BQ Next %p after %p">,a0,a1
move.l a0,(a1) ; bq_Next
move.l a0,fw_BlitterQueueWritePtr(a6)
rts
.first PUTMSG 50,<"Add BQ Init %p First">,a0
move.l a0,(a1)+ ; fw_BlitterQueueWritePtr
move.l a0,(a1)+ ; fw_BlitterQueueHeadPtr
rts
;--------------------------------------------------------------------
; Appends a blitter node to a previously triggered queue
;
; Given a running blitter queue, this call will attempt to add a node
; to it.
; If the queue has run out of stuff to do, it will retrigger the
; queue automatically.
; If the last blit was still running, it will resume interrupt driven
; blitting (in fact, this also works with running blits that were not
; started from a blitter queue!).
;
; This call is slightly more complex than AddToBlitterQueue, so
; choose wisely.
; In: a0 = BlitterQueueNode
; Trashes: a0/a1/d0
;
fw_AppendToRunningBlitterQueue:
PUTMSG 50,<"Append Head/Write/Read %p %p %p">,fw_BlitterQueueHeadPtr(a6),fw_BlitterQueueWritePtr(a6),fw_BlitterQueueReadPtr(a6)
pea .restints(pc)
DISABLE_INTS
tst.l fw_BlitterQueueHeadPtr(a6)
bne.s fw_AddToBlitterQueue
tst.l fw_BlitterQueueReadPtr(a6)
bne.s fw_AddToBlitterQueue
bsr.s fw_AddToBlitterQueue
btst #DMAB_BLTDONE-8,dmaconr(a5)
beq.s fw_TriggerBlitterQueue
PUTMSG 50,<"Install IRQ %p %p %p">,fw_BlitterQueueHeadPtr(a6),fw_BlitterQueueWritePtr(a6),fw_BlitterQueueReadPtr(a6)
move.w #INTF_BLIT,intreq(a5) ; clear pending blitter int
move.l fw_VBR(a6),a1
move.l fw_BlitterQueueIRQ(a6),$6c(a1)
move.w #INTF_SETCLR|INTF_BLIT,intena(a5) ; enable blitter int
lea fw_BlitterQueueHeadPtr(a6),a1
move.l (a1)+,(a1) ; fw_BlitterQueueHeadPtr -> fw_BlitterQueueReadPtr
clr.l -(a1) ; fw_BlitterQueueHeadPtr
addq.w #4,sp
btst #DMAB_BLTDONE-8,dmaconr(a5)
bne.s .restints
move.w #INTF_SETCLR|INTF_BLIT,intreq(a5) ; set pending blitter int to avoid race condition
.restints
ENABLE_INTS
rts
;--------------------------------------------------------------------
; Terminates the blitter queue list
;
; Makes sure that the adding new nodes to will not contribute to a
; running blitter queue. Must be called before starting a new queue.
;
fw_TerminateBlitterQueue:
clr.l fw_BlitterQueueWritePtr(a6)
rts
;--------------------------------------------------------------------
; Setup the blitter queue for multiple frames
;
; Selects the slightly slower interrupt routine that allows spilling
; of interrupt driven blits across a VBL.
;
; Either this function or SetBlitterQueueSingleFrame must be called
; at least once!
;
; NOTE: Even if you have a multi-frame blitter queue set up, you may
; NOT use VSyncWithTask unless you made sure the queue has been
; processed by calling JoinBlitterQueue. You still can call VSync
; of course.
;
; Trashes: a0
;
fw_SetBlitterQueueMultiFrame:
lea fw_blitter_queue_multiframe_irq(pc),a0
move.l a0,fw_BlitterQueueIRQ(a6)
rts
;--------------------------------------------------------------------
; Setup the blitter queue for multiple frames
;
; Selects the slightly faster interrupt routine that does not care
; about a vertical blank interrupt and may crash or do fancy stuff
; if the blit before the last spills into the next frame.
;
; Either this function or SetBlitterQueueMultiFrame must be called
; at least once!
;
; Trashes: a0
;
fw_SetBlitterQueueSingleFrame:
lea fw_blitter_queue_irq(pc),a0
move.l a0,fw_BlitterQueueIRQ(a6)
rts
;--------------------------------------------------------------------
; Triggers execution of the blitter queue.
;
; Starts the current queue if it is not empty.
; Warning: You MUST make sure the blitter is NOT busy when calling
; this. It is up to you if you want to start the blitter with
; hogging or not (you can control this in your routines as well,
; of course!). Blitter hogging on makes only sense if you will have
; blits with IDLE frames!
;
; NOTE! You MUST join the blitter queue before waiting for the next
; vertical blank because a running interrupt driven blitter queue
; is not compatible with multitasking!
;
; Trashes: a0/a1/d0
;
fw_TriggerBlitterQueue:
PUTMSG 50,<"Trigger Head/Write/Read %p %p %p">,fw_BlitterQueueHeadPtr(a6),fw_BlitterQueueWritePtr(a6),fw_BlitterQueueReadPtr(a6)
move.l fw_BlitterQueueHeadPtr(a6),d0
bne.s .cont
PUTMSG 50,<"BQ empty">
rts
.cont
clr.l fw_BlitterQueueHeadPtr(a6)
move.l d0,a0
fw_TriggerCustomBlitterQueue:
PUTMSG 50,<"Exe BQ %p">,a0
move.l (a0)+,fw_BlitterQueueReadPtr(a6)
beq.s .onlyone
move.w #INTF_BLIT,intena(a5) ; disable blitter int
move.w #INTF_BLIT,intena(a5) ; disable blitter int
.allsyncloop
move.w #INTF_BLIT,intreq(a5) ; clear pending blitter int
move.l (a0)+,a1
jsr (a1)
bne.s .activate
move.l fw_BlitterQueueReadPtr(a6),a0
move.l (a0)+,fw_BlitterQueueReadPtr(a6)
bne.s .allsyncloop
.lastwasalsosync
.onlyone
cmp.l fw_BlitterQueueWritePtr(a6),d0
bne.s .noconflict
PUTMSG 50,<"Trigger caught up">
clr.l fw_BlitterQueueWritePtr(a6)
.noconflict
PUTMSG 50,<"BQ Trigger Last!">
move.l (a0)+,a1
jmp (a1)
.activate
PUTMSG 50,<"Activate!">
move.l fw_VBR(a6),a0
move.l fw_BlitterQueueIRQ(a6),$6c(a0)
move.w #INTF_SETCLR|INTF_BLIT,intena(a5) ; enable blitter int
rts
;--------------------------------------------------------------------
; Makes the blitter queue synchronous again -- no longer causes
; interrupts and will restore normal multitasking operation.
;
; The last blit might still be running when this function returns!
;
; Trashes: a0/a1/d0
;
fw_JoinBlitterQueue:
PUTMSG 50,<"Join Head/Write/Read %p %p %p">,fw_BlitterQueueHeadPtr(a6),fw_BlitterQueueWritePtr(a6),fw_BlitterQueueReadPtr(a6)
move.w #INTF_INTEN|INTF_BLIT,intena(a5) ; disable main and blitter int
move.w #INTF_INTEN|INTF_BLIT,intena(a5) ; disable main and blitter int
tst.l fw_BlitterQueueReadPtr(a6)
beq.s .done
PUTMSG 50,<"Joining blitter queue">
move.l fw_VBR(a6),a0
move.l fw_DefaultIRQ(a6),$6c(a0)
ENABLE_INTS
.retry
move.l fw_BlitterQueueReadPtr(a6),a0
PUTMSG 50,<"BQ Next %p">,a0
move.l (a0)+,fw_BlitterQueueReadPtr(a6)
beq.s .last
pea .retry(pc)
.last
move.l (a0)+,a1 ; bq_Routine
BLTHOGON
BLTWAIT
BLTHOGOFF
jmp (a1)
.done
ENABLE_INTS
rts
;--------------------------------------------------------------------
fw_blitter_queue_multiframe_irq:
btst #INTB_VERTB,$dff000+intreqr+1
bne fw_vblank_standard_irq
fw_blitter_queue_irq:
PUTMSG 50,<"BQINT %lx">,$dff000+intenar
IF FW_COPPER_IRQ_SUPPORT
btst #INTB_COPER,$dff000+intreqr+1
bne fw_copper_irq
ENDC
IF FW_A5_A6_UNTOUCHED
PUSHM d0/a0/a1
ELSE
PUSHM d0/a0/a1/a5/a6
lea $dff000,a5
move.l fw_BasePtr(pc),a6
ENDC
.retry
move.w #INTF_BLIT,intreq(a5) ; acknowledge the blitter irq.
move.l fw_BlitterQueueReadPtr(a6),a0
PUTMSG 50,<"BQ Next Head/Write/Read %p %p %p">,fw_BlitterQueueHeadPtr(a6),fw_BlitterQueueWritePtr(a6),a0
move.l (a0)+,fw_BlitterQueueReadPtr(a6)
beq.s .last
move.l (a0)+,a1 ; bq_Routine
jsr (a1)
beq.s .retry
; this has some issues regarding starvation e.g. if you're spamming
; lots of hogging zero-idle blits across VBL, e.g. music code will not execute in time.
;btst #DMAB_BLTDONE-8,dmaconr(a5)
;beq.s .retry
.finished
POPM NOBUMP
nop
rte
.last
PUTMSG 50,<"BQ Last!">
move.w #INTF_BLIT,intena(a5) ; disable blitter int
lea -4(a0),a1
cmp.l fw_BlitterQueueWritePtr(a6),a1
bne.s .noconflict
PUTMSG 50,<"Caught up">
clr.l fw_BlitterQueueWritePtr(a6)
.noconflict
move.l (a0)+,a1 ; bq_Routine
jsr (a1)
move.l fw_VBR(a6),a0
move.l fw_DefaultIRQ(a6),$6c(a0)
POPM
nop
rte

View File

@ -0,0 +1,11 @@
mfw_copperlist:
COP_MOVE diwstrt,$2c81 ; window start
COP_MOVE diwstop,$2cc1 ; window stop
COP_MOVE ddfstrt,$0038 ; bitplane start
COP_MOVE ddfstop,$00d0 ; bitplane stop
COP_MOVE bplcon0,$0200 ; turn off all bitplanes
COP_END
mfw_emptysprite:
dc.w 0,0
mfw_copperlistend:

View File

@ -0,0 +1,867 @@
;--------------------------------------------------------------------
; Load, decrunch and run the given part
;
; Searches for the given file name on disk, allocates enough memory
; to load the compressed hunks, decrunches them (maybe in-place)
; relocates the hunks, executes an optional pre-launch hook
; and finally calls the loaded part.
;
; A part may have been preloaded using PreloadPart in which case the
; loading from disk is skipped and only the allocation and decrunching
; happens.
;
; Restores the framework base to the default after execution and
; frees all memory allocated.
;
; In : a0 = filename
; Trashes: probably all registers
;
fw_ExecuteNextPart:
PUTMSG 10,<10,"%d: *** Preparing to execute next part %s ***">,fw_FrameCounterLong(a6),a0
bsr.s fw_LoadNextPart
PUSHM a0
bsr fw_CheckPrePartLaunchHook
POPM
IF FW_MUSIC_SUPPORT
PUTMSG 10,<"%d: *** Executing next part %p at music frame %d">,fw_FrameCounterLong(a6),a0,fw_MusicFrameCount-2(a6)
ELSE
PUTMSG 10,<"%d: *** Executing next part %p">,fw_FrameCounterLong(a6),a0
ENDC
jsr (a0)
IF FW_MUSIC_SUPPORT
PUTMSG 10,<"%d: *** Part finished at music frame %d",10>,fw_FrameCounterLong(a6),fw_MusicFrameCount-2(a6)
ELSE
PUTMSG 10,<"%d: *** Part finished",10>,fw_FrameCounterLong(a6)
ENDC
bsr fw_RestoreFrameworkBase
bsr fw_DropCurrentMemoryAllocations
rts
;--------------------------------------------------------------------
; Load and decrunch given part
;
; Searches for the given file name on disk, allocates enough memory
; to load the compressed hunks, decrunches them (maybe in-place)
; and relocates the hunks. Part is not executed, stores the loading
; address of first (typically code) hunk in fw_LastLoadedPart(a6).
; Note that this also allocates BSS hunks if there any.
;
; This can be used for background loading the next part.
; See also PreloadPart for an alternative without decrunching.
;
; In : a0 = filename
; Out: a0 = loading address of first hunk
; Trashes: probably all registers
;
fw_LoadNextPart:
PUTMSG 10,<10,"%d: *** Loading next part %s ***">,fw_FrameCounterLong(a6),a0
clr.l fw_LastLoadedPart(a6)
bsr fw_DropCurrentMemoryAllocations
bsr fw_FindFile
bsr fw_LoadAndDecrunchPart
move.l a0,fw_LastLoadedPart(a6)
rts
;--------------------------------------------------------------------
; Wait until next part has been loaded (and decrunched)
;
; Can be used if a background task is used to load the next part to
; to ensure the loading and decrunching has finished.
;
IF FW_MULTITASKING_SUPPORT
fw_WaitForPartLoaded:
tst.l fw_LastLoadedPart(a6)
bne.s .done
PUTMSG 10,<"%d: Part not yet fully loaded. Waiting.">,fw_FrameCounterLong(a6)
.loop bsr fw_Yield
tst.l fw_LastLoadedPart(a6)
beq.s .loop
.done rts
ENDC
;--------------------------------------------------------------------
; Check and execute the pre-part launch hook
;
; Internal function to execute a hook that is supposed to be called
; just before ExecuteNextPart starts the part after loading/decrunching.
;
; Hooks can be installed by writing fw_PrePartLaunchHook(a6).
; If this field is NULL, this function does nothing.
; fw_PrePartLaunchHook(a6) is cleared prior to executing the hook.
;
fw_CheckPrePartLaunchHook:
move.l fw_PrePartLaunchHook(a6),d0
beq.s .skip
clr.l fw_PrePartLaunchHook(a6)
move.l d0,a0
PUTMSG 10,<"Executing pre-part launch hook at %p">,a0
jmp (a0)
.skip
rts
;--------------------------------------------------------------------
; Poor-man's multi disk check
;
; Waits for a disk-change, then re-initializes the loader and reads
; the new directory. This is currently untested and might not work
; well with multiple drives.
;
; In : d0.l = First four bytes of first filename on expected disk.
;
IFEQ FW_HD_TRACKMO_MODE
fw_NextDisk:
move.l d0,fw_ExpectedFirstFileID(a6)
bsr fw_TrackloaderWaitForDiskChange
;bra.b fw_InitDos
ENDC
;--------------------------------------------------------------------
; Initializes the trackloader and reads the disk directory
fw_InitDos:
IF FW_MULTITASKING_SUPPORT
move.l fw_TrackloaderTask(a6),a1
move.b #-10,LN_PRI(a1) ; FIXME breaks things! Why?
IFNE DEBUG_DETAIL
lea .loadertask(pc),a0
move.l a0,LN_NAME(a1)
ENDC
ENDC
tst.l fw_DirBuffer(a6)
bne.s .hasmem
move.l #FW_NUM_DIRECTORY_BLOCKS*512,d0
bsr fw_AllocFast
move.l a0,fw_DirBuffer(a6)
IFEQ FW_HD_TRACKMO_MODE
move.l #'Plat',fw_ExpectedFirstFileID(a6) ; Standard ID for launcher, change ID to detect a second disk
ENDC
.hasmem
.retry
IFEQ FW_HD_TRACKMO_MODE
bsr fw_TrackloaderDiskMotorOn
ENDC
move.l fw_DirBuffer(a6),a0
PUTMSG 10,<"Directory at %p">,a0
move.l #FW_DIRECTORY_ENTRIES_OFFSET,d0 ; second block
move.l #FW_NUM_DIRECTORY_BLOCKS*512,d1
bsr fw_TrackloaderLoad
IFEQ FW_HD_TRACKMO_MODE
move.l fw_DirBuffer(a6),a0
move.l fw_ExpectedFirstFileID(a6),d0
cmp.l (a0),d0
bne.s .otherdisk
rts
.otherdisk
PUTMSG 10,<"Wrong disk %lx">,(a0)
move.w fw_CurrentDrive(a6),d0
addq.w #1,d0
move.w d0,fw_CurrentDrive(a6)
cmp.w #4,d0
bne.s .retry
move.w #ERROR_DISK,d0
bra fw_Error
ELSE
rts
ENDC
IFNE DEBUG_DETAIL
.loadertask
dc.b "Loadertask",0
even
ENDC
;--------------------------------------------------------------------
; Locates the DirEntry of a file on disk
;
; The DirEntry contains the meta-data for a file on disk
; (see framework.i).
;
; In : a0 = filename
; Out: a1 = Dir entry structure
;
fw_FindFile:
PUTMSG 10,<"Searching for %s...">,a0
move.l fw_DirBuffer(a6),a1
.restartloop
moveq.l #0,d0
.loop
move.b de_Name(a1,d0.w),d1
cmp.b (a0,d0.w),d1
bne.s .next
addq.w #1,d0
tst.b d1
beq .foundit
cmp.w #16,d0
beq .foundit
bra.s .loop
.next
PUTMSG 40,<"%s did not match">,a1
.nextline
tst.w de_Flags(a1)
bpl.s .nextentry
PUTMSG 40,<"NL">
lea de_NextHunk(a1),a1
bra.s .nextline
.nextentry
lea de_SIZEOF(a1),a1
tst.b de_Name(a1)
beq.s .notfound
PUTMSG 40,<"Next Entry %s">,a1
bra .restartloop
.notfound
PUTMSG 10,<"File %s not found">,a0
move.w #ERROR_FILE_NOT_FOUND,d0
bra fw_Error
.foundit
PUTMSG 10,<"Found %s at %p">,a1,a1
rts
;--------------------------------------------------------------------
; Allocate and load a file (filename) from disk without decrunching
;
; Allocates sufficient memory and loads the possibly compressed file
; from the directory into this memory. File will be loaded to fast
; memory if crunched, otherwise memory allocation depends on the
; flags. Note that this call is not useful for DOS hunk files.
;
; In : a0 = filename
; Out: a0 = start of loaded file in a0
; a1 = Dir entry structure of the file
;
fw_LoadFile:
bsr fw_FindFile
move.w #DEFM_PACKMODE,d0
and.w de_Flags(a1),d0
bne.s fw_LoadPlainFileEntryToFast
;--------------------------------------------------------------------
; Allocate and load a file via DirEntry from disk without decrunching
;
; Allocates sufficient memory and loads the possibly compressed file
; from the directory into this memory. File will be loaded to the
; type of memory specified in the DirEntry.
; Note that this call is not useful for DOS hunk files.
;
; In : a1 = Dir entry structure
; Out: a0 = start of loaded file in a0
; a1 = Dir entry structure of the file
;
fw_LoadPlainFileEntry:
PUTMSG 10,<"%d: Loading plain file from offset %ld, size %ld">,fw_FrameCounterLong(a6),de_DiskOffset(a1),de_DiskLength(a1)
tst.b de_Flags+1(a1)
bpl.s fw_LoadPlainFileEntryToFast
move.l de_DiskLength(a1),d0
move.l a1,-(sp)
bsr fw_AllocChip
bra.s fw_InternalLoadFileEntryToBuffer
;--------------------------------------------------------------------
; Allocate and load a file via DirEntry from disk to fast mem
;
; Allocates sufficient memory and loads the possibly compressed file
; from the directory into this memory. File will be loaded to
; fast memory, if available.
;
; In : a1 = DirEntry
; Out: a0 = start of loaded file in a0
; a1 = DirEntry of the file
;
fw_LoadPlainFileEntryToFast:
IFEQ FW_HD_TRACKMO_MODE
fw_LoadReadOnlyPlainFileEntryToFast:
ENDC
move.l de_DiskLength(a1),d0
move.l a1,-(sp)
bsr fw_AllocFast
fw_InternalLoadFileEntryToBuffer:
move.l (sp)+,a1
bsr fw_LoadFileToBuffer
move.l de_DiskLength(a1),d0
rts
IFNE FW_HD_TRACKMO_MODE
fw_LoadReadOnlyPlainFileEntryToFast:
move.l de_DiskLength(a1),d0
move.l fw_TrackBuffer(a6),a0
adda.l de_DiskOffset(a1),a0
fw_TrackloaderDiskMotorOff:
rts
ENDC
;--------------------------------------------------------------------
; Load a file from disk and decrunch it
;
; Allocates sufficient memory and loads the possibly compressed file
; from the directory into this memory. File will be decompressed to
; chip or fast memory depending on its flags.
; Allocation may be slightly bigger if file is decrunchable in-place,
; but uses no additional memory for the compressed data in this case.
;
; Note that this call is not useful for DOS hunk files.
;
; In : a0: Filename
; Out: a0: Pointer to loaded buffer
; a1: Dir entry structure
;
fw_LoadAndDecrunchFile:
bsr fw_FindFile
move.w #DEFM_PACKMODE,d0
and.w de_Flags(a1),d0
beq fw_LoadPlainFileEntry
PUTMSG 10,<"File %s is crunched">,a1
IFEQ FW_HD_TRACKMO_MODE
IF FW_ZX0_SUPPORT
btst #DEFB_IN_PLACE,de_Flags(a1)
bne.s .inplacedecrunch
ENDC
ENDC
move.l a1,-(sp) ; dir entry
move.l de_MemorySize(a1),d0
tst.b de_Flags+1(a1)
bpl.s .usefast
bsr fw_AllocChip
bra.s .allocated
.usefast
bsr fw_AllocFast
.allocated
move.l a0,-(sp) ; target buffer
IFEQ FW_HD_TRACKMO_MODE
bsr fw_PushMemoryState
move.l de_DiskLength(a1),d0
bsr fw_AllocFast
move.l 4(sp),a1 ; dir entry
bsr fw_LoadFileToBuffer
move.l (sp),a2 ; target buffer
bsr fw_DecrunchToBuffer
move.l de_MemorySize(a1),d0
bsr fw_PopMemoryState
ELSE
move.l a0,a2
move.l 4(sp),a1
move.l fw_TrackBuffer(a6),a0
adda.l de_DiskOffset(a1),a0
bsr fw_DecrunchToBuffer
move.l de_MemorySize(a1),d0
ENDC
move.l (sp)+,a0 ; target buffer
move.l (sp)+,a1 ; dir entry
rts
IFEQ FW_HD_TRACKMO_MODE
IF FW_ZX0_SUPPORT
.inplacedecrunch
bsr.s fw_AllocInPlaceDecrunchBuffer
PUSHM a0
bsr.s fw_LoadAndInPlaceDecrunchToBuffer
POPM
rts
ENDC
ENDC
;--------------------------------------------------------------------
; Allocate buffer big enough to hold decrunched data + safety distance
;
; In : a1 = dir entry (preserved)
; Out: a0 = buffer
;
fw_AllocInPlaceDecrunchBuffer:
PUSHM a1
move.l de_MemorySize(a1),d0
addq.l #1,d0
and.w #-2,d0
add.l #FW_IN_PLACE_DECR_SAFE_DIST,d0
tst.b de_Flags+1(a1)
bpl.s .usefast2
bsr fw_AllocChip
bra.s .allocated2
.usefast2
bsr fw_AllocFast
.allocated2
POPM
rts
;--------------------------------------------------------------------
; Loads a crunched file to the end of a pre-allocated buffer and decrunches it in-place
;
; In : a0 = target buffer (memory size of decrunched + safety distance)
; a1 = dir entry (preserved)
; Out: a0 = end of decrunched buffer
;
fw_LoadAndInPlaceDecrunchToBuffer:
move.l a0,-(sp)
move.l de_DiskLength(a1),d0
addq.l #1,d0
and.w #-2,d0
lea FW_IN_PLACE_DECR_SAFE_DIST(a0),a0
move.l de_MemorySize(a1),d1
addq.l #1,d1
and.w #-2,d1
adda.l d1,a0
suba.l d0,a0
bsr fw_LoadFileToBuffer
move.l (sp)+,a2 ; target buffer
;bra.s fw_DecrunchToBuffer
;--------------------------------------------------------------------
; Decrunches the given file to the target buffer
;
; In : a0 = source buffer
; a1 = Dir entry structure
; a2 = target buffer
; Out: a0 = END of the buffer written
; a1 = Dir entry structure
;
fw_DecrunchToBuffer:
PUSHM a1/a2
move.w #DEFM_PACKMODE,d0
and.w de_Flags(a1),d0
IF FW_DOYNAX_SUPPORT
cmp.w #DEFF_DOYNAX,d0
bne.s .nodoynax
PUTMSG 10,<"%d: DoynaxDecrunch from %p (%ld) to %p (%ld)">,fw_FrameCounterLong(a6),a0,de_DiskLength(a1),a2,de_MemorySize(a1)
move.l a2,a1
bsr doynaxdepack
bra .decdone
.nodoynax
ENDC
IF FW_ZX0_SUPPORT
cmp.w #DEFF_ZX0,d0
bne.s .nozx0
PUTMSG 10,<"%d: ZX0Decrunch from %p (%ld) to %p (%ld)">,fw_FrameCounterLong(a6),a0,de_DiskLength(a1),a2,de_MemorySize(a1)
move.l a2,a1
bsr zx0_decompress
bra.s .decdone
.nozx0
ENDC
IF FW_LZ4_SUPPORT
cmp.w #DEFF_LZ4,d0
bne.s .nolz4
move.l de_DiskLength(a1),d0
PUTMSG 10,<"%d: LZ4Decrunch from %p (%ld) to %p (%ld)">,fw_FrameCounterLong(a6),a0,d0,a2,de_MemorySize(a1)
move.l a2,a1
bsr lz4_depack
bra.s .decdone
.nolz4
ENDC
move.w #ERROR_INVALID_PARAMS,d0
bra fw_Error
.decdone
move.l a1,a0
POPM
move.w #DEFM_DELTAMODE,d0
and.w de_Flags(a1),d0
beq.s .nodelta
cmp.w #DEFF_DELTA8,d0
beq.s .delta8
move.w #ERROR_INVALID_PARAMS,d0
bra fw_Error
.delta8
PUSHM a2
move.l de_MemorySize(a1),d0
beq.s .d8done
PUTMSG 10,<"%d: Delta8 decoding %p %ld bytes">,fw_FrameCounterLong(a6),a2,d0
moveq.l #0,d1
subq.l #1,d0
.d8loop
add.b (a2),d1
move.b d1,(a2)+
dbra d0,.d8loop
swap d0
subq.w #1,d0
bcs.s .d8done
swap d0
bra.s .d8loop
.d8done
POPM
.nodelta
PUTMSG 10,<"%d: Decrunching done">,fw_FrameCounterLong(a6)
rts
;--------------------------------------------------------------------
; Loads the file into the given buffer
;
; In : a0 = buffer (preserved)
; a1 = Dir entry structure (preserved)
;
fw_LoadFileToBuffer:
PUSHM a0-a3
move.l de_DiskOffset(a1),d0
move.l de_DiskLength(a1),d1
PUTMSG 10,<"%d: Loading file %p to buffer %p (%ld)">,fw_FrameCounterLong(a6),a1,a0,d1
bsr fw_TrackloaderLoad
POPM
rts
;--------------------------------------------------------------------
; Loads and uncompresses the (LZ4) file into the given buffer
;
; Loads and decrunches the given LZ4 or LZ4 delta compressed file while
; loading it from disk -- needs no extra memory.
;
; In : a0 = target buffer
; a1 = Dir entry structure
; Out: a1 = end of decrunching pointer
;
fw_TrackmoLoadAndDecrunchToBuffer:
PUTMSG 10,<"%d: Trackmo Loading and Decrunching %p">,fw_FrameCounterLong(a6),a1
move.w #DEFM_PACKMODE,d0
and.w de_Flags(a1),d0
IF FW_TRACKMO_LZ4_SUPPORT|FW_TRACKMO_LZ4_DLT8_SUPPORT
cmp.w #DEFF_LZ4,d0
bne.s .nolz4
move.l de_DiskOffset(a1),d0
move.l de_DiskLength(a1),d1
move.w #DEFM_DELTAMODE,d2
and.w de_Flags(a1),d2
IF FW_TRACKMO_LZ4_SUPPORT
cmp.w #DEFF_NODELTA,d2
beq fw_TrackloaderLoadAndDecrunchLZ4
ENDC
IF FW_TRACKMO_LZ4_DLT8_SUPPORT
cmp.w #DEFF_DELTA8,d2
beq fw_TrackloaderLoadAndDecrunchLZ4Delta8
ENDC
.nolz4
ENDC
.error
move.w #ERROR_INVALID_PARAMS,d0
bra fw_Error
;--------------------------------------------------------------------
; Load and decrunch a part
;
; Reads, allocates, decrunches and relocates all hunks for the given
; directory entry.
;
; In : a1 = Dir entry structure
; Out: a0 = launch address of first hunk
;
fw_LoadAndDecrunchPart:
move.l d7,-(sp)
PUTMSG 10,<"%d: Loading and Decrunching %p">,fw_FrameCounterLong(a6),a1
tst.b de_NumHunks(a1)
bne.s .cont
.b0rked
move.w #ERROR_HUNKBROKEN,d0
bra fw_Error
.cont
move.l a1,a2 ; backup top of the dir entries
lea fw_HunkPointers(a6),a3
.hunkallocloop
moveq.l #0,d7
move.b de_HunkNum(a1),d7
lsl.w #2,d7
PUTMSG 30,<"HunkSize %lx">,de_MemorySize(a1)
move.l de_MemorySize(a1),d0
beq.s .skipthat
btst #DEFB_IN_PLACE,de_Flags(a1)
beq.s .noinplace
add.l #FW_IN_PLACE_DECR_SAFE_DIST,d0
.noinplace
; allocate hunk
PUSHM a1-a3
tst.b de_Flags+1(a1)
bpl.s .nochipmem
bsr fw_AllocChip
bra.s .gotmem
.nochipmem
bsr fw_AllocFast
.gotmem
POPM
move.l a0,(a3,d7.w)
.skipthat
tst.w de_Flags(a1)
bpl.s .hunksallocated
lea de_NextHunk(a1),a1
bra.s .hunkallocloop
.hunksallocated
move.l a2,a1 ; start over
.hunkloadloop
moveq.l #0,d7
move.b de_HunkNum(a1),d7
PUTMSG 10,<"Hunk num %d">,d7
lsl.w #2,d7
moveq.l #DEFM_TYPE,d0
and.w de_Flags(a1),d0
cmp.w #DEFF_HUNK_CODE,d0
beq.s .codedata
cmp.w #DEFF_HUNK_DATA,d0
beq.s .codedata
cmp.w #DEFF_HUNK_BSS,d0
beq .justclear
cmp.w #DEFF_HUNK_RELOC,d0
beq .reloc
bra .b0rked
.codedata
move.w #DEFM_PACKMODE,d0
and.w de_Flags(a1),d0
beq .unpacked
move.l fw_PreloadHunkPointers-fw_HunkPointers(a3,d7.w),d1
beq.s .loadpacked
PUSHM a2-a3
move.l (a3,d7.w),a2
move.l d1,a0
clr.l fw_PreloadHunkPointers-fw_HunkPointers(a3,d7.w)
PUTMSG 10,<"Decrunching packed data from preload buffer %p to %p">,a0,a2
bsr fw_DecrunchToBuffer
POPM
bra .clearmem
.loadpacked
IF FW_ZX0_SUPPORT
btst #DEFB_IN_PLACE,de_Flags(a1)
bne.s .inplacedecrunch
ENDC
IF FW_LZ4_SUPPORT
IF FW_TRACKMO_LZ4_SUPPORT
cmp.w #DEFF_LZ4,d0
beq .trackloadlz4
ELSE
cmp.w #DEFF_LZ4,d0
beq.s .genericdecrunch
ENDC
ENDC
IF FW_ZX0_SUPPORT
cmp.w #DEFF_ZX0,d0
beq.s .genericdecrunch
ENDC
IF FW_DOYNAX_SUPPORT
cmp.w #DEFF_DOYNAX,d0
beq.s .genericdecrunch
ENDC
bra .b0rked
IF FW_ZX0_SUPPORT|FW_DOYNAX_SUPPORT|(FW_LZ4_SUPPORT&!FW_TRACKMO_LZ4_SUPPORT)
.genericdecrunch
bsr fw_PushMemoryState
PUSHM a1-a3
bsr fw_LoadPlainFileEntryToFast
POPM
PUSHM a1-a3
move.l (a3,d7.w),a2 ; target buffer
bsr fw_DecrunchToBuffer
POPM
bsr fw_PopMemoryState
bra .clearmem
ENDC
IF FW_ZX0_SUPPORT
.inplacedecrunch
PUTMSG 10,<"%d: In-place loading and decrunching %ld bytes to %p (%d)">,fw_FrameCounterLong(a6),de_DiskLength(a1),a0,d7
PUSHM a1-a3
move.l (a3,d7.w),a0
bsr fw_LoadAndInPlaceDecrunchToBuffer
POPM
bra .clearmem
ENDC
IF FW_TRACKMO_LZ4_SUPPORT
.trackloadlz4
move.l (a3,d7.w),a0
PUSHM a1-a3
PUTMSG 10,<"%d: LZ4 loading and decrunching %ld bytes to %p (%d)">,fw_FrameCounterLong(a6),de_DiskLength(a1),a0,d7
bsr fw_TrackmoLoadAndDecrunchToBuffer
move.l a1,a0
POPM
bra .clearmem
ENDC
.unpacked
move.l fw_PreloadHunkPointers-fw_HunkPointers(a3,d7.w),d0
beq.s .loadunpacked
move.l d0,a0
clr.l fw_PreloadHunkPointers-fw_HunkPointers(a3,d7.w)
PUTMSG 10,<"Copying unpacked data from preload buffer %p">,a0
move.l de_DiskLength(a1),d0
subq.l #1,d0
bmi.s .clearunpacked
lsr.w #2,d0
move.l (a3,d7.w),a2
.upcopyloop
move.l (a0)+,(a2)+
dbra d0,.upcopyloop
bra.s .clearunpacked
.loadunpacked
move.l (a3,d7.w),a0
bsr fw_LoadFileToBuffer
.clearunpacked
move.l de_MemorySize(a1),d0
move.l de_DiskLength(a1),d1
sub.l d1,d0
move.l (a3,d7.w),a0
adda.l d1,a0
bra .clearit
.justclear
move.l (a3,d7.w),a0
move.l de_MemorySize(a1),d0
bra .clearit
.clearmem
move.l (a3,d7.w),d0
add.l de_MemorySize(a1),d0
PUTMSG 10,<"%d: End of buffer %p, expected %p, memory size %ld">,fw_FrameCounterLong(a6),a0,d0,de_MemorySize(a1)
sub.l a0,d0 ; bytes to clear
.clearit
tst.l d0
bmi fw_Error
lsr.l #2,d0
beq.s .checknexthunk
PUTMSG 10,<"Clearing %d longs at end of buffer %p">,d0,a0
subq.w #1,d0
moveq.l #0,d1
.clearloop
move.l d1,(a0)+
dbra d0,.clearloop
.checknexthunk
tst.b de_Flags(a1)
bpl .hunksloaded
lea de_NextHunk(a1),a1
bra .hunkloadloop
.reloc
move.l fw_PreloadRelocHunkPointers-fw_HunkPointers(a3,d7.w),d0
beq.s .loadreloc
move.l d0,a0
clr.l fw_PreloadRelocHunkPointers-fw_HunkPointers(a3,d7.w)
PUTMSG 10,<"Doing Reloc from preloaded data %p">,a0
PUSHM a1
bsr .doreloc
POPM
bra.s .checknexthunk
.loadreloc
bsr fw_PushMemoryState
PUSHM a1-a3
move.l a3,-(sp)
bsr fw_LoadReadOnlyPlainFileEntryToFast
move.l (sp)+,a3
bsr .doreloc
POPM
bsr fw_PopMemoryState
bra .checknexthunk
.hunksloaded
bsr fw_FlushCaches
move.l (sp)+,d7
move.l fw_HunkPointers(a6),a0
rts
.doreloc
move.l (a3,d7.w),a1 ; target-hunk
PUTMSG 40,<"Relocating for target hunk %p (%d)">,a1,d7
.hunkrelloop
move.w (a0)+,d0
beq.s .hunkrelocend
move.w (a0)+,d1 ; source-hunk
PUTMSG 50,<"%d offsets for hunk %d">,a0,d1
subq.w #1,d0
lsl.w #2,d1
move.l (a3,d1.w),d2 ; source_hunk offset
.offsetsloop
moveq.l #0,d1
move.w (a0)+,d1 ; offset
add.l d1,d1
add.l d2,(a1,d1.l) ; patch offset into target-hunk
dbra d0,.offsetsloop
bra.s .hunkrelloop
.hunkrelocend
rts
;--------------------------------------------------------------------
; Loads the next part into memory without decrunching or executing it
;
; Preloads a part that will be almost instantly executed when calling
; ExecuteNextPart (because only the decrunching will be done).
;
; This function is usually called from a background task with memory
; allocation direction flipped. Note that the filename given here and
; later to ExecuteNextPart must match exactly, otherwise, bad things
; will happen.
;
; In : a0 = filename
;
fw_PreloadPart:
IFEQ FW_HD_TRACKMO_MODE
bsr fw_FindFile
move.l d7,-(sp)
PUTMSG 10,<"%d: Preparing loading and decrunching of %p">,fw_FrameCounterLong(a6),a1
tst.b de_NumHunks(a1)
bne.s .cont
.b0rked
move.w #ERROR_HUNKBROKEN,d0
bra fw_Error
.cont
lea fw_PreloadHunkPointers(a6),a2
lea fw_PreloadRelocHunkPointers(a6),a3
.hunkloadloop
moveq.l #0,d7
move.b de_HunkNum(a1),d7
PUTMSG 10,<"Hunk num %d">,d7
lsl.w #2,d7
moveq.l #DEFM_TYPE,d0
and.w de_Flags(a1),d0
cmp.w #DEFF_HUNK_CODE,d0
beq.s .codedata
cmp.w #DEFF_HUNK_DATA,d0
beq.s .codedata
cmp.w #DEFF_HUNK_BSS,d0
beq.s .ignorehunk
cmp.w #DEFF_HUNK_RELOC,d0
bne .b0rked
PUSHM a1-a3
bsr fw_LoadPlainFileEntryToFast
POPM
move.l a0,(a3,d7.w)
bra.s .loaded
.codedata
PUSHM a1-a3
bsr fw_LoadPlainFileEntryToFast
POPM
move.l a0,(a2,d7.w)
.loaded
.ignorehunk
tst.b de_Flags(a1)
bpl .hunksloaded
lea de_NextHunk(a1),a1
bra .hunkloadloop
.hunksloaded
move.l (sp)+,d7
ENDC
rts

View File

@ -0,0 +1,77 @@
;--------------------------------------------------------------------
; Trackdisk loader replacement for harddisk/filedemo loading
;
; In : a0: buffer to load the data into
; d0: disk starting offset
; d1: length in bytes
;
fw_TrackloaderLoad:
PUTMSG 10,<"TrackloaderLoad to %p (%ld bytes)">,a0,d0
move.l fw_TrackBuffer(a6),a1
adda.l d0,a1
addq.l #1,d1
and.w #-2,d1
btst #1,d1
beq.s .nooddword
move.w (a1)+,(a0)+
subq.l #2,d1
.nooddword
subq.l #1,d1
lsr.l #2,d1
.cpyloop
move.l (a1)+,(a0)+
dbra d1,.cpyloop
rts
;--------------------------------------------------------------------
; Load LZ4 compressed data from disk and decompress it while loading
;
; In : a0: buffer to load the data into
; d0: disk starting offset
; d1: compressed length in bytes
;
IF FW_TRACKMO_LZ4_SUPPORT
fw_TrackloaderLoadAndDecrunchLZ4:
PUTMSG 10,<"TrackloaderLoadAndDecrunchLZ4 to %p (%ld bytes)">,a0,d1
move.l fw_TrackBuffer(a6),a1
adda.l d0,a1
exg a0,a1
move.l d1,d0
bra lz4_depack
ENDC
;--------------------------------------------------------------------
; Load LZ4 and delta compressed data from disk and decompress it while loading
;
; In : a0: buffer to load the data into
; d0: disk starting offset
; d1: compressed length in bytes
;
IF FW_TRACKMO_LZ4_DLT8_SUPPORT
fw_TrackloaderLoadAndDecrunchLZ4Delta8:
PUTMSG 10,<"TrackloaderLoadAndDecrunchLZ4Delta8 to %p (%ld bytes)">,a0,d1
move.l fw_TrackBuffer(a6),a1
adda.l d0,a1
move.l d1,d0
PUSHM a0
exg a0,a1
bsr lz4_depack
POPM
move.l a1,d0
sub.l a0,d0
PUTMSG 10,<"Delta8 decoding %p %ld bytes">,a2,d0
moveq.l #0,d1
subq.l #1,d0
bmi.s .d8done
.d8loop
add.b (a0),d1
move.b d1,(a0)+
dbra d0,.d8loop
swap d0
subq.w #1,d0
bcs.s .d8done
swap d0
bra.s .d8loop
.d8done
rts
ENDC

View File

@ -0,0 +1,93 @@
FWLVOPOS SET 0
DEFFWFUNC InitPart
DEFFWFUNC RestoreFrameworkBase
DEFFWFUNC Error
DEFFWFUNC FlushCaches
DEFFWFUNC SetBaseCopper
DEFFWFUNC SetCopper
DEFFWFUNC VSync
DEFFWFUNC WaitForFrame
IF FW_DYNAMIC_MEMORY_SUPPORT
DEFFWFUNC PushMemoryState
DEFFWFUNC PopMemoryState
DEFFWFUNC AllocChip
IF FW_64KB_PAGE_MEMORY_SUPPORT
DEFFWFUNC AllocChip64KB
ENDC
DEFFWFUNC AllocFast
DEFFWFUNC DropCurrentMemoryAllocations
IF FW_TOP_BOTTOM_MEM_SECTIONS
DEFFWFUNC FlipAllocationDirection
ENDC
ENDC
IF (FW_STANDALONE_FILE_MODE==0)|FW_HD_TRACKMO_MODE
DEFFWFUNC FindFile
DEFFWFUNC LoadFile
DEFFWFUNC LoadAndDecrunchFile
DEFFWFUNC LoadFileToBuffer
DEFFWFUNC DecrunchToBuffer
DEFFWFUNC TrackmoLoadAndDecrunchToBuffer
DEFFWFUNC TrackloaderDiskMotorOff
ENDC
IF FW_MUSIC_SUPPORT
DEFFWFUNC StartMusic
DEFFWFUNC StopMusic
ENDC
IF FW_MULTITASKING_SUPPORT
DEFFWFUNC AddTask
DEFFWFUNC RemTask
DEFFWFUNC VSyncWithTask
DEFFWFUNC Yield
DEFFWFUNC WaitUntilTaskFinished
IF FW_BLITTERTASK_MT_SUPPORT
DEFFWFUNC AddAndRunBlitterTask
DEFFWFUNC YieldToBlitterTask
DEFFWFUNC FinishBlitterTask
ENDC
ELSE
IFEQ FWGENLVOTABLE
_LVOFrameWorkVSyncWithTask = _LVOFrameWorkVSync
ENDC
ENDC
IF FW_PALETTE_LERP_SUPPORT
DEFFWFUNC InitPaletteLerp
DEFFWFUNC InitPaletteLerpSameColor
DEFFWFUNC FadePaletteTo
DEFFWFUNC DoFadePaletteStep
ENDC
IF FW_SCRIPTING_SUPPORT
DEFFWFUNC InstallScript
DEFFWFUNC CheckScript
IF FW_MUSIC_SUPPORT
DEFFWFUNC InstallMusicScript
DEFFWFUNC CheckMusicScript
ENDC
ENDC
IF FW_BLITTERQUEUE_SUPPORT
DEFFWFUNC AddToBlitterQueue
DEFFWFUNC SetBlitterQueueMultiFrame
DEFFWFUNC SetBlitterQueueSingleFrame
DEFFWFUNC TriggerBlitterQueue
DEFFWFUNC TriggerCustomBlitterQueue
DEFFWFUNC JoinBlitterQueue
DEFFWFUNC TerminateBlitterQueue
ENDC
IF FW_LZ4_SUPPORT
DEFFWFUNC DecompressLZ4
ENDC
IF FW_ZX0_SUPPORT
DEFFWFUNC DecompressZX0
ENDC
IF FW_DOYNAX_SUPPORT
DEFFWFUNC DecompressDoynax
ENDC

View File

@ -0,0 +1,214 @@
IFND FRAMEWORK_MACROS_I
FRAMEWORK_MACROS_I SET 1
IFD FW_DEMO_PART
CALLFW MACRO
jsr _LVOFrameWork\1(a6)
ENDM
ELSE
CALLFW MACRO
bsr fw_\1
ENDM
ENDC
DEFFWFUNC MACRO
IF FWGENLVOTABLE
dc.w fw_\1-*
ELSE
FWLVOPOS SET FWLVOPOS-6
IFND _LVOFrameWork\1
_LVOFrameWork\1 = FWLVOPOS
ENDC
ENDC
ENDM
DISABLE_INTS MACRO
; do this twice so to be sure that it has propagated to IPL and we really don't get an interrupt
move.w #INTF_INTEN,intena(a5)
move.w #INTF_INTEN,intena(a5)
ENDM
ENABLE_INTS MACRO
move.w #INTF_SETCLR|INTF_INTEN,intena(a5)
ENDM
;Blitter logic macros
;& (bitwise and)
;^ (bitwise exclusive-or)
;| (bitwise inclusive-or)
;~ (bitwise not)
; idle cycles for normal operation (not line or fill!)
BLTEN_A = $0800 ; 1 idle cycle
BLTEN_B = $0400 ; 2 idle cycles
BLTEN_C = $0200 ; 1 idle cycle
BLTEN_D = $0100 ; 1 idle cycle
BLTEN_AD = (BLTEN_A|BLTEN_D) ; NO idle cycle
BLTEN_BD = (BLTEN_B|BLTEN_D) ; 1 idle cycle
BLTEN_CD = (BLTEN_C|BLTEN_D) ; 1 idle cycle
BLTEN_ABD = (BLTEN_A|BLTEN_B|BLTEN_D) ; NO idle cycle
BLTEN_ACD = (BLTEN_A|BLTEN_C|BLTEN_D) ; NO idle cycle
BLTEN_BCD = (BLTEN_B|BLTEN_C|BLTEN_D) ; 1 idle cycle
BLTEN_ABCD = (BLTEN_A|BLTEN_B|BLTEN_C|BLTEN_D) ; NO idle cycle
BLTEN_AB = (BLTEN_A|BLTEN_B) ; 1 idle cycle
BLTEN_AC = (BLTEN_A|BLTEN_C) ; NO idle cycle
BLTEN_BC = (BLTEN_B|BLTEN_C) ; 1 idle cycle
BLTEN_ABC = (BLTEN_A|BLTEN_B|BLTEN_C) ; NO idle cycle
BLT_A = %11110000
BLT_B = %11001100
BLT_C = %10101010
BLTHOGON MACRO
move.w #DMAF_SETCLR|DMAF_BLITHOG,dmacon(a5)
ENDM
BLTHOGOFF MACRO
move.w #DMAF_BLITHOG,dmacon(a5)
ENDM
BLTWAIT MACRO
.bw\@
btst #DMAB_BLTDONE-8,dmaconr(a5)
bne.s .bw\@
ENDM
;--------------------------------------------------------------------
; channels, minterm, shift a, shift b, (optional: target)
BLTCON_SET MACRO
; write both bltcon0/bltcon1
IFNC '\5',''
move.l #(((BLTEN_\1+((\2)&$ff))|(\3<<12))<<16)|(\4<<12),\5
ELSE
move.l #(((BLTEN_\1+((\2)&$ff))|(\3<<12))<<16)|(\4<<12),bltcon0(a5)
ENDC
ENDM
; channels, minterm, shift a, (optional: target)
BLTCON0_SET MACRO
; write only bltcon0
IFNC '\4',''
move.w #((BLTEN_\1+((\2)&$ff))|(\3<<12)),\4
ELSE
move.w #((BLTEN_\1+((\2)&$ff))|(\3<<12)),bltcon0(a5)
ENDC
ENDM
; channels, minterm, shift a, shift b, bltcon1 flags, (optional: target)
BLTCON_SET_X MACRO
; write both bltcon0/bltcon1
IFNC '\6',''
move.l #(((BLTEN_\1+((\2)&$ff))|(\3<<12))<<16)|(\4<<12)|(\5),\6
ELSE
move.l #(((BLTEN_\1+((\2)&$ff))|(\3<<12))<<16)|(\4<<12)|(\5),bltcon0(a5)
ENDC
ENDM
; issue blitter wait to copper list (in a0)
COPBLITWAIT MACRO
move.l #COP_WAITBLIT_DATA,(a0)+
move.l #COP_WAITBLIT_DATA,(a0)+ ; avoid OCS hardware bug
ENDM
; issue immediate write of register to copper list (in a0)
COPIMOVE MACRO
move.l #((\2)<<16)|((\1)&$ffff),(a0)+
ENDM
; issue register (or ea) write of register to copper list (in a0)
COPRMOVE MACRO
move.w #\2,(a0)+
move.w \1,(a0)+
ENDM
; write 32 bit pointer to register pair to copper list (in a0) using temp data register
COPPTMOVE MACRO
move.l \1,\3
swap \3
move.w #\2,(a0)+
move.w \3,(a0)+
move.w #(\2)+2,(a0)+
move.w \1,(a0)+
ENDM
; reuse temp register of COPPTMOVE to write the same pointer to more register pairs
COPPTMOVEMORE MACRO
move.w #\2,(a0)+
move.w \3,(a0)+
move.w #(\2)+2,(a0)+
move.w \1,(a0)+
ENDM
; write 32 bit pointer in data register to register pair to copper list (in a0)
COPDPTMOVE MACRO
swap \1
move.w #\2,(a0)+
move.w \1,(a0)+
swap \1
move.w #(\2)+2,(a0)+
move.w \1,(a0)+
ENDM
IF FW_BLITTERQUEUE_SUPPORT
; shortcut macro for AddToBlitterQueue (queue must NOT be empty!)
; first parameter: node
; second parameter: scratch address register
ADD_TO_BLITTER_QUEUE MACRO
move.l fw_BlitterQueueWritePtr(a6),\2
move.l \1,(\2)
move.l \1,fw_BlitterQueueWritePtr(a6)
ENDM
; the following macros are for a series of blits,
; shortcut macro for AddToBlitterQueue (queue must NOT be empty!)
; parameter: register that is used for storing the previous node pointer
PREP_ADD_TO_BLITTER_QUEUE MACRO
move.l fw_BlitterQueueWritePtr(a6),\1
ENDM
; shortcut macro for AddToBlitterQueue (queue MUST be empty!), replaces PREP_ADD_TO_BLITTER_QUEUE
; first parameter: node
; second parameter: register that is used for storing the previous node pointer
FIRST_ADD_TO_BLITTER_QUEUE MACRO
move.l \1,\2
ENDM
; shortcut macro for AddToBlitterQueue (queue must NOT be empty!)
; first parameter: node
; second parameter: register that is used for storing the previous node pointer
FAST_ADD_TO_BLITTER_QUEUE MACRO
move.l \1,(\2)
move.l \1,\2
ENDM
; shortcut macro for AddToBlitterQueue (queue MAY be empty!)
; first parameter: node
; second parameter: register that is used for storing the previous node pointer
SAFE_ADD_TO_BLITTER_QUEUE MACRO
tst.l fw_BlitterQueueWritePtr(a6)
beq.s .isfirst\@
move.l fw_BlitterQueueWritePtr(a6),\2
move.l \1,(\2)
.isfirst\@
move.l \1,\2
ENDM
; shortcut macro for AddToBlitterQueue (queue must NOT be empty!)
; first parameter: node
; second parameter: register that is used for storing the previous node pointer
LAST_ADD_TO_BLITTER_QUEUE MACRO
move.l \1,(\2)
move.l \1,fw_BlitterQueueWritePtr(a6)
ENDM
; shortcut macro for AddToBlitterQueue
; parameter: register that is used for storing the previous node pointer
TERM_ADD_TO_BLITTER_QUEUE MACRO
move.l \1,fw_BlitterQueueWritePtr(a6)
ENDM
TERMINATE_BLITTER_QUEUE MACRO
clr.l fw_BlitterQueueWritePtr(a6)
ENDM
ENDC
ENDC ; FRAMEWORK_MACROS_I

View File

@ -0,0 +1,534 @@
;--------------------------------------------------------------------
DEBUGMEM MACRO
IFGE DEBUG_DETAIL-10
bsr fw_DebugMemoryManagement
ENDC
ENDM
;--------------------------------------------------------------------
; Initializes the memory stacks for chip- and fast-mem
;
fw_InitMemoryManagement:
move.l fw_ChipMemStack(a6),d0
move.l fw_ChipMemStackEnd(a6),d1
move.l fw_FastMemStack(a6),d2
move.l fw_FastMemStackEnd(a6),d3
PUTMSG 10,<"Chipmem %p - %p, Fastmem %p - %p">,d0,d1,d2,d3
lea fw_MemBottomStack(a6),a1
move.l d0,cf_ChipMemLevel+mtb_CurrLevelPtr(a1)
move.l d0,cf_ChipMemLevel+mtb_MinLevelPtr(a1)
move.l d2,cf_FastMemLevel+mtb_CurrLevelPtr(a1)
move.l d2,cf_FastMemLevel+mtb_MinLevelPtr(a1)
;clr.w fw_CurrMemBottomLevel(a6)
lea fw_MemTopStack(a6),a1
move.l d1,cf_ChipMemLevel+mtb_CurrLevelPtr(a1)
move.l d1,cf_ChipMemLevel+mtb_MinLevelPtr(a1)
move.l d3,cf_FastMemLevel+mtb_CurrLevelPtr(a1)
move.l d3,cf_FastMemLevel+mtb_MinLevelPtr(a1)
;clr.w fw_CurrMemTopLevel(a6)
DEBUGMEM
rts
;--------------------------------------------------------------------
; Frees all allocated memory
;
; Frees the memory of the current stack and current direction.
; Memory of other allocation direction is unchanged.
;
fw_DropCurrentMemoryAllocations:
PUTMSG 10,<"%d: DropCurrentMemoryAllocations">,fw_FrameCounterLong(a6)
IFGE DEBUG_DETAIL-20
PUSHM a0/a1/d0
ELSE
PUSHM a1
ENDC
DEBUGMEM
IF FW_TOP_BOTTOM_MEM_SECTIONS
bsr fw_DetectAllocationDirection
bne.s .toptobottom
ENDC
PUTMSG 10,<"DOWN: Freeing all">
lea fw_MemBottomStack(a6),a1
adda.w fw_CurrMemBottomLevel(a6),a1
IFGE DEBUG_DETAIL-20
move.l cf_ChipMemLevel+mtb_MinLevelPtr(a1),a0
move.l cf_ChipMemLevel+mtb_CurrLevelPtr(a1),d0
sub.l a0,d0
bsr fw_FillWithGarbage
move.l cf_FastMemLevel+mtb_MinLevelPtr(a1),a0
move.l cf_FastMemLevel+mtb_CurrLevelPtr(a1),d0
sub.l a0,d0
bsr fw_FillWithGarbage
ENDC
.cont
move.l cf_ChipMemLevel+mtb_MinLevelPtr(a1),cf_ChipMemLevel+mtb_CurrLevelPtr(a1)
move.l cf_FastMemLevel+mtb_MinLevelPtr(a1),cf_FastMemLevel+mtb_CurrLevelPtr(a1)
DEBUGMEM
POPM
rts
IF FW_TOP_BOTTOM_MEM_SECTIONS
.toptobottom
PUTMSG 10,<"UP: Freeing all">
lea fw_MemTopStack(a6),a1
adda.w fw_CurrMemTopLevel(a6),a1
IFGE DEBUG_DETAIL-20
move.l cf_ChipMemLevel+mtb_CurrLevelPtr(a1),a0
move.l cf_ChipMemLevel+mtb_MinLevelPtr(a1),d0
sub.l a0,d0
bsr fw_FillWithGarbage
move.l cf_FastMemLevel+mtb_CurrLevelPtr(a1),a0
move.l cf_FastMemLevel+mtb_MinLevelPtr(a1),d0
sub.l a0,d0
bsr fw_FillWithGarbage
ENDC
bra.s .cont
ENDC
;--------------------------------------------------------------------
; Pushes the current memory allocation state to the stack
;
; This only pushes the state for the current memory allocation
; direction onto the stack. All allocated memory upto this point
; will be kept safe and will no longer be freed automatically.
;
fw_PushMemoryState:
PUSHM a1/d0-d1
moveq.l #cf_SIZEOF,d0
IF FW_TOP_BOTTOM_MEM_SECTIONS
bsr fw_DetectAllocationDirection
bne.s .toptobottom
ENDC
PUTMSG 10,<"UP: ++++++ Pushing mem state ++++++">
add.w fw_CurrMemBottomLevel(a6),d0
move.w d0,fw_CurrMemBottomLevel(a6)
lea fw_MemBottomStack(a6,d0.w),a1
.cont
move.l cf_ChipMemLevel+mtb_CurrLevelPtr-cf_SIZEOF(a1),d0
move.l cf_FastMemLevel+mtb_CurrLevelPtr-cf_SIZEOF(a1),d1
move.l d0,cf_ChipMemLevel+mtb_CurrLevelPtr(a1)
move.l d0,cf_ChipMemLevel+mtb_MinLevelPtr(a1)
move.l d1,cf_FastMemLevel+mtb_CurrLevelPtr(a1)
move.l d1,cf_FastMemLevel+mtb_MinLevelPtr(a1)
DEBUGMEM
POPM
rts
IF FW_TOP_BOTTOM_MEM_SECTIONS
.toptobottom
PUTMSG 10,<"DOWN: ++++++ Pushing mem state ++++++">
add.w fw_CurrMemTopLevel(a6),d0
move.w d0,fw_CurrMemTopLevel(a6)
lea fw_MemTopStack(a6,d0.w),a1
bra.s .cont
ENDC
;--------------------------------------------------------------------
; Restore the last memory state from the memory stack for the current
; allocation direction. All memory from the previous allocation is
; freed.
;
; With debug enabled, freed memory is also overwritten with garbage.
;
; Out: All registers unchanged.
;
fw_PopMemoryState:
PUSHM a0/d0
DEBUGMEM
IF FW_TOP_BOTTOM_MEM_SECTIONS
bsr fw_DetectAllocationDirection
bne .toptobottom
ENDC
IFGE DEBUG_DETAIL-10
PUTMSG 10,<"UP: ------ Popping mem state ------">
bsr fw_DropCurrentMemoryAllocations
sub.w #cf_SIZEOF,fw_CurrMemBottomLevel(a6)
bmi.s .errorbottom
ELSE
sub.w #cf_SIZEOF,fw_CurrMemBottomLevel(a6)
ENDC
.cont
DEBUGMEM
POPM
rts
IFGE DEBUG_DETAIL-10
.errorbottom
PUTMSG 10,<"!!! Could not pop bottom memory stack (TOP: %d vs %d)">,fw_CurrMemBottomLevel-2(a6),fw_CurrMemTopLevel-2(a6)
move.w #ERROR_MEMORYWRONGPOP,d0
bra fw_Error
.errortop
PUTMSG 10,<"!!! Could not pop top memory stack (TOP: %d vs %d)">,fw_CurrMemBottomLevel-2(a6),fw_CurrMemTopLevel-2(a6)
move.w #ERROR_MEMORYWRONGPOP,d0
bra fw_Error
ENDC
IF FW_TOP_BOTTOM_MEM_SECTIONS
.toptobottom
IFGE DEBUG_DETAIL-10
PUTMSG 10,<"DOWN: ------ Popping mem state ------">
bsr fw_DropCurrentMemoryAllocations
sub.w #cf_SIZEOF,fw_CurrMemTopLevel(a6)
bmi .errortop
ELSE
sub.w #cf_SIZEOF,fw_CurrMemTopLevel(a6)
ENDC
bra .cont
ENDC
;--------------------------------------------------------------------
; Allocates the given amount of fastmem in the current direction of
; memory allocation (bottom->top or top->bottom).
;
; If theres not enough fast-mem, it falls back and returns chip-mem
; instead.
;
; Contents of memory are not cleared!
;
; In : d0: Size in bytes
; Out: a0: Start of memory allocation
; d0: Rounded size of allocation
; d1/a1: Trashed.
;
fw_AllocFast:
PUTMSG 10,<"%d: AllocFast(%ld)">,fw_FrameCounterLong(a6),d0
addq.l #3,d0
and.w #-4,d0
lea fw_MemBottomStack(a6),a0
adda.w fw_CurrMemBottomLevel(a6),a0
lea fw_MemTopStack(a6),a1
adda.w fw_CurrMemTopLevel(a6),a1
move.l cf_FastMemLevel+mtb_CurrLevelPtr(a1),d1
sub.l cf_FastMemLevel+mtb_CurrLevelPtr(a0),d1
cmp.l d0,d1
blo.s fw_AllocChip
moveq.l #cf_FastMemLevel,d1
bsr fw_DoAllocation
PUTMSG 30,<"Fast allocated at %p">,a0
IFGE DEBUG_DETAIL-12
bsr.s fw_FillWithGarbage
ENDC
DEBUGMEM
rts
;--------------------------------------------------------------------
; Allocates the given amount of chipmem in the current direction of
; memory allocation (bottom->top or top->bottom).
;
; Contents of memory are not cleared!
;
; In : d0: Size in bytes
; Out: a0: Start of memory allocation
; d0: Rounded size of allocation
; d1/a1: Trashed.
;
fw_AllocChip:
PUTMSG 10,<"%d: AllocChip(%ld)">,fw_FrameCounterLong(a6),d0
addq.l #7,d0
and.w #-8,d0
lea fw_MemBottomStack(a6),a0
adda.w fw_CurrMemBottomLevel(a6),a0
lea fw_MemTopStack(a6),a1
adda.w fw_CurrMemTopLevel(a6),a1
move.l cf_ChipMemLevel+mtb_CurrLevelPtr(a1),d1
sub.l cf_ChipMemLevel+mtb_CurrLevelPtr(a0),d1
cmp.l d0,d1
blo.s .error
moveq.l #cf_ChipMemLevel,d1
bsr fw_DoAllocation
PUTMSG 30,<"Chip allocated at %p">,a0
IFGE DEBUG_DETAIL-12
bsr fw_FillWithGarbage
ENDC
DEBUGMEM
rts
.error
PUTMSG 10,<"Out of memory: %ld smaller than %ld">,d1,d0
DEBUGMEM
move.w #ERROR_OUTOFMEMORY,d0
bra fw_Error
;--------------------------------------------------------------------
; Allocates the given amount of chipmem within a 64 KB page in the
; current direction of memory allocation.
;
; Memory area returned is guaranteed not to cross a 64 KB page
; boundary for the given size. Depending on the current memory
; situation and size requirements, may waste up to 64 KB of memory
; in the worst case. If you need multiple allocations these
; requirements, make sure to cluster them in a good way.
;
; Contents of memory are not cleared!
;
; In : d0: Size in bytes (less or equal to 64 KB!)
; Out: a0: Start of memory allocation
; d0: Rounded size of allocation
; d1/a1: Trashed.
;
IF FW_64KB_PAGE_MEMORY_SUPPORT
fw_AllocChip64KB:
PUTMSG 10,<"%d: AllocChip64KB(%ld)">,fw_FrameCounterLong(a6),d0
addq.l #7,d0
and.w #-8,d0
lea fw_MemBottomStack(a6),a0
adda.w fw_CurrMemBottomLevel(a6),a0
lea fw_MemTopStack(a6),a1
adda.w fw_CurrMemTopLevel(a6),a1
.retry
move.l cf_ChipMemLevel+mtb_CurrLevelPtr(a1),d1
sub.l cf_ChipMemLevel+mtb_CurrLevelPtr(a0),d1
cmp.l d0,d1
blo .error
IF FW_TOP_BOTTOM_MEM_SECTIONS
bsr fw_DetectAllocationDirection
bne.s .toptobottom
ENDC
move.l cf_ChipMemLevel+mtb_CurrLevelPtr(a0),d1
add.l d0,d1
subq.l #1,d1
swap d1
cmp.w cf_ChipMemLevel+mtb_CurrLevelPtr(a0),d1
beq .doallocation
addq.w #1,cf_ChipMemLevel+mtb_CurrLevelPtr(a0)
IFGE DEBUG_DETAIL-10
moveq.l #0,d1
move.w cf_ChipMemLevel+mtb_CurrLevelPtr+2(a0),d1
neg.w d1
PUTMSG 10,<"Skipping %ld bytes of memory DOWN (sorry)">,d1
ENDC
clr.w cf_ChipMemLevel+mtb_CurrLevelPtr+2(a0)
bra.s .retry
IF FW_TOP_BOTTOM_MEM_SECTIONS
.toptobottom
moveq.l #0,d1
move.w cf_ChipMemLevel+mtb_CurrLevelPtr+2(a1),d1
beq.s .doallocation
cmp.l d0,d1
bge.s .doallocation
PUTMSG 10,<"Skipping %d bytes of memory UP (sorry)">,cf_ChipMemLevel+mtb_CurrLevelPtr(a1)
clr.w cf_ChipMemLevel+mtb_CurrLevelPtr+2(a1)
bra .retry
ENDC
.doallocation
moveq.l #cf_ChipMemLevel,d1
bsr fw_DoAllocation
PUTMSG 30,<"Chip within 64 KB page allocated at %p">,a0
IFGE DEBUG_DETAIL-20
bsr fw_FillWithGarbage
ENDC
DEBUGMEM
rts
.error
PUTMSG 10,<"Out of memory: %ld smaller than %ld">,d1,d0
DEBUGMEM
move.w #ERROR_OUTOFMEMORY,d0
bra fw_Error
ENDC
;--------------------------------------------------------------------
; Changes the direction of memory allocation (bottom to top vs top
; to bottom). Also works from subtasks (be a bit careful there).
;
; Out: All registers unchanged.
;
IF FW_TOP_BOTTOM_MEM_SECTIONS
fw_FlipAllocationDirection:
IF FW_MULTITASKING_SUPPORT
tst.l fw_BackgroundTask(a6)
beq.s .flipmain
PUSHM a0
move.l fw_BackgroundTask(a6),a0
eor.w #1,ft_MemDirection(a0)
PUTMSG 10,<"Flipping allocation direction of task %p (%s) to %d">,a0,LN_NAME(a0),ft_MemDirection-2(a0)
POPM
rts
ENDC
.flipmain
eor.w #1,fw_MainMemDirection(a6)
PUTMSG 10,<"Flipping main allocation direction to %d">,fw_MainMemDirection-2(a6)
rts
;--------------------------------------------------------------------
fw_DetectAllocationDirection:
IF FW_MULTITASKING_SUPPORT
tst.l fw_BackgroundTask(a6)
beq.s .flipmain
PUSHM a0/d0 ; avoid optimizing the movem to move so that the CCs remain intact
move.l fw_BackgroundTask(a6),a0
tst.w ft_MemDirection(a0)
POPM
rts
ENDC
.flipmain
tst.w fw_MainMemDirection(a6)
rts
ENDC
;--------------------------------------------------------------------
fw_DoAllocation:
PUSHM a1/d0/d1
IF FW_TOP_BOTTOM_MEM_SECTIONS
bsr fw_DetectAllocationDirection
bne.s .toptobottom
ENDC
; allocate from bottom
lea fw_MemBottomStack(a6),a1
adda.w fw_CurrMemBottomLevel(a6),a1
move.l mtb_CurrLevelPtr(a1,d1.w),a0
PUTMSG 10,<"UP: Allocating %ld bytes from bottom at %p">,d0,a0
add.l a0,d0
move.l d0,mtb_CurrLevelPtr(a1,d1.w)
.cont
POPM
rts
IF FW_TOP_BOTTOM_MEM_SECTIONS
.toptobottom
; allocate from top
lea fw_MemTopStack(a6),a1
adda.w fw_CurrMemTopLevel(a6),a1
move.l mtb_CurrLevelPtr(a1,d1.w),a0
sub.l d0,a0
PUTMSG 10,<"DOWN: Allocating %ld bytes from top at %p">,d0,a0
move.l a0,mtb_CurrLevelPtr(a1,d1.w)
bra.s .cont
ENDC
;--------------------------------------------------------------------
IFGE DEBUG_DETAIL-12
fw_FillWithGarbage:
PUTMSG 10,<"Filling with garbage %p (%ld)">,a0,d0
PUSHM a0/d0/d1
lsr.l #2,d0
beq.s .skipfill
subq.w #1,d0
move.l #$DEADBE00,d1
.fillloop
move.l d1,(a0)+
addq.l #1,d1
dbra d0,.fillloop
swap d0
subq.w #1,d0
bcs.s .skipfill
swap d0
bra.s .fillloop
.skipfill
POPM
rts
ENDC
;--------------------------------------------------------------------
IFGE DEBUG_DETAIL-10
fw_DebugMemoryManagement:
PUSHM d0-d7/a0/a1
lea fw_MemBottomStack(a6),a0
adda.w fw_CurrMemBottomLevel(a6),a0
lea fw_MemTopStack(a6),a1
adda.w fw_CurrMemTopLevel(a6),a1
move.l cf_ChipMemLevel+mtb_CurrLevelPtr(a1),d0 ; current free chip: chip top - bottom
sub.l cf_ChipMemLevel+mtb_CurrLevelPtr(a0),d0
lsr.l #8,d0
lsr.w #2,d0
move.l fw_MemTopStack+cf_ChipMemLevel+mtb_MinLevelPtr(a6),d1 ; max free chip within this frame
sub.l cf_ChipMemLevel+mtb_MinLevelPtr(a0),d1
lsr.l #8,d1
lsr.w #2,d1
move.l cf_ChipMemLevel+mtb_CurrLevelPtr(a0),d2 ; bottom chip allocated in stack
sub.l cf_ChipMemLevel+mtb_MinLevelPtr(a0),d2
lsr.l #8,d2
lsr.w #2,d2
move.l cf_ChipMemLevel+mtb_MinLevelPtr(a1),d3 ; top chip allocated in stack
sub.l cf_ChipMemLevel+mtb_CurrLevelPtr(a1),d3
lsr.l #8,d3
lsr.w #2,d3
move.l cf_FastMemLevel+mtb_CurrLevelPtr(a1),d4 ; current free fast: fast top - bottom
sub.l cf_FastMemLevel+mtb_CurrLevelPtr(a0),d4
lsr.l #8,d4
lsr.w #2,d4
move.l cf_FastMemLevel+mtb_MinLevelPtr(a1),d5 ; max free fast within this frame
sub.l fw_MemBottomStack+cf_FastMemLevel+mtb_MinLevelPtr(a6),d5
lsr.l #8,d5
lsr.w #2,d5
move.l cf_FastMemLevel+mtb_CurrLevelPtr(a0),d6 ; bottom fast allocated in stack
sub.l cf_FastMemLevel+mtb_MinLevelPtr(a0),d6
lsr.l #8,d6
lsr.w #2,d6
move.l cf_FastMemLevel+mtb_MinLevelPtr(a1),d7 ; top fast allocated in stack
sub.l cf_FastMemLevel+mtb_CurrLevelPtr(a1),d7
lsr.l #8,d7
lsr.w #2,d7
PUTMSG 10,<"Mem Free: Chip: %ld of %ld KB (%ld/%ld KB) | Fast: %ld of %ld KB (%ld/%ld KB)">,d0,d1,d2,d3,d4,d5,d6,d7
move.l cf_ChipMemLevel+mtb_CurrLevelPtr(a0),d0 ; bottom chip allocated total
sub.l fw_MemBottomStack+cf_ChipMemLevel+mtb_MinLevelPtr(a6),d0
add.l fw_MemTopStack+cf_ChipMemLevel+mtb_MinLevelPtr(a6),d0 ; top chip allocated total
sub.l cf_ChipMemLevel+mtb_CurrLevelPtr(a1),d0
lsr.l #8,d0
lsr.w #2,d0
cmp.l fw_MaxChipUsed(a6),d0
blt.s .lesschip
move.l d0,fw_MaxChipUsed(a6)
.lesschip
move.l fw_MemTopStack+cf_ChipMemLevel+mtb_MinLevelPtr(a6),d1 ; max free chip total
sub.l fw_MemBottomStack+cf_ChipMemLevel+mtb_MinLevelPtr(a6),d1
lsr.l #8,d1
lsr.w #2,d1
move.l cf_FastMemLevel+mtb_CurrLevelPtr(a0),d2 ; bottom fast allocated total
sub.l fw_MemBottomStack+cf_FastMemLevel+mtb_MinLevelPtr(a6),d2
add.l fw_MemTopStack+cf_FastMemLevel+mtb_MinLevelPtr(a6),d2 ; top fast allocated total
sub.l cf_FastMemLevel+mtb_CurrLevelPtr(a1),d2
lsr.l #8,d2
lsr.w #2,d2
cmp.l fw_MaxFastUsed(a6),d2
blt.s .lessfast
move.l d2,fw_MaxFastUsed(a6)
.lessfast
move.l fw_MemTopStack+cf_FastMemLevel+mtb_MinLevelPtr(a6),d3 ; max free fast total
sub.l fw_MemBottomStack+cf_FastMemLevel+mtb_MinLevelPtr(a6),d3
lsr.l #8,d3
lsr.w #2,d3
PUTMSG 10,<"Mem Used: Chip: %ld of %ld KB (max. %ld KB) | Fast: %ld of %ld KB (max. %ld KB)">,d0,d1,fw_MaxChipUsed(a6),d2,d3,fw_MaxFastUsed(a6)
PUTMSG 20,<"Chip Bottom: %p, Chip Top %p, Fast Bottom: %p, Fast Top: %p">,cf_ChipMemLevel+mtb_CurrLevelPtr(a0),cf_ChipMemLevel+mtb_CurrLevelPtr(a1),cf_FastMemLevel+mtb_CurrLevelPtr(a0),cf_FastMemLevel+mtb_CurrLevelPtr(a1)
POPM
rts
ENDC

View File

@ -0,0 +1,205 @@
;--------------------------------------------------------------------
; Endlessly loops and indicate an error
;
; In : d0.w - errorcode
; Out: never returns
;
fw_Error:
ext.l d0
PUTMSG 10,<"Error %x (%d)">,d0,d0
.l0 move.w d0,color(a5)
bra.s .l0
;--------------------------------------------------------------------
; Sets the base copperlist and irq (empty screen).
;
; Background colour is unchanged, sprites and display are disabled.
;
; Out: Trashes d0/a0
;
fw_SetBaseCopper:
PUTMSG 10,<"%d: SetBaseCopper">,fw_FrameCounterLong(a6)
moveq.l #0,d0
IF FW_VBL_IRQ_SUPPORT
move.l d0,fw_VBlankIRQ(a6)
ENDC
IF FW_COPPER_IRQ_SUPPORT
move.l d0,fw_CopperIRQ(a6)
ENDC
move.w #DMAF_SPRITE|DMAF_RASTER|DMAF_COPPER,dmacon(a5) ; Disable sprite- and copper DMA to avoid race conditions overwriting cop1lc
bsr.s .clrspr
move.w #$0200,bplcon0(a5)
move.l fw_BaseCopperlist(a6),a0
move.l a0,cop1lc(a5)
move.l fw_VBR(a6),a0
move.l fw_DefaultIRQ(a6),$6c(a0)
move.w #INTF_BLIT,intena(a5) ; disable blitter interrupt
move.w #INTF_BLIT|INTF_COPER,intreq(a5)
IF FW_COPPER_IRQ_SUPPORT
move.w #INTF_SETCLR|INTF_INTEN|INTF_COPER|INTF_VERTB,intena(a5) ; enable vblank & copper interrupts
ELSE
move.w #INTF_SETCLR|INTF_INTEN|INTF_VERTB,intena(a5) ; enable vblank interrupt
ENDC
bsr.s fw_VSync
move.w #DMAF_SETCLR|DMAF_MASTER|DMAF_BLITTER|DMAF_RASTER|DMAF_COPPER,dmacon(a5)
.clrspr
moveq.l #0,d0
move.w d0,spr+0*8+sd_ctl(a5)
move.w d0,spr+1*8+sd_ctl(a5)
move.w d0,spr+2*8+sd_ctl(a5)
move.w d0,spr+3*8+sd_ctl(a5)
move.w d0,spr+4*8+sd_ctl(a5)
move.w d0,spr+5*8+sd_ctl(a5)
move.w d0,spr+6*8+sd_ctl(a5)
move.w d0,spr+7*8+sd_ctl(a5)
rts
;--------------------------------------------------------------------
; Sets a new copperlist (and waits for VBL)
;
; In: a0 = the new copperlist
;
fw_SetCopper:
move.l a0,cop1lc(a5)
IF FW_MULTITASKING_SUPPORT
bra fw_VSyncWithTask
ELSE
;bra.s fw_VSync
; fall through
ENDC
;--------------------------------------------------------------------
; Waits for the next vertical blank.
;
; This version does not allow other tasks to run in the background!
;
; Note: Also checks left mouse button for exit if configured.
;
; In : -
; Out: d0 is trashed
;
IFEQ FW_MULTITASKING_SUPPORT
fw_VSyncWithTask:
ENDC
fw_VSync:
IF FW_LMB_EXIT_SUPPORT
btst #6,$bfe001
beq .abortdemo
ENDC
.noabort
IF 1
move.w fw_FrameCounter(a6),d0
BLTHOGON
.loop cmp.w fw_FrameCounter(a6),d0
beq.s .loop
ELSE
;btst #DMAB_BLTDONE-8,dmaconr(a5)
;beq.s .vs1
BLTHOGON
.vs1 btst #0,vposr+1(a5)
beq.s .vs1
.vs0 btst #0,vposr+1(a5)
bne.s .vs0
ENDC
rts
IF FW_LMB_EXIT_SUPPORT
.abortdemo
move.l fw_DemoAbortStackPointer(a6),d0
beq.s .noabort
move.l d0,sp
rts
ENDC
;--------------------------------------------------------------------
; Waits until the global framecounter reaches the given frame
;
; In : d0.w - frame to wait for
; Out: May trash all registers!
;
fw_WaitForFrame:
PUTMSG 10,<"%d: Waiting for frame %d">,fw_FrameCounterLong(a6),d0
.loop
cmp.w fw_FrameCounter(a6),d0
bmi.s .endwait
PUSHM d0
IF FW_MULTITASKING_SUPPORT
bra fw_VSyncWithTask
ELSE
bra fw_VSync
ENDC
POPM
bra.s .loop
.endwait
PUTMSG 10,<"%d: Waiting done">,fw_FrameCounterLong(a6)
rts
;--------------------------------------------------------------------
; Flushes the cache on Kick 2.0 or higher to avoid problems with SMC.
; (also after loading code).
;
fw_FlushCaches:
PUSHM a6
move.l 4.w,a6
cmp.w #37,LIB_VERSION(a6)
blo.s .lameos
CALL CacheClearU
.lameos
POPM
rts
;--------------------------------------------------------------------
IF FW_COPPER_IRQ_SUPPORT
fw_copper_irq:
PUSHM d0/a0/a5/a6
lea $dff000,a5
move.w #INTF_COPER,intreq(a5) ;acknowledge the copper-irq.
move.w #INTF_COPER,intreq(a5) ;acknowledge the copper-irq.
move.l fw_BasePtr(pc),a6
move.l fw_CopperIRQ(a6),d0
beq.s .nocop
move.l d0,a0
jsr (a0)
.nocop POPM
nop
rte
ENDC
;--------------------------------------------------------------------
fw_vblank_standard_irq:
IF FW_COPPER_IRQ_SUPPORT
btst #INTB_COPER,$dff000+intreqr+1
bne.s fw_copper_irq
ENDC
IF FW_VBL_IRQ_SUPPORT|(FW_MUSIC_SUPPORT&FW_VBL_MUSIC_IRQ)
PUSHM d0-d3/a0-a3/a5/a6
ELSE
PUSHM a5/a6
ENDC
lea $dff000,a5
move.w #INTF_VERTB,intreq(a5) ;acknowledge the VBL-irq.
move.w #INTF_VERTB,intreq(a5) ;acknowledge the VBL-irq.
move.l fw_BasePtr(pc),a6
addq.w #1,fw_FrameCounter(a6)
IF (FW_MUSIC_SUPPORT&FW_VBL_MUSIC_IRQ)
tst.w fw_MusicEnabled(a6)
beq.s .skipmus
bsr fw_MusicPlay
.skipmus
ENDC
IF FW_VBL_IRQ_SUPPORT
move.l fw_VBlankIRQ(a6),d0
beq.s .novbl
move.l d0,a0
jsr (a0) ; IRQ must maintain d4-d7/a4
.novbl
ENDC
POPM
nop
rte

View File

@ -0,0 +1,211 @@
;--------------------------------------------------------------------
; Multipart support for trackmos
;
; In my former demo system I used a6 as a base pointer to the demo
; framework and a4 as a pointer to my demo part variables. That
; seemed a bit wasteful and so the new system uses one pointer for
; both framework AND part variables for the current part. This,
; however, means that the framework base needs to be relocated
; depending on the part because, of course, the size of the
; local variables may vary.
;
; You must start your local variable space with
;
; STRUCTURE PartData,fw_SIZEOF
;
; and end it with
;
; LABEL pd_SIZEOF
;
;--------------------------------------------------------------------
; Allocate the part variables
;
; The first thing each demo part needs to do is to call InitPart.
; I repeat: Start your code with:
; IFD FW_DEMO_PART
; move.l #pd_SIZEOF,d0
; CALLFW InitPart
; ENDC
;
; Otherwise, no part variables are available via a6 and no other
; framework calls can be made (the jumping table is not available).
;
; After this call, a6 will be pointing to the new framework base
; with all your variable space cleared.
;
; Make sure that you don't free the memory allocated here until
; the end of your part! The demo framework will call
; RestoreFrameworkBase automatically at exit of your part.
;
; Flushes the caches (if available), too.
;
; In : d0 = pd_SIZEOF (part data structure size including fw_SIZEOF)
; Out: a6 = new base pointer
; Trashes: everything except a5/a6
;
fw_InitPart:
PUTMSG 10,<"%d: InitPart(%ld)">,fw_FrameCounterLong(a6),d0
PUSHM d0
bsr fw_RestoreFrameworkBase
POPM
DISABLE_INTS
move.l fw_PartFwBase(a6),a0
move.l d0,fw_PartDataSize(a6)
add.l #-FWLVOPOS,d0
bsr fw_AllocFast
lea -FWLVOPOS(a0),a1
PUTMSG 40,<"LVOs from %p to %p">,a1,a0
move.l a6,a0
move.l a6,a3
move.l a1,a6
move.w #(fw_SIZEOF/4)-1,d7
PUTMSG 40,<"Copying %d LW from %p to %p">,d7,a0,a1
.copynew
move.l (a0)+,(a1)+
dbra d7,.copynew
move.l a6,fw_PartFwBase(a6)
move.l fw_PartDataSize(a6),d7
addq.w #3,d7
lsr.w #2,d7
beq.s .skipclr
subq.w #1,d7
moveq.l #0,d0
.clrnew
move.l d0,(a1)+
dbra d7,.clrnew
.skipclr
move.l a6,a0
lea fw_lvo_offsets(pc),a1
.lvoloop
move.w (a1)+,d0
beq.s .lvodone
lea -2(a1,d0.w),a2
move.l a2,-(a0)
move.w #%0100111011111001,-(a0) ; $4ef9 jmp x.L
bra.s .lvoloop
.lvodone
IF FW_MULTITASKING_SUPPORT
; The task list header is now broken after copying! We need to fix it.
lea fw_Tasks(a6),a1
bsr fw_RelocateList
bsr fw_FixA6BaseInTaskStacks
ENDC
lea fw_BasePtr(pc),a0
move.l a6,(a0)
bsr fw_FlushCaches
ENABLE_INTS
PUTMSG 20,<"%d: InitPart done %p">,fw_FrameCounterLong(a6),a6
rts
;--------------------------------------------------------------------
; Restore global framework base
;
; Removes the custom framework variable space and makes the global
; one active again.
;
; Out: a6 = new base pointer
; Trashes: everything except a5/a6
;
fw_RestoreFrameworkBase:
PUTMSG 10,<"%d: RestoreFrameworkBase(%p)">,fw_FrameCounterLong(a6),a6
DISABLE_INTS
move.l fw_PartFwBase(a6),a0
move.l fw_PrimaryFwBase(a6),a1
PUTMSG 40,<"Part %p, Primary %p">,a0,a1
cmp.l a1,a0
beq.s .noold
move.l a0,a3
PUTMSG 40,<"Restore from %p to %p">,a0,a1
move.l a1,a6
move.w #(fw_SIZEOF/4)-1,d7
.copyold
move.l (a0)+,(a1)+
dbra d7,.copyold
IF FW_MULTITASKING_SUPPORT
bsr fw_FixA6BaseInTaskStacks
ENDC
move.l a6,fw_PartFwBase(a6)
clr.l fw_PartDataSize(a6)
IF FW_MULTITASKING_SUPPORT
; The task list header is now broken after copying! We need to fix it.
lea fw_Tasks(a6),a1
bsr.s fw_RelocateList
ENDC
lea fw_BasePtr(pc),a0
move.l a6,(a0)
.noold
ENABLE_INTS
rts
;--------------------------------------------------------------------
; Helper function to relocate a doubly-linked list
;
; When relocating the framework base structure, we need to fix the
; contents of lists, otherwise BadThings(TM) will happen.
; This function goes through the relocated list and fixes the linkage.
;
; In: a1 = ListHead
; Trashes: a0/a1
;
IF FW_MULTITASKING_SUPPORT
fw_RelocateList:
move.l LH_HEAD(a1),a0
subq.l #4,a0
cmp.l LH_TAILPRED(a1),a0
bne.s .nonewlist
PUTMSG 10,<"Fixup empty list %p">,a1
move.l a1,LH_TAILPRED(a1) ; fix empty list
addq.l #4,a1
move.l a1,-(a1)
bra.s .listfixed
.nonewlist
PUTMSG 10,<"Fixup existing list %p">,a1
move.l a1,4+LN_PRED(a0) ; fixup LN_PRED of first node (points to LH_HEAD)
move.l LH_TAILPRED(a1),a0 ; get last node
addq.l #4,a1 ; now points to LH_TAIL
move.l a1,LN_SUCC(a0) ; fixup LN_SUCC of last node (pointing to LH_TAIL)
.listfixed
rts
ENDC
;--------------------------------------------------------------------
; Running tasks will have the old framework base stored in their
; register context. We need to fix these occurrences. Note that
; this is not completely fool-proof, but should work for 99% of the
; cases (there shouldn't be framework-relative things).
;
; In: a3 = old base
; a6 = new base
fw_FixA6BaseInTaskStacks:
lea fw_Tasks(a3),a1
.loop
TSTNODE a1,a1
beq.s .done
move.l ft_USP(a1),a0
lea ft_StackEnd(a1),a2
.findloop
cmp.l a0,a2
beq.s .loop
cmp.l (a0),a3
bne.s .notmatched
PUTMSG 10,<"Replacing base at %p">,a0
move.l a6,(a0)
.notmatched
addq.l #2,a0
bra.s .findloop
.done rts
fw_lvo_offsets:
FWGENLVOTABLE SET 1
include "../framework/framework_lvos.i"
dc.w 0
FWGENLVOTABLE SET 0

View File

@ -0,0 +1,23 @@
;--------------------------------------------------------------------
; Starts the music playback with the given module
;
; Data and samples should be provided in fw_MusicData(a6) and
; fw_MusicSamples(a6) respectively.
;
fw_StartMusic:
move.l fw_MusicData(a6),a0
move.l fw_MusicSamples(a6),a1
bsr fw_MusicInit
move.w #1,fw_MusicEnabled(a6)
rts
;--------------------------------------------------------------------
; Stops the music playback if music is active
;
fw_StopMusic:
tst.w fw_MusicEnabled(a6)
bne.s .cont
rts
.cont clr.w fw_MusicEnabled(a6)
bra fw_MusicStop

View File

@ -0,0 +1,193 @@
;--------------------------------------------------------------------
; Initializes linear interpolation for simple palette fading.
;
; In : a0 = source palette buffer (12 bit)
; a1 = lerp structures
; d0 = number of colors
;
fw_InitPaletteLerp:
PUTMSG 20,<"Init Lerp %p with %p">,a1,a0
subq.w #1,d0
bcc.s .cont
rts
.cont move.w #$800,d2
.loop
moveq.l #0,d1
move.w d1,cl_Steps(a1)
move.w (a0),cl_Color(a1)
move.w d1,cl_Red+le_Add(a1)
move.w d1,cl_Green+le_Add(a1)
move.w d1,cl_Blue+le_Add(a1)
move.b (a0)+,d1
ror.w #4,d1
add.w d2,d1
move.w d1,cl_Red+le_Current(a1)
moveq.l #-16,d1
and.b (a0),d1
addq.b #8,d1
move.b d1,cl_Green+le_Current(a1)
clr.b cl_Green+1+le_Current(a1)
moveq.l #15,d1
and.b (a0)+,d1
ror.w #4,d1
add.w d2,d1
move.w d1,cl_Blue+le_Current(a1)
lea cl_SIZEOF(a1),a1
dbra d0,.loop
rts
;--------------------------------------------------------------------
; Initializes linear interpolation for simple palette fading to given color
;
; In : a1 = lerp structures
; d0 = number of colors
; d1 = color value
;
fw_InitPaletteLerpSameColor:
PUTMSG 20,<"Init Lerp %p with %x">,a1,d1
subq.w #1,d0
bcc.s .cont
rts
.cont move.w d1,cl_Color(a1)
moveq.l #0,d1
move.w d1,cl_Steps(a1)
move.w d1,cl_Red+le_Add(a1)
move.w d1,cl_Green+le_Add(a1)
move.w d1,cl_Blue+le_Add(a1)
move.b cl_Color(a1),d1
ror.w #4,d1
add.w #$800,d1
move.w d1,cl_Red+le_Current(a1)
moveq.l #-16,d1
and.b cl_Color+1(a1),d1
addq.b #8,d1
move.b d1,cl_Green+le_Current(a1)
clr.b cl_Green+1+le_Current(a1)
moveq.l #15,d1
and.b cl_Color+1(a1),d1
ror.w #4,d1
add.w #$800,d1
move.w d1,cl_Blue+le_Current(a1)
dbra d0,.iloop
rts
.iloop movem.l (a1),d1-d4
.loop lea cl_SIZEOF(a1),a1
movem.l d1-d4,(a1)
dbra d0,.loop
rts
;--------------------------------------------------------------------
; Initialize fading to the given palette from current state
;
; In : a0 = target palette (12 bit)
; a1 = lerp structures
; d0 = number of colors
; d1 = number of steps (power of two)
;
fw_FadePaletteTo:
subq.w #1,d0
bcc.s .cont
rts
.cont
move.w d1,d4
moveq.l #-2,d2
.stepsizeloop
addq.w #1,d2
lsr.w #1,d1
bne.s .stepsizeloop
.loop
move.w d4,cl_Steps(a1)
moveq.l #0,d1
move.b (a0)+,d1
ror.w #4,d1
move.w cl_Red+le_Current(a1),d3
lsr.w #1,d1
add.w #$80,d1
lsr.w #1,d3
sub.w d3,d1
asr.w d2,d1
move.w d1,cl_Red+le_Add(a1)
moveq.l #-16,d1
and.b (a0),d1
lsl.w #8,d1
clr.b d1
move.w cl_Green+le_Current(a1),d3
lsr.w #1,d1
add.w #$80,d1
lsr.w #1,d3
sub.w d3,d1
asr.w d2,d1
move.w d1,cl_Green+le_Add(a1)
moveq.l #15,d1
and.b (a0)+,d1
ror.w #4,d1
move.w cl_Blue+le_Current(a1),d3
lsr.w #1,d1
add.w #$80,d1
lsr.w #1,d3
sub.w d3,d1
asr.w d2,d1
move.w d1,cl_Blue+le_Add(a1)
lea cl_SIZEOF(a1),a1
dbra d0,.loop
rts
;--------------------------------------------------------------------
; Do one step in fading for the pre-initialized
;
; Will do nothing if end-point has been already reached.
;
; In : a1 = lerp structures
; d0 = number of colors
;
fw_DoFadePaletteStep:
subq.w #1,d0
bcc.s .cont
.done rts
.cont lea cl_Steps(a1),a0
tst.w (a0)
bmi.s .done
moveq.l #0,d4
.loop
addq.w #2,a1
move.w (a1),d1 ; cl_Steps
beq.s .skip
moveq.l #1,d4
subq.w #1,d1
move.w d1,(a1)+ ; cl_Steps
move.w (a1)+,d1 ; cl_Red+le_Add
add.w (a1),d1 ; cl_Red+le_Current
move.w d1,(a1)+ ; cl_Red+le_Current
move.w (a1)+,d2 ; cl_Green+le_Add
add.w d2,(a1)+ ; cl_Green+le_Current
move.w (a1)+,d3 ; cl_Blue+le_Add
add.w (a1),d3 ; cl_Blue+le_Current
move.w d3,(a1)+ ; cl_Blue+le_Current
lsr.w #4,d1
moveq.l #15,d2
rol.w #4,d3
and.w d2,d3
moveq.l #-16,d2
and.b cl_Green+le_Current-(cl_Blue+le_Current+2)(a1),d2
or.b d3,d2
move.b d2,d1
move.w d1,-cl_SIZEOF(a1) ; cl_Color
dbra d0,.loop
rts
.skip
lea cl_SIZEOF-2(a1),a1
dbra d0,.loop
tst.w d4
bne.s .noend
st (a0)
.noend
rts

View File

@ -0,0 +1,90 @@
;--------------------------------------------------------------------
; Install a script
;
; Routines of the script will be executed via CheckScript once the
; given relative frame numbers (from the point in time this routine
; is called) have been reached (or passed).
;
; A script is built in this way:
; dc.w <framenumber>,<routinetocall>-*
; dc.w <framenumber>,<routinetocall>-*
;
; The script is terminated with a zero word.
;
; In : a0 = script pointer
;
fw_InstallScript:
PUTMSG 10,<"%d: Script at %p installed">,fw_FrameCounterLong(a6),a0
move.l a0,fw_ScriptPointer(a6)
move.w fw_FrameCounter(a6),fw_ScriptFrameOffset(a6)
rts
;--------------------------------------------------------------------
; Checks the script for execution
;
; Checkes if a script is installed and another cue is due to the
; current frame counter, executes it and advances the script pointer.
;
fw_CheckScript:
move.l fw_ScriptPointer(a6),d0
bne.s .cont
rts
.cont move.l d0,a0
move.w (a0)+,d0
add.w fw_ScriptFrameOffset(a6),d0
cmp.w fw_FrameCounter(a6),d0
bgt.s .exit
move.w (a0)+,d0
move.l a0,fw_ScriptPointer(a6)
pea -2(a0,d0.w)
PUTMSG 10,<"%d: Script hit %p">,fw_FrameCounterLong(a6),(sp)
tst.w (a0)
bne.s .exit
PUTMSG 10,<"Script terminated.">
clr.l fw_ScriptPointer(a6)
.exit rts
IF FW_MUSIC_SUPPORT
;--------------------------------------------------------------------
; Install a music-frame based script
;
; Routines of the script will be executed via CheckMusicScript once
; the given absolute music frame numbers have been reached (or passed).
;
; A script is built in this way:
; dc.w <musicframenumber>,<routinetocall>-*
; dc.w <musicframenumber>,<routinetocall>-*
;
; The script is terminated with a zero word.
;
; In : a0 = script pointer
;
fw_InstallMusicScript:
PUTMSG 10,<"%d: MusicScript at %p installed">,fw_FrameCounterLong(a6),a0
move.l a0,fw_MusicScriptPointer(a6)
rts
;--------------------------------------------------------------------
; Checks the music script for execution
;
; Checkes if a music script is installed and another cue is due to the
; current frame counter, executes it and advances the script pointer.
;
fw_CheckMusicScript:
move.l fw_MusicScriptPointer(a6),d0
bne.s .cont
rts
.cont move.l d0,a0
move.w (a0)+,d0
cmp.w fw_MusicFrameCount(a6),d0
bgt.s .exit
move.w (a0)+,d0
move.l a0,fw_MusicScriptPointer(a6)
pea -2(a0,d0.w)
PUTMSG 10,<"%d: MusicScript (%d) hit %p">,fw_FrameCounterLong(a6),fw_MusicFrameCount-2(a6),(sp)
tst.w (a0)
bne.s .exit
PUTMSG 10,<"MusicScript terminated.">
clr.l fw_MusicScriptPointer(a6)
.exit rts
ENDC

View File

@ -0,0 +1,57 @@
;--------------------------------------------------------------------
; Initializes the built-in sine-table
;
; Code by a/b (EAB forum)
;
; Sine and cosine tables with 1024 entries and -16384 to +16384 range are
; accessible through the fw_SinTable(a6) and fw_CosTable(a6) base pointers.
;
fw_InitSineTable:
PUTMSG 10,<"%d: Script at %p installed">,fw_FrameCounterLong(a6),a0
IF FW_DYNAMIC_MEMORY_SUPPORT
move.l #(1024+256)*2,d0
bsr fw_AllocFast
move.l a0,fw_SinTable(a6)
lea 256*2(a0),a1
move.l a1,fw_CosTable(a6)
ELSE
move.l fw_FastMemStack(a6),a0
move.l a0,fw_SinTable(a6)
lea 256*2(a0),a1
move.l a1,fw_CosTable(a6)
lea 1024*2(a1),a1
move.l a1,fw_FastMemStack(a6)
ENDC
PUTMSG 10,<"%d: Init Sine table %p">,fw_FrameCounterLong(a6),a0
moveq.l #0,d0 ; amp=16384, length=1024
move.w #511+2,a1
.loop subq.l #2,a1
move.l d0,d1
IF 1
; extra accuracy begin
move.w d1,d2
not.w d2
mulu.w d1,d2
divu.w #75781/2,d2 ; 16384/0.2162
lsr.w #3,d2 ; can't do a 32-bit divu
sub.w d2,d1
; extra accuracy end
ENDC
asr.l #2,d1
move.w d1,(a0)+
neg.w d1
move.w d1,1024-2(a0)
add.l a1,d0
bne.s .loop
move.l fw_SinTable(a6),a0 ; fill back of cos table
lea 1024*2(a0),a1
moveq.l #(256/2)-1,d0
.cloop move.l (a0)+,(a1)+
dbra d0,.cloop
PUTMSG 10,<"%d: Sine table done">,fw_FrameCounterLong(a6)
rts

View File

@ -0,0 +1,497 @@
;--------------------------------------------------------------------
; Initialize the multitasking environment.
;
fw_InitTasks:
lea fw_Tasks(a6),a1
NEWLIST a1
lea fw_backgroundtask_restore_irq(pc),a0
move.l a0,fw_MultitaskingIRQ(a6)
IF FW_BLITTERTASK_MT_SUPPORT
lea fw_blitter_task_irq(pc),a0
move.l a0,fw_BlitterTaskIRQ(a6)
ENDC
rts
;--------------------------------------------------------------------
; Adds a task to the list of background tasks.
;
; LN_NAME(a1) can be populated for debugging reasons
; LN_PRI(a1) from -128 (low) to +127 (high) describes the priority
; of the task. Unless a task yields, no lower priority task will be
; processed.
; Exception: For FW_ROUNDROBIN_MT_SUPPORT=1, if LN_PRI is negative,
; low prio tasks will be scheduled round robin, if the task did not yield.
;
; Note that every task will only be scheduled at most once every frame.
; May also be called from subtask.
; Note: All tasks must preserve a5/a6 until exit!
;
; In : a0: start address of routine
; a1: FrameworkTask structure (with length of ft_SIZEOF)
; All registers will be initial registers for subtask.
; Out: All registers are unchanged.
;
fw_AddTask:
PUTMSG 10,<"%d: AddTask(%p,%p,%s)">,fw_FrameCounterLong(a6),a0,a1,LN_NAME(a1)
tst.l ft_USP(a1)
bne fw_Error
IF FW_TOP_BOTTOM_MEM_SECTIONS
move.w fw_MainMemDirection(a6),ft_MemDirection(a1)
ENDC
move.l a2,-(sp)
lea ft_StackEnd(a1),a2
exg a2,sp ; temporarily swap stack pointers
move.l a1,-(sp) ; keep node for cleanup
pea .cleanup(pc) ; routine to call after RTS from backgroundtask
move.l a0,-(sp) ; background task to jump to
clr.w -(sp) ; initial ccr
movem.l d0-d7/a0-a6,-(sp) ; initial register dump from caller
move.l sp,ft_USP(a1)
exg a2,sp
move.l (sp)+,(8+2)*4(a2) ; restore a2 to stack
move.l (8+2)*4(a2),a2 ; restore a2 to register
lea fw_Tasks(a6),a0
DISABLE_INTS
bsr fw_EnqueueNode
ENABLE_INTS
rts
.cleanup
;move.l fw_BasePtr(pc),a6
move.l (sp)+,a1 ; suppress M68kDeadWrite used by REMOVE
PUTMSG 10,<"%d: background task %p (%s) finished">,fw_FrameCounterLong(a6),a1,LN_NAME(a1)
.waitforsafearea
move.l #$1ff00,d0
and.l vposr(a5),d0
cmp.l #307<<8,d0 ; we are too short before VBL, it's not safe to disable ints
bgt .waitforsafearea
DISABLE_INTS
clr.l ft_USP(a1) ; mark task finished
REMOVE
lea fw_Tasks(a6),a1
IFEMPTY a1,fw_KillTaskContext ; wait for doom
move.l LN_SUCC(a1),a0 ; hand over to next task
PUTMSG 40,<"Continuing to task %p (%s)">,a0,LN_NAME(a0)
move.l a0,fw_BackgroundTask(a6)
move.l ft_USP(a0),sp
ENABLE_INTS
movem.l (sp)+,d0-d7/a0-a6
rtr
;--------------------------------------------------------------------
fw_EnqueueNode:
move.b LN_PRI(a1),d1
move.l (a0),d0
.next
move.l d0,a0
move.l (a0),d0
beq.s .done
cmp.b LN_PRI(a0),d1
ble.s .next
.done
move.l LN_PRED(a0),d0
move.l a1,LN_PRED(a0)
move.l a0,(a1)
move.l d0,LN_PRED(a1)
move.l d0,a0
move.l a1,(a0)
rts
;--------------------------------------------------------------------
fw_KillTaskContext:
PUTMSG 50,<"KillTaskContext">
move.l fw_VBR(a6),a0
move.l fw_DefaultIRQ(a6),$6c(a0)
clr.l fw_BackgroundTask(a6) ; make sure we don't have a stray pointer
move.l fw_PrimaryUSP(a6),sp ; primary USP from before
clr.l fw_PrimaryUSP(a6)
move.w fw_MainCurrentFrame(a6),d0
ENABLE_INTS
.loop cmp.w fw_FrameCounter(a6),d0
beq.s .loop
rts
;--------------------------------------------------------------------
; Waits for next vertical blank and allows multitasking to happen.
;
; Note: Also checks left mouse button for exit if configured.
;
; In : -
; Out: All registers except for a5 and a6 may be trashed.
;
fw_VSyncWithTask:
move.l #$1ff00,d0
and.l vposr(a5),d0
cmp.l #FW_MAX_VPOS_FOR_BG_TASK<<8,d0 ; if we're too late, don't continue background task
bgt fw_VSync
IF FW_LMB_EXIT_SUPPORT
btst #6,$bfe001
beq .abortdemo
.noabort
ENDC
lea fw_Tasks(a6),a1
IFEMPTY a1,fw_VSync
SUCC a1,a1 ; take first task from list
; context switch takes a few hundred cycles (with idle DMA)
move.w fw_FrameCounter(a6),fw_MainCurrentFrame(a6)
.switch
PUTMSG 50,<"TaskSwitch %p">,a1
move.l sp,fw_PrimaryUSP(a6) ; store old stackpointer (pointing to RTS address)
move.l fw_VBR(a6),a0
move.l fw_MultitaskingIRQ(a6),$6c(a0)
PUTMSG 40,<"Switching to task %p (%s)">,a1,LN_NAME(a1)
move.l a1,fw_BackgroundTask(a6)
move.l ft_USP(a1),sp
movem.l (sp)+,d0-d7/a0-a6 ; restore context, 132 cycles (another >132 cycles in interrupt)
PUTMSG 50,<"RTR %p">,sp
rtr
IF FW_LMB_EXIT_SUPPORT
.abortdemo
move.l fw_DemoAbortStackPointer(a6),d0
beq.s .noabort
move.l d0,sp
rts
ENDC
;--------------------------------------------------------------------
; Allows the current task to switch CPU to the next task in queue.
;
; Usually may not be called from tasks, except if FW_YIELD_FROM_MAIN_TOO
; is set (then it will just call VSyncWithTask).
;
; Preserves all registers!
;
fw_Yield:
IF FW_YIELD_FROM_MAIN_TOO
tst.l fw_PrimaryUSP(a6)
bne.s .switch
; So we're not in a background task (method should actually not be used this way)
PUTMSG 50,<"Simple yield %p">,a7
PUSHM d0-d7/a0-a4
bsr fw_VSyncWithTask
POPM
rts
ENDC
.switch
PUSHM d0/a0
move.l #$1ff00,d0
and.l vposr(a5),d0
cmp.l #307<<8,d0 ; it's too close to VBL, we cannot safely disable ints
ble .cont
POPM NOBUMP
rts
.cont
DISABLE_INTS
move.l fw_BackgroundTask(a6),a0
TSTNODE a0,a0
POPM
bne.s .doswitch
PUTMSG 50,<"No more tasks">
subq.w #2,sp ; ccr can be anything
movem.l d0-d7/a0-a6,-(sp)
move.l fw_BackgroundTask(a6),a0
move.l sp,ft_USP(a0)
bra fw_KillTaskContext
.doswitch
; return address already on stack
subq.w #2,sp ; ccr can be anything
PUSHM d0-d7/a0-a6
move.l fw_BackgroundTask(a6),a0
move.l sp,ft_USP(a0)
SUCC a0,a0
PUTMSG 40,<"Yield to task %p (%s)">,a0,LN_NAME(a0)
move.l a0,fw_BackgroundTask(a6)
move.l ft_USP(a0),sp
ENABLE_INTS
POPM
rtr
;--------------------------------------------------------------------
; Makes sure the given task is finished.
;
; May only be called from main.
;
; In: a1 = task structure
;
; May trash all registers except a1
;
fw_WaitUntilTaskFinished:
.retry tst.l ft_USP(a1)
bne.s .wait
rts
.wait PUSHM a1
bsr fw_VSyncWithTask
POPM
bra.s .retry
;--------------------------------------------------------------------
; Removes the task from list if it was still running
;
; May only be called from main.
;
; In: a1 = task structure
; Trashes: a0/a1
fw_RemTask:
tst.l ft_USP(a1)
bne.s .remove
rts
.remove PUTMSG 10,<"%d: Removing still running task %p (%s)">,
clr.l ft_USP(a1)
REMOVE
rts
;--------------------------------------------------------------------
fw_backgroundtask_restore_irq:
PUTMSG 50,<"MTINT %lx">,$dff000+intenar
IF FW_COPPER_IRQ_SUPPORT
btst #INTB_COPER,$dff000+intreqr+1
bne fw_copper_irq
ENDC
move.l a6,-(sp) ; save a6, we need a spare register
move.l usp,a6 ; get USP
PUTMSG 50,<"USP %p">,a6
move.l 4+2(sp),-(a6) ; store PC
move.w 4(sp),-(a6) ; store SR
move.l (sp)+,-(a6) ; store a6 in stack frame
movem.l d0-d7/a0-a5,-(a6) ; store the rest of the registers
move.l a6,a0
move.l fw_BasePtr(pc),a6
move.l fw_BackgroundTask(a6),a1
move.l a0,ft_USP(a1) ; save USP for background task
IF FW_ROUNDROBIN_MT_SUPPORT
tst.b LN_PRI(a1)
bpl.s .tasklocked
move.l a1,a2
; REMOVE
move.l (a2)+,a0
move.l (a2),a2 ; LN_PRED
move.l a0,(a2)
move.l a2,LN_PRED(a0)
lea fw_Tasks+LN_PRED(a6),a0
; ADDTAIL
move.l LN_PRED(a0),d0
move.l a1,LN_PRED(a0)
exg d0,a0
movem.l d0/a0,(a1)
move.l a1,(a0)
.tasklocked
ENDC
clr.l fw_BackgroundTask(a6)
move.l fw_PrimaryUSP(a6),a0 ; primary USP from before
move.l (a0)+,2(sp) ; store return PC to exception frame (keep SR unchanged)
move.l a0,usp ; restore primary USP (now at position before calling the vblank wait)
clr.l fw_PrimaryUSP(a6)
PUTMSG 50,<"Restoring USP %p">,a0
move.l fw_VBR(a6),a0
move.l fw_DefaultIRQ(a6),$6c(a0)
lea $dff000,a5
move.w #INTF_VERTB,intreq(a5) ; acknowledge the vbl-irq.
move.w #INTF_VERTB,intreq(a5) ; acknowledge the vbl-irq.
addq.w #1,fw_FrameCounter(a6)
IF (FW_MUSIC_SUPPORT&FW_VBL_MUSIC_IRQ)
tst.w fw_MusicEnabled(a6)
beq.s .skipmus
bsr fw_MusicPlay
.skipmus
ENDC
IF FW_VBL_IRQ_SUPPORT
move.l fw_VBlankIRQ(a6),d0
beq.s .novbl1
move.l d0,a0
; IRQ may destroy everything here (except a5/a6)
jsr (a0)
.novbl1
ENDC
nop
rte
;--------------------------------------------------------------------
; Allows to run a specific task in parallel to the blitter.
;
; Make sure the blitter has been started and will not terminate within
; a few cycles (otherwise it might lose the interrupt).
;
; Due to the overhead, this routine is best used for
; - larger blits with idle cycles
; - larger blits with no idle cycles, but with blitter hogging off and
; slow CPU operations such as multiplications or division.
;
; Returns from this call, if either a blitter interrupt or VBL has
; occurred or the task finished execution. Thus you will still need to
; make sure that the blitter has finished before starting another blit.
; The task may be continued during another running blitter operation
; using YieldToBlitterTask. The task can be also finished ("joined")
; synchroneously using FinishBlitterTask.
;
; Compared to a blitter queue or normal background task, this allows more
; fine grained control over the operations to perform during specific blits.
; It also has little complexity overhead, works well when combining large
; (with bg task) and small (without separate task) blits.
;
; Although it might be possible to use this across VBL, it is not recommended.
; A VBL will interrupt the blitter task early even if the blitter is still
; running for some more time.
;
; Note: The task must preserve a5/a6 until exit! This task may not Yield!
; May only be called from the main task!
;
; Trashes all registers except for a5/a6
;
IF FW_BLITTERTASK_MT_SUPPORT
fw_AddAndRunBlitterTask:
DISABLE_INTS
move.w #INTF_BLIT,intreq(a5) ; clear the blitter-irq.
move.l a1,fw_BackgroundTask(a6)
.switch
move.l sp,fw_PrimaryUSP(a6) ; store old stackpointer (pointing to RTS address)
PUTMSG 50,<"Blitter TaskSwitch %p">,a1
lea ft_StackEnd(a1),sp
clr.l -(sp) ; a little space for the task stackpointer
pea .cleanup(pc) ; routine to call after RTS from backgroundtask
move.l a0,-(sp) ; background task to jump to
move.l fw_VBR(a6),a0
move.l fw_BlitterTaskIRQ(a6),$6c(a0)
move.w #INTF_SETCLR|INTF_INTEN|INTF_BLIT,intena(a5) ; enable interrupts, including blitter int
rts
.cleanup
move.w #INTF_INTEN|INTF_BLIT,intena(a5) ; disable interrupts, including blitter int
move.w #INTF_INTEN|INTF_BLIT,intena(a5) ; disable interrupts, including blitter int
; FIXME do we have a race condition here? What happens if the blitter finishes right before this instruction?
;move.l fw_BasePtr(pc),a6
move.l fw_PrimaryUSP(a6),d0
bne.s .irqcleanup
move.l (sp)+,sp ; we're coming from FinishBlitterTask
ENABLE_INTS
rts
.irqcleanup
PUTMSG 30,<"%d: blitter task finished">,fw_FrameCounterLong(a6)
move.l fw_VBR(a6),a0
move.l fw_DefaultIRQ(a6),$6c(a0)
clr.l fw_BackgroundTask(a6) ; make sure we don't have a stray pointer
move.l d0,sp ; switch to primary task
clr.l fw_PrimaryUSP(a6)
move.w #INTF_BLIT,intena(a5) ; disable blitter int again
ENABLE_INTS
rts
;--------------------------------------------------------------------
; Allows the current task to switch CPU to the current blitter task.
;
; Returns from this call immediately if the task was already finished.
; May return later if either a blitter interrupt or VBL has
; occurred or the task finished execution.
; The task can be also finished synchroneously using FinishBlitterTask.
;
; May only be called from the main task!
;
; In: a0 = task
; Trashes all registers except for a5/a6
;
fw_YieldToBlitterTask:
move.l fw_BackgroundTask(a6),d0
beq.s .noswitch
DISABLE_INTS
move.w #INTF_BLIT,intreq(a5) ; clear the blitter-irq.
move.l sp,fw_PrimaryUSP(a6) ; store old stackpointer (pointing to RTS address)
move.l d0,a0
move.l ft_USP(a0),sp
PUTMSG 40,<"Yielding to Blitter task %p (%s)">,a0,LN_NAME(a0)
move.l fw_VBR(a6),a0
move.l fw_BlitterTaskIRQ(a6),$6c(a0)
movem.l (sp)+,d0-d7/a0-a6
move.w #INTF_SETCLR|INTF_INTEN|INTF_BLIT,intena(a5) ; enable interrupts, including blitter int
rtr
.noswitch
PUTMSG 50,<"Blitter task not available">
rts
;--------------------------------------------------------------------
; Finish Blitter parallel task outside of blitter action.
;
; Returns from this call, immediately if the task was already finished.
; Otherwise, runs the task until the end.
;
; May only be called from the main task!
;
; Trashes all registers except for a5/a6
;
fw_FinishBlitterTask:
DISABLE_INTS
move.l fw_BackgroundTask(a6),d0
bne.s .doswitch
PUTMSG 50,<"Blitter task not available">
ENABLE_INTS
rts
.doswitch
move.l d0,a0
PUTMSG 50,<"Restoring Blitter Task %p">,a0
clr.l fw_BackgroundTask(a6)
move.l sp,ft_StackEnd-4(a0)
move.l ft_USP(a0),sp
ENABLE_INTS
movem.l (sp)+,d0-d7/a0-a6
rtr
;--------------------------------------------------------------------
fw_blitter_task_irq:
PUTMSG 50,<"BLINT %lx">,$dff000+intenar
IF FW_COPPER_IRQ_SUPPORT
btst #INTB_COPER,$dff000+intreqr+1
bne fw_copper_irq
ENDC
move.l a6,-(sp) ; save a6, we need a spare register
move.l usp,a6 ; get USP
PUTMSG 50,<"USP %p">,a6
move.l 4+2(sp),-(a6) ; store PC
move.w 4(sp),-(a6) ; store SR
move.l (sp)+,-(a6) ; store a6 in stack frame
movem.l d0-d7/a0-a5,-(a6) ; store the rest of the registers
move.l a6,a0
move.l fw_BasePtr(pc),a6
move.l fw_BackgroundTask(a6),a1
move.l a0,ft_USP(a1) ; save USP for background task
move.l fw_PrimaryUSP(a6),a0 ; primary USP from before
move.l (a0)+,2(sp) ; store return PC to exception frame (keep SR unchanged)
move.l a0,usp ; restore primary USP (now at position before calling the vblank wait)
clr.l fw_PrimaryUSP(a6)
lea $dff000,a5
move.w #INTF_BLIT,intreq(a5) ; acknowledge the blitter irq.
move.w #INTF_BLIT,intena(a5) ; disable the blitter irq
PUTMSG 50,<"Restoring USP %p">,a0
move.l fw_VBR(a6),a0
move.l fw_DefaultIRQ(a6),$6c(a0)
nop
rte
ENDC

View File

@ -0,0 +1,902 @@
;------------------------------------------------------
; MFM trackloader based on Photon/Scoopex old snippets
; Changes by Michael "Axis" Hillebrandt.
; Completely reworked by Chris 'platon42' Hodges.
;------------------------------------------------------
MFMsync = $4489
MFMBUFSIZE = 12800
IF FW_MULTITASKING_SUPPORT
IFEQ FW_YIELD_FROM_MAIN_TOO
fail "Trackloader will be called from main task, too"
ENDC
TRKLDRYIELD MACRO
bsr fw_Yield
ENDM
ELSE
TRKLDRYIELD MACRO
ENDM
ENDC
; Initializes the loader, turns motor on and steps to track 0
fw_InitTrackLoader:
move.l #MFMBUFSIZE,d0
bsr fw_AllocChip
move.l a0,fw_MfmTrackBuffer(a6)
move.l #11*512,d0
bsr fw_AllocFast
move.l a0,fw_TrackBuffer(a6)
PUSHM a4
PUTMSG 10,<"MfmTrack buffer at %p, decoded Track buffer at %p">,fw_MfmTrackBuffer(a6),fw_TrackBuffer(a6)
lea $bfd100,a4
clr.w fw_CurrentHead(a6)
;clr.w fw_CurrentDrive(a6)
IF FW_MULTITASKING_SUPPORT
move.w #1,fw_TrackloaderIdle(a6)
ENDC
moveq.l #-1,d0
move.w d0,fw_LastMfmTrack(a6)
move.w d0,fw_LastTrack(a6)
clr.l fw_TrackChecksum(a6)
bsr fw_FindRightFloppyDriveUnit
POPM
rts
; Turns on motor if not already on
fw_TrackloaderDiskMotorOn:
tst.w fw_DriveMotorOn(a6)
bne.s .skip
PUSHM a4
lea $bfd100,a4
bsr fw_MotorOn
POPM
.skip
rts
; Turns the motor off (after reading has completed)
fw_TrackloaderDiskMotorOff:
PUSHM a4
lea $bfd100,a4
bsr fw_MotorOff
POPM
rts
;--------------------------------------------------------------------
; Load data from disk
;
; In : a0: buffer to load the data into
; d0: disk starting offset
; d1: length in bytes
;
fw_TrackloaderLoad:
PUSHM d4-d7/a4
lea $bfd100,a4
lea .plaincopy(pc),a2
bsr fw_LoadMFM
POPM
rts
.plaincopy
PUTMSG 10,<"Copying %d bytes (%ld left) from %p to %p">,d3,d7,a1,a3
subq.w #1,d3
lsr.w #1,d3
.copyloop
move.w (a1)+,(a3)+
dbra d3,.copyloop
rts
;--------------------------------------------------------------------
; Load LZ4 compressed data from disk and decompress it while loading
;
; In : a0: buffer to load the data into
; d0: disk starting offset
; d1: compressed length in bytes
;
IF FW_TRACKMO_LZ4_SUPPORT
fw_TrackloaderLoadAndDecrunchLZ4:
PUSHM d4-d7/a4
lea $bfd100,a4
lea .lz4decode(pc),a2
clr.w fw_TrackLz4State(a6)
bsr fw_LoadMFM
POPM
rts
.lz4decode
moveq.l #0,d5
move.w fw_TrackLz4State(a6),d5
PUTMSG 50,<"LZ4 State %d %ld bytes, %ld left from %p to %p">,d5,d3,d7,a1,a3
lea .lz4states(pc),a0
adda.w (a0,d5.w),a0
jmp (a0)
.lz4states
dc.w .lzstart-.lz4states ; 0
dc.w .lzlitsizeentry-.lz4states ; 2
dc.w .lzlitcopy-.lz4states ; 4
dc.w .lzreadoffsetlo-.lz4states ; 6
dc.w .lzreadoffsethi-.lz4states ; 8
dc.w .lzmatchlengthentry-.lz4states ; 10
.lzstart
moveq.l #0,d0
move.b (a1)+,d0
moveq.l #15,d1
and.w d0,d1
lsr.b #4,d0
move.w d0,fw_TrackLz4LiteralLength(a6)
move.w d1,fw_TrackLz4MatchLength(a6)
moveq.l #2,d5 ; next state (lit size)
cmp.w #15,d0
blt.s .lzlitsizefinished
.lzlitsizeloop
subq.w #1,d3
beq.s .lzstateterm ; buffer ends before literal size finalized
.lzlitsizeentry
moveq.l #0,d0
move.b (a1)+,d0
add.w d0,fw_TrackLz4LiteralLength(a6)
not.b d0
beq.s .lzlitsizeloop
.lzlitsizefinished
moveq.l #4,d5 ; next state (lit copy)
subq.w #1,d3
beq.s .lzstateterm ; buffer ends right after literal size finished
.lzlitcopy
move.w fw_TrackLz4LiteralLength(a6),d0
beq.s .lznoliterals ; literal size is 0, skip copying literals
cmp.w d3,d0
ble.s .lzfulllitcopy
; at least one byte is leftover
.lzlitcopyuntileob
move.w d3,d0
sub.w d3,fw_TrackLz4LiteralLength(a6) ; deduct from literal size
subq.w #1,d3
.lzlitcopyloopeob
move.b (a1)+,(a3)+
dbra d3,.lzlitcopyloopeob
bra .lzstateterm
.lzstateterm
PUTMSG 40,<"Terminated at %p (output %p)">,a1,a3
move.w d5,fw_TrackLz4State(a6)
rts
.lzfulllitcopy
sub.w d0,d3
subq.w #1,d0
.lzlitcopyloop
move.b (a1)+,(a3)+
dbra d0,.lzlitcopyloop
.lznoliterals
moveq.l #6,d5 ; next state (match offset hi)
tst.w d3
beq.s .lzstateterm ; buffer ended right after lit copy
.lzreadoffsetlo
move.b (a1)+,fw_TrackLz4Offset+3(a6)
moveq.l #8,d5 ; next state (match offset lo)
subq.w #1,d3
beq.s .lzstateterm ; buffer ended right after offset lo
.lzreadoffsethi
move.b (a1)+,fw_TrackLz4Offset+2(a6)
moveq.l #10,d5 ; next state (additional match length)
moveq.l #0,d0
move.w fw_TrackLz4MatchLength(a6),d1
cmp.w #15,d1
blt.s .lzskipmatchlength
.lzmatchlengthloop
subq.w #1,d3
bne.s .lzmatchlengthenterloop
move.w d1,fw_TrackLz4MatchLength(a6)
bra.s .lzstateterm ; buffer ends before literal size finalized
.lzmatchlengthentry
move.w fw_TrackLz4MatchLength(a6),d1
moveq.l #0,d0
.lzmatchlengthenterloop
move.b (a1)+,d0
add.w d0,d1
not.b d0
beq.s .lzmatchlengthloop
.lzskipmatchlength
; copy match
addq.w #3,d1
move.l a3,a0
suba.l fw_TrackLz4Offset(a6),a0
.lzmatchcopy
move.b (a0)+,(a3)+
dbra d1,.lzmatchcopy
.lzskipmatch
moveq.l #0,d5 ; reset state machine
subq.w #1,d3
beq .lzstateterm ; buffer ends before next sequence
bra .lzstart ; start over
ENDC
;--------------------------------------------------------------------
; Load LZ4 and delta compressed data from disk and decompress it while loading
;
; In : a0: buffer to load the data into
; d0: disk starting offset
; d1: compressed length in bytes
;
IF FW_TRACKMO_LZ4_DLT8_SUPPORT
fw_TrackloaderLoadAndDecrunchLZ4Delta8:
PUSHM d4-d7/a4
lea $bfd100,a4
lea .lz4decode(pc),a2
clr.w fw_TrackLz4State(a6)
clr.b fw_TrackLz4Delta8Value(a6)
bsr fw_LoadMFM
POPM
rts
.lz4decode
moveq.l #0,d5
move.w fw_TrackLz4State(a6),d5
PUTMSG 50,<"LZ4 State %d %ld bytes, %ld left from %p to %p">,d5,d3,d7,a1,a3
lea .lz4states(pc),a0
adda.w (a0,d5.w),a0
jmp (a0)
.lz4states
dc.w .lzstart-.lz4states ; 0
dc.w .lzlitsizeentry-.lz4states ; 2
dc.w .lzlitcopy-.lz4states ; 4
dc.w .lzreadoffsetlo-.lz4states ; 6
dc.w .lzreadoffsethi-.lz4states ; 8
dc.w .lzmatchlengthentry-.lz4states ; 10
.lzstart
moveq.l #0,d0
move.b (a1)+,d0
moveq.l #15,d1
and.w d0,d1
lsr.b #4,d0
move.w d0,fw_TrackLz4LiteralLength(a6)
move.w d1,fw_TrackLz4MatchLength(a6)
moveq.l #2,d5 ; next state (lit size)
cmp.w #15,d0
blt.s .lzlitsizefinished
.lzlitsizeloop
subq.w #1,d3
beq.s .lzstateterm ; buffer ends before literal size finalized
.lzlitsizeentry
moveq.l #0,d0
move.b (a1)+,d0
add.w d0,fw_TrackLz4LiteralLength(a6)
not.b d0
beq.s .lzlitsizeloop
.lzlitsizefinished
moveq.l #4,d5 ; next state (lit copy)
subq.w #1,d3
beq.s .lzstateterm ; buffer ends right after literal size finished
.lzlitcopy
move.w fw_TrackLz4LiteralLength(a6),d0
beq.s .lznoliterals ; literal size is 0, skip copying literals
cmp.w d3,d0
ble.s .lzfulllitcopy
; at least one byte is leftover
.lzlitcopyuntileob
move.w d3,d0
sub.w d3,fw_TrackLz4LiteralLength(a6) ; deduct from literal size
subq.w #1,d3
move.b fw_TrackLz4Delta8Value(a6),d4
.lzlitcopyloopeob
add.b (a1)+,d4
move.b d4,(a3)+
dbra d3,.lzlitcopyloopeob
move.b d4,fw_TrackLz4Delta8Value(a6)
bra .lzstateterm
.lzstateterm
PUTMSG 40,<"Terminated at %p (output %p)">,a1,a3
move.w d5,fw_TrackLz4State(a6)
rts
.lzfulllitcopy
sub.w d0,d3
subq.w #1,d0
move.b fw_TrackLz4Delta8Value(a6),d4
.lzlitcopyloop
add.b (a1)+,d4
move.b d4,(a3)+
dbra d0,.lzlitcopyloop
move.b d4,fw_TrackLz4Delta8Value(a6)
.lznoliterals
moveq.l #6,d5 ; next state (match offset hi)
tst.w d3
beq.s .lzstateterm ; buffer ended right after lit copy
.lzreadoffsetlo
move.b (a1)+,fw_TrackLz4Offset+3(a6)
moveq.l #8,d5 ; next state (match offset lo)
subq.w #1,d3
beq.s .lzstateterm ; buffer ended right after offset lo
.lzreadoffsethi
move.b (a1)+,fw_TrackLz4Offset+2(a6)
moveq.l #10,d5 ; next state (additional match length)
moveq.l #0,d0
move.w fw_TrackLz4MatchLength(a6),d1
cmp.w #15,d1
blt.s .lzskipmatchlength
.lzmatchlengthloop
subq.w #1,d3
bne.s .lzmatchlengthenterloop
move.w d1,fw_TrackLz4MatchLength(a6)
bra.s .lzstateterm ; buffer ends before literal size finalized
.lzmatchlengthentry
move.w fw_TrackLz4MatchLength(a6),d1
moveq.l #0,d0
.lzmatchlengthenterloop
move.b (a1)+,d0
add.w d0,d1
not.b d0
beq.s .lzmatchlengthloop
.lzskipmatchlength
; copy match
addq.w #3,d1
move.l a3,a0
suba.l fw_TrackLz4Offset(a6),a0
move.b fw_TrackLz4Delta8Value(a6),d4
.lzmatchcopy
move.b (a0)+,d0
sub.b -2(a0),d0
add.b d0,d4
move.b d4,(a3)+
dbra d1,.lzmatchcopy
move.b d4,fw_TrackLz4Delta8Value(a6)
.lzskipmatch
moveq.l #0,d5 ; reset state machine
subq.w #1,d3
beq .lzstateterm ; buffer ends before next sequence
bra .lzstart ; start over
ENDC
;--------------------------------------------------------------------
; Waits for a diskchange (disk is removed and inserted again)
;
fw_TrackloaderWaitForDiskChange:
PUSHM a4
lea $bfd100,a4
.ready TRKLDRYIELD
btst #CIAB_DSKRDY,$bfe001-$bfd100(a4)
bne.s .ready
.notready
TRKLDRYIELD
btst #CIAB_DSKRDY,$bfe001-$bfd100(a4)
beq.s .notready
bsr fw_MotorOff
POPM
rts
; Load sectors from disk
; a0 - buffer to load the data into (must be even)
; a2 - routine to be called for post processing buffer with a3 current buffer pos, a1, trackdisk buffer, d3 length
; d0.l - disk offset (must be even)
; d1.l - bytes to read (may be odd, but one extra byte will be written then)
; returns a1 end of buffer written
fw_LoadMFM:
PUTMSG 10,<"%d: LoadMFM of %ld bytes at offset %ld to %p">,fw_FrameCounterLong(a6),d1,d0,a0
IF FW_MULTITASKING_SUPPORT
.retry
subq.w #1,fw_TrackloaderIdle(a6)
beq.s .notbusy
addq.w #1,fw_TrackloaderIdle(a6)
PUTMSG 10,<"Trackloader busy! %p">,sp
.wait
TRKLDRYIELD
tst.w fw_TrackloaderIdle(a6)
ble.s .wait
bra.s .retry
.notbusy
ENDC
PUSHM d6-d7/a3
divu #11*512,d0
move.l d0,d6 ; starting track / offset
move.l d1,d7 ; length
move.l a0,a3
cmp.w fw_LastTrack(a6),d6
beq .righttrack
.wrongtrack
cmp.w fw_LastMfmTrack(a6),d6
beq.s .rightmfmtrackbutnotyetdecoded
tst.w fw_MfmReadingTriggered(a6)
beq.s .noreadinginprogress
PUTMSG 10,<"Wrong track reading in progress... please wait">
bsr fw_WaitForTrackDmaDone
PUTMSG 10,<"DMA done">
.noreadinginprogress
tst.w fw_DriveMotorOn(a6)
bne.s .noturnon
bsr fw_MotorOn
.noturnon
bsr fw_StepToRightCylinderAndSelectRightHead
bsr fw_TriggerReadTrack
.nexttrack
.rightmfmtrackbutnotyetdecoded
bsr fw_WaitForTrackDmaDone
tst.w fw_DriveMotorOn(a6)
bne.s .noturnon2
bsr fw_MotorOn
.noturnon2
bsr fw_PreparePrefetchOfNextTrack
bsr fw_DecodeMfmTrack
tst.w fw_MfmDoPrefetch(a6)
beq.s .noprefetch
PUTMSG 30,<"Prefetching next track">
bsr fw_TriggerReadTrack
.noprefetch
.righttrack
move.l d6,d1
swap d1 ; start offset inside track
move.l fw_TrackBuffer(a6),a1 ; start in track buffer
adda.w d1,a1
move.w #11*512,d3
sub.w d1,d3
ext.l d3
cmp.l d7,d3
ble.s .notcompleteinbuffer
move.w d7,d3
.notcompleteinbuffer
sub.l d3,d7
jsr (a2)
tst.l d7
beq.s .finished
swap d6
clr.w d6 ; next track always starts at offset 0
swap d6
bra .nexttrack
.finished
move.l a3,a1
POPM
PUTMSG 10,<"%d: Data load finished">,fw_FrameCounterLong(a6)
IF FW_MULTITASKING_SUPPORT
addq.w #1,fw_TrackloaderIdle(a6)
ENDC
;bsr.s MotorOff
rts
; Prefetch the next track to be loaded (but not decoded) into MFM buffer
fw_PreparePrefetchOfNextTrack:
PUTMSG 20,<"%d: PreparePrefetchOfNextTrack %d+1 (%d:%d)">,fw_FrameCounterLong(a6),fw_LastMfmTrack-2(a6),fw_CurrentCylinder-2(a6),fw_CurrentHead-2(a6)
PUSHM d6
clr.w fw_MfmDoPrefetch(a6)
tst.w fw_MfmReadingTriggered(a6)
bne.s .noprefetch
move.w fw_CurrentCylinder(a6),d6
add.w d6,d6
add.w fw_CurrentHead(a6),d6
cmp.w fw_LastMfmTrack(a6),d6
bne.s .noprefetch
addq.w #1,d6
cmp.w #80*2,d6
bge.s .noprefetch
lsr.w #1,d6
bcs.s .head1pre
bsr fw_DriveStepHeadIn ; 1 cyl forward
bsr fw_SelectUpperHead
bra.s .prefetch
.head1pre
bsr fw_SelectLowerHead
.prefetch
st fw_MfmDoPrefetch(a6)
move.w #235,d0 ; 15 ms=235 scan lines!
bsr fw_SetDriveSettleTime
.noprefetch
POPM
rts
; d6=track
fw_StepToRightCylinderAndSelectRightHead:
PUTMSG 50,<"Select track %d">,d6
PUSHM a0/d0/d1/d6/d7
move.w d6,d7
lsr.w #1,d7
sub.w fw_CurrentCylinder(a6),d7 ;delta-step
beq.s .steppingdone
bmi.s .stepout
bsr.s fw_DriveStepHeadIn
subq.w #2,d7
bmi.s .steppingdone
.stepinloop
bsr fw_DriveStepHeadInFast
dbra d7,.stepinloop
bra.s .steppingdone
.stepout
neg.w d7 ; = neg+sub#1
bsr.s fw_DriveStepHeadOut
subq.w #2,d7
bmi.b .steppingdone
.stepoutloop
bsr.s fw_DriveStepHeadOutFast
dbra d7,.stepoutloop
.steppingdone
lsr.w #1,d6
bcs.s .head1
bsr.s fw_SelectUpperHead
bra.s .done
.head1
bsr fw_SelectLowerHead
.done
move.w #235,d0 ; 15 ms=235 scan lines!
bsr fw_SetDriveSettleTime
POPM
rts
; step head 1 track in and wait for timeout
fw_DriveStepHeadIn:
bsr fw_LoaderCiaWait
bclr #CIAB_DSKDIREC,(a4)
addq.w #1,fw_CurrentCylinder(a6)
PUTMSG 30,<"Step in %d">,fw_CurrentCylinder-2(a6)
fw_DriveStepHead:
bclr #CIAB_DSKSTEP,(a4)
bset #CIAB_DSKSTEP,(a4)
move.w #282,d0 ;18 ms=282 scan lines!
bra.s fw_SetDriveSettleTime
; step head 1 track in fast and wait for timeout (this can be used if the direction of the head didnt change)
fw_DriveStepHeadInFast:
addq.w #1,fw_CurrentCylinder(a6)
PUTMSG 30,<"Step in fast %d">,fw_CurrentCylinder-2(a6)
fw_DriveStepHeadFast:
bsr.s fw_LoaderCiaWait
bclr #CIAB_DSKSTEP,(a4)
bset #CIAB_DSKSTEP,(a4)
moveq.l #47,d0 ;3 ms=47 scan lines!
bra.s fw_SetDriveSettleTime
; step head 1 track out and wait for timeout
fw_DriveStepHeadOut:
bsr.s fw_LoaderCiaWait
bset #CIAB_DSKDIREC,(a4)
subq.w #1,fw_CurrentCylinder(a6)
PUTMSG 30,<"Step out %d">,fw_CurrentCylinder-2(a6)
bra.s fw_DriveStepHead
; step head 1 track out fast and wait for timeout (this can be used if the direction of the head didnt change)
fw_DriveStepHeadOutFast:
subq.w #1,fw_CurrentCylinder(a6)
PUTMSG 30,<"Step out fast %d">,fw_CurrentCylinder-2(a6)
bra.s fw_DriveStepHeadFast
;switch to upper head and wait for timeout
fw_SelectUpperHead:
bsr.s fw_LoaderCiaWait
PUTMSG 30,<"Head0">
bset #CIAB_DSKSIDE,(a4) ; Head 0
clr.w fw_CurrentHead(a6)
moveq.l #2,d0 ;0,1 ms=2 scan lines!
bra.s fw_SetDriveSettleTime
;switch to lower head and wait for timeout
fw_SelectLowerHead:
bsr.s fw_LoaderCiaWait
PUTMSG 30,<"Head1">
bclr #CIAB_DSKSIDE,(a4) ; Head 1
move.w #1,fw_CurrentHead(a6)
moveq.l #2,d0 ;0,1 ms=2 scan lines!
bra.s fw_SetDriveSettleTime
; move the head to track 0 (step out until track 0 is reached)
fw_DriveStepToCylinder0:
bsr.s fw_LoaderCiaWait
btst #CIAB_DSKTRACK0,$bfe001-$bfd100(a4) ;Cyl 0 when low.
beq.s .zeroreached
bsr fw_DriveStepHeadOut
.stepto0loop
btst #CIAB_DSKTRACK0,$bfe001-$bfd100(a4) ;Cyl 0 when low.
beq.s .zeroreached
bsr fw_DriveStepHeadOutFast
bra.s .stepto0loop
.zeroreached
PUTMSG 30,<"Cylinder0">
clr.w fw_CurrentCylinder(a6)
rts
fw_SetDriveSettleTime:
moveq.l #0,d1
move.b $bfda00-$bfd100(a4),d1
swap d1
move.b $bfd900-$bfd100(a4),-(sp)
move.w (sp)+,d1
move.b $bfd800-$bfd100(a4),d1
ext.l d0
add.l d1,d0
move.l d0,fw_DriveSettleTime(a6)
rts
;wait the specified amount of rasterlines
;d0 - amount of scanlines
fw_LoaderCiaWait:
IF FW_MULTITASKING_SUPPORT
bra.s .skipyield
.yieldloop
cmp.w #-50,d1
bgt.s .skipyield
TRKLDRYIELD
.skipyield
ELSE
.yieldloop
ENDC
moveq.l #0,d1
move.b $bfda00-$bfd100(a4),d1
swap d1
move.b $bfd900-$bfd100(a4),-(sp)
move.w (sp)+,d1
move.b $bfd800-$bfd100(a4),d1
sub.l fw_DriveSettleTime(a6),d1
blt.s .yieldloop
PUTMSG 40,<"%ld: YD">,d1
rts
fw_FindRightFloppyDriveUnit:
move.l 4.w,a0
cmp.w #37,LIB_VERSION(a0)
bhs.s .checkdrives
PUTMSG 10,<"LameOS, no drives check">
; kick 1.3 can only boot from DF0
bsr fw_MotorOn
bsr fw_DriveStepToCylinder0
rts
.checkdrives
.retry
move.w fw_CurrentDrive(a6),d0
PUTMSG 30,<"Checking disk in drive %d">,d0
addq.w #CIAB_DSKSEL0,d0
or.b #CIAF_DSKSEL0|CIAF_DSKSEL1|CIAF_DSKSEL2|CIAF_DSKSEL3,(a4)
bclr d0,(a4)
bsr fw_DriveStepToCylinder0
bsr fw_DriveStepHeadIn
bsr fw_DriveStepHeadOut
btst #CIAB_DSKCHANGE,$bfe001-$bfd100(a4)
bne.s .found
move.w fw_CurrentDrive(a6),d0
addq.w #1,d0
cmp.w #4,d0
beq.s .error
move.w d0,fw_CurrentDrive(a6)
bra.s .retry
.found PUTMSG 10,<"Found valid floppy">
bsr fw_MotorOn
rts
.error
PUTMSG 10,<"No valid floppy found">
move.w #ERROR_DISK,d0
bra fw_Error
; turn the floppy motor on and wait until the motor is running
fw_MotorOn:
PUTMSG 10,<"%d: Motor on">,fw_FrameCounterLong(a6)
move.w fw_CurrentDrive(a6),d0
addq.w #CIAB_DSKSEL0,d0
or.b #CIAF_DSKSEL0|CIAF_DSKSEL1|CIAF_DSKSEL2|CIAF_DSKSEL3,(a4)
;bset d0,(a4)
bclr #CIAB_DSKMOTOR,(a4) ; turns motor on
bclr d0,(a4)
move.w fw_FrameCounter(a6),d0
add.w #25,d0 ; 500 ms delay max
.diskreadyloop
TRKLDRYIELD
cmp.w fw_FrameCounter(a6),d0
beq.s .diskreadybroken
btst #CIAB_DSKRDY,$bfe001-$bfd100(a4) ; wait until motor running
bne.s .diskreadyloop
.diskreadybroken
st fw_DriveMotorOn(a6)
rts
; turn the floppy motor off
fw_MotorOff:
.retry
tst.w fw_MfmReadingTriggered(a6)
beq.s .noreadinginprogress
PUTMSG 10,<"%d: Waiting for read to finish before turning off motor">,fw_FrameCounterLong(a6)
bsr fw_WaitForTrackDmaDone
.noreadinginprogress
IF FW_MULTITASKING_SUPPORT
tst.w fw_TrackloaderIdle(a6)
bgt.s .nowait
TRKLDRYIELD
bra.s .retry
ENDC
.nowait
PUTMSG 10,<"%d: Motor Off">,fw_FrameCounterLong(a6)
move.w fw_CurrentDrive(a6),d0
addq.w #CIAB_DSKSEL0,d0
bset d0,(a4)
bset #CIAB_DSKMOTOR,(a4)
bclr d0,(a4)
clr.w fw_DriveMotorOn(a6)
rts
; trigger reading of one track
; trashes a1, d0
fw_TriggerReadTrack:
tst.w fw_MfmReadingTriggered(a6)
bne fw_Error
move.w fw_CurrentCylinder(a6),d0
add.w d0,d0
add.w fw_CurrentHead(a6),d0
cmp.w fw_LastMfmTrack(a6),d0
bne.s .cont
PUTMSG 30,<"MfmTrack already read %d">,d0
rts
.cont
PUTMSG 20,<"%d: Triggered reading of track %d">,fw_FrameCounterLong(a6),d0
clr.w fw_MfmReadingDone(a6)
move.w d0,fw_LastMfmTrack(a6)
bsr fw_LoaderCiaWait ; wait settle time
move.l fw_MfmTrackBuffer(a6),a1
move.w #INTF_DSKBLK,intreq(a5)
move.w #MFMsync,MFMBUFSIZE-2(a1) ; make sure we get another sync match at the end of buffer
clr.w (a1)+
move.l a1,dskpt(a5)
move.w #DMAF_SETCLR|DMAF_MASTER|DMAF_DISK,dmacon(a5)
move.w #MFMsync,dsksync(a5)
move.w #ADKF_SETCLR|ADKF_MFMPREC|ADKF_WORDSYNC|ADKF_FAST,adkcon(a5)
move.w #$4000,dsklen(a5)
move.w #$8000+(MFMBUFSIZE/2)-2,dsklen(a5) ; DskLen(12800)+DmaEn
move.w #$8000+(MFMBUFSIZE/2)-2,dsklen(a5) ; start reading MFMdata
st fw_MfmReadingTriggered(a6)
rts
fw_WaitForTrackDmaDone:
tst.w fw_MfmReadingTriggered(a6)
bne.s .waitdma
rts
.waitdma
.rereadwaitdma
PUTMSG 40,<"%d: MFM Wait">,fw_FrameCounterLong(a6)
IF FW_MULTITASKING_SUPPORT
bra.s .firstskipyield
ENDC
.waitdmadone
TRKLDRYIELD
.firstskipyield
btst #INTB_DSKBLK,intreqr+1(a5) ; wait until data read
beq.s .waitdmadone
PUTMSG 20,<"%d: MFM Done">,fw_FrameCounterLong(a6)
st fw_MfmReadingDone(a6)
clr.w fw_MfmReadingTriggered(a6)
rts
; Decode the loaded MFM track
fw_DecodeMfmTrack:
PUSHM a2-a3/d7
.rereadwaitdma
bsr fw_WaitForTrackDmaDone
PUTMSG 20,<"%d: Decoding Track %d">,fw_FrameCounterLong(a6),fw_LastMfmTrack-2(a6)
move.w #-1,fw_LastTrack(a6) ; mark last track buffer as invalid in case of error
move.l #$55555555,d3 ; and-const
move.l fw_MfmTrackBuffer(a6),a1
; This routine is trickier than it appears. The trick is that we must NOT
; assume a $4489 at the beginning of our buffer. This phenomenon occurs when
; the DMA starts in the middle of the first sync word. The second sync word
; is thrown away by the hardware. It sounds exotic, but it actually happens
; quite often!
cmp.w #MFMsync,2(a1)
beq.s .nofixsyncbug
PUTMSG 10,<"Fixing missing sync">
move.w #MFMsync,(a1)
.nofixsyncbug
moveq.l #0,d7
clr.l fw_TrackChecksum(a6)
.decode
.findsyncword
lea MFMBUFSIZE(a1),a2
.syncloop
PUTMSG 70,<"LW %lx">,(a1)
cmp.w #MFMsync,(a1)+ ; search for a sync word
bne.s .syncloop
PUTMSG 60,<"Sync %lx at %p">,(a1),a1
cmp.l a1,a2 ; check for end of buffer
beq .diskerror ; no more sync found
cmp.b (a1),d3 ; search for 0-nibble
bne.s .syncloop
bsr .decodemfmword
PUTMSG 60,<"SectorInfo %lx">,d0
move.b d0,d1
lsr.w #8,d0 ; sector number
cmp.w #11,d0
bge .diskerror
btst d0,d7
bne .diskerror
bset d0,d7 ; mark as decoded
add.w d0,d0 ; x512
lsl.w #8,d0
move.l fw_TrackBuffer(a6),a0
adda.w d0,a0
PUTMSG 60,<"Decoding %d to %p">,d0,a0
move.w d1,d4
lea 40(a1),a1 ; found a sec, skip unnecessary data
bsr .decodemfmword
move.l d0,d2 ; checksum
lea 512(a1),a2 ; first half of sector in a1 and second half in a2
moveq.l #(512/4)-1,d5
.decodeloop
move.l (a1)+,d0 ; decode fmtbyte/trk#,sec#,eow#
move.l (a2)+,d1
and.l d3,d0
and.l d3,d1
eor.l d0,d2 ; EOR with checksum
eor.l d1,d2 ; EOR with checksum
add.l d0,d0
or.l d1,d0 ; MFM decoded first longword
move.l d0,(a0)+
dbra d5,.decodeloop ; chksum should now be 0 if correct
or.l d2,fw_TrackChecksum(a6) ; or with track total chksum
cmp.b #1,d4
bne.s .nogapskip
PUTMSG 60,<"Skipping much of gap after decoding">
lea 300*2(a2),a2 ; gap of 300 words should be safe (340 is about normal)
.nogapskip
lea 6(a2),a1
cmp.w #(1<<11)-1,d7
bne .findsyncword ; decode until the bitmap is complete
PUTMSG 50,<"Track Checksum %lx">,fw_TrackChecksum(a6)
tst.l fw_TrackChecksum(a6) ; track total chksum OK?
bne .diskerror ; no, then retry
move.w fw_LastMfmTrack(a6),fw_LastTrack(a6)
move.w fw_LastMfmTrack(a6),d0
ext.l d0
PUTMSG 10,<"%d: Decoded Track %d">,fw_FrameCounterLong(a6),d0
POPM
rts
.decodemfmword
move.l (a1)+,d0 ; decode fmtbyte/trk#,sec#,eow#
move.l (a1)+,d1
and.l d3,d0
and.l d3,d1
add.l d0,d0
or.l d1,d0 ; MFM decoded first longword
rts
.diskerror
PUTMSG 10,<"Disk Error!">
move.w #$800,color(a5)
move.w #-1,fw_LastMfmTrack(a6)
bsr fw_TriggerReadTrack
bra .rereadwaitdma

View File

@ -0,0 +1,256 @@
;*****************************************************************
;
; Light Speed Player v1.11
; Fastest Amiga MOD player ever :)
; Written By Arnaud Carré (aka Leonard / OXYGENE)
; Adapted to demo framework (and optimized) by platon42.
;
; https://github.com/arnaud-carre/LSPlayer
; twitter: @leonard_coder
;
; "small & fast" player version ( average time: 1 scanline )
; Less than 512 bytes of code!
; You can also use generated "insane" player code for even more half scanline replayer (-insane option)
;
; LSP_MusicInit Initialize a LSP driver + relocate score&bank music data
; LSP_MusicPlayTick Play a LSP music (call it per frame)
; LSP_MusicGetPos Get mod seq pos (see -setpos option in LSPConvert)
; LSP_MusicSetPos Set mod seq pos (see -getpos option in LSPConvert)
;
;*****************************************************************
;------------------------------------------------------------------
;
; LSP_MusicPlayTick
;
; In: a5: should be $dff000
; Scratched regs: d0-d2/a0-a4
; Out:None
;
;------------------------------------------------------------------
LSP_MusicPlayTick:
addq.w #1,fw_MusicFrameCount(a6)
lea fw_LspByteStream(a6),a3
move.l (a3),a0 ; fw_LspByteStream, byte stream
move.l fw_LspCodeTableAddr(a6),a2 ; code table
.process
moveq.l #0,d0
move.b (a0)+,d0
beq.s .cextended
add.w d0,d0
move.w (a2,d0.w),d0 ; code
bne.s .cmdExec
.noInstBS
move.l a0,(a3) ; fw_LspByteStream, store byte stream if coming from early out
rts
.cextended
add.w #$0100,d0
move.b (a0)+,d0
beq.s .cextended
add.w d0,d0
move.w (a2,d0.w),d0 ; code
lea fw_LspEscCodeRewind(a6),a1
cmp.w (a1)+,d0 ; fw_LspEscCodeRewind
beq.s .r_rewind
cmp.w (a1)+,d0 ; fw_LspEscCodeSetBpm
beq.s .r_chgBpm
cmp.w (a1)+,d0 ; fw_LspEscCodeGetPos
bne.s .cmdExec
.r_setPos
move.b (a0)+,fw_LspCurrentSeq+1(a6)
bra.s .process
.r_rewind
move.l fw_LspByteStreamLoop(a6),a0
move.l fw_LspWordStreamLoop(a6),fw_LspWordStream(a6)
bra.s .process
.r_chgBpm
move.b (a0)+,fw_LspCurrentBpm+1(a6) ; BPM
bra.s .process
.cmdExec
add.b d0,d0
bcc.s .noVd
move.b (a0)+,aud3+ac_vol+1(a5)
.noVd add.b d0,d0
bcc.s .noVc
move.b (a0)+,aud2+ac_vol+1(a5)
.noVc add.b d0,d0
bcc.s .noVb
move.b (a0)+,aud1+ac_vol+1(a5)
.noVb add.b d0,d0
bcc.s .noVa
move.b (a0)+,aud0+ac_vol+1(a5)
.noVa
move.l a0,(a3)+ ; fw_LspByteStream, store byte stream ptr
move.l (a3),a0 ; fw_LspWordStream, word stream
tst.b d0
beq.s .noPa
add.b d0,d0
bcc.s .noPd
move.w (a0)+,aud3+ac_per(a5)
.noPd add.b d0,d0
bcc.s .noPc
move.w (a0)+,aud2+ac_per(a5)
.noPc add.b d0,d0
bcc.s .noPb
move.w (a0)+,aud1+ac_per(a5)
.noPb add.b d0,d0
bcc.s .noPa
move.w (a0)+,aud0+ac_per(a5)
.noPa
tst.w d0
beq.s .noInstWS
moveq.l #0,d1
move.l fw_LspInstruments(a6),a2 ; instrument table
lea fw_LspResetv+4*4(a6),a4
lea aud+3*ac_SIZEOF(a5),a1
moveq.l #4-1,d2
.vloop add.w d0,d0
bcs.s .setIns
add.w d0,d0
; suppress M68kUnexpectedConditionalInstruction
move.l -(a4),a3 ; take loop data
bcc.s .skip
move.l (a3)+,ac_ptr(a1) ; and update pointer/len with it
move.w (a3)+,ac_len(a1) ; (usually triggered from previous frame)
bra.s .skip
.setIns
add.w (a0)+,a2
add.w d0,d0
bcc.s .noReset
bset d2,d1
move.w d1,dmacon(a5)
.noReset
move.l (a2)+,ac_ptr(a1)
move.w (a2)+,ac_len(a1)
move.l a2,-(a4) ; set reset values for next iteration to contain loop data
.skip lea -ac_SIZEOF(a1),a1
dbra d2,.vloop
move.l fw_LspDmaConPatch(a6),a1 ; dmacon patch
move.b d1,(a1) ; dmacon
.noInstWS
move.l a0,fw_LspWordStream(a6) ; store word stream
rts
;------------------------------------------------------------------
;
; LSP_MusicInit
;
; In: a0: LSP music data (any memory)
; a1: LSP sound bank (chip memory)
;
;------------------------------------------------------------------
LSP_DataError:
illegal
LSP_MusicInit:
cmp.l #'LSP1',(a0)+
bne.s LSP_DataError
move.l (a0)+,d0 ; unique id
cmp.l (a1),d0 ; check that sample bank is this one
bne.s LSP_DataError
cmp.w #$010b,(a0)+ ; v1.11 minimal major & minor version of latest compatible
blt.s LSP_DataError
moveq.l #0,d1
bset d1,(a0) ; test and mark this music score as "relocated"
bne.s .noRelocate
move.l a1,d1
.noRelocate
addq.w #2,a0 ; skip relocation flag
lea fw_LspCurrentBpm(a6),a3
move.w (a0)+,(a3)+ ; fw_LspCurrentBpm
move.l a0,(a3)+ ; fw_LspInstruments, LSP data has -12 offset on instrument tab (to win 2 cycles in fast player :))
move.w (a0)+,(a3)+ ; fw_LspEscCodeRewind
move.l (a0)+,(a3)+ ; fw_LspEscCodeSetBpm/fw_LspEscCodeGetPos
move.l (a0)+,(a3)+ ; fw_LspMusicLength
move.w (a0)+,d0 ; instrument count
add.w d0,d0
subq.w #1,d0
.relocLoop
add.l d1,(a0)+
addq.l #2,a0
dbra d0,.relocLoop
move.w (a0)+,d0 ; codes table size
move.l a0,fw_LspCodeTableAddr(a6) ; code table
add.w d0,d0
add.w d0,a0
; read sequence timing infos (if any)
move.w (a0)+,d0
move.w d0,(a3)+ ; fw_LspSeqCount
move.l a0,(a3)+ ; fw_LspSeqTable
clr.w (a3)+ ; fw_LspCurrentSeq
move.w d0,d1
lsl.w #3,d1 ; 8 bytes per entry
adda.w d1,a0
movem.l (a0)+,d0/d1/d2 ; word stream size/byte stream loop point/word stream loop point
move.l a0,(a3)+ ; fw_LspStreamBase
lea (a0,d0.l),a1 ; byte stream
move.l a1,(a3)+ ; fw_LspByteStream
move.l a0,(a3)+ ; fw_LspWordStream
add.l d1,a1
add.l d2,a0
move.l a1,(a3)+ ; fw_LspByteStreamLoop
move.l a0,(a3)+ ; fw_LspWordStreamLoop
bset #1,$bfe001 ; disabling this fucking Low pass filter!!
rts
;------------------------------------------------------------------
;
; LSP_MusicSetPos
;
; In: d0: seq position (from 0 to last seq of the song)
; Out:None
;
; Force the replay pointer to a seq position. If music wasn't converted
; using -setpos option, this func does nothing
;
;------------------------------------------------------------------
LSP_MusicSetPos:
lea fw_LspSeqCount(a6),a1
cmp.w (a1)+,d0 ; fw_LspSeqCount
bge.s .noTimingInfo
move.l (a1)+,a0 ; fw_LspSeqTable
move.w d0,(a1)+ ; fw_LspCurrentSeq
lsl.w #3,d0
lea 8(a0,d0.w),a0
move.l (a1)+,d0 ; fw_LspStreamBase
move.l -(a0),d1
add.l d0,d1
move.l d1,(a1)+ ; fw_LspByteStream
move.l -(a0),d1
add.l d0,d1
move.l d1,(a1)+ ; fw_LspWordStream
.noTimingInfo
rts
IF 0
;------------------------------------------------------------------
;
; LSP_MusicGetPos
;
; In: None
; Out: d0: seq position (from 0 to last seq of the song)
;
; Get the current seq position. If music wasn't converted with
; -getpos option, this func just returns 0
;
;------------------------------------------------------------------
LSP_MusicGetPos:
move.w fw_LspCurrentSeq(a6),d0
rts
ENDC

View File

@ -0,0 +1,135 @@
;*****************************************************************
;
; Light Speed Player v1.11
; Fastest Amiga MOD player ever :)
; Written By Arnaud Carré (aka Leonard / OXYGENE)
; Slightly modified by platon42 for demo framework.
;
; https://github.com/arnaud-carre/LSPlayer
; twitter: @leonard_coder
;
; "cia" player version ( or "less effort" )
;
; Warnings:
; a) this file is provided for "easy of use". But if you're working
; on a cycle-optimizated demo effect, please call LightSpeedPlayer from your
; own existing interrupt and use copper to set DMACON 11 raster lines later
;
; b) this code doesn't restore any amiga OS stuff.
; ( are you a cycle-optimizer or what? :) )
;
; --------How to use---------
;
; bsr LSP_MusicDriver_CIA_Start : Init LSP player code and install CIA interrupt
; a0: LSP music data(any memory)
; a1: LSP sound bank(chip memory)
; a2: VBR (CPU Vector Base Register) ( use 0 if 68000 )
; d0: 0=PAL, 1=NTSC
;
; bsr LSP_MusicDriver_CIA_Stop : Stop LSP music replay
;
;*****************************************************************
LSP_MusicDriver_CIA_Stop:
move.b #$7f,$bfd000+ciaicr
move.w #INTF_EXTER,intena(a5)
move.w #INTF_EXTER,intreq(a5)
move.w #DMAF_AUDIO,dmacon(a5)
rts
LSP_MusicDriver_CIA_Start:
move.w d0,-(sp)
lea .dmaCon+1(pc),a2 ; DMACON byte patch address
clr.b (a2)
move.l a2,fw_LspDmaConPatch(a6)
bsr LSP_MusicInit ; init the LSP player ( whatever fast or insane version )
move.w fw_LspCurrentBpm(a6),d0
move.w d0,fw_LspLastCiaBpm(a6)
moveq #1,d1
and.w (sp)+,d1
; d0: music BPM
; d1: PAL(0) or NTSC(1)
.LSP_IrqInstall
move.w #INTF_EXTER,intena(a5) ; disable CIA interrupt
lea .LSP_MainIrq(pc),a0
move.l fw_VBR(a6),a2
move.l a0,$78(a2)
lea $bfd000,a0
move.b #$7f,ciaicr(a0)
move.b #CIACRAF_LOAD,ciacra(a0)
move.b #CIACRBF_LOAD,ciacrb(a0)
lsl.w #2,d1
move.l .palClocks(pc,d1.w),d1 ; PAL or NTSC clock
move.l d1,fw_LspCiaClock(a6)
divu.w d0,d1
move.b d1,ciatalo(a0)
lsr.w #8,d1
move.b d1,ciatahi(a0)
move.b #CIAICRF_SETCLR|CIAICRF_TA|CIAICRF_TB,ciaicr(a0)
move.b #CIACRAF_START|CIACRAF_LOAD,ciacra(a0)
move.b #496&$ff,ciatblo(a0) ; set timer b to 496 ( to set DMACON )
move.b #496>>8,ciatbhi(a0)
move.w #INTF_EXTER,intreq(a5) ; clear any req CIA
move.w #INTF_SETCLR|INTF_EXTER,intena(a5) ; CIA interrupt enabled
rts
.palClocks
dc.l 1773447,1789773
.dmaCon
dc.w $8000 ; we won't put this into the framework variables to the avoid need for relocation
.LSP_MainIrq
btst.b #CIAICRB_TA,$bfd000+ciaicr
beq.s .skipa
PUSHM d0-d2/a0-a6
; call player tick
lea $dff000,a5
move.l fw_BasePtr(pc),a6
bsr LSP_MusicPlayTick ; LSP main music driver tick
; check if BMP changed in the middle of the music
lea $bfd000,a4
move.w fw_LspCurrentBpm(a6),d0 ; current music BPM
cmp.w fw_LspLastCiaBpm(a6),d0
beq.s .noChg
move.w d0,fw_LspLastCiaBpm(a6) ; current BPM
move.l fw_LspCiaClock(a6),d1
divu.w d0,d1
move.b d1,ciatalo(a4)
lsr.w #8,d1
move.b d1,ciatahi(a4)
.noChg lea .LSP_DmaconIrq(pc),a0
move.l fw_VBR(a6),a1
move.l a0,$78(a1)
move.b #CIACRBF_START|CIACRBF_RUNMODE|CIACRBF_LOAD,ciacrb(a4) ; start timerB, one shot
POPM
.skipa
move.w #INTF_EXTER,$dff000+intreq
move.w #INTF_EXTER,$dff000+intreq
nop
rte
.LSP_DmaconIrq
btst.b #CIAICRB_TB,$bfd000+ciaicr
beq.s .skipb
PUSHM a0/a1
move.w .dmaCon(pc),$dff000+dmacon
move.l fw_BasePtr(pc),a1
lea .LSP_MainIrq(pc),a0
move.l fw_VBR(a1),a1
move.l a0,$78(a1)
POPM
.skipb
move.w #INTF_EXTER,$dff000+intreq
move.w #INTF_EXTER,$dff000+intreq
nop
rte

View File

@ -0,0 +1,36 @@
IF FW_VBL_MUSIC_IRQ
fail "FW_VBL_MUSIC_IRQ must be disabled"
ENDC
fw_MusicInit:
PUTMSG 10,<"Music-Init %p %p">,a0,a1
PUSHM d4-d7/a3-a4
move.l fw_VBR(a6),a2
IF FW_STANDALONE_FILE_MODE
move.l $78(a2),fw_OldCiaIRQ(a6)
ENDC
moveq.l #0,d0
bsr.s LSP_MusicDriver_CIA_Start
moveq.l #-1,d0
move.w d0,fw_MusicFrameCount(a6)
POPM
PUTMSG 10,<"Music-Init done">
rts
fw_MusicStop:
bsr.s LSP_MusicDriver_CIA_Stop
IF FW_STANDALONE_FILE_MODE
move.l fw_VBR(a6),a2
move.l fw_OldCiaIRQ(a6),$78(a2)
ENDC
rts
;--------------------------------------------------------------------
; sets the position if supported
; d0.w = new position
fw_MusicSetPosition:
bra LSP_MusicSetPos
include "../framework/musicplayers/lightspeedplayer_cia.asm"
include "../framework/musicplayers/lightspeedplayer.asm"

View File

@ -0,0 +1,30 @@
IFEQ FW_VBL_MUSIC_IRQ
fail "FW_VBL_MUSIC_IRQ must be enabled"
ENDC
fw_MusicInit:
PUTMSG 10,<"Music-Init %p %p">,a0,a1
bsr.s LSP_MusicInit
moveq.l #-1,d0
move.w d0,fw_MusicFrameCount(a6)
PUTMSG 10,<"Music-Init done">
rts
fw_MusicPlay:
PUSHM a4
bsr.s LSP_MusicPlayTick
POPM
rts
fw_MusicStop:
move.w #DMAF_AUDIO,dmacon(a5)
; unsupported right now
rts
;--------------------------------------------------------------------
; sets the position if supported
; d0.w = new position
fw_MusicSetPosition:
bra LSP_MusicSetPos
include "../framework/musicplayers/lightspeedplayer.asm"

View File

@ -0,0 +1,5 @@
fw_MusicInit:
fw_MusicStop:
fw_MusicPlay:
fw_MusicSetPosition:
rts

View File

@ -0,0 +1,64 @@
IFEQ FW_VBL_MUSIC_IRQ
fail "FW_VBL_MUSIC_IRQ must be enabled"
ENDC
IFEQ FW_DYNAMIC_MEMORY_SUPPORT
fail "FW_DYNAMIC_MEMORY_SUPPORT must be enabled"
ENDC
fw_MusicAlloc:
; actually $1C6E for player (V1.0), $984 for song
move.l #$1C6E+$984,d0
bsr fw_AllocFast
move.l a0,fw_PretrackerMyPlayer(a6)
lea $1C6E(a0),a0
move.l a0,fw_PretrackerMySong(a6)
rts
fw_MusicInit:
PUTMSG 10,<"%d: Pretracker song init %p %p">,fw_FrameCounterLong(a6),a0,a1
move.l a0,a2
PUSHM d7/a1
move.l fw_PretrackerMyPlayer(a6),a0
move.l fw_PretrackerMySong(a6),a1
PUTMSG 10,<"MyPlayer=%p MySong=%p Data=%p">,a0,a1,a2
lea fw_PretrackerReplayer(pc),a3
adda.w 2(a3),a3
jsr (a3) ; songInit
POPM
move.l a1,d1
bne.s .noalloc
PUTMSG 10,<"Allocating %ld bytes samples memory for Pretracker">,d0
bsr fw_AllocChip
move.l a0,fw_MusicSamples(a6)
move.l a0,a1
.noalloc
PUTMSG 10,<"%d: Pretracker player init">,fw_FrameCounterLong(a6)
move.l fw_PretrackerMyPlayer(a6),a0
move.l fw_PretrackerMySong(a6),a2
lea fw_PretrackerReplayer(pc),a3
adda.w 6(a3),a3
jsr (a3) ; playerInit
PUTMSG 10,<"%d: Pretracker init done">,fw_FrameCounterLong(a6)
rts
fw_MusicPlay:
move.l fw_PretrackerMyPlayer(a6),a0
lea fw_PretrackerReplayer(pc),a3
adda.w 10(a3),a3
jsr (a3) ; playerTick
rts
fw_MusicStop:
move.w #DMAF_AUDIO,dmacon(a5)
; unsupported right now
rts
;--------------------------------------------------------------------
fw_PretrackerReplayer:
;include "../framework/musicplayers/pretracker_replayer_resourced.asm"
incbin "../framework/musicplayers/pretracker_replayer_binary_blob.bin"

View File

@ -0,0 +1,71 @@
IFEQ FW_VBL_MUSIC_IRQ
fail "FW_VBL_MUSIC_IRQ must be enabled"
ENDC
IFEQ FW_DYNAMIC_MEMORY_SUPPORT
fail "FW_DYNAMIC_MEMORY_SUPPORT must be enabled"
ENDC
fw_MusicAlloc:
move.l #pv_SIZEOF+sv_SIZEOF,d0
bsr fw_AllocFast
move.l a0,fw_PretrackerMyPlayer(a6)
lea pv_SIZEOF(a0),a0
move.l a0,fw_PretrackerMySong(a6)
rts
fw_MusicInit:
PUTMSG 10,<"%d: Pretracker song init %p %p">,fw_FrameCounterLong(a6),a0,a1
move.l a0,a2
PUSHM d4-d7/a1/a4-a6
;move.l fw_PretrackerMyPlayer(a6),a0 ; unused
move.l fw_PretrackerMySong(a6),a1
PUTMSG 10,<"MyPlayer=%p MySong=%p Data=%p">,a0,a1,a2
bsr pre_SongInit
POPM
move.l a1,d1
bne.s .noalloc
PUTMSG 10,<"Allocating %ld bytes samples memory for Pretracker">,d0
bsr fw_AllocChip
move.l a0,fw_MusicSamples(a6)
move.l a0,a1
.noalloc
PUTMSG 10,<"%d: Pretracker player init">,fw_FrameCounterLong(a6)
move.l fw_PretrackerMyPlayer(a6),a0
move.l fw_PretrackerMySong(a6),a2
lea fw_PretrackerProgress(a6),a3
PUTMSG 10,<"Progress at %p">,a3
clr.l (a3)
PUSHM d4-d7/a4-a6
bsr pre_PlayerInit
POPM
PUTMSG 10,<"%d: Pretracker init done">,fw_FrameCounterLong(a6)
rts
fw_MusicPlay:
PUSHM d4-d7/a4-a6
move.l fw_PretrackerMyPlayer(a6),a0
move.l fw_PretrackerCopperlist(a6),a1
bsr.s pre_PlayerTick
POPM
rts
fw_MusicStop:
move.w #DMAF_AUDIO,dmacon(a5)
; unsupported right now
rts
;--------------------------------------------------------------------
; sets the position if supported
; d0.w = new position
fw_MusicSetPosition:
move.w d0,fw_PretrackerMySong+sv_curr_pat_pos_w(a6)
rts
;--------------------------------------------------------------------
PRETRACKER_COPPER_OUTPUT = FW_MUSIC_PLAYER_CHOICE-4
PRETRACKER_DONT_TRASH_REGS = 0
include "../framework/musicplayers/raspberry_casket.asm"

Some files were not shown because too many files have changed in this diff Show More