playvars.s ---------- Version A# This file describes the major routines and variables used by the Blahtune player. The first part discusses some important routines in detail, and the second part contains a complete listing of all variables along with a short comment and their location. Section 1 --------- A saved file contains the player, some editor tables, the actual music data, and any folds, beginning at $0EFC. A two-byte identification code is placed at the beginning of the file, so a saved file is just the memory from $0EFA to FREBOT, the beginning of free memory. From $0EFC to $0FFF are tables and locations used by the editor. The most important locations in this area are the pointers located at $0FE0, labeled FIELDP. Currently this table contains three pointers, in lo-byte hi-byte form. First is MACBEGIN, which marks the end of the player and the beginning of compiled macros. Second ($0FE2) is ENDFIELD, which marks the end of all field data. Third ($0FE4) is FREBOT, which marks the beginning of free memory (and hence the last address+1 used in the file). Folds are stored immediately following the end of the music data, at ENDFIELD; if there are no folds, then ENDFIELD is equal to FREBOT. The player does not use anything underneath $1000 and above ENDFIELD. $1000 to $103F are entry points into the major player routines, i.e. a kernal jump table. The main player routine is accessed via $1000 (i.e. JSR $1000 will call the player). The init routine is at $1003. SETIRQ is at $1006 (4102) -- calling this routine will install the player into the normal interrupt sequence, which is handy for listening to a tune from BASIC or wherever. LOADINST takes the instrument number contained in .X (0-13) and loads that instrument into the current voice (see CURVOICE below). GETP and SETP get and set the data pointer for the current field; V1GETP, V1SETP etc. get and set the data pointer for the specific voice. The pointer is set/returned in (.A, .X) = (lo, hi). Finally is RETURN, located at $1024. This is the routine macros call to return control to the player. Note that the player expects .Y to be preserved by all macros. $1040-$11BF contains frequency data. There are twenty four frequencies available, and eight octaves for each frequency, giving 24*8 = 192 entires for the low and high frequency bytes. Think of these tables as a piano keyboard with 24 keys per octave and eight octaves. The user can tune a set of 24 keys to whatever frequency is desired, and all the octaves are computed from these 24 base tones. $11C0 contains MARKERS, the table of marker locations as set in the editor. These can be used in conjunction with V1SETP etc. to implement flow control from outside programs (i.e. an outside program can change the music that is being played by simply shifting the data pointers). $1240 is an important location, the Shadow SID. The important SID registers are all read-only, so these locations are set up to keep track of the current values of those registers. Thus it is up to macros and programs and such to update these values when SID is updated, if SHADOW is going to accurately reflect SID. DURTAB, at $1259, contains a table of durations. All notes have an associated duration, which is actually an index into this table -- for instance, a duration of "3" means use the duration value contained at DURTAB+3. Thus changing values in this table will change corresponding values throughout the song. DURATION, at $12FA, on the other hand, is a countdown table for the current notes. When a new note is read in the duration is fetched from DURTAB and stored here. On each pass of the music player this value is decremented, and when it hits zero the next batch of music data is read in. The "ritard" macro increments these locations to implement a "local" delay in the music. LASTNOTE, at $12F4, contains the last note read in for voices 1, 2, and 3. This note is an index into the FREQLO and FREQHI tables. It is sometimes handy to be able to restore the original note after mucking about with SID by using this location. TIMERUPT is located at $1300. This two-byte pointer (in lo,hi form of course) contains the interrupt setting chosen by the composer from the editor, using CTRL-i. The default value is $42C6, which corresponds to a 1/60th second interrupt on an NTSC 64. This value is loaded into the CIA countdown timers by SETIRQ and the editor (when CTRL-p is selected). STOPME, at $1302, tells which voices are active or not. A zero indicates the voice is active, anything else will halt processing for that voice -- the player will simply ignore it and skip to the next voice. FIELDS, at $130B, contains pointers to the beginning of field data for each field, i.e., the initialization routine uses these values along with V1SETP etc. to set the initial data pointers. MACBYTE, starting at $1317, contains the active macro bytes for each field. Twenty-four macros are allowed, thus three bytes are necessary for each field to specify which macros are active and which are not. (There are six fields available, plus field 0, which corresponds to global macros). Outside programs may thus turn macros on and off, although doing so will cause macros to simply "resume", instead of restarting (i.e. can lead to trouble when not used carefully). Section 2 --------- * * These are variables and such taken from the * player routine. They are common from player to * player, thus the compiler etc. doesn't care * which player is being used. * * * Editor and new start information * PLAYSTRT EQU $0EFC INAMES EQU $0EFC ;Instrument names, 6 chars per ;instrument. KEYPOS EQU $0F50 ;Key positions NOTEPOS EQU KEYPOS+24 ;positions of note in big table NOTETEXT EQU $0F80 ;Text which goes with notes e.g. a# NOTEFREQ EQU NOTETEXT+48 ;Base freq values for notes FIELDP EQU $0FE0 ;Pointers, init by player ;MACBEGIN ;ENDFIELD ;FREBOT BOOKMARK EQU $0FF0 * * My little kernal jump table * KERNAL EQU $1000 MAINPLAY EQU KERNAL $1000 PLAYINIT EQU MAINPLAY+3 $1003 SETIRQ EQU PLAYINIT+3 $1006 LOADINST EQU SETIRQ+3 ;.X = Instrument number (0-13) $1009 GETP EQU LOADINST+3 ;(.A, .X) = (lo, hi) data pointer value SETP EQU GETP+3 V1GETP EQU SETP+3 V2GETP EQU V1GETP+3 V3GETP EQU V2GETP+3 V1SETP EQU V3GETP+3 V2SETP EQU V1SETP+3 V3SETP EQU V2SETP+3 RETURN EQU V3SETP+3 * * Variables, tables, etc. * * * These are the variables and such that must stay fixed * so that the compiler and editor don't screw everything * up. * FREQLO EQU KERNAL+64 $1040 * $1100 FREQHI EQU FREQLO+192 $1100 MARKERS EQU FREQHI+192 ;Table of 32 marker locations $11C0 * $1200 MACADR EQU MARKERS+64 ;Macro starting addresses $1200 ;stored seqentially, i.e. ;lo hi lo hi ... thus may ;be jumped to via JMP() ;MUST start on page boundary GLOBVAR = MACADR+48 ;Global variables $1230 SHADOW = GLOBVAR+16 ;Shadow SID $1240 DURTAB = SHADOW+25 ;Table of initial durations $1259 INSTAB = DURTAB+24 ;Instrument table $1271 ;126 bytes (14 instruments) TEMPY = INSTAB+126 ;Temporary storage $12EF LOCOFF = TEMPY+1 ;(local) variable offset $12F0 ;8*current voice COFFSET = LOCOFF+1 ;SID offset (0 7 14) of current voice $12F1 CURVOICE = COFFSET+1 ;Current voice $12F2 CURFIELD = CURVOICE+1 ;Current field $12F3 LASTNOTE = CURFIELD+1 ;Last note read in for voice $12F4 V1FIELD = LASTNOTE+3 ;Voice 1 field $12F7 V2FIELD = V1FIELD+1 ;Voice 2 field $12F8 V3FIELD = V2FIELD+1 ;field associated with Voice 3 $12F9 DURATION = V3FIELD+1 ;Duration for current field $12FA * $1300 TIMERUPT = DURATION+6 ;Interrupt timer setting $1300 STOPME = TIMERUPT+2 ;Stop this voice V1STOP = STOPME $1302 V2STOP = V1STOP+1 $1303 V3STOP = V2STOP+1 $1304 CURINST = V3STOP+1 ;Current instrument for this field $1305 FIELDS EQU CURINST+6 ;Pointers to start of fields. $130B MACBYTE1 = FIELDS+12 ;Macro active bytes $1317 MACBYTE2 = MACBYTE1+7 $131E MACBYTE3 = MACBYTE2+7 $1325 LOCALVAR EQU MACBYTE3+7 ;3+1 sets of 8 local variables $132C