Initial version 1.0.

This commit is contained in:
Chris Hodges 2022-12-26 21:50:46 +01:00
parent e6d0cb88f4
commit be9dea0d67
16 changed files with 9964 additions and 2 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2022 chrisly42
Copyright (c) 2022 Chris 'platon42' Hodges <chrisly@platon42.de>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

101
README.md
View File

@ -1,2 +1,101 @@
# PretrackerRaspberryCasket
# Raspberry Casket
A fast and small open source Pretracker replayer
## Raspberry Casket Player V1.0 (26-Dec-2022)
Provided by Chris 'platon42' Hodges <chrisly@platon42.de>
Rewritten by *platon42/Desire* based on a resourced, binary identical
version of the original Pretracker V1.0 replayer binary provided
by *hitchhikr* (thanks!), originally written in C by *Pink/Abyss*.
This version is the hard work of reverse engineering all the
offsets, removing all the C compiler crud, removing dead and
surplus code (maybe artefacts from earlier ideas that did nothing),
optimizing the code where possible. This resulted in both reduced
size of the replayer, faster sample calculation and speeding the
tick routine up significantly.
I also added a few optional features that come in handy, such as
song-end detection and precalc progress support.
It took me more than a month and it was not fun.
Also: Open source. It's 2022, keeping the code closed is just not
part of the demoscene spirit (anymore?), at least for a replayer.
Also note that this is not the final state of the source code.
I could go over many places still and try to rework them.
But I wanted the code to be out in public.
### Verification
The replayer has been verified on about 60 Pretracker tunes to
create an identical internal state for each tick and identical
samples (if certain optimizations switches are disabled).
I might have introduced bugs though. If you find some problems,
please let me know under chrisly@platon42.de. Thank you.
### Usage
The new replayer comes as a drop-in binary replacement if you wish.
In this case you will get faster sample generation (about 12%
faster on 68000) and about 45% less CPU time spent. However, you
won't get stuff as song-end detection and precalc progress this way.
This mode uses the old CPU DMA wait that takes away 8 raster lines.
If you want to get rid of the unnecessary waiting, you can switch
to a copper driven audio control. If you want to use the top portion
of the copperlist for this, you probably need to double buffer it.
Otherwise, you could also position the copperlist at the end of
the display and use single buffering if you call the tick routine
during the vertical blank.
Please use the documented sizes for the `MySong` and `MyPlayer` data
structures, which are the symbols `sv_SIZEOF` and `pv_SIZEOF`
respectively (about 2K and 12K with volume table).
The source needs two common include files to compile (`custom.i` and
`dmabits.i`). You should leave assembler optimizations enabled.
1. (If you're using copper list mode, call `pre_PrepareCopperlist`.)
2. Call `pre_SongInit` with
- a pointer to `MySong` (`mv_SIZEOF`) in `a1` and
- the music data in `a2`.
It will return the amount of sample memory needed in `d0`.
3. Then call `pre_PlayerInit` with
- a pointer to `MyPlayer` (`pv_SIZEOF`) in `a0`
- a pointer to chip memory sample buffer in `a1`
- the pointer to `MySong` in `a2`
- a pointer to a longword for progress information or null in `a3`
This will create the samples, too.
4. After that, regularly call `pre_PlayerTick` with `MyPlayer` in `a0`
and optionally the copperlist in a1 if you're using that mode).
### Size
The original C compiled code was... just bad. The new binary is
about 1/3 of the original one.
The code has been also optimized in a way that it compresses better.
The original code compressed with *Blueberry's* Shrinkler goes from
18052 bytes down to 9023 bytes.
Raspberry Casket, depending on the features compiled in, is about
6374 bytes and goes down to ~4410 bytes (in isolation).
So this means that the optimization is not just "on the outside".
### Timing
Unfortunately, the replayer is still pretty slow and has high
jitter compared to other standard music replayers.
This means it may take up to 33 raster lines (14-19 on average)
which is significant more than a standard Protracker replayer
(the original one could take about 60 raster lines worst case and
about 34 on average!).
Watch out for *Presto*, the [LightSpeedPlayer](https://github.com/arnaud-carre/LSPlayer) variant that should
solve this problem.

Binary file not shown.

5
binaries/readme.txt Normal file
View File

@ -0,0 +1,5 @@
This file "raspberry_casket.bin" can replace the original "player.bin"
provided that you used the 16 KB + 16 KB allocation for player
variables as in the original player.
It has been assembled from src/drop_in_replacement.asm.

203
example/plastic_duff.asm Normal file
View File

@ -0,0 +1,203 @@
; Framework settings
FW_STANDALONE_FILE_MODE = 1 ; enable standalone (part testing)
FW_HD_TRACKMO_MODE = 0 ; DO NOT CHANGE (not supported for standalone mode)
FW_MUSIC_SUPPORT = 0
FW_MUSIC_PLAYER_CHOICE = 0 ; 0 = None, 1 = LSP, 2 = LSP_CIA, 3 = P61A, 4 = Pretracker Turbo, 5 = Pretracker Copper
FW_LMB_EXIT_SUPPORT = 1 ; allows abortion of intro with LMB
FW_MULTIPART_SUPPORT = 0 ; DO NOT CHANGE (not supported for standalone mode)
FW_DYNAMIC_MEMORY_SUPPORT = 0 ; enable dynamic memory allocation. Otherwise, use fw_ChipMemStack/End etc fields.
FW_MAX_MEMORY_STATES = 4 ; the amount of memory states
FW_TOP_BOTTOM_MEM_SECTIONS = 0 ; allow allocations from both sides of the memory
FW_64KB_PAGE_MEMORY_SUPPORT = 0 ; allow allocation of chip memory that doesn't cross the 64 KB page boundary
FW_MULTITASKING_SUPPORT = 0 ; enable multitasking
FW_ROUNDROBIN_MT_SUPPORT = 0 ; enable fair scheduling among tasks with same priority
FW_BLITTERTASK_MT_SUPPORT = 0 ; enable single parallel task during large blits
FW_MAX_VPOS_FOR_BG_TASK = 300 ; max vpos that is considered to be worth switching to a background task, if any
FW_SCRIPTING_SUPPORT = 0 ; enable simple timed scripting functions
FW_PALETTE_LERP_SUPPORT = 0 ; enable basic palette fading functions
FW_YIELD_FROM_MAIN_TOO = 0 ; adds additional code that copes with Yield being called from main code instead of task
FW_VBL_IRQ_SUPPORT = 0 ; enable custom VBL IRQ routine
FW_COPPER_IRQ_SUPPORT = 1 ; enable copper IRQ routine support
FW_AUDIO_IRQ_SUPPORT = 0 ; enable audio IRQ support (unimplemented)
FW_VBL_MUSIC_IRQ = 0 ; enable calling of VBL based music ticking (disable, if using CIA timing!)
FW_BLITTERQUEUE_SUPPORT = 0 ; enable blitter queue support
FW_A5_A6_UNTOUCHED = 1 ; speed up blitter queue if registers a5/a6 are never changed in main code
FW_LZ4_SUPPORT = 0 ; compile in LZ4 decruncher
FW_DOYNAX_SUPPORT = 0 ; compile in doynax decruncher
FW_ZX0_SUPPORT = 0 ; compile in ZX0 decruncher
CHIPMEM_SIZE = 4
FASTMEM_SIZE = 4
; Raspberry Casket settings
PRETRACKER_SUPPORT_V1_5 = 1
PRETRACKER_PARANOIA_MODE = 0
PRETRACKER_DUBIOUS_PITCH_SHIFT_FOR_DELAYED_TRACK = 0
PRETRACKER_KEEP_JUMP_TABLE = 0
PRETRACKER_SONG_END_DETECTION = 0
PRETRACKER_PROGRESS_SUPPORT = 0
PRETRACKER_FASTER_CODE = 1
PRETRACKER_VOLUME_TABLE = 1
PRETRACKER_BUGFIX_CODE = 1
PRETRACKER_DONT_TRASH_REGS = 0
PRETRACKER_COPPER_OUTPUT = 1
DEBUG_DETAIL SET 0
NEWAGE_DEBUG = 1
include "../frameworkng/framework.i"
STRUCTURE PartData,fw_SIZEOF
ULONG pd_Progress
ULONG pd_SamplesSize
ULONG pd_StartVHPos
ULONG pd_MinClocks
ULONG pd_SumClocks
ULONG pd_MaxClocks
UWORD pd_SumCount
STRUCT pd_MyPlayer,pv_SIZEOF
STRUCT pd_MySong,sv_SIZEOF
LABEL pd_SIZEOF
include "../frameworkng/framework.asm"
entrypoint:
IFNE PRETRACKER_COPPER_OUTPUT
lea pld_pretracker_copperlist,a0
move.w #300,d0
bsr pre_PrepareCopperlist
move.l d1,(a0) ; terminate copperlist
ENDC
;lea pd_MyPlayer(a6),a0
lea pd_MySong(a6),a1
move.l #pretracker_data,a2
PUTMSG 10,<"NewInit songInit %p, %p, %p">,a0,a1,a2
PUSHM a5/a6
bsr pre_SongInit
POPM
PUTMSG 10,<"Return val %ld">,d0
move.l d0,pd_SamplesSize(a6)
CALLFW VSync
move.w fw_FrameCounter(a6),d6
lea pd_MyPlayer(a6),a0
move.l #lsp_samples,a1
lea pd_MySong(a6),a2
sub.l a3,a3
PUTMSG 10,<"NewInit playerInit %p, %p, %p">,a0,a1,a2
PUSHM d6/a5/a6
bsr pre_PlayerInit
POPM
move.w fw_FrameCounter(a6),d1
sub.w d6,d1
PUTMSG 10,<"Return val %ld, Frames: %d">,d0,d1
move.l #100000,pd_MinClocks(a6)
lea pld_copperlist,a0
CALLFW SetCopper
lea .track_time(pc),a0
move.l a0,fw_CopperIRQ(a6)
.loop moveq.l #63,d0
and.w fw_FrameCounter(a6),d0
bne.s .nooutput
move.l pd_SumClocks(a6),d0
divu pd_SumCount(a6),d0
PUTMSG 10,<"Min %d Max %d Average %d">,pd_MinClocks(a6),pd_MaxClocks(a6),d0
.nooutput
CALLFW VSync
bra.s .loop
.track_time
move.w #$5ff,color(a5)
move.l vposr(a5),pd_StartVHPos(a6)
PUSHM d1-d7/a0-a6
lea pd_MyPlayer(a6),a0
lea pld_pretracker_copperlist,a1
bsr pre_PlayerTick
POPM
move.l vposr(a5),d0
move.w #$f6f,color(a5)
PUSHM d1-d4
and.l #$1ffff,d0
move.l pd_StartVHPos(a6),d1
and.l #$1ffff,d1
moveq.l #0,d3
move.b d0,d3
lsr.l #8,d0
mulu #227,d0
add.l d3,d0
moveq.l #0,d4
move.b d1,d4
lsr.l #8,d1
mulu #227,d1
add.l d4,d1
PUTMSG 20,<"Startclocks %ld Clocks %ld">,d1,d0
sub.l d1,d0
cmp.l pd_MinClocks(a6),d0
bge.s .nomin
move.l d0,pd_MinClocks(a6)
.nomin
cmp.l pd_MaxClocks(a6),d0
ble.s .nomax
move.l d0,pd_MaxClocks(a6)
.nomax
add.l d0,pd_SumClocks(a6)
addq.w #1,pd_SumCount(a6)
POPM
rts
include "../frameworkng/musicplayers/raspberry_casket.asm"
;--------------------------------------------------------------------
section "pld_copper",data,chip
pld_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 bplcon3,$0c00
pld_fmode:
COP_MOVE fmode,$0000 ; fixes the aga modulo problem
COP_MOVE bplcon0,$0200
COP_MOVE color,$fff
;dc.w $0180,$0fff,$01a2,$0eee,$01a4,$0edd,$01a6,$0e9b
;dc.w $01a8,$0e69,$01aa,$0b78,$01ac,$0d57,$01ae,$0a56
;dc.w $01b0,$0a34,$01b2,$0934,$01b4,$0923,$01b6,$0612
;dc.w $01b8,$0211,$01ba,$0000
COP_WAITLINE $80
COP_MOVE intreq,INTF_SETCLR|INTF_COPER
COP_WAITRAST $ff,$de
pld_pretracker_copperlist
COP_END
ds.l 36
COP_END
;incbin "../data/pretracker/raspberry_casket64x64.SPR"
section "pretracker_data",data
pretracker_data:
incbin "../data/pretracker/Pink - Plastic Dove (from Coda Intro).prt"
section "lsp_samples",data,chip
lsp_samples:
ds.b 19522
END

BIN
example/plastic_duff.exe Normal file

Binary file not shown.

23
example/readme.txt Normal file
View File

@ -0,0 +1,23 @@
This is a bare-bone example on how to use the replayer.
It features Pink's song Plastic Dove (from the Coda Intro).
Even though it features the full replayer code and tune,
the replayer including my demo framework and the song only
takes a mere 6560 bytes (shrinkled), which is even smaller
than the new streaming replayer used in Pink's new streaming
player demonstrated (closed source) in
https://www.pouet.net/prod.php?which=91551
which is 6860 bytes.
The Raspberry Casket replayer takes an average of 14
rasterlines while Pink's new streaming player takes
only about 10 rasterlines.
However, the song is not really busy and very short (1:35).
This means, regarding file size, this streaming format will
always lose against storing the full song data.
But anyway, I think I will create a compact streaming
format later next year (2023), too.

154
includes/hardware/custom.i Normal file
View File

@ -0,0 +1,154 @@
IFND HARDWARE_CUSTOM_I
HARDWARE_CUSTOM_I SET 1
**
** $VER: custom.i 39.1 (18.09.92)
** Includes Release 39.108
**
** Offsets of Amiga custom chip registers
**
** (C) Copyright 1985-1992 Commodore-Amiga, Inc.
** All Rights Reserved
**
*
* do this to get base of custom registers:
* XREF _custom;
*
bltddat EQU $000
dmaconr EQU $002
vposr EQU $004
vhposr EQU $006
dskdatr EQU $008
joy0dat EQU $00A
joy1dat EQU $00C
clxdat EQU $00E
adkconr EQU $010
pot0dat EQU $012
pot1dat EQU $014
potinp EQU $016
potgor EQU potinp
serdatr EQU $018
dskbytr EQU $01A
intenar EQU $01C
intreqr EQU $01E
dskpt EQU $020
dsklen EQU $024
dskdat EQU $026
refptr EQU $028
vposw EQU $02A
vhposw EQU $02C
copcon EQU $02E
serdat EQU $030
serper EQU $032
potgo EQU $034
joytest EQU $036
strequ EQU $038
strvbl EQU $03A
strhor EQU $03C
strlong EQU $03E
bltcon0 EQU $040
bltcon1 EQU $042
bltafwm EQU $044
bltalwm EQU $046
bltcpt EQU $048
bltbpt EQU $04C
bltapt EQU $050
bltdpt EQU $054
bltsize EQU $058
bltcon0l EQU $05B ; note: byte access only
bltsizv EQU $05C
bltsizh EQU $05E
bltcmod EQU $060
bltbmod EQU $062
bltamod EQU $064
bltdmod EQU $066
bltcdat EQU $070
bltbdat EQU $072
bltadat EQU $074
deniseid EQU $07C
dsksync EQU $07E
cop1lc EQU $080
cop2lc EQU $084
copjmp1 EQU $088
copjmp2 EQU $08A
copins EQU $08C
diwstrt EQU $08E
diwstop EQU $090
ddfstrt EQU $092
ddfstop EQU $094
dmacon EQU $096
clxcon EQU $098
intena EQU $09A
intreq EQU $09C
adkcon EQU $09E
aud EQU $0A0
aud0 EQU $0A0
aud1 EQU $0B0
aud2 EQU $0C0
aud3 EQU $0D0
* AudChannel
ac_ptr EQU $00 ; ptr to start of waveform data
ac_len EQU $04 ; length of waveform in words
ac_per EQU $06 ; sample period
ac_vol EQU $08 ; volume
ac_dat EQU $0A ; sample pair
ac_SIZEOF EQU $10
bplpt EQU $0E0
bplcon0 EQU $100
bplcon1 EQU $102
bplcon2 EQU $104
bplcon3 EQU $106
bpl1mod EQU $108
bpl2mod EQU $10A
bplcon4 EQU $10C
clxcon2 EQU $10E
bpldat EQU $110
sprpt EQU $120
spr EQU $140
* SpriteDef
sd_pos EQU $00
sd_ctl EQU $02
sd_dataa EQU $04
sd_dataB EQU $06
sd_SIZEOF EQU $08
color EQU $180
htotal EQU $1c0
hsstop EQU $1c2
hbstrt EQU $1c4
hbstop EQU $1c6
vtotal EQU $1c8
vsstop EQU $1ca
vbstrt EQU $1cc
vbstop EQU $1ce
sprhstrt EQU $1d0
sprhstop EQU $1d2
bplhstrt EQU $1d4
bplhstop EQU $1d6
hhposw EQU $1d8
hhposr EQU $1da
beamcon0 EQU $1dc
hsstrt EQU $1de
vsstrt EQU $1e0
hcenter EQU $1e2
diwhigh EQU $1e4
fmode EQU $1fc
ENDC !HARDWARE_CUSTOM_I

View File

@ -0,0 +1,49 @@
IFND HARDWARE_DMABITS_I
HARDWARE_DMABITS_I SET 1
**
** $VER: dmabits.i 39.1 (18.09.92)
** Includes Release 39.108
**
** include file for defining dma control stuff
**
** (C) Copyright 1985-1992 Commodore-Amiga, Inc.
** All Rights Reserved
**
* write definitions for dmaconw
DMAF_SETCLR EQU $8000
DMAF_AUDIO EQU $000F ; 4 bit mask
DMAF_AUD0 EQU $0001
DMAF_AUD1 EQU $0002
DMAF_AUD2 EQU $0004
DMAF_AUD3 EQU $0008
DMAF_DISK EQU $0010
DMAF_SPRITE EQU $0020
DMAF_BLITTER EQU $0040
DMAF_COPPER EQU $0080
DMAF_RASTER EQU $0100
DMAF_MASTER EQU $0200
DMAF_BLITHOG EQU $0400
DMAF_ALL EQU $01FF ; all dma channels
* read definitions for dmaconr
* bits 0-8 correspnd to dmaconw definitions
DMAF_BLTDONE EQU $4000
DMAF_BLTNZERO EQU $2000
DMAB_SETCLR EQU 15
DMAB_AUD0 EQU 0
DMAB_AUD1 EQU 1
DMAB_AUD2 EQU 2
DMAB_AUD3 EQU 3
DMAB_DISK EQU 4
DMAB_SPRITE EQU 5
DMAB_BLITTER EQU 6
DMAB_COPPER EQU 7
DMAB_RASTER EQU 8
DMAB_MASTER EQU 9
DMAB_BLITHOG EQU 10
DMAB_BLTDONE EQU 14
DMAB_BLTNZERO EQU 13
ENDC ; HARDWARE_DMABITS_I

5052
original/player.asm Normal file

File diff suppressed because it is too large Load Diff

BIN
original/player.bin Normal file

Binary file not shown.

BIN
original/player.bin.rs Normal file

Binary file not shown.

101
original/player.i Normal file
View File

@ -0,0 +1,101 @@
; MySong offsets
org_sv_num_waves_b = $00
org_sv_num_steps_b = $01
org_sv_num_steps_w = $02
org_sv_patterns_ptr = $04
org_sv_inst_patterns_table = $08 ; 32 ($18) waves max (until $88)
org_sv_curr_pat_pos_l = $88 ; only byte used FIXME why is this part of MySong? Should be in Player
org_sv_pat_pos_len_l = $8c ; only byte used
org_sv_pat_restart_pos_l = $90 ; only byte used
org_sv_pos_data_adr = $94
org_sv_inst_infos_ptr = $98
org_sv_waveinfo_ptr = $9c ; base pointer of wave info
org_sv_pattern_table = $a0 ; until $49c (excl.)
; $4d0 bytes of nothing here
org_sv_wavegen_order_table = $96c ; 24 bytes
; ----------------------------------------
; channel structure
org_pcd_arp_notes_l = 0
org_pcd_arp_note_1_b = 0
org_pcd_arp_note_2_b = 1
org_pcd_arp_note_3_b = 2
org_pcd_last_trigger_pos_w = 4 ; I think this makes sure that we don't retrigger the note on same pos
org_pcd_pat_vol_b = 6 ; Multiplied with volume of instrument.
org_pcd_pat_portamento_speed_b = 7
org_pcd_pat_adsr_rel_delay_b = 8 ; counts down until adsr release. Seems unused?
org_pcd_pat_2nd_inst_num_b = 9
org_pcd_pat_2nd_inst_delay_b = 10 ; low byte only?
org_pcd_pat_vol_ramp_speed_b = 11
org_pcd_new_inst_num_b = 12 ; load new instrument (number)
org_pcd_wave_offset_b = 13
org_pcd_note_off_delay_b = 14 ; time before note is released ($ff = disabled)
org_pcd_note_delay_b = 15 ; $ff = no note delay
org_pcd_pat_portamento_dest_w = $10 ; portamento destination pitch
org_pcd_pat_pitch_slide_w = $12
org_pcd_track_delay_steps_b = $14 ; $00 = no track delay, $ff = stop track delay (this is for the next channel!)
org_pcd_track_delay_offset_b = $15 ; $ff = no track delay
org_pcd_track_delay_vol16_b = $16
org_pcd_inst_vol_w = $18
org_pcd_inst_num_w = $1a ; current instrument number (lower byte used)
org_pcd_inst_wave_num_w = $1c ; current wave number (1 based) (lower byte used)
org_pcd_loaded_inst_vol_w = $1e ; low byte only
org_pcd_inst_sel_arp_note_w = $20
org_pcd_inst_new_step_w = $22 ; seems to be unused
org_pcd_inst_ping_pong_s_w = $24 ; direction of pingpong (-1 / +1)
org_pcd_inst_pitch_pinned_b = $26
org_pcd_inst_vol_slide_w = $28
org_pcd_inst_pitch_w = $2a
org_pcd_inst_curr_port_pitch_w = $2c
org_pcd_inst_note_pitch_w = $2e
org_pcd_inst_pitch_slide_w = $30
org_pcd_inst_subloop_wait_w = $32
org_pcd_inst_loop_offset_l = $34 ; only lower word reasonable
org_pcd_inst_info_ptr = $38 ; pointer to currently active instrument
org_pcd_waveinfo_ptr = $3c ; pointer to currently active waveinfo
org_pcd_adsr_phase_l = $40 ; 0=attack, 1=decay, 2=sustain, 3=release
org_pcd_adsr_phase_speed_b = $44 ;
org_pcd_adsr_pos_w = $46 ; $10 (release pos?)
org_pcd_adsr_vol64_w = $48 ; speed? ($48)+($46)
org_pcd_adsr_attack_speed_l = $4a ; (low byte only)
org_pcd_adsr_decay_speed_l = $4e ; (low byte only)
org_pcd_adsr_sustain_l = $52 ; 15/16 (low byte only)
org_pcd_adsr_release_l = $56 ; read in release (low byte only)
org_pcd_adsr_volume_l = $5a ; 0 for restart / $400 (word only)
org_pcd_adsr_trigger_b = $5e ; 1 for restart (FIXME: never read??)
org_pcd_vibrato_pos_w = $60 ;
org_pcd_vibrato_depth_w = $62 ; is a byte value
org_pcd_vibrato_speed_w = $64 ; is a byte value
org_pcd_vibrato_delay_w = $66 ; is a byte value
org_pcd_inst_step_pos_b = $68
org_pcd_inst_speed_stop_b = $69 ; speed byte, $ff stops processing
org_pcd_inst_line_ticks_b = $6a ; $00
org_pcd_channel_num_b = $6b
org_pcd_track_delay_buffer = $7c ; 16 bytes x 32 steps, until $27c
org_pcd_out_ptr_l = $6c
org_pcd_out_len_w = $70
org_pcd_out_lof_w = $72
org_pcd_out_per_w = $74
org_pcd_out_vol_b = $76
org_pcd_out_trg_b = $77
org_pcd_out_unused_l = $78 ; copied for track delay, but not used?
org_pcd_SIZEOF = $27c
; player global variables (not bound to channel)
org_pv_pat_curr_row_b = $9f0 ; what is this? bit 0 is tested for shuffle
org_pv_next_pat_row_b = $9f1
org_pv_next_pat_pos_b = $9f2
org_pv_pat_speed_b = $9f3 ; speed byte (unfiltered)
org_pv_pat_line_ticks_b = $9f4
org_pv_my_song = $9f6 ; fw_PretrackerMySong
org_pv_pat_stopped_b = $9fa ; 0 = stop, 1 = run
org_pv_wave_sample_table = $9fc ; 24 pointers to sample starts, until $a5c
org_pv_sample_buffer_ptr = $a5c ; pointer to empty sample (for idle channel)
org_pv_osc_buffers = $a60
org_pv_loop_pattern_b = $1c6c ; repeat current pattern, do not advance

6
original/readme.txt Normal file
View File

@ -0,0 +1,6 @@
Here's the original player in binary form and resourced by hitchhikr
(his original archive does no longer seem to be available).
I added a player.i include file with the "original offsets" of the
internal data structures, in case you want to fiddle with it.

View File

@ -0,0 +1,17 @@
; vasmm68k_mot.exe -devpac -Fbin -o ..\binaries\raspberry_casket.bin -opt-allbra drop_in_replacement.asm
PRETRACKER_SUPPORT_V1_5 = 0
PRETRACKER_PARANOIA_MODE = 0
PRETRACKER_DUBIOUS_PITCH_SHIFT_FOR_DELAYED_TRACK = 0
PRETRACKER_KEEP_JUMP_TABLE = 1
PRETRACKER_SONG_END_DETECTION = 0
PRETRACKER_PROGRESS_SUPPORT = 0
PRETRACKER_FASTER_CODE = 1
PRETRACKER_VOLUME_TABLE = 1
PRETRACKER_BUGFIX_CODE = 1
PRETRACKER_DONT_TRASH_REGS = 1
PRETRACKER_COPPER_OUTPUT = 0
opt p+,o+
include "raspberry_casket.asm"

4253
src/raspberry_casket.asm Executable file

File diff suppressed because it is too large Load Diff