home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 1
/
amigaformatcd01.iso
/
pd
/
music
/
utilities
/
hippoplayer
/
scopes
/
examplescope.s
next >
Wrap
Text File
|
1996-04-30
|
12KB
|
603 lines
*******************************************************************************
* Example scope for HippoPlayer
* By K-P Koljonen
*******************************************************************************
* Can be assembled with Asm-One v1.25, at least.
* Works on all Amiga configurations!
* Version 1.1: Considered sample length to be bytes when it actually was in
* words.
* V1.2: Little fix.
*** Includes:
incdir include:
include exec/exec_lib.i
include exec/ports.i
include exec/types.i
include graphics/graphics_lib.i
include graphics/rastport.i
include intuition/intuition_lib.i
include intuition/intuition.i
incdir
*** Some useful macros
lob macro
jsr _LVO\1(a6)
endm
lore macro
ifc "\1","Exec"
ifd _ExecBase
ifeq _ExecBase
move.l (a5),a6
else
move.l _ExecBase(a5),a6
endc
else
move.l 4.w,a6
endc
else
move.l _\1Base(a5),a6
endc
jsr _LVO\2(a6)
endm
pushm macro
ifc "\1","all"
movem.l d0-a6,-(sp)
else
movem.l \1,-(sp)
endc
endm
popm macro
ifc "\1","all"
movem.l (sp)+,d0-a6
else
movem.l (sp)+,\1
endc
endm
push macro
move.l \1,-(sp)
endm
pop macro
move.l (sp)+,\1
endm
*** HippoPlayer's port:
STRUCTURE HippoPort,MP_SIZE
LONG hip_private1 * Private..
APTR hip_kplbase * kplbase address
WORD hip_reserved0 * Private..
BYTE hip_reserved1 * Private..
BYTE hip_opencount * Open count
BYTE hip_mainvolume * Main volume, 0-64
BYTE hip_play * If non-zero, HiP is playing
BYTE hip_playertype * 33 = Protracker, 49 = PS3M.
*** Protracker ***
BYTE hip_reserved2
APTR hip_PTch1 * Protracker channel data for ch1
APTR hip_PTch2 * ch2
APTR hip_PTch3 * ch3
APTR hip_PTch4 * ch4
*** PS3M ***
APTR hip_ps3mleft * Buffer for the left side
APTR hip_ps3mright * Buffer for the right side
LONG hip_ps3moffs * Playing position
LONG hip_ps3mmaxoffs * Max value for hip_ps3moffs
BYTE hip_PTtrigger1
BYTE hip_PTtrigger2
BYTE hip_PTtrigger3
BYTE hip_PTtrigger4
LABEL HippoPort_SIZEOF
*** PT channel data block
STRUCTURE PTch,0
LONG PTch_start * Start address of sample
WORD PTch_length * Length of sample in words
LONG PTch_loopstart * Start address of loop
WORD PTch_replen * Loop length in words
WORD PTch_volume * Channel volume
WORD PTch_period * Channel period
WORD PTch_private1 * Private...
*** Dimensions:
WIDTH = 320
HEIGHT = 64
*** Variables:
rsreset
_ExecBase rs.l 1
_GFXBase rs.l 1
_IntuiBase rs.l 1
port rs.l 1
owntask rs.l 1
screenlock rs.l 1
oldpri rs.l 1
windowbase rs.l 1
rastport rs.l 1
userport rs.l 1
windowtop rs 1
windowright rs 1
windowleft rs 1
windowbottom rs 1
draw1 rs.l 1
draw2 rs.l 1
omabitmap rs.b bm_SIZEOF
size_var rs.b 0
*** Main program
main lea var_b,a5 * Store execbase
move.l 4.w,a6
move.l a6,(a5)
sub.l a1,a1 * Find our process
lob FindTask
move.l d0,owntask(a5)
lea intuiname(pc),a1 * Open libs
lore Exec,OldOpenLibrary
move.l d0,_IntuiBase(a5)
lea gfxname(pc),a1
lob OldOpenLibrary
move.l d0,_GFXBase(a5)
*** Try to find HippoPlayer's port. If succesful, add 1 to hip_opencount
*** indicating we are using the information in the port.
*** Protect this procedure with Forbid()-Permit()!
lob Forbid
lea portname(pc),a1
lob FindPort
move.l d0,port(a5)
beq.w exit
move.l d0,a0
addq.b #1,hip_opencount(a0) * We are using the port now!
lob Permit
*** Get some info about the screen we're running on
bsr.w getscreendata
*** Open our window
lea winstruc,a0
lore Intui,OpenWindow
move.l d0,windowbase(a5)
beq.w exit
move.l d0,a0
move.l wd_RPort(a0),rastport(a5) * Store rastport and userport
move.l wd_UserPort(a0),userport(a5)
*** Draw a bevel box
plx1 equr d4
plx2 equr d5
ply1 equr d6
ply2 equr d7
moveq #8,plx1
move #331,plx2
moveq #13,ply1
moveq #80,ply2
add windowleft(a5),plx1
add windowleft(a5),plx2
add windowtop(a5),ply1
add windowtop(a5),ply2
move.l rastport(a5),a2
bsr.w piirra_loota2
subq #1,plx1
addq #1,plx2
bsr.w piirra_loota2a
*** Initialize the bitmap structure
lea omabitmap(a5),a0
moveq #1,d0 * depth (1 bitplane)
move #WIDTH,d1 * width
move #HEIGHT,d2 * height
lore GFX,InitBitMap
move.l #buffer1,omabitmap+bm_Planes(a5) * Plane pointer
move.l #buffer1,draw1(a5) * Buffer pointers for drawing
move.l #buffer2,draw2(a5)
*** Set task priority to -30 to prevent messing up with other programs
move.l owntask(a5),a1
moveq #-30,d0
lore Exec,SetTaskPri
move.l d0,oldpri(a5) * Store the old priority
*** Main loop begins here
loop move.l _GFXBase(a5),a6 * Wait a while..
lob WaitTOF
move.l port(a5),a0 * Check if HiP is playing
tst.b hip_play(a0)
beq.b .oh
bsr.w dung * Do the scope
.oh
move.l userport(a5),a0 * Get messages from IDCMP
lore Exec,GetMsg
tst.l d0
beq.b loop
move.l d0,a1
move.l im_Class(a1),d2
lob ReplyMsg
cmp.l #IDCMP_CLOSEWINDOW,d2 * Should we exit?
bne.b loop * No. Keep loopin'
move.l owntask(a5),a1 * Restore the old priority
move.l oldpri(a5),d0
lore Exec,SetTaskPri
exit
*** Exit program
move.l port(a5),d0 * IMPORTANT! Subtract 1 from
beq.b .uh0 * hip_opencount when the port is not
move.l d0,a0 * needed anymore!
subq.b #1,hip_opencount(a0)
.uh0
move.l windowbase(a5),d0 * Close the window
beq.b .uh1
move.l d0,a0
lore Intui,CloseWindow
.uh1
move.l _IntuiBase(a5),a1 * And the libs
lore Exec,CloseLibrary
move.l _GFXBase(a5),a1
lob CloseLibrary
moveq #0,d0 * No error
rts
***** Get some info about the screen we're running on
getscreendata
move.l (a5),a0 * Running kick2.0 or newer?
cmp #37,LIB_VERSION(a0)
bhs.b .new
rts
.new * Yes.
sub.l a0,a0 * Default public screen
lore Intui,LockPubScreen * Kick2.0+ function
move.l d0,d7
beq.b exit
move.l d0,a0 * Store the values
move.b sc_BarHeight(a0),windowtop+1(a5)
move.b sc_WBorLeft(a0),windowleft+1(a5)
move.b sc_WBorRight(a0),windowright+1(a5)
move.b sc_WBorBottom(a0),windowbottom+1(a5)
subq #4,windowleft(a5)
subq #4,windowright(a5)
subq #2,windowbottom(a5)
sub #10,windowtop(a5)
bpl.b .olde
clr windowtop(a5)
.olde
move windowtop(a5),d0 * Adjust the window size
add d0,winstruc+nw_Height
move windowleft(a5),d1
add d1,winstruc+nw_Width
move windowbottom(a5),d3
add d3,winstruc+nw_Height
move.l d7,a1 * Unlock it. Let's hope it doesn't
sub.l a0,a0 * go anywhere before we open our
lob UnlockPubScreen * window ;-)
rts
*** Draw a bevel box
piirra_loota2a
pushm all
moveq #1,d3
bra.b prl
piirra_loota2
pushm all
moveq #0,d3
prl
move.l rastport(a5),a2
move #1,a3
move #2,a4
move.l _GFXBase(a5),a6
move.l a3,d0
move.l a2,a1
lob SetAPen
move.l plx1,d0
move.l ply2,d1
lob Move
move.l a2,a1
move.l plx1,d0
move.l ply1,d1
lob Draw
move.l a2,a1
move.l plx2,d0
move.l ply1,d1
lob Draw
move.l a2,a1
move.l a4,d0
lob SetAPen
move.l a2,a1
move.l plx2,d0
move.l ply1,d1
addq.l #1,d1
sub.l d3,d1
lob Move
move.l a2,a1
move.l plx2,d0
move.l ply2,d1
lob Draw
move.l a2,a1
move.l plx1,d0
addq.l #1,d0
move.l ply2,d1
lob Draw
move.l a2,a1
moveq #1,d0
lob SetAPen
popm all
rts
*** Display the scope
* I have two buffers, one for drawing and one for clearing.
* Clearing is done with blitter during which cpu draws into the other
* buffer. The drawn buffer is then dumped into the window using
* BltBitMapRastPort(). If someone knows a faster way for doing this please
* tell me.
dung
move.l _GFXBase(a5),a6 * Grab the blitter
lob OwnBlitter
lob WaitBlit
* Clear the drawing area using 'demo programmer code'.. :)
move.l draw2(a5),$dff054 * Blitter destination D
move #0,$dff066 * Modulo D
move.l #$01000000,$dff040 * Enable D
move #HEIGHT*64+WIDTH/16,$dff058 * Write size, start blitter
lob DisownBlitter * Free the blitter
pushm all
move.l port(a5),a0
cmp.b #33,hip_playertype(a0) * Protracker?
beq.b .1
cmp.b #49,hip_playertype(a0) * PS3M?
beq.b .2
bra.b .3
.1 bsr.b quadrascope * Quadrascope for PT
bra.b .3
.2 bsr.w multiscope * Stereoscope for PS3M
.3 popm all
movem.l draw1(a5),d0/d1 * Switch the buffers
exg d0,d1
movem.l d0/d1,draw1(a5)
lea omabitmap(a5),a0 * Set the bitplane pointer
move.l d1,bm_Planes(a0)
; lea omabitmap(a5),a0 * Copy from bitmap to rastport
move.l rastport(a5),a1
moveq #0,d0 * source x,y
moveq #0,d1
moveq #10,d2 * dest x,y
moveq #15,d3
add windowleft(a5),d2
add windowtop(a5),d3
move #$c0,d6 * minterm a->d
move #WIDTH,d4 * x-size
move #HEIGHT,d5 * y-size
lore GFX,BltBitMapRastPort * Zwoosh!
rts
*** Quarascope routine for Protracker
* This (and the stereoscope) are very unoptimized. The reason for this is
* that unoptimized code is usually easier to understand than optimized code.
* Also this leaves a certain challenge for coders to try to get the loop
* as fast as possible.
quadrascope
move.l port(a5),a3
move.l hip_PTch1(a3),a3 * Channel 1 data
move.l draw1(a5),a0
bsr.b .scope
* WIDTH/8/4 = 10
move.l port(a5),a3
move.l hip_PTch2(a3),a3
move.l draw1(a5),a0
lea 10(a0),a0 * Position
bsr.b .scope
move.l port(a5),a3
move.l hip_PTch3(a3),a3
move.l draw1(a5),a0
lea 10+10(a0),a0
bsr.b .scope
move.l port(a5),a3
move.l hip_PTch4(a3),a3
move.l draw1(a5),a0
lea 10+10+10(a0),a0
bsr.b .scope
rts
.scope
tst.l PTch_loopstart(a3) * Always check these to avoid
beq.b .halt * enforcer hits!
move.l PTch_start(a3),d0
bne.b .jolt
.halt rts
.jolt
move.l d0,a1 * Sample start
moveq #0,d5
move PTch_length(a3),d5 * Sample length in words
add.l d5,d5 * Convert to bytes
move.l port(a5),a2 * Get mainvolume
moveq #0,d1
move.b hip_mainvolume(a2),d1 * (Main volume * sample volume)/64
mulu PTch_volume(a3),d1
lsr #6,d1 * Value for scaling the data
moveq #0,d0 * X coordinate
moveq #80-1,d7 * Loop counter, do 80 pixels
drlo
move.b (a1)+,d2 * Read one byte sample data
ext d2 * Sign extend to word
muls d1,d2 * Scale according to volume
asr #6,d2 * ...
add #$80,d2 * Change the sign
asr #2,d2 * Scale down to 0-63
mulu #WIDTH/8,d2 * Get Y coordinate in the bitplane
move d0,d4 * X
move d0,d3
lsr #3,d4 * X offset in bytes = x-coord/8
add d4,d2 * Add to Y
not d3 * Plot pixel
bset d3,(a0,d2) * ...
subq.l #1,d5 * Subtract sample length
bpl.b .l * sample end?
moveq #0,d5 * Get values for loop
move PTch_replen(a3),d5
add.l d5,d5
move.l PTch_loopstart(a3),a1
.l
addq #1,d0 * Increase X
dbf d7,drlo * Loop..
rts
*** Stereoscope for PS3M
multiscope
move.l port(a5),a1
move.l hip_ps3mleft(a1),a1
move.l draw1(a5),a0
bsr.b .h
move.l port(a5),a1
move.l hip_ps3mright(a1),a1
move.l draw1(a5),a0
lea WIDTH/8/2(a0),a0
bsr.b .h
rts
.h move.l port(a5),a2
move.l hip_ps3moffs(a2),d5 * Get offset in buffers
move.l hip_ps3mmaxoffs(a2),d4 * Get max offset
move #160-1,d7 * Draw 160 pixels
moveq #0,d0 * X coord
.drlo
moveq #0,d2
move.b (a1,d5.l),d2 * Get data from mixing buffer
add.b #$80,d2
lsr #2,d2
mulu #WIDTH/8,d2 * Y
move d0,d6
move d0,d3
lsr #3,d6 * X offset in bytes = x-coord/8
add d6,d2
not d3 * Plot pixel
bset d3,(a0,d2) * ...
addq #1,d0 * Increase x coord
addq.l #1,d5 * Increase buffer position
and.l d4,d5 * make sure it stays in the buffer
dbf d7,.drlo * Loop
rts
*******************************************************************************
* Window
wflags = WFLG_SMART_REFRESH!WFLG_DRAGBAR!WFLG_CLOSEGADGET!WFLG_DEPTHGADGET
idcmpflags = IDCMP_CLOSEWINDOW
winstruc
dc 110,85 * x,y position
winsiz dc 340,85 * x,y size
dc.b 2,1
dc.l idcmpflags
dc.l wflags
dc.l 0
dc.l 0
dc.l .t * title
dc.l 0
dc.l 0
dc 0,640 * min/max x
dc 0,256 * min/max y
dc WBENCHSCREEN
dc.l 0
.t dc.b "HiP - Example scope",0
intuiname dc.b "intuition.library",0
gfxname dc.b "graphics.library",0
portname dc.b "HiP-Port",0
even
section udnm,bss_p
* Variables
var_b ds.b size_var
section hihi,bss_c
* GFX buffers
buffer1 ds.b WIDTH/8*HEIGHT
buffer2 ds.b WIDTH/8*HEIGHT
end