Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 00000000 E94403 jmp RUN_FUNCTION
- 00000003 E95C03 jmp SONG_START
- 00000006 E9C603 jmp SONG_STOP
- 00000009 E9C303 jmp SONG_STOP
- 0000000C E9C003 jmp SONG_STOP
- 0000000F E9BD03 jmp SONG_STOP
- MIDI_DATA_SEGMENT
- 00000012 .word 0x22F6
- PITCH_TABLE
- 00000014 .word 344, 364, 386, 409, 433, 459, 486, 515, 546, 578
- .word 613, 649,1368,1388,1410,1433,1457,1483,1510,1539
- .word 1570,1602,1637,1673,2392,2412,2434,2457,2481,2507
- .word 2534,2563,2594,2626,2661,2697,3416,3436,3458,3481
- .word 3505,3531,3558,3587,3618,3650,3685,3721,4440,4460
- .word 4482,4505,4529,4555,4582,4611,4642,4674,4709,4745
- .word 5464,5484,5506,5529,5553,5579,5606,5635,5666,5698
- .word 5733,5769,6488,6508,6530,6553,6577,6603,6630,6659
- .word 6690,6722,6757,6793,7512,7532,7554,7577,7601,7627
- .word 7654,7683,7714,7746,7781,7817, 0
- LIST_OF_INITIAL_00_REGISTERS
- 000000D6 .byte 0x01,0x08,0xBD,0x20..0x25,0x28..0x2D,0x30..0x35
- .byte 0x40..0x45,0x48..0x4D,0x50..0x55
- .byte 0x60..0x65,0x68..0x6D,0x70..0x75
- .byte 0xA0..0xA8,0xB0..0xB8,0xC0..0xC8
- .byte 0xE0..0xE5,0xE8..0xED,0xF0..0xF5
- LIST_OF_INITIAL_3F_REGISTERS
- 0000013C .byte 0x80..0x8D, 0x90..0x95
- LSFR_VALUE
- 0000014E .word 0x563A
- PATCH_NUMBER_MAPPING_TO_INSTRUMENT_NUMBERS
- 00000150 .byte 0x00..0x14, 0x00...
- INSTRUMENT_POINTERS
- 00000187 .word 0x259,0x1EB,0x21D,0x1F5
- .word 0x1EB,0x1B9,0x209,0x1E1
- .word 0x1FF,0x1C3,0x26D,0x1AF
- .word 0x213,0x1CD,0x1D7,0x231
- .word 0x295,0x227,0x23B,0x1CD
- INSTRUMENT_DATA
- 000001AF B1 1C 61 1F 61 9D 92 1B 0E F4 ins 11
- 000001B9 F0 86 61 03 71 1F E3 2C 0A 00 ins 5
- 000001C3 30 15 D5 19 71 9B 61 1B 0C 00 ins 9
- 000001CD 07 4F F2 60 12 21 F2 72 08 F4 ins 13 & 19
- 000001D7 01 40 F4 53 08 64 F3 53 00 EE ins 14
- 000001E1 F2 4B 31 03 F4 21 53 2C 04 E8 ins 7
- 000001EB E4 8A FF 0F E1 A9 FF 0F 01 F4 ins 1
- 000001F5 01 4F F1 50 01 22 E4 7C 06 00 ins 3
- 000001FF E2 11 AE 8F 61 23 85 2A 0E 00 ins 8
- 00000209 B0 86 61 03 F3 1F E3 2C 08 00 ins 6
- 00000213 21 18 63 4C 21 A0 C5 0F 0C F4 ins 12
- 0000021D 10 07 FF 31 01 25 FF 04 0A 00 ins 2
- 00000227 62 00 F0 F5 0E 1F F6 F8 0E 00 ins 17 (percussion 0x26)
- 00000231 32 44 F8 FF 11 1F F5 7F 0E E2 ins 15
- 0000023B 4E 00 FC 05 0C 24 F9 F8 00 00 ins 18 (percussion 0x2A)
- 00000245 6E 00 75 05 01 22 F6 F8 0E 00 unused?
- 0000024F 31 90 F1 11 18 A5 D4 43 08 E8 unused?
- 00000259 E0 8D F4 1B E0 23 F3 18 0A 00 ins 0
- 00000263 E0 E8 AE 8F 61 21 85 0A 0E 00 unused?
- 0000026D 31 1C 41 0B 61 99 92 3B 0E F4 ins 10 (percussion 0x36)
- 00000277 F2 16 90 29 F2 22 61 2C 0A E8 unused?
- 00000281 E0 8D F4 2B E0 1F F3 48 08 00 unused?
- 0000028B 31 45 F3 23 33 25 43 9C 06 E8 unused?
- 00000295 00 00 A7 4C 00 22 C6 4F 00 00 ins 16 (percussion 0x24)
- 0000029F 00 00 A7 4C 00 2B C6 4F 00 E8 unused?
- 000002A9 04 00 F7 B5 0C unused?
- MODULATOR_REGISTER_INDEX_TABLE
- 000002AE .byte 00 01 02 08 09 0A 10 11 12
- CARRIER_REGISTER_INDEX_TABLE
- 000002B7 .byte 03 04 05 0B 0C 0D 13 14 15
- ADLIB_CHANNEL_IS_PLAYING_THIS_MIDI_CHANNEL
- 000002C0 .byte 1,2,3,4, -1,-1,-1,-1,-1 (LOADED FROM MIDI DATA AT OFFSET 0x22)
- ADLIB_CHANNEL_CURRENTLY_KEYED_ON
- 000002C9 .byte 1,1,1,1, 0,0,0,0,0
- ADLIB_CHANNEL_KEYED_ON_NOTENUMBER
- 000002D2 .byte 0x3C,0x4D,0x45,0x41, 0,0,0,0,0
- ADLIB_CHANNEL_CURRENT_FINETUNE_LEVEL
- 000002DB .byte -12,-12,-12,-12, 0,0,0,0,0
- ADLIB_CHANNEL_PLAYING_THIS_MIDI_PERCUSSION_NOTENUMBER
- 000002E4 .byte 0,0,0,0,0, 0x36,0x2A,0x24,0x26
- ADLIB_CHANNEL_PLAYING_THIS_ACTUAL_NOTENUMBER_FOR_PERCUSSION
- 000002ED .byte 0,0,0,0,0, 0x49,0x17,0x0C,0x01
- ADLIB_CHANNEL_PERCUSSION_PATCH_NUMBER
- 000002F6 .byte 0,0,0,0,0, 0x0A,0x12,0x10,0x11
- ADLIB_CHANNEL_REGISTER_43_VALUE
- 000002FF .byte 0xA9,0x99,0xA9,0xA9,0x00,0x00,0x00,0x00,0x00
- ADLIB_CHANNEL_REG_A0_PITCH_LOW_8_BITS
- 00000308 .byte 0x58,0xCB,0x42,0xCB,0x00,0x00,0x00,0x00,0x00
- ADLIB_CHANNEL_REG_B0_PITCH_HIGH_2_BITS_AND_KEYON_BITS
- 00000311 .byte 0x31,0x35,0x32,0x31,0x00,0x00,0x00,0x00,0x00
- ADLIB_CHANNEL_NOTE_AGE
- 0000031A .word 0x003A,0x000C,0x003A,0x003A,0x0000,0x0000,0x0000,0x0000,0x0000
- MIDI_SOURCE_POINTER
- 0000032C .word 0x0161 (LOADED FROM MIDI DATA AT OFFSET 0x00)
- MIDI_LOOPSTART_POINTER
- 0000032E .word 0x007D (LOADED FROM MIDI DATA AT OFFSET 0x00)
- MIDI_RUNNING_STATUS
- 00000330 .byte 0x90
- MIDI_CHANNEL_NUMBER
- 00000331 .byte 0x02
- MIDI_REMAINING_DELAY_COUNTER
- 00000332 .byte 7
- MIDI_COMMAND_WAS_UNRECOGNIZED
- 00000333 .byte 0
- MIDI_UNKNOWN_COMMAND_IS_TRIPLEBYTE
- 00000334 .byte 1
- MIDI_SONG_PLAYING_FLAG
- 00000335 .byte 0
- FUNCTION_PARAMETER_KEYON_BITS_FOR_REG_B0
- 00000336 .byte 0x20
- OLDEST_CHANNEL_POINTER
- 00000337 .word 0x0000
- FUNCTION_PARAMETER_PITCH_BEND_VALUE
- 00000339 .word 0x0000
- TEMPORARY
- 0000033B .byte 0x00
- UNKNOWN_BYTE_33C
- 0000033C .byte 0
- FUNCTION_TABLE
- 00000341 .word TIMER_CALLBACK, SONG_START, SONG_STOP
- RUN_FUNCTION
- AH = function number (0 = timer callback, 1 = start song, 2 = stop song)
- 0:
- 1: CX = segment number where song is located
- 2:
- 00000347 53 push bx
- 00000348 51 push cx
- 00000349 52 push dx
- 0000034A 57 push di
- 0000034B 56 push si
- 0000034C 1E push ds
- 0000034D 0E push cs
- 0000034E 1F pop ds
- 0000034F 8BF3 mov si,bx
- 00000351 32FF xor bh,bh
- 00000353 8ADC mov bl,ah
- 00000355 D0E3 shl bl,1
- 00000357 FF974103 call word near [bx+FUNCTION_TABLE]
- 0000035B 1F pop ds
- 0000035C 5E pop si
- 0000035D 5F pop di
- 0000035E 5A pop dx
- 0000035F 59 pop cx
- 00000360 5B pop bx
- 00000361 CB retf
- SONG_START
- 00000362 FA cli
- 00000363 890E1200 mov [MIDI_DATA_SEGMENT],cx
- 00000367 06 push es
- 00000368 8EC1 mov es,cx
- 0000036A 26A10000 mov ax,[es:0x0]
- 0000036E A32C03 mov [MIDI_SOURCE_POINTER],ax
- 00000371 A32E03 mov [MIDI_LOOPSTART_POINTER],ax
- 00000374 33FF xor di,di
- 00000376 268A4522 mov al,[es:di+0x22]
- 0000037A 8885C002 mov [di+ADLIB_CHANNEL_IS_PLAYING_THIS_MIDI_CHANNEL],al
- 0000037E 47 inc di
- 0000037F 83FF09 cmp di,byte +0x9
- 00000382 75F2 jnz 0x376
- 00000384 07 pop es
- 00000385 E89A04 call word RESET_ADLIB
- 00000388 33FF xor di,di
- 0000038A 8BDF mov bx,di
- 0000038C D1E3 shl bx,1 ; Initialize data
- 0000038E C685C90200 mov byte [di+ADLIB_CHANNEL_CURRENTLY_KEYED_ON],0x0
- 00000393 C685D20200 mov byte [di+ADLIB_CHANNEL_KEYED_ON_NOTENUMBER],0x0
- 00000398 C7871A030000 mov word [bx+ADLIB_CHANNEL_NOTE_AGE],0x0
- 0000039E 47 inc di
- 0000039F 83FF09 cmp di,byte +0x9 ; Loop for 9 AdLib channels
- 000003A2 75E6 jnz 0x38a
- 000003A4 33FF xor di,di
- 000003A6 80BDC00209 cmp byte [di+ADLIB_CHANNEL_IS_PLAYING_THIS_MIDI_CHANNEL],0x9
- 000003AB 750B jnz 0x3b8 ; Initialize percussion channels used in the song
- 000003AD 8A9DF602 mov bl,[di+ADLIB_CHANNEL_PERCUSSION_PATCH_NUMBER]
- 000003B1 8BCF mov cx,di
- 000003B3 57 push di
- 000003B4 E86903 call PROGRAM_PATCH
- 000003B7 5F pop di
- 000003B8 47 inc di
- 000003B9 83FF09 cmp di,byte +0x9 ; Loop for 9 AdLib channels
- 000003BC 75E8 jnz 0x3a6
- 000003BE C606320300 mov byte [MIDI_REMAINING_DELAY_COUNTER],0x0 ;Initialize rest of data
- 000003C3 C6063C0300 mov byte [UNKNOWN_BYTE_33C],0x0
- 000003C8 C606350301 mov byte [MIDI_SONG_PLAYING_FLAG],0x1
- 000003CD FB sti
- 000003CE C3 ret
- SONG_STOP
- 000003CF FA cli
- 000003D0 C606350300 mov byte [MIDI_SONG_PLAYING_FLAG],0x0
- 000003D5 E84A04 call word RESET_ADLIB
- 000003D8 FB sti
- 000003D9 C3 ret
- TIMER_CALLBACK
- 000003DA 803E350301 cmp byte [MIDI_SONG_PLAYING_FLAG],0x1
- 000003DF 7403 jz 0x3e4 ; Quit early if no song is playing
- 000003E1 E9F200 ret
- 000003E4 8E061200 mov es,[MIDI_DATA_SEGMENT]
- 000003E8 8B362C03 mov si,[MIDI_SOURCE_POINTER]
- 000003EC 33FF xor di,di
- 000003EE 8BDF mov bx,di
- 000003F0 D1E3 shl bx,1
- 000003F2 80BDC90201 cmp byte [di+ADLIB_CHANNEL_CURRENTLY_KEYED_ON],0x1
- 000003F7 7504 jne 0x3fd
- 000003F9 FF871A03 inc word [bx+ADLIB_CHANNEL_NOTE_AGE] ; Increment the age of all keyed-on channels
- 000003FD 47 inc di
- 000003FE 83FF09 cmp di,byte +0x9
- 00000401 75EB jnz 0x3ee
- 00000403 803E320300 cmp byte [MIDI_REMAINING_DELAY_COUNTER],0x0
- 00000408 7407 jz 0x411
- 0000040A FE0E3203 dec byte [MIDI_REMAINING_DELAY_COUNTER] ; Wait until delay is completed
- 0000040E E9C100 jmp SaveCurrentPointer
- LoadNextCommand
- 00000411 268A04 mov al,[es:si]
- 00000414 46 inc si
- 00000415 84C0 test al,al
- 00000417 7818 js 0x431
- 00000419 8A263003 mov ah,[MIDI_RUNNING_STATUS] ; Repeat last command if command < 0x80
- 0000041D 4E dec si
- 0000041E 803E330300 cmp byte [MIDI_COMMAND_WAS_UNRECOGNIZED],0x0 ; If repeated command was unrecognized, skip byte:
- 00000423 7425 jz 0x44a
- 00000425 46 inc si
- 00000426 803E340300 cmp byte [MIDI_UNKNOWN_COMMAND_IS_TRIPLEBYTE],0x0 ; If triplebyte, skip another byte
- 0000042B 7401 jz 0x42e
- 0000042D 46 inc si
- 0000042E E98E00 jmp LoadDelayValue ; Done skipping; jump to loading the delay byte.
- 00000431 3CFC cmp al,0xfc ; Command was >= 0x80. Identify it.
- 00000433 7503 jnz 0x438
- 00000435 E9C500 jmp HANDLE_FC_LOOP
- 00000438 8AE0 mov ah,al
- 0000043A 80E40F and ah,0xf
- 0000043D 88263103 mov [MIDI_CHANNEL_NUMBER],ah
- 00000441 8AE0 mov ah,al
- 00000443 80E4F0 and ah,0xf0
- 00000446 88263003 mov [MIDI_RUNNING_STATUS],ah
- 0000044A 80FCE0 cmp ah,0xe0 ; Lands here also if there was running status.
- 0000044D 753A jnz WasNotPitchBend
- HANDLE_E0_PITCHBEND
- 0000044F C606340301 mov byte [MIDI_UNKNOWN_COMMAND_IS_TRIPLEBYTE],0x1
- 00000454 268A14 mov dl,[es:si]
- 00000457 46 inc si
- 00000458 268A34 mov dh,[es:si]
- 0000045B 46 inc si
- 0000045C D0EE shr dh,1
- 0000045E 7303 jnc 0x463
- 00000460 80CA80 or dl,0x80
- 00000463 89163903 mov [FUNCTION_PARAMETER_PITCH_BEND_VALUE],dx ; Save pitch-bend value.
- 00000467 A03103 mov al,[MIDI_CHANNEL_NUMBER] ; Update all notes playing on this MIDI channel.
- 0000046A 33FF xor di,di
- 0000046C 3A85C002 cmp al,[di+ADLIB_CHANNEL_IS_PLAYING_THIS_MIDI_CHANNEL]
- 00000470 750E jnz 0x480
- 00000472 80BDC90201 cmp byte [di+ADLIB_CHANNEL_CURRENTLY_KEYED_ON],0x1
- 00000477 7507 jnz 0x480
- 00000479 8BCF mov cx,di
- 0000047B 57 push di
- 0000047C E84902 call RECALCULATE_PITCH_AND_WRITE
- 0000047F 5F pop di
- 00000480 47 inc di
- 00000481 83FF09 cmp di,byte +0x9 ; Loop for 9 AdLib channels.
- 00000484 75E6 jnz 0x46c
- 00000486 EB3790 jmp LoadDelayValue
- WasNotPitchBend
- 00000489 C606330300 mov byte [MIDI_COMMAND_WAS_UNRECOGNIZED],0x0
- 0000048E C606340301 mov byte [MIDI_UNKNOWN_COMMAND_IS_TRIPLEBYTE],0x1
- 00000493 80FCC0 cmp ah,0xc0
- 00000496 7508 jnz 0x4a0
- 00000498 C606340300 mov byte [MIDI_UNKNOWN_COMMAND_IS_TRIPLEBYTE],0x0 ; Command Cx is double-byte
- 0000049D EB3890 jmp HANDLE_C0_PATCHCHANGE
- 000004A0 80FC90 cmp ah,0x90
- 000004A3 7503 jnz 0x4a8
- 000004A5 EB6C90 jmp HANDLE_90_NOTEON
- 000004A8 80FC80 cmp ah,0x80
- 000004AB 7503 jnz 0x4b0
- 000004AD E92C01 jmp HANDLE_80_NOTEOFF
- 000004B0 46 inc si
- 000004B1 46 inc si
- 000004B2 C606340301 mov byte [MIDI_UNKNOWN_COMMAND_IS_TRIPLEBYTE],0x1 ; Assume unsupported command is triple-byte
- 000004B7 C606330301 mov byte [MIDI_COMMAND_WAS_UNRECOGNIZED],0x1
- 000004BC EB0190 jmp LoadDelayValue
- LoadDelayValue
- 000004BF 268A04 mov al,[es:si]
- 000004C2 46 inc si
- 000004C3 3C00 cmp al,0x0 ; If the delay is zero,
- 000004C5 7503 jnz 0x4ca ; process the next command immediately.
- 000004C7 E947FF jmp LoadNextCommand
- 000004CA FEC8 dec al
- 000004CC A23203 mov [MIDI_REMAINING_DELAY_COUNTER],al
- 000004CF EB0190 jmp SaveCurrentPointer
- SaveCurrentPointer
- 000004D2 89362C03 mov [MIDI_SOURCE_POINTER],si
- 000004D6 C3 ret
- HANDLE_C0_PATCHCHANGE
- 000004D7 33FF xor di,di
- 000004D9 33C9 xor cx,cx
- 000004DB 268A1C mov bl,[es:si]
- 000004DE 46 inc si
- 000004DF A03103 mov al,[MIDI_CHANNEL_NUMBER]
- 000004E2 3C09 cmp al,0x9
- 000004E4 740F jz 0x4f5 ; Ignore if MIDI channel is 9 (percussion)
- 000004E6 3A85C002 cmp al,[di+ADLIB_CHANNEL_IS_PLAYING_THIS_MIDI_CHANNEL]
- 000004EA 7509 jnz 0x4f5 ; Update patch on all AdLib channels that
- 000004EC 8BCF mov cx,di ; are dedicated for this MIDI channel
- 000004EE 57 push di
- 000004EF 53 push bx
- 000004F0 E82D02 call PROGRAM_PATCH
- 000004F3 5B pop bx
- 000004F4 5F pop di
- 000004F5 47 inc di
- 000004F6 83FF09 cmp di,byte +0x9 ; Loop for 9 AdLib channels
- 000004F9 75E4 jnz 0x4df
- 000004FB EBC2 jmp LoadDelayValue
- HANDLE_FC_LOOP
- 000004FD 268A04 mov al,[es:si]
- 00000500 46 inc si
- 00000501 3C80 cmp al,0x80
- 00000503 7407 jz 0x50c ; Terminate song if next byte is not 0x80
- 00000505 C606350300 mov byte [MIDI_SONG_PLAYING_FLAG],0x0
- 0000050A EBCA ret
- 0000050C 8B362E03 mov si,[MIDI_LOOPSTART_POINTER] ; Restart from beginning
- 00000510 E9FEFE jmp LoadNextCommand
- HANDLE_90_NOTEON
- 00000513 268A5C01 mov bl,[es:si+0x1]
- 00000517 80FB00 cmp bl,0x0 ; If the pressure is zero, treat as noteoff command
- 0000051A 7503 jnz 0x51f
- 0000051C E9BD00 jmp HANDLE_80_NOTEOFF
- 0000051F 33FF xor di,di
- 00000521 33C9 xor cx,cx
- 00000523 268A1C mov bl,[es:si]
- 00000526 46 inc si
- 00000527 268A24 mov ah,[es:si]
- 0000052A 46 inc si
- 0000052B A03103 mov al,[MIDI_CHANNEL_NUMBER]
- 0000052E 3C09 cmp al,0x9 ; MIDI channel 9 is handled as a percussion channel
- 00000530 7503 jnz NoteOnMelodic
- 00000532 E90401 jmp NoteOnPercussion
- NoteOnMelodic
- 00000535 3A85C002 cmp al,[di+ADLIB_CHANNEL_IS_PLAYING_THIS_MIDI_CHANNEL]
- 00000539 752B jnz 0x566
- 0000053B 80BDC90201 cmp byte [di+ADLIB_CHANNEL_CURRENTLY_KEYED_ON],0x1
- 00000540 7424 je 0x566
- 00000542 8BCF mov cx,di ; If there is an AdLib channel that is dedicated
- 00000544 57 push di ; for this MIDI channel, but NOT playing anything,
- 00000545 C606360320 mov byte [FUNCTION_PARAMETER_KEYON_BITS_FOR_REG_B0],0x20
- 0000054A C685C90201 mov byte [di+ADLIB_CHANNEL_CURRENTLY_KEYED_ON],0x1
- 0000054F 889DD202 mov [di+ADLIB_CHANNEL_KEYED_ON_NOTENUMBER],bl
- 00000553 029DDB02 add bl,[di+ADLIB_CHANNEL_CURRENT_FINETUNE_LEVEL]
- 00000557 D0E3 shl bl,1 ; the use that channel and key-on the note.
- 00000559 32FF xor bh,bh
- 0000055B 8B9F1400 mov bx,[bx+PITCH_TABLE]
- 0000055F E80E01 call UPDATE_VOLUME_AND_PITCH
- 00000562 5F pop di
- 00000563 E959FF jmp LoadDelayValue ; and that's it.
- 00000566 47 inc di
- 00000567 83FF09 cmp di,byte +0x9
- 0000056A 75C9 jnz NoteOnMelodic
- 0000056C 53 push bx ; No free channel was found.
- 0000056D 33FF xor di,di ; Otherwise find the oldest one of the AdLib channels
- 0000056F 33D2 xor dx,dx ; dedicated for this MIDI channel -- i.e. one where
- 00000571 C7063703FFFF mov word [OLDEST_CHANNEL_POINTER],0xffff
- 00000577 8BDF mov bx,di ; a note has been playing for the longest time
- 00000579 D1E3 shl bx,1
- 0000057B 3A85C002 cmp al,[di+ADLIB_CHANNEL_IS_PLAYING_THIS_MIDI_CHANNEL]
- 0000057F 750E jnz 0x58f ; Skip irrelevant channels
- 00000581 8B8F1A03 mov cx,[bx+ADLIB_CHANNEL_NOTE_AGE] ; Compare note age
- 00000585 3BD1 cmp dx,cx ; If older than what we currently have,
- 00000587 7306 jae 0x58f ; i.e. skip if saved >= this
- 00000589 8BD1 mov dx,cx
- 0000058B 893E3703 mov [OLDEST_CHANNEL_POINTER],di ; save the channel age
- 0000058F 47 inc di
- 00000590 83FF09 cmp di,byte +0x9
- 00000593 75E2 jnz 0x577
- 00000595 833E3703FF cmp word [OLDEST_CHANNEL_POINTER],byte -0x1
- 0000059A 7504 jne 0x5a0 ; Don't play if no channel was not found.
- 0000059C 5B pop bx ; This should be impossible to happen.
- 0000059D E91FFF jmp LoadDelayValue
- 000005A0 8B0E3703 mov cx,[OLDEST_CHANNEL_POINTER] ; Take the channel that was found
- 000005A4 8BF9 mov di,cx ; Key it off first
- 000005A6 BB0000 mov bx,0x0
- 000005A9 C606360300 mov byte [FUNCTION_PARAMETER_KEYON_BITS_FOR_REG_B0],0x0
- 000005AE E8BF00 call UPDATE_VOLUME_AND_PITCH
- 000005B1 8BDF mov bx,di ; Then, reset its age
- 000005B3 D1E3 shl bx,1
- 000005B5 C7871A030000 mov word [bx+ADLIB_CHANNEL_NOTE_AGE],0x0
- 000005BB 5B pop bx ; And key it on.
- 000005BC C606360320 mov byte [FUNCTION_PARAMETER_KEYON_BITS_FOR_REG_B0],0x20
- 000005C1 C685C90201 mov byte [di+ADLIB_CHANNEL_CURRENTLY_KEYED_ON],0x1
- 000005C6 889DD202 mov [di+ADLIB_CHANNEL_KEYED_ON_NOTENUMBER],bl
- 000005CA 029DDB02 add bl,[di+ADLIB_CHANNEL_CURRENT_FINETUNE_LEVEL]
- 000005CE D0E3 shl bl,1
- 000005D0 32FF xor bh,bh
- 000005D2 8B9F1400 mov bx,[bx+PITCH_TABLE]
- 000005D6 E89700 call UPDATE_VOLUME_AND_PITCH ; Done.
- 000005D9 E9E3FE jmp LoadDelayValue
- HANDLE_80_NOTEOFF
- 000005DC 33FF xor di,di
- 000005DE 33C9 xor cx,cx
- 000005E0 268A1C mov bl,[es:si]
- 000005E3 46 inc si
- 000005E4 46 inc si
- 000005E5 A03103 mov al,[MIDI_CHANNEL_NUMBER] ; Find an AdLib channel
- 000005E8 3A85C002 cmp al,[di+ADLIB_CHANNEL_IS_PLAYING_THIS_MIDI_CHANNEL]
- 000005EC 7542 jnz 0x630 ; that is dedicated for this MIDI channel
- 000005EE 389DD202 cmp [di+ADLIB_CHANNEL_KEYED_ON_NOTENUMBER],bl
- 000005F2 753C jnz 0x630 ; and is currently playing this note
- 000005F4 8BCF mov cx,di
- 000005F6 57 push di ; Key it off
- 000005F7 C606360300 mov byte [FUNCTION_PARAMETER_KEYON_BITS_FOR_REG_B0],0x0
- 000005FC C685C90200 mov byte [di+ADLIB_CHANNEL_CURRENTLY_KEYED_ON],0x0
- 00000601 3C09 cmp al,0x9 ; Choose the notenumber depending
- 00000603 7507 jnz NoteOffMelodic ; on whether it's melodic or percussion
- NoteOffPercussion
- 00000605 8A9DED02 mov bl,[di+ADLIB_CHANNEL_PLAYING_THIS_ACTUAL_NOTENUMBER_FOR_PERCUSSION]
- 00000609 EB0590 jmp NoteOffContinued
- NoteOffMelodic
- 0000060C 8A9DD202 mov bl,[di+ADLIB_CHANNEL_KEYED_ON_NOTENUMBER]
- NoteOffContinued
- 00000610 C685D20200 mov byte [di+ADLIB_CHANNEL_KEYED_ON_NOTENUMBER],0x0
- 00000615 029DDB02 add bl,[di+ADLIB_CHANNEL_CURRENT_FINETUNE_LEVEL]
- 00000619 D0E3 shl bl,1
- 0000061B 32FF xor bh,bh
- 0000061D 8B9F1400 mov bx,[bx+PITCH_TABLE] ; And key it off.
- 00000621 D1E7 shl di,1
- 00000623 C7851A030000 mov word [di+ADLIB_CHANNEL_NOTE_AGE],0x0
- 00000629 E84400 call UPDATE_VOLUME_AND_PITCH
- 0000062C 5F pop di
- 0000062D E98FFE jmp LoadDelayValue ; Key-off completed, done.
- 00000630 47 inc di
- 00000631 83FF09 cmp di,byte +0x9 ; Haven't found a note yet,
- 00000634 75B2 jnz 0x5e8 ; so loop for 9 AdLib channels.
- 00000636 E986FE jmp LoadDelayValue ; Didn't find note, done.
- NoteOnPercussion
- 00000639 3A85C002 cmp al,[di+ADLIB_CHANNEL_IS_PLAYING_THIS_MIDI_CHANNEL]
- 0000063D 7528 jnz 0x667 ; For percussion, the process is same as for melodic
- 0000063F 3A9DE402 cmp bl,[di+ADLIB_CHANNEL_PLAYING_THIS_MIDI_PERCUSSION_NOTENUMBER]
- 00000643 7522 jnz 0x667 ; except notenumber is handled from a different table.
- 00000645 8BCF mov cx,di
- 00000647 C606360320 mov byte [FUNCTION_PARAMETER_KEYON_BITS_FOR_REG_B0],0x20
- 0000064C C685C90201 mov byte [di+ADLIB_CHANNEL_CURRENTLY_KEYED_ON],0x1
- 00000651 889DD202 mov [di+ADLIB_CHANNEL_KEYED_ON_NOTENUMBER],bl
- 00000655 8A9DED02 mov bl,[di+ADLIB_CHANNEL_PLAYING_THIS_ACTUAL_NOTENUMBER_FOR_PERCUSSION]
- 00000659 D0E3 shl bl,1
- 0000065B 32FF xor bh,bh
- 0000065D 8B9F1400 mov bx,[bx+PITCH_TABLE]
- 00000661 E80C00 call UPDATE_VOLUME_AND_PITCH
- 00000664 E958FE jmp LoadDelayValue
- 00000667 47 inc di
- 00000668 83FF09 cmp di,byte +0x9 ; Loop 9 AdLib channels.
- 0000066B 75CC jnz 0x639
- 0000066D E94FFE jmp LoadDelayValue
- UPDATE_VOLUME_AND_PITCH
- 00000670 56 push si
- 00000671 8BF1 mov si,cx
- 00000673 803E360300 cmp byte [FUNCTION_PARAMETER_KEYON_BITS_FOR_REG_B0],0x0
- 00000678 741C jz ChannelNotKeyedOnSkip
- 0000067A BA8803 mov dx,0x388 ; Only update volume if keyed on.
- 0000067D 8A84B702 mov al,[si+CARRIER_REGISTER_INDEX_TABLE]
- 00000681 0440 add al,0x40
- 00000683 EE out dx,al
- 00000684 E89301 call word DELAY_12
- 00000687 42 inc dx
- 00000688 8A84FF02 mov al,[si+ADLIB_CHANNEL_REGISTER_43_VALUE]
- 0000068C D0EC shr ah,1 ; Carrier port 40 (43)
- 0000068E D0EC shr ah,1 ; is written with
- 00000690 2AC4 sub al,ah ; value - volume/4.
- 00000692 EE out dx,al
- 00000693 E86601 call DELAY_32
- ChannelNotKeyedOnSkip
- 00000696 BA8803 mov dx,0x388 ; Poke the frequency value (bx)
- 00000699 B0A0 mov al,0xa0 ; into A0 and B0.
- 0000069B 02C1 add al,cl
- 0000069D EE out dx,al
- 0000069E E87901 call word DELAY_12
- 000006A1 42 inc dx
- 000006A2 8AC3 mov al,bl
- 000006A4 EE out dx,al ; Save into cached A0 register value.
- 000006A5 88840803 mov [si+ADLIB_CHANNEL_REG_A0_PITCH_LOW_8_BITS],al
- 000006A9 E85001 call DELAY_32
- 000006AC BA8803 mov dx,0x388
- 000006AF B0B0 mov al,0xb0
- 000006B1 02C1 add al,cl
- 000006B3 EE out dx,al
- 000006B4 E86301 call word DELAY_12
- 000006B7 42 inc dx
- 000006B8 8AC7 mov al,bh ; B0 keyon bits are loaded from different variable.
- 000006BA 0A063603 or al,[FUNCTION_PARAMETER_KEYON_BITS_FOR_REG_B0]
- 000006BE EE out dx,al ; Save into cached B0 register value.
- 000006BF 88841103 mov [si+ADLIB_CHANNEL_REG_B0_PITCH_HIGH_2_BITS_AND_KEYON_BITS],al
- 000006C3 E85401 call word DELAY_12
- 000006C6 5E pop si
- 000006C7 C3 ret
- RECALCULATE_PITCH_AND_WRITE
- 000006C8 50 push ax
- 000006C9 8A850803 mov al,[di+ADLIB_CHANNEL_REG_A0_PITCH_LOW_8_BITS] ; Load the designated pitch
- 000006CD 8AA51103 mov ah,[di+ADLIB_CHANNEL_REG_B0_PITCH_HIGH_2_BITS_AND_KEYON_BITS]
- 000006D1 8ADC mov bl,ah
- 000006D3 80E3FC and bl,0xfc
- 000006D6 881E3B03 mov [TEMPORARY],bl ; Save the keyon bits
- 000006DA 80E403 and ah,0x3 ; Pitch is 10 bits.
- 000006DD 8B163903 mov dx,[FUNCTION_PARAMETER_PITCH_BEND_VALUE]; Multiply by pitch-bend
- 000006E1 F7E2 mul dx
- 000006E3 8AC4 mov al,ah ; Divide by 1024
- 000006E5 8AE2 mov ah,dl
- 000006E7 8AD6 mov dl,dh
- 000006E9 51 push cx
- 000006EA B90500 mov cx,0x5
- 000006ED D0EA shr dl,1
- 000006EF D1D8 rcr ax,1
- 000006F1 E2FA loop 0x6ed
- 000006F3 59 pop cx ; Done dividing
- 000006F4 8BD8 mov bx,ax ; Save the pitch into bx
- 000006F6 BA8803 mov dx,0x388
- 000006F9 B0A0 mov al,0xa0 ; Write the low 8 bits into register A0
- 000006FB 02C1 add al,cl
- 000006FD EE out dx,al
- 000006FE E81901 call word DELAY_12
- 00000701 42 inc dx
- 00000702 8AC3 mov al,bl
- 00000704 EE out dx,al
- 00000705 E8F400 call DELAY_32
- 00000708 BA8803 mov dx,0x388 ; Write the high 8 bits into register B0
- 0000070B B0B0 mov al,0xb0
- 0000070D 02C1 add al,cl
- 0000070F EE out dx,al
- 00000710 E80701 call word DELAY_12
- 00000713 42 inc dx
- 00000714 8AC7 mov al,bh
- 00000716 0A063B03 or al,[TEMPORARY] ; Add the keyon bits, too.
- 0000071A EE out dx,al
- 0000071B E8FC00 call word DELAY_12
- 0000071E 58 pop ax
- 0000071F C3 ret
- PROGRAM_PATCH:
- 00000720 32FF xor bh,bh
- 00000722 8BFB mov di,bx
- 00000724 8A9D5001 mov bl,[di+PATCH_NUMBER_MAPPING_TO_INSTRUMENT_NUMBERS]
- 00000728 D0E3 shl bl,1
- 0000072A 8BFB mov di,bx
- 0000072C 8BBD8701 mov di,[di+INSTRUMENT_POINTERS]
- 00000730 56 push si
- 00000731 8BF1 mov si,cx
- 00000733 BA8803 mov dx,0x388
- 00000736 8A84AE02 mov al,[si+MODULATOR_REGISTER_INDEX_TABLE]
- 0000073A 0420 add al,0x20
- 0000073C EE out dx,al
- 0000073D E8DA00 call word DELAY_12
- 00000740 42 inc dx
- 00000741 8A05 mov al,[di] Byte 0: register 0x20
- 00000743 EE out dx,al
- 00000744 E8B500 call DELAY_32
- 00000747 BA8803 mov dx,0x388
- 0000074A 8A84AE02 mov al,[si+MODULATOR_REGISTER_INDEX_TABLE]
- 0000074E 0440 add al,0x40
- 00000750 EE out dx,al
- 00000751 E8C600 call word DELAY_12
- 00000754 42 inc dx
- 00000755 47 inc di
- 00000756 8A05 mov al,[di] Byte 1: register 0x40
- 00000758 EE out dx,al
- 00000759 E8A000 call DELAY_32
- 0000075C BA8803 mov dx,0x388
- 0000075F 8A84AE02 mov al,[si+MODULATOR_REGISTER_INDEX_TABLE]
- 00000763 0460 add al,0x60
- 00000765 EE out dx,al
- 00000766 E8B100 call word DELAY_12
- 00000769 42 inc dx
- 0000076A 47 inc di
- 0000076B 8A05 mov al,[di] Byte 2: register 0x60
- 0000076D EE out dx,al
- 0000076E E88B00 call DELAY_32
- 00000771 BA8803 mov dx,0x388
- 00000774 8A84AE02 mov al,[si+MODULATOR_REGISTER_INDEX_TABLE]
- 00000778 0480 add al,0x80
- 0000077A EE out dx,al
- 0000077B E89C00 call word DELAY_12
- 0000077E 42 inc dx
- 0000077F 47 inc di
- 00000780 8A05 mov al,[di] Byte 3: register 0x80
- 00000782 EE out dx,al
- 00000783 E87600 call DELAY_32
- 00000786 BA8803 mov dx,0x388
- 00000789 8A84B702 mov al,[si+CARRIER_REGISTER_INDEX_TABLE]
- 0000078D 0420 add al,0x20
- 0000078F EE out dx,al
- 00000790 E88700 call word DELAY_12
- 00000793 42 inc dx
- 00000794 47 inc di
- 00000795 8A05 mov al,[di] Byte 4: register 0x23
- 00000797 EE out dx,al
- 00000798 E86100 call DELAY_32
- 0000079B BA8803 mov dx,0x388
- 0000079E 8A84B702 mov al,[si+CARRIER_REGISTER_INDEX_TABLE]
- 000007A2 0440 add al,0x40
- 000007A4 EE out dx,al
- 000007A5 E87200 call word DELAY_12
- 000007A8 42 inc dx
- 000007A9 47 inc di
- 000007AA 8A05 mov al,[di] Byte 5: register 0x43
- 000007AC 8884FF02 mov [si+ADLIB_CHANNEL_REGISTER_43_VALUE],al Saved also here
- 000007B0 EE out dx,al
- 000007B1 E84800 call DELAY_32
- 000007B4 BA8803 mov dx,0x388
- 000007B7 8A84B702 mov al,[si+CARRIER_REGISTER_INDEX_TABLE]
- 000007BB 0460 add al,0x60
- 000007BD EE out dx,al
- 000007BE E85900 call word DELAY_12
- 000007C1 42 inc dx
- 000007C2 47 inc di
- 000007C3 8A05 mov al,[di] Byte 6: register 0x63
- 000007C5 EE out dx,al
- 000007C6 E83300 call DELAY_32
- 000007C9 BA8803 mov dx,0x388
- 000007CC 8A84B702 mov al,[si+CARRIER_REGISTER_INDEX_TABLE]
- 000007D0 0480 add al,0x80
- 000007D2 EE out dx,al
- 000007D3 E84400 call word DELAY_12
- 000007D6 42 inc dx
- 000007D7 47 inc di
- 000007D8 8A05 mov al,[di] Byte 7: register 0x83
- 000007DA EE out dx,al
- 000007DB E81E00 call DELAY_32
- 000007DE BA8803 mov dx,0x388
- 000007E1 B0C0 mov al,0xc0
- 000007E3 02C1 add al,cl
- 000007E5 EE out dx,al
- 000007E6 E83100 call word DELAY_12
- 000007E9 42 inc dx
- 000007EA 47 inc di
- 000007EB 8A05 mov al,[di] Byte 8: register 0xC0
- 000007ED EE out dx,al
- 000007EE E80B00 call DELAY_32
- 000007F1 47 inc di
- 000007F2 8A05 mov al,[di] Byte 9: finetune
- 000007F4 8BF9 mov di,cx
- 000007F6 8885DB02 mov [di+ADLIB_CHANNEL_CURRENT_FINETUNE_LEVEL],al Saved here
- 000007FA 5E pop si
- 000007FB C3 ret
- DELAY_32
- 000007FC B020 mov al,0x20
- 000007FE FEC8 dec al
- 00000800 90 nop
- 00000801 75FB jnz 0x7fe
- 00000803 C3 ret
- NEXT_RANDOM
- 00000804 52 push dx
- 00000805 A14E01 mov ax,[LSFR_VALUE]
- 00000808 D1E8 shr ax,1
- 0000080A 7303 jnc 0x80f
- 0000080C 80F4B4 xor ah,0xb4
- 0000080F A34E01 mov [LSFR_VALUE],ax
- 00000812 33D2 xor dx,dx
- 00000814 F7F1 div cx
- 00000816 8BCA mov cx,dx
- 00000818 5A pop dx
- 00000819 C3 ret
- DELAY_12
- 0000081A B00C mov al,0xc
- 0000081C FEC8 dec al
- 0000081E 90 nop
- 0000081F 75FB jnz 0x81c
- 00000821 C3 ret
- RESET_ADLIB
- 00000822 BE6500 mov si,0x65
- 00000825 8A84D600 mov al,[si+LIST_OF_INITIAL_00_REGISTERS]
- 00000829 BA8803 mov dx,0x388
- 0000082C EE out dx,al
- 0000082D E8CCFF call DELAY_32
- 00000830 B000 mov al,0x0
- 00000832 42 inc dx
- 00000833 EE out dx,al
- 00000834 E8C5FF call DELAY_32
- 00000837 4E dec si
- 00000838 79EB jns 0x825
- 0000083A BE1100 mov si,0x11
- 0000083D 8A843C01 mov al,[si+LIST_OF_INITIAL_3F_REGISTERS]
- 00000841 BA8803 mov dx,0x388
- 00000844 EE out dx,al
- 00000845 E8B4FF call DELAY_32
- 00000848 B03F mov al,0x3f
- 0000084A 42 inc dx
- 0000084B EE out dx,al
- 0000084C E8ADFF call DELAY_32
- 0000084F 4E dec si
- 00000850 79EB jns 0x83d
- 00000852 C3 ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement