Appendix 4

Listing for MemOutput.asm

nolist

include 'DSPInit.asm'

;-----------------------------------------------------------------------------------

;Memory Map :

;- See how the C compiler organizes the data and variables

; and we will hand code the asm file generated

;

;- We will use the pre-defined sine table in ROM of the DSP56000

; which resides in Y:256 to Y:511 and

; we need the set Data Rom Enable, DE = 1, in the Operating Mode Register (OMR)

;-----------------------------------------------------------------------------------

ProgramStart EQU $0040

WAVE_TABLE_START EQU $0001

WAVE_TABLE_END EQU $0002

WAVE_TABLE_SIZE EQU $0003

WAVE_TABLE_INC EQU $0004

CYCLES EQU $0005

DELAY EQU $0006

AMPLIFICATION EQU $0007

ENVELOPE_TABLE_START EQU $0021

ENVELOPE_TABLE_END EQU $0022

ENVELOPE_TABLE_SIZE EQU $0023

ENVELOPE_TABLE_INC EQU $0024

;-----------------------------------------------------------------------------------

;Host Command Jump Table

;This is where we assign the interrupt vectors to the labels (addresses)

;of the various subroutines

;-----------------------------------------------------------------------------------

ORG P:Reset

JMP ProgramStart

ORG P:SSITxInt

JSR TxInterrupt

ORG P:SSITxEx

JSR SSIException

ORG P:HostCmdInt0

JSR hcOutputWave

ORG P:HostCmdInt13

JSR RxDataInterrupt

;-----------------------------------------------------------------------------------

;Main Program

;-----------------------------------------------------------------------------------

ORG P:ProgramStart

MOVEP #$0000,X:M_BCR ;no wait states

BCLR #M_HF3,X:M_HCR ;HF3 = 0 ie handshake to Mac indicating now not in play mode

;This is where we usually set up various constants in memory, initialize pointers, etc...

;that stay the same between running of the algorithm. REMEMBER that if you request a card

;that has your algorithm already loaded into it, code that lives here WILL NOT BE RUN again

;because the driver will just say heres your card and it's already loaded so don't put

;stuff here that changes after or while you run your algorithm. Put stuff like that in a

;host command called initialize or at the start of your generic do it host command. See

;the filter module in DSPWorkshop for an example.

;NOTE: The following lines set up the various on chip and on card hardware. Generally you should

;just cut and paste from here and/or DSPWorkshop to get things the way you want them. The order

;is important so don't change it unless you know what your doing. See the white binder for

;more info on all the card control logic and chapter 11 in the red book for the SSI etc...

;The I/O-interrupts on the 56k are quite complicated so mess with these initial 'magic' bit settings

;at your own risk and only after consulting the white binder and the red book.

MOVE #>$001377,X0 ;standard STEREO_ON_CARD_PLAYBACK (see white book)

MOVEM X0,P:CTL_LATCH ;set I/O control latch (see white book for details)

MOVEP #$2400,X:M_IPR ;set ssi ipl = 1, host port ipl = 0

MOVEP #$4006,X:M_CRA ;prescale = 1,const = 6,wl = 16 bits ie 44.1kHz

;sets SSI's on chip baud rate - see chap 11 in red book

BTST #4,X:M_SR ;read SSI SR to clear TUE bit so we don't get intrrupted??

MOVEP #0,X:M_TX ;send out zero sample, in conjunction with last line clrs TUE

MOVEP #$531E,X:M_CRB ;RIE = disable,RE = disable, TIE = enable,TE = enable

;SCKD = 0(ext clk),OF1 =1(stereo),OF0 = 0(ext clk)

MOVEP #$0005,X:M_PCDDR ;always!! set to this value so PAL's on card don't get

;conflicting pin directions on expansion port

MOVEP #$0001,X:M_PCD ;Oncard clock source,enable expansion port transmit

;it's a good idea to always enable the expansion port

;transmit so that someone using external DAC,I/O boxes etc...

;can get hold of the data your program generates

;The following three lines must be in this order and next to each other.

MOVEP #$01F8,X:M_PCC ;set port c to SSI mode, disable SCI

BSET #M_HCIE,X:M_HCR ;enable host command data interrupts

ANDI #$FC,MR ;enable interrupts ie set interrupt level to 0

;remember, reseting and loading code into the card

;starts you our at level 3 so you can set up the I/O

;stuff.

ORI #$FF,OMR ;set to mode 0 and set DE = 1 to use ROM table

ANDI #$0C,OMR ;

WtHost WAIT ;wait for mac/host to say start

JMP WtHost

;-----------------------------------------------------------------------------------

;

;-----------------------------------------------------------------------------------

hcOutputWave

BSET #M_HF3,X:M_HCR ;set HF3 to 1 to let host know code is running

BCLR #M_OF0,X:M_CRB ;OF0 = 0 external clock, OF0 = 1 internal clock

BCLR #M_OF1,X:M_CRB

BCLR #M_SCD0,X:M_CRB ;SCD0,SCD1,SCD2 must be set to 1

BSET #M_SCD1,X:M_CRB ;

BSET #M_SCD2,X:M_CRB ;

BCLR #M_SCKD,X:M_CRB ;SCKD = 0 external clock, SCKD = 1 internal clock

BSET #M_FSL,X:M_CRB

BSET #M_SYN,X:M_CRB

BCLR #M_GCK,X:M_CRB

BCLR #M_MOD,X:M_CRB

BSET #M_STE,X:M_CRB

BCLR #M_SRE,X:M_CRB

; BCLR #M_STIE,X:M_CRB

BCLR #M_SRIE,X:M_CRB

nolist

;Start of algorithm

MOVE X:WAVE_TABLE_INC,N0

MOVE X:ENVELOPE_TABLE_START,R1

MOVE X:ENVELOPE_TABLE_INC,N1

BSET #M_STIE,X:M_CRB ;switch DAC on

DO X:CYCLES,_EndCycle

MOVE X:(R1)+N1,X1

MOVE X:WAVE_TABLE_START,R0

DO X:WAVE_TABLE_SIZE,_EndSize

MOVE Y:(R0)+N0,X0

MPY X1,X0,A

DO X:DELAY,_EndDelay

MOVE A0,Y:OUTPUT

_EndDelay

NOP

_EndSize

NOP ;needed because addresses between "end of do loops" cannot be less than 2

_EndCycle

BCLR #M_STIE,X:M_CRB ;switch DAC off

BCLR #M_HF3,X:M_HCR ;clear HF3 to let host know end of code running

RTI

nolist

;-------------------------------------------------------------------------------------

;SSI transmit data

;-------------------------------------------------------------------------------------

TxInterrupt

JSET #M_HF3,X:M_HCR,Playing ;see if we think we are playing

MOVEP #0,X:M_TX ;play a zero

RTI

Playing

MOVEP Y:OUTPUT,X:M_TX ;send the sample to SSI port (DAC)

JCLR #1,X:M_PCD,Done ;if we just played a right sample

Done RTI

;-------------------------------------------------------------------------------------

;Handle a SSI transmit interrupt with underrun exception - tell Mac via HREQ interrupts

;-------------------------------------------------------------------------------------

SSIException

BTST #4,X:M_SR ;read SSI SR to clear TUE bit

MOVEP Y:OUTPUT,X:M_TX ;transmit data to DAC (also needed to clear TUE)

RTI

;-------------------------------------------------------------------------------------

;Interrupt to receive data from host to specific locations of X or Y memory

;-------------------------------------------------------------------------------------

RxDataInterrupt

LoopRxa JCLR #M_HRDF,X:M_HSR,LoopRxa ;wait till MAC has sent the address over

MOVEP X:M_HRX,X0 ;read the xySelect into X0

LoopRxb JCLR #M_HRDF,X:M_HSR,LoopRxb ;wait till MAC has sent the address over

MOVEP X:M_HRX,R0 ;read the xyAddress into R0

LoopRxc JCLR #M_HRDF,X:M_HSR,LoopRxc ;wait till MAC has sent the value over

MOVEP X:M_HRX,Y0 ;read the xyValue into Y0

CLR B

ADD X0,B

JNE RxY

RxX MOVE Y0,X:(R0) ;put value into specified location in X memory

RTI

RxY MOVE Y0,Y:(R0) ;put value into specified location in Y memory

RTI

END