home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
apl
/
saplpc_b.arc
/
MUSIC.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-03-21
|
18KB
|
578 lines
; 1854339PC360:MUSIC:MUSIC.IPSA.ASM.60.31677. */
TITLE MUSIC MUSIC AUXILIARY PROCESSOR.
; IF SINGLE VOICE SQUARE WAVES CAN BE CALLED MUSIC.
DATA SEGMENT
;
INCLUDE APDEFNA.PCC
;
; VARIOUS HARDWARE-RELATED EQUATES.
;
SPKRGATE EQU 061H ; TIMER GATE ADDRESS
SPKRMODE EQU 043H ; TIMER MODE ADDRESS
SPKRSQU EQU 03H ; TIMER MODE OF SQUARE WAVE.
SPKRRATE EQU 042H ; COUNTER VALUE FOR TIMER.
TYPC EQU 4 ; SHARP APL CHARACTER TYPE.
;
;
; PERCMD FOR MUSIC AP.
;
MYCMD PERCMD <SVPON,0,0,0,0> ; COMMAND CODE.
;
; PERPCV FOR MUSIC AP.
;
PROCID EQU 440 ; MY PROCESSOR ID.
MYPCV PERPCV <PROCID,0,0,0,0,0,0>
; PROCESSOR ID,CLONEID,POSTCODES ; PROCESSOR ID
; IP:CS VALUE CLONEID
; STACK GETS SETUP LATER.
; DX:DS VALUE, BP VALUE.
;
; END OF PERPCV.
;
SVDAT DB (4000) DUP (0) ; LAST VALUE FROM APL.
;
MYSCV PERSCV <0,0,PROCID,0,0,0,0,0,0,MAXPSN>
; COUNT
; SCVSOS
; ID,NID
; AVLUE,CHRON,SCVPO,OTHER,NOTHR
; ID LENGTH,ANYID.
;
MYSCVL EQU $-MYSCV ; BYTE COUNT OF PERSCV
THEPSP DD 0 ; SI:CS OF PROGRAM SEGMENT PREFIX.
ASVDAT DD 0 ; MSADR OF SVDAT.
AMYSCV DD 0 ; MSADR OF MY PERSCV.
AMYCMD DD 0 ; MSADR OF MY PERCMD.
TICKINT EQU 4*01CH ; THE TIMER TICK INTERRUPT.
;
NOTETIME DB 0 ; NUMBER OF TICKS LEFT IN THIS NOTE.
NOTEINDEX DW 0 ; BYTE INDEX OF CURR NOTE IN SVDAT
NOTELIM DW 0 ; INDEX OF 1+LAST BYTE OF SVDAT
TICKWORK DB 0 ; WORK AT CLOCK TIME TIME.
TICKENAB EQU 01H ; ENABLE MUSIC.
TICKDEC EQU 02H ; DECREMENT REMAINING NOTE TIME.
; UNUSED 0FCH ; UNUSED BITS.
SHARING DB 0 ; DEGREE OF COUPLING.
PPI DW 0 ; THE PERPROC INDEX OF AP440.
VECTOR EQU 4 ; ORANK VALUE FOR VECTOR.
OKTEXT DB TYPC,0,0,VECTOR ; CHARACTER VECTOR RESULT.
DB 0,0,0,2 ; NUMBER OF CHARACTERS IN RESULT.
DB QO,QK,QBLANK,QBLANK ; THE RESULT.
OKTEXTZ EQU $
;
BADTEXT DB TYPC,0,0,VECTOR
DB 0,0,0,3
DB QB,QA,QD,QBLANK
BADTEXTZ EQU $
;
TXHIMSG DB 'SHARP APL Music Auxiliary Processor'
DB 0DH,0AH,'Copyright 1984 by I.P. Sharp Associates Limited.'
DB 0DH,0AH,24H
;
NOSVPMSG DB 'SVP NOT RUNNING.',0DH,0AH,24H
SVPFAILMSG DB 'SVP SIGNON FAILED',0DH,0AH,24H
;
DATA ENDS;
;
STAK SEGMENT STACK ; MUSIC'S STACK SEGMENT.
DB 300 DUP (0) ; MAYBE BIG ENOUGH.
STAK ENDS;
;
MUSIC SEGMENT BYTE PUBLIC
;
ASSUME CS:MUSIC,SS:STAK ; WE RUN ON LIMITED RESOURCES.
;
MYDS DW 0 ; DS VALUE DURING INTERRUPT RTN.
TICKNEXT DD 0 ; THE NEXT TIMER TICK INTERRUPT RTN.
;
MYTICKINT PROC NEAR
;
; THIS ROUTINE GETS CONTROL AT 18.2HZ, WHEN THE TIMER TICK INTERRUPT
; GOES OFF.
;
PUSH AX
PUSH BX
PUSH SI
PUSH DS
MOV DS,MYDS ; FIND OUR DATA.
ASSUME DS:DATA ; TELL THE ASSEMBLER ABOUT IT.
TEST TICKWORK,TICKDEC+TICKENAB ; ANY WORK TO DO?
JNZ DOWORK ; YES.
;
TICKZ: POP DS
POP SI
POP BX
POP AX
ASSUME DS:NOTHING
JMP TICKNEXT ; ON TO NEXT INTERRUPT GRABBER.
;
; WE HAVE SOMETHING USEFUL TO DO DURING THIS CLOCK TICK.
;
ASSUME DS:DATA ; TELL THE ASSEMBLER ABOUT IT.
DOWORK: TEST TICKWORK,TICKENAB ; CLOCK ENABLE TO DO?
JZ DOTICK ; NO. ASSUME DECREMENT ONLY.
AND TICKWORK,255-TICKENAB
CALL MON ; YES. ENABLE SPEAKER.
OR TICKWORK,TICKDEC ; START DECREMENTING.
;
DOTICK: TEST TICKWORK,TICKDEC ; DECREMENT NOTE TIME?
JZ TICKZ ; NO. WE'RE DONE.
;
; DECREMENT TIME REMAINING ON THIS NOTE.
;
DEC NOTETIME ; PICK UP TIME REMAINING ON NOTE.
JZ NEWNOTE ; EXPIRED. PICK UP NEXT NOTE.
JMP TICKZ
;
; NOTE TIME EXPIRED. PICK UP NEXT NOTE, IF ANY.
;
NEWNOTE: MOV AX,NOTEINDEX ; INCREMENT TO NEXT NOTE.
ADD AX,3
CMP AX,NOTELIM ; END OF ARRAY OF NOTES?
JNB NOTEZ ; YES
MOV NOTEINDEX,AX ; NO. GET NEXT NOTE.
MOV SI,AX
MOV AX,WORD PTR SVDAT[SI]; GET FREQUENCY OF NEXT NOTE.SORTA
XCHG AL,AH
OUT SPKRRATE,AL ; TELL FREQUNCY COUNTER ABOUT IT.
XCHG AL,AH
OUT SPKRRATE,AL
MOV AL,BYTE PTR SVDAT[SI+2] ; GET NOTE DURATION.
MOV NOTETIME,AL ; IN 18.2HZ UNITS.
JMP TICKZ ; WE IS DONE.
;
; END OF CURRENT MUSIC STRING.
;
NOTEZ: CALL MOFF ; DISABLE THE MUSIC.
MOV TICKWORK,0 ; NO MORE WORK TO DO.
;
; POST THE ROUND-ROBIN TASK SO IT CAN TELL APL WE'RE DONE WITH
; THIS STRING OF MUSIC.
;
MOV BX,PPI ; THE PERPROC INDEX OF THE AP.
MOV AX,PERPAP0 ; WHY WE'RE POSTING THE AP.
INT INTPOST
JMP TICKZ
;
MYTICKINT ENDP;
;
; FUNCTION TO TURN OFF MUSIC.
;
MOFF PROC NEAR
CLI ; AVOID RACE CONDITIONS.
IN AL,SPKRGATE
AND AL,0FDH ; DEGATE THE SPEAKER.
OUT SPKRGATE,AL
STI ; AVOID RACE CONDITIONS.
RET
MOFF ENDP
;
; FUNCTION TO TURN ON MUSIC.
;
MON PROC NEAR
CLI ; AVOID RACE CONDITIONS.
IN AL,SPKRGATE
OR AL,03H ; GATE THE SPEAKER.
OUT SPKRGATE,AL
STI ; AVOID RACE CONDITIONS.
RET
MON ENDP
ASSUME CS:NOTHING,DS:NOTHING ; END OF INTERRUPT HANDLER.
;
; THE FOLLOWING ROUTINES ARE CALLED WHEN WE ARE UNDER CONTROL
; OF THE TASK DISPATCHER.
;
ASSUME CS:MUSIC,DS:DATA,SS:STAK
;
; MESSAGE WRITER.
;
WRMSG PROC NEAR
; DS:[DX] IS 1ST BYTE $ (024H)TERMINATES
MOV AH,9 ;PRINT STRING.
INT 21H
RET
WRMSG ENDP
;
GOSVP PROC NEAR; ; INVOKE SVP.
MOV AX,WORD PTR AMYCMD
MOV BX,WORD PTR AMYCMD+2
INT INTSVP
RET ;
GOSVP ENDP ;
;
;
GRABTIMER PROC NEAR
;
; STEAL THE TIMER TICK INTERRUPT IN SUCH A MANNER THAT WE CAN GIVE
; IT BACK AT SHUTDOWN TIME.
;
XOR AX,AX
MOV ES,AX
CLI ; NO INTERRUPTS NOW,PLEASE.
MOV AX,WORD PTR ES:[TICKINT] ; OFFSET.
MOV WORD PTR TICKNEXT,AX
MOV AX,WORD PTR ES:[TICKINT+2];SEGMENT.
MOV WORD PTR TICKNEXT+2,AX ;WE'VE STOLEN IT.
MOV AX,OFFSET MYTICKINT ; MY TIMER TICK ROUTINE.
MOV WORD PTR ES:[TICKINT],AX
MOV AX,CS
MOV WORD PTR ES:[TICKINT+2],AX
STI
RET
GRABTIMER ENDP;
;
;
UNGRABTIMER PROC NEAR
;
; RESTORE THE TIMER TICK INTERRUPT AT SHUTDOWN TIME.
;
XOR AX,AX
MOV ES,AX
CLI ; NO INTERRUPTS NOW,PLEASE.
MOV AX,WORD PTR TICKNEXT;THE STOLEN VALUE.
MOV WORD PTR ES:[TICKINT],AX
MOV AX,WORD PTR TICKNEXT+2
MOV WORD PTR ES:[TICKINT+2],AX
STI
RET
UNGRABTIMER ENDP;
;
;
;
; FUNCTION TO TURN ES:SI INTO MSADR IN AX,BX IN JRGS FORMAT.
;
SEGTOMS PROC NEAR;
MOV AX,ES
XOR BX,BX
MOV CX,4
L1: SAL AX,1
RCL BX,1
LOOP L1
ADD AX,SI
ADC BX,0
; RESULT FORMAT IN AX,BX IS: 2 3 0 1
; THIS WILL STORE INTO MAINSTORE AS 3 2 1 0.
;
RET
SEGTOMS ENDP;
;
; THE FOLLOWING PROCEDURE IS CALLED WHEN THE AP DETECTS SOME SORT
; OF ERROR.
;
BEEP PROC NEAR
MOV AX,OFFSET BADTEXT
MOV BX,BADTEXTZ-BADTEXT
CALL GOREPLY
RET
BEEP ENDP
;
; THE FOLLOWING PROCEDURES ARE CALLED WHEN WE GET DISPATCHED, AND
; THE RELEVANT BIT SETTINGS IN THE PERPCV ARE ON.
;
;
; THIS FUNCTION GETS CONTROL WHEN WE OBSERVE A SET BY THE
; PARTNER.
;
GOSET PROC NEAR
; OTHER SIDE MAY HAVE SET. ATTEMPT TO OBTAIN A VALUE.
;
MOV MYCMD.PCCMD,SVPUIS
MOV AX,WORD PTR MYSCV.SCVPO
MOV WORD PTR MYCMD.PCP1,AX
MOV AX,WORD PTR MYSCV.SCVPO+2
MOV WORD PTR MYCMD.PCP1+2,AX
CALL GOSVP
;
AND AL,255-SVZNOS ;IGNORE SHARE VS OFFER.
CMP AL,SVZNE ; IS THERE A VALUE?
JE GETVAL ; YES.
NOGOT: CALL BEEP ; NO. STRANGE.
RET
;
GETVAL: CMP WORD PTR MYCMD.PCP2+2,0 ; IS VALUE VERY LARGE?
JE GETVAL1
CALL BEEP
GETVAL1: MOV WORD PTR MYCMD.PCP3+2,0
MOV AX,WORD PTR MYCMD.PCP2
CMP AX,LENGTH SVDAT
JNA GETVAL2
CALL BEEP
MOV AX,LENGTH SVDAT
GETVAL2: MOV WORD PTR MYCMD.PCP3,AX ; GET VALUE OF VARIABLE.
MOV MYCMD.PCCMD,SVPUDT
MOV AX,WORD PTR ASVDAT ; ADDRESS OF OUR BUFFER.
MOV WORD PTR MYCMD.PCP2,AX
MOV AX,WORD PTR ASVDAT+2
MOV WORD PTR MYCMD.PCP2+2,AX
CALL GOSVP
AND AL,255-SVZNOS
CMP AL,SVZNE
JNE NOGOT
;
; WE GOT THE VALUE INTO SVSTORE. CHECK THE VALUE, AND
; SETUP FOR PLAYING.
;
CMP BYTE PTR SVDAT+3,8 ;RANK MUST BE MATRIX.
JNE NOGOT
CMP BYTE PTR SVDAT,TYPC
JNE NOGOT
;
; THE NEW VALUE IS GOOD.
;
CALL MOFF
CLI
MOV AX,12-3 ; OFFSET OF FIRST DATA BYTE,
MOV NOTEINDEX,AX ; LESS PREINCREMENT.
MOV AX,WORD PTR SVDAT+6 ; BYTE COUNT.
OR AX,AX ; DID USER SET EMPTY ARRAY?
JZ GONONE ; YES. IGNORE THE SET.
XCHG AL,AH
ADD AX,12 ; PLUS OFFSET OF FIRST ELEMENT.
MOV NOTELIM,AX
MOV TICKWORK,TICKENAB ; ENABLE CLOCK AT NEXT TICK.
MOV NOTETIME,1 ; FORCE REFETCH ON NEXT TICK.
GONONE: STI ; ALLOW CLOCK TICKING.
RET
GOSET ENDP;
;
;
GOREPLY PROC NEAR
;
; THIS FUNCTION GETS CONTROL WHEN WE WISH TO SEND A REPLY
; TO OUR PARTNER.
;
; AX IS THE OFFSET OF THE REPLY.
; BX IS THE BYTE COUNT OF THE REPLY.
;
PUSH AX
PUSH BX
; INTERLOCK THE VARIABLE.
MOV MYCMD.PCCMD,SVPSIS
MOV AX,WORD PTR MYSCV.SCVPO
MOV WORD PTR MYCMD.PCP1,AX
MOV AX,WORD PTR MYSCV.SCVPO+2
MOV WORD PTR MYCMD.PCP1+2,AX
CALL GOSVP
;
MOV MYCMD.PCCMD,SVPSDT ; ASSUME WE HAVE VARIABLE NOW.
POP AX ; TRANSFER THE DATA.
MOV WORD PTR MYCMD.PCP3,AX ; BYTE COUNT.
XOR AX,AX
MOV WORD PTR MYCMD.PCP3+2,AX
POP SI ; OFFSET OF VALUE.
PUSH DS
POP ES
CALL SEGTOMS
MOV WORD PTR MYCMD.PCP2,AX
MOV WORD PTR MYCMD.PCP2+2,BX
CALL GOSVP
RET ; A SERIOUS USER WOULD CHECK FOR
; ERRORS IN THESE FUNCTIONS.
;
GOREPLY ENDP;
;
; THIS FUNCTION GETS CONTROL WHEN WE RECEIVE AN OFFER.
;
GOOFFER PROC NEAR
;
; FIRST OF ALL, IGNORE THE OFFER IF WE'RE ALREADY SHARING.
;
CMP SHARING,2
JE GOOFERZ
;
; WE'RE NOT SHARING. LET'S MAKE AN OFFER. CLEAR THE PERSCV.
;
MOV CX,MYSCVL
XOR AL,AL
PUSH DS
POP ES
MOV DI,OFFSET MYSCV
REP STOSB
MOV WORD PTR MYSCV.SCVID,PROCID ; REFRESH PROCID.
MOV BYTE PTR MYSCV.SCVNAMEL,MAXPSN ; LONGEST NAME LENGTH.
MOV MYCMD.PCCMD,SVPSVQ ;SCAN TO FIND THE OFFER
MOV BYTE PTR MYSCV.SCVNAME,0 ; ACCEPT ANY NAME.
MOV AX,WORD PTR AMYSCV
MOV WORD PTR MYCMD.PCP1,AX
MOV AX,WORD PTR AMYSCV+2
MOV WORD PTR MYCMD.PCP1+2,AX
CALL GOSVP
AND AL,0FEH ;IGNORE SVZNOS.
CMP AL,SVZNE
JNE GOOFNO ; COULDN'T FIND OFFER.
; FOUND OFFER. SHARE WITH IT.
MOV MYCMD.PCCMD,SVPSVO ; SHARE.
CALL GOSVP
MOV SHARING,2 ; WE'RE SHARING(MAYBE)
CMP AL,SVZNE
JE GOOFEROK ; SHARE WORKED. SEE IF WE GOT DATA.
GOOFNO: CALL BEEP ; SHARE FAILED. TELL SOMEONE.
; NO SHARE OBTAINED. RETRACT OUR OFFER.
GORETR: MOV MYCMD.PCCMD,SVPSVR
MOV AX,WORD PTR MYSCV.SCVPO
MOV WORD PTR MYCMD.PCP1,AX
MOV AX,WORD PTR MYSCV.SCVPO+2
MOV WORD PTR MYCMD.PCP1+2,AX
CALL GOSVP
MOV SHARING,0 ; WE'RE NOT SHARING.
GOOFERZ: RET
;
; SHARE WORKED. SEE IF A VALUE IS AVAILABLE.
;
GOOFEROK:CALL GOSET; SEE IF A VALUE IS AVAILABLE.
RET;
GOOFFER ENDP
;
; SHUTDOWN ROUTINE FOR MUSIC AP.
;
GOSHUT PROC NEAR
CALL UNGRABTIMER ; GIVE BACK TIMER TICK ROUTINE.
CALL MOFF ; STOP THE BUBBLE MACHINE.
RET ; AND RETURN TO THE TASK DISPATCHER.
GOSHUT ENDP
;
; THIS FUNCTION GETS CONTROL WHEN WE ARE POSTED BY THE TASK DISPATCHER
; AS THE RESULT OF A SHARED VARIABLE ARRIVING FROM APL, OR AT SHUTDOWN
; TIME.
;
PLAY PROC FAR
;
; WE'VE BEEN POSTED BY THE TASK DISPATCHER. FIND OUT WHY.
;
TEST MYPCV.PCVPOST,PERPSET ; OTHER SIDE DID A SET.
JZ NOTSET
CALL GOSET
;
NOTSET: TEST MYPCV.PCVPOST,PERPOFFR; SOMEONE OFFERED TO US.
JZ NOTOFFER
CALL GOOFFER
;
NOTOFFER:TEST MYPCV.PCVPOST,PERPRETR; OTHER SIDE RETRACTED.
JZ NOTRETR
CALL GORETR
;
;
NOTRETR: TEST MYPCV.PCVPOST,PERPSHUT
JZ NOTSHUT
CALL GOSHUT
;
; CHECK FOR POST BY TIMER INTERRUPT ROUTINE.
;
NOTSHUT: TEST MYPCV.PCVPOST,PERPAP0 ; END OF TUNE?
JZ PLAYZ ; NOPE.
MOV AX,OFFSET OKTEXT ; YES. TELL PARTNER WE'RE DONE.
MOV BX,OKTEXTZ-OKTEXT
CALL GOREPLY
;
; POSTED FOR OTHER REASON. WE'LL IGNORE IT.
;
PLAYZ: RET ; RETURN TO TASK DISPATCHER.
PLAY ENDP;
;
;
; MUSIC AP FOR SHARP APL/PC: ENTRY POINT.
;
MUSICEP PROC FAR
;
; SETUP DS
;
ASSUME DS:NOTHING
PUSH DS ;SAVE PSP ADDRESS.
MOV SI,DATA
MOV DS,SI
ASSUME DS:DATA
POP SI ; ADDRESS OF PSP.
MOV WORD PTR THEPSP,SI
MOV WORD PTR THEPSP+2,CS
;
; SETUP THE PERPCV ENTRY.
;
SPVAL EQU 320 ;SIZE OF STACK, USED HERE AND AT TASR
MOV WORD PTR MYPCV.PCVTSS+2,SS
MOV WORD PTR MYPCV.PCVTSS,SPVAL ;SPACE FOR STACK
MOV WORD PTR MYPCV.PCVTDS+2,DS
MOV WORD PTR MYPCV.PCVTCS+2,CS
MOV WORD PTR MYPCV.PCVTCS,OFFSET PLAY
;
; SETUP VARIOUS NUMBERS WE'LL NEED
; FROM TIME TO TIME.
;
MOV MYDS,DS
PUSH DS ;SETUP ADDRESSES OF PERCMD,PERSCV
POP ES
MOV SI,OFFSET MYCMD
CALL SEGTOMS
MOV WORD PTR AMYCMD,AX
MOV WORD PTR AMYCMD+2,BX
;
MOV SI,OFFSET SVDAT
CALL SEGTOMS
MOV WORD PTR ASVDAT,AX
MOV WORD PTR ASVDAT+2,BX
;
MOV SI,OFFSET MYSCV
CALL SEGTOMS
MOV WORD PTR AMYSCV,AX
MOV WORD PTR AMYSCV+2,BX
;
; ATTEMPT TO SIGNON TO THE SVP.
;
XOR AX,AX
MOV ES,AX
MOV AX,ES:WORD PTR[2+INTSVP*4]
OR AX,ES:WORD PTR[INTSVP*4];ASSUME SVP ISN'T IN SEGMENT 0.
JZ NOSVP ; NO SVP. TOO BAD.
;
; SVP APPEARS TO EXIST. ATTEMPT THE SIGNON.
;
; PASS ADDRESS OF PCV IN PCP1.
;
PUSH DS
POP ES
MOV SI,OFFSET MYPCV.PCVID
CALL SEGTOMS
MOV WORD PTR MYCMD.PCP1,AX
MOV WORD PTR MYCMD.PCP1+2,BX
;
; ATTEMPT SIGNON TO SVP.
;
CALL GOSVP
;
; IF THE SIGNON FAILED, FORGET IT.
;
CMP AX,SVZNE
JNE SVPFAIL
;
; SIGNON TO SVP WORKED.
;
MOV AX,MYCMD.PCP2 ;PRESERVE THE TASK IDENTIFIER.
MOV PPI,AX
CALL GRABTIMER ; START BORROWING TIMER INTERRUPTS.
MOV DX,OFFSET TXHIMSG ;POINT TO MESSAGE TEXT.
CALL WRMSG;
;
; NOW TERMINATE AND STAY RESIDENT.
;
MOV DX,SS
PUSH DS ;OUR DATA SEGMENT IS FIRST
POP AX
SUB DX,AX ;SS-DS
ADD DX,16 ;ROOM FOR PSP
MOV CL,4 ; TIMES 16
SHL DX,CL ;SPACE NEEDED AS BYTES
ADD DX,SPVAL ;SPACE FOR STACK
INT 27H
; NOW WE ONLY GET DISPATCHED BY SVP AND TASK DISPATCHER.
;
NOSVP: MOV DX,OFFSET NOSVPMSG
CALL WRMSG
JMP TERMINATE
;
SVPFAIL: MOV DX,OFFSET SVPFAILMSG
CALL WRMSG
TERMINATE: JMP THEPSP ; TERMINATE THIS AP.
;
MUSICEP ENDP
MUSIC ENDS;
END MUSICEP