Buffer EQU [BP + 8] N EQU [BP + 6] POLY4_SIZE EQU 0Fh POLY5_SIZE EQU 1Fh POLY9_SIZE EQU 1FFh data segment byte public 'data' assume DS:data extrn AUDC : byte extrn AUDV : byte extrn p5 : byte extrn outvol : byte extrn div_n_cnt : byte extrn div_n_max : byte extrn div31 : byte extrn p4 : byte extrn p9 : byte extrn bit4 : byte extrn bit5 : byte extrn bit9 : byte extrn samp_n_cnt : byte extrn samp_n_max : byte extrn ProcessSet : byte extrn ProcessJump0 : byte extrn ProcessJump1 : byte RepData1 DW 0 RepData2 DW 0 RepData3 DW 0 data ends code segment para public 'code' assume DS:data,CS:code public ProcessSound .486 ; ------------------------------------------------------ Ch0 macro _Bit8,_Bit4,_Bit2,_Bit1 local _IsOne,_NotPOLY5_SIZE,_NotPOLY9_SIZE,_NotPOLY4_SIZE,_True2,_GetOut CMP BYTE PTR div_n_cnt,1 JBE SHORT _IsOne DEC BYTE PTR div_n_cnt JMP _GetOut _IsOne: JNE SHORT _GetOut MOV BYTE PTR div_n_cnt,DL INC WORD PTR P5 CMP WORD PTR P5,POLY5_SIZE JNE SHORT _NotPOLY5_SIZE MOV WORD PTR P5,0 _NotPOLY5_SIZE: If _Bit2 ne 0 MOV SI,WORD PTR P5 If _Bit1 ne 0 TEST BYTE PTR Bit5[SI],AH JZ SHORT _GetOut else TEST BYTE PTR Div31[SI],AH JZ SHORT _GetOut endif endif If _Bit4 ne 0 OR BL,BL JZ SHORT _True2 SUB BL,BL JMP _GetOut else If _Bit8 ne 0 If (_Bit1 + _Bit2 + _Bit4) eq 0 INC WORD PTR P9 CMP WORD PTR P9,POLY9_SIZE JNE SHORT _NotPOLY9_SIZE MOV WORD PTR P9,0 _NotPOLY9_SIZE: MOV SI,WORD PTR P9 TEST BYTE PTR Bit9[SI],AH JNZ SHORT _True2 SUB BL,BL JMP _GetOut else MOV SI,WORD PTR P5 TEST BYTE PTR Bit5[SI],AH JNZ SHORT _True2 SUB BL,BL JMP _GetOut endif else INC WORD PTR P4 CMP WORD PTR P4,POLY4_SIZE JNE SHORT _NotPOLY4_SIZE MOV WORD PTR P4,0 _NotPOLY4_SIZE: MOV SI,WORD PTR P4 TEST BYTE PTR Bit4[SI],AH JNZ SHORT _True2 SUB BL,BL JMP _GetOut endif endif _True2: MOV BL,CL _GetOut: endm ; ------------------------------------------------------ Ch1 macro _Bit8,_Bit4,_Bit2,_Bit1 local _IsOneA,_NotPOLY5_SIZEA,_NotPOLY9_SIZEA,_NotPOLY4_SIZEA,_True2A,_GetOutA CMP BYTE PTR div_n_cnt[1],1 JBE SHORT _IsOneA DEC BYTE PTR div_n_cnt[1] JMP _GetOutA _IsOneA: JNE SHORT _GetOutA MOV BYTE PTR div_n_cnt[1],DH INC WORD PTR P5[2] CMP WORD PTR P5[2],POLY5_SIZE JNE SHORT _NotPOLY5_SIZEA MOV WORD PTR P5[2],0 _NotPOLY5_SIZEA: If _Bit2 ne 0 MOV SI,WORD PTR P5[2] If _Bit1 ne 0 TEST BYTE PTR Bit5[SI],AH JZ SHORT _GetOutA else TEST BYTE PTR Div31[SI],AH JZ SHORT _GetOutA endif endif If _Bit4 ne 0 OR BH,BH JZ SHORT _True2A SUB BH,BH JMP _GetOutA else If _Bit8 ne 0 If (_Bit1 + _Bit2 + _Bit4) eq 0 INC WORD PTR P9[2] CMP WORD PTR P9[2],POLY9_SIZE JNE SHORT _NotPOLY9_SIZEA MOV WORD PTR P9[2],0 _NotPOLY9_SIZEA: MOV SI,WORD PTR P9[2] TEST BYTE PTR Bit9[SI],AH JNZ SHORT _True2A SUB BH,BH JMP _GetOutA else MOV SI,WORD PTR P5[2] TEST BYTE PTR Bit5[SI],AH JNZ SHORT _True2A SUB BH,BH JMP _GetOutA endif else INC WORD PTR P4[2] CMP WORD PTR P4[2],POLY4_SIZE JNE SHORT _NotPOLY4_SIZEA MOV WORD PTR P4[2],0 _NotPOLY4_SIZEA: MOV SI,WORD PTR P4[2] TEST BYTE PTR Bit4[SI],AH JNZ SHORT _True2A SUB BH,BH JMP _GetOutA endif endif _True2A: MOV BH,CH _GetOutA: endm ; ------------------------------------------------------ align 16 ProcessSound proc far PUSH BP MOV BP,SP ; Fill jump tables TEST BYTE PTR ProcessSet,0FFh JNZ TableFilled MOV WORD PTR ProcessJump0[00h * 2],OFFSET C0_0000 MOV WORD PTR ProcessJump0[01h * 2],OFFSET C0_0001 MOV WORD PTR ProcessJump0[02h * 2],OFFSET C0_0010 MOV WORD PTR ProcessJump0[03h * 2],OFFSET C0_0011 MOV WORD PTR ProcessJump0[04h * 2],OFFSET C0_0100 MOV WORD PTR ProcessJump0[05h * 2],OFFSET C0_0101 MOV WORD PTR ProcessJump0[06h * 2],OFFSET C0_0110 MOV WORD PTR ProcessJump0[07h * 2],OFFSET C0_0111 MOV WORD PTR ProcessJump0[08h * 2],OFFSET C0_1000 MOV WORD PTR ProcessJump0[09h * 2],OFFSET C0_1001 MOV WORD PTR ProcessJump0[0Ah * 2],OFFSET C0_1010 MOV WORD PTR ProcessJump0[0Bh * 2],OFFSET C0_1011 MOV WORD PTR ProcessJump0[0Ch * 2],OFFSET C0_1100 MOV WORD PTR ProcessJump0[0Dh * 2],OFFSET C0_1101 MOV WORD PTR ProcessJump0[0Eh * 2],OFFSET C0_1110 MOV WORD PTR ProcessJump0[0Fh * 2],OFFSET C0_1111 MOV WORD PTR ProcessJump1[00h * 2],OFFSET C1_0000 MOV WORD PTR ProcessJump1[01h * 2],OFFSET C1_0001 MOV WORD PTR ProcessJump1[02h * 2],OFFSET C1_0010 MOV WORD PTR ProcessJump1[03h * 2],OFFSET C1_0011 MOV WORD PTR ProcessJump1[04h * 2],OFFSET C1_0100 MOV WORD PTR ProcessJump1[05h * 2],OFFSET C1_0101 MOV WORD PTR ProcessJump1[06h * 2],OFFSET C1_0110 MOV WORD PTR ProcessJump1[07h * 2],OFFSET C1_0111 MOV WORD PTR ProcessJump1[08h * 2],OFFSET C1_1000 MOV WORD PTR ProcessJump1[09h * 2],OFFSET C1_1001 MOV WORD PTR ProcessJump1[0Ah * 2],OFFSET C1_1010 MOV WORD PTR ProcessJump1[0Bh * 2],OFFSET C1_1011 MOV WORD PTR ProcessJump1[0Ch * 2],OFFSET C1_1100 MOV WORD PTR ProcessJump1[0Dh * 2],OFFSET C1_1101 MOV WORD PTR ProcessJump1[0Eh * 2],OFFSET C1_1110 MOV WORD PTR ProcessJump1[0Fh * 2],OFFSET C1_1111 MOV BYTE PTR ProcessSet,1 TableFilled: ; loop until the buffer is filled ; Self-modifying code MOV SI,WORD PTR AUDC ADD SI,SI AND SI,01Eh MOV SI,WORD PTR ProcessJump0[SI] ; MOV WORD PTR CS:[Rep1 - 2],SI MOV WORD PTR RepData1,SI MOV SI,WORD PTR AUDC[1] ADD SI,SI AND SI,01Eh MOV SI,WORD PTR ProcessJump1[SI] ; MOV WORD PTR CS:[Rep2 - 2],SI MOV WORD PTR RepData2,SI MOV SI,WORD PTR Samp_N_Max ; MOV WORD PTR CS:[Rep3 - 2],SI MOV WORD PTR RepData3,SI ; MOV AL,128 ; MOV BX,WORD PTR AUDV ; SHR BL,1 ; SHR BH,1 ; SUB AL,BL ; SUB AL,BH ; MOV BYTE PTR CS:[Rep4 - 1],AL ; Load commonly-used values into registers MOV AH,0FFh MOV BX,WORD PTR OutVol MOV CX,WORD PTR AUDV MOV DX,WORD PTR Div_N_Max ; Start the loop LES DI,DWORD PTR Buffer CLD CMP WORD PTR N,0 JZ GetOut CheckN: ; Process channel 0 ; MOV SI,1212h ; Self-modified code MOV SI,WORD PTR RepData1 Rep1: JMP SI C0_0000: Ch0 0 0 0 0 JMP Channel1 C0_0001: Ch0 0 0 0 1 JMP Channel1 C0_0010: Ch0 0 0 1 0 JMP Channel1 C0_0011: Ch0 0 0 1 1 JMP Channel1 C0_0100: Ch0 0 1 0 0 JMP Channel1 C0_0101: Ch0 0 1 0 1 JMP Channel1 C0_0110: Ch0 0 1 1 0 JMP Channel1 C0_0111: Ch0 0 1 1 1 JMP Channel1 C0_1000: Ch0 1 0 0 0 JMP Channel1 C0_1001: Ch0 1 0 0 1 JMP Channel1 C0_1010: Ch0 1 0 1 0 JMP Channel1 C0_1011: Ch0 1 0 1 1 JMP Channel1 C0_1100: Ch0 1 1 0 0 JMP Channel1 C0_1101: Ch0 1 1 0 1 JMP Channel1 C0_1110: Ch0 1 1 1 0 JMP Channel1 C0_1111: Ch0 1 1 1 1 ; ------------------------------------------------------ Channel1: ; MOV SI,1212h ; Self-modified code MOV SI,WORD PTR RepData2 Rep2: JMP SI C1_0000: Ch1 0 0 0 0 JMP Next C1_0001: Ch1 0 0 0 1 JMP Next C1_0010: Ch1 0 0 1 0 JMP Next C1_0011: Ch1 0 0 1 1 JMP Next C1_0100: Ch1 0 1 0 0 JMP Next C1_0101: Ch1 0 1 0 1 JMP Next C1_0110: Ch1 0 1 1 0 JMP Next C1_0111: Ch1 0 1 1 1 JMP Next C1_1000: Ch1 1 0 0 0 JMP Next C1_1001: Ch1 1 0 0 1 JMP Next C1_1010: Ch1 1 0 1 0 JMP Next C1_1011: Ch1 1 0 1 1 JMP Next C1_1100: Ch1 1 1 0 0 JMP Next C1_1101: Ch1 1 1 0 1 JMP Next C1_1110: Ch1 1 1 1 0 JMP Next C1_1111: Ch1 1 1 1 1 ; ------------------------------------------------------ Next: DEC BYTE PTR Samp_N_Cnt[1] JNZ CheckN ; ADD WORD PTR Samp_N_Cnt,1212h ; Self-modified code MOV SI,WORD PTR RepData3 ADD WORD PTR Samp_N_Cnt,SI Rep3: MOV AL,BL ADD AL,BH ; OV0 := OutVol_0 - (_audv0 Div 2); ; OV1 := OutVol_1 - (_audv1 Div 2); ; _OutVol := (OV0 + OV1) + 128; ; ADD AL,12h ; Self-modified code ;Rep4: STOSB DEC WORD PTR N JNZ CheckN ; ------------------------------------------------------ GetOut: MOV WORD PTR OutVol,BX POP BP RET 6 ProcessSound endp code ends end