Subversion Repositories NedoOS

Rev

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