; #-----+-----------------------------------------# ; |Name:| P6112 Example Source | ; +-----+-----------------------------------------+ ; |V1.06| P6112,E1x/E2x fix | ; |V1.05| P6111,Edx fix,init/exit patch,Dxx note. | ; |V1.04| P6110 final, E6x command fix+new option | ; |V1.03| Final, compatibility changes only. | ; |V1.02| Made more user friendly | ; |V1.01| Plays the example P61 song until you | ; | | press the left mouse button. | ; +-----+-----------------------------------------+ ; | Photon/Scoopex | ; #-----------------------------------------------# ;Tutorial here: http://youtu.be/xBtHO-IuN9E ;Put it in your demo: http://youtu.be/JYLcIR6tyO4 ;Relevant Protracker, P61, music, and code articles on http://coppershade.org ;I'm leaving the P61 project. Read sources and docs. ;I now strictly follow a "Don't ask, don't tell" policy :D ;(I know I said the same in P6111, but I made an exception because it would be ;unnecessarily hard to spot the erroneous line for a coder coming in.) ;If the song works here but not in your demo, the playroutine is okay. Check ;that you have selected the right mode. P61_Music is called automatically in ;p61mode 1 (CIA interrupt, remember?),so don't call it anywhere in your source. ;older notes: ;NOTE: it is now extra important that you SET THE USECODE. See the Special Note ;in P6112-Play.i for why. TIP: using 80x for syncing (timing) instead of E8x ;won't make the song sound worse in non-legacy trackers. It's plug and play, ;just swap them out. ;This example demonstrates simple syncing Set visuctrs=1 to see them :) ;There also 3 commands you can use for module-controller syncing (80x recommen- ;ded), and an oscilloscope ptrs option as well. ;This source demonstrates non-system, non-exec mode. (That means that it can ;also be used in trackmos where you're using ALL low chipmem ;) ) ;It uses an AGA compatible startup that shows a simple copper with a copper ;interrupt request trigger that you poll in the frame loop to wait for a raster ;position. (I.e. you can turn it into a proper copper interrupt). ;Compatibility: You can assemble with or without Label: option. ;Any case-sensitivity and "special operators" issues should be gone. ;Esau/Traktor sent me a nice module to include (thanks!), if it's too big for ;your chipmem left, try one of the smaller ones. ;IT CAN BE USED IN 4 MODES: ;------------------------- ; 1 CIA mode. Plays any song. Uses the CIA interrupt. ; - (default, P61_Music should not be called, easiest to use) ; 2 VBLANK mode. No F20 or higher commands must be used in the song. ; - (use when you want to decide when P61_Music should be called.) ; 3 COPPER mode. No F20 or higher commands must be used in the song. ; - (requires a timed call to P61_Music and a timed copper command ; 11 scanlines later to set sound DMA.) ; 4 MAXOPTI mode. No F20 or higher commands must be used in the song. ; - (requires a timed call to P61_Music and a timed copper command ; 11 scanlines later to set sound DMA. Maximum optimized.) 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. ;; --- 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 ********** CODE START ********** ;(slightly) modified from CIA_Example.G in P6106, credits to original author. section "P6112-Example",code movem.l d0-a6,-(sp) move $dff002,-(sp) ;Old DMA lea gfxname(pc),a1 ;Open graphics.library moveq #0,d0 move.l 4.w,a6 jsr -$228(a6) move.l d0,a6 move.l 34(a6),-(sp) ;Old view move.l a6,-(sp) sub.l a1,a1 jsr -$de(a6) ;LoadView jsr -$10e(a6) ;WaitTOF jsr -$10e(a6) ;WaitTOF lea $dff000,a6 move #$7ff,$96(a6) ;Disable DMAs move #%1000001111000000,$96(a6) ;Master,Copper,Blitter,Bitplanes move $1c(a6),-(sp) ;Old IRQ move #$7fff,$9a(a6) ;Disable IRQs move #$e000,$9a(a6) ;Master and lev6 ;NO COPPER-IRQ! moveq #0,d0 move d0,$106(a6) ;Disable AGA/ECS-stuff move d0,$1fc(a6) ;; --- Call P61_Init --- lea Module1,a0 sub.l a1,a1 sub.l a2,a2 moveq #0,d0 lea p61coppoke+3,a4 ;only used in P61mode >=3 jsr P61_Init move.l #p61copper,$80(a6) ;; --- frame loop start --- wait: move $1e(a6),d0 ;Wait for Copper-bit in INTREQR and.l #$10,d0 beq.b wait move #$10,$9c(a6) ;Clear the bit (poll) ifeq p61cia move #$7f3,$180(a6) jsr P61_Music ;and call the playroutine manually. move #$003,$180(a6) endc ;; --- your demo code start --- ; ===> Put some cool stuff here :) <=== ifne visuctrs lea P61_visuctr0(PC),a0 lea p61visupoke+6,a1 moveq #channels-1,d7 .l: moveq #15,d0 ;maxvalue sub.w (a0)+,d0 ;-#frames/irqs since instrument trigger bpl.s .ok ;below minvalue? moveq #0,d0 ;then set to minvalue .ok: move.w d0,(a1) ;poke blue color lea 16(a1),a1 ;next colorline in copper. dbf d7,.l endc ;; --- your demo code end --- btst #6,$bfe001 ;repeat until left mouse button pressed bne wait ;; --- frame loop end --- exit: btst #6,2(a6) ;Wait for blitter to finish, if used. bne.b exit ;; --- Call P61_End --- jsr P61_End ;; --- exit --- move #$7fff,$9a(a6) ;Restore system status move #$7ff,$96(a6) move (sp)+,d7 ;Old IRQs move.l (sp)+,a6 move.l (sp)+,a1 jsr -$de(a6) ;Old view move.l 38(a6),d3 ;3fd Copper1 move.l a6,a1 move.l 4.w,a6 jsr -$19e(a6) ;CLOSE graphics.library lea $dff000,a6 move.l d3,$80(a6) ;Set old Copper move d3,$88(a6) ;Trigger or #$8000,d7 move d7,$9a(a6) ;Old IRQs move (sp)+,d7 or #$8000,d7 move d7,$96(a6) ;Old DMAs movem.l (sp)+,d0-a6 moveq #0,d0 ;No error code to CLI rts ********** DATA ********** gfxname: dc.b "graphics.library",0 even ********** PLAYROUTINE CODE ********** ;Note: if this is put in its own section (or compiled as separate binary), then ;jsr +P61_InitOffset,P61_MusicOffset,P61_EndOffset,P61_SetPositionOffset ;to call the routines. Playrtn: include "P6112-Play.i" ********** CHIP DATA ********** section "CHIPDATA",data_c p61copper: dc $100,$0200 dc $180,$003 dc $800f,$fffe ;The line to wait to dc $09c,$8010 ;Set Copper-bit in INTREQ ;; --- set dma --- ;(for instruments triggered this frame) dc $8b0f,$fffe p61coppoke: dc $096,$8000 ;sound DMA poke address (in P61mode>=3) ;; --- visualizers --- p61visupoke: dc.w $f007,$fffe dc.w $180,$003 dc.w $f107,$fffe dc.w $180,$003 dc.w $f407,$fffe dc.w $180,$003 dc.w $f507,$fffe dc.w $180,$003 dc.w $f807,$fffe dc.w $180,$003 dc.w $f907,$fffe dc.w $180,$003 dc.w $fc07,$fffe dc.w $180,$003 dc.w $fd07,$fffe dc.w $180,$003 dc.w $ffff,$fffe Module1: ; incbin "P61.sowhat-intro" ;usecode $9410 ; incbin "P61.new_ditty" ;CIA, usecode $c00b43b incbin "P61.Dolphins-Dreamquest-by-Esau" ;CIA, usecode $1006bf5f