Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. set_refresh:
  2.         ld hl,DEFAULT_QNOTE_DURATION_MCS%65536
  3.         ld de,DEFAULT_QNOTE_DURATION_MCS/65536
  4. setticksperupdate
  5. ;dehl = qnote duration in mcs
  6.         exx
  7.         ld hl,(g_header.ticksperqnoteXupdatelen+0)
  8.         ld de,(g_header.ticksperqnoteXupdatelen+2)
  9.         call uintdiv32
  10.         ld (g_ticks_per_update+0),hl
  11.         ld (g_ticks_per_update+2),de
  12.         ret
  13.  
  14.  
  15.  
  16. midheadersig:
  17.                         db  "MThd",0,0,0,6
  18. midheadersigsize: equ $-midheadersig
  19. midtracksig
  20.                         db "MTrk"
  21. midtracksigsize = $-midtracksig
  22.  
  23. midchecksignature
  24. ;b = byte count
  25. ;de = signature
  26. ;out: zf=1 if ok, zf=0 otherwise
  27.                         ld hl,(memorystreamcurrentaddr)
  28. .loop   memory_stream_read_byte c
  29.                         ld a,(de)
  30.                         cp c
  31.                         ret nz
  32.                         inc de
  33.                         djnz .loop
  34.                         ld (memorystreamcurrentaddr),hl
  35.                         ret
  36.  
  37.  
  38. generate_tables:
  39.             ld hl,g_header.g_midi_channel_data+128
  40.             ld iy,NR_OF_MIDI_CHANNELS      
  41.             ld bc,MIDI_CHANNEL_DATA
  42.             ld de,midi_ch_table  
  43. .loop1:
  44.             ld a,l
  45.             ld (de),a
  46.             inc de
  47.             ld a,h              
  48.             ld (de),a
  49.             inc de
  50.  
  51.  
  52.             add hl,bc
  53.             dec iyl
  54.             jr nz,.loop1
  55.             ret    
  56.                        
  57. rewind:
  58.                         ld hl,0
  59.                         ld (g_MIDI_counter),hl
  60.                         ld (g_MIDI_counter+2),hl
  61.  
  62.                         ld hl,g_header.g_track_data
  63.                         ld iy,(g_header.number_of_tracks)
  64.  
  65. .loop1
  66. ;waiting_for_t -> waiting_for
  67.                         ld b,(hl) : inc hl : ld c,(hl) : inc hl : ld d,(hl) : inc hl : ld e,(hl) : inc hl
  68.                         ld (hl),b : inc hl : ld (hl),c : inc hl : ld (hl),d : inc hl : ld (hl),e : inc hl
  69.  
  70. ;streamoffset -> currentoffset
  71.                         ld b,(hl) : inc hl : ld c,(hl) : inc hl : ld d,(hl) : inc hl : ld e,(hl) : inc hl
  72.                         ld (hl),b : inc hl : ld (hl),c : inc hl : ld (hl),d : inc hl : ld (hl),e : inc hl
  73.                         ;track_finished
  74.                         ld (hl),0 : inc hl
  75. ;last command    
  76.                         ld (hl),0xff : inc hl
  77.                         dec iyl
  78.                         jp nz,.loop1
  79.                         call init_channels
  80.                         call init_voices
  81.                         ret
  82.                        
  83.                        
  84. init_channels:
  85.                         ld hl,g_header.g_midi_channel_data
  86.                         ld iy,NR_OF_MIDI_CHANNELS
  87.                         ld d,0   ;channel
  88. .loop
  89.                         xor a
  90.                         ld b,128+15   ;128 notes + 1instrument + 1vibrato + 2pitchbend + 2 finetuning + 2 coarsetuning + 4 midictl reg +1sustain  +1 panpot ymf278  -7 [0] +7   1pitch bend range (low)
  91. .clear_status
  92.                         ld (hl),a
  93.                         inc hl
  94.                         djnz .clear_status
  95.                         inc a
  96.                         ld (hl),a ; rpn_pitch_bend_range+1
  97.                         inc hl
  98.                         ld (hl),a ; param_type
  99.                         inc hl        
  100.                         ld (hl),100  ;gm_volume
  101.                         inc hl        
  102.                         ld (hl),127  ;gm_expression                                    
  103.                         inc hl      
  104.                                                                                
  105.                         ld a,DRUM_CHANNEL
  106.                         cp d
  107.                         ld a,0
  108.                         jr nz,.loop1
  109.                         ld a,1
  110. .loop1
  111.                         ld (hl),a
  112.                         inc hl
  113.  
  114.                         inc d
  115.                         dec iyl
  116.                         jp nz,.loop
  117.                         ret
  118.  
  119. init_voices:
  120.                         ld hl,g_header.g_voice_data
  121.                         ld iy,NR_OF_WAVE_CHANNELS
  122.                         xor a
  123.                         ld d,a
  124. .loop                                                
  125.                         ld (hl),d:inc hl  ;VOICE_DATA.number          
  126.                         ld b,15                                      
  127. .loop2                                                
  128.                         ld (hl),a:inc hl                              
  129.                         djnz .loop2                                  
  130.                         inc d
  131.                         dec iyl
  132.                         jp nz,.loop
  133.                         ret
  134.                        
  135. midloadtracks:
  136.                         ld ix,g_header.g_track_data
  137.                         ld iy,(g_header.number_of_tracks)
  138.  
  139. .loop           ld b,midtracksigsize
  140.                         ld de,midtracksig
  141.                         call midchecksignature
  142.                         ret nz
  143.                         call memorystreamread4
  144.                         ld l,b
  145.                         ld h,c
  146.                         push hl
  147.                         ld e,a
  148.                         push de
  149.                         call memorystreamgetpos
  150.                         push de
  151.                         push hl
  152.  
  153.                         ld hl,(memorystreamcurrentaddr)
  154.                         call midreadvarint
  155.                         ld (memorystreamcurrentaddr),hl
  156.                        
  157.                         ld b,0
  158.                         sla de : rl bc
  159.                         sla de : rl bc
  160.                         ld (ix+TRACK_DATA.waiting_for_t+0),de  
  161.                         ld (ix+TRACK_DATA.waiting_for_t+2),bc
  162.                         call memorystreamgetpos
  163.                         ld (ix+TRACK_DATA.streamoffset+0),hl
  164.                         ld (ix+TRACK_DATA.streamoffset+2),de
  165.                         pop hl
  166.                         pop de
  167.                         pop bc
  168.                         add hl,bc
  169.                         ex de,hl
  170.                         pop bc
  171.                         adc hl,bc
  172.                         ex de,hl
  173.                         call memorystreamseek
  174.                         ld bc,TRACK_DATA
  175.                         add ix,bc
  176.                         dec iyl
  177.                         jp nz,.loop
  178.                         ret
  179.  
  180.  
  181. midplay:
  182.                         YIELD
  183.                        
  184.                        
  185.                         ld a,(opl4tablespage)
  186.                         SETPGC000
  187.                        
  188.                        
  189.                         ld hl,(g_MIDI_counter+0)
  190.                         ld de,(g_ticks_per_update+0)
  191.                         add hl,de
  192.                         ld (g_MIDI_counter+0),hl
  193.                         ex de,hl
  194.                         ld hl,(g_MIDI_counter+2)
  195.                         ld bc,(g_ticks_per_update+2)
  196.                         adc hl,bc
  197.                         ld (g_MIDI_counter+2),hl
  198.                         ex de,hl
  199.  
  200.                         call midgetprogress    
  201.                         call updateprogress
  202.  
  203.  
  204. ;iterate through the tracks
  205.                 ld ix,g_header.g_track_data
  206.                 ld a,(g_header.number_of_tracks)
  207.                 ld b,a
  208.                 ld c,0
  209. .trackloop
  210.                 bit 7,(ix+TRACK_DATA.track_finished)
  211.                 jr nz,.skiptrack
  212.                         ld c,255
  213.                         ld hl,(g_MIDI_counter+0)
  214.                         ld de,(ix+TRACK_DATA.waiting_for+0)
  215.                         sub hl,de
  216.                         ld hl,(g_MIDI_counter+2)
  217.                         ld de,(ix+TRACK_DATA.waiting_for+2)
  218.                         sbc hl,de
  219.                         jr c,.skiptrack
  220.                         push bc
  221. .handle_track_event
  222.                         ld hl,(ix+TRACK_DATA.currentoffset+0)
  223.                         ld de,(ix+TRACK_DATA.currentoffset+2)
  224.                         call memorystreamseek
  225.                         call process_midi_event
  226.                         call finalize  ;get_delta_time
  227.                         call memorystreamgetpos
  228.                         ld (ix+TRACK_DATA.currentoffset+0),hl
  229.                         ld (ix+TRACK_DATA.currentoffset+2),de
  230.                         pop bc
  231.             jr .trackloop
  232. .skiptrack
  233.                 ld de,TRACK_DATA
  234.                 add ix,de
  235.                 djnz .trackloop
  236.                 ld a,c  
  237.                 or a          ;a 0 track still play  !0 - finished
  238.                 ret
  239.                        
  240.                        
  241.  
  242.  
  243. midreadvarint
  244. ;hl = memory stream addr
  245. ;out: cde = number, hl = memory stream addr
  246.         ld de,0
  247.         ld c,0
  248. .loop   memory_stream_read_byte b
  249.         ld a,e
  250.         rrca
  251.         xor b
  252.         and 0x80
  253.         xor b
  254.         rr c
  255.         rr de
  256.         ld c,d
  257.         ld d,e
  258.         ld e,a
  259.         bit 7,b
  260.         jr nz,.loop
  261.         ret
  262.  
  263. process_midi_event
  264.                         memory_stream_read_1 b         ;data_byte_1   ;command
  265. /* If MSB is not set, this is a running status */
  266.                         bit 7,b
  267.                         jr z,.is_running
  268. /*not_running*/
  269.                         ld (ix+TRACK_DATA.last_command),b                                        
  270.                         memory_stream_read_1 c
  271.                         jr ._next_step1              ;b - data_byte_1  (command) c-data_byte_2 (first parameter)
  272. .is_running
  273. /*command running*/
  274.                         ld c,b
  275.                         ld b,(ix+TRACK_DATA.last_command)     ;b - data_byte_1  (command) c-data_byte_2 (first parameter)
  276.  
  277. ._next_step1:
  278.  
  279.                         ld a,b
  280.                         rrca
  281.                         rrca
  282.                         rrca
  283.                         rrca
  284.                         and 7
  285.                         ld d,a
  286.                         add a,a
  287.                         add a,d
  288.                         ld (.commandtable),a
  289.  
  290.                         ld a,b
  291.                         and a,0x0f
  292.                         ld e,a           ;e - used channel
  293.  
  294. .commandtable=$+1
  295.                         jr $
  296.                         jp _j_note_off
  297.                         jp _j_note_on
  298.                         jp _j_key_after_touch
  299.                         jp _j_control_change
  300.                         jp _j_program_change
  301.                         jp _j_channel_after_touch
  302.                         jp _j_pitch_wheel
  303. ;;;;;;;;;;;;;;;;;;; F System
  304.                         ld a,b
  305.                         cp 0xff
  306.                         jp z,handle_meta_event
  307.                         cp 0xf0
  308.                         ret nz
  309. handle_sys_ex_event:            
  310.  
  311.                         ld hl,(memorystreamcurrentaddr)      
  312. .sendloop:
  313.                         memory_stream_read_byte a
  314.                         cp 0xf7
  315.                         jr nz,.sendloop
  316.                         ld (memorystreamcurrentaddr),hl            
  317.                         ret
  318.  
  319. _j_note_off:
  320.                         memory_stream_read_1 d          ;data_byte_3
  321.                                                                                 ;b - data_byte_1 - command
  322.                                                                                 ;c - data_byte_2 - note
  323.                                                                                 ;d - data_byte_3 - velocity  //  not used
  324.                                                                                 ;e - wave channel
  325. _j_note_off_1:
  326.                         ld a,c
  327.                         and 0x7f
  328.                         ld c,a
  329.                        
  330.                         cpl
  331.                         ld (._note_evv1),a
  332.                         ld (._note_evv2),a
  333.                         ld (._note_evv3),a
  334.                         ld (._note_evv4),a
  335.                         ld (._note_evv5),a
  336.                         ld (._note_evv6),a
  337. ;looking for midi channel
  338.                         push ix
  339.             ld a,e
  340.             add a,a
  341.             ld h,HIGH midi_ch_table
  342.             ld l,a    
  343.             ld a,(hl)    
  344.             inc hl  
  345.             ld h,(hl)
  346.             ld l,a    
  347.             ld (.wave_channel_pointer),hl
  348.             push hl
  349.             pop ix
  350.             ld a,(ix+0)
  351. ._note_evv1 equ $-1
  352.             and SNDRV_MIDI_NOTE_ON
  353.             jp z,._note_off_break                      ;noteoff but event for note is not note on
  354.                         ld  a,(IX+MIDI_CHANNEL_DATA.gm_sustain-128)
  355.                         and a
  356.                         jr z,.check_solstenuto
  357.  
  358.                         ld a,(ix+0)
  359. ._note_evv2 equ $-1
  360.                         or  SNDRV_MIDI_NOTE_RELEASED
  361.                         ld (ix+0),a
  362. ._note_evv3 equ $-1                
  363.                         jp ._note_off_break
  364. .check_solstenuto
  365.                         ld a,(ix+0)
  366. ._note_evv4 equ $-1
  367.                         and SNDRV_MIDI_NOTE_SOSTENUTO
  368.                         jr z,.no_solstenuto    
  369.                         or SNDRV_MIDI_NOTE_RELEASED
  370.                         ld (ix+0),a
  371. ._note_evv5 equ $-1                
  372.                         jp ._note_off_break
  373. .no_solstenuto
  374.                         ld (ix+0),0
  375. ._note_evv6 equ $-2
  376.                         ld ix,g_header.g_voice_data
  377.                         ld iy,NR_OF_WAVE_CHANNELS        
  378. .loop_v1:        
  379.                         ld a,(ix+VOICE_DATA.note)
  380.                         cp c
  381.                         jr nz,.loop_v2
  382.                         ld  a,(ix+VOICE_DATA.activated)
  383.                         or (ix+VOICE_DATA.activated+1)
  384.                         or (ix+VOICE_DATA.activated+2)
  385.                         or (ix+VOICE_DATA.activated+3)
  386.                         jr z,.loop_v2
  387.                         ld hl,(ix+VOICE_DATA.midi_channel)
  388.                         ld de,0
  389. .wave_channel_pointer: equ $-2
  390.                         and a
  391.                         sbc hl,de
  392.                         jr nz,.loop_v2
  393.                         ld (ix+VOICE_DATA.is_active),0
  394.                         ld a,(ix+VOICE_DATA.reg_misc)
  395.                         and OPL4_KEY_ON_BIT_INV
  396.                         ld (ix+VOICE_DATA.reg_misc),a
  397.                         ld d,a  ;//(ix+VOICE_DATA.reg_misc)
  398.                         ld a,OPL4_REG_MISC
  399.                         add a,(ix+VOICE_DATA.number)
  400.                         ld e,a
  401.                         call opl4writewave
  402. .loop_v2:
  403.             ld de,VOICE_DATA    
  404.             add ix,de
  405.             dec iyl
  406.             jr nz,.loop_v1            
  407. ._note_off_break
  408.                         pop ix
  409.                         ret
  410.                        
  411. _j_key_after_touch:
  412.                         memory_stream_read_1 d          ;data_byte_3
  413.                                                                                 ;b - data_byte_1 - command
  414.                                                                                 ;c - data_byte_2 - note
  415.                                                                                 ;d - data_byte_3 - pressure value
  416.                                                                                 ;e - wave channel
  417.                         ret
  418. _j_control_change:
  419.                         memory_stream_read_1 d          ;data_byte_3
  420.                                                                                 ;b - data_byte_1 - command
  421.                                                                                 ;c - data_byte_2 - controller
  422.                                                                                 ;d - data_byte_3 - new value
  423.                                                                                 ;e - wave channel
  424.                         push ix
  425.                         ld hl,.exxt
  426.                         push hl
  427.                         ld a,e
  428.                         ld (.sustain_midi_channel),a
  429.                         ld (.sostenuto_midi_channel),a
  430.                         add a,a
  431.                         ld h,HIGH midi_ch_table
  432.                         ld l,a    
  433.                         ld a,(hl)    
  434.                         inc hl  
  435.                         ld h,(hl)
  436.                         ld l,a
  437.                         push hl
  438.                         pop ix      
  439. ;=======================================================================================================
  440. ;       /* Switches */
  441. ;       if ((control >=64 && control <=69) || (control >= 80 && control <= 83)) {
  442. ;               /* These are all switches; either off or on so set to 0 or 127 */
  443. ;               value = (value >= 64)? 127: 0;
  444. ;       }
  445.                         ld a,c
  446.                         cp 64
  447.                         jp c,.no_c_switch:
  448.                         cp 83+1
  449.                         jp nc,.no_c_switch:
  450.                         cp 69+1
  451.                         jp c,.its_c_switch
  452.                         cp 80
  453.                         jp c,.no_c_switch
  454. .its_c_switch:
  455.                         ld a,01000000b
  456.                         and a,d
  457.                         add a,a
  458.                         ld d,a
  459. .no_c_switch:
  460. ;=======================================================================================================
  461.                         ld a,MIDI_CTL_MSB_MODWHEEL
  462.                         cp c
  463.                         jp z,.SUB_MIDI_CTL_MSB_MODWHEEL
  464.  
  465.                         ld a,MIDI_CTL_MSB_MAIN_VOLUME
  466.                         cp c
  467.                         jp z,.SUB_MIDI_CTL_MSB_MAIN_VOLUME
  468.  
  469.                         ld a,MIDI_CTL_MSB_EXPRESSION
  470.                         cp c
  471.                         jp z,.SUB_MIDI_CTL_MSB_EXPRESSION
  472.  
  473.                         ld a,MIDI_CTL_MSB_DATA_ENTRY                      ;0x06  - 6
  474.                         cp c
  475.                         jp z,.SUB_MIDI_CTL_MSB_DATA_ENTRY
  476.  
  477.  
  478.                         ld a,MIDI_CTL_MSB_PAN                           ; 0x0a  10
  479.                         cp c
  480.                         jp z,.SUB_MIDI_CTL_MSB_PAN
  481.  
  482.  
  483.                         ld a,MIDI_CTL_LSB_DATA_ENTRY                    ;0x26  - 38
  484.                         cp c
  485.                         jp z,.SUB_MIDI_CTL_LSB_DATA_ENTRY
  486.  
  487.  
  488.                         ld a,MIDI_CTL_REGIST_PARM_NUM_LSB                  ;0x64 - 100
  489.                         cp c
  490.                         jp z,.SUB_MIDI_CTL_REGIST_PARM_NUM_LSB            
  491.  
  492.                         ld a,MIDI_CTL_REGIST_PARM_NUM_MSB                 ;0x65 - 101
  493.                         cp c
  494.                         jp z,.SUB_MIDI_CTL_REGIST_PARM_NUM_MSB
  495.  
  496.                         ld a,MIDI_CTL_SUSTAIN                           ;0x40 sustain pedal
  497.                         cp c
  498.                         jp z,.SUB_MIDI_CTL_SUSTAIN
  499.  
  500.                         ld a,MIDI_CTL_SOSTENUTO
  501.                         cp c
  502.                         jp z,.SUB_MIDI_CTL_SOSTENUTO
  503.  
  504.                         ret
  505. .exxt:
  506.                         pop ix        
  507.                         ret
  508.  
  509. .SUB_MIDI_CTL_MSB_MAIN_VOLUME:
  510.                         ld (IX+MIDI_CHANNEL_DATA.gm_volume-128),d ;MIDI_CTL_MSB_MAIN_VOLUME
  511.                         ret
  512. .SUB_MIDI_CTL_MSB_EXPRESSION:
  513.                         ld (IX+MIDI_CHANNEL_DATA.gm_expression-128),d
  514.                         ret
  515.  
  516.  
  517. .SUB_MIDI_CTL_MSB_MODWHEEL:
  518.                         ld (IX+MIDI_CHANNEL_DATA.vibrato-128),d
  519.                         ld a,d
  520.                         ld (update_vibrato_depth.ctl_vibrato),a
  521. ;======================================
  522. ;do for channel
  523.                         ld (.comparrerr),ix
  524.                         ld ix,g_header.g_voice_data
  525.                         ld iy,NR_OF_WAVE_CHANNELS        
  526. .loop_v1:        
  527.                         ld a,(IX+VOICE_DATA.is_active)
  528.                         and a
  529.                         jr z,.nnofffooond
  530.                         ld hl,(IX+VOICE_DATA.midi_channel)
  531.                         ld de,0
  532. .comparrerr:    equ $-2
  533.                         and a
  534.                         sbc hl,de        
  535.                         jr nz,.nnofffooond
  536.                         ld hl,(IX+VOICE_DATA.wave_data)
  537.                         push hl
  538.                         pop iy    
  539.                         ld a,(IY+YRW801_WAVE_DATA.vibrato)
  540.                         ld (update_vibrato_depth.vibrato_data),a                
  541.                         ;in - IX+VOICE_DATA
  542.                         push ix
  543.                         call update_vibrato_depth
  544.                         pop ix
  545. .nnofffooond:
  546.             ld de,VOICE_DATA    
  547.             add ix,de
  548.             dec iyl
  549.             jr nz,.loop_v1            
  550.             ret    
  551. .SUB_MIDI_CTL_MSB_PAN
  552.             ld a,DRUM_CHANNEL
  553.             cp e
  554.             ret z      
  555.             ld a,d
  556.             sub 0x40
  557.             sra a:sra a:sra a    
  558.             ld (ix+MIDI_CHANNEL_DATA.panpot-128),a
  559.             ret
  560. ;registered parameter (fine) 100
  561. .SUB_MIDI_CTL_REGIST_PARM_NUM_LSB
  562.                         ld  (IX+MIDI_CHANNEL_DATA._MIDI_CTL_REGIST_PARM_NUM_LSB-128),d      
  563.                         ret    
  564. ;registered parameter (coarse) 101
  565. .SUB_MIDI_CTL_REGIST_PARM_NUM_MSB
  566.                         ld  (IX+MIDI_CHANNEL_DATA._MIDI_CTL_REGIST_PARM_NUM_MSB-128),d
  567.                         ret
  568.  ;0x06  
  569. .SUB_MIDI_CTL_MSB_DATA_ENTRY:
  570.                         ld  (IX+MIDI_CHANNEL_DATA._MIDI_CTL_LSB_DATA_ENTRY-128),0
  571.                         ld  (IX+MIDI_CHANNEL_DATA._MIDI_CTL_MSB_DATA_ENTRY-128),d
  572.                         jr .rpn
  573. ;0x26
  574. .SUB_MIDI_CTL_LSB_DATA_ENTRY:
  575.                         ld  (IX+MIDI_CHANNEL_DATA._MIDI_CTL_LSB_DATA_ENTRY-128),d
  576. .rpn:  
  577.                         ;calculate rpn value
  578.                         ld h,0
  579.                         ld l,(IX+MIDI_CHANNEL_DATA._MIDI_CTL_MSB_DATA_ENTRY-128)
  580.                         SRL H
  581.                         RR L
  582.                         LD H, L
  583.                         LD L, 0
  584.                         RR L            ; hl <<7
  585.                         ld a,l
  586.                         or   (IX+MIDI_CHANNEL_DATA._MIDI_CTL_LSB_DATA_ENTRY-128)
  587.                         ld l,a
  588.                         push hl
  589.  
  590.                         ld  a,(IX+MIDI_CHANNEL_DATA._MIDI_CTL_REGIST_PARM_NUM_MSB-128)
  591.                         and a
  592.                         jr nz,.rpn_ext            
  593.  
  594.                         ld  a,(IX+MIDI_CHANNEL_DATA._MIDI_CTL_REGIST_PARM_NUM_LSB-128)
  595.                         cp 0      
  596.                         jr z,.pb_sens      
  597.                         cp 1
  598.                         jr z,.pb_finetun
  599.                         cp 2
  600.                         jr z,.pb_coarsetun
  601. .rpn_ext
  602.                         pop hl
  603.                         ret
  604. .pb_sens:
  605.                         pop hl
  606.                         ld (IX+MIDI_CHANNEL_DATA.gm_rpn_pitch_bend_range-128),hl
  607.                         ret
  608. .pb_finetun:
  609.                         pop hl
  610.                         and a
  611.                         ld bc,8192
  612.                         sbc hl,bc
  613.                         ADD HL,HL    ;11       signed hl >> 7
  614.                         LD L,H    ;4
  615.                         SBC A    ;4
  616.                         LD H,A    ;4    23t
  617.                         ld (IX+MIDI_CHANNEL_DATA.gm_rpn_fine_tuning-128),hl    
  618.                         ret
  619. .pb_coarsetun:
  620.                         pop hl
  621.                         and a
  622.                         ld bc,8192
  623.                         sbc hl,bc
  624.                         ld (IX+MIDI_CHANNEL_DATA.gm_rpn_coarse_tuning-128),hl    
  625.                         ret
  626. .SUB_MIDI_CTL_SUSTAIN
  627.                         ld  (IX+MIDI_CHANNEL_DATA.gm_sustain-128),d
  628.                         ld a,d
  629.                         and a
  630.                         ret nz
  631.                         ld a,0xff
  632. .SUB_MIDI_CTL_SUSTAIN_loop:
  633.                         ld  (.sustain_notev1),a
  634.                         ld  (.sustain_notev2),a
  635.                         push af
  636.                         cpl
  637.                         ld c,a   ; note
  638.                         ld e,0   ;midi channel
  639. .sustain_midi_channel equ $-1                
  640.                         ld a,(ix+0)
  641. .sustain_notev1 equ $-1
  642.                         AND SNDRV_MIDI_NOTE_RELEASED     ; bit 1,(ix+0)
  643.                         jp z,.SUB_MIDI_CTL_SUSTAIN_skip_loop                
  644.                         call _j_note_off_1
  645.                         ld (ix+0),SNDRV_MIDI_NOTE_OFF
  646. .sustain_notev2 equ $-2
  647.                       ;======= call noteoff  
  648. .SUB_MIDI_CTL_SUSTAIN_skip_loop
  649.                         pop af      
  650.                         dec a
  651.                         cp 0x7f
  652.                         jr nz,.SUB_MIDI_CTL_SUSTAIN_loop
  653.                         ret
  654. .SUB_MIDI_CTL_SOSTENUTO:
  655.                         ld a,d
  656.                         and a
  657.                         jp z,.SUB_MIDI_CTL_SOSTENUTO_SWITCH_OFF
  658.                         ;sostenuto switch on
  659.                         ld a,0xff
  660. .sostenuto_sw_on_loop:
  661.                         ld (.sostenuto_sw_on_notevv1),a
  662.                         ld (.sostenuto_sw_on_notevv2),a
  663.                         push af
  664.                         ld a,(ix+0)
  665. .sostenuto_sw_on_notevv1 equ $-1
  666.                         ld c,a
  667.                         and SNDRV_MIDI_NOTE_ON             ;bit 0,(ix+0)
  668.                         jp z,.sostenuto_sw_on_skip_loop
  669.                         ld a,c
  670.                         or SNDRV_MIDI_NOTE_SOSTENUTO
  671.                         ld (ix+0),a                        ;set 2,(ix+0)
  672. .sostenuto_sw_on_notevv2 equ $-1
  673. .sostenuto_sw_on_skip_loop:
  674.                         pop af      
  675.                         dec a
  676.                         cp 0x7f
  677.                         jr nz,.sostenuto_sw_on_loop
  678.                         ret
  679. .SUB_MIDI_CTL_SOSTENUTO_SWITCH_OFF
  680.                         ld a,0xff
  681. .sostenuto_sw_off_loop:
  682.                         ld (.sostenuto_sw_off_notevv1),a
  683.                         ld (.sostenuto_sw_off_notevv2),a
  684.                         ld (.sostenuto_sw_off_notevv3),a
  685.                         ld (.sostenuto_sw_off_notevv4),a
  686.                         push af
  687.                         ld c,a
  688.                         ld e,0
  689. .sostenuto_midi_channel equ $-1
  690.                         bit 2,(ix+0)                ;if (note & SNDRV_MIDI_NOTE_SOSTENUTO) == 0
  691. .sostenuto_sw_off_notevv1 equ $-2
  692.                         jp z,.sostenuto_sw_off_skip_loop
  693.                         res 2,(ix+0)            ;note[i] &= ~SNDRV_MIDI_NOTE_SOSTENUTO
  694. .sostenuto_sw_off_notevv2 equ $-2
  695.                         bit 1,(ix+0)            ;if (note & SNDRV_MIDI_NOTE_RELEASED) == 0
  696. .sostenuto_sw_off_notevv3 equ $-2
  697.                         jp z,.sostenuto_sw_off_skip_loop
  698.                         call _j_note_off_1
  699.                         ld (ix+0),SNDRV_MIDI_NOTE_OFF
  700. .sostenuto_sw_off_notevv4 equ $-2
  701. .sostenuto_sw_off_skip_loop:
  702.                         pop af      
  703.                         dec a
  704.                         cp 0x7f
  705.                         jr nz,.sostenuto_sw_off_loop
  706.                         ret
  707.                        
  708. _j_program_change:
  709.                                         ;b - data_byte_1 - command
  710.                                         ;c - data_byte_2 - new program number (instrument)
  711.                                         ;e - wave channel
  712.                         push ix
  713.                         ld a,e
  714.                         add a,a
  715.                         ld h,HIGH midi_ch_table
  716.                         ld l,a    
  717.                         ld a,(hl)    
  718.                         inc hl  
  719.                         ld h,(hl)
  720.                         ld l,a
  721.                         push hl
  722.                         pop ix
  723.                         ld a,c
  724.                         and 0x7f
  725.                         ld (ix+MIDI_CHANNEL_DATA.instrument-128),a
  726.                         pop ix
  727.                         ret
  728.  
  729. _j_channel_after_touch:
  730.                                         ;b - data_byte_1 - command
  731.                                         ;c - data_byte_2 - pressure
  732.                                         ;e - wave channel
  733.                         ret
  734.  
  735. _j_pitch_wheel:
  736. ;pitch_wheel(midi_channel, ((data_byte_3 <<= 7) | data_byte_2));
  737.                         memory_stream_read_1 d    ;data_byte_3
  738.                                                                         ;b - data_byte_1 - command
  739.                                                                         ;c - data_byte_2 - pitch wheel 0lllllll
  740.                                                                         ;d - data_byte_3 - pitch wheel 0mmmmmmm
  741.                                                                         ;e - wave channel    
  742.                         push ix
  743.                         ld a,e
  744.                         add a,a
  745.                         ld h,HIGH midi_ch_table
  746.                         ld l,a    
  747.                         ld a,(hl)    
  748.                         inc hl  
  749.                         ld h,(hl)
  750.                         ld l,a
  751.                         push hl
  752.                         pop ix
  753.                         ld (.comparrerr),ix  ; store midi channel data
  754.                         ld h,0
  755.                         ld l,d  
  756.                         SRL H   ;<<7
  757.                         RR L
  758.                         LD H, L
  759.                         LD L, 0
  760.                         RR L
  761.                         ld a,l
  762.                         or c
  763.                         ld l,a    ;hl - pitch wheel data combined 14bit
  764.                         ld bc,8192
  765.                         and a
  766.                         sbc hl,bc
  767.                         ld (ix+MIDI_CHANNEL_DATA.pitch_bend-128),hl    
  768.                         push iy
  769.                         ld ix,g_header.g_voice_data
  770.                         ld iy,NR_OF_WAVE_CHANNELS
  771. .loop_v1:        
  772.             ld a,(IX+VOICE_DATA.is_active)
  773.             and a
  774.             jr z,.nnofffooond
  775.  
  776.             ld hl,(IX+VOICE_DATA.midi_channel)
  777.             ld de,0
  778. .comparrerr:    equ $-2
  779.             and a
  780.             sbc hl,de        
  781.             jr nz,.nnofffooond
  782.             push ix
  783.                         ld iy,(.comparrerr)
  784.                         ;in ix - g_voice_data     iy - g_midi_channel_data
  785.                         call update_pitch
  786.             pop ix
  787. .nnofffooond:
  788.             ld de,VOICE_DATA    
  789.             add ix,de
  790.             dec iyl
  791.             jr nz,.loop_v1            
  792.                         pop iy
  793.                         pop ix
  794.                         ret
  795.  
  796.  
  797.  
  798. _j_note_on:
  799.                         memory_stream_read_1 d   ;data_byte_3
  800.                                                                         ;b - data_byte_1 - command
  801.                                                                         ;c - data_byte_2 - note
  802.                                                                         ;d - data_byte_3 - velocity
  803.                                                                         ;e - midi channel
  804.             ld a,d
  805.             and 0x7f
  806.             jp z,_j_note_off_1
  807.             ld (.on_v_midi_veloc),a
  808.             ld a,c
  809.             and 0x7f
  810.             ld (.on_v_midi_note),a
  811.             cpl
  812.             ld (._note_evv),a
  813.                         push ix
  814.                         ld a,e
  815.                         add a,a
  816.                         ld h,HIGH midi_ch_table
  817.                         ld l,a    
  818.                         ld a,(hl)    
  819.                         inc hl  
  820.                         ld h,(hl)
  821.                         ld l,a
  822.                         ld (.on_v_midi_ch),hl
  823.                         push hl
  824.                         pop ix    
  825.                         ld (ix+0),SNDRV_MIDI_NOTE_ON            ; DD 21 offset value ;MIDI_CHANNEL_DATA note status
  826. ._note_evv equ $-2
  827.                         ld a,(ix+MIDI_CHANNEL_DATA.vibrato-128)
  828.                         ld (update_vibrato_depth.ctl_vibrato),a
  829.                         xor a
  830.                         ld (n_on_voices),a
  831.                         ld hl,n_on_data
  832.                         ld (n_on_data_ptr),hl
  833.                         ld a,(ix+MIDI_CHANNEL_DATA.drum_channel-128)
  834.                         and a
  835.                         jr z,.not_drum_chanel
  836. .drummsssss
  837.                         ld hl,snd_yrw801_regions+0x80*2
  838.                         ld a,(hl)
  839.                         inc hl
  840.                         ld h,(hl)
  841.                         ld l,a    ;hl - pointer to regions_drums
  842.                         ;ld a,(.on_v_midi_note)
  843.                         ld a,c
  844.                         cp 0x23
  845.                         jp c,.exit_sub        
  846.                         cp 0x53
  847.                         jp nc,.exit_sub        
  848.                         sub 0x1a+9
  849.                         ld d,0
  850.                         ld e,a
  851.                         ex de,hl
  852.                         add hl,hl
  853.                         add hl,hl
  854.                         add hl,hl
  855.                         add hl,hl
  856.                         add hl,de
  857.                         inc hl:inc hl   ;hl = drums wave data region
  858.                         ld de,(n_on_data_ptr)
  859.                         ld a,l
  860.                         ld (de),a
  861.                         inc de
  862.                         ld a,h
  863.                         ld (de),a
  864.                         ld hl,(n_on_data_ptr)
  865.                         ld de,4
  866.                         add hl,de
  867.                         ld (n_on_data_ptr),hl
  868.                         ld hl,n_on_voices
  869.                         inc (hl)
  870.                         jr .n_on_alloc_init_voices  
  871. .not_drum_chanel:
  872.                         ld a,(ix+MIDI_CHANNEL_DATA.instrument-128)
  873.                         add a,a
  874.                         ld d,0
  875.                         ld e,a
  876.                         ld hl,snd_yrw801_regions
  877. ._drum_chanel:
  878.                         add hl,de        
  879.                         ld a,(hl)
  880.                         inc hl
  881.                         ld h,(hl)
  882.                         ld l,a      ;hl - instrument region
  883. .loop_nd
  884.                         ld a,(hl)
  885.                         cp 0xff
  886.                         jr z,.n_on_alloc_init_voices
  887.                         cp c
  888.                         jr z,.found_by_low
  889.                         jr c,.check_by_high                
  890.                         ld de,16
  891.                         add hl,de
  892.                         jr .loop_nd
  893. .check_by_high:
  894.                         inc hl
  895.                         ld a,(hl)
  896.                         cp c
  897.                         jr z,.found_by_high
  898.                         jr nc,.found_by_high
  899.  
  900.                         ld de,15
  901.                         add hl,de
  902.                         jr .loop_nd
  903. .found_by_low:
  904.                         inc hl
  905. .found_by_high:
  906.                         inc hl
  907.                         ld de,(n_on_data_ptr)
  908.                         ld a,l
  909.                         ld (de),a
  910.                         inc de
  911.                         ld a,h
  912.                         ld (de),a
  913.                         push hl
  914.                         ld hl,(n_on_data_ptr)
  915.                         ld de,4
  916.                         add hl,de
  917.                         ld (n_on_data_ptr),hl
  918.                         ld hl,n_on_voices
  919.                         inc (hl)
  920.                         pop hl
  921.                         ld de,14
  922.                         add hl,de
  923.                         ld a,(n_on_voices)
  924.                         cp 2
  925.                         jr nc,.n_on_alloc_init_voices
  926.                         jr .loop_nd
  927. .n_on_alloc_init_voices:
  928.             ld a,(n_on_voices)
  929.             and a
  930.             jp z,.exit_sub        
  931.             ld (.n_onv_test),a
  932.             ld (.n_onv_test2),a
  933.             ld (.n_onv_test4),a
  934.             ld (.n_onv_test5),a
  935.                         xor a   ;voice number for loop
  936. .gv_loop:    
  937.                         push af
  938.                         ; get wave data adress by voice number
  939.                         add a,a
  940.                         add a,a    
  941.                         ld d,0
  942.                         ld e,a                    
  943.                         ld hl,n_on_data
  944.                         add hl,de
  945.                         ld e,(hl)
  946.                         inc hl
  947.                         ld d,(hl)
  948.                         inc hl
  949.                         push de     ;wave data adress in yrw801 table    
  950.                         push hl   ;store pointer
  951.                         call get_voice  ;out  
  952.                         pop hl  
  953. .checkpoint:
  954.                         ;ix = free_voice  
  955.                         ld a,ixl                          
  956.                         ld (hl),a      ;ld (hl),e
  957.                         inc hl
  958.                         ld a,ixh
  959.                         ld (hl),a      ;ld (hl),d
  960.                         ld (ix+VOICE_DATA.is_active),1
  961.                         ld hl,(g_MIDI_counter)
  962.                         LD (ix+VOICE_DATA.activated),hl
  963.                         ld hl,(g_MIDI_counter+2)
  964.                         LD (ix+VOICE_DATA.activated+2),hl
  965.                         ld de,0
  966. .on_v_midi_ch: equ $-2      
  967.                         ld (ix+VOICE_DATA.midi_channel),de
  968.                         ld (ix+VOICE_DATA.note),0
  969. .on_v_midi_note equ $-1  
  970.                         ld (ix+VOICE_DATA.velocity),0
  971. .on_v_midi_veloc        equ $-1
  972.                         pop hl
  973.                         ld (ix+VOICE_DATA.wave_data),hl
  974.                         pop af
  975.                         inc a  
  976.                         cp 0
  977. .n_onv_test equ $-1
  978.                         jr nz,.gv_loop                  
  979.                         xor a   ;voice number for loop
  980. .gr_loop:    
  981.                         push af
  982. ; get wave data adress by voice number
  983.                         add a,a
  984.                         add a,a    
  985.                         ld d,0
  986.                         ld e,a                    
  987.                         ld hl,n_on_data
  988.                         add hl,de
  989.                         ld e,(hl)
  990.                         inc hl
  991.                         ld d,(hl)
  992.                         inc hl    
  993.                         push de
  994.                         pop iy    ; iy wave data pointer
  995.                         ld e,(hl)
  996.                         inc hl
  997.                         ld d,(hl)
  998.                         push de
  999.                         pop ix    ;ix - voice data pointer
  1000. /* Set tone number (triggers header loading) */
  1001.                         ld a,(iy+YRW801_WAVE_DATA.panpot)
  1002.                         ld (update_pan.yrw_panpot),a
  1003.                         ld a,(iy+YRW801_WAVE_DATA.tone_attenuate)
  1004.                         ld (update_volume.yrw_tone_attenuate),a
  1005.                         ld a,(iy+YRW801_WAVE_DATA.volume_factor)
  1006.                         ld (update_volume.yrw_volume_factor),a
  1007.                         ld hl,(IY+YRW801_WAVE_DATA.tone)
  1008.                         push hl
  1009.                         ld a,h
  1010.                         and OPL4_TONE_NUMBER_BIT8
  1011.                         ld (ix+VOICE_DATA.reg_f_number),a
  1012.                         ld d,a    
  1013.                         LD a,(ix+VOICE_DATA.number)                    
  1014.                         add a,OPL4_REG_F_NUMBER
  1015.                         ld e,a
  1016.                         call opl4writewave                      
  1017.                         pop hl                            
  1018.                         ld d,l
  1019.                         LD a,(ix+VOICE_DATA.number)                    
  1020.                         add a,OPL4_REG_TONE_NUMBER
  1021.                         ld e,a
  1022.                         call opl4writewave                                          
  1023. /* Set parameters which can be set while loading */
  1024.                         ld (ix+VOICE_DATA.reg_misc),OPL4_LFO_RESET_BIT
  1025.                         ld hl,(ix+VOICE_DATA.midi_channel)
  1026.                         push hl
  1027.                         pop iy
  1028.                         call update_pan
  1029.                         call update_pitch
  1030.                         ld (ix+VOICE_DATA.level_direct),OPL4_LEVEL_DIRECT_BIT    
  1031.                         call update_volume
  1032.                         pop af
  1033.                         inc a  
  1034.                         cp 0
  1035. .n_onv_test2 equ $-1
  1036.                         jp nz,.gr_loop
  1037. .ello
  1038.                         in a,(MOON_STAT)
  1039.                         and 0x02
  1040.                         jr nz,.ello
  1041.                         xor a   ;voice number for loop
  1042. .gn_loop:    
  1043.                         push af
  1044.                         ; get wave data adress by voice number
  1045.                         add a,a
  1046.                         add a,a    
  1047.                         ld d,0
  1048.                         ld e,a                    
  1049.                         ld hl,n_on_data
  1050.                         add hl,de
  1051.                         ld e,(hl)
  1052.                         inc hl
  1053.                         ld d,(hl)
  1054.                         inc hl    
  1055.                         push de
  1056.                         pop iy    ; iy wave data pointer
  1057.                         ld e,(hl)
  1058.                         inc hl
  1059.                         ld d,(hl)
  1060.                         push de
  1061.                         pop ix    ;ix - voice data pointer
  1062.                         ld h,(IX+VOICE_DATA.number)
  1063.                         ld a,(IY+YRW801_WAVE_DATA.vibrato)
  1064.                         ld (update_vibrato_depth.vibrato_data),a
  1065.                         ;update tone parameters
  1066.                         ld d,(IY+YRW801_WAVE_DATA.reg_attack_decay1)
  1067.                         ld a,OPL4_REG_ATTACK_DECAY1
  1068.                         add a,h;(IX+VOICE_DATA.number)
  1069.                         ld e,a
  1070.                         call opl4writewave
  1071.                         ld d,(IY+YRW801_WAVE_DATA.reg_level_decay2)
  1072.                         ld a,OPL4_REG_LEVEL_DECAY2
  1073.                         add a,h;(IX+VOICE_DATA.number)
  1074.                         ld e,a
  1075.                         call opl4writewave
  1076.                         ld d,(IY+YRW801_WAVE_DATA.reg_release_correction)
  1077.                         ld a,OPL4_REG_RELEASE_CORRECTION
  1078.                         add a,h;(IX+VOICE_DATA.number)
  1079.                         ld e,a
  1080.                         call opl4writewave
  1081.                         ld d,(IY+YRW801_WAVE_DATA.reg_tremolo)
  1082.                         ld a,OPL4_REG_TREMOLO
  1083.                         add a,h;(IX+VOICE_DATA.number)
  1084.                         ld e,a
  1085.                         call opl4writewave
  1086.                         ld a,(IY+YRW801_WAVE_DATA.reg_lfo_vibrato)
  1087.                         ld (IX+VOICE_DATA.reg_lfo_vibrato),a
  1088.                         push hl  
  1089.                         ld hl,(IX+VOICE_DATA.midi_channel)
  1090.                         push hl
  1091.                         pop iy
  1092.                         ld a,(IY+MIDI_CHANNEL_DATA.drum_channel-128)
  1093.                         and a
  1094.                         call z,update_vibrato_depth
  1095.                         pop hl
  1096.                         pop af
  1097.                         inc a  
  1098.                         cp 0
  1099. .n_onv_test4 equ $-1
  1100.                         jr nz,.gn_loop
  1101.  
  1102.                         xor a   ;voice number for loop
  1103. .gn5_loop:    
  1104.                         push af
  1105.                         ; get wave data adress by voice number
  1106.                         add a,a
  1107.                         add a,a    
  1108.                         ld d,0
  1109.                         ld e,a                    
  1110.                         ld hl,n_on_data
  1111.                         add hl,de
  1112.                         ld e,(hl)
  1113.                         inc hl
  1114.                         ld d,(hl)
  1115.                         inc hl    
  1116.                         push de
  1117.                         pop iy    ; iy wave data pointer
  1118.                         ld e,(hl)
  1119.                         inc hl
  1120.                         ld d,(hl)
  1121.                         push de
  1122.                         pop ix    ;ix - voice data pointer
  1123.                         ld a,(ix+VOICE_DATA.reg_misc)
  1124.                         and 00011111b
  1125.                         or OPL4_KEY_ON_BIT
  1126.                         ld (IX+VOICE_DATA.reg_misc),a
  1127.                         ld d,a
  1128.                         ld a,OPL4_REG_MISC
  1129.                         add a,(IX+VOICE_DATA.number)
  1130.                         ld e,a
  1131.                         call opl4writewave
  1132.                         pop af
  1133.                         inc a  
  1134.                         cp 0
  1135. .n_onv_test5 equ $-1
  1136.                         jr nz,.gn5_loop
  1137. .exit_sub
  1138.                         pop ix
  1139.                         ret
  1140.  
  1141.  
  1142. update_vibrato_depth:
  1143.                         ld hl,0x007
  1144.                         ld d,0         ;d=0
  1145.                         ld e,0  
  1146. .vibrato_data equ $-1                   ;(IY+YRW801_WAVE_DATA.vibrato)
  1147.                         push de            ;save YRW801_WAVE_DATA.vibrato
  1148.                         and a
  1149.                         sbc hl,de
  1150.                         ex de,hl  ; de - 7-YRW801_WAVE_DATA.vibrato
  1151.                         ld a,0
  1152. .ctl_vibrato equ $-1
  1153.                         and 0x7f
  1154.                         ld hl,0
  1155.                         ld c,0
  1156.                         call mult_de_a      ;de * midi_channel->vibrato
  1157.                         ;hl = depth
  1158.                         ADD HL,HL    ;11       signed hl >> 7
  1159.                         LD L,H    ;4
  1160.                         SBC A    ;4
  1161.                         LD H,A    ;4    23t
  1162.                         pop de
  1163.                         add hl,de   ;l = depth + YRW801_WAVE_DATA.vibrato    ;  h is unused
  1164.                         ld a,l
  1165.                         and OPL4_VIBRATO_DEPTH_MASK                                                            
  1166.                         ld l,a           ; l = depth & OPL4_VIBRATO_DEPTH_MASK
  1167.                         ld a,(ix+VOICE_DATA.reg_lfo_vibrato)
  1168.                         and OPL4_VIBRATO_DEPTH_MASK_INV
  1169.                         or l
  1170.                         ld (ix+VOICE_DATA.reg_lfo_vibrato),a
  1171.                         ld d,a
  1172.                         ld a,OPL4_REG_LFO_VIBRATO
  1173.                         add a,(ix+VOICE_DATA.number)
  1174.                         ld e,a
  1175.                         jp opl4writewave
  1176.                        
  1177. update_pan:
  1178.  
  1179.             ld d,0     ;l        d d,(iy+YRW801_WAVE_DATA.panpot)
  1180. .yrw_panpot   equ $-1
  1181.                         ld a,(iy+MIDI_CHANNEL_DATA.drum_channel-128)
  1182.                         and a
  1183.                         jr nz,.drum_is
  1184.                         ld a,(iy+MIDI_CHANNEL_DATA.panpot-128)
  1185.                         add a,d
  1186.                         ld d,a
  1187. .drum_is:
  1188.                         bit 7,d
  1189.                         ld a,d
  1190.                         jr nz,.below_zero
  1191.                         cp 8
  1192.                         jr c,.adv_run  
  1193.                         ld a,7
  1194.                         jr .adv_run  
  1195. .below_zero:
  1196.                         cp 0xf9   ;-1
  1197.                         jr nc,.adv_run
  1198.                         ld a,0xf9                
  1199. .adv_run    
  1200.                         and OPL4_PAN_POT_MASK
  1201.                         ld d,a
  1202.                         ld a,(ix+VOICE_DATA.reg_misc)
  1203.                         and OPL4_PAN_POT_MASK_INV
  1204.                         or d
  1205.                         ld (ix+VOICE_DATA.reg_misc),a
  1206.                         ld d,a
  1207.                         ld a,(ix+VOICE_DATA.number)
  1208.                         add a,OPL4_REG_MISC
  1209.                         ld e,a
  1210.                         jp opl4writewave
  1211.  
  1212.  
  1213. update_pitch:
  1214.                         push ix
  1215.                         ld hl,(ix+VOICE_DATA.wave_data)        
  1216.                         ld a,h
  1217.                         or l
  1218.                         jp z,.rerett2
  1219.                         push hl
  1220.                         pop ix
  1221.                         ld a,(ix+YRW801_WAVE_DATA.key_scaling)    
  1222.                         ld hl,(ix+YRW801_WAVE_DATA.pitch_offset)
  1223.                         jp .rerett1
  1224. .rerett2
  1225.             ld a,100        
  1226.             ld hl,0
  1227. .rerett1:
  1228.                         ld (.key_scaling),a
  1229.                         ld (.pitch_offset),hl
  1230.                         pop ix
  1231.  
  1232.                         ld a,(iy+MIDI_CHANNEL_DATA.drum_channel-128)
  1233.                         and a
  1234.                         ld de,0:ld h,d:ld l,e   ;pitch int32_t
  1235.                         jp nz,.drum_is
  1236.                         ;;;;int32_t pitch = (voice->midi_channel->drum_channel) ? 0 : voice->note - 60;
  1237.                         ld l,(ix+VOICE_DATA.note)
  1238.                         and a
  1239.                         ld bc,60
  1240.                         sbc hl,bc
  1241.                         ;hl - int16_t   - pitch                    
  1242.                         SRL H
  1243.                         RR L
  1244.                         LD H, L
  1245.                         LD L, 0
  1246.                         RR L           ;hl*128
  1247.                         bit 7,h              
  1248.                         jp z,.drum_is
  1249.                         dec de                                                                                                                
  1250. .drum_is
  1251. .key_scaling equ $+1
  1252.                         ld a, 0 ;(IY+MIDI_CHANNEL_DATA.key_scaling-128)
  1253.                         cp 100
  1254.                         jp z,._skip_math
  1255. ;pitch = (pitch * voice->wave_data->key_scaling) / 100;
  1256. ; dehl    int32_t pitch
  1257. ;a - int8_t   key_scaling
  1258.  
  1259.                         push de
  1260.                         pop bc
  1261.                         ex de,hl                    
  1262.                         push ix
  1263.                         call BCDE_Times_A    ;Outputs: A:HL:IX is the 40-bit product, BC,DE unaffected
  1264.                         push hl,ix
  1265.                         pop hl,de
  1266.                         bit 7,b    
  1267.                         jp z,.positive_div
  1268. .negative_div                                        
  1269.                         ld a,h:cpl:ld h,a
  1270.                         ld a,l:cpl:ld l,a
  1271.                         ld a,d:cpl:ld d,a
  1272.                         ld a,e:cpl:ld e,a                                  
  1273.                         ld c,100
  1274.                         call DEHL_Div_C    
  1275.                         ld a,h:cpl:ld h,a
  1276.                         ld a,l:cpl:ld l,a
  1277.                         ld a,d:cpl:ld d,a
  1278.                         ld a,e:cpl:ld e,a                                  
  1279.                         jp .prrr
  1280. .positive_div        
  1281.                         ld c,100
  1282.                         call DEHL_Div_C
  1283. .prrr
  1284. ; DEHL is the result of the division
  1285.                         pop ix
  1286. ._skip_math                    
  1287. ;pitch = pitch + 7680      
  1288.                         ld bc,7680   ;(60 << 7)
  1289.                         add hl,bc
  1290.                         ld bc,0
  1291.                         ex de,hl
  1292.                         adc hl,bc
  1293.                         ex de,hl
  1294. ;pitch = pitch +  voice->wave_data->pitch_offset;
  1295. .pitch_offset: equ $+1        
  1296.                         ld bc,0  ;(IY+MIDI_CHANNEL_DATA.pitch_offset-128)
  1297.                         add hl,bc
  1298.                         ld bc,0
  1299.                         ex de,hl
  1300.                         adc hl,bc
  1301.                         ex de,hl
  1302. ;       if (!chan->drum_channel)
  1303. ;               pitch += chan->gm_rpn_coarse_tuning;
  1304.                         ld a,(IY+MIDI_CHANNEL_DATA.drum_channel-128)
  1305.                         and a
  1306.                         jp nz,._its_drum_channel
  1307.                         ld bc,(IY+MIDI_CHANNEL_DATA.gm_rpn_coarse_tuning-128)
  1308.                         add hl,bc
  1309.                         ld bc,0
  1310.                         ex de,hl
  1311.                         adc hl,bc
  1312.                         ex de,hl                            
  1313. ._its_drum_channel
  1314. ;       pitch += chan->gm_rpn_fine_tuning >> 7;
  1315.  
  1316.                         ld bc,(IY+MIDI_CHANNEL_DATA.gm_rpn_fine_tuning-128)
  1317.                         add hl,bc
  1318.                         ld bc,0
  1319.                         ex de,hl
  1320.                         adc hl,bc
  1321.                         ex de,hl
  1322.  
  1323. ;       pitch += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 0x2000;
  1324.  
  1325.                         ld bc,(IY+MIDI_CHANNEL_DATA.pitch_bend-128)
  1326.                         ld a,b
  1327.                         or c
  1328.                         jp z,.skip_math2    
  1329.                         push de
  1330.                         push hl
  1331.                         ld de,(IY+MIDI_CHANNEL_DATA.gm_rpn_pitch_bend_range-128)
  1332.                         call intmul16
  1333.                         exx                                                            
  1334.                         ld de,0x0000                                                          
  1335.                         ld hl,0x2000              
  1336.                         exx                                                                    
  1337.                         push ix,iy
  1338.                         call uintdiv32                                                
  1339.                         pop iy,ix  
  1340.                         pop de
  1341.                         add hl,de
  1342.                         pop de    
  1343. .skip_math2
  1344. .limiter
  1345.                         bit 7,h ;d
  1346.                         jp nz,.ll3z  
  1347.                         ld a,h
  1348.                         cp 0x60
  1349.                         jp c,.dsds            
  1350.                         ld hl,0x5fff
  1351.                         jp .dsds            
  1352. .ll3z
  1353.                         ;value is negative
  1354.                         ld hl,0
  1355. .dsds:
  1356.                         ;hl - pitch
  1357.                         ld de,0x600
  1358.                         ld a,h
  1359.                         ld c,l
  1360.                         call div_ac_de      ;c = octave  ;hl - remainder
  1361.                         ld a,c
  1362.                         sub 8
  1363.                         add a,a:add a,a:add a,a:add a,a
  1364.                         ld (.octave),a     ;c - octave   .octave - octave<<4
  1365.                         add hl,hl
  1366.                         ld de,g_wave_pitch_map
  1367.                         add hl,de
  1368.                         ld a,(hl)  
  1369.                         inc hl
  1370.                         ld h,(hl)
  1371.                         ld l,a    ;hl = fnumber pitch from ms_wave_pitch_map                          
  1372.                         push hl
  1373.                         ;fnumber >>7
  1374.                         ADD HL,HL    ;11       signed hl >> 7
  1375.                         LD L,H    ;4
  1376.                         SBC A    ;4
  1377.                         LD H,A    ;4    23t
  1378.                         ld a,l
  1379.                         and OPL4_F_NUMBER_HIGH_MASK
  1380.                         ld d,a
  1381.                         ld a,0
  1382. .octave    equ $-1
  1383.                         or d
  1384.                         ld d,a
  1385.                         ld a,OPL4_REG_OCTAVE
  1386.                         add a,(IX+VOICE_DATA.number)
  1387.                         ld e,a
  1388.                         call opl4writewave
  1389.                         pop hl
  1390.                         ld a,l
  1391.                         add a,a
  1392.                         and OPL4_F_NUMBER_LOW_MASK
  1393.                         ld d,a
  1394.                         ld a,(IX+VOICE_DATA.reg_f_number)
  1395.                         and OPL4_TONE_NUMBER_BIT8
  1396.                         or d
  1397.                         ld (ix+VOICE_DATA.reg_f_number),a
  1398.                         ld d,a
  1399.                         ld a,OPL4_REG_F_NUMBER
  1400.                         add a,(ix+VOICE_DATA.number)
  1401.                         ld e,a
  1402.                         call opl4writewave
  1403.                         ret
  1404.            
  1405.            
  1406. update_volume:
  1407.                         ld d,0
  1408.                         ld e,0   ;(IY+YRW801_WAVE_DATA.tone_attenuate)  ;att
  1409. .yrw_tone_attenuate equ $-1
  1410. ;att += snd_opl4_volume_table[voice->chan->gm_volume & 0x7f];
  1411.                         push ix
  1412.                         ld hl,(ix+VOICE_DATA.midi_channel)
  1413.                         push hl
  1414.                         pop ix
  1415.                         ld l,(IX+MIDI_CHANNEL_DATA.gm_volume-128)  
  1416.                         ld h,HIGH g_volume_table
  1417.  
  1418.                         ld a,e
  1419.                         add a,(hl)    ;att+=midi_ch.gm_volume
  1420.                         ld e,a
  1421.  
  1422.                         ld a,d
  1423.                         adc a,0
  1424.                         ld d,a 
  1425.  
  1426. ;att += snd_opl4_volume_table[voice->chan->gm_expression & 0x7f];
  1427.                         ld l,(IX+MIDI_CHANNEL_DATA.gm_expression-128)  
  1428.                         ld a,e
  1429.                         add a,(hl)    ;att+=midi_ch.expression
  1430.                         ld e,a
  1431.                         ld a,d
  1432.                         adc a,0
  1433.                         ld d,a 
  1434.                         ;att += snd_opl4_volume_table[voice->velocity];
  1435.                         pop ix
  1436.                         ld l,(ix+VOICE_DATA.velocity)
  1437.                         ld a,e
  1438.                         add a,(hl)    ;att+=voice.velocity
  1439.                         ld e,a
  1440.                         ld a,d
  1441.                         adc a,0
  1442.                         ld d,a 
  1443.                         ld hl,0x007f
  1444.                         and a
  1445.                         sbc hl,de
  1446.                         ex de,hl  ;de = (0x7f-att)
  1447.                         ld a,0   ;(IY+YRW801_WAVE_DATA.volume_factor)
  1448. .yrw_volume_factor equ $-1
  1449.                         ld hl,0
  1450.                         ld c,0
  1451.                         call mult_de_a
  1452.                         ld c,0xfe
  1453.                         bit 7,h
  1454.                         jr z,.positive
  1455.                         ld a,h:cpl:ld h,a
  1456.                         ld a,l:cpl:ld l,a
  1457.                         call div_hl_c        
  1458.                         ld a,h:cpl:ld h,a
  1459.                         ld a,l:cpl:ld l,a
  1460.                         jr .contaa
  1461. .positive
  1462.                         call div_hl_c        
  1463.  
  1464. .contaa
  1465.                         ld de,0x007f
  1466.                         ex de,hl
  1467.                         and a
  1468.                         sbc hl,de
  1469.                         ld a,(g_volume_boost)
  1470.                         ld e,a
  1471.                         ld d,0
  1472.                         and a
  1473.                         sbc hl,de
  1474.                         bit 7,h
  1475.                         jr nz,.below_zero
  1476.                         ld a,l
  1477.                         cp 0x7f
  1478.                         jr c,.okk  ;value in 0 -0x7e
  1479.                         ld a,0x7e           ;value is positive
  1480.                         jr .okk
  1481. .below_zero
  1482.                         ;value is negative
  1483.                         ld a,0
  1484. .okk:
  1485.                         add a,a
  1486.                         or (ix+VOICE_DATA.level_direct)
  1487.                         ld d,a
  1488.                         ld a,OPL4_REG_LEVEL    
  1489.                         add a,(ix+VOICE_DATA.number)
  1490.                         ld e,a
  1491.                         call opl4writewave
  1492.                         ld (ix+VOICE_DATA.level_direct),0
  1493.                         ret          
  1494.            
  1495.        
  1496. handle_meta_event:        
  1497.                         ld a,c  
  1498.                         cp 0x2f
  1499.                         jr z,.endoftrack
  1500.                         cp 0x51
  1501.                         jr z,.setduration
  1502.                        
  1503.                         ld hl,(memorystreamcurrentaddr)
  1504.                         call midreadvarint  ;;read count of upcoming parameters
  1505.                         ld a,e
  1506.                         or d
  1507.                         jr z,.skipall
  1508.                         ld a,e
  1509.                         dec de
  1510.                         inc d
  1511.                         ld c,d
  1512.                         ld b,a
  1513. .skiploop:
  1514.                         bit 6,h
  1515.                         call nz,memorystreamnextpage
  1516.                         inc hl
  1517.                         djnz .skiploop
  1518.                         dec c
  1519.                         jr nz,.skiploop
  1520. .skipall:
  1521.                         ld (memorystreamcurrentaddr),hl
  1522.                         ret
  1523. .endoftrack
  1524.                         ld a,255
  1525.                         ld (ix+TRACK_DATA.track_finished),a
  1526.                         ret
  1527. .setduration
  1528.                         ld hl,(memorystreamcurrentaddr)
  1529.                         call midreadvarint  ;read count of upcoming parameters
  1530.                         memory_stream_read_byte a
  1531.                         memory_stream_read_byte d
  1532.                         memory_stream_read_byte e
  1533.                         ld (memorystreamcurrentaddr),hl
  1534.                         ex de,hl
  1535.                         ld e,a
  1536.                         ld d,0
  1537.                         push ix
  1538.                         call setticksperupdate
  1539.                         pop ix
  1540.                         ret    
  1541. finalize:
  1542.                         ld hl,(memorystreamcurrentaddr)
  1543.                         call midreadvarint                  ;read delta-time
  1544.                         ld (memorystreamcurrentaddr),hl
  1545.                         ld b,0
  1546.                         sla de : rl bc
  1547.                         sla de : rl bc
  1548.                         ld hl,(ix+TRACK_DATA.waiting_for+0)
  1549.                         add hl,de
  1550.                         ld (ix+TRACK_DATA.waiting_for+0),hl
  1551.                         ld hl,(ix+TRACK_DATA.waiting_for+2)
  1552.                         adc hl,bc
  1553.                         ld (ix+TRACK_DATA.waiting_for+2),hl
  1554.                         ret
  1555.  
  1556.                                                 ;gv_wavedata dw 0  
  1557.    
  1558.    
  1559. get_voice:    
  1560. ;in de - wave data
  1561.                         ld ix,g_header.g_voice_data
  1562.                         ld (free_voice),ix
  1563.                         ld (oldest_voice),ix
  1564.                         ld bc,NR_OF_WAVE_CHANNELS
  1565. .loop3
  1566.                         LD a,(ix+VOICE_DATA.is_active)
  1567.                         and a
  1568.                         jr z,.voice_not_active
  1569.                         ;voice active
  1570.                         ld iy,(oldest_voice)
  1571.                         and a
  1572.                         ld l,(ix+VOICE_DATA.activated)
  1573.                         ld h,(ix+VOICE_DATA.activated+1)
  1574.                         ld e,(iy+VOICE_DATA.activated)
  1575.                         ld d,(iy+VOICE_DATA.activated+1)
  1576.                         sbc hl,de
  1577.                         ld l,(ix+VOICE_DATA.activated+2)
  1578.                         ld h,(ix+VOICE_DATA.activated+3)
  1579.                         ld e,(iy+VOICE_DATA.activated+2)
  1580.                         ld d,(iy+VOICE_DATA.activated+3)
  1581.                         sbc hl,de
  1582.                         jr nc,.loop_ext
  1583. .old_greater:
  1584.                         ld (oldest_voice),ix
  1585.                         jp .loop_ext
  1586. .voice_not_active:
  1587.             ;voice inactive
  1588. .vo_not_cat_not_match:
  1589.             ld iy,(free_voice)
  1590.             and a
  1591.             ld l,(ix+VOICE_DATA.activated)
  1592.             ld h,(ix+VOICE_DATA.activated+1)
  1593.             ld e,(iy+VOICE_DATA.activated)
  1594.             ld d,(iy+VOICE_DATA.activated+1)
  1595.                 sbc hl,de
  1596.             ld l,(ix+VOICE_DATA.activated+2)
  1597.             ld h,(ix+VOICE_DATA.activated+3)
  1598.             ld e,(iy+VOICE_DATA.activated+2)
  1599.             ld d,(iy+VOICE_DATA.activated+3)
  1600.                 sbc hl,de
  1601.             jr nc,.loop_ext  ;jr nc,.loop_ext  
  1602. .vo_old_greater:
  1603.                         ld (free_voice),ix
  1604.                         jr .loop_ext
  1605.  
  1606. .loop_ext:
  1607.                 ld de,VOICE_DATA
  1608.                 add ix,de
  1609.                 ;dec iyl
  1610.             dec c
  1611.                 jp nz,.loop3
  1612. .loop_exit
  1613. ;    /* If no free voice found, deactivate the 'oldest' */
  1614. ;    if(free_voice->is_active)
  1615. ;    {
  1616. ;        free_voice = oldest_voice;
  1617. ;        free_voice->activated = 0;
  1618. ;
  1619. ;        free_voice->reg_misc &= ~OPL4_KEY_ON_BIT;
  1620. ;        g_roboplay_interface->opl_write_wave(OPL4_REG_MISC + free_voice->number, free_voice->reg_misc);
  1621. ;    }
  1622.  
  1623.                         ld ix,(free_voice)
  1624.                         ld a,(ix+VOICE_DATA.is_active)
  1625.                         and a
  1626.                         ret z
  1627.                         ld ix,(oldest_voice)
  1628.                         ld (free_voice),ix
  1629.                         xor a
  1630.                         ld (ix+VOICE_DATA.activated),a
  1631.                         ld (ix+VOICE_DATA.activated+1),a
  1632.                         ld (ix+VOICE_DATA.activated+2),a
  1633.                         ld (ix+VOICE_DATA.activated+3),a        
  1634.                         ld a,(ix+VOICE_DATA.reg_misc)
  1635.                         and OPL4_KEY_ON_BIT_INV
  1636.                         LD (ix+VOICE_DATA.reg_misc),a
  1637.                         ld d,a
  1638.                         ;g_roboplay_interface->opl_write_wave(OPL4_REG_MISC + voice->number, voice->reg_misc);
  1639.                         LD a,(ix+VOICE_DATA.number)
  1640.                         add a,OPL4_REG_MISC
  1641.                         ld e,a
  1642.                         jp opl4writewave
  1643.  
  1644. ;=================================================================
  1645. midgetprogress
  1646. ;dehl = ticks
  1647. ;out: a = progress
  1648.         ld a,e
  1649.         add hl,hl : rla
  1650.         add hl,hl : rla
  1651.         add hl,hl : rla
  1652.         add hl,hl : rla
  1653.         ret
  1654.        
  1655. midsetprogressdelta    
  1656.                 ld ix,g_header.g_track_data
  1657.                 ld a,(g_header.number_of_tracks)
  1658.                         ld b,a
  1659.                         ld c,0
  1660. .trackloop
  1661.                         push bc
  1662.                         ld hl,(ix+TRACK_DATA.currentoffset+0)
  1663.                         ld de,(ix+TRACK_DATA.currentoffset+2)
  1664.                         call memorystreamseek
  1665. .eventloop
  1666.                         call midadvancetrack
  1667.                         bit 7,(ix+TRACK_DATA.track_finished)
  1668.                         jr z,.eventloop
  1669.                         ld hl,(ix+TRACK_DATA.waiting_for+0)
  1670.                         ld de,(ix+TRACK_DATA.waiting_for+2)
  1671.                         call midgetprogress
  1672.                         pop bc
  1673.                         cp c
  1674.                         jr c,$+3
  1675.                         ld c,a
  1676.                         ld de,TRACK_DATA
  1677.                         add ix,de
  1678.                         djnz .trackloop
  1679.                         ld a,c
  1680.                         jp setprogressdelta
  1681.  
  1682. midadvancetrack
  1683. ;ix = track
  1684.                 ld hl,(memorystreamcurrentaddr)
  1685.                 memory_stream_read_byte b
  1686.                 bit 7,b
  1687.                 jr z,.gotdatabyte
  1688.                 ld (ix+TRACK_DATA.last_command),b
  1689.                 memory_stream_read_byte d
  1690.                 jr .handlecommand
  1691. .gotdatabyte
  1692.                 ld d,b
  1693.                 ld b,(ix+TRACK_DATA.last_command)
  1694. .handlecommand
  1695.                 ld a,b
  1696.                 rrca
  1697.                 rrca
  1698.                 rrca
  1699.                 rrca
  1700.                 and 7
  1701.                 ld c,a
  1702.                 add a,a
  1703.                 add a,c
  1704.                 ld (.commandtable),a
  1705. .commandtable=$+1
  1706.                 jr $
  1707.                 jp .send3 ; 8 Note Off
  1708.                 jp .send3 ; 9 Note On
  1709.                 jp .send3 ; A Polyphonic Pressure
  1710.                 jp .send3 ; B Control Change   
  1711.                 jp .send2 ; C Program Change
  1712.                 jp .send2 ; D Channel Pressure
  1713.                 jp .send3 ; E Pitch Bend
  1714. ;;;;;;;;;;;;;;;;;;; F System
  1715.                 ld a,b
  1716.                 cp 0xff
  1717.                 jp z,.handlemeta
  1718.                 cp 0xf0
  1719.                 jp nz,.finalize
  1720.                 call midreadvarint
  1721.                 ld d,0xf0
  1722. ;               call_send_byte
  1723. .sendloop
  1724.                 memory_stream_read_byte e
  1725.                 ld d,e
  1726. ;               call_send_byte
  1727.                 ld a,e
  1728.                 cp 0xf7
  1729.                 jr nz,.sendloop
  1730.                 ld (memorystreamcurrentaddr),hl
  1731.                 jr .finalize
  1732. .handlemeta
  1733.                 ld a,d
  1734.                 cp 0x2f
  1735.                 jr z,.markdone
  1736.                 cp 0x51
  1737.                 jr z,.setduration
  1738.                 call midreadvarint
  1739.                 ld a,e
  1740.                 or d
  1741.                 jr z,.finalize
  1742.                 ld a,e
  1743.                 dec de
  1744.                 inc d
  1745.                 ld c,d
  1746.                 ld b,a
  1747. .skiploop
  1748.                 bit 6,h
  1749.                 call nz,memorystreamnextpage
  1750.                 inc hl
  1751.                 djnz .skiploop
  1752.                 dec c
  1753.                 jr nz,.skiploop
  1754.                 ld (memorystreamcurrentaddr),hl
  1755.                 jr .finalize
  1756. .markdone
  1757.                 set 7,(ix+TRACK_DATA.track_finished)
  1758.                 ret
  1759. .setduration
  1760.                 call midreadvarint
  1761.                 memory_stream_read_byte a
  1762.                 memory_stream_read_byte d
  1763.                 memory_stream_read_byte e
  1764.                 ld (memorystreamcurrentaddr),hl
  1765.                 ex de,hl
  1766.                 ld e,a
  1767.                 ld d,0
  1768.                 push ix
  1769.                 call setticksperupdate
  1770.                 pop ix
  1771.                 jr .finalize
  1772. .send2  ld (memorystreamcurrentaddr),hl
  1773.                 ld l,d
  1774.                 ld h,b
  1775. ;               call_send_2
  1776.         jr .finalize
  1777. .send3  memory_stream_read_byte e
  1778.                 ld (memorystreamcurrentaddr),hl
  1779.                 ex de,hl
  1780.                 ld d,b
  1781. ;               call_send_3
  1782. .finalize
  1783.                 ld hl,(memorystreamcurrentaddr)
  1784.                 call midreadvarint
  1785.                 ld (memorystreamcurrentaddr),hl
  1786.                 ld b,0
  1787.                 sla de : rl bc
  1788.                 sla de : rl bc
  1789.                 ld hl,(ix+TRACK_DATA.waiting_for+0)
  1790.                 add hl,de
  1791.                 ld (ix+TRACK_DATA.waiting_for+0),hl
  1792.                 ld hl,(ix+TRACK_DATA.waiting_for+2)
  1793.                 adc hl,bc
  1794.                 ld (ix+TRACK_DATA.waiting_for+2),hl
  1795.                 ret