************************************************************************* * * * The 81st Track MusicDisk 1 Loader by The 81st Track * * * ************************************************************************* incdir "asrc:include/" include "libraries/dos_lib.i" include "exec/exec_lib.i" include "hardware/custom.i" include "hardware/blit.i" include "81/my_macros.i" org $10000 a1save equ $7f400 Hardware equ $dff000 PortA equ $bfe001 LeftMouse equ 6 ************************************************************************* MainCode move.l #Hardware,a6 move.l #0,d0 ; read first tune before jsr ReadTune ; the main section runs bsr SetupAll MainCodeLoop bsr WaitForFrame ; the main loop bsr dopointer ; the mouse pointer... bsr cycleptrcolors ; ...colour cycles bsr DoScroll ; the scroll text jsr mt_music ; the music bsr dovubars ; the copper bar! btst #LeftMouse,PortA bne.s MainCodeLoop move.l #loadbuttons,a0 ; check for click on 'button' move.l #5,d7 ; 6 buttons move.l #0,d0 ; first=0 (for ReadTune) buttoncheckloop move.w (a0)+,d1 ; read button corner co-ords move.w (a0)+,d2 move.w (a0)+,d3 move.w (a0)+,d4 move.w pointerposx,d5 ; check for click within area move.w pointerposy,d6 cmp.w d5,d1 ; too far left? bcc.s checknext cmp.w d6,d2 ; too far up? bcc.s checknext cmp.w d3,d5 ; too far right? bcc.s checknext cmp.w d4,d6 ; too far down? bcc.s checknext jsr ReadTune ; okay then, get the tune! bra.s MainCodeLoop checknext add.l #1,d0 ; check next 'button' area dbf d7,buttoncheckloop move.w #0,potgo(a6) ; me want RMB input! btst #10,potinp(a6) beq LoadXtraBit ; if pressed, load extra bit bra MainCodeLoop LoadXtraBit jsr mt_end ; first stop music move.l #LoadCopper,cop1lc(a6) ; set 'load' copper list move.l a1save,a1 ; load it move.l #$20000,40(a1) move.l #$8fa00,44(a1) move.l #$3fe00,36(a1) move.l _SysBase,a6 jsr _LVODoIO(a6) jmp $20000 ; I know this only loads, ; but I'm not going to put ; in a 'loading only' bitmap ; just to please purists! ************************************************************************* SetupAll move.l #NewCopper,cop1lc(a6) ; setup main copper list move.w #0,copjmp1(a6) move.w #0,joytest(a6) ; zero mouse counters move.l #screencolors,a0 ; set them colour registers! lea color(a6),a1 move.l #31,d0 SetupAllLoop move.w (a0)+,(a1)+ dbf d0,SetupAllLoop move.l #0,pointerposx ; set pointer pos to 0,0 move.w #0,d0 ; set pointer sprite move.w #0,d1 jsr setpointer move.w #$83e0,dmacon(a6) ; enable DMA bsr WaitForBlit ; wait for any blits to finish rts WaitForVBlank btst #5,intreqr+1(a6) ; wait for VBlank Int Req beq.s WaitForVBlank move.w #$20,intreq(a6) rts KillSprDatBuff moveq.l #0,d0 ; Kill Sprite DMA Data Buffer move.l d0,$144(a6) ; for all sprites! move.l d0,$14c(a6) move.l d0,$154(a6) move.l d0,$15c(a6) move.l d0,$164(a6) move.l d0,$16c(a6) move.l d0,$174(a6) move.l d0,$17c(a6) rts WaitForFrame btst #4,intreqr+1(a6) ; Wait for Copper Int Req beq.s WaitForFrame move.w #$10,intreq(a6) rts WaitForBlit btst #14,dmaconr(a6) ; Wait for Blit finished flag WFBLoop btst #14,dmaconr(a6) bne.s WFBLoop rts ************************************************************************* dopointer move.w joy0dat(a6),d0 ; get current counter values and.w #$fcfc,d0 ; mask certain bits move.w #0,joytest(a6) ; zero counters cmp.b #$80,d0 ; check x direction bcc.s ptrleft move.b d0,d1 ; amend pointer x pos (+) and.w #$ff,d1 lsr.w #2,d1 add.w d1,pointerposx bra.s dopointery ptrleft move.b d0,d1 ; amend pointer x pos (-) and.w #$ff,d1 not.b d1 add.w #1,d1 lsr.w #2,d1 sub.w d1,pointerposx dopointery move.w d0,d1 lsr.w #8,d1 cmp.b #$80,d1 ; check y direction bcc.s ptrup and.w #$ff,d1 ; amend pointer y pos (+) lsr.w #2,d1 add.w d1,pointerposy bra.s checkpointerpos ptrup and.w #$ff,d1 ; amend pointer y pos (-) not.b d1 add.w #1,d1 lsr.w #2,d1 sub.w d1,pointerposy checkpointerpos move.w pointerposx,d0 ; check if pointer on screen bmi.s poswrapleft ; check for moving off to left cmp.w #320,d0 bcc.s poswrapright ; ...and right chkptrposy move.w pointerposy,d0 bmi.s poswrapup ; ...and top cmp.w #256,d0 bcc.s poswrapdown ; ...and bottom pointerposokay move.w pointerposx,d0 move.w pointerposy,d1 jsr setpointer rts poswrapleft move.w #0,pointerposx ; if off to left, xpos=0 bra.s chkptrposy poswrapright move.w #319,pointerposx ; if off to right, xpos=319 bra.s chkptrposy poswrapup move.w #0,pointerposy ; if off to top, ypos=0 bra.s pointerposokay poswrapdown move.w #255,pointerposy ; if off to bottom, ypos=255 bra.s pointerposokay cycleptrcolors move.l #pointercolors+30,a0 ; make the pointer look less move.l #pointercolors+32,a1 ; boring by doing a simple move.w (a0),d1 ; colour cycle on colour move.l #13,d0 ; registers 17-31 cpcloop1 move.w -(a0),-(a1) dbf d0,cpcloop1 move.w d1,(a0) lea color+34(a6),a1 move.l #14,d0 cpcloop2 move.w (a0)+,(a1)+ dbf d0,cpcloop2 rts ; This next section produces ; a 'quad' copper bar - a bar ; split into four pieces ; along its length dovubars move.l #trigvoice1,a0 ; my tracker add-on data move.l #vucolorbits,a1 ; colours for bar move.l #vuvalues,a2 ; value of vu move.w #0,d1 ; first part first! move.l #3,d0 ; four parts (of copper bar) dovubarsloop tst.w (a0) ; if no new note, fade bar beq.s fadevubar move.w #0,(a0) ; else, zero new note data move.w #16,(a2) ; set value to max fadevubar tst.w (a2) ; if vu at zero, don't fade beq.s nofadevubar sub.w #1,(a2) ; else, decrease value by 1 move.w (a2),d2 ; create bar from vu value move.l #vubuffer+32,a3 ; start in middle of buffer move.l a3,a4 move.l #15,d3 ; upto 16 lines (each side) fadevubarloop move.w d2,d4 ; make screen colour mulu (a1),d4 move.w d4,-(a3) ; put it into buffer move.w d4,(a4)+ sub.w #1,d2 ; next colour (colour-1) bcc.s fadeokay ; if NextColour<0, colour=0 move.w #0,d2 fadeokay dbf d3,fadevubarloop ; next line move.l #vubuffer,a3 ; dump vu bar in copper list move.l #vubars+6,a4 move.w d1,d2 mulu #8,d2 add.l d2,a4 move.l #31,d2 ; 32 entries dumpbarloop move.w (a3)+,(a4) ; buffer -> copper list add.l #32,a4 dbf d2,dumpbarloop ; next entry nofadevubar add.w #1,d1 ; next vu bar add.l #2,a0 ; next 'new note data' add.l #2,a1 ; next vu bar colour add.l #2,a2 ; next vu value dbf d0,dovubarsloop ; next vu bar rts ; this is a simple scroll ; routine - 8x8 chars, single ; speed - except double height DoScroll bsr WaitForBlit ; wait for blitter move.l #-1,bltafwm(a6) ; then move it: no mask move.l #$f9f00000,bltcon0(a6) ; shift 15 right move.w #0,bltamod(a6) move.w #0,bltdmod(a6) move.l #scrollarea+2,bltapt(a6) move.l #scrollarea,bltdpt(a6) ; dest 1 word left move.w #$0455,bltsize(a6) bsr WaitForBlit ; wait for blit to finish sub.b #1,scrollpixel ; 1 less blit to next char tst.b scrollpixel ; if no more, beq.s scrollnewchar ; get new character rts scrollnewchar add.l #1,scrollptr ; next character in message move.l scrollptr,a0 ; get message pointer tst.b (a0) ; if char=0(NUL), restart beq.s scrollrestart cmp.b #32,(a0) ; if char<32, skip char bcs.s scrollnewchar move.l #0,d0 ; get char (into long) move.b (a0),d0 sub.b #32,d0 ; get address of char def mulu #8,d0 add.l #scrollfont,d0 move.l d0,a0 move.l #scrollarea+82,a1 ; get address of bitmap move.l #7,d0 ; 8 lines scrollputchloop move.b (a0),(a1) ; copy it! move.b (a0)+,42(a1) add.l #84,a1 ; next bitmap line dbf d0,scrollputchloop move.b #8,scrollpixel ; 8 blits until next char rts scrollrestart move.l #scrollmessage,scrollptr ; pretty obvious! bra.s scrollnewchar ; This section reads a tune ; when given a number from ; 0 to 5. It 'knows' where ; the tunes are on disk by ; looking in a table ReadTune jsr mt_end ; first, stop current tune move.l #LoadCopper,cop1lc(a6) ; set 'load&decrunch' display move.l a1save,a1 ; get trackdisk IO req move.l #TuneParamTable,a0 ; get tune offset&length and.l #$f,d0 asl.l #3,d0 add.l d0,a0 move.l #$52000,40(a1) ; crunched version at $52000 move.l (a0)+,44(a1) move.l (a0)+,36(a1) move.l _SysBase,a6 jsr _LVODoIO(a6) ; read it! move.l #Hardware,a6 jsr $52000 ; decrunches to $20000 move.l #NewCopper,cop1lc(a6) ; set 'menu' display jsr mt_init ; setup new tune rts ************************************************************************* even ; Here follows the copper list used when a tune is loading - the sprites are ; not used, so all pointers are directed to the 'nullsprite' longword. LoadCopper cmove $0200,bplcon0 cmove $0000,bplcon1 cmove $2c81,diwstrt cmove $2cc1,diwstop cmove $0038,ddfstrt cmove $00d0,ddfstop cmove $0000,bpl1mod cmove $0000,bpl2mod cmove ((nullsprite&$ffff0000)>>16),sprpt cmove (nullsprite&$ffff),sprpt+$02 cmove ((nullsprite&$ffff0000)>>16),sprpt+$04 cmove (nullsprite&$ffff),sprpt+$06 cmove ((nullsprite&$ffff0000)>>16),sprpt+$08 cmove (nullsprite&$ffff),sprpt+$0a cmove ((nullsprite&$ffff0000)>>16),sprpt+$0c cmove (nullsprite&$ffff),sprpt+$0e cmove ((nullsprite&$ffff0000)>>16),sprpt+$10 cmove (nullsprite&$ffff),sprpt+$12 cmove ((nullsprite&$ffff0000)>>16),sprpt+$14 cmove (nullsprite&$ffff),sprpt+$16 cmove ((nullsprite&$ffff0000)>>16),sprpt+$18 cmove (nullsprite&$ffff),sprpt+$1a cmove ((nullsprite&$ffff0000)>>16),sprpt+$1c cmove (nullsprite&$ffff),sprpt+$1e cmove $0000,color cmove $0f00,color+$02 cwait $71,$09 cmove $1200,bplcon0 cmove ((loadingbitmap&$ffff0000)>>16),bplpt cmove (loadingbitmap&$ffff),bplpt+$02 cwait $e7,$09 cmove $0200,bplcon0 dc.w $ff09,$fffe,$ffdd,$fffe cend ; This is the main copper list for the menu display, and includes the 'mouse ; pointer' sprite pointer setting, and the vu copper bar! NewCopper cmove $1200,bplcon0 ; some general screen stuff cmove $0000,bplcon1 cmove $2c81,diwstrt cmove $2cc1,diwstop cmove $0038,ddfstrt cmove $00d0,ddfstop cmove $0000,bpl2mod ; how to set up a mouse pointer! cmove ((ptrspr0&$ffff0000)>.>.16),sprpt cmove (ptrspr0&$ffff),sprpt+$02 cmove ((ptrspr1&$ffff0000)>.>.16),sprpt+$04 cmove (ptrspr1&$ffff),sprpt+$06 cmove ((nullsprite&$ffff0000)>.>.16),sprpt+$08 cmove (nullsprite&$ffff),sprpt+$0a cmove ((nullsprite&$ffff0000)>.>.16),sprpt+$0c cmove (nullsprite&$ffff),sprpt+$0e cmove ((nullsprite&$ffff0000)>.>.16),sprpt+$10 cmove (nullsprite&$ffff),sprpt+$12 cmove ((nullsprite&$ffff0000)>.>.16),sprpt+$14 cmove (nullsprite&$ffff),sprpt+$16 cmove ((nullsprite&$ffff0000)>.>.16),sprpt+$18 cmove (nullsprite&$ffff),sprpt+$1a cmove ((nullsprite&$ffff0000)>.>.16),sprpt+$1c cmove (nullsprite&$ffff),sprpt+$1e ; more general screen stuff cmove ((scrollarea&$ffff0000)>.>.16),bplpt cmove (scrollarea&$ffff),bplpt+$02 cmove $0000,color+$02 cmove $0002,bpl1mod cwait $2d,$09 cmove $0fff,color+$02 cwait $3d,$09 cmove $0000,color+$02 cwait $3e,$09 cmove $4200,bplcon0 cmove $0fff,color+$02 cmove ((screenplane1&$ffff0000)>.>.16),bplpt cmove (screenplane1&$ffff),bplpt+$02 cmove ((screenplane2&$ffff0000)>.>.16),bplpt+$04 cmove (screenplane2&$ffff),bplpt+$06 cmove ((screenplane3&$ffff0000)>.>.16),bplpt+$08 cmove (screenplane3&$ffff),bplpt+$0a cmove ((screenplane4&$ffff0000)>.>.16),bplpt+$0c cmove (screenplane4&$ffff),bplpt+$0e cmove $0000,bpl1mod ; *** THE VU COPPER BAR *** ; ; ATTENTION! ATTENTION! Clear the area! ; Bloody big copper list section approaching! vubars dc.w $9c09,$fffe,$180,$000,$9c65,$fffe,$180,$000 dc.w $9c8f,$fffe,$180,$000,$9cb9,$fffe,$180,$000 dc.w $9d09,$fffe,$180,$000,$9d65,$fffe,$180,$000 dc.w $9d8f,$fffe,$180,$000,$9db9,$fffe,$180,$000 dc.w $9e09,$fffe,$180,$000,$9e65,$fffe,$180,$000 dc.w $9e8f,$fffe,$180,$000,$9eb9,$fffe,$180,$000 dc.w $9f09,$fffe,$180,$000,$9f65,$fffe,$180,$000 dc.w $9f8f,$fffe,$180,$000,$9fb9,$fffe,$180,$000 dc.w $a009,$fffe,$180,$000,$a065,$fffe,$180,$000 dc.w $a08f,$fffe,$180,$000,$a0b9,$fffe,$180,$000 dc.w $a109,$fffe,$180,$000,$a165,$fffe,$180,$000 dc.w $a18f,$fffe,$180,$000,$a1b9,$fffe,$180,$000 dc.w $a209,$fffe,$180,$000,$a265,$fffe,$180,$000 dc.w $a28f,$fffe,$180,$000,$a2b9,$fffe,$180,$000 dc.w $a309,$fffe,$180,$000,$a365,$fffe,$180,$000 dc.w $a38f,$fffe,$180,$000,$a3b9,$fffe,$180,$000 dc.w $a409,$fffe,$180,$000,$a465,$fffe,$180,$000 dc.w $a48f,$fffe,$180,$000,$a4b9,$fffe,$180,$000 dc.w $a509,$fffe,$180,$000,$a565,$fffe,$180,$000 dc.w $a58f,$fffe,$180,$000,$a5b9,$fffe,$180,$000 dc.w $a609,$fffe,$180,$000,$a665,$fffe,$180,$000 dc.w $a68f,$fffe,$180,$000,$a6b9,$fffe,$180,$000 dc.w $a709,$fffe,$180,$000,$a765,$fffe,$180,$000 dc.w $a78f,$fffe,$180,$000,$a7b9,$fffe,$180,$000 dc.w $a809,$fffe,$180,$000,$a865,$fffe,$180,$000 dc.w $a88f,$fffe,$180,$000,$a8b9,$fffe,$180,$000 dc.w $a909,$fffe,$180,$000,$a965,$fffe,$180,$000 dc.w $a98f,$fffe,$180,$000,$a9b9,$fffe,$180,$000 dc.w $aa09,$fffe,$180,$000,$aa65,$fffe,$180,$000 dc.w $aa8f,$fffe,$180,$000,$aab9,$fffe,$180,$000 dc.w $ab09,$fffe,$180,$000,$ab65,$fffe,$180,$000 dc.w $ab8f,$fffe,$180,$000,$abb9,$fffe,$180,$000 dc.w $ac09,$fffe,$180,$000,$ac65,$fffe,$180,$000 dc.w $ac8f,$fffe,$180,$000,$acb9,$fffe,$180,$000 ; still reading?? dc.w $ad09,$fffe,$180,$000,$ad65,$fffe,$180,$000 dc.w $ad8f,$fffe,$180,$000,$adb9,$fffe,$180,$000 dc.w $ae09,$fffe,$180,$000,$ae65,$fffe,$180,$000 dc.w $ae8f,$fffe,$180,$000,$aeb9,$fffe,$180,$000 dc.w $af09,$fffe,$180,$000,$af65,$fffe,$180,$000 dc.w $af8f,$fffe,$180,$000,$afb9,$fffe,$180,$000 dc.w $b009,$fffe,$180,$000,$b065,$fffe,$180,$000 dc.w $b08f,$fffe,$180,$000,$b0b9,$fffe,$180,$000 dc.w $b109,$fffe,$180,$000,$b165,$fffe,$180,$000 dc.w $b18f,$fffe,$180,$000,$b1b9,$fffe,$180,$000 dc.w $b209,$fffe,$180,$000,$b265,$fffe,$180,$000 dc.w $b28f,$fffe,$180,$000,$b2b9,$fffe,$180,$000 dc.w $b309,$fffe,$180,$000,$b365,$fffe,$180,$000 dc.w $b38f,$fffe,$180,$000,$b3b9,$fffe,$180,$000 dc.w $b409,$fffe,$180,$000,$b465,$fffe,$180,$000 dc.w $b48f,$fffe,$180,$000,$b4b9,$fffe,$180,$000 dc.w $b509,$fffe,$180,$000,$b565,$fffe,$180,$000 dc.w $b58f,$fffe,$180,$000,$b5b9,$fffe,$180,$000 dc.w $b609,$fffe,$180,$000,$b665,$fffe,$180,$000 dc.w $b68f,$fffe,$180,$000,$b6b9,$fffe,$180,$000 dc.w $b709,$fffe,$180,$000,$b765,$fffe,$180,$000 dc.w $b78f,$fffe,$180,$000,$b7b9,$fffe,$180,$000 dc.w $b809,$fffe,$180,$000,$b865,$fffe,$180,$000 dc.w $b88f,$fffe,$180,$000,$b8b9,$fffe,$180,$000 dc.w $b909,$fffe,$180,$000,$b965,$fffe,$180,$000 dc.w $b98f,$fffe,$180,$000,$b9b9,$fffe,$180,$000 dc.w $ba09,$fffe,$180,$000,$ba65,$fffe,$180,$000 dc.w $ba8f,$fffe,$180,$000,$bab9,$fffe,$180,$000 dc.w $bb09,$fffe,$180,$000,$bb65,$fffe,$180,$000 dc.w $bb8f,$fffe,$180,$000,$bbb9,$fffe,$180,$000 ; the last of the general screen stuff cwait $bc,$09 cmove $0000,color dc.w $ff09,$fffe,$ffdd,$fffe cwait $19,$09 cmove $0000,color+$02 cwait $1a,$09 cmove $1200,bplcon0 cmove ((scrollarea&$ffff0000)>>16),bplpt cmove (scrollarea&$ffff),bplpt+$02 cmove $0000,color+$02 cmove $0002,bpl1mod cwait $1b,$09 cmove $0fff,color+$02 cwait $2c,$09 ; cause a copper interrupt request cmove $8010,intreq ; end of copper list (at last) cend ************************************************************************* ; The data for where the tunes are held on the disk TuneParamTable dc.l $10600,$1fc00,$30200,$21000,$51200,$0c600 dc.l $5d800,$18e00,$76600,$06400,$7ca00,$13000 ; The data for where a mouse click causes a tune to load loadbuttons dc.w 017,030,089,077,124,036,196,077,231,036,303,077 dc.w 017,177,089,218,124,177,196,218,231,177,303,218 ; The mouse pointer data pointerposx dc.w 0 pointerposy dc.w 0 ; Data for screen (and associated stuff) loadscreen incbin "loadscreen.raw.trim" screenplane1 equ loadscreen screenplane2 equ screenplane1+8800 screenplane3 equ screenplane2+8800 screenplane4 equ screenplane3+8800 screencolors dc.w $000,$fff,$ddd,$bbb,$999,$777,$555,$333 dc.w $fa0,$f00,$ff0,$ff0,$ff0,$038,$04b,$04e pointercolors dc.w $000,$0bf,$08f,$08f,$0bf,$0fd,$0f7,$0f2 dc.w $4f0,$af0,$ff0,$af0,$4f0,$0f2,$0f7,$0fd loadingbitmap incbin "load-decr.bitmap" ; The scroll data scrollfont include "asrc:fontsrc/hsspace.fontsrc" scrollarea dcb.b 756,0 scrollptr dc.l scrollmessage scrollmessage incbin "load.msg" dc.b 0 scrollpixel dc.b 1 even ; The 'vu' data area vubuffer dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.w 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 vuvalues dc.w 0,0,0,0 vucolorbits dc.w $100,$010,$001,$111 ************************************************************************* include "pointer.s" include "asrc:demo/common/nt20play.s" ds.b $1fffe-* ; *** This rts has to go at $1fffe - the tunes JMP $1FFFE after decrunch rts mt_data equ $20000