.FILE 'GSPSND.ASM' .TITLE 'GSP SOUND PROCESSOR VER. 1.0' ************************************************************************** * * * COPYRIGHT (C) 1988 WILLIAMS ELECTRONICS GAMES, INC. * * ALL RIGHTS RESERVED. * * * ************************************************************************** .WIDTH 132 .OPTION B,D,L,T .MNOLIST .INCLUDE "\VIDEO\SYS\SYS.INC" ;Z UNIT SYSTEM EQUATES .INCLUDE "\VIDEO\SYS\MACROS.HDR" ;MACROS DEFINITIONS ; .INCLUDE "MACROS.EQU" .INCLUDE "MPROC.EQU" .INCLUDE "\VIDEO\SYS\SND.EQU" .TEXT * *SOUND PROCESSOR MAKES SOUNDS FOR N-CHANNELS (CURRENTLY 4) *THE ROUTINE "SNDRES" MUST BE CALLED TO INITAILIZE SOUND BOARD *ALSO SCRATCHPAD RAM MUST BE INITIALIZED TO ZERO *THE ROUTINE "SNDPRC" MUST BE CALLED EVERY 16MSEC. IN THE MAIN PROGRAM LOOP *(THE SAME PLACE WHERE "PRCDSP" IS NORMALLY CALLED) *MAKING A SOUND: * *SOUND TABLE FORMAT * *SOUND DESCRIPTION= PRIORITY,TIME,SOUND CODE,(PRIORITY),(TIME),(SOUND CODE),0 *SOUND ENDS IN 0000. *PRIORITY WORD = 1111IENNPPPPPPPP; I=1=NON-INTERRUPTABLE, E=1=NON-INT BY EQUAL *NN=CHANNEL #(0-3); *PP=PRIORITY (00-FF), FF=HIGHEST. *TIME WORD =TTTT (0000-7FFF X 16MS). *SOUND WORD =8SSS SSS=SOUND CODE(000-FFF). *SOUND WORD =4SSS SSS=SOUND CODE (ZERO TIME SOUND CODE) *EXAMPLE 1: * * MOVI SND1,A0 ;LOAD ABSOLUTE ADDRESS OF SND1 IN A0 * CALLA ONESND ;MAKE ONE SND1 * *SND1: .WORD >F0FF,>0100,>8088,0 * *SND1 IS FOR CHANNEL=0, PRIORITY=FF (HIGHEST), TIME = 100H X 16MSEC. *SOUND CODE = 88H *SND1 WILL MAKE ONE SOUND 88H, AND NOT ALLOW IT TO BE INTERRUPTED *FOR 100H X 16MSEC., EXCEPT BY A SOUND OF EQUAL OR GREATER PRIORITY ON *CHANNEL 0 * * MOVI SND2,A0 ;LOAD SND2 ADDRESS * MOVK 3,A1 ;REPEAT IT 3 TIMES * CALLA SNDLD ;GO DO IT *SND2: .WORD >F311,>0020,>8044,>8044,0 * *SND2 IS ON CHANNEL 3, PRIORITY 11H. IT WILL MAKE ONE SOUND 44H, WAIT *20H X 16 MSEC., THEN MAKE ANOTHER SOUND 44H, WHICH CANNOT BE INTERRUPTED *FOR 20H X 16 MSEC., EXCEPT BY A SOUND OF EQUAL OR GREATER PRIORITY ON *CHANNEL 3 * *SINCE A1 IS LOADED WITH A REPEAT COUNT OF 3, THIS PROCESS WILL BE REPEATED *THREE TIMES. THE END RESULT WILL BE 6 SOUND 44H SEPERATED BY 20H X 16MSEC. * *NOTE: THE CHANNEL SPECIFIED BY "MUSICHAN" WILL CAUSE THE MUSIC SECTION OF * THE SOUND BOARD TO BE STROBED. * SNDPRI .SET 0 ;PRIORITY (00=LOWEST, FF=HIGHEST) SNDTIM .SET 010h ;TIMER 000-7FFF SNDTMR .SET 020h ;TIMER COUNTDOWN SNDST .SET 030h ;ADDRESS OF SOUND TABLE START SNDPTR .SET 050h ;POINTER TO SOUND TABLE DATA SNDREP .SET 070h ;REPEAT COUNT OF SOUND *NOTE: IF YOU CHANGE SNDSIZ, MAKE SURE ANY CODE THAT USES IT AS A DIVISOR * PERFORMS THE CORRECT OP. CURRENTLY IT IS A POWER OF 2 SO SRL IS USED. SNDSIZ .SET 080h NCHAN .SET 4 ;DECLARE CHANNEL NUMBER MUSICHAN .EQU 3 ;THIS CHANNEL IS FOR THE TUNES .BSS SNDSTR,NCHAN*SNDSIZ ;RESERVE STORAGE AREA * *MAKE ONE SOUND *A0=SOUND ADDRESS ONESND: MOVE A1,-*SP,L MOVK 1,A1 CALLR SNDLD MOVE *SP+,A1,L RETS * *SOUND LOADER *A0=SOUND ADDRESS, A1=REPEAT COUNT *SOUND DESCRIPTION= PRIORITY,TIME,SOUND CODE,(PRIORITY),(TIME),(SOUND CODE),0 *SOUND ENDS IN ZERO *PRIORITY WORD = 1111IENNPPPPPPPP; I=1=NON-INTERRUPTABLE, E=1=NON-INT BY EQUAL *NN=CHANNEL #(0-3); *PP=PRIORITY (00-FF), FF=HIGHEST. *TIME WORD =TTTT (0000-7FFF X 16MS). *SOUND WORD =8SSS SSS=SOUND CODE(000-FFF). *SOUND WORD =4SSS SSS=SOUND CODE (ZERO TIME SOUND CODE) SNDLD: MMTM SP,A0,A1,A2,A3,A4,A5 MOVE @SOUNDSUP,A4,W JRNZ SNDLDX ;SOMEBODY SAYS NO! MOVE *A0,A5 ;GET PRIORITY BYTE MOVE A5,A2 MOVI SNDSIZ,A3 SLL 22,A5 SRL 30,A5 ;EXTRACT CHANNEL BITS MPYU A5,A3 ADDI SNDSTR,A3 ;CALC RAM CHANNEL ADDRESS MOVE *A3(SNDPRI),A4 ;GET CURRENT PRIORITY BTST 11,A4 ;CURRENT SOUND NON-INTERRUPTABLE ? JRNE SNDLDX ;YES, CAN NEW SOUND MOVE A2,A5 ;EXTRACT PRIORITY SLL 24,A5 SRL 24,A5 SLL 24,A4 SRL 24,A4 CMP A5,A4 ;NEW ONE GREATER OR EQUAL? JRHI SNDLDX ;OLD ONE IS GREATER, FORGET NEW SOUND JRLO SNDLD1 ;NEW ONE IS GREATER, DO IT MOVE *A3(SNDPRI),A4 ;INTERRUPTABLE BY EQUAL? BTST 10,A4 JRNE SNDLDX ;NON-INTERRUPTABLE BY EQUAL, CAN NEW GUY SNDLD1: MOVE A0,A4 MOVE A3,A0 ;CHANNEL RAM ADDRESS MOVE A4,*A0(SNDPTR),L ;SETUP SOUND DATA POINTER (ROM) MOVE A4,*A0(SNDST),L ;SETUP SOUND START POINTER MOVE A1,*A0(SNDREP) ;REPEAT COUNT CALLR SNDUPD ;START SOUND GOING SNDLDX: MMFM SP,A0,A1,A2,A3,A4,A5 RETS * *SOUND PROCESSOR CALLED EVERY 16 MSEC. * SNDPRC: MOVI SNDSTR,A0 MOVK NCHAN,A1 SNDLP0: MOVE *A0(SNDTMR),A2 ;CHECK TIMER JREQ SNDPLP ;EQUAL, INACTIVE CHANNEL DEC A2 MOVE A2,*A0(SNDTMR) ;DEC TIME JRNE SNDPLP ;NO TIMEOUT CALLR SNDUPD ;UPDATE SOUND SNDPLP: ADDI SNDSIZ,A0 DSJS A1,SNDLP0 RETS * *UPDATE SOUND *A0=POINTER TO SOUND CHANNEL RAM * SNDUPD: SNDUP0: MOVE *A0(SNDPTR),A2,L ;GET POINTER TO ROM TABLE SNDUP1: MOVE *A2+,A3 ;GET NEXT ROM TABLE ENTRY JREQ SNDUP5 ;END OF SOUND *CHECK FOR PRIORITY CMPI ->1000,A3 JRLO SNDUP2 ;NOT PRIORITY CHANGE MOVE A3,*A0(SNDPRI) ;UPDATE PRIORITY JRUC SNDUP1 ;GO GET NEXT ONE *CHECK FOR SOUND CODE SNDUP2: CMPI 4000H,A3 JRLO SNDUP3 CMPI ->8000,A3 JRHS SNDUP2A MOVE A0,A5 SUBI SNDSTR,A5 SRL 7,A5 ;DIVIDE BY 128 CALLR SNDSND ;SEND SOUND CODE JRUC SNDUP1 ;GET THE NEXT ONE BOYS SNDUP2A: MOVE A0,A5 SUBI SNDSTR,A5 SRL 7,A5 ;DIVIDE BY 128 ************************************************************************** * * * MOVI SNDSIZ,A6 ;IF SNDSIZ IS NOT A POWER OF 2, * * DIVU A6,A5 ;USE DIVIDE TO CALCULATE SOUND CHANNEL # * * * ************************************************************************** CALLR SNDSND ;SEND SOUND CODE MOVE *A0(SNDTIM),*A0(SNDTMR) MOVE A2,*A0(SNDPTR),L ;STORE POINTER RETS *TIMER VALUE X 16MSEC. SNDUP3: MOVE A3,*A0(SNDTIM) MOVE A3,*A0(SNDTMR) JRUC SNDUP1 ;SET TIMER VALUE, AND GO GET NEXT *CHECK FOR REPEATERS SNDUP5: MOVE *A0(SNDREP),A3 ;CHECK REPEAT COUNT DEC A3 MOVE A3,*A0(SNDREP) JREQ SNDUP6 ;ALL OVER MOVE *A0(SNDST),*A0(SNDPTR) JRUC SNDUP0 ;START SOUND OVER *SOUND IS OVER CLEAR THE CHANNEL SNDUP6: CLR A2 MOVE A2,*A0(SNDPRI) ;CLEAR SOUND PRIORITY SNDUPX: RETS * *HARDWARE SOUND CALL *A3=SOUND CODE B0-B7 *A5=SOUND CHANNEL # * SNDSND: MMTM SP,A0,A3 MOVI 600,A0 ;SLOW DOWN FOR GRANNER & C0. SNDSND0: DSJS A0,SNDSND0 SLL 24,A3 SRL 24,A3 ;STRIP OFF BITS CMPI MUSICHAN,A5 JRNE SNDSND1 ADDI 0FD00H,A3 ;PULL MUSIC SECTION INTERRUPT JRUC SNDSND2 SNDSND1 ADDI 0FE00h,A3 ;PULL SOUND SECTION INTERRUPT SNDSND2 MOVE A3,@SOUND ;HIT SOUND MOVI 8,A0 SNDSND3 DSJS A0,SNDSND3 ;SLOW IT DOWN A BIT ORI 0FF00h,A3 ;PUT OUT 1'S MOVE A3,@SOUND MMFM SP,A0,A3 RETS * *RESET SOUND BOARD, FULL RESET, CHECKSUM DINGS AND ALL * SNDRES: MMTM SP,A0 MOVI 0FB00h,A0 ;HIT RESET BIT MOVE A0,@SOUND MOVI 6000,A0 ;WAIT FOR IT TO CATCH SNDRL: DSJS A0,SNDRL MOVI 0FFFFh,A0 ;LET IT GO MOVE A0,@SOUND MMFM SP,A0 RETS * *RESET SOUND BOARD, PARTIAL RESET, NO CHECKSUM DINGS * SNDRESP: MMTM SP,A0 MOVI 0FB00h,A0 ;HIT RESET BIT MOVE A0,@SOUND,W MOVI 6000,A0 ;WAIT FOR IT TO CATCH DSJS A0,$ MOVI 0FFFFh,A0 ;LET IT GO MOVE A0,@SOUND,W MOVI 0FE00H,A0 MOVE A0,@SOUND,W ;SUPRESS MUSIC SIDE CHECKSUMMER MOVK 8,A0 DSJS A0,$ MOVI 0FF00H,A0 MOVE A0,@SOUND,W MOVK 8,A0 DSJS A0,$ MOVI 0FD00H,A0 MOVE A0,@SOUND,W ;SUPRESS SOUND SIDE CHECKSUMMER MOVK 8,A0 DSJS A0,$ MOVI 0FF00H,A0 MOVE A0,@SOUND,W MMFM SP,A0 RETS ************************************************************************** * * * CKSNDPRI - CHECK SOUND CHANNEL FOR EXISTANCE OF A GIVEN SOUND PRIORITY * * A0 = CHANNEL # * * A1 = SOUND PRIORITY * * RETURNS: * * CARRY CLEAR = PRIORITY NOT ACTIVE * * CARRY SET = PRIORITY ACTIVE * * * ************************************************************************** CKSNDPRI MMTM SP,A0,A2 MOVI SNDSTR,A2 SLL 7,A0 ;CHANNEL x 128 ADD A2,A0 ;OFFSET TO CORRECT CHANNEL AREA MOVB *A0,A0 CMP A0,A1 JRNE CKSPRI1 ;BR = PRIORITY NOT ACTIVE SETC MMFM SP,A0,A2 RETS CKSPRI1 CLRC MMFM SP,A0,A2 RETS ************************************************************************** * * * QSNDRST - QUIET SOUND RESET, NO DIAGNOSTIC DONGERS * * * ************************************************************************** QSNDRST PUSH A0 CALLR SNDRES ;RESET THE BOARD MOVI DIGOFF,A0 ;PEND ON DIG SIDE CALLR ONESND MOVI HYAMOFF,A0 ;PEND ON YAM SIDE CALLR ONESND PULL A0 RETS *HUSH CALLS FOR EACH SOUND SIDE DIGOFF .WORD >F0FF|>800,>01,>8000,0 ;TURN SOUND SIDE OFF HYAMOFF .WORD >F3FF|>800,>01,>8000,0 ;MUSIC HARD OFF .END