Changeset 4f508e6 in buchla-68k for ram/fpuint.s
- Timestamp:
- 07/01/2017 02:34:46 PM (7 years ago)
- Branches:
- master
- Children:
- 08e1da1
- Parents:
- f40a309
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
ram/fpuint.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *fpuint.s -- process FPU interrupts / clear FPU3 *Version 63 -- 1988-08-31 -- D.N. Lynx Crowe4 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | fpuint.s -- process FPU interrupts / clear FPU 3 | Version 63 -- 1988-08-31 -- D.N. Lynx Crowe 4 | ------------------------------------------------------------------------------ 5 5 .text 6 * 7 .xdef _fpuint *process an FPU interrupt8 .xdef _fpuclr *reset the FPU9 .xdef _clrvce *quiet a voice10 * 11 .xdef _fputrap *a very good debug trap point12 * 13 .xdef _fp_resv *'spare' function reset value table14 .xdef _fpuifnc *FPU interrupt code (voice / function)15 * 16 .xref _irand *ranged random number function17 .xref _scope *diagnostic scope function18 .xref _xgetran *random number function19 * 6 7 .xdef _fpuint | process an FPU interrupt 8 .xdef _fpuclr | reset the FPU 9 .xdef _clrvce | quiet a voice 10 11 .xdef _fputrap | a very good debug trap point 12 13 .xdef _fp_resv | 'spare' function reset value table 14 .xdef _fpuifnc | FPU interrupt code (voice / function) 15 16 .xref _irand | ranged random number function 17 .xref _scope | diagnostic scope function 18 .xref _xgetran | random number function 19 20 20 .xref _expbit 21 21 .xref _funcndx … … 33 33 .xref _vce2trg 34 34 .xref _veltab 35 * 36 .page 37 *------------------------------------------------------------------------------38 *Register usage39 *--------------40 *d0 scratch41 *d1 FPU function index42 *d2 point index from FH_CPT (idfcpt)43 *d3 scratch44 *d4 jump point number from PT_PAR1 (ippar1)45 *d5 scratch46 * 47 *a0 scratch48 *a1 function header base49 *a2 point table base50 *a3 FPU base51 * 52 *------------------------------------------------------------------------------53 *FPU definitions54 *---------------55 * 56 UPD_BIT .equ $0001 *update bit (1 = update)57 INT_BIT .equ $0002 *int. bit (0 = disable)58 RAT_BIT .equ $0004 *ratio bit (0 = ratio)59 * 60 VSUBNBIT .equ 3 *new value select bit number61 VAL_BITS .equ $0018 *new value select bit mask62 * 63 MSK_RNVB .equ $000C *new value / ratio bits64 MSK_ONVB .equ $0010 *old new value bit65 * 66 FKILL .equ $0014 *kill value for function67 FSEND .equ $0015 *send new value to function68 * 69 CLREXP .equ $8000 *clear value for time exponent70 CLRMNT .equ $8000 *clear value for time mantissa71 * 72 *------------------------------------------------------------------------------73 *Miscellaneous definitions74 *-------------------------75 * 76 PCHMAX .equ 21920 *maximum pitch value77 VALMAX .equ 32000 *maximum value to send to FPU78 VALMIN .equ -32000 *minimum value to send to FPU79 * 80 LSPCH .equ 2 *left shift for sources to freq81 * 82 VALLEN .equ 10 *length of the 'valent' struct83 VT_VAL .equ 8 *value offset in 'valent'84 * 85 .page 86 *------------------------------------------------------------------------------87 *FPU addresses88 *-------------89 * 90 FPUBASE .equ $180000 *FPU base address91 * 92 FPUWST .equ FPUBASE *FPU waveshape base93 FPUFUNC .equ FPUBASE+$4000 *FPU function base94 FPUINT1 .equ FPUBASE+$4000 *FPU int. input address (R/O)95 FPUINT2 .equ FPUBASE+$6000 *FPU int. reset address (W/O)96 FPUCFG .equ FPUBASE+$5FE0 *FPU config. data address (W/O)97 * 98 F_CTL .equ $00 *control word99 F_VAL10 .equ $02 *new value "10"100 F_CV1 .equ $08 *control voltage 1101 F_SF1 .equ $0A *scale factor 1102 F_CV2 .equ $0C *control voltage 2103 F_SF2 .equ $0E *scale factor 2104 F_CV3 .equ $10 *control voltage 3105 F_SF3 .equ $12 *scale factor 3106 F_MNT .equ $14 *time mantissa107 F_EXP .equ $16 *time exponent108 F_VAL01 .equ $1C *new value "01"109 * 110 P_FREQ1 .equ $0020 *frequency 1111 P_FREQ2 .equ $0060 *frequency 2112 P_FREQ3 .equ $00A0 *frequency 3113 P_FREQ4 .equ $00E0 *frequency 4114 P_FILTER .equ $0140 *filter115 P_FILTRQ .equ $00C0 *filter q116 * 117 P_INDEX1 .equ $0120 *index 1118 P_INDEX2 .equ $0160 *index 2119 P_INDEX3 .equ $0180 *index 3120 P_INDEX4 .equ $01A0 *index 4121 P_INDEX5 .equ $01C0 *index 5122 P_INDEX6 .equ $01E0 *index 6123 * 124 P_LEVEL .equ $0040 *level125 * 126 P_LOCN .equ $0080 *location127 P_DYNAM .equ $0100 *dynamics128 * 129 .page 130 *------------------------------------------------------------------------------131 *Structure definitions132 *------------------------------------------------------------------------------133 *The following MUST match the idfnhdr structure definition in instdsp.h:134 * 135 FH_LEN .equ 12 *length of the idfnhdr structure136 * 137 FH_PCH .equ 0 *WORD - pitch offset (freq1 only)138 FH_MLT .equ 2 *WORD - overall value multiplier139 FH_SRC .equ 4 *BYTE - overall value source140 FH_PIF .equ 5 *BYTE - # of points in the function141 FH_PT1 .equ 6 *BYTE - index of first point142 FH_TMD .equ 7 *BYTE - trigger mode / control bits143 FH_CPT .equ 8 *BYTE - current point144 FH_PRM .equ 9 *BYTE - misc. function parameter145 FH_TRG .equ 10 *WORD - trigger146 * 147 I_ACTIVE .equ 1 *'Active' bit number (in FH_TMD)148 * 149 MSK_CTL .equ $001C *mask for FPU hardware bits (in FH_TMD)150 * 151 *------------------------------------------------------------------------------152 *The following MUST match the instpnt structure definition in instdsp.h:153 * 154 PT_LEN .equ 12 *length of the instpnt structure155 * 156 PT_TIM .equ 0 *WORD - time (packed)157 PT_VAL .equ 2 *WORD - value158 PT_VMLT .equ 4 *WORD - value multiplier159 PT_VSRC .equ 6 *BYTE - value source160 PT_ACT .equ 7 *BYTE - action161 PT_PAR1 .equ 8 *BYTE - parameter 1162 PT_PAR2 .equ 9 *BYTE - parameter 2163 PT_PAR3 .equ 10 *BYTE - parameter 3164 PT_PAD .equ 11 *BYTE - padding for even boundary165 * 166 MSK_MNT .equ $FFF0 *mask for mantissa (in PT_TIM)167 MSK_EXP .equ $000F *mask for exponent (in PT_TIM)168 * 169 MAX_ACT .equ 7 *maximum action code value170 * 171 .page 172 * 173 *------------------------------------------------------------------------------174 *pflist definitions -- must match those in instdsp.h175 * 176 PF_NEXT .equ0177 PF_TRIG .equ4178 PF_FUNC .equ6179 PF_D1 .equ8180 PF_D2 .equ12181 PF_D4 .equ16182 PF_A1 .equ20183 PF_A2 .equ24184 PF_A3 .equ28185 *------------------------------------------------------------------------------186 *Source definitions -- must match those in 'smdefs.h'187 * 188 SM_RAND .equ 1 *random189 SM_PTCH .equ 5 *pitch190 SM_KPRS .equ 6 *key pressure191 SM_KVEL .equ 7 *key velocity192 SM_FREQ .equ 10 *frequency193 * 194 .page 195 *------------------------------------------------------------------------------196 *_fpuint() -- process FPU interrupts197 * 198 *void199 *fpuint();200 * 201 *Processes FPU interrupts. Must be the target of vector 26,202 *which is Autovector Interrupt level 2.203 * 204 *------------------------------------------------------------------------------205 * 206 _fpuint: movem.l d0-d5/a0-a3,-(a7) *preserve registers we use207 move.w FPUINT1,d0 *read FPU interrupt status208 andi.w # $00FF,d0 *mask out garbage in MS bits209 move.w d0,_fpuifnc *save for later use210 move.w _ndisp,d1 *get display number211 cmpi.w #11,d1 *see if we display212 bne nodisp *jump if not213 * 214 tst.w _scopef *...215 beq nodisp *...216 * 217 move.w d0,-(a7) *display value218 jsr _scope *...219 tst.w (a7)+ *...220 * 221 move.w _fpuifnc,d0 *get FPU status222 * 223 nodisp: move.w d0,d1 *save in d1 (becomes function offset)224 * 225 lsl.w #5,d1 *develop FPU function offset226 lea FPUFUNC,a3 *setup FPU function base address227 * 228 lsl.w #3,d0 *develop funcndx[] index229 lea _funcndx,a0 *setup funcndx[] base address230 * 231 tst.l 0(a0,d0.W) *see if function is defined232 bne fnok *jump if so233 * 234 move.w d1,d0 *get function offset in d0235 andi.w # $1E00,d0 *mask for voice number236 cmpi.w # $1800,d0 *see if it's a real voice (0..11)237 bge fpexit *don't send a kill if not a real voice238 * 239 move.w #FKILL,F_CTL(a3,d1.W) *kill the undefined function240 * 241 fpexit: clr.w FPUINT2 *reset the FPU interrupt latch242 movem.l (a7)+,d0-d5/a0-a3 *restore the registers243 rte *return to interrupted code244 * 245 .page 246 *------------------------------------------------------------------------------247 *set up to process active functions, stop ones that should be inactive248 *------------------------------------------------------------------------------249 fnok: movea.l 0(a0,d0.W),a1 *get pointer to function header250 movea.l 4(a0,d0.W),a2 *get pointer to point table251 btst #I_ACTIVE,FH_TMD(a1) *see if function is active252 bne doact *go process action if so253 * 254 *------------------------------------------------------------------------------255 *stop a function256 *------------------------------------------------------------------------------257 stopfn: move.b FH_TMD(a1),d0 *get function control bits258 andi.w #MSK_RNVB,d0 *mask for ratio / new new-value bit259 move.w d0,d3 *isolate new new-value bit260 add.w d3,d3 *... from function header261 andi.w #MSK_ONVB,d3 *... shift to old new-value bit262 or.w d3,d0 * ... and put new bit in old bit263 move.w d0,F_CTL(a3,d1.W) *stop the function264 bclr #I_ACTIVE,FH_TMD(a1) *reset the active bit265 bra fpexit *go restore registers and exit266 * 267 .page 268 *------------------------------------------------------------------------------269 *setup for and dispatch to the proper action handler270 *------------------------------------------------------------------------------271 doact: clr.w d2 *get current point index in d2272 move.b FH_CPT(a1),d2 *...273 lsl.w #2,d2 *multiply it by the length of a point274 move.w d2,d0 *... (fast multiply by PT_LEN = 12275 add.w d2,d2 *... via shift and add)276 add.w d0,d2 *...277 clr.w d4 *get jump point # into d4278 move.b PT_PAR1(a2,d2.W),d4 *...279 clr.w d3 *get action code in d3280 move.b PT_ACT(a2,d2.W),d3 *...281 cmpi.b #MAX_ACT,d3 *check against the limit282 bgt stopfn *stop things if it's a bad action code283 * 284 lsl.w #2,d3 *develop index to action dispatch table285 lea actab,a0 *get the address of the action handler286 movea.l 0(a0,d3.W),a0 *...287 * 288 *------------------------------------------------------------------------------289 *At this point we're ready to do the action associated with the point,290 *and the registers are set up, and will remain, as follows:291 * 292 *d1 FPU function index a1 function header base293 *d2 point table index a2 point table base294 *a3 FPU function base295 *d4 jump point number296 * 297 *d0, d3, d5, and a0 are used as scratch throughout the code.298 * 299 *------------------------------------------------------------------------------300 * 301 _fputrap: jmp (a0) *dispatch to action handler302 * 303 .page 304 *------------------------------------------------------------------------------305 *act0 -- AC_NULL -- no action306 *---- --------------------307 act0: move.b FH_PT1(a1),d0 *get first point number308 add.b FH_PIF(a1),d0 *add number of points in function309 subq.b #1,d0 *make it last point number310 cmp.b FH_CPT(a1),d0 *see if we're at the last point311 beq stopfn *stop function if so312 * 313 addq.b #1,FH_CPT(a1) *update function header for next point314 addi.w #PT_LEN,d2 *advance the point index315 * 316 *------------------------------------------------------------------------------317 *outseg -- output a segment318 *------ ----------------319 outseg: move.w PT_TIM(a2,d2.w),d3 *get packed time320 move.w d3,d0 *extract mantissa321 andi.w #MSK_MNT,d0 *...322 mulu _timemlt,d0 *multiply by panel time pot value323 lsr.l #8,d0 *... and scale it324 lsr.l #7,d0 *...325 move.w d0,F_MNT(a3,d1.W) *send mantissa to FPU326 andi.w #MSK_EXP,d3 *extract exponent code327 add.w d3,d3 *look up decoded exponent328 lea _expbit,a0 *... in expbit329 move.w 0(a0,d3.W),F_EXP(a3,d1.W) *send exponent to FPU330 move.w PT_VAL(a2,d2.W),d3 *get the function value331 * 332 *------------------------------------------------------------------------------333 *get the point source, if any334 *------------------------------------------------------------------------------335 tst.w PT_VMLT(a2,d2.W) *see if we have a point mlt.336 beq nosrc *don't do anything for zero337 * 338 clr.w d0 *get the source number339 move.b PT_VSRC(a2,d2.W),d0 *...340 beq nosrc *don't do anything for zero341 * 342 *------------------------------------------------------------------------------343 *SM_RAND -- random344 *------------------------------------------------------------------------------345 cmpi.w #SM_RAND,d0 *is this the random source ?346 bne srctyp0 *jump if not347 * 348 movem.l d1-d2/a0-a2,-(a7) *preserve registers around call349 move.w PT_VMLT(a2,d2.W),-(a7) *pass multiplier to xgetran()350 jsr _xgetran *call for a random number351 tst.w (a7)+ *clean up stack352 movem.l (a7)+,d1-d2/a0-a2 *restore registers353 move.w d0,d5 *put random value in the value register354 bra applym *go apply the multiplier355 * 356 .page 357 *------------------------------------------------------------------------------358 *SM_FREQ -- frequency359 *------------------------------------------------------------------------------360 srctyp0: cmpi.w #SM_FREQ,d0 *is this the frequency source ?361 bne srctyp1 *jump if not362 * 363 move.w (a1),d0 *get the pitch364 lsr.w #6,d0 *shift to a word index365 andi.w # $01FE,d0 *mask out extraneous bits366 lea _ptoftab,a0 *get entry from ptoftab[]367 move.w 0(a0,d0.W),d5 *...368 bra applym *go apply the multiplier369 * 370 *------------------------------------------------------------------------------371 *SM_PTCH -- pitch372 *------------------------------------------------------------------------------373 srctyp1: cmpi.w #SM_PTCH,d0 *is this the pitch source ?374 bne srctyp2 *jump if not375 * 376 move.w (a1),d5 *get the pitch as the value377 bra applym *go apply the multiplier378 * 379 *------------------------------------------------------------------------------380 *SM_KVEL -- velocity381 *------------------------------------------------------------------------------382 srctyp2: cmpi.w #SM_KVEL,d0 *is this the key velocity source ?383 bne srctyp3 *jump if not384 * 385 move.w FH_TRG(a1),d0 *get the trigger number386 add.w d0,d0 *... as a word index387 lea _veltab,a0 *... into veltab[]388 move.w 0(a0,d0.W),d5 *get the velocity from veltab[trg]389 bra applym *go apply the multiplier390 * 391 *------------------------------------------------------------------------------392 *SM_KPRS -- pressure393 *------------------------------------------------------------------------------394 srctyp3: cmpi.w #SM_KPRS,d0 *is this the key pressure source ?395 bne srctyp4 *jump if not (must be an analog input)396 * 397 move.w FH_TRG(a1),d0 *get the trigger number398 add.w d0,d0 *... as a word index399 lea _prstab,a0 *... into prstab[]400 move.w 0(a0,d0.W),d5 *get the pressure from prstab[trg]401 bra applym *go apply the multiplier402 * 403 .page 404 *------------------------------------------------------------------------------405 *all other sources come out of the valents[] array406 *------------------------------------------------------------------------------407 srctyp4: lea _vce2grp,a0 *point at vce2grp[]408 move.w _fpuifnc,d5 *get voice number in d5409 lsr.w #3,d5 *...410 andi.w # $001E,d5 *... as a word index411 move.w 0(a0,d5.W),d5 *get the group number412 subq.w #1,d5 *...413 lsl.w #4,d5 *shift it left a nybble414 or.w d5,d0 *OR it into the source number415 add.w d0,d0 *make source number a valents[] index416 move.w d0,d5 *... (fast multiply by VALLEN = 10417 lsl.w #2,d0 *... via shift and add)418 add.w d5,d0 *...419 lea _valents,a0 *get base of valents[]420 move.w VT_VAL(a0,d0.W),d5 *get value421 * 422 *------------------------------------------------------------------------------423 *apply the multiplier to the source, and add it to the function value424 *------------------------------------------------------------------------------425 applym: muls PT_VMLT(a2,d2.W),d5 *apply the multiplier426 asr.l #7,d5 *scale the result427 asr.l #8,d5 *...428 ext.l d3 *add the function value429 add.l d3,d5 *...430 cmpi.l #VALMAX,d5 *check for overflow431 ble srcmlt1 *jump if no overflow432 * 433 move.l #VALMAX,d5 *limit at VALMAX434 bra srcmlt2 *...435 * 436 srcmlt1: cmpi.l #VALMIN,d5 *check for underflow437 bge srcmlt2 *jump if no underflow438 * 439 move.l #VALMIN,d5 *limit at VALMIN440 * 441 srcmlt2: move.w d5,d3 *setup value for output to FPU442 * 443 .page 444 *------------------------------------------------------------------------------445 *adjust the value according to the function type446 *------------------------------------------------------------------------------447 nosrc: move.w d1,d0 *get function type448 andi.w # $01E0,d0 *...449 * 450 *------------------------------------------------------------------------------451 *level or location452 *------------------------------------------------------------------------------453 cmpi.w #P_LEVEL,d0 *see if it's the level454 beq outsegl *jump if so455 * 456 cmpi.w #P_LOCN,d0 *see if it's the location457 bne outsegf *jump if not458 * 459 tst.w d3 *check sign of value460 bpl outsegc *jump if positive461 * 462 clr.w d3 *force negative values to 0463 * 464 outsegc: asr.w #5,d3 *shift value to LS bits465 sub.w #500,d3 *subtract 5.00 from value466 asl.w #6,d3 *readjust to MS bits467 bra outseg3 *go output the value468 * 469 outsegl: tst.w d3 *check sign of value470 bpl outsegm *jump if positive471 * 472 clr.w d3 *limit negative values at 0473 * 474 outsegm: asr.w #5,d3 *shift value to LS bits475 sub.w #500,d3 *subtract 5.00 from value476 asl.w #6,d3 *readjust to MS bits477 bra outseg3 *go output the value478 * 479 .page 480 *------------------------------------------------------------------------------481 *filter482 *------------------------------------------------------------------------------483 outsegf: cmpi.w #P_FILTER,d0 *see if it's filter484 bne outsegp *jump if not485 * 486 ext.l d3 *make function value a long487 asr.l #1,d3 *multiply function value by .75488 move.l d3,d0 *... (fast multiply by .75489 asr.l #1,d0 *... via shift and add)490 add.l d0,d3 *...491 move.w (a1),d0 *add pitch492 ext.l d0 *...493 add.l d0,d3 *...494 cmpi.l #VALMAX,d3 *see if it's within limits495 ble outsega *...496 * 497 move.w #VALMAX,d3 *limit at VALMAX498 bra outseg3 *...499 * 500 outsega: cmpi.l #VALMIN,d3 *...501 bge outseg3 *...502 * 503 move.w #VALMIN,d3 *limit at VALMIN504 bra outseg3 *...505 * 506 .page 507 *------------------------------------------------------------------------------508 *freq 1..4509 *------------------------------------------------------------------------------510 outsegp: cmpi.w #P_FREQ1,d0 *see if it's freq1511 beq outseg0 *go process freq1512 * 513 outsegq: cmpi.w #P_FREQ2,d0 *see if it's freq2514 beq outseg0 *process it if so515 * 516 cmpi.w #P_FREQ3,d0 *see if it's freq3517 beq outseg0 *process it if so518 * 519 cmpi.w #P_FREQ4,d0 *see if it's freq4520 bne outseg3 *jump if not521 * 522 outseg0: ext.l d3 *scale the point value to cents offset523 asr.l #5,d3 *...524 sub.l #500,d3 *... value - 500525 asl.l #LSPCH,d3 *mult. by 2 and scale for 1/2 cent lsb526 move.w (a1),d0 *add pitch from function header527 ext.l d0 *...528 add.l d0,d3 *...529 cmp.l #PCHMAX,d3 *see if result is valid530 ble outseg3 *jump if within pitch limits531 * 532 move.l #PCHMAX,d3 *limit at maximum pitch533 * 534 *------------------------------------------------------------------------------535 *send the value to the FPU536 *------------------------------------------------------------------------------537 outseg3: move.b FH_TMD(a1),d0 *get hardware bits from function header538 eor.w #VAL_BITS,d0 *toggle new value select bits539 move.b d0,FH_TMD(a1) *store updated word540 btst.l #VSUBNBIT,d0 *check which value address to use35 36 .page 37 | ------------------------------------------------------------------------------ 38 | Register usage 39 | -------------- 40 | d0 scratch 41 | d1 FPU function index 42 | d2 point index from FH_CPT (idfcpt) 43 | d3 scratch 44 | d4 jump point number from PT_PAR1 (ippar1) 45 | d5 scratch 46 47 | a0 scratch 48 | a1 function header base 49 | a2 point table base 50 | a3 FPU base 51 52 | ------------------------------------------------------------------------------ 53 | FPU definitions 54 | --------------- 55 56 UPD_BIT = 0x0001 | update bit (1 = update) 57 INT_BIT = 0x0002 | int. bit (0 = disable) 58 RAT_BIT = 0x0004 | ratio bit (0 = ratio) 59 60 VSUBNBIT = 3 | new value select bit number 61 VAL_BITS = 0x0018 | new value select bit mask 62 63 MSK_RNVB = 0x000C | new value / ratio bits 64 MSK_ONVB = 0x0010 | old new value bit 65 66 FKILL = 0x0014 | kill value for function 67 FSEND = 0x0015 | send new value to function 68 69 CLREXP = 0x8000 | clear value for time exponent 70 CLRMNT = 0x8000 | clear value for time mantissa 71 72 | ------------------------------------------------------------------------------ 73 | Miscellaneous definitions 74 | ------------------------- 75 76 PCHMAX = 21920 | maximum pitch value 77 VALMAX = 32000 | maximum value to send to FPU 78 VALMIN = -32000 | minimum value to send to FPU 79 80 LSPCH = 2 | left shift for sources to freq 81 82 VALLEN = 10 | length of the 'valent' struct 83 VT_VAL = 8 | value offset in 'valent' 84 85 .page 86 | ------------------------------------------------------------------------------ 87 | FPU addresses 88 | ------------- 89 90 FPUBASE = 0x180000 | FPU base address 91 92 FPUWST = FPUBASE | FPU waveshape base 93 FPUFUNC = FPUBASE+0x4000 | FPU function base 94 FPUINT1 = FPUBASE+0x4000 | FPU int. input address (R/O) 95 FPUINT2 = FPUBASE+0x6000 | FPU int. reset address (W/O) 96 FPUCFG = FPUBASE+0x5FE0 | FPU config. data address (W/O) 97 98 F_CTL = 0x00 | control word 99 F_VAL10 = 0x02 | new value "10" 100 F_CV1 = 0x08 | control voltage 1 101 F_SF1 = 0x0A | scale factor 1 102 F_CV2 = 0x0C | control voltage 2 103 F_SF2 = 0x0E | scale factor 2 104 F_CV3 = 0x10 | control voltage 3 105 F_SF3 = 0x12 | scale factor 3 106 F_MNT = 0x14 | time mantissa 107 F_EXP = 0x16 | time exponent 108 F_VAL01 = 0x1C | new value "01" 109 110 P_FREQ1 = 0x0020 | frequency 1 111 P_FREQ2 = 0x0060 | frequency 2 112 P_FREQ3 = 0x00A0 | frequency 3 113 P_FREQ4 = 0x00E0 | frequency 4 114 P_FILTER = 0x0140 | filter 115 P_FILTRQ = 0x00C0 | filter q 116 117 P_INDEX1 = 0x0120 | index 1 118 P_INDEX2 = 0x0160 | index 2 119 P_INDEX3 = 0x0180 | index 3 120 P_INDEX4 = 0x01A0 | index 4 121 P_INDEX5 = 0x01C0 | index 5 122 P_INDEX6 = 0x01E0 | index 6 123 124 P_LEVEL = 0x0040 | level 125 126 P_LOCN = 0x0080 | location 127 P_DYNAM = 0x0100 | dynamics 128 129 .page 130 | ------------------------------------------------------------------------------ 131 | Structure definitions 132 | ------------------------------------------------------------------------------ 133 | The following MUST match the idfnhdr structure definition in instdsp.h: 134 135 FH_LEN = 12 | length of the idfnhdr structure 136 137 FH_PCH = 0 | WORD - pitch offset (freq1 only) 138 FH_MLT = 2 | WORD - overall value multiplier 139 FH_SRC = 4 | BYTE - overall value source 140 FH_PIF = 5 | BYTE - # of points in the function 141 FH_PT1 = 6 | BYTE - index of first point 142 FH_TMD = 7 | BYTE - trigger mode / control bits 143 FH_CPT = 8 | BYTE - current point 144 FH_PRM = 9 | BYTE - misc. function parameter 145 FH_TRG = 10 | WORD - trigger 146 147 I_ACTIVE = 1 | 'Active' bit number (in FH_TMD) 148 149 MSK_CTL = 0x001C | mask for FPU hardware bits (in FH_TMD) 150 151 | ------------------------------------------------------------------------------ 152 | The following MUST match the instpnt structure definition in instdsp.h: 153 154 PT_LEN = 12 | length of the instpnt structure 155 156 PT_TIM = 0 | WORD - time (packed) 157 PT_VAL = 2 | WORD - value 158 PT_VMLT = 4 | WORD - value multiplier 159 PT_VSRC = 6 | BYTE - value source 160 PT_ACT = 7 | BYTE - action 161 PT_PAR1 = 8 | BYTE - parameter 1 162 PT_PAR2 = 9 | BYTE - parameter 2 163 PT_PAR3 = 10 | BYTE - parameter 3 164 PT_PAD = 11 | BYTE - padding for even boundary 165 166 MSK_MNT = 0xFFF0 | mask for mantissa (in PT_TIM) 167 MSK_EXP = 0x000F | mask for exponent (in PT_TIM) 168 169 MAX_ACT = 7 | maximum action code value 170 171 .page 172 173 | ------------------------------------------------------------------------------ 174 | pflist definitions -- must match those in instdsp.h 175 176 PF_NEXT = 0 177 PF_TRIG = 4 178 PF_FUNC = 6 179 PF_D1 = 8 180 PF_D2 = 12 181 PF_D4 = 16 182 PF_A1 = 20 183 PF_A2 = 24 184 PF_A3 = 28 185 | ------------------------------------------------------------------------------ 186 | Source definitions -- must match those in 'smdefs.h' 187 188 SM_RAND = 1 | random 189 SM_PTCH = 5 | pitch 190 SM_KPRS = 6 | key pressure 191 SM_KVEL = 7 | key velocity 192 SM_FREQ = 10 | frequency 193 194 .page 195 | ------------------------------------------------------------------------------ 196 | _fpuint() -- process FPU interrupts 197 198 | void 199 | fpuint(); 200 201 | Processes FPU interrupts. Must be the target of vector 26, 202 | which is Autovector Interrupt level 2. 203 204 | ------------------------------------------------------------------------------ 205 206 _fpuint: movem.l d0-d5/a0-a3,-(a7) | preserve registers we use 207 move.w FPUINT1,d0 | read FPU interrupt status 208 andi.w #0x00FF,d0 | mask out garbage in MS bits 209 move.w d0,_fpuifnc | save for later use 210 move.w _ndisp,d1 | get display number 211 cmpi.w #11,d1 | see if we display 212 bne nodisp | jump if not 213 214 tst.w _scopef | ... 215 beq nodisp | ... 216 217 move.w d0,-(a7) | display value 218 jsr _scope | ... 219 tst.w (a7)+ | ... 220 221 move.w _fpuifnc,d0 | get FPU status 222 223 nodisp: move.w d0,d1 | save in d1 (becomes function offset) 224 225 lsl.w #5,d1 | develop FPU function offset 226 lea FPUFUNC,a3 | setup FPU function base address 227 228 lsl.w #3,d0 | develop funcndx[] index 229 lea _funcndx,a0 | setup funcndx[] base address 230 231 tst.l 0(a0,d0.W) | see if function is defined 232 bne fnok | jump if so 233 234 move.w d1,d0 | get function offset in d0 235 andi.w #0x1E00,d0 | mask for voice number 236 cmpi.w #0x1800,d0 | see if it's a real voice (0..11) 237 bge fpexit | don't send a kill if not a real voice 238 239 move.w #FKILL,F_CTL(a3,d1.W) | kill the undefined function 240 241 fpexit: clr.w FPUINT2 | reset the FPU interrupt latch 242 movem.l (a7)+,d0-d5/a0-a3 | restore the registers 243 rte | return to interrupted code 244 245 .page 246 | ------------------------------------------------------------------------------ 247 | set up to process active functions, stop ones that should be inactive 248 | ------------------------------------------------------------------------------ 249 fnok: movea.l 0(a0,d0.W),a1 | get pointer to function header 250 movea.l 4(a0,d0.W),a2 | get pointer to point table 251 btst #I_ACTIVE,FH_TMD(a1) | see if function is active 252 bne doact | go process action if so 253 254 | ------------------------------------------------------------------------------ 255 | stop a function 256 | ------------------------------------------------------------------------------ 257 stopfn: move.b FH_TMD(a1),d0 | get function control bits 258 andi.w #MSK_RNVB,d0 | mask for ratio / new new-value bit 259 move.w d0,d3 | isolate new new-value bit 260 add.w d3,d3 | ... from function header 261 andi.w #MSK_ONVB,d3 | ... shift to old new-value bit 262 or.w d3,d0 | ... and put new bit in old bit 263 move.w d0,F_CTL(a3,d1.W) | stop the function 264 bclr #I_ACTIVE,FH_TMD(a1) | reset the active bit 265 bra fpexit | go restore registers and exit 266 267 .page 268 | ------------------------------------------------------------------------------ 269 | setup for and dispatch to the proper action handler 270 | ------------------------------------------------------------------------------ 271 doact: clr.w d2 | get current point index in d2 272 move.b FH_CPT(a1),d2 | ... 273 lsl.w #2,d2 | multiply it by the length of a point 274 move.w d2,d0 | ... (fast multiply by PT_LEN = 12 275 add.w d2,d2 | ... via shift and add) 276 add.w d0,d2 | ... 277 clr.w d4 | get jump point # into d4 278 move.b PT_PAR1(a2,d2.W),d4 | ... 279 clr.w d3 | get action code in d3 280 move.b PT_ACT(a2,d2.W),d3 | ... 281 cmpi.b #MAX_ACT,d3 | check against the limit 282 bgt stopfn | stop things if it's a bad action code 283 284 lsl.w #2,d3 | develop index to action dispatch table 285 lea actab,a0 | get the address of the action handler 286 movea.l 0(a0,d3.W),a0 | ... 287 288 | ------------------------------------------------------------------------------ 289 | At this point we're ready to do the action associated with the point, 290 | and the registers are set up, and will remain, as follows: 291 292 | d1 FPU function index a1 function header base 293 | d2 point table index a2 point table base 294 | a3 FPU function base 295 | d4 jump point number 296 297 | d0, d3, d5, and a0 are used as scratch throughout the code. 298 299 | ------------------------------------------------------------------------------ 300 301 _fputrap: jmp (a0) | dispatch to action handler 302 303 .page 304 | ------------------------------------------------------------------------------ 305 | act0 -- AC_NULL -- no action 306 | ---- -------------------- 307 act0: move.b FH_PT1(a1),d0 | get first point number 308 add.b FH_PIF(a1),d0 | add number of points in function 309 subq.b #1,d0 | make it last point number 310 cmp.b FH_CPT(a1),d0 | see if we're at the last point 311 beq stopfn | stop function if so 312 313 addq.b #1,FH_CPT(a1) | update function header for next point 314 addi.w #PT_LEN,d2 | advance the point index 315 316 | ------------------------------------------------------------------------------ 317 | outseg -- output a segment 318 | ------ ---------------- 319 outseg: move.w PT_TIM(a2,d2.w),d3 | get packed time 320 move.w d3,d0 | extract mantissa 321 andi.w #MSK_MNT,d0 | ... 322 mulu _timemlt,d0 | multiply by panel time pot value 323 lsr.l #8,d0 | ... and scale it 324 lsr.l #7,d0 | ... 325 move.w d0,F_MNT(a3,d1.W) | send mantissa to FPU 326 andi.w #MSK_EXP,d3 | extract exponent code 327 add.w d3,d3 | look up decoded exponent 328 lea _expbit,a0 | ... in expbit 329 move.w 0(a0,d3.W),F_EXP(a3,d1.W) | send exponent to FPU 330 move.w PT_VAL(a2,d2.W),d3 | get the function value 331 332 | ------------------------------------------------------------------------------ 333 | get the point source, if any 334 | ------------------------------------------------------------------------------ 335 tst.w PT_VMLT(a2,d2.W) | see if we have a point mlt. 336 beq nosrc | don't do anything for zero 337 338 clr.w d0 | get the source number 339 move.b PT_VSRC(a2,d2.W),d0 | ... 340 beq nosrc | don't do anything for zero 341 342 | ------------------------------------------------------------------------------ 343 | SM_RAND -- random 344 | ------------------------------------------------------------------------------ 345 cmpi.w #SM_RAND,d0 | is this the random source ? 346 bne srctyp0 | jump if not 347 348 movem.l d1-d2/a0-a2,-(a7) | preserve registers around call 349 move.w PT_VMLT(a2,d2.W),-(a7) | pass multiplier to xgetran() 350 jsr _xgetran | call for a random number 351 tst.w (a7)+ | clean up stack 352 movem.l (a7)+,d1-d2/a0-a2 | restore registers 353 move.w d0,d5 | put random value in the value register 354 bra applym | go apply the multiplier 355 356 .page 357 | ------------------------------------------------------------------------------ 358 | SM_FREQ -- frequency 359 | ------------------------------------------------------------------------------ 360 srctyp0: cmpi.w #SM_FREQ,d0 | is this the frequency source ? 361 bne srctyp1 | jump if not 362 363 move.w (a1),d0 | get the pitch 364 lsr.w #6,d0 | shift to a word index 365 andi.w #0x01FE,d0 | mask out extraneous bits 366 lea _ptoftab,a0 | get entry from ptoftab[] 367 move.w 0(a0,d0.W),d5 | ... 368 bra applym | go apply the multiplier 369 370 | ------------------------------------------------------------------------------ 371 | SM_PTCH -- pitch 372 | ------------------------------------------------------------------------------ 373 srctyp1: cmpi.w #SM_PTCH,d0 | is this the pitch source ? 374 bne srctyp2 | jump if not 375 376 move.w (a1),d5 | get the pitch as the value 377 bra applym | go apply the multiplier 378 379 | ------------------------------------------------------------------------------ 380 | SM_KVEL -- velocity 381 | ------------------------------------------------------------------------------ 382 srctyp2: cmpi.w #SM_KVEL,d0 | is this the key velocity source ? 383 bne srctyp3 | jump if not 384 385 move.w FH_TRG(a1),d0 | get the trigger number 386 add.w d0,d0 | ... as a word index 387 lea _veltab,a0 | ... into veltab[] 388 move.w 0(a0,d0.W),d5 | get the velocity from veltab[trg] 389 bra applym | go apply the multiplier 390 391 | ------------------------------------------------------------------------------ 392 | SM_KPRS -- pressure 393 | ------------------------------------------------------------------------------ 394 srctyp3: cmpi.w #SM_KPRS,d0 | is this the key pressure source ? 395 bne srctyp4 | jump if not (must be an analog input) 396 397 move.w FH_TRG(a1),d0 | get the trigger number 398 add.w d0,d0 | ... as a word index 399 lea _prstab,a0 | ... into prstab[] 400 move.w 0(a0,d0.W),d5 | get the pressure from prstab[trg] 401 bra applym | go apply the multiplier 402 403 .page 404 | ------------------------------------------------------------------------------ 405 | all other sources come out of the valents[] array 406 | ------------------------------------------------------------------------------ 407 srctyp4: lea _vce2grp,a0 | point at vce2grp[] 408 move.w _fpuifnc,d5 | get voice number in d5 409 lsr.w #3,d5 | ... 410 andi.w #0x001E,d5 | ... as a word index 411 move.w 0(a0,d5.W),d5 | get the group number 412 subq.w #1,d5 | ... 413 lsl.w #4,d5 | shift it left a nybble 414 or.w d5,d0 | OR it into the source number 415 add.w d0,d0 | make source number a valents[] index 416 move.w d0,d5 | ... (fast multiply by VALLEN = 10 417 lsl.w #2,d0 | ... via shift and add) 418 add.w d5,d0 | ... 419 lea _valents,a0 | get base of valents[] 420 move.w VT_VAL(a0,d0.W),d5 | get value 421 422 | ------------------------------------------------------------------------------ 423 | apply the multiplier to the source, and add it to the function value 424 | ------------------------------------------------------------------------------ 425 applym: muls PT_VMLT(a2,d2.W),d5 | apply the multiplier 426 asr.l #7,d5 | scale the result 427 asr.l #8,d5 | ... 428 ext.l d3 | add the function value 429 add.l d3,d5 | ... 430 cmpi.l #VALMAX,d5 | check for overflow 431 ble srcmlt1 | jump if no overflow 432 433 move.l #VALMAX,d5 | limit at VALMAX 434 bra srcmlt2 | ... 435 436 srcmlt1: cmpi.l #VALMIN,d5 | check for underflow 437 bge srcmlt2 | jump if no underflow 438 439 move.l #VALMIN,d5 | limit at VALMIN 440 441 srcmlt2: move.w d5,d3 | setup value for output to FPU 442 443 .page 444 | ------------------------------------------------------------------------------ 445 | adjust the value according to the function type 446 | ------------------------------------------------------------------------------ 447 nosrc: move.w d1,d0 | get function type 448 andi.w #0x01E0,d0 | ... 449 450 | ------------------------------------------------------------------------------ 451 | level or location 452 | ------------------------------------------------------------------------------ 453 cmpi.w #P_LEVEL,d0 | see if it's the level 454 beq outsegl | jump if so 455 456 cmpi.w #P_LOCN,d0 | see if it's the location 457 bne outsegf | jump if not 458 459 tst.w d3 | check sign of value 460 bpl outsegc | jump if positive 461 462 clr.w d3 | force negative values to 0 463 464 outsegc: asr.w #5,d3 | shift value to LS bits 465 sub.w #500,d3 | subtract 5.00 from value 466 asl.w #6,d3 | readjust to MS bits 467 bra outseg3 | go output the value 468 469 outsegl: tst.w d3 | check sign of value 470 bpl outsegm | jump if positive 471 472 clr.w d3 | limit negative values at 0 473 474 outsegm: asr.w #5,d3 | shift value to LS bits 475 sub.w #500,d3 | subtract 5.00 from value 476 asl.w #6,d3 | readjust to MS bits 477 bra outseg3 | go output the value 478 479 .page 480 | ------------------------------------------------------------------------------ 481 | filter 482 | ------------------------------------------------------------------------------ 483 outsegf: cmpi.w #P_FILTER,d0 | see if it's filter 484 bne outsegp | jump if not 485 486 ext.l d3 | make function value a long 487 asr.l #1,d3 | multiply function value by .75 488 move.l d3,d0 | ... (fast multiply by .75 489 asr.l #1,d0 | ... via shift and add) 490 add.l d0,d3 | ... 491 move.w (a1),d0 | add pitch 492 ext.l d0 | ... 493 add.l d0,d3 | ... 494 cmpi.l #VALMAX,d3 | see if it's within limits 495 ble outsega | ... 496 497 move.w #VALMAX,d3 | limit at VALMAX 498 bra outseg3 | ... 499 500 outsega: cmpi.l #VALMIN,d3 | ... 501 bge outseg3 | ... 502 503 move.w #VALMIN,d3 | limit at VALMIN 504 bra outseg3 | ... 505 506 .page 507 | ------------------------------------------------------------------------------ 508 | freq 1..4 509 | ------------------------------------------------------------------------------ 510 outsegp: cmpi.w #P_FREQ1,d0 | see if it's freq1 511 beq outseg0 | go process freq1 512 513 outsegq: cmpi.w #P_FREQ2,d0 | see if it's freq2 514 beq outseg0 | process it if so 515 516 cmpi.w #P_FREQ3,d0 | see if it's freq3 517 beq outseg0 | process it if so 518 519 cmpi.w #P_FREQ4,d0 | see if it's freq4 520 bne outseg3 | jump if not 521 522 outseg0: ext.l d3 | scale the point value to cents offset 523 asr.l #5,d3 | ... 524 sub.l #500,d3 | ... value - 500 525 asl.l #LSPCH,d3 | mult. by 2 and scale for 1/2 cent lsb 526 move.w (a1),d0 | add pitch from function header 527 ext.l d0 | ... 528 add.l d0,d3 | ... 529 cmp.l #PCHMAX,d3 | see if result is valid 530 ble outseg3 | jump if within pitch limits 531 532 move.l #PCHMAX,d3 | limit at maximum pitch 533 534 | ------------------------------------------------------------------------------ 535 | send the value to the FPU 536 | ------------------------------------------------------------------------------ 537 outseg3: move.b FH_TMD(a1),d0 | get hardware bits from function header 538 eor.w #VAL_BITS,d0 | toggle new value select bits 539 move.b d0,FH_TMD(a1) | store updated word 540 btst.l #VSUBNBIT,d0 | check which value address to use 541 541 beq outseg1 542 * 543 move.w d3,F_VAL01(a3,d1.W) *send value to FPU542 543 move.w d3,F_VAL01(a3,d1.W) | send value to FPU 544 544 bra outseg2 545 * 546 outseg1: move.w d3,F_VAL10(a3,d1.W) *send value to FPU547 * 548 outseg2: andi.w #MSK_CTL,d0 *mask off software bits549 ori.w #UPD_BIT+INT_BIT,d0 *set the update & !lastseg bits550 move.w d0,F_CTL(a3,d1.W) *send control word to FPU551 bra fpexit *done -- exit552 * 553 .page 554 * 555 *------------------------------------------------------------------------------556 *act1 -- AC_SUST -- pause if key is down (sustain)557 *---- ------------------------------------------558 act1: move.w _fpuifnc,d0 *get voice as a word index559 lsr.w #3,d0 *...560 andi.w # $001E,d0 *...561 lea _vce2trg,a0 *point at voice to trigger table562 move.w 0(a0,d0.W),d0 *get trigger table entry into d0563 cmpi.w #-1,d0 *see if voice is free564 beq act0 *continue function if so565 * 566 btst #15,d0 *see if voice is held by a pedal567 bne act1a *sustain if so568 * 569 btst #14,d0 *see if voice is sustained by a pedal570 bne act1a *sustain if so571 * 572 lea _trgtab,a0 *point at trigger table573 tst.b 0(a0,d0.W) *check trigger status574 beq act0 *continue function if not active575 * 576 act1a: move.l _pfqhdr,d3 *see if any pflist entries remain577 beq act0 *continue if not (shouldn't happen!)578 * 579 move.b FH_PT1(a1),d0 *get first point number580 add.b FH_PIF(a1),d0 *add base to first point581 subq.b #1,d0 *make d0 last point number582 cmp.b FH_CPT(a1),d0 *check current point number583 beq stopfn *done if this is the last point584 * 585 addq.b #1,FH_CPT(a1) *update current point number586 addi.w #PT_LEN,d2 *advance the point index587 movea.l d3,a0 *acquire a new pflist entry588 move.l (a0),_pfqhdr *...589 move.l _pflist,(a0) *chain it to pflist590 move.l a0,_pflist *...591 move.w FH_TRG(a1),PF_TRIG(a0) *set trigger number in entry592 move.w _fpuifnc,PF_FUNC(a0) *set v/p word in entry593 movem.l d1-d2/d4/a1-a3,PF_D1(a0) *set registers in entry594 move.b FH_TMD(a1),d0 *stop the function595 andi.w #MSK_RNVB,d0 *...596 move.w d0,d3 *...597 add.w d3,d3 *...598 andi.w #MSK_ONVB,d3 *...599 or.w d3,d0 *...600 move.w d0,F_CTL(a3,d1.W) *...601 bra fpexit *exit602 * 603 .page 604 * 605 *------------------------------------------------------------------------------606 *act2 -- AC_ENBL -- stop if key is up607 *---- ----------------------------608 act2: move.w _fpuifnc,d0 *get voice as a word index609 lsr.w #3,d0 *...610 andi.w # $001E,d0 *...611 lea _vce2trg,a0 *check to see if voice is free612 move.w 0(a0,d0.W),d0 *...613 cmpi.w #-1,d0 *...614 beq stopfn *if so, stop the function615 * 616 btst #15,d0 *see if voice is held617 bne act0 *continue if so618 * 619 btst #14,d0 *...620 bne act0 *...621 * 622 lea _trgtab,a0 *check trigger table entry623 tst.b 0(a0,d0.W) *...624 bne act0 *if trigger is active, continue625 * 626 bra stopfn *if not, stop the function627 * 628 *------------------------------------------------------------------------------629 *act3 -- AC_JUMP -- unconditional jump630 *---- -----------------------------631 act3: cmp.b FH_PIF(a1),d4 *check jump point against limit632 bcc stopfn *stop function if jump point invalid633 * 634 clr.w d2 *get index of first point635 move.b FH_PT1(a1),d2 *...636 add.b d4,d2 *add jump point637 move.b d2,FH_CPT(a1) *make it the current point638 lsl.w #2,d2 *develop new point index in d2639 move.w d2,d0 *... (fast multiply by PT_LEN = 12640 add.w d2,d2 *... via shift and add)641 add.w d0,d2 *...642 bra outseg *output the segment643 * 644 .page 645 * 646 *------------------------------------------------------------------------------647 *act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times648 *---- ----------------------------------------------649 act4: tst.b PT_PAR3(a2,d2.W) *check counter650 bne act4a *jump if it's running651 * 652 move.b PT_PAR2(a2,d2.W),d0 *get parameter653 subi.w #90,d0 *put parameter in random range654 bmi act4b *treat as normal if < 90655 * 656 movem.l d1-d2/a0-a2,-(a7) *get ranged random number657 move.w d0,-(a7) *...658 jsr _irand *...659 tst.w (a7)+ *...660 movem.l (a7)+,d1-d2/a0-a2 *...661 move.b d0,PT_PAR3(a2,d2.w) *set counter662 beq act0 *next segment if cntr set to 0663 * 664 bra act3 *else jump to the point665 * 666 act4b: move.b PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W) *set counter667 beq act0 *next segment if cntr set to 0668 * 669 bra act3 *else jump to the point670 * 671 act4a: subq.b #1,PT_PAR3(a2,d2.W) *decrement counter672 beq act0 *next segment if cntr ran out673 * 674 bra act3 *jump if it's still non-zero675 * 676 *------------------------------------------------------------------------------677 *act5 -- AC_KYUP -- jump if key is up678 *---- ----------------------------679 act5: move.w _fpuifnc,d0 *get voice as a word index680 lsr.w #3,d0 *...681 andi.w # $001E,d0 *...682 lea _vce2trg,a0 *check to see if voice is free683 move.w 0(a0,d0.W),d0 *...684 cmpi.w #-1,d0 *...685 beq act3 *if so (inactive), do the jump686 * 687 btst #15,d0 *see if voice is held688 bne act0 *continue if so689 * 690 btst #14,d0 *...691 bne act0 *...692 * 693 lea _trgtab,a0 *check trigger table entry694 tst.b 0(a0,d0.W) *see if the trigger is active695 beq act3 *if not, do the jump696 * 697 bra act0 *if so, do next segment698 * 699 .page 700 * 701 *------------------------------------------------------------------------------702 *act6 -- AC_KYDN -- jump if key is down703 *---- ------------------------------704 act6: move.w _fpuifnc,d0 *get voice as a word index705 lsr.w #3,d0 *...706 andi.w # $001E,d0 *...707 lea _vce2trg,a0 *check to see if voice is free708 move.w 0(a0,d0.W),d0 *...709 cmpi.w #-1,d0 *...710 beq act0 *if so (inactive), continue711 * 712 btst #15,d0 *see if voice is held713 bne act3 *do jump if so714 * 715 btst #14,d0 *...716 bne act3 *...717 * 718 lea _trgtab,a0 *check trigger table entry719 tst.b 0(a0,d0.W) *see if the trigger is active720 bne act3 *if so, do the jump721 * 722 bra act0 *if not, do next segment723 * 724 *------------------------------------------------------------------------------725 *Test stub726 *---------727 act7: bra act0 *AC_HERE: treat act7 as AC_NULL728 * 729 .page 730 *------------------------------------------------------------------------------731 * 732 *_fpuclr -- clear the FPU733 *------- -------------734 * 735 *void736 *fpuclr()737 * 738 *Resets the FPU functions to their nominal values.739 * 740 *------------------------------------------------------------------------------741 * 742 _fpuclr: link a6,#0 *link stack frames743 move.w sr,-(a7) *save the interrupt level744 ori.w # $0700,sr *turn off interrupts745 * 746 lea FPUFUNC,a0 *point at the first function747 lea _fp_resv,a2 *point at reset value table748 move.w #11,d1 *set the outer loop count749 * 750 .page 751 *------------------------------------------------------------------------------752 *reset the 'spare' function for the voice753 *------------------------------------------------------------------------------754 clr0: move.w #CLREXP,F_EXP(a0) *set time exponent755 tst.l actab *delay756 tst.l actab *...757 move.w #CLRMNT,F_MNT(a0) *set time mantissa758 tst.l actab *delay759 tst.l actab *...760 * 761 move.w #0,F_SF3(a0) *set scale factor 3762 tst.l actab *delay763 tst.l actab *...764 move.w #0,F_CV3(a0) *set voltage 3765 tst.l actab *delay766 tst.l actab *...767 * 768 move.w #0,F_SF2(a0) *set scale factor 2769 tst.l actab *delay770 tst.l actab *...771 move.w #0,F_CV2(a0) *set voltage 2772 tst.l actab *delay773 tst.l actab *...774 * 775 move.w #0,F_SF1(a0) *set scale factor 1776 tst.l actab *delay777 tst.l actab *...778 move.w #0,F_CV1(a0) *set voltage 1779 tst.l actab *delay780 tst.l actab *...781 * 782 move.w (a2),F_VAL10(a0) *set value from variable table783 tst.l actab *delay784 tst.l actab *...785 move.w (a2)+,F_VAL01(a0) *...786 tst.l actab *delay787 tst.l actab *...788 move.w #FSEND,F_CTL(a0) *set control word789 tst.l actab *delay790 tst.l actab *...791 * 792 .page 793 adda.w # $0020,a0 *point at 2nd function794 lea fprescon,a1 *set reset constant pointer795 move.w #14,d0 *set inner loop count796 * 797 *------------------------------------------------------------------------------798 *reset the other functions for the voice799 *------------------------------------------------------------------------------800 clr1: move.w #CLREXP,F_EXP(a0) *set time exponent801 tst.l actab *delay802 tst.l actab *...803 move.w #CLRMNT,F_MNT(a0) *set time mantissa804 tst.l actab *delay805 tst.l actab *...806 * 807 move.w #0,F_SF3(a0) *set scale factor 3808 tst.l actab *delay809 tst.l actab *...810 move.w #0,F_CV3(a0) *set voltage 3811 tst.l actab *delay812 tst.l actab *...813 * 814 move.w #0,F_SF2(a0) *set scale factor 2815 tst.l actab *delay816 tst.l actab *...817 move.w #0,F_CV2(a0) *set voltage 2818 tst.l actab *delay819 tst.l actab *...820 * 821 move.w #0,F_SF1(a0) *set scale factor 1822 tst.l actab *delay823 tst.l actab *...824 move.w #0,F_CV1(a0) *set voltage 1825 tst.l actab *delay826 tst.l actab *...827 * 828 move.w (a1),F_VAL10(a0) *set value from constant table829 tst.l actab *delay830 tst.l actab *...831 move.w (a1)+,F_VAL01(a0) *...832 tst.l actab *delay833 tst.l actab *...834 move.w #FSEND,F_CTL(a0) *set control word835 tst.l actab *delay836 tst.l actab *...837 * 838 .page 839 *------------------------------------------------------------------------------840 *loop through reset for all of the voices and functions841 *------------------------------------------------------------------------------842 adda.w # $0020,a0 *point at next function843 dbra d0,clr1 *loop until all funcs. cleared844 * 845 dbra d1,clr0 *loop until all voices cleared846 *------------------------------------------------------------------------------847 *clear the FPU interrupt, and return848 *------------------------------------------------------------------------------849 move.w #0,FPUINT2 *clear FPU interrupt850 move.w (a7)+,sr *restore interrupts851 unlk a6 *unlink stack frames852 rts *return to caller853 * 854 .page 855 * 856 *_clrvce -- quiet a voice857 *------- -------------858 * 859 *void860 *clrvce(vce)861 *short vce;862 * 863 *Quiet the voice by resetting the FPU functions it uses.864 * 865 _clrvce: link a6,#0 *link stack frames866 move.w sr,-(a7) *save the interrupt level867 ori.w # $0700,sr *turn off interrupts868 * 869 lea FPUFUNC+ $20,a0 *point at the 2nd function870 move.w 8(a6),d0 *get voice number871 ext.l d0 *...872 lsl.l #8,d0 *shift into position873 add.l d0,d0 *...874 adda.l d0,a0 *add to function base875 lea fprescon,a1 *set reset constant pointer876 move.w #14,d0 *set inner loop count877 * 878 vclr1: move.l a0,d1 *see if we reset this function879 and.w # $01F0,d1 *...880 * 881 cmpi.w # $0100,d1 *dynamics ?882 beq vclr2 *skip it if so883 * 884 move.w #CLREXP,F_EXP(a0) *set time exponent885 tst.l actab *delay886 tst.l actab *...887 move.w #CLRMNT,F_MNT(a0) *set time mantissa888 tst.l actab *delay889 tst.l actab *...890 * 891 cmpi.w # $0020,d1 *freq 1 ?892 beq vclr3 *don't reset CV3 (fine tune)893 * 894 move.w #0,F_SF3(a0) *set scale factor 3895 tst.l actab *delay896 tst.l actab *...897 move.w #0,F_CV3(a0) *set voltage 3898 tst.l actab *delay899 tst.l actab *...900 * 901 vclr3: move.w #0,F_SF1(a0) *set scale factor 1902 tst.l actab *delay903 tst.l actab *...904 move.w #0,F_CV1(a0) *set voltage 1905 tst.l actab *delay906 tst.l actab *...907 * 908 .page 909 * 910 move.w (a1),F_VAL10(a0) *set value from constant table911 tst.l actab *delay912 tst.l actab *...913 move.w (a1),F_VAL01(a0) *...914 tst.l actab *delay915 tst.l actab *...916 move.w #FSEND,F_CTL(a0) *set control word917 tst.l actab *delay918 tst.l actab *...919 * 920 vclr2: adda.w #2,a1 *point at next function921 adda.w # $0020,a0 *922 dbra d0,vclr1 *loop until all funcs. cleared923 * 924 move.w (a7)+,sr *restore interrupts925 unlk a6 *unlink stack frames926 rts *return to caller927 * 928 .page 929 *------------------------------------------------------------------------------545 546 outseg1: move.w d3,F_VAL10(a3,d1.W) | send value to FPU 547 548 outseg2: andi.w #MSK_CTL,d0 | mask off software bits 549 ori.w #UPD_BIT+INT_BIT,d0 | set the update & !lastseg bits 550 move.w d0,F_CTL(a3,d1.W) | send control word to FPU 551 bra fpexit | done -- exit 552 553 .page 554 555 | ------------------------------------------------------------------------------ 556 | act1 -- AC_SUST -- pause if key is down (sustain) 557 | ---- ------------------------------------------ 558 act1: move.w _fpuifnc,d0 | get voice as a word index 559 lsr.w #3,d0 | ... 560 andi.w #0x001E,d0 | ... 561 lea _vce2trg,a0 | point at voice to trigger table 562 move.w 0(a0,d0.W),d0 | get trigger table entry into d0 563 cmpi.w #-1,d0 | see if voice is free 564 beq act0 | continue function if so 565 566 btst #15,d0 | see if voice is held by a pedal 567 bne act1a | sustain if so 568 569 btst #14,d0 | see if voice is sustained by a pedal 570 bne act1a | sustain if so 571 572 lea _trgtab,a0 | point at trigger table 573 tst.b 0(a0,d0.W) | check trigger status 574 beq act0 | continue function if not active 575 576 act1a: move.l _pfqhdr,d3 | see if any pflist entries remain 577 beq act0 | continue if not (shouldn't happen!) 578 579 move.b FH_PT1(a1),d0 | get first point number 580 add.b FH_PIF(a1),d0 | add base to first point 581 subq.b #1,d0 | make d0 last point number 582 cmp.b FH_CPT(a1),d0 | check current point number 583 beq stopfn | done if this is the last point 584 585 addq.b #1,FH_CPT(a1) | update current point number 586 addi.w #PT_LEN,d2 | advance the point index 587 movea.l d3,a0 | acquire a new pflist entry 588 move.l (a0),_pfqhdr | ... 589 move.l _pflist,(a0) | chain it to pflist 590 move.l a0,_pflist | ... 591 move.w FH_TRG(a1),PF_TRIG(a0) | set trigger number in entry 592 move.w _fpuifnc,PF_FUNC(a0) | set v/p word in entry 593 movem.l d1-d2/d4/a1-a3,PF_D1(a0) | set registers in entry 594 move.b FH_TMD(a1),d0 | stop the function 595 andi.w #MSK_RNVB,d0 | ... 596 move.w d0,d3 | ... 597 add.w d3,d3 | ... 598 andi.w #MSK_ONVB,d3 | ... 599 or.w d3,d0 | ... 600 move.w d0,F_CTL(a3,d1.W) | ... 601 bra fpexit | exit 602 603 .page 604 605 | ------------------------------------------------------------------------------ 606 | act2 -- AC_ENBL -- stop if key is up 607 | ---- ---------------------------- 608 act2: move.w _fpuifnc,d0 | get voice as a word index 609 lsr.w #3,d0 | ... 610 andi.w #0x001E,d0 | ... 611 lea _vce2trg,a0 | check to see if voice is free 612 move.w 0(a0,d0.W),d0 | ... 613 cmpi.w #-1,d0 | ... 614 beq stopfn | if so, stop the function 615 616 btst #15,d0 | see if voice is held 617 bne act0 | continue if so 618 619 btst #14,d0 | ... 620 bne act0 | ... 621 622 lea _trgtab,a0 | check trigger table entry 623 tst.b 0(a0,d0.W) | ... 624 bne act0 | if trigger is active, continue 625 626 bra stopfn | if not, stop the function 627 628 | ------------------------------------------------------------------------------ 629 | act3 -- AC_JUMP -- unconditional jump 630 | ---- ----------------------------- 631 act3: cmp.b FH_PIF(a1),d4 | check jump point against limit 632 bcc stopfn | stop function if jump point invalid 633 634 clr.w d2 | get index of first point 635 move.b FH_PT1(a1),d2 | ... 636 add.b d4,d2 | add jump point 637 move.b d2,FH_CPT(a1) | make it the current point 638 lsl.w #2,d2 | develop new point index in d2 639 move.w d2,d0 | ... (fast multiply by PT_LEN = 12 640 add.w d2,d2 | ... via shift and add) 641 add.w d0,d2 | ... 642 bra outseg | output the segment 643 644 .page 645 646 | ------------------------------------------------------------------------------ 647 | act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times 648 | ---- ---------------------------------------------- 649 act4: tst.b PT_PAR3(a2,d2.W) | check counter 650 bne act4a | jump if it's running 651 652 move.b PT_PAR2(a2,d2.W),d0 | get parameter 653 subi.w #90,d0 | put parameter in random range 654 bmi act4b | treat as normal if < 90 655 656 movem.l d1-d2/a0-a2,-(a7) | get ranged random number 657 move.w d0,-(a7) | ... 658 jsr _irand | ... 659 tst.w (a7)+ | ... 660 movem.l (a7)+,d1-d2/a0-a2 | ... 661 move.b d0,PT_PAR3(a2,d2.w) | set counter 662 beq act0 | next segment if cntr set to 0 663 664 bra act3 | else jump to the point 665 666 act4b: move.b PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W) | set counter 667 beq act0 | next segment if cntr set to 0 668 669 bra act3 | else jump to the point 670 671 act4a: subq.b #1,PT_PAR3(a2,d2.W) | decrement counter 672 beq act0 | next segment if cntr ran out 673 674 bra act3 | jump if it's still non-zero 675 676 | ------------------------------------------------------------------------------ 677 | act5 -- AC_KYUP -- jump if key is up 678 | ---- ---------------------------- 679 act5: move.w _fpuifnc,d0 | get voice as a word index 680 lsr.w #3,d0 | ... 681 andi.w #0x001E,d0 | ... 682 lea _vce2trg,a0 | check to see if voice is free 683 move.w 0(a0,d0.W),d0 | ... 684 cmpi.w #-1,d0 | ... 685 beq act3 | if so (inactive), do the jump 686 687 btst #15,d0 | see if voice is held 688 bne act0 | continue if so 689 690 btst #14,d0 | ... 691 bne act0 | ... 692 693 lea _trgtab,a0 | check trigger table entry 694 tst.b 0(a0,d0.W) | see if the trigger is active 695 beq act3 | if not, do the jump 696 697 bra act0 | if so, do next segment 698 699 .page 700 701 | ------------------------------------------------------------------------------ 702 | act6 -- AC_KYDN -- jump if key is down 703 | ---- ------------------------------ 704 act6: move.w _fpuifnc,d0 | get voice as a word index 705 lsr.w #3,d0 | ... 706 andi.w #0x001E,d0 | ... 707 lea _vce2trg,a0 | check to see if voice is free 708 move.w 0(a0,d0.W),d0 | ... 709 cmpi.w #-1,d0 | ... 710 beq act0 | if so (inactive), continue 711 712 btst #15,d0 | see if voice is held 713 bne act3 | do jump if so 714 715 btst #14,d0 | ... 716 bne act3 | ... 717 718 lea _trgtab,a0 | check trigger table entry 719 tst.b 0(a0,d0.W) | see if the trigger is active 720 bne act3 | if so, do the jump 721 722 bra act0 | if not, do next segment 723 724 | ------------------------------------------------------------------------------ 725 | Test stub 726 | --------- 727 act7: bra act0 | AC_HERE: treat act7 as AC_NULL 728 729 .page 730 | ------------------------------------------------------------------------------ 731 732 | _fpuclr -- clear the FPU 733 | ------- ------------- 734 735 | void 736 | fpuclr() 737 738 | Resets the FPU functions to their nominal values. 739 740 | ------------------------------------------------------------------------------ 741 742 _fpuclr: link a6,#0 | link stack frames 743 move.w sr,-(a7) | save the interrupt level 744 ori.w #0x0700,sr | turn off interrupts 745 746 lea FPUFUNC,a0 | point at the first function 747 lea _fp_resv,a2 | point at reset value table 748 move.w #11,d1 | set the outer loop count 749 750 .page 751 | ------------------------------------------------------------------------------ 752 | reset the 'spare' function for the voice 753 | ------------------------------------------------------------------------------ 754 clr0: move.w #CLREXP,F_EXP(a0) | set time exponent 755 tst.l actab | delay 756 tst.l actab | ... 757 move.w #CLRMNT,F_MNT(a0) | set time mantissa 758 tst.l actab | delay 759 tst.l actab | ... 760 761 move.w #0,F_SF3(a0) | set scale factor 3 762 tst.l actab | delay 763 tst.l actab | ... 764 move.w #0,F_CV3(a0) | set voltage 3 765 tst.l actab | delay 766 tst.l actab | ... 767 768 move.w #0,F_SF2(a0) | set scale factor 2 769 tst.l actab | delay 770 tst.l actab | ... 771 move.w #0,F_CV2(a0) | set voltage 2 772 tst.l actab | delay 773 tst.l actab | ... 774 775 move.w #0,F_SF1(a0) | set scale factor 1 776 tst.l actab | delay 777 tst.l actab | ... 778 move.w #0,F_CV1(a0) | set voltage 1 779 tst.l actab | delay 780 tst.l actab | ... 781 782 move.w (a2),F_VAL10(a0) | set value from variable table 783 tst.l actab | delay 784 tst.l actab | ... 785 move.w (a2)+,F_VAL01(a0) | ... 786 tst.l actab | delay 787 tst.l actab | ... 788 move.w #FSEND,F_CTL(a0) | set control word 789 tst.l actab | delay 790 tst.l actab | ... 791 792 .page 793 adda.w #0x0020,a0 | point at 2nd function 794 lea fprescon,a1 | set reset constant pointer 795 move.w #14,d0 | set inner loop count 796 797 | ------------------------------------------------------------------------------ 798 | reset the other functions for the voice 799 | ------------------------------------------------------------------------------ 800 clr1: move.w #CLREXP,F_EXP(a0) | set time exponent 801 tst.l actab | delay 802 tst.l actab | ... 803 move.w #CLRMNT,F_MNT(a0) | set time mantissa 804 tst.l actab | delay 805 tst.l actab | ... 806 807 move.w #0,F_SF3(a0) | set scale factor 3 808 tst.l actab | delay 809 tst.l actab | ... 810 move.w #0,F_CV3(a0) | set voltage 3 811 tst.l actab | delay 812 tst.l actab | ... 813 814 move.w #0,F_SF2(a0) | set scale factor 2 815 tst.l actab | delay 816 tst.l actab | ... 817 move.w #0,F_CV2(a0) | set voltage 2 818 tst.l actab | delay 819 tst.l actab | ... 820 821 move.w #0,F_SF1(a0) | set scale factor 1 822 tst.l actab | delay 823 tst.l actab | ... 824 move.w #0,F_CV1(a0) | set voltage 1 825 tst.l actab | delay 826 tst.l actab | ... 827 828 move.w (a1),F_VAL10(a0) | set value from constant table 829 tst.l actab | delay 830 tst.l actab | ... 831 move.w (a1)+,F_VAL01(a0) | ... 832 tst.l actab | delay 833 tst.l actab | ... 834 move.w #FSEND,F_CTL(a0) | set control word 835 tst.l actab | delay 836 tst.l actab | ... 837 838 .page 839 | ------------------------------------------------------------------------------ 840 | loop through reset for all of the voices and functions 841 | ------------------------------------------------------------------------------ 842 adda.w #0x0020,a0 | point at next function 843 dbra d0,clr1 | loop until all funcs. cleared 844 845 dbra d1,clr0 | loop until all voices cleared 846 | ------------------------------------------------------------------------------ 847 | clear the FPU interrupt, and return 848 | ------------------------------------------------------------------------------ 849 move.w #0,FPUINT2 | clear FPU interrupt 850 move.w (a7)+,sr | restore interrupts 851 unlk a6 | unlink stack frames 852 rts | return to caller 853 854 .page 855 856 | _clrvce -- quiet a voice 857 | ------- ------------- 858 859 | void 860 | clrvce(vce) 861 | short vce; 862 863 | Quiet the voice by resetting the FPU functions it uses. 864 865 _clrvce: link a6,#0 | link stack frames 866 move.w sr,-(a7) | save the interrupt level 867 ori.w #0x0700,sr | turn off interrupts 868 869 lea FPUFUNC+0x20,a0 | point at the 2nd function 870 move.w 8(a6),d0 | get voice number 871 ext.l d0 | ... 872 lsl.l #8,d0 | shift into position 873 add.l d0,d0 | ... 874 adda.l d0,a0 | add to function base 875 lea fprescon,a1 | set reset constant pointer 876 move.w #14,d0 | set inner loop count 877 878 vclr1: move.l a0,d1 | see if we reset this function 879 and.w #0x01F0,d1 | ... 880 881 cmpi.w #0x0100,d1 | dynamics ? 882 beq vclr2 | skip it if so 883 884 move.w #CLREXP,F_EXP(a0) | set time exponent 885 tst.l actab | delay 886 tst.l actab | ... 887 move.w #CLRMNT,F_MNT(a0) | set time mantissa 888 tst.l actab | delay 889 tst.l actab | ... 890 891 cmpi.w #0x0020,d1 | freq 1 ? 892 beq vclr3 | don't reset CV3 (fine tune) 893 894 move.w #0,F_SF3(a0) | set scale factor 3 895 tst.l actab | delay 896 tst.l actab | ... 897 move.w #0,F_CV3(a0) | set voltage 3 898 tst.l actab | delay 899 tst.l actab | ... 900 901 vclr3: move.w #0,F_SF1(a0) | set scale factor 1 902 tst.l actab | delay 903 tst.l actab | ... 904 move.w #0,F_CV1(a0) | set voltage 1 905 tst.l actab | delay 906 tst.l actab | ... 907 908 .page 909 910 move.w (a1),F_VAL10(a0) | set value from constant table 911 tst.l actab | delay 912 tst.l actab | ... 913 move.w (a1),F_VAL01(a0) | ... 914 tst.l actab | delay 915 tst.l actab | ... 916 move.w #FSEND,F_CTL(a0) | set control word 917 tst.l actab | delay 918 tst.l actab | ... 919 920 vclr2: adda.w #2,a1 | point at next function 921 adda.w #0x0020,a0 | 922 dbra d0,vclr1 | loop until all funcs. cleared 923 924 move.w (a7)+,sr | restore interrupts 925 unlk a6 | unlink stack frames 926 rts | return to caller 927 928 .page 929 | ------------------------------------------------------------------------------ 930 930 .data 931 *------------------------------------------------------------------------------932 * 933 *actab -- action code dispatch table934 *----- --------------------------935 actab: dc.l act0 *0 - AC_NULL: no action936 dc.l act1 *1 - AC_SUST: sustain937 dc.l act2 *2 - AC_ENBL: enable938 dc.l act3 *3 - AC_JUMP: unconditional jump939 dc.l act4 *4 - AC_LOOP: jump n times (loop)940 dc.l act5 *5 - AC_KYUP: jump if key up (enable jump)941 dc.l act6 *6 - AC_KYDN: jump if key down (sustain jump)942 dc.l act7 *7 - AC_HERE: here on key up943 * 944 *fprescon -- FPU reset constant table945 *-------- ------------------------946 fprescon: dc.w $0000 *frq 1 0.00947 dc.w $8300 *level -10.00948 dc.w $0000 *frq 2 0.00949 dc.w $0000 *locn 0.00950 dc.w $0000 *frq 3 0.00951 dc.w $0000 *reson 0.00952 dc.w $0000 *frq 4 0.00953 dc.w $7D00 *dyn +10.00954 dc.w $0000 *ind 1 0.00955 dc.w $3E80 *filt +5.00956 dc.w $0000 *ind 2 0.00957 dc.w $0000 *ind 3 0.00958 dc.w $0000 *ind 4 0.00959 dc.w $0000 *ind 5 0.00960 dc.w $0000 *ind 6 0.00961 * 962 *------------------------------------------------------------------------------931 | ------------------------------------------------------------------------------ 932 933 | actab -- action code dispatch table 934 | ----- -------------------------- 935 actab: dc.l act0 | 0 - AC_NULL: no action 936 dc.l act1 | 1 - AC_SUST: sustain 937 dc.l act2 | 2 - AC_ENBL: enable 938 dc.l act3 | 3 - AC_JUMP: unconditional jump 939 dc.l act4 | 4 - AC_LOOP: jump n times (loop) 940 dc.l act5 | 5 - AC_KYUP: jump if key up (enable jump) 941 dc.l act6 | 6 - AC_KYDN: jump if key down (sustain jump) 942 dc.l act7 | 7 - AC_HERE: here on key up 943 944 | fprescon -- FPU reset constant table 945 | -------- ------------------------ 946 fprescon: dc.w 0x0000 | frq 1 0.00 947 dc.w 0x8300 | level -10.00 948 dc.w 0x0000 | frq 2 0.00 949 dc.w 0x0000 | locn 0.00 950 dc.w 0x0000 | frq 3 0.00 951 dc.w 0x0000 | reson 0.00 952 dc.w 0x0000 | frq 4 0.00 953 dc.w 0x7D00 | dyn +10.00 954 dc.w 0x0000 | ind 1 0.00 955 dc.w 0x3E80 | filt +5.00 956 dc.w 0x0000 | ind 2 0.00 957 dc.w 0x0000 | ind 3 0.00 958 dc.w 0x0000 | ind 4 0.00 959 dc.w 0x0000 | ind 5 0.00 960 dc.w 0x0000 | ind 6 0.00 961 962 | ------------------------------------------------------------------------------ 963 963 .bss 964 *------------------------------------------------------------------------------965 * 966 _fp_resv: ds.w 12 *fpu spare function reset values967 _fpuifnc: ds.w 1 *interrupting function number from FPU968 * 964 | ------------------------------------------------------------------------------ 965 966 _fp_resv: ds.w 12 | fpu spare function reset values 967 _fpuifnc: ds.w 1 | interrupting function number from FPU 968 969 969 .end
Note:
See TracChangeset
for help on using the changeset viewer.