; Atomic PD Intro Demo ;---------------------- ORG &8000 DUMP &8000 clut: EQU &00F8 vmpr: EQU 252 hmpr: EQU 251 lmpr: EQU 250 vscan: EQU &01F8 scl: EQU 160 screen: EQU &C000 scroll: EQU 32*scl+screen reflect: EQU 25*32+screen vubars: EQU 142*32+screen MDAT "atommus" ; include ETRACKER music start: DI IN A,(lmpr) ;keep a copy of the BASIC information LD (lmpr.store),A LD (sp.store),SP LD SP,&C000 ;stick stack in a nice place XOR A ;set border to zero OUT (&FE),A IN A,(vmpr) ;initialise video memory LD (vmpp),A ;store video memory page for later LD HL,&C000 LD DE,&C001 LD (HL),L LD BC,6143 LDIR LD HL,&E000 LD DE,&E001 LD (HL),64+7 ;set attributes to color 15 LD BC,6143 LDIR CALL convert ;fast convert Etracker music (totally ;decompress) LD A,2+32 ; page in screen OUT (vmpr),A LD BC,&01FF ;clear sound chip to zero LD E,0 LD A,28 loop: OUT (C),A DEC B OUT (C),E INC B DEC A JR NZ,loop LD BC,&01FF ;enable sound chip LD A,28 OUT (C),A LD A,B DEC B OUT (C),A LD IX,colourlist ;initialise colors for scrolly LD HL,scroll+8192 LD DE,scroll+8193 EXX LD B,32 col.loop: EXX LD A,(IX) INC IX LD (HL),A LD BC,32 LDIR EXX DJNZ col.loop EXX IN A,(lmpr) EX AF,AF' LD A,4+32 OUT (lmpr),A LD HL,logo LD DE,0 LD BC,logo.len LDIR ;put mode 4 (16 color) logo at top of screen EX AF,AF' OUT (lmpr),A XOR A ; set ripple position to zero LD (ripple+1),A main.loop: IN A,(&F9) ;wait for vblank BIT 3,A JR NZ,main.loop LD A,4+96 ;put screen in mode 4 (to display logo) OUT (vmpr),A LD HL,logo.palette+15 LD BC,&10F8 ;set logo palette OTDR LD A,&7F ;check for SYMBOl key to exit -- debugging only IN A,(&FE) RRA RRA JP NC,exitter CALL mode2.scroll ; scroll the mode2 scrolling text area LD E,23 ; wait for scan to reach line 23 of screen area LD BC,vscan check.4.line: IN A,(C) CP E JR NZ,check.4.line LD HL,scrl.palette+15 LD BC,&10F8 ; set scrolling text palette OTDR LD A,2+32 ; put screen in mode 2 (to display OUT (vmpr),A ; rippling logo area) LD E,37 ; wait for scan to reach screen line 37 LD BC,vscan check.5.line: IN A,(C) CP E JR NZ,check.5.line LD A,4+96 ; put screen in mode 4 (display product data) OUT (vmpr),A CALL ripple ; put rippling text on screen CALL vubar ; put vubar on bottom of screen LD E,141 ; wait for scan to reach line 141 LD BC,vscan check.6.line: IN A,(C) CP E JR NZ,check.6.line LD A,2+32 ;put screen in mode 2 (for scroll/vubars) OUT (vmpr),A CALL music.play ; play music routine JP main.loop ;Scroll a large ATTRIBUTE scroll across the bottom of the MODE 2 screen ;---------------------------------------------------------------------- mode2.scroll: scr.count: LD A,&01 ;has current character been totally DEC A ;displayed? LD (scr.count+1),A JR NZ,next.charb ;if not, shift more of it onto screen scr.store: LD HL,scroll.text ;HL = current position in scroll text scr.read: LD A,(HL) ;get next text char and carry on INC HL LD (scr.store+1),HL CP 255 ;text terminator marker? If so, start JR NZ,not.loop ;at beginning of text again... LD HL,scroll.text ;point HL to beginning of text JR scr.read ;and read data not.loop: LD L,A ;calculate FONT position of this char. LD H,0 LD A,8 ;set counter -- 8 blocks of gfx have to LD (scr.count+1),A ;be printed LD DE,font-256 ADD HL,HL ADD HL,HL ADD HL,HL ADD HL,DE LD DE,charstore ;copy the character into a buffer LDI LDI LDI LDI LDI LDI LDI LDI next.charb: ;put the character on the screen LD DE,63 LD B,8 LD HL,scroll+31 EXX LD HL,charstore EXX lines.loop: EXX XOR A ;font bit default; blank RLC (HL) ; rotate font to left JR NC,nobits ; if leftmost bit is low (blank), jump LD A,&FF ;set font to SET instead of blank nobits: INC HL ;next line of font data EXX LD C,A ;C = font data (needed as a copy; ;RLD changes contents of A) RLD ; <-- scroll font data into screen area DEC L ;Unlooped for speed RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD ADD HL,DE ; jump to next screen line LD A,C ; get original A back again RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD ADD HL,DE LD A,C RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD ADD HL,DE LD A,C RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD DEC L RLD ADD HL,DE DEC B JP NZ,lines.loop ;do next font lines... RET exitter: LD BC,&01FF ; set soundchip to off LD E,0 LD A,28 blloop: OUT (C),A DEC B OUT (C),E INC B DEC A JR NZ,blloop LD A,(vmpp) ;restore BASIC information OUT (vmpr),A LD SP,(sp.store) LD A,(lmpr.store) OUT (lmpr),A RET ;********************SUPER FAST MUSIC ROUTINE******************* ;Routine is (c) 1993 Simon Cooke ;This routine takes between 2 and 7 rasters per frame... dmusic.offs: EQU &0000 ;where to put decompressed music dmusic.page: EQU 6+32 ;Play decompressed music -- basically just dumps data to the soundchip ;every frame (only data which changes each frame). a code of 255 means "end ;of data for this frame", a code of 254 means "end of music data -- restart ;at the beginning". music.play: IN A,(&FA) PUSH AF LD BC,&00FF music.pos: LD HL,dmusic.offs ;start address of music data music.page: LD A,dmusic.page ;page where decomp. music OUT (&FA),A ;starts... f.loop: LD A,(HL) CP 255 JR NZ,not.exit INC HL BIT 6,H JR Z,okay.hi RES 6,H LD A,(music.page+1) INC A LD (music.page+1),A okay.hi: LD (music.pos+1),HL POP AF OUT (&FA),A RET not.exit: CP 254 JR NZ,not.restart music2: LD HL,&0000 music2b: LD A,6+32 OUT (&FA),A LD (music.page+1),A JR f.loop not.restart: CP 6 JR NC,not.vol LD (voll+1),A INC HL LD A,(HL) DEC HL PUSH HL PUSH DE voll: LD HL,&0000 LD DE,vol.table ADD HL,DE LD (HL),A POP DE POP HL not.vol: OUTI ;set soundchip register OUTI ;output data to soundchip JR f.loop ;*******************END OF ROUTINE...*************************** ;ETRACKER > SUPA-FAST MUSIC ;~~~~~~~~~~~~~~~~~~~~~~~~~~ ;Takes an ETRACKER compiled tune, and plays it (silently) as fast as possible, ;copying out any data that changes each frame. This enables super-fast ;playback, as no decoding has to be done. emusic.page: EQU 1 ;page and offset where ETRACKER tune sits emusic.init: EQU 32768 emusic.play: EQU emusic.init+6 output.offset: EQU 979 convert: LD HL,0 LD (counter),HL emusic.ad1: CALL 32768 LD HL,current ;in high memory (32768>65535) LD DE,current+1 LD BC,27 LD (HL),0 LDIR emusic.len: LD HL,1681 ;Number of frames the music ;takes to play in its ;entirety, plus one frame to ;loop it... LD (looper+1),HL decomp.p: LD A,dmusic.page ;page to stash uncomp. music LD (mem.page+1),A decomp.o: LD HL,dmusic.offs ;offset in page to store from LD (mem.offs+1),HL ;MEM.PAGE and MEM.OFFS can be read to find how ;long the decompacted music is - just take them ;away from their initial values... main.dloop: CALL emusic.play ;Call ETRACKER player... emusic.ad2: LD HL,emusic.init+ouput.offset ;(this is the sound chip data ;store) LD DE,new LD BC,28 LDIR LD IX,current LD IY,new mem.page: LD A,0 ;self modifying position regs OUT (lmpr),A mem.offs: LD HL,&0000 LD B,0 check.loop: LD A,(IY) ;Is this register the same as CP (IX) ;last frame? JR Z,okay write.byte: LD (HL),B ;If not, store register and INC HL ;new value in the decompacted LD (HL),A ;area INC HL okay: INC IY INC IX INC B LD A,B CP 28 ;End of music data? JR NZ,check.loop PUSH HL ;Has last music frame just LD HL,(looper+1) ;been played? DEC HL LD A,L OR H POP HL LD A,255 ;if not, store 255 (finished ;this frame's music) JR NZ,not.end LD A,254 ;If yes, store 254 (end of ;tune - so loop to beginning) not.end: CALL put.byte PUSH HL PUSH DE LD HL,(counter) INC HL LD (counter),HL LD DE,321 SBC HL,DE LD A,H OR L POP DE POP HL JR NZ,lower LD A,(mem.page+1) LD HL,(mem.offs+1) LD (music2+1),HL LD (music2b+1),A lower: LD HL,new LD DE,current LD BC,28 LDIR looper: LD HL,&0000 DEC HL LD (looper+1),HL LD A,H OR L JP NZ,main.dloop RET ;this set to the page you're ;in... (eg this routine is at ;16384, and you call it from ;32768 - so you set ;it back to page 1 on exit) put.byte: LD (HL),A INC HL LD (mem.offs+1),HL PUSH BC LD A,R AND 1 LD BC,clut OUT (C),A POP BC BIT 6,H RET Z LD A,(mem.page+1) INC A LD (mem.page+1),A RES 6,H LD (mem.offs+1),HL RET current: DEFS 28 new: DEFS 28 sp.store: DEFW &0000 lmpr.store: DEFB &00 vmpp: DEFB &00 charstore: DEFB %01111100 ;just a copyright symbol for posterity :) DEFB %11000110 DEFB %10010010 DEFB %10011110 DEFB %10010010 DEFB %11000110 DEFB %01111100 DEFB %00000000 ;Put a rippling reflection of the logo at the top of the screen. ;--------------------------------------------------------------- ripple: LD HL,&0000 ;modified by routine previously -- which ripple ADD HL,HL ;frame? then multiply by two to give offset LD DE,refl.table ;in the table ADD HL,DE LD E,(HL) ;address of ripple gfx from table INC HL LD D,(HL) EX DE,HL LD DE,reflect ;area that reflection has to be put at on LD A,6 ;screen notff: LDI ;Copy reflection to screen -- unlooped for speed LDI ;(looped 6 times to keep from taking up too much memory) LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI LDI DEC A JP NZ,notff flip: LD A,&00 ;this is a delay loop. Called flip, as INC A ;it used to merely toggle instead of CP 2 ;incremementing. Stops from rippling too LD (flip+1),A ;fast... RET NZ XOR A LD (flip+1),A LD A,(ripple+1) ;increment ripple frame counter.. INC A AND 7 ;make sure it hasn't gone over end of table LD (ripple+1),A RET counter: DEFW &0000 font: ;font for scrolly MDAT "metal4.fnt" logo: MDAT "logo.cde" logo.len: EQU $-logo refl: ;reflected image of ATOMIC PD logo, rippling MDAT "reflec" refl.table: DEFW refl,refl+384,2*384+refl,3*384+refl ;ripple frame table DEFW 4*384+refl,5*384+refl,6*384+refl,7*384+refl DEFW 8*384+refl,9*384+refl,10*384+refl DEFW 11*384+refl colourlist: ;attribute data for scrolly area of screen DEFB 1,2,1,2,2,3,2,3,3,4,3,4,4,5,4,5,5,6,5,6,6 DEFB 7,6,7,7 DEFB 65,7,65,65,66,65,66,66,67,66,67,67,68,67,68 DEFB 68,69,68,69,69 logo.palette: DEFB 0,4,64,68,100,102,118,127 DEFB 81,24,1,3,2,32,38,98 scrl.palette: DEFB 0,17,21,81,85,84,69,68,0,70,100,102,98,38 DEFB 34,4 ;scrolly palette ;Print VUBARS based on volumes of sound chip channnels. ;------------------------------------------------------ vubar: LD A,(vol.table) AND 15 LD C,A LD A,15 SUB C LD B,A LD DE,32-5 LD HL,vubars+1 CALL put.lines LD A,(vol.table+3) AND 15 LD C,A LD A,15 SUB C LD B,A LD HL,vubars+9 CALL put.lines LD A,(vol.table+5) AND 240 RRCA RRCA RRCA RRCA LD C,A LD A,15 SUB C LD B,A LD HL,vubars+17 CALL put.lines LD A,(vol.table+2) AND 240 RRCA RRCA RRCA RRCA LD C,A LD A,15 SUB C LD B,A LD HL,vubars+25 CALL put.lines RET put.lines: LD A,B blank.l: OR A JR Z,fill.l LD (HL),&00 INC L LD (HL),&00 INC L LD (HL),&00 INC L LD (HL),&00 INC L LD (HL),&00 INC L LD (HL),&00 DEC A ADD HL,DE JR blank.l fill.l: LD A,C fill.l2: OR A JR Z,filled LD (HL),&FF INC L LD (HL),&FF INC L LD (HL),&FF INC L LD (HL),&FF INC L LD (HL),&FF INC L LD (HL),&FF DEC A ADD HL,DE JR fill.l2 filled: RET vol.table: DEFB 0,0,0,0,0,0 end.intro: EQU $ intro.length: EQU $-32768 scroll.text: DEFM "WELCOME, COLIN, TO THE INTRO THAT ENTROPY" DEFM " HAVE WRITTEN FOR YOU! AS YOU CAN SEE, " DEFM "IT'S PRETTY FUNKY, WITH LOTS OF " DEFM "GROOVY GRAPHIC EFFECTS, MUSIC ETC. GOING " DEFM "ON... CREDITS: CODING & IDEA: COOKIE, " DEFM "MUSIC: DR. H, GRAPHICS: COOKIE, ATOMIC PD " DEFM "LOGO: TOBERMORY ... SEE YA LATER ... " DEFM " " DEFB 255