From 0c35e4f0f7f2096b50bb78bedfc10aee76dd505c Mon Sep 17 00:00:00 2001 From: alpine9000 Date: Sat, 23 Apr 2016 09:03:33 +1000 Subject: [PATCH] Placeholder music --- 028.game2/.gitignore | 1 + 028.game2/Makefile | 2 +- 028.game2/P6112-Options.i | 91 + 028.game2/P6112-Play.s | 4136 +++++++++++++++++++++++++++++++++++++ 028.game2/game1.s | 10 +- 028.game2/music.s | 12 + 6 files changed, 4248 insertions(+), 4 deletions(-) create mode 100644 028.game2/.gitignore create mode 100644 028.game2/P6112-Options.i create mode 100644 028.game2/P6112-Play.s create mode 100644 028.game2/music.s diff --git a/028.game2/.gitignore b/028.game2/.gitignore new file mode 100644 index 0000000..5b68c9f --- /dev/null +++ b/028.game2/.gitignore @@ -0,0 +1 @@ +assets/P61.placeholder \ No newline at end of file diff --git a/028.game2/Makefile b/028.game2/Makefile index 1d7e723..eb86dc5 100644 --- a/028.game2/Makefile +++ b/028.game2/Makefile @@ -11,7 +11,7 @@ BASE_ADDRESS=4000 NUM_COLORS=8 BOOTBLOCK_ASM=alpine_bootblock.s -OBJS=out/init.o out/utils.o out/image.o out/blit.o out/joystick.o out/pig.o out/items.o out/blittext.o out/splash.o +OBJS=out/init.o out/utils.o out/image.o out/blit.o out/joystick.o out/pig.o out/items.o out/blittext.o out/music.o out/P6112-Play.o out/splash.o IMAGES=foreground.png \ background.png \ diff --git a/028.game2/P6112-Options.i b/028.game2/P6112-Options.i new file mode 100644 index 0000000..aa3bf02 --- /dev/null +++ b/028.game2/P6112-Options.i @@ -0,0 +1,91 @@ +P61mode =1 ;Try other modes ONLY IF there are no Fxx commands >= 20. + ;(f.ex., P61.new_ditty only works with P61mode=1) + + +;; --- options common to all P61modes --- + + +usecode=-1 ;CHANGE! to the USE hexcode from P61con for a big + ;CPU-time gain! (See module usecodes at end of source) + ;Multiple songs, single playroutine? Just "OR" the + ;usecodes together! + + ;...STOP! Have you changed it yet!? ;) + ;You will LOSE RASTERTIME AND FEATURES if you don't. + +P61pl=usecode&$400000 + +split4=0 ;Great time gain, but INCOMPATIBLE with F03, F02, and F01 + ;speeds in the song! That's the ONLY reason it's default 0. + ;So ==> PLEASE try split4=1 in ANY mode! + ;Overrides splitchans to decrunch 1 chan/frame. + ;See ;@@ note for P61_SetPosition. + + +splitchans=1 ;#channels to be split off to be decrunched at "playtime frame" + ;0=use normal "decrunch all channels in the same frame" + ;Experiment to find minimum rastertime, but it should be 1 or 2 + ;for 3-4 channels songs and 0 or 1 with less channels. + +visuctrs=1 ;enables visualizers in this example: P61_visuctr0..3.w + ;containing #frames (#lev6ints if cia=1) elapsed since last + ;instrument triggered. (0=triggered this frame.) + ;Easy alternative to E8x or 1Fx sync commands. + +asmonereport =0 ;ONLY for printing a settings report on assembly. Use + ;if you get problems (only works in AsmOne/AsmPro, tho) + +p61system=0 ;1=system-friendly. Use for DOS/Workbench programs. + +p61exec =0 ;0 if execbase is destroyed, such as in a trackmo. + +p61fade =0 ;enable channel volume fading from your demo + +channels=4 ;<4 for game sound effects in the higher channels. Incompatible + ; with splitchans/split4. + +playflag=0 ;1=enable music on/off capability (at run-time). .If 0, you can + ;still do this by just, you know, not calling P61_Music... + ;It's a convenience function to "pause" music in CIA mode. + +p61bigjtab=0 ;1 to waste 480b and save max 56 cycles on 68000. + +opt020 =0 ;1=enable optimizations for 020+. Please be 68000 compatible! + ;splitchans will already give MUCH bigger gains, and you can + ;try the MAXOPTI mode. + +p61jump =0 ;0 to leave out P61_SetPosition (size gain) + ;1 if you need to force-start at a given position fex in a game + +C =0 ;If you happen to have some $dffxxx value in a6, you can + ;change this to $xxx to not have to load it before P61_Music. + +clraudxdat=0 ;enable smoother start of quiet sounds. probably not needed. + +optjmp =1 ;0=safety check for jump beyond end of song. Clear it if you + ;play unknown P61 songs with erroneous Bxx/Dxx commands in them + +oscillo =0 ;1 to get a sample window (ptr, size) to read and display for + ;oscilloscope type effects (beta, noshorts=1, pad instruments) + ;IMPORTANT: see ;@@ note about chipmem dc.w buffer. + +quietstart=0 ;attempt to avoid the very first click in some modules + ;IMPORTANT: see ;@@ note about chipmem dc.w buffer. + +use1Fx=0 ;Optional extra effect-sync trigger (*). If your module is free + ;from E commands, and you add E8x to sync stuff, this will + ;change the usecode to include a whole code block for all E + ;commands. You can avoid this by only using 1Fx. (You can + ;also use this as an extra sync command if E8x is not enough, + ;of course.) + +;(*) Slideup values>116 causes bugs in Protracker, and E8 causes extra-code +;for all E-commands, so I used this. It's only faster if your song contains 0 +;E-commands, so it's only useful to a few, I guess. Bit of cyclemania. :) + +;Just like E8x, you will get the trigger after the P61_Music call, 1 frame +;BEFORE it's heard. This is good, because it allows double-buffered graphics +;or effects running at < 50 fps to show the trigger synced properly. + + + diff --git a/028.game2/P6112-Play.s b/028.game2/P6112-Play.s new file mode 100644 index 0000000..06ed1ed --- /dev/null +++ b/028.game2/P6112-Play.s @@ -0,0 +1,4136 @@ + include "P6112-Options.i" + xdef P61_Init +; #-----+-----------------------------------------# +; |Name:| P6112 - Optimized Player 6.1 Playroutine| +; +-----+-----------------------------------------+ +; |V1.06| P6112,E1x/E2x fix | +; |V1.05| P6111, EDx fix,better init/exit,Dxx note| +; |V1.04| P6110, E6x command fix+new option | +; |V1.03| P6109, compatibility changes only. | +; |V1.02| Cleaned up P6108 with minor changes. | +; |V1.01| 2.4-3 scanlines faster than my p6107. | +; | | SLen (song length) bug fixed | +; | | lev6 implemented with "poke DMA here" | +; | | Two options for clickless sound start | +; | | P61_Osc precis samplewindow tracking | +; | | Many optimization options - read the | +; | | info or leave them at defaults. | +; +-----+-----------------------------------------+ +; | by Photon/Scoopex | +; #-----------------------------------------------# + +;SPECIAL NOTE FOR THIS VERSION: +;----------------------------- +;Tutorial here: http://youtu.be/xBtHO-IuN9E +;Put it in your demo: http://youtu.be/JYLcIR6tyO4 + +;I'm leaving the P61 project, feeling I've left it in good shape. +;There is nothing left to optimize, and I've gone through everything I could +;find that was bad and fixed it. + +;I support this only with the readme.txt and all the comment documentation. +;Please follow the advice in my Youtube tutorial specifically made for adding +;P61 to your demo before deciding the playroutine is at fault. If you are sure +;you have found a bug, fix it yourself. + +;A song must fail in the example source and play correctly in P61con, before +;you can suspect the playroutine is at fault. + +;A note on syncing: apart from the new options for $1Fx, channel triggers, and +;oscilloscope ptrs I added, you should no longer ask musicians to scatter E8x +;commands in the song. Don't worry, it plays fine in P61 and always has. +;But some non-legacy trackers destroy the loop with a filter where E8x commands +;are used. 80x is an alternative, which works in all trackers, according to +;them. To use it, just replace E8x with 80x in the module and you need change +;nothing else. + +;P6112: +;E1x/E2x fix. One line changed in the source, in the GetNote macro used by +;these two effects combined with a note trigger (i.e. for F-3 E1x, not --- E1x) + +;P6111: +;- Fix notedelay bug introduced in P6108 +;- Fix in legacy code, CIA regs were modified in init/exit even when p61_cia=0. +;- Verified that $9xx offset behavior takes effect at loop end, a behavior +;used by chip musicians. + +;Dxx command: P61 has never implemented Dxx support other than for xx=00. + +;I took a good look, and the way I see it, only pointers to previously +;decrunched notesteps are stored. This means patternloop backjumps work, but +;forward jumps to some offset from the pattern start pointer - doesn't. +;xx steps must first be decrunched. This will cause a spike in rastertime +;(CPU load) used, which is counter to my efforts to make the P61 playroutine +;match the performance of optimized normal Protracker playroutines. + +;So I've decided to not implement it. Instead, musicians are recommended to +;copy the jumped-to pattern and delete xx notes to make the offset=0. Then +;the Dxx command can be changed to a D00 command, which is supported. +;The copied pattern will only add 16 bytes or so to the filesize, and +;performance will remain excellent. + +;--- + +;P6110: A bug regarding Patternloops (E6x) was introduced in P6108 when I added +;super optimization flags. This is fixed, but it also revealed the obvious: +;that Patternloop is incompatible with suppF01=0. The example will set this +;automatically for you, but you will not get the great speed gains if you try +;split4=1 unless you SET THE USECODE PROPERLY. + +;Of course all modes will work properly if you leave everything at default +;in the example, but I recommend to set the usecode to get the most out of p61 +; - not just the size gain. + +;Also, new option: set visuctrs=1 to get elapsed time since last instrument +;trigger in P61visuctr0..3. + +;NOTE: vasm users MUST turn optimizations off for the jmp xx(PC) instructions +;in the jump tables and at P61_motuuli. If not, the source will assemble +;without errors, but generate bra.b which WILL cause fatal run-time errors. + +;May the Source be with you! //Photon + + +;Credits to Jarno for V6.1A, and bugfixers up to 6.1.0.6. +;(Notes from previous versions below.) + + +* The Player 6.1A - by Guru / Sahara Surfers + +* Interrupt problem with 060 fixed by NoName/Haujobb^Sector 7 +* Some Enforcer Hits fixed by Platon42 +* Memory trashing bug in routine P61_End fixed by Tolkien +* Bug in routine P61_Init (when opt020=1) fixed by The Dark Coder/Trinity^Morbid Visions + +* for Devpac 3, ASM-One, PhxAss and maybe some other assemblers +* +* NEEDS: Default sizes must be words (ASM-One default...) +* Preferably no optimizations on (the jump table must be word jumps) +* +* Tested with Devpac 3.04 by Guru +* Tested with PhxAss 4.14, Asm-Pro 1.1 and ASM-One 1.29 +* +* Note 1:All the bugfixes done after version 610.2 (the latest release from +* Guru / Sahara Surfers) are marked with the comment "* BUGFIX" +* followed by some explanations, so that if can quickly copy them +* into a previous version tailored to your needs. +* +* Note 2:The unelegant double WRITE to INTREQ unforunately seems to be +* the best solution to the "interrupt problem" that occurs on +* some 040/060 equipped Amiga. On many 040/060 Amigas it is enough +* to put an access to whatever hardware register and a NOP between +* the first write to INTREQ and he RTE. However we had reports that +* on some Amiga it is really necessary to do a double write to INTREQ + +;; --- CIA mode options (default) --- + + ifeq P61mode-1 + +p61cia =1 ;call P61_Music on the CIA interrupt instead of every frame. + +lev6 =1 ;1=keep the timer B int at least for setting DMA. + ;0="FBI mode" - ie. "Free the B-timer Interrupt". + + ;0 requires noshorts=1, p61system=0, and that YOU make sure DMA + ;is set at 11 scanlines (700 usecs) after P61_Music is called. + ;AsmOne will warn you if requirements are wrong. + + ;DMA bits will be poked in the address you pass in A4 to + ;P61_init. (Update P61_DMApokeAddr during playing if necessary, + ;for example if switching Coppers.) + + ;P61_Init will still save old timer B settings, and initialize + ;it. P61_End will still restore timer B settings from P61_Init. + ;So don't count on it 'across calls' to these routines. + ;Using it after P61_Init and before P61_End is fine. + +noshorts=0 ;1 saves ~1 scanline, requires Lev6=0. Use if no instrument is + ;shorter than ~300 bytes (or extend them to > 300 bytes). + ;It does this by setting repeatpos/length the next frame + ;instead of after a few scanlines,so incompatible with MAXOPTI + +dupedec =0 ;0=save 500 bytes and lose 26 cycles - I don't blame you. :) + ;1=splitchans or split4 must be on. + +suppF01 =1 ;0 is incompatible with CIA mode. It moves ~100 cycles of + ;next-pattern code to the less busy 2nd frame of a notestep. + ;If you really need it, you have to experiment as the support + ;is quite complex. Basically set it to 1 and try the various + ;P61modes, if none work, change some settings. + + endc + +;; --- VBLANK mode options --- + + ifeq P61mode-2 + +p61cia =0 +lev6 =1 ;still set sound DMA with a simple interrupt. +noshorts=0 ;try 1 (and pad short instruments if nec) for 1 scanline gain +dupedec =0 +suppF01 =P61pl ;if 1, split4=1 may cause sound errors. but try it anyway. :) + + endc + +;; --- COPPER mode options --- + + ifeq P61mode-3 + +p61cia =0 +lev6 =0 ;don't set sound DMA with an interrupt. + ;(use the copper to set sound DMA 11 scanlines after P61_Music) +noshorts=1 ;You must pad instruments < 300 bytes for this mode to work. +dupedec =0 +suppF01 =P61pl ;if 1, split4=1 may cause sound errors. but try it anyway. :) + + endc + +;; --- MAXOPTI mode options --- + + ifeq P61mode-4 + +p61cia =0 +lev6 =0 +noshorts=1 ;You must pad instruments < 300 bytes for this mode to work. +dupedec =1 +suppF01 =P61pl ;if 1, split4=1 may cause sound errors. but try it anyway. :) + + endc + + +******************************** +* Player 6.1A ® * +* All in one-version * +* Version 610.6 * +* © 1992-95 Jarno Paananen * +* All rights reserved * +* Fixed by: NoName, Platon42, * +* Tolkien and The Dark Coder * +******************************** +nowaveforms=noshorts +copdma=1-lev6 +Custom_Block_Size=16 ;d7 used to replace clr.* instead of this const + + ifnd player61_i +player61_i:set 1 + ifnd exec_types_i +exec_types_i:set 1 +include_version:equ 40 +extern_lib:macro + xref _lvo\1 + endm +structure:macro +\1:equ 0 +soffset:set \2 + endm +fptr:macro +\1:equ soffset +soffset:set soffset+4 + endm +bool:macro +\1:equ soffset +soffset:set soffset+2 + endm +byte:macro +\1:equ soffset +soffset:set soffset+1 + endm +ubyte:macro +\1:equ soffset +soffset:set soffset+1 + endm +word:macro +\1:equ soffset +soffset:set soffset+2 + endm +uword:macro +\1:equ soffset +soffset:set soffset+2 + endm +short:macro +\1:equ soffset +soffset:set soffset+2 + endm +ushort:macro +\1:equ soffset +soffset:set soffset+2 + endm +long:macro +\1:equ soffset +soffset:set soffset+4 + endm +ulong:macro +\1:equ soffset +soffset:set soffset+4 + endm +float:macro +\1:equ soffset +soffset:set soffset+4 + endm +double:macro +\1:equ soffset +soffset:set soffset+8 + endm +aptr:macro +\1:equ soffset +soffset:set soffset+4 + endm +cptr:macro +\1:equ soffset +soffset:set soffset+4 + endm +rptr:macro +\1:equ soffset +soffset:set soffset+2 + endm +label:macro +\1:equ soffset + endm +struct:macro +\1:equ soffset +soffset:set soffset+\2 + endm +alignword:macro +soffset:set (soffset+1)&$fffffffe + endm +alignlong:macro +soffset:set (soffset+3)&$fffffffc + endm +enum:macro + ifc '\1','' +eoffset:set 0 + endc + ifnc '\1','' +eoffset:set \1 + endc + endm +eitem:macro +\1:equ eoffset +eoffset:set eoffset+1 + endm +bitdef0:macro +\1\3\2:equ \4 + endm +bitdef:macro + bitdef0 \1,\2,b_,\3 +\@bitdef:set 1<<\3 + bitdef0 \1,\2,f_,\@bitdef + endm +library_minimum:equ 33 + endc ;ifnd + + structure Player_Header,0 + ulong P61_InitOffset + ulong P61_MusicOffset + ulong P61_EndOffset + ulong P61_SetRepeatOffset + ulong P61_SetPositionOffset + uword P61_MasterVolume + uword P61_UseTempo + uword P61_PlayFlag + uword P61_E8_info + aptr P61_UseVBR + uword P61_Position + uword P61_Pattern + uword P61_Row + aptr P61_Cha0Offset + aptr P61_Cha1Offset + aptr P61_Cha2Offset + aptr P61_Cha3Offset + label Player_Header_SIZE + structure Channel_Block,0 + ubyte P61_SN_Note + ubyte P61_Command + ubyte P61_Info + ubyte P61_Pack + aptr P61_Sample + uword P61_OnOff + aptr P61_ChaPos + aptr P61_TempPos + uword P61_TempLen + + uword P61_Note + uword P61_Period + uword P61_Volume + uword P61_Fine + + uword P61_Offset + uword P61_LOffset + uword P61_ToPeriod + uword P61_TPSpeed + ubyte P61_VibCmd + ubyte P61_VibPos + ubyte P61_TreCmd + ubyte P61_TrePos + uword P61_RetrigCount + ubyte P61_Funkspd + ubyte P61_Funkoff + aptr P61_Wave + + uword P61_TData + aptr P61_TChaPos + aptr P61_TTempPos + uword P61_TTempLen + uword P61_Shadow + ifne oscillo ;Filled in by P61_osc call (div ptrs by 4) + aptr P61_oscptr ;points to end of current frame's sample-chunk. + uword P61_oscptrrem ;remainder for precision (internal use only) + aptr P61_oscptrWrap ;wrap (end) pointer for current Paula soundloop + endc + uword P61_DMABit + label Channel_Block_Size + structure Sample_Block,0 + aptr P61_SampleOffset + uword P61_SampleLength + aptr P61_RepeatOffset + uword P61_RepeatLength + uword P61_SampleVolume + uword P61_FineTune + label Sample_Block_SIZE +P61_ft=usecode&1 +P61_pu=usecode&2 +P61_pd=usecode&4 +P61_tp=usecode&40 +P61_vib=usecode&80 +P61_tpvs=usecode&32 +P61_vbvs=usecode&64 +P61_tre=usecode&$80 +P61_arp=usecode&$100 +P61_sof=usecode&$200 +P61_vs=usecode&$400 +P61_pj=usecode&$800 +P61_vl=usecode&$1000 +P61_pb=usecode&$2800 +P61_sd=usecode&$8000 +P61_ec=usecode&$ffff0000 +P61_fi=usecode&$10000 +P61_fsu=usecode&$20000 +P61_fsd=usecode&$40000 +P61_sft=usecode&$200000 +P61_pl=usecode&$400000&((1-split4)*$400000) ;incompatible with split4. +P61_timing=usecode&$1000000 +P61_rt=usecode&$2000000 +P61_fvu=usecode&$4000000 +P61_fvd=usecode&$8000000 +P61_nc=usecode&$10000000 +P61_nd=usecode&$20000000 +P61_pde=usecode&$40000000 +P61_il=usecode&$80000000 + endc + + ifne asmonereport + +********** REPORT ********** + + printt "" + printt "Options used:" + printt "-------------" + + ifne p61fade + printt "Mastervolume on" + else + printt "Mastervolume off" + endc + + ifne p61system + printt "System friendly" + else + printt "System killer" + endc + + ifne p61cia + printt "CIA-tempo on" + else + printt "CIA-tempo off" + endc + + ifne p61exec + printt "ExecBase valid" + else + printt "ExecBase invalid" + endc + +;; --- wicked nasty nested ifs --- + + ifne lev6 + printt "Level 6 IRQ on" + else + + ifeq (noshorts&(1-p61system)) + printt "FAIL: Non-lev6 NOT available for p61system=1 or noshorts=0!" + + else + printt "Non-lev6 implemented with 'poke DMAbits byte to a specified address'." + printt "* READ DOCS for how to specify it and how it works." + endc ;noshorts&(1-p61system) + + endc ;lev6 + +;; --- end of wicked nasty nested ifs --- + + ifne opt020 + printt "MC68020 optimizations" + else + printt "Normal MC68000 code" + endc + + printt "Channels:" + printv channels + + ifgt channels-4 + printt "FAIL: More than 4 channels." + endc + + ifeq channels + printt "FAIL: Can't have 0 channels." + endc + + printt "UseCode:" + printv usecode + + printt "Player binary size:" + printv P61E-P61B + +********** REPORT END ********** + + endc ;ifne asmonereport + +P61B: +P61_motuuli: + jmp P61_Init(PC) + + ifeq p61cia + jmp P61_Music(PC) + else + rts + rts + endc + + jmp P61_End(PC) + + rts ;no P61_SetRepeat + rts + + ifne p61jump + jmp P61_SetPosition(PC) + else + rts + rts + endc + +P61_Master: + dc.w 64 +P61_Tempo: + dc.w 1 +P61_Play: + dc.w 1 +P61_E8: + dc.w 0 +P61_VBR: + dc.l 0 +P61_Pos: + dc.w 0 +P61_Patt: + dc.w 0 +P61_CRow: + dc.w 0 +P61_Temp0Offset: + dc.l P61_temp0-P61_motuuli +P61_Temp1Offset: + dc.l P61_temp1-P61_motuuli +P61_Temp2Offset: + dc.l P61_temp2-P61_motuuli +P61_Temp3Offset: + dc.l P61_temp3-P61_motuuli +P61_getnote:macro + moveq #$7e,d0 + and.b (a5),d0 + beq.b .nonote + ifne P61_vib + clr.b P61_VibPos(a5) + endc + ifne P61_tre + clr.b P61_TrePos(a5) + endc + ifne P61_ft + add P61_Fine(a5),d0 + endc + move d0,P61_Note(a5) + move P61_periods-P61_cn(a3,d0),P61_Period(a5) ;P6112 fix. +.nonote: + endm + ifeq p61system + ifne p61cia +P61_intti: + movem.l d0-a6,-(sp) + tst.b $bfdd00 + lea $dff000+C,a6 + move #$2000,$9c-C(a6) + move #$2000,$9c-C(a6) + bsr P61_Music + movem.l (sp)+,d0-a6 + nop + rte + endc + endc + ifne p61system +P61_lev6server: + movem.l d2-d7/a2-a6,-(sp) + lea P61_timeron(pc),a0 + tst (a0) + beq.b P61_ohi + lea $dff000+C,a6 + move P61_server(pc),d0 + beq.b P61_musica + subq #1,d0 + beq P61_dmason + + ifeq nowaveforms + bra P61_setrepeat + else + bra.b P61_ohi + endc + +P61_musica: + bsr P61_Music +P61_ohi: + movem.l (sp)+,d2-d7/a2-a6 + moveq #1,d0 + rts + endc + +********** P61_Init ********** +* Input: A0=P61-module addr. + +* A1 [LONG] = 0 if samples are internal to the module +* Address of samples otherwise +* A2 [LONG] = Address of sample buffer if the module uses packed +* samples, otherwise can be left uninitialized +* A4 [LONG] = Address where 'DMA ON' byte (low 8 bits of DMACON) +* should be poked. ONLY used together with lev6=0. + +* D0 [WORD] = 0 autodetect CIA Timer frequency, if ExecBase +* is valid otherwise assume PAL +* 1 assume PAL +* 2 assume NTSC +* [Used only in CIA-enabled mode] + +* Uses: D0-A7, A6 set to $dff000+C (your custombase) at exit. +* Returns: D0=0 if okay (i.e. P61 module!). No need to change D0.l. +* NOTE: the define 'start' has been made runtime. move.w #,P61_InitPos instead. + +P61_Init: + lea $dff000+C,a6 + ifeq p61system + ifne quietstart + move.w #$f,$96-C(A6) ;audiodma off + lea $a0-C(A6),a5 ;chan 0 + lea P61_Quiet(PC),a3 + moveq #0,d1 + moveq #channels-1,d5 +.choffl:move.l a3,(a5)+ ;ptr + move.l #1<<16+124,(a5)+ ;len, 'fastest common' period + move.l d1,(a5)+ ;quiet volume & audchan. + addq.w #4,a5 + dbf d5,.choffl + endc + endc + + cmp.l #"P61A",(a0)+ + beq.b .modok + subq.l #4,a0 +.modok: + ifne p61cia + move d0,-(sp) + endc + moveq #0,d0 + cmp.l d0,a1 + bne.b .redirect + move (a0),d0 + lea (a0,d0.l),a1 +.redirect: + move.l a2,a6 + lea 8(a0),a2 + moveq #$40,d0 + and.b 3(a0),d0 + bne.b .buffer + move.l a1,a6 + subq.l #4,a2 +.buffer: + + lea P61_cn(pc),a3 + + move.w #$ff00,d1 + move.w d1,P61_OnOff+P61_temp0-P61_cn(a3) ;stop active decsteps + move.w d1,P61_OnOff+P61_temp1-P61_cn(a3) + move.w d1,P61_OnOff+P61_temp2-P61_cn(a3) + move.w d1,P61_OnOff+P61_temp3-P61_cn(a3) + + ifne copdma + move.l a4,p61_DMApokeAddr-P61_cn(a3) + endc + + moveq #$1f,d1 + and.b 3(a0),d1 + move.l a0,-(sp) +;; --- insert pan/echo in this loop --- + lea P61_samples(pc),a4 + subq #1,d1 + moveq #0,d4 +P61_lopos: + move.l a6,(a4)+ + move (a2)+,d4 + bpl.b P61_kook + neg d4 + lea P61_samples-16(pc),a5 + ifeq opt020 + asl #4,d4 + move.l (a5,d4),d6 + else + add d4,d4 + move.l (a5,d4*8),d6 + endc + move.l d6,-4(a4) + ifeq opt020 + move 4(a5,d4),d4 + else + move 4(a5,d4*8),d4 + endc + sub.l d4,a6 + sub.l d4,a6 + bra.b P61_jatk +P61_kook: + move.l a6,d6 + tst.b 3(a0) + bpl.b P61_jatk + tst.b (a2) + bmi.b P61_jatk + move d4,d0 + subq #2,d0 + bmi.b P61_jatk + move.l a1,a5 + move.b (a5)+,d2 + sub.b (a5),d2 + move.b d2,(a5)+ +.loop:sub.b (a5),d2 + move.b d2,(a5)+ + sub.b (a5),d2 + move.b d2,(a5)+ + dbf d0,.loop +P61_jatk: + move d4,(a4)+ + moveq #0,d2 + move.b (a2)+,d2 + moveq #0,d3 + move.b (a2)+,d3 + moveq #0,d0 + move (a2)+,d0 + bmi.b .norepeat + move d4,d5 + sub d0,d5 + move.l d6,a5 + add.l d0,a5 + add.l d0,a5 + move.l a5,(a4)+ + move d5,(a4)+ + bra.b P61_gene +.norepeat: + move.l d6,(a4)+ + move #1,(a4)+ +P61_gene: + move d3,(a4)+ + moveq #$f,d0 + and d2,d0 + mulu #74,d0 + move d0,(a4)+ + tst -6(a2) + bmi.b .nobuffer + moveq #$40,d0 + and.b 3(a0),d0 + beq.b .nobuffer + move d4,d7 + tst.b d2 + bpl.b .copy + subq #1,d7 + moveq #0,d5 + moveq #0,d4 +.lo: move.b (a1)+,d4 + moveq #$f,d3 + and d4,d3 + lsr #4,d4 + sub.b .table(pc,d4),d5 + move.b d5,(a6)+ + sub.b .table(pc,d3),d5 + move.b d5,(a6)+ + dbf d7,.lo + bra.b .kop +.copy: + add d7,d7 + subq #1,d7 +.cob: + move.b (a1)+,(a6)+ + dbf d7,.cob + bra.b .kop +.table: + dc.b 0,1,2,4,8,16,32,64,128,-64,-32,-16,-8,-4,-2,-1 +.nobuffer: + move.l d4,d6 + add.l d6,d6 + add.l d6,a6 + add.l d6,a1 +.kop: + dbf d1,P61_lopos + move.l (sp)+,a0 + and.b #$7f,3(a0) + move.l a2,-(sp) + lea P61_temp0(pc),a1 + lea P61_temp1(pc),a2 + lea P61_temp2(pc),a4 + lea P61_temp3(pc),a5 + moveq #Channel_Block_Size/2-2,d0 + moveq #0,d1 +.cl: move d1,(a1)+ + move d1,(a2)+ + move d1,(a4)+ + move d1,(a5)+ + dbf d0,.cl + lea P61_temp0-P61_cn(a3),a1 + lea P61_emptysample-P61_cn(a3),a2 + moveq #channels-1,d0 +.loo: + move.l a2,P61_Sample(a1) + lea Channel_Block_Size(a1),a1 + dbf d0,.loo + move.l (sp)+,a2 + move.l a2,P61_positionbase-P61_cn(a3) + moveq #$7f,d1 + and.b 2(a0),d1 + ifeq opt020 + lsl #3,d1 + lea (a2,d1.l),a4 + else + lea (a2,d1.l*8),a4 + endc + move.l a4,P61_possibase-P61_cn(a3) ;base to pos. indices. + move.l a4,a1 + moveq #-1,d0 +.search: + cmp.b (a1)+,d0 + bne.b .search + move.l a1,P61_patternbase-P61_cn(a3) + move.l a1,d0 + sub.l a4,d0 + subq.w #1,d0 ;this is the * BUGFIX! whoa! + move d0,P61_slen-P61_cn(a3) +;; --- Bugfix: P61_Init gives P61_slen=actual songlength +1. +;; --- This did not affect NextPattern, because it looks for endbyte flag. +;; --- It did affect Bxx/Dxx, but I guess nobody has tried to jump or +;; --- break to Last Pattern, ever. Now fixed to set correct SLen and +;; --- suddenly Bxx/Dxx/Setposition works as they should. //Photon + add.w P61_InitPos(pc),a4 ;position from which to start playing the song + + moveq #0,d0 + move.b (a4)+,d0 + move.l a4,P61_spos-P61_cn(a3) + lsl #3,d0 + add.l d0,a2 + move.l a1,a4 + moveq #0,d0 ;hi word must be clear to manage >32K of patterns + move (a2)+,d0 ;and no movem-signextend. This code is correct. + lea (a4,d0.l),a1 + move.l a1,P61_ChaPos+P61_temp0-P61_cn(a3) + move (a2)+,d0 + lea (a4,d0.l),a1 + move.l a1,P61_ChaPos+P61_temp1-P61_cn(a3) + move (a2)+,d0 + lea (a4,d0.l),a1 + move.l a1,P61_ChaPos+P61_temp2-P61_cn(a3) + move (a2)+,d0 + lea (a4,d0.l),a1 + move.l a1,P61_ChaPos+P61_temp3-P61_cn(a3) + + ifeq nowaveforms + lea P61_setrepeat(pc),a0 + move.l a0,P61_intaddr-P61_cn(a3) + endc + + move #63,P61_rowpos-P61_cn(a3) + move #6,P61_speed-P61_cn(a3) + move #5,P61_speed2-P61_cn(a3) + clr P61_speedis1-P61_cn(a3) + ifne P61_pl + clr.l P61_plcount-P61_cn(a3) + endc + ifne P61_pde + clr P61_pdelay-P61_cn(a3) + clr P61_pdflag-P61_cn(a3) + endc + clr (a3) ;start frame of very first song note. +;"reused" patterns with effects coming out of nowhere +;at start of song require 0. Otherwise F0x speed-2 is +;ok, except if split4=1, set to F-speed - #channels. +;Don't change if you don't need 'the very quickest click to start' speed. + moveq #2,d0 + and.b $bfe001,d0 + move.b d0,P61_ofilter-P61_cn(a3) + bset #1,$bfe001 + ifeq p61system + ifne p61exec + move.l 4.w,a6 + moveq #0,d0 + btst d0,297(a6) + beq.b .no68010 + lea P61_liko(pc),a5 + jsr -$1e(a6) +.no68010: + move.l d0,P61_VBR-P61_cn(a3) + endc + move.l P61_VBR-P61_cn(a3),a0 + lea $78(a0),a0 + move.l a0,P61_vektori-P61_cn(a3) + move.l (a0),P61_oldlev6-P61_cn(a3) + ifeq copdma + lea P61_dmason(pc),a1 ;set 'dma-on-interrupt'. + move.l a1,(a0) + endc + endc + moveq #$f,d0 + lea $dff000+C,a6 ;a6 trashed above. + ifeq quietstart + moveq #$0,d1 ;original code + move d1,$a8-C(a6) + move d1,$b8-C(a6) + move d1,$c8-C(a6) + move d1,$d8-C(a6) + move d0,$96-C(a6) + endc + + ifne nowaveforms + move.w d0,P61_NewDMA-P61_cn(a3) ;"NEXTframe setloop" to be triggered + endc + + ifeq p61system + ifeq copdma + lea P61_dmason(pc),a1 ;again? + move.l a1,(a0) + endc + move #$2000,$9a-C(a6) ;old timerb OFF + lea $bfd000,a0 + lea P61_timers(pc),a1 + move.b #$7f,$d00(a0) + + ifne p61cia ;only affect cia if actually used + move.b #$10,$e00(a0) + endc + move.b #$10,$f00(a0) + ifne p61cia + move.b $400(a0),(a1)+ + move.b $500(a0),(a1)+ + else + addq.w #2,a1 + endc + + move.b $600(a0),(a1)+ + move.b $700(a0),(a1) + endc + ifeq (p61system+p61cia) + move.b #$82,$d00(a0) + endc + ifne p61cia + move (sp)+,d0 + subq #1,d0 + beq.b P61_ForcePAL + subq #1,d0 + beq.b P61_NTSC + ifne p61exec + move.l 4.w,a1 + cmp.b #60,$213(a1) + beq.b P61_NTSC + endc +P61_ForcePAL: + move.l #1773447,d0 + bra.b P61_setcia +P61_NTSC: + move.l #1789773,d0 +P61_setcia: + move.l d0,P61_timer-P61_cn(a3) + divu #125,d0 + move d0,P61_thi2-P61_cn(a3) + sub #$1f0*2,d0 + move d0,P61_thi-P61_cn(a3) + ifeq p61system + move P61_thi2-P61_cn(a3),d0 + move.b d0,$400(a0) + lsr #8,d0 + move.b d0,$500(a0) + lea P61_intti(pc),a1 + move.l a1,P61_tintti-P61_cn(a3) + move.l P61_vektori(pc),a2 + move.l a1,(a2) + move.b #$83,$d00(a0) + move.b #$11,$e00(a0) + endc + endc + + ifeq p61system + ifeq copdma + move #$e000,$9a-C(a6) ;level 6 timer B int, at least for setloop + else + move #$c000,$9a-C(a6) ;no level 6 timer B int, please + ;(bit 14 is cleared above.) + endc + ifne quietstart + move.w #$800f,$96-C(A6) ;make all used channels start a quiet loop. + endc + + moveq #0,d0 + rts + + ifne p61exec +P61_liko: + dc.l $4E7A0801 + rte + endc + endc + + ifne p61system + move.l a6,-(sp) + ifne p61cia + clr P61_server-P61_cn(a3) + else + move #1,P61_server-P61_cn(a3) + endc + move.l 4.w,a6 + moveq #-1,d0 + jsr -$14a(a6) + move.b d0,P61_sigbit-P61_cn(a3) + bmi P61_err + lea P61_allocport(pc),a1 + move.l a1,P61_portti-P61_cn(a3) + move.b d0,15(a1) + move.l a1,-(sp) + suba.l a1,a1 + jsr -$126(a6) + move.l (sp)+,a1 + move.l d0,16(a1) + lea P61_reqlist(pc),a0 + move.l a0,(a0) + addq.l #4,(a0) + clr.l 4(a0) + move.l a0,8(a0) + lea P61_dat(pc),a1 + move.l a1,P61_reqdata-P61_cn(a3) + lea P61_allocreq(pc),a1 + lea P61_audiodev(pc),a0 + moveq #0,d0 + moveq #0,d1 + jsr -$1bc(a6) + tst.l d0 + bne P61_err + st.b P61_audioopen-P61_cn(a3) + lea P61_timerint(pc),a1 + move.l a1,P61_timerdata-P61_cn(a3) + lea P61_lev6server(pc),a1 + move.l a1,P61_timerdata+8-P61_cn(a3) + moveq #0,d3 + lea P61_cianame(pc),a1 +P61_openciares: + moveq #0,d0 + move.l 4.w,a6 + jsr -$1f2(a6) + move.l d0,P61_ciares-P61_cn(a3) + beq.b P61_err + move.l d0,a6 + lea P61_timerinterrupt(pc),a1 + moveq #0,d0 + jsr -6(a6) + tst.l d0 + beq.b P61_gottimer + addq.l #4,d3 + lea P61_timerinterrupt(pc),a1 + moveq #1,d0 + jsr -6(a6) + tst.l d0 + bne.b P61_err +P61_gottimer: + lea P61_craddr+8(pc),a6 + move.l P61_ciaaddr(pc,d3),d0 + move.l d0,(a6) + sub #$100,d0 + move.l d0,-(a6) + moveq #2,d3 + btst #9,d0 + bne.b P61_timerB + subq.b #1,d3 + add #$100,d0 +P61_timerB: + add #$900,d0 + move.l d0,-(a6) + move.l d0,a0 + and.b #%10000000,(a0) + move.b d3,P61_timeropen-P61_cn(a3) + moveq #0,d0 + ifne p61cia + move.l P61_craddr+4(pc),a1 + move.b P61_tlo(pc),(a1) + move.b P61_thi(pc),$100(a1) + endc + or.b #$19,(a0) + + st P61_timeron-P61_cn(a3) +P61_pois: + move.l (sp)+,a6 + rts +P61_err:moveq #-1,d0 + bra.b P61_pois +P61_ciaaddr: + dc.l $bfd500,$bfd700 + endc + +********** P61_End ********** +* Input: none. +* Uses: D0-D1/A0-A1/A3/A6, A6 set to $dff000+C (your custombase) at exit. + +P61_End: + lea $dff000+C,a6 + moveq #0,d0 + move d0,$a8-C(a6) + move d0,$b8-C(a6) + move d0,$c8-C(a6) + move d0,$d8-C(a6) + move #$f,$96-C(a6) + and.b #%11111101,$bfe001 + move.b P61_ofilter(pc),d0 + or.b d0,$bfe001 + ifeq p61system + move #$2000,$9a-C(a6) + move.l P61_vektori(pc),a0 + move.l P61_oldlev6(pc),(a0) + lea $bfd000,a0 + lea P61_timers(pc),a1 + + ifne p61cia ;only affect cia if used + move.b (a1)+,$400(a0) + move.b (a1)+,$500(a0) + else + addq.w #2,a1 + endc + move.b (a1)+,$600(a0) + move.b (a1)+,$700(a0) + ifne p61cia + move.b #$10,$e00(a0) + endc + + move.b #$10,$f00(a0) + else + move.l a6,-(sp) + lea P61_cn(pc),a3 + moveq #0,d0 + clr P61_timeron-P61_cn(a3) + move.b P61_timeropen(pc),d0 + beq.b P61_rem1 + move.l P61_ciares(pc),a6 + lea P61_timerinterrupt(pc),a1 + subq.b #1,d0 + jsr -12(a6) +P61_rem1: + move.l 4.w,a6 + tst.b P61_audioopen-P61_cn(a3) + beq.b P61_rem2 + lea P61_allocreq(pc),a1 + jsr -$1c2(a6) + clr.b P61_audioopen-P61_cn(a3) +P61_rem2: + moveq #0,d0 + move.b P61_sigbit(pc),d0 + bmi.b P61_rem3 + jsr -$150(a6) + st P61_sigbit-P61_cn(a3) +P61_rem3: + move.l (sp)+,a6 + endc + rts + +;WHY not just cond-add mulu to where the finalvolume is set?? +;"Jag blir så matt." (c) The Big A/Phenomena. + + ifne p61fade +P61_mfade: + lea $dff0a8,a4 + move P61_Master(pc),d0 + move P61_temp0+P61_Shadow(pc),d1 + mulu d0,d1 + lsr #6,d1 + move d1,(a4) + ifgt channels-1 + move P61_temp1+P61_Shadow(pc),d1 + mulu d0,d1 + lsr #6,d1 + move d1,$10(a4) + endc + ifgt channels-2 + move P61_temp2+P61_Shadow(pc),d1 + mulu d0,d1 + lsr #6,d1 + move d1,$20(a4) + endc + ifgt channels-3 + move P61_temp3+P61_Shadow(pc),d1 + mulu d0,d1 + lsr #6,d1 + move d1,$30(a4) + endc + rts + endc + + ifne oscillo +****************************************** +;Call directly after P61_Music to get ptr,count of samples playing THIS frame + +;Input: a0=P61_temp0/1/2/3 (selects channel) +;Output: d0-d1/d4/a2=WrapCount.w,Count.w,Replen=0,SamplePtr +;Only if d0.w>0:d2/d4/a1=LoopEndPtr,Replen,LoopStartPtr +;Destroys: d0-d4/a1-a2, a0 points to next channel in oscdata. + +;Usage: +;If d1=0, this channel has not yet started playing sounds, and there is no +;usable data in the other registers. (I.e. don't start drawing oscilloscope +;for this chan yet.). D1 is tested at exit, so you can just beq to skip the +;channel. +;If d0<=0, just read d1 bytes from a2-ptr. +;If d0>0, subtract it from d1 and read d1 bytes from a2-ptr. Backup Loopstart +;in a1 to (for example) a3. Then read d0 bytes from a1-ptr, if you hit the +;LoopEnd address in d2, then read the remaining bytes from Loopstart that +;you saved in a3. +;---------------- +;Most samples have a short loop at the end. If you extend all short loops to +;578 bytes, you won't have to check your sample-read-address vs the WrapPtr +;in d2 in your loop. + +;A silent, short loop of 2 bytes at the end is common to end an instrument. +;P61_emptyloop578 has been provided to save this check for you for all +;one-shot instruments. + +;Set the oscextloops option to 0 if you haven't extended the other loops. This +;will enable an extra modulo div and disable P61_emptyloop578. You will also +;have to check for "end of replen" yourself in-loop, as mentioned. + +;Bonus checkable things: +;If d4=0, the instrument has not yet reached its end loop. +;oscextloops=0: if d4=1, the instrument ended (playing quiet 2-byte loop) +;oscextloops=1: only if d2=P61_emptyloop578E has the instrument ended. + +;Some bragging: +;The sample-window start and end points are rounded for convenience. +;They are rounded so that the ptrs and counts generate sample-windows with no +;gap or overlap between each frame, for a perfect sequence of memory areas. +;Internally it calculates with an accuracy of 1/262144, or about 6-7 decimals. +;It supports 128KB samples with <64KB loops. + +;It's fully possible to do per-frame mixing directly into playing samples +;using this precision. + +oscextloops=0 ;this saves a modulo-div +oscbigempty=0 ;optional buf regardless of oscextloops option +ticksframePAL=70937*4+2 ;50.00028194 Hz +ticksframeNTSC=59719*4+3 ;59.94005233 Hz + +P61_osc: + move.w P61_Period(a0),d4 ;check for div0 + bne.b .non0 +.div0: lea Channel_Block_Size(a0),a0 ;next chan + moveq #0,d1 ;return count of 0. + rts +.non0: + lea P61_oscptr(a0),a0 + move.l (a0)+,d0 ;ptr "x4" + + moveq #3,d3 + and.l d0,d3 ;remainder for wrapcalc + move.l d0,d2 + addq.l #2,d2 + lsr.l #2,d2 + move.l d2,a2 ;ptr result. + + move.l #ticksframePAL,d2 ;for NTSC, use the NTSC constant above. + divu d4,d2 ;count.w "x4", (ticks/frame) div period) + moveq #0,d1 + move.w d2,d1 ;'cleared hi word' + clr.w d2 ;modulo in hi word (mod<<16)/period + divu d4,d2 ;f.ex. 379/380 converted to 65536ths + add.w d2,(a0)+ ;ptr.rem updated + addx.l d1,d0 ;add count+"carry"=nextframe/'end' ptr + move.l d0,-6(a0) ;saved. + move.l d0,d1 + addq.l #2,d1 + lsr.l #2,d1 + sub.l a2,d1 ;correctly aliased sample-window byte count. + moveq #0,d2 ;default replen 0->d4 later + sub.l (a0)+,d0 ;loopend hit? + blt.b .nowr +;; --- handle overshoot --- + move.l P61_Sample-P61_DMABit(a0),a1 ;a1 "trashed" + ifeq oscbigempty + move.w 10(a1),d2 ;replen + subq.w #1,d2 + endc + move.l 6(a1),a1 ;repptr + + ifne oscbigempty + bne.b .nol1 + lea P61_emptyloop578(PC),a1 ;replace with nice big loopbuffer. +.nol1: + endc +;; --- a1 loopstartptr result done --- + ifeq oscbigempty + addq.l #1,d2 ;128KB support but <64KB loops, see divu. + add.l d2,d2 ;wordlen->bytelen + else + move.l #P61_emptyquiet578E-P61_emptyquiet578,d2 + endc +;; --- d2 replen result done --- + move.l a1,d4 ;loopstart + lsl.l #2,d4 ;"x4" + or.b d3,d4 ;keep round-bits, d3 usable now + + addq.w #2,d0 ;word size okay cos positive; hi word clr. + lsr.w #2,d0 ;rounded count result. + move.l d0,d3 + + ifeq oscextloops + divu d2,d3 ;overshoot modulo replen. + clr.w d3 ;(to not accumulate overshoot but stay in loop) + swap d3 + endc + + add.w d3,d3 ;unrounded count modulized, x4. + add.w d3,d3 ;will be at most 578. + add.l d4,d3 + move.l d3,-10(a0) ;jump to near loopstart. remainder kept, ofc. + + move.l d2,d4 ;proper replen + add.l a1,d2 ;LoopEndPtr result. + move.l d2,d3 + lsl.l #2,d3 + move.l d3,-4(a0) ;new endptr(x4) for compare. + bra.s .ct +.nowr: + move.l d2,d4 ;replen, also done in wrap, before adding a1. + addq.l #2,d0 ;long cos negative and 128KB support. + asr.l #2,d0 ;rounded wraplen result. +.ct: + addq.w #2,a0 ;skip P61_DMAbit + tst.w d1 ;test the count. + RTS + ifne oscbigempty +P61_emptyloop578: + dcb.w 578/2,0 ;@@ this "sample" MUST be in chipmem! +P61_emptyloop578E: + endc + endc + + ifne p61jump +****************************************** +* P61_SetPosition +; Call P61_SetPosition to jump to a specific position in the song +; If called AFTER P61_Music, what's written below will be true but happen one +; frame later. +;­ OPTIONALLY Starts from the beginning if out of limits. ­ + +* Input: D0.b=songposition. A6=your custombase ("$dff000") +* Uses: D0-D1/A0-A1/A3 + +;If you want to change pos 'at next note', call this when P61_cn=(P61_speed2-1) +;if you also need to change pos 'in rhythm', AND P61_CRow with f.ex. 2^n-1. +;if that equals 2^n-1 ("all 1s"), and cn is 'in tempo', you will get a smooth +;transition. If n is 64, you are sure to make the switch at pattern end. + +;@@ NOTE: If you use this with split4=1, be aware that it must then decrunch +;up to 2 framesteps before starting to play the song (meaning the song won't +;start playing quite instantly). + +P61_SetPosition: + lea P61_cn(pc),a3 + ifne split4 + move.w P61_speed2(PC),d1 ;if _Speedis1, _cn doesn't matter. + subq.w #3,d1 ;allow 2 more pre-decrunch frames. + else + move.w P61_speed2(PC),d1 ;if _Speedis1, _cn doesn't matter. + subq.w #1,d1 + endc +;new pattern reaches your ears NEXT frame or CIA-int, or 3 frames later with +;the split4 option. + move.w d1,(a3) ;instant SetPos, ie. decrunch next NOW + ifne P61_pl + clr P61_plflag-P61_cn(a3) + endc + moveq #0,d1 + move.b d0,d1 + move.l d1,d0 + + ifeq optjmp + cmp P61_slen-P61_cn(a3),d0 + blo.b .e + moveq #0,d0 +.e: + endc + + move d0,P61_Pos-P61_cn(a3) + add.l P61_possibase(pc),d0 + move.l d0,P61_spos-P61_cn(a3) + + moveq #63,d0 ;yeah, the original SetPos is, like, wrong. + move d0,P61_rowpos-P61_cn(a3) + clr P61_CRow-P61_cn(a3) + move.l P61_spos(pc),a1 + move.l P61_patternbase(pc),a0 + addq #1,P61_Pos-P61_cn(a3) + move.b (a1)+,d0 + move.l a1,P61_spos-P61_cn(a3) + move.l P61_positionbase(pc),a1 + move d0,P61_Patt-P61_cn(a3) + + lsl #3,d0 + add.l d0,a1 + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp0-P61_cn(a3) + moveq #0,d0 ;actually faster than lea (a0,d0.l) + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp1-P61_cn(a3) + moveq #0,d0 ;actually faster than lea (a0,d0.l) + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp2-P61_cn(a3) + moveq #0,d0 ;actually faster than lea (a0,d0.l) + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp3-P61_cn(a3) + + lea P61_temp0(PC),a3 + clr.b P61_Pack+Channel_Block_Size*0(a3) ;force new take + clr.b P61_Pack+Channel_Block_Size*1(a3) + clr.b P61_Pack+Channel_Block_Size*2(a3) + clr.b P61_Pack+Channel_Block_Size*3(a3) + clr.b P61_TempLen+1+Channel_Block_Size*0(a3) ;force TakeNORM + clr.b P61_TempLen+1+Channel_Block_Size*1(a3) + clr.b P61_TempLen+1+Channel_Block_Size*2(a3) + clr.b P61_TempLen+1+Channel_Block_Size*3(a3) + move.w #$ff00,d0 + move.w d0,P61_OnOff+Channel_Block_Size*0(a3) ;stop active decsteps + move.w d0,P61_OnOff+Channel_Block_Size*1(a3) + move.w d0,P61_OnOff+Channel_Block_Size*2(a3) + move.w d0,P61_OnOff+Channel_Block_Size*3(a3) + clr.b P61_dma+1-P61_temp0(a3) ;stop playing channels + move.w #$000f,$96-C(A6) ;indeed, in speakers too. + ifne nowaveforms + clr P61_NewDMA-P61_temp0(a3) ;stop DMA next note + endc + ifne copdma + move.l p61_DMApokeAddr(PC),a3 ;don't set DMA until playtime + clr.b (a3) + endc + rts + endc +********** Main entry point from CIA/VB int or frame loop ********** +* Input: A6=your custombase ("$dff000") +* Uses: D0-A7, A6 set to $dff000+C (your custombase) at exit. +P61_Music: + lea P61_cn(pc),a3 + moveq #0,d7 ;replaced clr.* with move.* d7, + lea $a0-C(a6),a4 ;Aud Chan Base. + + ifne playflag + tst P61_Play-P61_cn(a3) ;set by init if CIA + bne.b P61_ohitaaa + ifne p61cia + ifne p61system + move.l P61_craddr+4(pc),a0 + move.b P61_tlo2(pc),(a0) + move.b P61_thi2(pc),$100(a0) + endc + endc + rts + endc + +P61_ohitaaa: + ifne visuctrs ;easy visualizer counters. + addq.w #1,P61_visuctr0-P61_cn(a3) ;inc elapsed #calls since last + addq.w #1,P61_visuctr1-P61_cn(a3) + addq.w #1,P61_visuctr2-P61_cn(a3) + addq.w #1,P61_visuctr3-P61_cn(a3) + endc + + ifne p61fade + pea P61_mfade(pc) + endc + + move.w (a3),d4 + cmp.w P61_speed2(pc),d4 ;Really compares with P61_speed, 1 added later. + beq.w P61_playtime ;if new note frame, handle +;; --- no new note --- +; bsr P61_Synth ;synth/pan/echo cpu-mix routine. Not done yet. +;(note: re-cmp to d4 if you put something here.) + ifeq suppF01 + blt.b P61_nowrap ;otherwise last was not playtime-frame. + endc +;; --- first frame of new step --- +;rolled over from playtime to frame after. incompatible with F01. + ifeq suppF01 + ifne nowaveforms + move.b P61_dma+1-P61_cn(a3),P61_NewDMA+1-P61_cn(a3) ;or set by fx + endc + clr.w d4 + + subq #1,P61_rowpos-P61_cn(a3) ;next pattern-step + bpl.b P61_nonewpatt + +P61_nextpattern: + ifne P61_pl + move d7,P61_plflag-P61_cn(a3) + endc + move.l P61_patternbase(pc),a0 + moveq #63,d0 + move d0,P61_rowpos-P61_cn(a3) + move d7,P61_CRow-P61_cn(a3) + move.l P61_spos(pc),a1 + addq #1,P61_Pos-P61_cn(a3) + move.b (a1)+,d0 + bpl.b P61_dk + move.l P61_possibase(pc),a1 + move.b (a1)+,d0 + move d7,P61_Pos-P61_cn(a3) +P61_dk: + move.l a1,P61_spos-P61_cn(a3) + move d0,P61_Patt-P61_cn(a3) + lsl #3,d0 + move.l P61_positionbase(pc),a1 + add.l d0,a1 + move.w (a1)+,d0 ;no movem sign-extend... check. + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp0-P61_cn(a3) + moveq #0,d0 ;actually faster than lea (a0,d0.l) + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp1-P61_cn(a3) + moveq #0,d0 ;actually faster than lea (a0,d0.l) + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp2-P61_cn(a3) + moveq #0,d0 ;actually faster than lea (a0,d0.l) + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp3-P61_cn(a3) + bra.b P61_nowrap +P61_nonewpatt: + moveq #63,d0 + sub P61_rowpos-P61_cn(a3),d0 + move d0,P61_CRow-P61_cn(a3) + endc +;; --- end of rolled over code --- + +P61_nowrap: + addq.w #1,d4 ;NOW I do! + move d4,(a3) + +P61_delay: + ifne nowaveforms ;nd,rt,sof, or note triggered dmaoff + move.w P61_NewDMA(PC),d5 ;on last P61_Music call? + beq.b .nosetloops + move.l P61_Sample+P61_temp0(PC),a0 + move.l 6(a0),(a4) ;loop start + move.w 10(a0),4(a4) ;loop len + ifgt channels-1 + move.l P61_Sample+P61_temp1(PC),a0 + move.l 6(a0),$10(a4) ;loop start + move.w 10(a0),$14(a4) ;loop len + endc + ifgt channels-2 + move.l P61_Sample+P61_temp2(PC),a0 + move.l 6(a0),$20(a4) ;loop start + move.w 10(a0),$24(a4) ;loop len + endc + ifgt channels-3 + move.l P61_Sample+P61_temp3(PC),a0 + move.l 6(a0),$30(a4) ;loop start + move.w 10(a0),$34(a4) ;loop len + endc + move.w d7,P61_NewDMA-P61_cn(a3) ;poll (clear) + +.nosetloops: + endc + + ifne p61cia + ifne p61system + move.l P61_craddr+4(pc),a0 + move.b P61_tlo2(pc),(a0) + move.b P61_thi2(pc),$100(a0) + endc + endc +********** mainfx handling ********** + lea P61_temp0(pc),a5 + moveq #channels-1,d5 +P61_lopas: + tst.b P61_OnOff+1(a5) + beq.w P61_contfxdone + moveq #$f,d0 + and (a5),d0 + ifeq opt020 + add d0,d0 + move P61_jtab2(pc,d0),d0 + else + move P61_jtab2(pc,d0*2),d0 + endc + jmp P61_jtab2(pc,d0) +P61_jtab2: + dc P61_contfxdone-P61_jtab2 + ifne P61_pu + dc P61_portup-P61_jtab2 + else + dc P61_contfxdone-P61_jtab2 + endc + ifne P61_pd + dc P61_portdwn-P61_jtab2 + else + dc P61_contfxdone-P61_jtab2 + endc + ifne P61_tp + dc P61_toneport-P61_jtab2 + else + dc P61_contfxdone-P61_jtab2 + endc + ifne P61_vib + dc P61_vib2-P61_jtab2 + else + dc P61_contfxdone-P61_jtab2 + endc + ifne P61_tpvs + dc P61_tpochvslide-P61_jtab2 + else + dc P61_contfxdone-P61_jtab2 + endc + ifne P61_vbvs + dc P61_vibochvslide-P61_jtab2 + else + dc P61_contfxdone-P61_jtab2 + endc + ifne P61_tre + dc P61_tremo-P61_jtab2 + else + dc P61_contfxdone-P61_jtab2 + endc + ifne P61_arp + dc P61_arpeggio-P61_jtab2 + else + dc P61_contfxdone-P61_jtab2 + endc + dc P61_contfxdone-P61_jtab2 + ifne P61_vs + dc P61_volslide-P61_jtab2 + else + dc P61_contfxdone-P61_jtab2 + endc + dc P61_contfxdone-P61_jtab2 + dc P61_contfxdone-P61_jtab2 + dc P61_contfxdone-P61_jtab2 + ifne P61_ec + dc P61_contecommands-P61_jtab2 + else + dc P61_contfxdone-P61_jtab2 + endc + dc P61_contfxdone-P61_jtab2 +;; --- end of contfx table --- + + ifne P61_ec +P61_contecommands: + move.b P61_Info(a5),d0 + and #$f0,d0 + lsr #3,d0 + move P61_etab2(pc,d0),d0 + jmp P61_etab2(pc,d0) +P61_etab2: + dc P61_contfxdone-P61_etab2 + ifne P61_fsu + dc P61_fineup2-P61_etab2 + else + dc P61_contfxdone-P61_etab2 + endc + ifne P61_fsd + dc P61_finedwn2-P61_etab2 + else + dc P61_contfxdone-P61_etab2 + endc + dc P61_contfxdone-P61_etab2 + dc P61_contfxdone-P61_etab2 + dc P61_contfxdone-P61_etab2 + dc P61_contfxdone-P61_etab2 + dc P61_contfxdone-P61_etab2 + dc P61_contfxdone-P61_etab2 + ifne P61_rt + dc P61_retrig-P61_etab2 + else + dc P61_contfxdone-P61_etab2 + endc + ifne P61_fvu + dc P61_finevup2-P61_etab2 + else + dc P61_contfxdone-P61_etab2 + endc + ifne P61_fvd + dc P61_finevdwn2-P61_etab2 + else + dc P61_contfxdone-P61_etab2 + endc + ifne P61_nc + dc P61_notecut-P61_etab2 + else + dc P61_contfxdone-P61_etab2 + endc + ifne P61_nd + dc P61_notedelay-P61_etab2 + else + dc P61_contfxdone-P61_etab2 + endc + dc P61_contfxdone-P61_etab2 + dc P61_contfxdone-P61_etab2 + endc + ifne P61_fsu +P61_fineup2: + tst (a3) + bne.w P61_contfxdone + moveq #$f,d0 + and.b P61_Info(a5),d0 + sub d0,P61_Period(a5) + moveq #113,d0 + cmp P61_Period(a5),d0 + ble.b .jup + move d0,P61_Period(a5) +.jup: move P61_Period(a5),6(a4) + bra.w P61_contfxdone + endc + ifne P61_fsd +P61_finedwn2: + tst (a3) + bne.w P61_contfxdone + moveq #$f,d0 + and.b P61_Info(a5),d0 + add d0,P61_Period(a5) + cmp #856,P61_Period(a5) + ble.b .jup + move #856,P61_Period(a5) +.jup: move P61_Period(a5),6(a4) + bra.w P61_contfxdone + endc + ifne P61_fvu +P61_finevup2: + tst (a3) + bne.w P61_contfxdone + moveq #$f,d0 + and.b P61_Info(a5),d0 + add d0,P61_Volume(a5) + moveq #64,d0 + cmp P61_Volume(a5),d0 + bge.b .jup + move d0,P61_Volume(a5) +.jup: move P61_Volume(a5),8(a4) + bra.w P61_contfxdone + endc + ifne P61_fvd +P61_finevdwn2: + tst (a3) + bne.w P61_contfxdone + moveq #$f,d0 + and.b P61_Info(a5),d0 + sub d0,P61_Volume(a5) + bpl.b .jup + move d7,P61_Volume(a5) +.jup: move P61_Volume(a5),8(a4) + bra.w P61_contfxdone + endc + ifne P61_nc +P61_notecut: + moveq #$f,d0 + and.b P61_Info(a5),d0 + cmp (a3),d0 + bne.w P61_contfxdone + ifeq p61fade + move d7,8(a4) + else + move d7,P61_Shadow(a5) + endc + move d7,P61_Volume(a5) + bra.w P61_contfxdone + endc + ifne P61_nd +P61_notedelay: + moveq #$f,d0 + and.b P61_Info(a5),d0 + cmp (a3),d0 + bne.w P61_contfxdone + moveq #$7e,d0 + and.b (a5),d0 + beq.w P61_contfxdone + move P61_DMABit(a5),d0 + move d0,$96-C(a6) ;turn chan dma off + or d0,P61_dma-P61_cn(a3) ;flag for turnon later + ifne nowaveforms + or d0,P61_NewDMA-P61_cn(a3) ;no interrupt needed, done next frame. + endc + move.l P61_Sample(a5),a1 ;set new ptr len already + ifeq oscillo + move.l (a1)+,(a4) + move (a1),4(a4) + else +;; --- wohoo oscilloscope ptrs --- + moveq #0,d1 + move.l (a1)+,d0 + move (a1),d1 + move.l d0,(a4) + move.w d1,4(a4) + subq.w #1,d1 + addq.l #1,d1 ;128KB support for sample endptr + lsl.l #2,d0 ;clear remainder. + move.l d0,P61_oscptr(a5) + move.w d7,P61_oscptrrem(a5) ;clear remainder. + lsl.l #3,d1 + add.l d0,d1 + move.l d1,P61_oscptrWrap(a5) ;wrap endptr for compare. + endc + +; move P61_Period(a5),(a4) +; subq.l #6,a4 + move P61_Period(a5),6(a4) ;bugfix from P6108+ + + ifne copdma + move.l p61_DMApokeAddr(PC),a0 + move.b P61_dma+1-P61_cn(a3),(a0) ;keep updated. + endc + + ifeq copdma&nowaveforms ;both must be on to skip int. + ifeq p61system ;int starter. + lea P61_dmason(pc),a1 + move.l P61_vektori(pc),a0 + move.l a1,(a0) + move.b #$f0,$bfd600 + move.b #$01,$bfd700 + move.b #$19,$bfdf00 + else + move #1,P61_server-P61_cn(a3) + move.l P61_craddr+4(pc),a1 + move.b #$f0,(a1) + move.b #1,$100(a1) + endc + endc + + bra.w P61_contfxdone + endc + ifne P61_rt +P61_retrig: + subq #1,P61_RetrigCount(a5) + bne.w P61_contfxdone + move P61_DMABit(a5),d0 + move d0,$96-C(a6) + or d0,P61_dma-P61_cn(a3) + ifne nowaveforms + or d0,P61_NewDMA-P61_cn(a3) ;no interrupt needed, done next frame. + endc + + move.l P61_Sample(a5),a1 + ifeq oscillo + move.l (a1)+,(a4) + move (a1),4(a4) + else +;; --- wohoo oscilloscope ptrs --- + moveq #0,d1 + move.l (a1)+,d0 + move (a1),d1 + move.l d0,(a4) + move.w d1,4(a4) + subq.w #1,d1 + addq.l #1,d1 ;128KB support for sample endptr + lsl.l #2,d0 ;clear remainder. + move.l d0,P61_oscptr(a5) + move.w d7,P61_oscptrrem(a5) ;clear remainder. + lsl.l #3,d1 + add.l d0,d1 + move.l d1,P61_oscptrWrap(a5) ;wrap endptr for compare. + endc + + ifne copdma + move.l p61_DMApokeAddr(PC),a0 + move.b P61_dma+1-P61_cn(a3),(a0) ;keep updated. + endc + + ifeq copdma&nowaveforms ;both must be on to skip int. + ifeq p61system ;int starter. + lea P61_dmason(pc),a1 + move.l P61_vektori(pc),a0 + move.l a1,(a0) + move.b #$f0,$bfd600 + move.b #$01,$bfd700 + move.b #$19,$bfdf00 + else + move #1,P61_server-P61_cn(a3) + move.l P61_craddr+4(pc),a1 + move.b #$f0,(a1) + move.b #1,$100(a1) + endc + endc + + moveq #$f,d0 + and.b P61_Info(a5),d0 + move d0,P61_RetrigCount(a5) + bra.w P61_contfxdone + endc + + ifne P61_arp +P61_arplist: + dc.b 0,1,-1,0,1,-1,0,1,-1,0,1,-1,0,1,-1,0 + dc.b 1,-1,0,1,-1,0,1,-1,0,1,-1,0,1,-1,0,1 +P61_arpeggio: + move (a3),d0 + move.b P61_arplist(pc,d0),d0 + beq.b .arp0 + bmi.b .arp1 + move.b P61_Info(a5),d0 + lsr #4,d0 + bra.b .arp3 +.arp0: + move P61_Note(a5),d0 + move P61_periods-P61_cn(a3,d0),6(a4) + bra.w P61_contfxdone +.arp1: + moveq #$f,d0 + and.b P61_Info(a5),d0 +.arp3: + add d0,d0 + add P61_Note(a5),d0 + move P61_periods-P61_cn(a3,d0),6(a4) + bra.w P61_contfxdone + endc +;; --- period table move to before P61_cn --- + ifne P61_vs +P61_volslide: + move.b P61_Info(a5),d0 + sub.b d0,P61_Volume+1(a5) + bpl.b .test + move d7,P61_Volume(a5) + ifeq p61fade + move d7,8(a4) + else + move d7,P61_Shadow(a5) + endc + bra.w P61_contfxdone +.test: + moveq #64,d0 + cmp P61_Volume(a5),d0 + bge.b .ncs + move d0,P61_Volume(a5) + ifeq p61fade + move d0,8(a4) + else + move d0,P61_Shadow(a5) + endc + bra.w P61_contfxdone +.ncs: + ifeq p61fade + move P61_Volume(a5),8(a4) + else + move P61_Volume(a5),P61_Shadow(a5) + endc + bra.w P61_contfxdone + endc + ifne P61_tpvs +P61_tpochvslide: + move.b P61_Info(a5),d0 + sub.b d0,P61_Volume+1(a5) + bpl.b .test + move d7,P61_Volume(a5) + ifeq p61fade + move d7,8(a4) + else + move d7,P61_Shadow(a5) + endc + bra.b P61_toneport +.test: + moveq #64,d0 + cmp P61_Volume(a5),d0 + bge.b .ncs + move d0,P61_Volume(a5) +.ncs: + ifeq p61fade + move P61_Volume(a5),8(a4) + else + move P61_Volume(a5),P61_Shadow(a5) + endc + endc + ifne P61_tp +P61_toneport: + move P61_ToPeriod(a5),d0 + beq.w P61_contfxdone + move P61_TPSpeed(a5),d1 + cmp P61_Period(a5),d0 + blt.b .topoup + add d1,P61_Period(a5) + cmp P61_Period(a5),d0 + bgt.b .setper + move d0,P61_Period(a5) + move d7,P61_ToPeriod(a5) + move d0,6(a4) + bra.b P61_contfxdone +.topoup: + sub d1,P61_Period(a5) + cmp P61_Period(a5),d0 + blt.b .setper + move d0,P61_Period(a5) + move d7,P61_ToPeriod(a5) +.setper: + move P61_Period(a5),6(a4) + else + nop + endc + bra.w P61_contfxdone + + ifne P61_pu +P61_portup: + moveq #0,d0 + move.b P61_Info(a5),d0 + ifne use1Fx + cmp.b #$f0,d0 + bhs.b P61_contfxdone + endc + sub d0,P61_Period(a5) + moveq #113,d0 + cmp P61_Period(a5),d0 + ble.b .skip + move d0,P61_Period(a5) + move d0,6(a4) + bra.b P61_contfxdone +.skip: + move P61_Period(a5),6(a4) + bra.w P61_contfxdone + endc + ifne P61_pd +P61_portdwn: + moveq #0,d0 + move.b P61_Info(a5),d0 + add d0,P61_Period(a5) + cmp #856,P61_Period(a5) ;max period=6.95 (7) scanlines per two samples. + ble.b .skip + move #856,d0 + move d0,P61_Period(a5) + move d0,6(a4) + bra.b P61_contfxdone +.skip: + move P61_Period(a5),6(a4) +; bra.w P61_contfxdone + endc +********** MainFX returns here from all fx ********** +P61_contfxdone: + ifne P61_il + bsr.w P61_funk2 + endc + lea Channel_Block_Size(a5),a5 + lea Custom_Block_Size(a4),a4 + dbf d5,P61_lopas +;; --- splitchans or normal decrunch --- + ifeq split4 + cmp P61_speed2(PC),d4 ;'decrunch frame'? (1 before playtime) + bne.w P61_ret2 + +P61_preplay2: + +.pr: ifle (channels-splitchans) + printt "splitchans >= channels! Must be less." + else + moveq #(channels-splitchans)-1,d5 ;do preplay "first" half + lea P61_temp0(pc),a5 + bra.w P61_preplay + endc + + else ;split4 +;; --- split4 decrunch --- +;Copies relevant chandata from a0 to a5 +CHANCPY: macro + movem.l (a0),d0-d4 + movem.l d0-d4,(a5) + ifne P61_ft + move.l P61_Volume(a0),P61_Volume(a5) ;vol+ft + else + move.w P61_Volume(a0),P61_Volume(a5) ;vol + endc + + ifne P61_sof + move.w P61_Offset(a0),P61_Offset(a5) + endc + ifne P61_il + move.l P61_Wave(a0),P61_Wave(a5) + endc + endm + +P61_split4: + move.w P61_speed2(PC),d5 + cmp.w d5,d4 + beq.b .pr2 + subq.w #1,d5 + cmp.w d5,d4 + beq.b .pr1 + subq.w #1,d5 + cmp.w d5,d4 + bne.w P61_ret2 ;last decrunchframe is in playtime +.pr0: + lea P61_temp0copy(PC),a5 ;dst + lea P61_temp0(PC),a0 ;src + CHANCPY + bra.w P61_preplay ;decrunches to copy +.pr1: + ifgt channels-1 + lea P61_temp1copy(PC),a5 ;dst + lea P61_temp1(PC),a0 ;src + CHANCPY + bra.w P61_preplay ;decrunches to copy + else + rts + endc +.pr2: + lea P61_temp0copy(PC),a0 ;src + lea P61_temp0(PC),a5 ;dst + CHANCPY + ifgt channels-1 + lea P61_temp1copy(PC),a0 ;src + lea P61_temp1(PC),a5 ;dst + CHANCPY + endc + ifgt channels-2 + lea P61_temp2(PC),a5 ;...and decrunch this chan to normal + bra.w P61_preplay + else + rts + endc + + endc ;if split4 +********** My Jump Table ********** +P61_MyJpt:;jump table,%x1111xxx,%x111xxxx,%x11xxxxx=note,cmd,all - else empty +; REPT 12 + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) + jmp P61_all(PC) + jmp P61_all2(PC) +; ENDR + jmp P61_cmd(PC) + jmp P61_cmd2(PC) + jmp P61_cmd(PC) + jmp P61_cmd2(PC) + jmp P61_noote(PC) + jmp P61_note2(PC) + jmp P61_empty(PC) + jmp P61_empty2(PC) + +; REPT 12 + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) + jmp P61_allS(PC) + jmp P61_all2S(PC) +; ENDR + jmp P61_cmdS(PC) + jmp P61_cmd2S(PC) + jmp P61_cmdS(PC) + jmp P61_cmd2S(PC) + jmp P61_noteS(PC) + jmp P61_note2S(PC) + jmp P61_emptyS(PC) +; jmp P61_empty2S(PC) +********** END OF MYJPT ********** +P61_empty2S: + move d7,(a5)+ + move.b d7,(a5)+ +;; --- alt exit --- +P61_proccompS: + move.b (a0)+,d1 + move.b d1,d0 + + add.b d1,d1 + bpl.b P61_permexit ;bit 6 was 0 +;; --- stay in chan, repeat --- +.b6set: bcs.b .bit16 + +.bit8: move.b d7,(a5) + subq.l #3,a5 ;stay tuned to this channel! + and.w d4,d0 ;nec to clr hi byte + move.b d0,P61_TempLen+1(a5) + move.b (a0)+,d0 ;hi word is clear. (constant) + move.l a0,P61_ChaPos(a5) ;dupe of above + sub.l d0,a0 ;this 'repeats' same but doesnt update! +.jedi1: move.b (a0)+,d0 ;used in .empty etc + moveq #-8,d1 ;if sign, new P61_pack, retaddr-2 + and.b d0,d1 + jmp P61_MyJpt+256(PC,d1.w) + +.bit16: move.b d7,(a5) + subq.l #3,a5 + and.w d4,d0 ;nec to clr hi byte + move.b d0,P61_TempLen+1(a5) + ifeq opt020 + move.b (a0)+,d0 ;hi word is clear. (constant) + lsl #8,d0 + move.b (a0)+,d0 + else + move.w (a0)+,d0 ;(potentially) odd-address word-read. + endc + move.l a0,P61_ChaPos(a5) ;dupe of above + sub.l d0,a0 ;this 'repeats' same but doesnt update! +.jedi2: move.b (a0)+,d0 ;used in .empty etc + moveq #-8,d1 ;if sign, new P61_pack, retaddr-2 + and.b d0,d1 + jmp P61_MyJpt+256(PC,d1.w) + +P61_Take: + tst.b P61_TempLen+1(a5) ;faster than subq + addq! + bne.b P61_takeone +P61_TakeNorm: ;this is more frequent than takeone + move.l P61_ChaPos(a5),a0 ;dflt - if takenorm + move.b (a0)+,d0 ;used in .empty etc + moveq #-8,d1 ;if sign, new P61_pack, retaddr-2 + and.b d0,d1 + jmp P61_MyJpt+256+4(PC,d1.w) ;first call can be this... +P61_takeone: + subq.b #1,P61_TempLen+1(a5) + move.l P61_TempPos(a5),a0 +P61_Jedi: ;temp/repeat. copy below proccompS. + move.b (a0)+,d0 ;used in .empty etc + moveq #-8,d1 ;if sign, new P61_pack, retaddr-2 + and.b d0,d1 + jmp P61_MyJpt+256(PC,d1.w) ;but rest is always this +;; --- alt (perm) exit --- ;does not affect maxtime. +P61_permexit: + move.b d0,(a5) + move.l a0,P61_ChaPos-3(a5) + bra.w P61_permdko + + ifne P61_pde +P61_return: + rts + endc +********** Replay, Decrunch notes ********** +;This routine is optimized absolutely and gets the Henrik-stamp of approval. +;d3,a4,a6 are usable ... if you can find a use for them. + + ifne P61_pde +P61_preplay: + tst P61_pdflag-P61_cn(a3) + bne.b P61_return + else +P61_preplay: + endc + +;; --- The hipper wilderbeest run gnu linux at midnight! --- + ifne P61_ft + lea (P61_samples-16)-P61_cn(a3),a2 + endc + moveq #$3f,d4 + moveq #-$10,d6 ;intelligent on/off-flag + moveq #0,d0 ;clear hi word, never dirtied below. +;; --- decrunch loop --- +P61_loaps: +;remember... code with BRAS in it is PANTS! +;As female coders know, they are often quite unnecessary. + ifne P61_pl ;make some backup copy of chanparams + lea P61_TData(a5),a1 + move 2(a5),(a1)+ + move.l P61_ChaPos(a5),(a1)+ + move.l P61_TempPos(a5),(a1)+ + move P61_TempLen(a5),(a1) + endc + + moveq #-65,d1 ;%10111111 const + and.b P61_Pack(a5),d1 + add.b d1,d1 ;sign in carry + beq.b P61_Take ;6 lsb bits 0? + bcc.b P61_nodko + addq #3,a5 + subq.b #1,(a5) + bra.w P61_permdko +P61_nodko: + move.b d7,P61_OnOff+1(a5) + subq.b #1,P61_Pack(a5) + addq #3,a5 + bra.w P61_koto + +;; --- routines --- +P61_empty: + move d7,(a5)+ + move.b d7,(a5)+ + bra.w P61_ex +P61_all: + move.b d0,(a5)+ ;but this can't... + ifeq opt020 + move.b (a0)+,(a5)+ + move.b (a0)+,(a5)+ + else + move (a0)+,(a5)+ + endc + bra.w P61_ex +P61_cmd: + moveq #$f,d1 + and d0,d1 + move d1,(a5)+ + move.b (a0)+,(a5)+ ;join common endcontinues... + bra.w P61_ex +P61_noote: + moveq #7,d1 + and d0,d1 + lsl #8,d1 + move.b (a0)+,d1 + lsl #4,d1 + move d1,(a5)+ + move.b d7,(a5)+ + bra.w P61_ex +;; --- copyS --- +P61_emptyS: + move d7,(a5)+ + move.b d7,(a5)+ + bra.w P61_exS +P61_allS: + move.b d0,(a5)+ ;but this can't... + ifeq opt020 + move.b (a0)+,(a5)+ + move.b (a0)+,(a5)+ + else + move (a0)+,(a5)+ + endc + bra.b P61_exS +P61_cmdS: + moveq #$f,d1 + and d0,d1 + move d1,(a5)+ + move.b (a0)+,(a5)+ ;join common endcontinues... + bra.b P61_exS +;; --- --- +********** copy, perm exit ********** +P61_empty2: + move d7,(a5)+ + move.b d7,(a5)+ + move.l a0,P61_ChaPos-3(a5) + bra.b P61_permdko +P61_all2: + move.b d0,(a5)+ + ifeq opt020 + move.b (a0)+,(a5)+ + move.b (a0)+,(a5)+ + else + move (a0)+,(a5)+ + endc + move.l a0,P61_ChaPos-3(a5) + bra.b P61_permdko +P61_cmd2: + moveq #$f,d1 + and d0,d1 + move d1,(a5)+ + move.b (a0)+,(a5)+ + move.l a0,P61_ChaPos-3(a5) + bra.b P61_permdko +P61_note2: + moveq #7,d1 + and d0,d1 + lsl #8,d1 + move.b (a0)+,d1 + lsl #4,d1 + move d1,(a5)+ + move.b d7,(a5)+ + move.l a0,P61_ChaPos-3(a5) + bra.b P61_permdko +;; --- copyS, diff exit --- +P61_note2S: + moveq #7,d1 + and d0,d1 + lsl #8,d1 + move.b (a0)+,d1 + lsl #4,d1 + move d1,(a5)+ + move.b d7,(a5)+ + bra.w P61_proccompS +P61_all2S: + move.b d0,(a5)+ + ifeq opt020 + move.b (a0)+,(a5)+ + move.b (a0)+,(a5)+ + else + move (a0)+,(a5)+ + endc + bra.w P61_proccompS +P61_cmd2S: + moveq #$f,d1 + and d0,d1 + move d1,(a5)+ + move.b (a0)+,(a5)+ + bra.w P61_proccompS +;; --- --- +P61_noteS: + moveq #7,d1 + and d0,d1 + lsl #8,d1 + move.b (a0)+,d1 + lsl #4,d1 + move d1,(a5)+ + move.b d7,(a5)+ +;; --- norm (temp) exit --- +;This exit is called when you have max rastertime. +P61_exS: + move.b (a0)+,(a5) +P61_ex: + move.l a0,P61_TempPos-3(a5) +P61_permdko: + move.w d6,P61_OnOff-3(a5) ;was byte size in word var... + move -3(a5),d0 + and #$1f0,d0 + beq.b .koto + ifne P61_ft + lea (a2,d0),a1 ;this is not the same a2 as the fix. + else + lea (P61_samples-16)-P61_cn(a3),a1 + add d0,a1 + endc + move.l a1,P61_Sample-3(a5) + ifne P61_ft + move.l P61_SampleVolume(a1),P61_Volume-3(a5) + else + move P61_SampleVolume(a1),P61_Volume-3(a5) + endc + ifne P61_il + move.l P61_RepeatOffset(a1),P61_Wave-3(a5) + endc + ifne P61_sof + move d7,P61_Offset-3(a5) + endc +.koto: +P61_koto: + ifeq split4 ;split4 means only do once. + lea Channel_Block_Size-3(a5),a5 + dbf d5,P61_loaps + endc +P61_ret2: + rts + +********** END OF LOAPS LOOP ********** +********** here comes another :) ********** + ifeq dupedec +P61_playtime: + addq.w #1,(a3) ;inc framecount past _Speed for detection+reset later + ifeq split4 + ifgt splitchans + moveq #splitchans-1,d5 ;channels split off?(optimization flag) + lea P61_temp0+Channel_Block_Size*(channels-splitchans)(PC),a5 + bsr P61_preplay + endc ;if splitchans + + else + + ifgt channels-3 + lea P61_temp3(PC),a5 + bsr P61_preplay + endc + endc ;if split4. + + endc ;dupedec=0 ends here + + ifgt (splitchans+split4) ;one of these must be on for dupe-code + ifne dupedec ;dupedec...you asked for it... +********** My Jump Table ********** +P61_MyJptB:;jump table,%x1111xxx,%x111xxxx,%x11xxxxx=note,cmd,all - else empty +; REPT 12 + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) + jmp P61_allB(PC) + jmp P61_all2B(PC) +; ENDR + jmp P61_cmdB(PC) + jmp P61_cmd2B(PC) + jmp P61_cmdB(PC) + jmp P61_cmd2B(PC) + jmp P61_nooteB(PC) + jmp P61_note2B(PC) + jmp P61_emptyB(PC) + jmp P61_empty2B(PC) + +; REPT 12 + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) + jmp P61_allSB(PC) + jmp P61_all2SB(PC) +; ENDR + jmp P61_cmdSB(PC) + jmp P61_cmd2SB(PC) + jmp P61_cmdSB(PC) + jmp P61_cmd2SB(PC) + jmp P61_noteSB(PC) + jmp P61_note2SB(PC) + jmp P61_emptySB(PC) + jmp P61_empty2SB(PC) +********** END OF MYJPT ********** +P61_empty2SB: + move d7,(a5)+ + move.b d7,(a5)+ +;; --- alt exit --- +P61_proccompSB: + move.b (a0)+,d1 + move.b d1,d0 + + add.b d1,d1 + bpl.b P61_permexitB ;bit 6 was 0 +;; --- stay in chan, repeat --- +.b6setB:bcs.b .bit16B +.bit8B: move.b d7,(a5) + subq.l #3,a5 ;stay tuned to this channel! + and.w d4,d0 ;nec to clr hi byte + move.b d0,P61_TempLen+1(a5) + move.b (a0)+,d0 ;hi word is clear. (constant) + move.l a0,P61_ChaPos(a5) ;dupe of above + sub.l d0,a0 ;this 'repeats' same but doesnt update! +.jedi1B:move.b (a0)+,d0 ;used in .empty etc + moveq #-8,d1 ;if sign, new P61_pack, retaddr-2 + and.b d0,d1 + jmp P61_MyJptB+256(PC,d1.w) + +.bit16B:move.b d7,(a5) + subq.l #3,a5 + and.w d4,d0 ;nec to clr hi byte + move.b d0,P61_TempLen+1(a5) + ifeq opt020 + move.b (a0)+,d0 ;hi word is clear. (constant) + lsl #8,d0 + move.b (a0)+,d0 + else + move.w (a0)+,d0 ;(potentially) odd-address word-read. + endc + move.l a0,P61_ChaPos(a5) ;dupe of above + sub.l d0,a0 ;this 'repeats' same but doesnt update! +.jedi2B:move.b (a0)+,d0 ;used in .empty etc + moveq #-8,d1 ;if sign, new P61_pack, retaddr-2 + and.b d0,d1 + jmp P61_MyJptB+256(PC,d1.w) + +P61_TakeB: + tst.b P61_TempLen+1(a5) ;faster than sub + add! + bne.b P61_takeoneB +P61_TakeNormB: ;this is more frequent than takeone + move.l P61_ChaPos(a5),a0 ;dflt - if takenorm + move.b (a0)+,d0 ;used in .empty etc + moveq #-8,d1 ;if sign, new P61_pack, retaddr-2 + and.b d0,d1 + jmp P61_MyJptB+256+4(PC,d1.w) ;first call can be this... +P61_takeoneB: + subq.b #1,P61_TempLen+1(a5) + move.l P61_TempPos(a5),a0 +P61_JediB: ;temp/repeat. copy below proccompS. + move.b (a0)+,d0 ;used in .empty etc + moveq #-8,d1 ;if sign, new P61_pack, retaddr-2 + and.b d0,d1 + jmp P61_MyJptB+256(PC,d1.w) ;but rest is always this +;; --- alt (perm) exit --- ;does not affect maxtime. +P61_permexitB: + move.b d0,(a5) + move.l a0,P61_ChaPos-3(a5) + bra.w P61_permdkoB + +********** Replay, Decrunch notes ********** +;This routine is optimized absolutely and gets the Henrik-stamp of approval. +;d3,a4,a6 are usable ... if you can find a use for them. + +P61_playtime: + addq.w #1,(a3) ;is wrong now, but never used below. + + ifne split4 + ifgt channels-3 + lea P61_temp3(PC),a5 + else + bra.w P61_playtimeCont + endc ;ifgt channels-3 + else ;not split4, splitchans. + moveq #splitchans-1,d5 ;channels split off?(optimization flag) + lea P61_temp0+Channel_Block_Size*(channels-splitchans)(PC),a5 + endc + + ifne P61_pde +P61_preplayB: + tst P61_pdflag-P61_cn(a3) + bne.w P61_return + else +P61_preplayB: + endc + +;; --- The hipper wilderbeest run gnu linux at midnight! --- + moveq #$3f,d4 + moveq #-$10,d6 ;intelligent on/off-flag + moveq #0,d0 ;clear hi word, never dirtied below. +;; --- decrunch loop --- +P61_loapsB: +;remember... code with BRAS in it is PANTS! +;As female coders know, they are often quite unnecessary. + ifne P61_pl ;make some backup copy of chanparams + lea P61_TData(a5),a1 + move 2(a5),(a1)+ + move.l P61_ChaPos(a5),(a1)+ + move.l P61_TempPos(a5),(a1)+ + move P61_TempLen(a5),(a1) + endc + + moveq #-65,d1 ;%10111111 const + and.b P61_Pack(a5),d1 + add.b d1,d1 ;sign in carry + beq.b P61_TakeB ;6 lsb bits 0? + bcc.b P61_nodkoB + addq #3,a5 + subq.b #1,(a5) + bra.w P61_permdkoB +P61_nodkoB: + move.b d7,P61_OnOff+1(a5) + subq.b #1,P61_Pack(a5) + addq #3,a5 + bra.w P61_kotoB +;; --- routines --- +P61_emptyB: + move d7,(a5)+ + move.b d7,(a5)+ + bra.w P61_exB +P61_allB: + move.b d0,(a5)+ ;but this can't... + ifeq opt020 + move.b (a0)+,(a5)+ + move.b (a0)+,(a5)+ + else + move (a0)+,(a5)+ + endc + bra.w P61_exB +P61_cmdB: + moveq #$f,d1 + and d0,d1 + move d1,(a5)+ + move.b (a0)+,(a5)+ ;join common endcontinues... + bra.w P61_exB +P61_nooteB: + moveq #7,d1 + and d0,d1 + lsl #8,d1 + move.b (a0)+,d1 + lsl #4,d1 + move d1,(a5)+ + move.b d7,(a5)+ + bra.w P61_exB +;; --- copyS --- +P61_emptySB: + move d7,(a5)+ + move.b d7,(a5)+ + bra.w P61_exSB +P61_allSB: + move.b d0,(a5)+ ;but this can't... + ifeq opt020 + move.b (a0)+,(a5)+ + move.b (a0)+,(a5)+ + else + move (a0)+,(a5)+ + endc + bra.b P61_exSB +P61_cmdSB: + moveq #$f,d1 + and d0,d1 + move d1,(a5)+ + move.b (a0)+,(a5)+ ;join common endcontinues... + bra.b P61_exSB +;; --- --- +********** copy, perm exit ********** +P61_empty2B: + move d7,(a5)+ + move.b d7,(a5)+ + move.l a0,P61_ChaPos-3(a5) + bra.b P61_permdkoB +P61_all2B: + move.b d0,(a5)+ + ifeq opt020 + move.b (a0)+,(a5)+ + move.b (a0)+,(a5)+ + else + move (a0)+,(a5)+ + endc + move.l a0,P61_ChaPos-3(a5) + bra.b P61_permdkoB +P61_cmd2B: + moveq #$f,d1 + and d0,d1 + move d1,(a5)+ + move.b (a0)+,(a5)+ + move.l a0,P61_ChaPos-3(a5) + bra.b P61_permdkoB +P61_note2B: + moveq #7,d1 + and d0,d1 + lsl #8,d1 + move.b (a0)+,d1 + lsl #4,d1 + move d1,(a5)+ + move.b d7,(a5)+ + move.l a0,P61_ChaPos-3(a5) + bra.b P61_permdkoB +;; --- copyS, diff exit --- +P61_note2SB: + moveq #7,d1 + and d0,d1 + lsl #8,d1 + move.b (a0)+,d1 + lsl #4,d1 + move d1,(a5)+ + move.b d7,(a5)+ + bra.w P61_proccompSB +P61_all2SB: + move.b d0,(a5)+ + ifeq opt020 + move.b (a0)+,(a5)+ + move.b (a0)+,(a5)+ + else + move (a0)+,(a5)+ + endc + bra.w P61_proccompSB +P61_cmd2SB: + moveq #$f,d1 + and d0,d1 + move d1,(a5)+ + move.b (a0)+,(a5)+ + bra.w P61_proccompSB +;; --- --- +P61_noteSB: + moveq #7,d1 + and d0,d1 + lsl #8,d1 + move.b (a0)+,d1 + lsl #4,d1 + move d1,(a5)+ + move.b d7,(a5)+ +;; --- norm (temp) exit --- +;This exit is called when you have max rastertime. +P61_exSB: + move.b (a0)+,(a5) +P61_exB: + move.l a0,P61_TempPos-3(a5) +P61_permdkoB: + move.w d6,P61_OnOff-3(a5) ;was byte size in word var... + move -3(a5),d0 + and #$1f0,d0 + beq.b .kotoB + lea (P61_samples-16)-P61_cn(a3),a1 + add d0,a1 + move.l a1,P61_Sample-3(a5) + ifne P61_ft + move.l P61_SampleVolume(a1),P61_Volume-3(a5) + else + move P61_SampleVolume(a1),P61_Volume-3(a5) + endc + ifne P61_il + move.l P61_RepeatOffset(a1),P61_Wave-3(a5) + endc + ifne P61_sof + move d7,P61_Offset-3(a5) + endc +.kotoB: +P61_kotoB: + ifeq split4 ;split4 means only do once. + lea Channel_Block_Size-3(a5),a5 + dbf d5,P61_loapsB + endc +;; --- end of dupedec --- + endc + endc +********** playtime continues ********** +P61_playtimeCont: + ifne P61_pde + tst P61_pdelay-P61_cn(a3) + beq.b .djdj + subq #1,P61_pdelay-P61_cn(a3) + bne.w P61_delay + tst P61_speedis1-P61_cn(a3) + bne.w P61_delay + move d7,P61_pdflag-P61_cn(a3) + bra.w P61_delay +.djdj: + move d7,P61_pdflag-P61_cn(a3) + endc + + ifne suppF01 + tst P61_speedis1-P61_cn(a3) + beq.b .mo + + lea P61_temp0(pc),a5 + moveq #channels-1,d5 +.chl: bsr.w P61_preplay ;then do the remaining from prev frame + ifeq split4 ;split4 means preplay is one-shot. So ext loop. + lea Channel_Block_Size-3(a5),a5 + dbf d5,.chl + endc + +.mo: + endc ;suppF01 + + ifeq copdma&nowaveforms ;both must be off to skip int. + ifeq p61system ;main 'new note' int starter. + lea P61_dmason(pc),a1 + move.l P61_vektori(pc),a0 + move.l a1,(a0) + move.b #$f0,$bfd600 ;496 ticks=11.000677 scanlines, + move.b #$01,$bfd700 ;dmaoff $1.38 scanlines later on 68000. + move.b #$19,$bfdf00 ;With unlucky timing and max period 856 + ;minimum="$1.38->2"+7+1=10 scanlines. +;With nonlev6 (copdma), "9 scanlines from call" is possible, but only with a +;margin of 51 color clocks. If chansplit/split4 is used, you must add 2 +;scanlines decrunch time before dmaclr occurs. So 11 is good. + else + move #1,P61_server-P61_cn(a3) + move.l P61_craddr+4(pc),a1 + move.b #$f0,(a1) + move.b #1,$100(a1) + endc + endc + + moveq #0,d4 ;clr dmamask accumulator + moveq #channels-1,d5 + lea P61_temp0(pc),a5 + bra.w P61_loscont ;I'd trade a bra for 2 Leias any day! +;; --- start of jtab (jumptable) --- + ifne p61bigjtab + rept 16*15 + dc.w P61_nocha-.j + endr + endc + + dc P61_fxdone-.j ;$0xx + + ifne use1Fx + dc P61_Trigger-.j + else + dc P61_fxdone-.j + endc + + dc P61_fxdone-.j + + ifne P61_tp + dc P61_settoneport-.j + else + dc P61_fxdone-.j + endc + + ifne P61_vib ;$4xx + dc P61_vibrato-.j + else + dc P61_fxdone-.j + endc + + ifne P61_tpvs + dc P61_toponochange-.j + else + dc P61_fxdone-.j + endc + + dc P61_fxdone-.j + + ifne P61_tre + dc P61_settremo-.j + else + dc P61_fxdone-.j + endc + + dc P61_fxdone-.j ;$8xx + + ifne P61_sof + dc P61_sampleoffse-.j + else + dc P61_fxdone-.j + endc + + dc P61_fxdone-.j + + ifne P61_pj + dc P61_posjmp-.j + else + dc P61_fxdone-.j + endc + + ifne P61_vl ;$Cxx + dc P61_volum-.j + else + dc P61_fxdone-.j + endc + + ifne P61_pb + dc P61_pattbreak-.j + else + dc P61_fxdone-.j + endc + + ifne P61_ec + dc P61_ecommands-.j + else + dc P61_fxdone-.j + endc + + ifne P61_sd ;Fxx + dc P61_cspeed-.j + else + dc P61_fxdone-.j + endc +.j: +P61_jtab: +;; --- end of table --- +P61_los: + lea Custom_Block_Size(a4),a4 + lea Channel_Block_Size(a5),a5 +P61_loscont: + move P61_OnOff(a5),d0 ;$ff00/$ffff? if off, will goto nocha. + ifeq p61bigjtab + tst.b d0 + beq.s P61_nocha + endc + or (a5),d0 + add d0,d0 ;->$fe00..$fffe (if big jtab) + move P61_jtab(PC,d0),d0 + jmp P61_jtab(PC,d0) + +P61_fxdone: ;this sets dma and paula values + moveq #$7e,d0 + and.b (a5),d0 + beq.b P61_nocha + ifne P61_vib + move.b d7,P61_VibPos(a5) + endc + ifne P61_tre + move.b d7,P61_TrePos(a5) + endc + ifne P61_ft + add P61_Fine(a5),d0 + endc + move d0,P61_Note(a5) + move P61_periods-P61_cn(a3,d0),P61_Period(a5) +P61_zample: ;also direct target for finetune retrig + ifne P61_sof + tst P61_Offset(a5) + bne.w P61_pek + endc +;; --- check DMA-mask for pan/echo samplestarts, modify it, mix. --- +; bsr P61_Synth ;synth/pan/echo cpu-mix routine. Not done yet. +;; --- modify below code to not touch synth/pan/echo fixchans --- + or P61_DMABit(a5),d4 ;accumulate channels touched + move.l P61_Sample(a5),a1 ;skipped if nocha + ifeq oscillo + move.l (a1)+,(a4) + move (a1),4(a4) + else +;; --- wohoo oscilloscope ptrs --- + moveq #0,d1 + move.l (a1)+,d0 + move (a1),d1 + move.l d0,(a4) + move.w d1,4(a4) + subq.w #1,d1 + addq.l #1,d1 ;128KB support for sample endptr + lsl.l #2,d0 ;clear remainder. + move.l d0,P61_oscptr(a5) + move.w d7,P61_oscptrrem(a5) ;clear remainder. + lsl.l #3,d1 + add.l d0,d1 + move.l d1,P61_oscptrWrap(a5) ;wrap endptr for compare. + endc ;oscillo +P61_nocha: + ifeq p61fade + move.l P61_Period(a5),6(a4) + else + move P61_Period(a5),6(a4) + move P61_Volume(a5),P61_Shadow(a5) + endc +P61_skip: + ifne P61_il + bsr.w P61_funk2 + endc + DBF d5,P61_los + +P61_chansdone: + ifne clraudxdat + move.w d4,d5 + lsl.w #3,d5 + add.b d5,d5 + bpl.b .noch3 + move.w d7,$da-C(A6) ;clear AUDxDAT +.noch3: add.b d5,d5 + bpl.b .noch2 + move.w d7,$ca-C(A6) ;clear AUDxDAT +.noch2: add.b d5,d5 + bpl.b .noch1 + move.w d7,$ba-C(A6) ;clear AUDxDAT +.noch1: add.b d5,d5 + bpl.b .noch0 + move.w d7,$aa-C(A6) ;clear AUDxDAT +.noch0: + endc + + move d4,$96-C(a6) ;DMAclear - changed to not be written 4 times + + ifne visuctrs + lea P61_visuctr0+channels*2(PC),a0 + moveq #channels-1,d5 +.visul: subq.w #2,a0 + btst d5,d4 + beq.s .noctr0 + move.w d7,(a0) +.noctr0: + dbf d5,.visul + endc + + ifne copdma + move.l p61_DMApokeAddr(PC),a0 + move.b d4,(a0) ;only the low byte is poked, allowing other dma + endc + move.b d4,P61_dma+1-P61_cn(a3) + +;; --- non-rolled over code --- compatible with F01. + ifne suppF01 ;moved to here in P6110. + ifne nowaveforms + move.b d4,P61_NewDMA+1-P61_cn(a3) ;or set by fx + endc + move.w d7,(a3) ;clr p61_cn + + ifne P61_pl + tst.b P61_plflag+1-P61_cn(a3) + beq.b P61_ohittaa + + lea P61_temp0(pc),a1 + lea P61_looppos(pc),a0 + moveq #channels-1,d0 +.talt: + move.b 1(a0),3(a1) + addq.l #2,a0 + move.l (a0)+,P61_ChaPos(a1) + move.l (a0)+,P61_TempPos(a1) + move (a0)+,P61_TempLen(a1) + lea Channel_Block_Size(a1),a1 + dbf d0,.talt + move P61_plrowpos(pc),P61_rowpos-P61_cn(a3) + move.b d7,P61_plflag+1-P61_cn(a3) + moveq #63,d0 + sub P61_rowpos-P61_cn(a3),d0 + move d0,P61_CRow-P61_cn(a3) + rts +P61_ohittaa: ;nextrow + endc + + subq #1,P61_rowpos-P61_cn(a3) ;next pattern-step + bpl.b P61_nonewpatt + +P61_nextpattern: + ifne P61_pl + move d7,P61_plflag-P61_cn(a3) + endc + move.l P61_patternbase(pc),a0 + moveq #63,d0 + move d0,P61_rowpos-P61_cn(a3) + move d7,P61_CRow-P61_cn(a3) + move.l P61_spos(pc),a1 + addq #1,P61_Pos-P61_cn(a3) + move.b (a1)+,d0 + bpl.b P61_dk + move.l P61_possibase(pc),a1 + move.b (a1)+,d0 + move d7,P61_Pos-P61_cn(a3) +P61_dk: + move.l a1,P61_spos-P61_cn(a3) + move d0,P61_Patt-P61_cn(a3) + lsl #3,d0 + move.l P61_positionbase(pc),a1 + add.l d0,a1 + move.w (a1)+,d0 ;no movem sign-extend... check. + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp0-P61_cn(a3) + moveq #0,d0 ;actually faster than lea (a0,d0.l) + move.w (a1)+,d0 ;for some reason this code doesn't + add.l a0,d0 ;use 'ifgt channels-1' etc. Kept as is. + move.l d0,P61_ChaPos+P61_temp1-P61_cn(a3) + moveq #0,d0 + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp2-P61_cn(a3) + moveq #0,d0 + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp3-P61_cn(a3) + rts +P61_nonewpatt: + moveq #63,d0 + sub P61_rowpos-P61_cn(a3),d0 + move d0,P61_CRow-P61_cn(a3) +;; --- end of non-rolled over code --- + endc ;suppF01 + rts ;end of P61_playtime. + +********** FX routines ********** + ifne use1Fx +P61_Trigger: + move.b P61_Info(a5),d0 + cmp.b #$f0,d0 + blo.w P61_fxdone + move.b d0,P61_PTrig+1-P61_cn(a3) + bra.w P61_fxdone + endc + + ifne P61_tp +P61_settoneport: + move.b P61_Info(a5),d0 + beq.b P61_toponochange + move.b d0,P61_TPSpeed+1(a5) +P61_toponochange: + moveq #$7e,d0 + and.b (a5),d0 + beq.w P61_nocha + add P61_Fine(a5),d0 + move d0,P61_Note(a5) + move P61_periods-P61_cn(a3,d0),P61_ToPeriod(a5) + bra.w P61_nocha + endc + + ifne P61_sof +P61_sampleoffse: + moveq #0,d1 + move #$ff00,d1 + and 2(a5),d1 + bne.b .deq + move P61_LOffset(a5),d1 +.deq: + move d1,P61_LOffset(a5) + add d1,P61_Offset(a5) + + moveq #$7e,d0 + and.b (a5),d0 + beq.w P61_nocha + move P61_Offset(a5),d2 + add d1,P61_Offset(a5) + move d2,d1 + ifne P61_vib + move.b d7,P61_VibPos(a5) + endc + ifne P61_tre + move.b d7,P61_TrePos(a5) + endc + ifne P61_ft + add P61_Fine(a5),d0 + endc + move d0,P61_Note(a5) + move P61_periods-P61_cn(a3,d0),P61_Period(a5) + bra.b P61_hup +P61_pek: + moveq #0,d1 + move P61_Offset(a5),d1 +P61_hup: + or P61_DMABit(a5),d4 ;don't write 4 times, please. + + move.l P61_Sample(a5),a1 + move.l (a1)+,d0 + add.l d1,d0 + move.l d0,(a4) + lsr #1,d1 + move (a1),d6 + sub d1,d6 + bpl.b P61_offok + move.l -4(a1),(a4) + moveq #1,d6 +P61_offok: + move d6,4(a4) + + ifne oscillo +;; --- wohoo oscilloscope ptrs --- + moveq #0,d1 + move.w d6,d1 + subq.w #1,d1 + addq.l #1,d1 ;128KB support for sample endptr + lsl.l #2,d0 ;clear remainder. + move.l d0,P61_oscptr(a5) + move.w d7,P61_oscptrrem(a5) ;clear remainder. + lsl.l #3,d1 + add.l d0,d1 + move.l d1,P61_oscptrWrap(a5) ;wrap endptr for compare. + endc ;oscillo + + bra.w P61_nocha ;continues to where ints etc is handled + endc + + ifne P61_vl +P61_volum: + move.b P61_Info(a5),P61_Volume+1(a5) + bra.w P61_fxdone + endc + + ifne P61_pj +P61_posjmp: + moveq #0,d0 + move.b P61_Info(a5),d0 + ifeq optjmp + cmp P61_slen-P61_cn(a3),d0 + blo.b .e + moveq #0,d0 + endc +.e: move d0,P61_Pos-P61_cn(a3) + add.l P61_possibase(pc),d0 + move.l d0,P61_spos-P61_cn(a3) + endc + ifne P61_pb +P61_pattbreak: ;needs to be execd if posjmp, and P61_pj>0. + moveq #64,d0 + move d0,P61_rowpos-P61_cn(a3) + move d7,P61_CRow-P61_cn(a3) +P61_Bc: move.l P61_spos(pc),a1 + move.l P61_patternbase(pc),a0 + addq #1,P61_Pos-P61_cn(a3) + move.b (a1)+,d0 + bpl.b P61_dk2 + move.l P61_possibase(pc),a1 + move.b (a1)+,d0 + move d7,P61_Pos-P61_cn(a3) +P61_dk2: + move.l a1,P61_spos-P61_cn(a3) + move.l P61_positionbase(pc),a1 + move d0,P61_Patt-P61_cn(a3) + lsl #3,d0 + add.l d0,a1 + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp0-P61_cn(a3) + moveq #0,d0 ;actually faster than lea (a0,d0.l) + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp1-P61_cn(a3) + moveq #0,d0 ;actually faster than lea (a0,d0.l) + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp2-P61_cn(a3) + moveq #0,d0 ;actually faster than lea (a0,d0.l) + move.w (a1)+,d0 + add.l a0,d0 + move.l d0,P61_ChaPos+P61_temp3-P61_cn(a3) + bra.w P61_fxdone + endc + + ifne P61_vib +P61_vibrato: + move.b P61_Info(a5),d0 + beq.w P61_fxdone + move.b d0,d1 + move.b P61_VibCmd(a5),d2 + and.b #$f,d0 + beq.b P61_vibskip + and.b #$f0,d2 + or.b d0,d2 +P61_vibskip: + and.b #$f0,d1 + beq.b P61_vibskip2 + and.b #$f,d2 + or.b d1,d2 +P61_vibskip2: + move.b d2,P61_VibCmd(a5) + bra.w P61_fxdone + endc + ifne P61_tre +P61_settremo: + move.b P61_Info(a5),d0 + beq.w P61_fxdone + move.b d0,d1 + move.b P61_TreCmd(a5),d2 + moveq #$f,d3 + and.b d3,d0 + beq.b P61_treskip + and.b #$f0,d2 + or.b d0,d2 +P61_treskip: + and.b #$f0,d1 + beq.b P61_treskip2 + and.b d3,d2 + or.b d1,d2 +P61_treskip2: + move.b d2,P61_TreCmd(a5) + bra.w P61_fxdone + endc + ifne P61_ec +P61_ecommands: + move.b P61_Info(a5),d0 + and.w #$f0,d0 + lsr #3,d0 + move P61_etab(pc,d0),d0 + jmp P61_etab(pc,d0) +P61_etab: + ifne P61_fi + dc P61_filter-P61_etab + else + dc P61_fxdone-P61_etab + endc + + ifne P61_fsu + dc P61_fineup-P61_etab + else + dc P61_fxdone-P61_etab + endc + + ifne P61_fsd + dc P61_finedwn-P61_etab + else + dc P61_fxdone-P61_etab + endc + + dc P61_fxdone-P61_etab ;e3 + + dc P61_fxdone-P61_etab ;e4 + + ifne P61_sft ;e5 + dc P61_setfinetune-P61_etab + else + dc P61_fxdone-P61_etab + endc + + ifne P61_pl ;e6,patternloop + dc P61_patternloop-P61_etab + else + dc P61_fxdone-P61_etab + endc + + dc P61_fxdone-P61_etab ;e7 + + ifne P61_timing + dc P61_sete8-P61_etab + else + dc P61_fxdone-P61_etab + endc + + ifne P61_rt + dc P61_setretrig-P61_etab + else + dc P61_fxdone-P61_etab + endc + ifne P61_fvu + dc P61_finevup-P61_etab + else + dc P61_fxdone-P61_etab + endc + ifne P61_fvd + dc P61_finevdwn-P61_etab + else + dc P61_fxdone-P61_etab + endc + dc P61_fxdone-P61_etab + ifne P61_nd + dc P61_ndelay-P61_etab + else + dc P61_fxdone-P61_etab + endc + ifne P61_pde + dc P61_pattdelay-P61_etab + else + dc P61_fxdone-P61_etab + endc + ifne P61_il + dc P61_funk-P61_etab + else + dc P61_fxdone-P61_etab + endc + endc + ifne P61_fi +P61_filter: + move.b P61_Info(a5),d0 + and.b #$fd,$bfe001 + or.b d0,$bfe001 + bra.w P61_fxdone + endc + ifne P61_fsu +P61_fineup: + P61_getnote + moveq #$f,d0 + and.b P61_Info(a5),d0 + sub d0,P61_Period(a5) + moveq #113,d0 + cmp P61_Period(a5),d0 + ble.b .jup + move d0,P61_Period(a5) +.jup: + moveq #$7e,d0 + and.b (a5),d0 + bne.w P61_zample + bra.w P61_nocha + endc + ifne P61_fsd +P61_finedwn: + P61_getnote + moveq #$f,d0 + and.b P61_Info(a5),d0 + add d0,P61_Period(a5) + cmp #856,P61_Period(a5) + ble.b .jup + move #856,P61_Period(a5) +.jup: moveq #$7e,d0 + and.b (a5),d0 + bne.w P61_zample + bra.w P61_nocha + endc + ifne P61_sft +P61_setfinetune: + moveq #$f,d0 + and.b P61_Info(a5),d0 + ifeq opt020 + add d0,d0 + move P61_mulutab(pc,d0),P61_Fine(a5) + else + move P61_mulutab(pc,d0*2),P61_Fine(a5) + endc + bra.w P61_fxdone +P61_mulutab: + dc 0,74,148,222,296,370,444,518,592,666,740,814,888,962,1036,1110 + endc +;; --- E6x start --- + ifne P61_pl +P61_patternloop: + moveq #$f,d0 + and.b P61_Info(a5),d0 ;E6x, x=0? + beq.b P61_setloop ;then set loop start point ONLY + + tst.b P61_plflag-P61_cn(a3) ;not first encounter? + bne.b P61_noset ;then don't set start count + + move d0,P61_plcount-P61_cn(a3) ;set start count + st.b P61_plflag-P61_cn(a3) ;and flag +P61_noset: + tst P61_plcount-P61_cn(a3) ;loop count expired? + bne.b P61_looppaa + move.b d7,P61_plflag-P61_cn(a3) ;then clear flag and done + bra.w P61_fxdone +P61_looppaa: + st.b P61_plflag+1-P61_cn(a3) ;else special-flag jump later + subq #1,P61_plcount-P61_cn(a3) ;and dec loop count + bra.w P61_fxdone + +P61_setloop: + tst.b P61_plflag-P61_cn(a3) ;flag already set? + bne.w P61_fxdone ;then do nothing + move P61_rowpos(pc),P61_plrowpos-P61_cn(a3) ;else set pos + lea P61_temp0+P61_TData(pc),a1 ;& prep chans + lea P61_looppos(pc),a0 + moveq #channels-1,d0 +.talt: + move.l (a1)+,(a0)+ + move.l (a1)+,(a0)+ + move.l (a1),(a0)+ + lea Channel_Block_Size-8(a1),a1 + dbf d0,.talt + bra.w P61_fxdone ;and done. + endc +;; --- E6x end --- + ifne P61_fvu +P61_finevup: + moveq #$f,d0 + and.b P61_Info(a5),d0 + add d0,P61_Volume(a5) + moveq #64,d0 + cmp P61_Volume(a5),d0 + bge.w P61_fxdone + move d0,P61_Volume(a5) + bra.w P61_fxdone + endc + ifne P61_fvd +P61_finevdwn: + moveq #$f,d0 + and.b P61_Info(a5),d0 + sub d0,P61_Volume(a5) + bpl.w P61_fxdone + move d7,P61_Volume(a5) + bra.w P61_fxdone + endc + ifne P61_timing +P61_sete8: + moveq #$f,d0 + and.b P61_Info(a5),d0 + move d0,P61_E8-P61_cn(a3) + bra.w P61_fxdone + endc + ifne P61_rt +P61_setretrig: + moveq #$f,d0 + and.b P61_Info(a5),d0 + move d0,P61_RetrigCount(a5) + bra.w P61_fxdone + endc + ifne P61_nd +P61_ndelay: + moveq #$7e,d0 + and.b (a5),d0 + beq.w P61_skip + ifne P61_vib + move.b d7,P61_VibPos(a5) + endc + ifne P61_tre + move.b d7,P61_TrePos(a5) + endc + ifne P61_ft + add P61_Fine(a5),d0 + endc + move d0,P61_Note(a5) + move P61_periods-P61_cn(a3,d0),P61_Period(a5) + ifeq p61fade + move P61_Volume(a5),8(a4) + else + move P61_Volume(a5),P61_Shadow(a5) + endc + bra.w P61_skip + endc + ifne P61_pde +P61_pattdelay: + moveq #$f,d0 + and.b P61_Info(a5),d0 + move d0,P61_pdelay-P61_cn(a3) + st P61_pdflag-P61_cn(a3) + bra.w P61_fxdone + endc + ifne P61_sd +P61_cspeed: + moveq #0,d0 + move.b P61_Info(a5),d0 + ifne p61cia + tst P61_Tempo-P61_cn(a3) + beq.b P61_VBlank + cmp.b #32,d0 + bhs.b P61_STempo + endc +P61_VBlank: + cmp.b #1,d0 + beq.b P61_jkd + move.b d0,P61_speed+1-P61_cn(a3) + subq.b #1,d0 + move.b d0,P61_speed2+1-P61_cn(a3) + move d7,P61_speedis1-P61_cn(a3) + bra.w P61_fxdone +P61_jkd: + move.b d0,P61_speed+1-P61_cn(a3) + move.b d0,P61_speed2+1-P61_cn(a3) + st P61_speedis1-P61_cn(a3) + bra.w P61_fxdone + ifne p61cia +P61_STempo: + move.l P61_timer(pc),d1 + divu d0,d1 + move d1,P61_thi2-P61_cn(a3) + sub #$1f0*2,d1 + move d1,P61_thi-P61_cn(a3) + ifeq p61system + move P61_thi2-P61_cn(a3),d1 + move.b d1,$bfd400 + lsr #8,d1 + move.b d1,$bfd500 + endc + bra P61_fxdone + endc + endc + ifne P61_vbvs +P61_vibochvslide: + move.b P61_Info(a5),d0 + sub.b d0,P61_Volume+1(a5) + bpl.b P61_test62 + move d7,P61_Volume(a5) + ifeq p61fade + move d7,8(a4) + else + move d7,P61_Shadow(a5) + endc + bra.b P61_vib2 +P61_test62: + moveq #64,d0 + cmp P61_Volume(a5),d0 + bge.b .ncs2 + move d0,P61_Volume(a5) +.ncs2: + ifeq p61fade + move P61_Volume(a5),8(a4) + else + move P61_Volume(a5),P61_Shadow(a5) + endc + endc + ifne P61_vib +P61_vib2: + move #$f00,d0 + move P61_VibCmd(a5),d1 + and d1,d0 + lsr #3,d0 + lsr #2,d1 + and #$1f,d1 + add d1,d0 + move P61_Period(a5),d1 + moveq #0,d2 + move.b P61_vibtab(pc,d0),d2 + tst.b P61_VibPos(a5) + bmi.b .vibneg + add d2,d1 + bra.b P61_vib4 +.vibneg:sub d2,d1 +P61_vib4: + move d1,6(a4) + move.b P61_VibCmd(a5),d0 + lsr.b #2,d0 + and #$3c,d0 + add.b d0,P61_VibPos(a5) + bra.w P61_contfxdone + endc + ifne P61_tre +P61_tremo: + move #$f00,d0 + move P61_TreCmd(a5),d1 + and d1,d0 + lsr #3,d0 + lsr #2,d1 + and #$1f,d1 + add d1,d0 + move P61_Volume(a5),d1 + moveq #0,d2 + move.b P61_vibtab(pc,d0),d2 + tst.b P61_TrePos(a5) + bmi.b .treneg + add d2,d1 + cmp #64,d1 + ble.b P61_tre4 + moveq #64,d1 + bra.b P61_tre4 +.treneg: + sub d2,d1 + bpl.b P61_tre4 + moveq #0,d1 +P61_tre4: + ifeq p61fade + move d1,8(a4) + else + move d1,P61_Shadow(a5) + endc + move.b P61_TreCmd(a5),d0 + lsr.b #2,d0 + and #$3c,d0 + add.b d0,P61_TrePos(a5) + bra.w P61_contfxdone + endc + ifne (P61_vib+P61_tre) +P61_vibtab: +; incbin "vibtab" + dc.b $00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$00,$00,$00,$01,$01 + dc.b $01,$01,$01,$01,$01,$01,$01,$01 + dc.b $01,$01,$01,$01,$01,$01,$01,$01 + dc.b $01,$01,$01,$00,$00,$00,$00,$00 + dc.b $00,$00,$00,$01,$01,$01,$02,$02 + dc.b $02,$03,$03,$03,$03,$03,$03,$03 + dc.b $03,$03,$03,$03,$03,$03,$03,$03 + dc.b $02,$02,$02,$01,$01,$01,$00,$00 + dc.b $00,$00,$01,$01,$02,$02,$03,$03 + dc.b $04,$04,$04,$05,$05,$05,$05,$05 + dc.b $05,$05,$05,$05,$05,$05,$04,$04 + dc.b $04,$03,$03,$02,$02,$01,$01,$00 + dc.b $00,$00,$01,$02,$03,$03,$04,$05 + dc.b $05,$06,$06,$07,$07,$07,$07,$07 + dc.b $07,$07,$07,$07,$07,$07,$06,$06 + dc.b $05,$05,$04,$03,$03,$02,$01,$00 + dc.b $00,$00,$01,$02,$03,$04,$05,$06 + dc.b $07,$07,$08,$08,$09,$09,$09,$09 + dc.b $09,$09,$09,$09,$09,$08,$08,$07 + dc.b $07,$06,$05,$04,$03,$02,$01,$00 + dc.b $00,$01,$02,$03,$04,$05,$06,$07 + dc.b $08,$09,$09,$0a,$0b,$0b,$0b,$0b + dc.b $0b,$0b,$0b,$0b,$0b,$0a,$09,$09 + dc.b $08,$07,$06,$05,$04,$03,$02,$01 + dc.b $00,$01,$02,$04,$05,$06,$07,$08 + dc.b $09,$0a,$0b,$0c,$0c,$0d,$0d,$0d + dc.b $0d,$0d,$0d,$0d,$0c,$0c,$0b,$0a + dc.b $09,$08,$07,$06,$05,$04,$02,$01 + dc.b $00,$01,$03,$04,$06,$07,$08,$0a + dc.b $0b,$0c,$0d,$0e,$0e,$0f,$0f,$0f + dc.b $0f,$0f,$0f,$0f,$0e,$0e,$0d,$0c + dc.b $0b,$0a,$08,$07,$06,$04,$03,$01 + dc.b $00,$01,$03,$05,$06,$08,$09,$0b + dc.b $0c,$0d,$0e,$0f,$10,$11,$11,$11 + dc.b $11,$11,$11,$11,$10,$0f,$0e,$0d + dc.b $0c,$0b,$09,$08,$06,$05,$03,$01 + dc.b $00,$01,$03,$05,$07,$09,$0b,$0c + dc.b $0e,$0f,$10,$11,$12,$13,$13,$13 + dc.b $13,$13,$13,$13,$12,$11,$10,$0f + dc.b $0e,$0c,$0b,$09,$07,$05,$03,$01 + dc.b $00,$02,$04,$06,$08,$0a,$0c,$0d + dc.b $0f,$10,$12,$13,$14,$14,$15,$15 + dc.b $15,$15,$15,$14,$14,$13,$12,$10 + dc.b $0f,$0d,$0c,$0a,$08,$06,$04,$02 + dc.b $00,$02,$04,$06,$09,$0b,$0d,$0f + dc.b $10,$12,$13,$15,$16,$16,$17,$17 + dc.b $17,$17,$17,$16,$16,$15,$13,$12 + dc.b $10,$0f,$0d,$0b,$09,$06,$04,$02 + dc.b $00,$02,$04,$07,$09,$0c,$0e,$10 + dc.b $12,$14,$15,$16,$17,$18,$19,$19 + dc.b $19,$19,$19,$18,$17,$16,$15,$14 + dc.b $12,$10,$0e,$0c,$09,$07,$04,$02 + dc.b $00,$02,$05,$08,$0a,$0d,$0f,$11 + dc.b $13,$15,$17,$18,$19,$1a,$1b,$1b + dc.b $1b,$1b,$1b,$1a,$19,$18,$17,$15 + dc.b $13,$11,$0f,$0d,$0a,$08,$05,$02 + dc.b $00,$02,$05,$08,$0b,$0e,$10,$12 + dc.b $15,$17,$18,$1a,$1b,$1c,$1d,$1d + dc.b $1d,$1d,$1d,$1c,$1b,$1a,$18,$17 + dc.b $15,$12,$10,$0e,$0b,$08,$05,$02 + + endc + ifne P61_il +P61_funk: + moveq #$f,d0 + and.b P61_Info(a5),d0 + move.b d0,P61_Funkspd(a5) + bra.w P61_fxdone +P61_funk2: + moveq #0,d0 + move.b P61_Funkspd(a5),d0 + beq.b P61_funkend + move.b P61_FunkTable(pc,d0),d0 + add.b d0,P61_Funkoff(a5) + bpl.b P61_funkend + move.b d7,P61_Funkoff(a5) + + move.l P61_Sample(a5),a1 + move.l P61_RepeatOffset(a1),d1 + move P61_RepeatLength(a1),d0 + add.l d0,d0 + add.l d1,d0 + move.l P61_Wave(a5),a0 + addq.l #1,a0 + cmp.l d0,a0 + blo.b P61_funkok + move.l d1,a0 +P61_funkok: + move.l a0,P61_Wave(a5) + not.b (a0) +P61_funkend: + rts +P61_FunkTable: + dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128 + endc +********** rest is NOT part of P61_music ********** +********** timing interrupt entry point ********** +;; --- first int, DMAs on again. --- + ifeq copdma +P61_dmason: + ifeq p61system + tst.b $bfdd00 + move #$2000,$dff09c + move #$2000,$dff09c + + ifeq nowaveforms + move.b #$19,$bfdf00 ;retrigger to chain replen int. + move.l a0,-(sp) + move.l P61_vektori(pc),a0 ;put another int in '$78.w' + move.l P61_intaddr(pc),(a0) + move.l (sp)+,a0 + endc + + move P61_dma(pc),$dff096 ;on only. includes $8200. + nop + rte + else + move P61_dma(pc),$dff096 ;on only. includes $8200. + lea P61_server(pc),a3 + addq #1,(a3) + move.l P61_craddr(pc),a0 + move.b #$19,(a0) + bra P61_ohi + endc + endc ;ifeq copdma +;; --- second chained int, replen --- + ifeq nowaveforms +P61_setrepeat: + ifeq p61system + tst.b $bfdd00 + movem.l a0/a1,-(sp) + lea $dff0a0,a1 + move #$2000,-4(a1) + move #$2000,-4(a1) + else + lea $dff0a0,a1 + endc + + move.l P61_Sample+P61_temp0(pc),a0 + addq.l #6,a0 + move.l (a0)+,(a1)+ + move (a0),(a1) + ifgt channels-1 + move.l P61_Sample+P61_temp1(pc),a0 + addq.l #6,a0 + move.l (a0)+,12(a1) + move (a0),16(a1) + endc + ifgt channels-2 + move.l P61_Sample+P61_temp2(pc),a0 + addq.l #6,a0 + move.l (a0)+,28(a1) + move (a0),32(a1) + endc + ifgt channels-3 + move.l P61_Sample+P61_temp3(pc),a0 + addq.l #6,a0 + move.l (a0)+,44(a1) + move (a0),48(a1) + endc + + ifne p61system + ifne p61cia + lea P61_server(pc),a3 + clr (a3) + move.l P61_craddr+4(pc),a0 + move.b P61_tlo(pc),(a0) + move.b P61_thi(pc),$100(a0) + endc + bra P61_ohi + endc + ifeq p61system + ifne p61cia + move.l P61_vektori(pc),a0 + move.l P61_tintti(pc),(a0) + endc + movem.l (sp)+,a0/a1 + nop + rte + endc + endc ;ifeq nowaveforms + +P61_temp0: + dcb.b Channel_Block_Size-2,0 + dc 1 +P61_temp1: + dcb.b Channel_Block_Size-2,0 + dc 2 +P61_temp2: + dcb.b Channel_Block_Size-2,0 + dc 4 +P61_temp3: + dcb.b Channel_Block_Size-2,0 + dc 8 + ifne split4 +P61_temp0copy: dcb.b P61_Wave+4,0 ;temp storage for split4. +P61_temp1copy: dcb.b P61_Wave+4,0 + endc +P61_cn: + dc 0 +P61_periods: + ifne P61_ft +; incbin "A:INC/SND/periods" + dc.w $0358,$0358,$0328,$02fa,$02d0,$02a6,$0280,$025c + dc.w $023a,$021a,$01fc,$01e0,$01c5,$01ac,$0194,$017d + dc.w $0168,$0153,$0140,$012e,$011d,$010d,$00fe,$00f0 + dc.w $00e2,$00d6,$00ca,$00be,$00b4,$00aa,$00a0,$0097 + dc.w $008f,$0087,$007f,$0078,$0071,$0352,$0352,$0322 + dc.w $02f5,$02cb,$02a2,$027d,$0259,$0237,$0217,$01f9 + dc.w $01dd,$01c2,$01a9,$0191,$017b,$0165,$0151,$013e + dc.w $012c,$011c,$010c,$00fd,$00ef,$00e1,$00d5,$00c9 + dc.w $00bd,$00b3,$00a9,$009f,$0096,$008e,$0086,$007e + dc.w $0077,$0071,$034c,$034c,$031c,$02f0,$02c5,$029e + dc.w $0278,$0255,$0233,$0214,$01f6,$01da,$01bf,$01a6 + dc.w $018e,$0178,$0163,$014f,$013c,$012a,$011a,$010a + dc.w $00fb,$00ed,$00e0,$00d3,$00c7,$00bc,$00b1,$00a7 + dc.w $009e,$0095,$008d,$0085,$007d,$0076,$0070,$0346 + dc.w $0346,$0317,$02ea,$02c0,$0299,$0274,$0250,$022f + dc.w $0210,$01f2,$01d6,$01bc,$01a3,$018b,$0175,$0160 + dc.w $014c,$013a,$0128,$0118,$0108,$00f9,$00eb,$00de + dc.w $00d1,$00c6,$00bb,$00b0,$00a6,$009d,$0094,$008c + dc.w $0084,$007d,$0076,$006f,$0340,$0340,$0311,$02e5 + dc.w $02bb,$0294,$026f,$024c,$022b,$020c,$01ef,$01d3 + dc.w $01b9,$01a0,$0188,$0172,$015e,$014a,$0138,$0126 + dc.w $0116,$0106,$00f7,$00e9,$00dc,$00d0,$00c4,$00b9 + dc.w $00af,$00a5,$009c,$0093,$008b,$0083,$007c,$0075 + dc.w $006e,$033a,$033a,$030b,$02e0,$02b6,$028f,$026b + dc.w $0248,$0227,$0208,$01eb,$01cf,$01b5,$019d,$0186 + dc.w $0170,$015b,$0148,$0135,$0124,$0114,$0104,$00f5 + dc.w $00e8,$00db,$00ce,$00c3,$00b8,$00ae,$00a4,$009b + dc.w $0092,$008a,$0082,$007b,$0074,$006d,$0334,$0334 + dc.w $0306,$02da,$02b1,$028b,$0266,$0244,$0223,$0204 + dc.w $01e7,$01cc,$01b2,$019a,$0183,$016d,$0159,$0145 + dc.w $0133,$0122,$0112,$0102,$00f4,$00e6,$00d9,$00cd + dc.w $00c1,$00b7,$00ac,$00a3,$009a,$0091,$0089,$0081 + dc.w $007a,$0073,$006d,$032e,$032e,$0300,$02d5,$02ac + dc.w $0286,$0262,$023f,$021f,$0201,$01e4,$01c9,$01af + dc.w $0197,$0180,$016b,$0156,$0143,$0131,$0120,$0110 + dc.w $0100,$00f2,$00e4,$00d8,$00cc,$00c0,$00b5,$00ab + dc.w $00a1,$0098,$0090,$0088,$0080,$0079,$0072,$006c + dc.w $038b,$038b,$0358,$0328,$02fa,$02d0,$02a6,$0280 + dc.w $025c,$023a,$021a,$01fc,$01e0,$01c5,$01ac,$0194 + dc.w $017d,$0168,$0153,$0140,$012e,$011d,$010d,$00fe + dc.w $00f0,$00e2,$00d6,$00ca,$00be,$00b4,$00aa,$00a0 + dc.w $0097,$008f,$0087,$007f,$0078,$0384,$0384,$0352 + dc.w $0322,$02f5,$02cb,$02a3,$027c,$0259,$0237,$0217 + dc.w $01f9,$01dd,$01c2,$01a9,$0191,$017b,$0165,$0151 + dc.w $013e,$012c,$011c,$010c,$00fd,$00ee,$00e1,$00d4 + dc.w $00c8,$00bd,$00b3,$00a9,$009f,$0096,$008e,$0086 + dc.w $007e,$0077,$037e,$037e,$034c,$031c,$02f0,$02c5 + dc.w $029e,$0278,$0255,$0233,$0214,$01f6,$01da,$01bf + dc.w $01a6,$018e,$0178,$0163,$014f,$013c,$012a,$011a + dc.w $010a,$00fb,$00ed,$00df,$00d3,$00c7,$00bc,$00b1 + dc.w $00a7,$009e,$0095,$008d,$0085,$007d,$0076,$0377 + dc.w $0377,$0346,$0317,$02ea,$02c0,$0299,$0274,$0250 + dc.w $022f,$0210,$01f2,$01d6,$01bc,$01a3,$018b,$0175 + dc.w $0160,$014c,$013a,$0128,$0118,$0108,$00f9,$00eb + dc.w $00de,$00d1,$00c6,$00bb,$00b0,$00a6,$009d,$0094 + dc.w $008c,$0084,$007d,$0076,$0371,$0371,$0340,$0311 + dc.w $02e5,$02bb,$0294,$026f,$024c,$022b,$020c,$01ee + dc.w $01d3,$01b9,$01a0,$0188,$0172,$015e,$014a,$0138 + dc.w $0126,$0116,$0106,$00f7,$00e9,$00dc,$00d0,$00c4 + dc.w $00b9,$00af,$00a5,$009c,$0093,$008b,$0083,$007b + dc.w $0075,$036b,$036b,$033a,$030b,$02e0,$02b6,$028f + dc.w $026b,$0248,$0227,$0208,$01eb,$01cf,$01b5,$019d + dc.w $0186,$0170,$015b,$0148,$0135,$0124,$0114,$0104 + dc.w $00f5,$00e8,$00db,$00ce,$00c3,$00b8,$00ae,$00a4 + dc.w $009b,$0092,$008a,$0082,$007b,$0074,$0364,$0364 + dc.w $0334,$0306,$02da,$02b1,$028b,$0266,$0244,$0223 + dc.w $0204,$01e7,$01cc,$01b2,$019a,$0183,$016d,$0159 + dc.w $0145,$0133,$0122,$0112,$0102,$00f4,$00e6,$00d9 + dc.w $00cd,$00c1,$00b7,$00ac,$00a3,$009a,$0091,$0089 + dc.w $0081,$007a,$0073,$035e,$035e,$032e,$0300,$02d5 + dc.w $02ac,$0286,$0262,$023f,$021f,$0201,$01e4,$01c9 + dc.w $01af,$0197,$0180,$016b,$0156,$0143,$0131,$0120 + dc.w $0110,$0100,$00f2,$00e4,$00d8,$00cb,$00c0,$00b5 + dc.w $00ab,$00a1,$0098,$0090,$0088,$0080,$0079,$0072 + + else +; incbin "periods.nft" + dc.w $0358,$0358,$0328,$02fa,$02d0,$02a6,$0280,$025c + dc.w $023a,$021a,$01fc,$01e0,$01c5,$01ac,$0194,$017d + dc.w $0168,$0153,$0140,$012e,$011d,$010d,$00fe,$00f0 + dc.w $00e2,$00d6,$00ca,$00be,$00b4,$00aa,$00a0,$0097 + dc.w $008f,$0087,$007f,$0078,$0071 + + endc +P61_dma: + dc $8200 +P61_rowpos: + dc 0 +P61_slen: + dc 0 +P61_speed: + dc 0 +P61_speed2: + dc 0 +P61_speedis1: + dc 0 +P61_spos: + dc.l 0 + ifeq p61system +P61_vektori: + dc.l 0 +P61_oldlev6: + dc.l 0 + endc +P61_ofilter: + dc 0 +P61_timers: + dc.l 0 + ifne p61cia +P61_tintti: + dc.l 0 +P61_thi: + dc.b 0 +P61_tlo: + dc.b 0 +P61_thi2: + dc.b 0 +P61_tlo2: + dc.b 0 +P61_timer: + dc.l 0 + endc + ifne P61_pl +P61_plcount: + dc 0 +P61_plflag: + dc 0 +P61_plreset: + dc 0 +P61_plrowpos: + dc 0 +P61_looppos: + dcb.b 12*channels,0 + endc + ifne P61_pde +P61_pdelay: + dc 0 +P61_pdflag: + dc 0 + endc +P61_samples: + dcb.b 16*31,0 +P61_emptysample: + dcb.b 16,0 +P61_positionbase: + dc.l 0 +P61_possibase: + dc.l 0 +P61_patternbase: + dc.l 0 +P61_intaddr: + dc.l 0 + + ifne p61system +P61_server: + dc 0 +P61_miscbase: + dc.l 0 +P61_audioopen: + dc.b 0 +P61_sigbit: + dc.b -1 +P61_ciares: + dc.l 0 +P61_craddr: + dc.l 0,0,0 +P61_dat: + dc $f00 +P61_timerinterrupt: + dc 0,0,0,0,127 +P61_timerdata: + dc.l 0,0,0 +P61_timeron: + dc 0 +P61_allocport: + dc.l 0,0 + dc.b 4,0 + dc.l 0 + dc.b 0,0 + dc.l 0 +P61_reqlist: + dc.l 0,0,0 + dc.b 5,0 +P61_allocreq: + dc.l 0,0 + dc 127 + dc.l 0 +P61_portti: + dc.l 0 + dc 68 + dc.l 0,0,0 + dc 0 +P61_reqdata: + dc.l 0 + dc.l 1,0,0,0,0,0,0 + dc 0 +P61_audiodev: + dc.b 'audio.device',0 +P61_cianame: + dc.b 'ciab.resource',0 +P61_timeropen: + dc.b 0 +P61_timerint: + dc.b 'P61_TimerInterrupt',0,0 + endc +P61_InitPos: + dc.w 0 ;P61_Init starts playing the song from this position. +;; --- optional declares --- + + ifne use1Fx +P61_PTrig: dc.w 0 ;Poll this Custom trigger, using 'Bxx',pos $80-$ff + endc + ifne nowaveforms +P61_NewDMA: dc.w 0 + endc + ifne copdma +p61_DMApokeAddr:dc.l 0 + endc +P61_PattFlag: dc.w 0 +P61_etu: + + ifne quietstart +P61_Quiet: dc.w 0 ;@@this "sample" MUST be in chipmem! + endc + + ifne visuctrs +P61_visuctr0: dc.w $4000 ;pretend long elapsed time at start +P61_visuctr1: dc.w $4000 ;(to not show inital trigger on all channels.) +P61_visuctr2: dc.w $4000 +P61_visuctr3: dc.w $4000 + endc + +P61E: ;end of player binary +samples: ;ds.b 65536 <--declare some space if used. diff --git a/028.game2/game1.s b/028.game2/game1.s index 2f84344..5d6a34c 100644 --- a/028.game2/game1.s +++ b/028.game2/game1.s @@ -28,10 +28,14 @@ Entry: move #$7ff,DMACON(a6) ; disable all dma move #$7fff,INTENA(a6) ; disable all interrupts + jsr StartMusic jsr ShowSplash - move #$7ff,DMACON(a6) ; disable all dma + + if 0 + move #$7ff,DMACON(a6) ; disable all dma move #$7fff,INTENA(a6) ; disable all interrupts + endif lea Level3InterruptHandler,a3 move.l a3,LVL3_INT_VECTOR @@ -738,9 +742,9 @@ panelFade: section .bss foregroundBitplanes1: - ds.b IMAGESIZE*3 + ds.b IMAGESIZE foregroundBitplanes2: - ds.b IMAGESIZE*3 + ds.b IMAGESIZE backgroundBitplanes1: ds.b IMAGESIZE*2 diff --git a/028.game2/music.s b/028.game2/music.s new file mode 100644 index 0000000..7f8a6f2 --- /dev/null +++ b/028.game2/music.s @@ -0,0 +1,12 @@ + xdef StartMusic + +StartMusic: + lea module,a0 + sub.l a1,a1 + sub.l a2,a2 + moveq #0,d0 + jsr P61_Init + rts + +module: + incbin "assets/P61.placeholder" \ No newline at end of file