home *** CD-ROM | disk | FTP | other *** search
/ Dave Lowe: Latest Version…itors Megaman XInfo File / Lowe_LatestVersionsOfMusicEditors_MegamanXInfoFile.img / GBOY / D-GBOY30.ASM next >
Encoding:
Assembly Source File  |  1994-10-31  |  54.7 KB  |  2,991 lines

  1. ;-------------------------------------------------------------------------------
  2. ;GAMEBOY MUSIC DRIVER - (c) Martin Walker 1992/1993/1994
  3. ;-------------------------------------------------------------------------------
  4.  
  5. ;example to produce a final customer driver file
  6. ;DEMO        equ    0    ;0=driver only/ 1=demo & driver
  7. ;MUSICROM    equ    04000h    ;Music Driver start address
  8. ;MUSICRAM    equ    0C500h    ;Ram variables start address
  9.  
  10. ;default settings to use with the music editor
  11. DEMO        equ    1    ;0=driver only/ 1=demo & driver
  12. MUSICROM    equ    00490h    ;Driver start address
  13. MUSICRAM    equ    0DE00h    ;Ram variables start address
  14.  
  15.  
  16.  
  17.  
  18. ;CURRENT STATISTICS
  19. ;CODESIZE (ROM) = 3214 bytes (3.14 Kbytes)
  20. ;VARSIZE  (RAM) = 226 bytes
  21. ;Typical compressed music file 2-4 Kbytes
  22.  
  23.  
  24. HOLDTIME    equ 200        ;number of frames to hold effect
  25.  
  26.  
  27. ;VERSION DETAILS
  28. ;3.0 - Tiny format adopted/drumbend special added/ Get_info added
  29. ;      tempo default to 0FFh
  30. ;2.3 - General routines added/GLBoffset added/effect VOLUME defaults to max
  31. ;      CLOCK added/fixed voice special added
  32. ;2.2 - Spidersoft Bugs in EYSY_OS2.ASM and D_GBOY.ASM implemented
  33. ;2.1 - arpeggio voice special/ voices to 64/ complex lo effect special
  34. ;2.0 - new format music file/fxtable/Swap nibbles effect special
  35. ;1.4 - stereo effects/stereo noise
  36. ;1.3 - new notetable/stereo music/tied note added/gate added
  37. ;1.2 - variable pulse width in all 3 channels
  38. ;1.1 - effects to 64/ voices to 32
  39. ;1.0 - new format notes with extended parameters/default tempo = 125bpm
  40. ;0.9 - new format musicfiles
  41. ;0.8 - new tempo routines
  42.  
  43.  
  44.  
  45.  
  46. ;GAMEBOY REGISTER EQUATES
  47.  
  48. P1    equ 0FF00h
  49. SB    equ 0FF01h
  50. SC    equ 0FF02h
  51. DIV    equ 0FF04h
  52. TIMA    equ 0FF05h
  53. TMA    equ 0FF06h
  54. TAC    equ 0FF07h
  55. IF    equ 0FF0Fh
  56. IE    equ 0FFFFh
  57. LCDC    equ 0FF40h
  58. STAT    equ 0FF41h
  59. SCY    equ 0FF42h
  60. SCX    equ 0FF43h
  61. LY    equ 0FF44h
  62. LYC    equ 0FF45h
  63. DMA    equ 0FF46h
  64. BGP    equ 0FF47h
  65. OBP0    equ 0FF48h
  66. OBP1    equ 0FF49h
  67. WY    equ 0FF4Ah
  68. WX    equ 0FF4Bh
  69.  
  70. NR10    equ 0FF10h
  71. NR11    equ 0FF11h
  72. NR12    equ 0FF12h
  73. NR13    equ 0FF13h
  74. NR14    equ 0FF14h
  75.  
  76. NR21    equ 0FF16h
  77. NR22    equ 0FF17h
  78. NR23    equ 0FF18h
  79. NR24    equ 0FF19h
  80.  
  81. NR30    equ 0FF1Ah
  82. NR31    equ 0FF1Bh
  83. NR32    equ 0FF1Ch
  84. NR33    equ 0FF1Dh
  85. NR34    equ 0FF1Eh
  86.  
  87. NR41    equ 0FF20h
  88. NR42    equ 0FF21h
  89. NR43    equ 0FF22h
  90. NR44    equ 0FF23h
  91.  
  92. NR50    equ 0FF24h
  93. NR51    equ 0FF25h
  94. NR52    equ 0FF26h
  95.  
  96. WAVE    equ 0FF30h
  97.  
  98.  
  99. COMAD    equ 0118H    ;The address of the comms interface
  100. HDLEN    equ 16    ;Header buffer length (don't change)
  101. RESTART    equ 0101H    ;Main program start address
  102.  
  103. ;-----------------------------------------------------------------------------
  104.     IF DEMO
  105.     ORG 0000H
  106.  
  107.     DB 0FFH DUP 040H
  108.  
  109.     ORG 0040H    ;V_BLANK INT
  110.     JP V_BLANK
  111.  
  112.     ORG 0048H    ;LCDC STATUS INTERRUPT
  113.     RETI
  114.  
  115. V_BLANK:    PUSH AF
  116.     PUSH BC
  117.     PUSH DE
  118.     PUSH HL
  119.     LDS A,(SCX)
  120.     INC A
  121.     LDS (SCX),A    ;SCROLL SCREEN LEFT
  122.     CALL JUMPTABLE+3    ;SOUND INTERRUPT ROUTINE
  123.     CALL Get_Info
  124.     LD A,1
  125.     LD (vbi_flag),A    ;VBLANK INTERRUPT END FLAG
  126.     POP HL
  127.     POP DE
  128.     POP BC
  129.     POP AF
  130.     RETI
  131.  
  132.  
  133.     ORG 0100H
  134.     NOP
  135.     JP START    ;USER START ADDRESS
  136.  
  137.     DB 0CEH,0EDH,066H,066H    ;NINTENDO DATA
  138.     DB 0CCH,00DH,000H,00BH
  139.     DB 003H,073H,000H,083H
  140.     DB 000H,00CH,000H,00DH
  141.     DB 000H,008H,011H,01FH
  142.     DB 088H,089H,000H,00EH
  143.     DB 0DCH,0CCH,06EH,0E6H
  144.     DB 0DDH,0DDH,0D9H,099H
  145.     DB 0BBH,0BBH,067H,063H
  146.     DB 06EH,00EH,0ECH,0CCH
  147.     DB 0DDH,0DCH,099H,09FH
  148.     DB 0BBH,0B9H,033H,03EH
  149.  
  150. ;-----------------------------------------------------------------------------
  151.     DB 'WALKER MUSIC DRV'    ;GAME TITLE
  152.     DB 0,0,0    ;NOT USED
  153.     DB 1    ;CARTIDGE TYPE = ROM+MMC
  154.     DB 2    ;ROM SIZE = 1M
  155.     DB 0    ;RAM SIZE = NO
  156.     DB 0,0    ;MAKER CODE
  157.     DB 1    ;VERSION NO
  158.     DB 070H    ;COMPLEMENT CHECK
  159.     DB 0,0    ;CHECK SUM
  160.  
  161.  
  162. ;-----------------------------------------------------------------------------
  163. ;Start of Debugger routines
  164. ;-----------------------------------------------------------------------------
  165. DEBUG:    PUSH BC    ;Enter debugger
  166.     LD BC,04170H
  167.     JR ASM10
  168. COMMS:    PUSH BC    ;Enter debugger if host waiting to transfer
  169.     LD BC,0C0F0H
  170. ASM10:    PUSH AF
  171.     LD A,(COMAD)    ;'Read' port of comms link
  172.     XOR B ;Bits 4-6 are used to determine if the comms is enabled
  173.     AND C ;Bit 7 set indicates that the host is waiting to transfer
  174.     JR NZ,ASM20    ;Skip debugger
  175.     ;CHANGE BANK    ;The debugger may be in a different rom bank
  176.     CALL COMRT    ;Enter debugger
  177.     ;RESTORE BANK
  178. ASM20:    POP AF
  179.     POP BC
  180.     RET    ;Return to main program
  181.     ;All regs preserved unless changed by host command
  182.  
  183.  
  184. ;-------------------------------------------------------------------------------
  185. ;This is the debugger.
  186. ;If a new bank was paged in, the previous value should be in the A
  187. ;reg. This can be read by the 'transfer registers' command.
  188. ;The B reg holds the breakpoint type (041H for DEBUG 0C0H for COMMS).
  189. ;-------------------------------------------------------------------------------
  190. COMRT:    PUSH DE
  191.     PUSH HL
  192.     LD HL,12
  193.     ADD HL,SP
  194.     PUSH HL    ;Stack value
  195.     LD C,A
  196.     PUSH BC    ;Bank and type
  197.     LD HL,-HDLEN
  198.     ADD HL,SP
  199.     LD SP,HL    ;Buffer for header
  200. COM20:    LD A,(COMAD)
  201.     AND 0F0H
  202.     CP 040H
  203.     JR Z,COM20    ;Wait for host (for DEBUG entry)
  204.     LD A,(COMAD+6)    ;Reset port
  205.     LD A,(COMAD+4)
  206. COM30:    LD A,(COMAD+3)
  207. COM40:    CALL COMRX    ;Read first byte of header
  208.     JR C,COM70    ;Enter ram or exit
  209.     AND A
  210.     JR Z,COM80    ;This command not used
  211.     LD HL,0
  212.     ADD HL,SP
  213.     CALL COMCMD    ;Execute command
  214.     JR NC,COM30    ;If no error loop back for next command
  215.     LD A,(COMAD+2)    ;Signal error to host
  216.     LD A,(COMAD+4)
  217.     LD A,(COMAD+7)
  218. COM60:    LD A,(COMAD)    ;Wait for host to disable comms with COMOFF
  219.     AND 0F0H
  220.     CP 0C0H
  221.     JR Z,COM60
  222.     JR COM90    ;Exit
  223. COM70:    JR NZ,COM80    ;Jump if exit
  224.     LD A,(COMAD+6)
  225.     DI        ;Prepare to enter ram (for ESYS access)
  226.     LD HL,HDLEN-CWTLN
  227.     ADD HL,SP
  228.     LD SP,HL    ;Make space for ram routine
  229.     PUSH HL
  230.     LD D,H
  231.     LD E,L
  232.     LD HL,COMWT    ;Copy routine into stack buffer
  233.     LD B,CWTLN    ;LD BC,/LDIR (for Z80)
  234. COM75:    LD A,(HLI)
  235.     LD (DE),A
  236.     INC DE
  237.     DEC B
  238.     JR NZ,COM75
  239.     RET        ;Enter ram
  240.  
  241. ;-------------------------------------------------------------------------------
  242. COMCT:    LD A,(COMAD+2)    ;Continue here after exiting ram
  243.     LD HL,CWTLN-HDLEN
  244.     ADD HL,SP
  245.     LD SP,HL    ;Reclaim space
  246.     EI
  247. COM78:  LD A,(COMAD)  ;Add these (BUG REPORT)
  248.         AND 0F2h      ;lines of code
  249.         CP 0C0h       ;in place of the
  250.         JR Z,COM78    ;CALL TXACK
  251.     JR COM30
  252. COM80:    LD A,(COMAD+6)    ;Prepare for exit
  253.     LD A,(COMAD+2)
  254. COM90:    LD HL,HDLEN    ;Exit after error
  255.     ADD HL,SP
  256.     LD SP,HL    ;Reclaim header buffer
  257.     POP BC
  258.     LD A,C
  259.     POP HL
  260.     POP HL
  261.     POP DE
  262.     RET        ;Exit
  263.  
  264.  
  265. ;-----------------------------------------------------------------------------
  266. ;Execute command, A is command number
  267. ;-----------------------------------------------------------------------------
  268. COMCMD:
  269.     CP 10H    ;This command not used
  270.     JR NZ,CMD10
  271.     LD DE,HDLEN+1
  272.     ADD HL,DE
  273.     LD A,(HL)
  274.     CALL COMTX
  275.     RET C
  276.  
  277. TXACK:    LD A,(COMAD)    ;Wait for acknowledgement from host
  278.     AND 0F2H
  279.     CP 0C0H
  280.     JR Z,TXACK
  281.     LD A,(COMAD+2)
  282. CMD5:    LD A,(COMAD)
  283.     AND 0F1H
  284.     XOR 0C0H
  285.     JR Z,CMD5
  286.     RET
  287.  
  288. CMD10:    LD E,A
  289.     AND 0FH
  290.     RET Z    ;Single byte command
  291.     LD C,A
  292.     LD B,0
  293.     PUSH DE
  294.     PUSH HL
  295.     CALL CRXLP    ;Load rest of header
  296.     POP HL
  297.     POP DE
  298.     RET C    ;Error
  299.     LD A,E
  300.     AND 0EFH
  301.     CP 02H
  302.     JR NZ,CMD20    ;Jump if not transfer regs command
  303.     LD C,(HL)
  304.     INC HL
  305.     LD A,(HL)
  306.     LD B,0
  307.     ADD HL,BC
  308.     LD C,HDLEN-1
  309.     ADD HL,BC    ;Point to regs list on stack
  310.     LD C,A
  311.     LD D,B
  312.     JR CMD30
  313. CMD20:    XOR 05H
  314.     RET NZ    ;Return if not transfer memory command
  315.     LD A,(HL)
  316.     INC HL
  317.     LD D,(HL)
  318.     INC HL
  319.     INC HL
  320.     LD C,(HL)
  321.     INC HL
  322.     LD B,(HL)
  323.     LD H,D
  324.     LD L,A
  325.     LD D,0
  326.  
  327. CMD30:    PUSH DE
  328.     BIT 4,E
  329.     JR Z,CMD40
  330.     CALL CTXBUF    ;Send data
  331.     CALL NC,TXACK    ;Wait for acknowledgement
  332.     JR CMD50
  333. CMD40:    CALL CRXBUF    ;Load data
  334. CMD50:    POP DE
  335.     DEC D
  336.     RET NZ    ;Return if display unchanged
  337.  
  338.  
  339. ;-----------------------------------------------------------------------------
  340. ;This routine is copied into ram to allow the host access
  341. ;to the ESYS
  342. ;-----------------------------------------------------------------------------
  343. COMWT:
  344.     LD A,(COMAD+2)
  345. CWT10:    XOR A    ;Wait for command
  346. CWT20:    ADD HL,HL
  347.     DEC A
  348.     JR NZ,CWT20
  349.     LD A,(COMAD)
  350.     AND 0F0H
  351.     CP 0C0H
  352.     JR Z,CWT30    ;Jump if host waiting to send command
  353.     CP 040H
  354.     JR Z,CWT10
  355.     JR CWT50        ;Jump if comms disabled
  356. CWT30:    LD A,(COMAD+3)    ;Send acknowledgement
  357. CWT40:    LD A,(COMAD)
  358.     AND 0F2H
  359.     CP 0C0H
  360.     JP Z,COMCT    ;Jump back to debugger
  361.     CP 0C2H
  362.     JR Z,CWT40
  363.     LD A,(COMAD+2)
  364. CWT50:    JP RESTART    ;Jump to start if comms disabled or ENDTRN called
  365. CWTLN    EQU    $-COMWT
  366.  
  367.  
  368. ;-----------------------------------------------------------------------------
  369. ;Transmit data to host
  370. ;HL points to data, BC is the length
  371. ;-----------------------------------------------------------------------------
  372. CTXBUF:
  373.     LD E,0
  374. CTX10:    LD A,(HL)
  375.     LD D,A
  376.     INC HL
  377.     CALL COMTX    ;Send byte
  378.     RET C    ;Error
  379.     LD A,D    ;Checksum
  380.     ADD A,E
  381.     LD E,A
  382.     DEC BC
  383.     LD A,B
  384.     OR C
  385.     JR NZ,CTX10
  386.     LD A,E    ;Send checksum
  387.     ;Send a byte (in A)
  388. COMTX:    PUSH BC
  389.     PUSH DE
  390.     PUSH HL
  391.     LD C,A
  392.     LD B,0C2H
  393.     LD DE,COMAD+2
  394.     LD HL,COMAD+4
  395.     SCF
  396.     RL C
  397. CTX20:    RR E
  398.     RLC E
  399. CTX30:    LD A,(COMAD)    ;Wait for handshake
  400.     XOR B
  401.     AND 0F2H
  402.     JR Z,CTX40
  403.     XOR 02H
  404.     JR Z,CTX30
  405.     AND 070H
  406.     SCF
  407.     JR NZ,CTX50    ;Exit if comms disabled
  408.     BIT 3,B
  409.     JR NZ,CTX30
  410. CTX40:    SET 3,B    ;Send first bit even if host is not ready
  411.     LD A,(DE)
  412.     LD A,L
  413.     XOR 01H
  414.     LD L,A
  415.     LD A,B
  416.     XOR 02H
  417.     LD B,A
  418.     LD A,(HL)
  419.     SLA C
  420.     JR NZ,CTX20
  421.     AND A
  422. CTX50:    POP HL
  423.     POP DE
  424.     POP BC
  425.     RET
  426.     ;On exit NC=send OK, C=comms disabled
  427.  
  428.  
  429. ;-----------------------------------------------------------------------------
  430. ;Receive data from host
  431. ;HL points to data, BC is the length
  432. ;-----------------------------------------------------------------------------
  433. CRXBUF:
  434.     LD E,0
  435. CRXLP:    CALL COMRX    ;Load byte
  436.     RET C    ;Error
  437.     LD (HL),A
  438.     INC HL
  439.     ADD A,E    ;Checksum
  440.     LD E,A
  441.     DEC BC
  442.     LD A,B
  443.     OR C
  444.     JR NZ,CRXLP
  445.     CALL COMRX    ;Load checksum
  446.     RET C    ;Error
  447.     XOR E
  448.     ADD A,0FFH    ;Signal error if checksums do not match
  449.     RET
  450.     ;On exit NC=load OK, C=comms disabled or error
  451.  
  452.  
  453. ;-----------------------------------------------------------------------------
  454. ;Receive a byte from host
  455. ;-----------------------------------------------------------------------------
  456. COMRX:
  457.     PUSH BC
  458.     PUSH HL
  459.     LD BC,0C001H
  460.     LD HL,COMAD+6
  461. CRX10:    LD A,(COMAD)    ;Wait for handshake
  462.     AND 0F2H
  463.     XOR B
  464.     JR Z,CRX20
  465.     XOR 02H
  466.     JR Z,CRX10
  467.     XOR B
  468.     XOR 042H
  469.     JR NZ,CRX30    ;Jump if comms disabled
  470.     LD A,C    ;Check for 'enter ram' command
  471.     XOR 3
  472.     JR CRX30
  473. CRX20:    LD A,L
  474.     XOR 01H
  475.     LD L,A
  476.     LD A,B
  477.     XOR 02H
  478.     LD B,A
  479.     LD A,(COMAD)
  480.     CP (HL)
  481.     RRA
  482.     RL C
  483.     JR NC,CRX10
  484.     LD A,C
  485. CRX30:    POP HL
  486.     POP BC
  487.     CCF
  488.     RET
  489.     ;On exit NC=load OK, value in A
  490.     ;        C and A=0 - Enter ram command
  491.     ;        C and A<>0 - Comms transfer ended
  492.  
  493.  
  494.  
  495.  
  496. ;-------------------------------------------------------------------------------
  497. START:    DI
  498.     LD SP,0E000H    ;PLACE STACK AT E000
  499.  
  500.     XOR A    ;CLEAR 8K OF WORK RAM (C000-DFFF)
  501.     LD HL,0C000H
  502. CLRWORK:    LD (HLI),A
  503.     BIT 5,H
  504.     JR Z,CLRWORK
  505.  
  506.     XOR A
  507.     LDS (STAT),A    ;CLEAR LCD STATUS
  508.     LDS (IF),A    ;CLEAR INTERRUPT FLAG
  509.  
  510.     LD A,1
  511.     LDS (IE),A    ;ENABLE V_BLANK INTERRUPT
  512.  
  513.  
  514.     CALL JUMPTABLE+0    ;Initialise driver
  515.     LD A,0FFH
  516.     LD (sfxno),A
  517.     LD (tuneno),A
  518.     LD (PCnewdata),A
  519.     XOR A
  520.     LD (editnum),A
  521.     LD (selectflag),A
  522.     EI
  523.  
  524. ;-------------------------------------------------------------------------------
  525. MAIN:    CALL COMMS
  526.  
  527. NEWchk:    ld a,(PCnewdata)
  528.     cp 0ffh
  529.     jr z,JOYchk
  530.     call JUMPTABLE+6    ;re-initialise after compression
  531.     LD A,0FFH
  532.     LD (PCnewdata),A    ;cancel flag
  533.  
  534.  
  535. JOYchk:    CALL CONT    ;get a key press
  536.     LD A,(CNT1)    ;GET VALUE
  537.     bit 0,A
  538.     JR NZ,AKEY
  539.     bit 1,a
  540.     jr nz,BKEY
  541.     bit 2,a
  542.     jr nz,SELECT
  543.     bit 3,A
  544.     JR NZ,STRTBUT
  545.     bit 6,A
  546.     JR NZ,UPKEY
  547.     bit 7,A
  548.     JR NZ,DNKEY
  549.     JR VBLK_WT
  550.  
  551. UPKEY:    LD A,(editnum)    ;inc call number
  552.     INC A
  553.     LD (editnum),A
  554.     JR KEYEND
  555. DNKEY:    LD A,(editnum)    ;dec call number
  556.     DEC A
  557.     LD (editnum),A
  558.     JR KEYEND
  559. AKEY:    ld a,0        ;select music calls
  560.     ld (selectflag),a
  561.     JR KEYEND
  562. BKEY:    ld a,0FFh    ;select effect calls
  563.     ld (selectflag),a
  564.     JR KEYEND
  565.  
  566. SELECT:    ld a,080h
  567.     ld (tuneno),A    ;kill music
  568.     xor a
  569.     ld (sfxno),A    ;effect 0
  570.     jr keyend
  571.  
  572. STRTBUT:
  573.     ld a,(selectflag)
  574.     cp 0ffh
  575.     jr nz,STRTUNE
  576.     LD A,(editnum)
  577.     LD (sfxno),A
  578.     JR keyend
  579.  
  580. STRTUNE:
  581.     ld a,(editnum)
  582.     LD (tuneno),A    ;start tune
  583.  
  584. KEYEND:    CALL CONT
  585.     LD A,(CNT1)
  586.     CP 0
  587.     JR NZ,KEYEND    ;wait for key release
  588.  
  589. VBLK_WT:
  590.     HALT        ;system stop until next interrupt
  591.     LD A,(vbi_flag)
  592.     AND A        ;VBLANK interrupt ?
  593.     JR Z,VBLK_WT
  594.     XOR A
  595.     LD (vbi_flag),A    ;clear flag (set at end of VBLANK)
  596.     JP MAIN
  597.  
  598.  
  599. ;-------------------------------------------------------------------------------
  600. CONT:    LD C,P1 AND 0FFH    ;key port address
  601.     LD A,020H
  602.     LD (C),A
  603.     LD A,(C)
  604.     LD A,(C)
  605.     LD A,(C)
  606.  
  607.     LD B,A
  608.     LD A,010H
  609.     LD (C),A
  610.     LD A,B
  611.  
  612.     AND 0FH
  613.     SWAP A
  614.     LD B,A
  615.  
  616.     LD A,(C)
  617.     LD A,(C)
  618.     LD A,(C)
  619.     LD A,(C)
  620.     LD A,(C)
  621.     LD A,(C)
  622.     LD A,(C)
  623.     LD A,(C)
  624.     LD A,(C)
  625.  
  626.     AND 0FH
  627.     OR B
  628.     CPL
  629.     LD B,A
  630.  
  631.     LD A,030H
  632.     LD (C),A
  633.     LD A,(CNT1)
  634.     XOR B
  635.     AND B
  636.     LD (TRG1),A
  637.  
  638.     LD A,B
  639.     LD (CNT1),A
  640.  
  641.     RET
  642.  
  643.  
  644.  
  645. ;-------------------------------------------------------------------------------
  646. ;Get_Info
  647. ;-------------------------------------------------------------------------------
  648. Get_Info:
  649.     LD BC,PCbuffer
  650.     LD A,(TUNENO)
  651.     LD (BC),A
  652.     INC BC
  653.     LD A,(STATUS)
  654.     LD (BC),A
  655.     INC BC
  656.     LD A,(TEMPOVAL)
  657.     LD (BC),A
  658.     INC BC
  659.     LD A,(CLOCK_L)
  660.     LD (BC),A
  661.     INC BC
  662.     LD A,(CLOCK_H)
  663.     LD (BC),A
  664.     INC BC
  665.     LD A,(GLOBOFFSET)
  666.     LD (BC),A
  667.     INC BC
  668.  
  669.     XOR A
  670.     LD D,A
  671.     LD E,A
  672.     LD (CURCHAN),A
  673.  
  674. Gilup1:    LD HL,NOTELENGTH
  675.     ADD HL,DE
  676.     LD A,(HL)
  677.     LD (BC),A
  678.     INC BC
  679.     LD HL,THRESHOLD
  680.     ADD HL,DE
  681.     LD A,(HL)
  682.     LD (BC),A
  683.     INC BC
  684.     LD HL,VOICENUM
  685.     ADD HL,DE
  686.     LD A,(HL)
  687.     LD (BC),A
  688.     INC BC
  689.     LD HL,NOTEVALUE
  690.     ADD HL,DE
  691.     LD A,(HL)
  692.     LD (BC),A
  693.     INC BC
  694.     LD HL,SEQNUM
  695.     ADD HL,DE
  696.     LD A,(HL)
  697.     LD (BC),A
  698.     INC BC
  699.     LD HL,STEREO
  700.     ADD HL,DE
  701.     LD A,(HL)
  702.     LD (BC),A
  703.     INC BC
  704.  
  705.     LD HL,SDLN
  706.     ADD HL,DE    ;add current value
  707.     LD D,H
  708.     LD E,L        ;& move to DE
  709.     LD HL,CURCHAN
  710.     INC (HL)
  711.     LD A,(HL)
  712.     CP 3
  713.     JP C,Gilup1
  714.     RET
  715.  
  716.  
  717.  
  718.  
  719.     ENDIF
  720.  
  721.  
  722. ;-------------------------------------------------------------------------------
  723. ; ****** START OF DRIVER CODE ******
  724. ;-------------------------------------------------------------------------------
  725.  
  726.     ORG MUSICROM
  727.  
  728. JUMPTABLE:
  729.     JP INITSND    ;Initialise sound routine
  730.     JP INTSND    ;Interrupt routine
  731.     JP INVEC        ;New load routine
  732.  
  733. INITSND:
  734.     LD HL,MUSICVAR    ;clear variable RAM
  735.     LD BC,VARSIZE
  736. CLRVAR:    LD (HL),0
  737.     INC HL
  738.     DEC BC
  739.     LD A,B
  740.     OR C
  741.     JR NZ,CLRVAR
  742.     CALL INVEC    ;calc. addresses from vector table
  743.  
  744.     LD A,0ffh    ;initialise RAM variables
  745.     LD (SFXCHAN1),A
  746.     LD (SFXCHAN1+SDLN),A
  747.     LD (SFXCHAN1+SDLN+SDLN),A
  748.     LD (PRIORITY),A
  749.     LD (PRIORITY+SDLN),A
  750.     LD (PRIORITY+SDLN+SDLN),A
  751.     LD (VCEMUTE),A
  752.     LD (VCEMUTE+SDLN),A
  753.     LD (VCEMUTE+SDLN+SDLN),A
  754.     LD (NCHAN),A
  755.     LD A,8
  756.     LD (ENVAL+1),A
  757.     LD (ENVAL+SDLN+1),A
  758.     LD (ENVAL+SDLN+SDLN+1),A
  759.     ld a,0FFh
  760.     ld (TEMPOVAL),a    ;default tempo = 296
  761.  
  762.     LD A,80H
  763.     LDS (NR52),A    ;all sound circuits on
  764.     LD A,008h
  765.     LDS (NR10),A    ;sound 1 mode = sweep off
  766.     XOR A
  767.     LDS (NR30),A    ;sound 3 output stop
  768.     LDS (NR34),A    ;continuous sound 3
  769.  
  770.     LD B,16    ;clear WAVE RAM
  771.     LD HL,WAVE
  772. CLRWAVE:    LD (HLI),A
  773.     DEC B
  774.     JR NZ,CLRWAVE
  775.  
  776.     LD BC,0400h    ;set all 4 channels to freq=0
  777. IN30:    PUSH BC
  778.     CALL FREQOFF
  779.     POP BC
  780.     INC C
  781.     DEC B
  782.     JR NZ,IN30
  783.  
  784.     xor a
  785.     LDS (NR11),A
  786.     LDS (NR21),A
  787.     LDS (NR31),A
  788.     LDS (NR41),A
  789.     LD A,020h
  790.     LDS (NR32),A    ;sound 3 full volume
  791.     LD A,77h
  792.     LDS (NR50),A    ;max. volume to SO1 & SO2
  793.     LD A,0FFh
  794.     LDS (NR51),A    ;all channels to both SO1 & SO2
  795.     LD A,08Fh
  796.     LDS (NR52),A    ;all sound channels on
  797.     RET
  798.  
  799.  
  800. ;-----------------------------------------------------------------------------
  801. ;Calculate new pointers from Musicdata chunk sizes
  802. ;-----------------------------------------------------------------------------
  803. INVEC:    LD HL,GAMEDAT1    ;chunk table start address
  804.     LD DE,GAMEDAT1+14    ;music data start address
  805. IN50:    LD A,E
  806.     LD (FXBANK),A
  807.     LD A,D
  808.     LD (FXBANK+1),A    ;save start address of effects
  809.  
  810.     ld bc,FXTABLE
  811.     call stvar    ;calculate FXTABLE address
  812.     CALL STVAR    ;calculate VCEBANK address
  813.     CALL STVAR    ;calc. SEQOFF address
  814.     CALL STVAR    ;calc. SEQDATA address
  815.     CALL STVAR    ;calc. TRKOFF address
  816.             ;calc. TRKDATA address
  817. STVAR:    LD A,(HLI)    ;get low byte from vector table
  818.     ADD A,E        ;add GAMEDATA low byte address
  819.     LD E,A        ;and save in E
  820.     LD (BC),A    ;and save in final offset low byte
  821.     INC BC        ;now move to high byte
  822.     LD A,(HLI)    ;get high byte from vector table
  823.     ADC A,D        ;add GAMEDATA high byte address
  824.     LD D,A        ;DE now holds address of this block
  825.     LD (BC),A    ;save to final offset high byte
  826.     INC BC        ;now move to next dest. entry
  827.  
  828.     RET
  829.  
  830.  
  831.  
  832.  
  833. ;-------------------------------------------------------------------------------
  834. ;INTERRUPT ROUTINE
  835. ;-------------------------------------------------------------------------------
  836. INTSND:    LD A,(sfxno)
  837.     CP 0FFH
  838.     JR Z,INTSND2
  839.     CALL SENDFX
  840.     LD A,0FFH
  841.     LD (sfxno),A
  842. INTSND2:
  843.     LD A,(tuneno)
  844.     CP 0FFH
  845.     JR Z,INTSND3
  846.     CALL SENDMUS
  847.     LD A,0FFH
  848.     LD (tuneno),A
  849. INTSND3:
  850.     CALL INTSFX
  851.     CALL INTMUSIC
  852.  
  853.     ld de,0
  854.     ld a,0
  855.     call EXESD
  856.     ld de,SDLN
  857.     ld a,1
  858.     call EXESD
  859.     ld de,2*SDLN
  860.     ld a,2
  861. EXESD:    ld (CURCHAN),a    ;0/1/2 (current channel)
  862.     call OUTSOUND
  863.     ret
  864.  
  865.  
  866.  
  867.  
  868. ;-------------------------------------------------------------------------------
  869. SENDFX:    ld hl,0
  870.     ld l,a    ;enter with A=FXTABLE call number
  871.     add hl,hl
  872.     add hl,hl    ;4 bytes for each entry
  873.     ld a,(FXTABLE)
  874.     add a,l
  875.     ld c,a
  876.     ld a,(FXTABLE+1)
  877.     adc a,h
  878.     ld h,a    ;final high byte of address
  879.     ld l,c    ;final low byte of address
  880.  
  881.     ld c,(hl)    ;get priority
  882.     inc hl
  883.     ld a,(hli)    ;get chan0 call
  884.     cp 0ffh
  885.     jr z,sendfx1
  886.     ld (SFXCHAN1),a
  887.     ld a,c
  888.     ld (PRIORTEST),a
  889. sendfx1:    ld a,(hli)    ;get chan1 call
  890.     cp 0ffh
  891.     jr z,sendfx2
  892.     ld (SFXCHAN1+SDLN),a
  893.     ld a,c
  894.     ld (PRIORTEST+SDLN),a
  895. sendfx2:    ld a,(hli)    ;get chan2 call
  896.     cp 0ffh
  897.     jr z,sendfx3
  898.     ld (SFXCHAN1+SDLN+SDLN),a
  899.     ld a,c
  900.     ld (PRIORTEST+SDLN+SDLN),a
  901. sendfx3:    ld a,(STATUS)
  902.     rla
  903.     ret C    ;not during music
  904.     ld a,077H    ;max volume in both left & right
  905.     lds (NR50),a    ;(after fade etc.)
  906.     ret
  907.  
  908.  
  909.  
  910.  
  911. ;-------------------------------------------------------------------------------
  912. INTSFX:    XOR A
  913.     LD D,A    ;channel 0
  914.     LD E,A
  915.     CALL CALLFX
  916.     LD A,1
  917.     LD DE,SDLN    ;channel 1
  918.     CALL CALLFX
  919.     LD A,2
  920.     LD DE,2*SDLN    ;channel 2
  921.  
  922. CALLFX:    LD (CURCHAN),A
  923.     LD HL,FQOFF
  924.     ADD HL,DE
  925.     LD (HL),0    ;FQOFF=0
  926.  
  927.     LD HL,SFXCHAN1
  928.     ADD HL,DE
  929.     BIT 7,(HL)
  930.     JR NZ,TESTMUSIC    ;no call in this channel
  931.     LD A,(HL)
  932.     LD B,A    ;new effect number saved in B
  933.  
  934.     inc hl
  935.     ld c,(hl)    ;C=PRIORTEST for required effect
  936.  
  937.     LD HL,PRIORITY
  938.     ADD HL,DE
  939.     LD A,(HL)    ;get current priority
  940.     CP C
  941.     JR NC,LOADFX    ;higher or equal, so accept
  942.     PUSH HL    ;save address of current priority
  943.     LD HL,SFXHOLD
  944.     ADD HL,DE
  945.     LD A,(HL)
  946.     POP HL
  947.     AND A
  948.     JR Z,LOADFX    ;64 frames past
  949.     LD HL,SFXCHAN1
  950.     ADD HL,DE
  951.     LD (HL),0ffh    ;else cancel try
  952.  
  953. TESTMUSIC:    LD HL,SFXCHOP
  954.     ADD HL,DE
  955.     XOR A
  956.     CP (HL)
  957.     JR Z,TESTABORT    ;end of sound (endcnt reduced to 0)
  958.     PUSH HL
  959.     LD HL,VCEMUTE
  960.     ADD HL,DE
  961.     CP (HL)    ;cmp vcemute to 0
  962.     POP HL
  963.     JP NZ,TIMEFX
  964.     LD (HL),A    ;sfxchop to 0
  965.  
  966. TESTABORT:    LD HL,SFXHOLD    ;force to 0 for sounds < 64 frames
  967.     ADD HL,DE
  968.     LD (HL),A
  969.     RET
  970.  
  971.  
  972. LOADFX:    ld (hl),c    ;save this priority
  973.     ld hl,0
  974.     ld l,b    ;retreive effect number
  975.     add hl,hl
  976.     add hl,hl
  977.     add hl,hl
  978.     add hl,hl    ;16 bytes each effect
  979.     ld a,(FXBANK)
  980.     add a,l
  981.     ld c,a
  982.     ld a,(FXBANK+1)
  983.     adc a,h
  984.     ld b,a
  985.  
  986.     LD HL,ENAD
  987.     ADD HL,DE
  988.     LD A,(BC)
  989.     LD (HLI),A    ;save attdec to ENAD (overwrite music)
  990.  
  991.     INC BC
  992.     LD A,(BC)
  993.     LD (HLI),A    ;save susrel to ENSR (overwrite music)
  994.  
  995.     ld a,0F8H
  996.     ld (hli),a    ;ATKLVL forced to maximum level
  997.  
  998.     INC BC
  999.     LD A,(BC)
  1000.     LD (HLI),A    ;save atkcnt to ATKHOLD
  1001.  
  1002.     XOR A
  1003.     LD (HLI),A    ;ENSEQ=0 (attack)
  1004.     INC A
  1005.     LD (HLI),A    ;ENVAL=1
  1006.     LD (HL),8    ;FQOFF=8
  1007.  
  1008.     LD HL,SFXCHOP
  1009.     ADD HL,DE
  1010.     INC BC
  1011.     LD A,(BC)
  1012.     LD (HLD),A    ;save endcnt to SFXCHOP
  1013.  
  1014.     LD (HL),HOLDTIME    ;SFXHOLD= 100 frames
  1015.     DEC HL
  1016.     dec hl
  1017.     ld (hl),0ffh    ;SFXCHAN1=0ffh
  1018.  
  1019.     LD HL,CTRLAD
  1020.     ADD HL,DE
  1021.     inc bc
  1022.     ld a,(bc)
  1023.     ld (hli),a    ;save wave ad to CTRLAD
  1024.  
  1025.     inc bc
  1026.     ld a,(bc)
  1027.     ld (hli),a    ;save wave sr to CTRLSR
  1028.  
  1029.     inc bc
  1030.     ld a,(bc)
  1031.     inc hl    ;skip freqlo dest.
  1032.     ld (hl),a    ;save freqhi to FREQ high byte
  1033.     inc bc
  1034.     ld a,(bc)
  1035.     dec hl
  1036.     ld (hli),a    ;save freqlo to FREQ low byte
  1037.     inc hl
  1038.  
  1039.     inc bc
  1040.     LD A,(BC)
  1041.     LD (HLI),A    ;save bend to BENDTYPE
  1042.  
  1043.     INC BC
  1044.     LD A,(BC)
  1045.     inc hl    ;skip bendlo dest
  1046.     LD (HL),A    ;save bendhi to BEND high byte
  1047.     INC BC
  1048.     LD A,(BC)
  1049.     dec hl
  1050.     LD (hli),A    ;save bendlo to BEND low byte
  1051.     inc hl    ;skip bendhi dest
  1052.  
  1053.     inc bc
  1054.     push bc
  1055.     push hl
  1056.     ld a,(bc)
  1057.     and 11h    ;L/R bits only
  1058.     ld hl,STEREO
  1059.     add hl,de
  1060.     ld (hl),a    ;save STEREO (effect)
  1061.     push af
  1062.     ld a,(CURCHAN)    ;STEREO (1st frame only)
  1063.     inc a
  1064.     ld c,a    ;C=1,2,3 (current channel+1)
  1065.     pop af    ;retrieve STEREO
  1066.     ld b,0EEh
  1067.     dec c
  1068.     jr z,loadfx2    ;channel 1
  1069.     add a,a    ;11h to 22h
  1070.     ld b,0DDh
  1071.     dec c
  1072.     jr z,loadfx2    ;channel 2
  1073.     add a,a    ;channel 3   (22h to 44h)
  1074.     ld b,0BBh
  1075. loadfx2:    ld c,a    ;C=stereo bits
  1076.     lds a,(NR51)    ;get assignment
  1077.     and b    ;mask out this channel
  1078.     or c        ;add stereo for this channel
  1079.     lds (NR51),a
  1080.     pop hl
  1081.     pop bc
  1082.  
  1083.     inc bc
  1084.     LD A,(BC)
  1085.     LD (HLI),A    ;save specls to SFXEXTRA
  1086.  
  1087.     inc bc
  1088.     ld a,(bc)
  1089.     ld (hli),a    ;save newcnt to CNTDOWN
  1090.     ld (hli),a    ;         and to CNTVAL
  1091.     inc bc
  1092.     ld a,(bc)
  1093.     ld (hli),a    ;save newfhi to NEWVAL
  1094.     inc bc
  1095.     ld a,(bc)
  1096.     ld (hli),a    ;save newflo to NEWVAL2
  1097.     INC HL    ;skip PRIORITY
  1098.     LD (HL),0FFH    ;DIRFLAG=0FFh
  1099.     ret
  1100.  
  1101.  
  1102.  
  1103. TIMEFX:    LD HL,SFXHOLD
  1104.     ADD HL,DE
  1105.     LD A,(HL)
  1106.     AND A
  1107.     JR Z,TIMING1
  1108.     DEC (HL)
  1109. TIMING1:    LD HL,CNTDOWN
  1110.     ADD HL,DE
  1111.     DEC (HL)
  1112.     BIT 7,(HL)
  1113.     JR Z,TIMING2
  1114.     INC HL
  1115.     LD A,(HLD)    ;cntval
  1116.     LD (HLI),A
  1117.     INC HL
  1118.     INC HL
  1119.     INC HL
  1120.     inc hl
  1121.     LD A,(HL)    ;DIRFLAG
  1122.     CPL        ;toggle
  1123.     LD (HL),A    ;& resave
  1124. TIMING2:    LD HL,ATKHOLD
  1125.     ADD HL,DE
  1126.     LD A,(HL)
  1127.     AND A    ;set flags
  1128.     JR NZ,TIMING4    ;continue attack cycle
  1129.     LD HL,CTRLSR
  1130.     ADD HL,DE
  1131.     LD A,(HLD)
  1132.     CP (HL)
  1133.     JR NZ,TIMING3    ;start release cycle
  1134.  
  1135.     DEC HL
  1136.     LD A,(HL)    ;sfxchop
  1137.     CP 0FFH
  1138.     JR Z,SBENDING    ;ff=no chop
  1139.     DEC (HL)
  1140.     JR NZ,SBENDING    ;not ended, so continue effects
  1141.     INC HL
  1142.     LD (HL),0    ;CTRLAD=0
  1143.     LD HL,ENVAL+1
  1144.     ADD HL,DE
  1145.     LD (HL),0    ;ENVAL+1=0
  1146.     RET
  1147.  
  1148. TIMING3:    LD (HL),A    ;CTRLSR to CTRLAD (start release)
  1149.     JR SBENDING
  1150. TIMING4:    DEC (HL)    ;atkhold
  1151.  
  1152.  
  1153. SBENDING:    LD HL,BENDTYPE
  1154.     ADD HL,DE
  1155.     LD A,(HL)
  1156.     AND A
  1157.     JR Z,SPECSFX
  1158.  
  1159. BEND3:    LD HL,ATKHOLD
  1160.     ADD HL,DE
  1161.     SUB 3
  1162.     JR NZ,BEND4
  1163.     OR (HL)
  1164.     JR NZ,BEND1A
  1165.     JR SPECSFX
  1166.  
  1167. BEND4:    DEC A    ;BEND4
  1168.     JR NZ,BEND5
  1169.     OR (HL)
  1170.     JR NZ,BEND2A
  1171.     JR SPECSFX
  1172.  
  1173. BEND5:    DEC A    ;BEND5
  1174.     JR NZ,BEND6
  1175.     OR (HL)
  1176.     JR NZ,BEND1A
  1177.     JR BEND2A
  1178.  
  1179. BEND6:    DEC A    ;BEND6
  1180.     JR NZ,BEND7
  1181.     OR (HL)
  1182.     JR NZ,BEND2A
  1183.     JR BEND1A
  1184.  
  1185. BEND7:    DEC A    ;BEND7
  1186.     JR NZ,BEND8
  1187.     OR (HL)
  1188.     JR Z,BEND1A
  1189.     JR SPECSFX
  1190.  
  1191. BEND8:    DEC A    ;BEND8
  1192.     JR NZ,BEND9
  1193.     OR (HL)
  1194.     JR Z,BEND2A
  1195.     JR SPECSFX
  1196.  
  1197. BEND9:    DEC A    ;BEND9
  1198.     JR NZ,BEND1
  1199.     LD HL,DIRFLAG
  1200.     ADD HL,DE
  1201.     BIT 7,(HL)
  1202.     JR NZ,BEND1A
  1203.     JR BEND2A
  1204.  
  1205. BEND1    SUB 0F8H        ;WAS '1-9'    BEND1
  1206.     JR NZ,BEND2
  1207. BEND1A:    LD HL,FREQ
  1208.     ADD HL,DE
  1209.     LD B,H
  1210.     LD C,L
  1211.     INC BC
  1212.     INC BC
  1213.     INC BC
  1214.     LD A,(BC)    ;BEND low byte
  1215.     ADD A,(HL)
  1216.     LD (HLI),A
  1217.     INC BC
  1218.     LD A,(BC)    ;BEND high byte
  1219.     ADC A,(HL)
  1220.     LD (HL),A
  1221.     JR SPECSFX
  1222.  
  1223. BEND2:    DEC A
  1224.     JR NZ,SPECSFX
  1225. BEND2A:    LD HL,FREQ
  1226.     ADD HL,DE
  1227.     LD B,H
  1228.     LD C,L
  1229.     INC HL
  1230.     INC HL
  1231.     INC HL
  1232.     LD A,(BC)
  1233.     SUB (HL)
  1234.     LD (BC),A
  1235.     INC BC
  1236.     INC HL
  1237.     LD A,(BC)
  1238.     SBC A,(HL)
  1239.     LD (BC),A
  1240.  
  1241.  
  1242. SPECSFX:
  1243.     LD HL,SFXEXTRA
  1244.     ADD HL,DE
  1245.     LD A,(HL)
  1246.     AND A
  1247.     RET Z        ;no special effect
  1248.     LD C,A
  1249.     LD HL,FREQ+1
  1250.     ADD HL,DE
  1251.  
  1252. SF01:    SRL C        ;swap F lo/F hi @ 60Hz
  1253.     JR NC,SF02
  1254.     LD A,(HLD)
  1255.     LD B,(HL)
  1256.     LD (HLI),A
  1257.     LD (HL),B
  1258.  
  1259. SF02:    SRL C        ;Complex F hi sbc bendhi/eor newval
  1260.     JR NC,SF04
  1261.     PUSH HL
  1262.     LD A,(HL)    ;FREQ high byte
  1263.     INC HL
  1264.     INC HL
  1265.     INC HL
  1266.     SUB (HL)        ;BEND high byte
  1267.     LD HL,NEWVAL
  1268.     ADD HL,DE
  1269.     XOR (HL)
  1270.     POP HL
  1271.     LD (HL),A
  1272.  
  1273. SF04:    SRL C        ;waver F lo + (random and #7)
  1274.     JR NC,SF08
  1275.     LD A,(SEED)    ;random number generator
  1276.     LD B,A
  1277.     ADD A,A
  1278.     ADD A,A
  1279.     ADD A,A
  1280.     ADD A,A
  1281.     ADD A,B
  1282.     ADD A,11
  1283.     LD (SEED),A
  1284.     SWAP A
  1285.     AND 0fH
  1286.     PUSH HL
  1287.     LD HL,FQOFF    ;08 if effect call/0 if not
  1288.     ADD HL,DE
  1289.     LD (HL),A    ;FQOFF= random 0-0fh i.e. +/- 8
  1290.     POP HL
  1291.  
  1292. SF08:    SRL C        ;Reload
  1293.     jr nc,SF10
  1294.     PUSH HL
  1295.     LD HL,CNTDOWN
  1296.     ADD HL,DE
  1297.     LD A,(HLI)
  1298.     INC HL        ;NEWVAL is 2 bytes further on
  1299.     AND A        ;set flags according to CNTDOWN
  1300.     LD A,(HL)    ;get NEWVAL
  1301.     POP HL
  1302.     RET NZ
  1303.     LD (HL),A    ;F hi reloaded with NEWVAL
  1304.  
  1305. SF10:    SRL C        ;swap low frequency nibbles @ 60Hz
  1306.     jr nc,SF20
  1307.     dec hl
  1308.     ld a,(hl)
  1309.     swap a
  1310.     ld (hl),a
  1311.     inc hl
  1312.  
  1313. SF20:    SRL C        ;Complex F lo sbc bendlo/eor newflo
  1314.     RET NC
  1315.     PUSH HL
  1316.     dec hl
  1317.     LD A,(HL)    ;FREQ low byte
  1318.     INC HL
  1319.     INC HL
  1320.     INC HL
  1321.     SUB (HL)        ;BEND low byte
  1322.     LD HL,NEWVAL2
  1323.     ADD HL,DE
  1324.     XOR (HL)
  1325.     POP HL
  1326.     dec hl
  1327.     LD (HL),A
  1328.     ret
  1329.  
  1330.  
  1331.  
  1332.  
  1333. ;-------------------------------------------------------------------------------
  1334. ;OUT SOUND - Envelope/ FQOFF/ Noise/ Frequency/ Waveform
  1335. ;DE=0,SDLN,SDLN*2
  1336. ;CURCHAN=0,1,2
  1337. ;-------------------------------------------------------------------------------
  1338. OUTSOUND:    LD HL,SFXHOLD    ;Check for effect in this channel
  1339.     ADD HL,DE
  1340.     ld a,(hl)
  1341.     cp 0
  1342.     JR Z,OUTSOUND2    ;EFFSND=0  (music)
  1343.     ld a,0FFh    ;EFFSND=FF (effect)
  1344. OUTSOUND2:    LD (EFFSND),A
  1345.  
  1346.     LD HL,CTRLAD    ;current waveform (effect or music)
  1347.     ADD HL,DE
  1348.     BIT 0,(HL)    ;gate bit
  1349.     LD HL,ENSR    ;current sustain/release
  1350.     ADD HL,DE
  1351.     JR Z,RELEASE    ;if gate off
  1352.  
  1353. ATTDECSUS:    LD A,(HLD)    ;gate bit on
  1354.     AND 0F0H    ;ENSR sustain nibble
  1355.     LD B,A    ;B holds sustain value
  1356.     LD A,(HLI)    ;ENAD
  1357.     INC HL
  1358.     INC HL
  1359.     inc hl
  1360.     LD C,(HL)    ;C=ENSEQ
  1361.     PUSH HL
  1362.     BIT 1,C
  1363.     CALL Z,EXENVF    ;if attack or decay phase
  1364.     POP HL
  1365.     LD (HL),C    ;save new ENSEQ phase
  1366.     JR OUTFREQ
  1367.  
  1368. RELEASE:    LD B,(HL)    ;B=ENSR (gate off)
  1369.     INC HL
  1370.     INC HL
  1371.     inc hl
  1372.     LD (HL),0    ;ENSEQ=0 (set attack phase)
  1373.     LD HL,ENVAL+1
  1374.     ADD HL,DE
  1375.     LD A,(HLD)
  1376.     SUB 08H
  1377.     JR NZ,RELEASE2    ;not at sustain level
  1378.     OR (HL)    ;at sustain level (ENVAL)
  1379.     RET Z    ;at sustain level of 0
  1380. RELEASE2:    LD A,B    ;A=ENSR (gate off)
  1381.     LD BC,1    ;force decay (release phase)
  1382.     CALL EXENVF    ;release phase
  1383.  
  1384. ;-----------------------------------------------------------------------------
  1385. OUTFREQ:    LD HL,FQOFF    ;frequency offset
  1386.     ADD HL,DE
  1387.     LD A,(HL)    ;A=FQOFF (0 if music/8 or 0-0F effect)
  1388.     LD HL,CTRLAD
  1389.     ADD HL,DE
  1390.     LD B,(HL)    ;B=current waveform
  1391.     INC HL
  1392.     INC HL
  1393.     add a,(hl)
  1394.     ld e,a    ;E=FREQ low byte +FQOFF
  1395.     inc hl
  1396.     ld d,(hl)    ;DE = word FREQ+FQOFF
  1397.     ld a,d
  1398.  
  1399.     LD A,B    ;A=current waveform
  1400.     LD BC,ENVAL-FREQ AND 0FFH
  1401.     ADD HL,BC
  1402.     LD L,(HL)    ;L=ENVAL
  1403.     LD H,A    ;H=current waveform
  1404.     LD A,(CURCHAN)
  1405.     LD C,A    ;C=current channel (0/1/2/3)
  1406.     LD A,L    ;A=ENVAL
  1407.     AND 0F0H    ;isolate current envelope level
  1408.     JR Z,NOVOLUME    ;volume = 0
  1409.     LD A,(NCHAN)    ;A=current noise channel
  1410.     BIT 7,H    ;H=current waveform
  1411.     JR Z,NONOISE    ;noise bit not set (in H)
  1412.  
  1413. ;-----------------------------------------------------------------------------
  1414.     push af
  1415.     ld a,(EFFSND)
  1416.     cp 0
  1417.     jr z,NOISE    ;music, so check other channels
  1418.     pop af
  1419.     jr NOISE_EFF    ;effect, so force noise
  1420. NOISE:    pop af
  1421.  
  1422.     CP 0FFH    ;any other noise already?
  1423.     JR NZ,NOISE1    ;yes, so leave noise channel alone
  1424. NOISE_EFF:    LD A,C    ;no noise used so far
  1425.     LD (NCHAN),A    ;so this channel will use noise
  1426. NOISE1:    CP C        ;noise in this channel?
  1427.     JR NZ,PULSE    ;no
  1428.  
  1429.     PUSH BC    ;yes,noise in this channel
  1430.     PUSH DE
  1431.     PUSH HL    ;H was CTRLAD/L was ENVAL
  1432.     LD B,L    ;B=ENVAL
  1433.  
  1434.     ld a,d    ;get high byte of freq
  1435.     xor 0ffh
  1436.     swap a
  1437.     and 70h    ;bits 4,5,6 only
  1438.     ld d,a
  1439.  
  1440.     ld a,e    ;get low byte of freq
  1441.     xor 0ffh
  1442.     swap a
  1443.     and 0Ch    ;bits 2 and 3 only (& force bit 3 low)
  1444.     rr a
  1445.     rr a        ;a has bits 0 and 1
  1446.     or 04h    ;force bit 2 high
  1447.     or d        ;add top 4 bits
  1448. NOISE2:    ld l,a    ;low byte into l
  1449.     ld c,3    ;force channel 3 (noise)
  1450.     ld h,0    ;3 bits of freq hi always 0
  1451.     CALL SETFREQ    ;set noise frequency
  1452.  
  1453.     ld a,(CURCHAN)    ;noise stereo position
  1454.     ld c,a
  1455.     inc c    ;c=1,2,3
  1456.     ld hl,STEREO
  1457.     dec c
  1458.     jr z,noise3    ;1 to 0
  1459.     ld hl,STEREO+SDLN
  1460.     dec c    ;2 to 1 to 0
  1461.     jr z,noise3
  1462.     ld hl,STEREO+SDLN+SDLN
  1463. noise3:    ld a,(hl)
  1464.     add a,a
  1465.     add a,a
  1466.     add a,a    ;convert to channel 4 bit position
  1467.     ld b,077h    ;channel 4 mask
  1468.     ld c,a    ;C=stereo bits
  1469.     lds a,(NR51)    ;get assignment
  1470.     and b    ;mask out this channel
  1471.     or c        ;add stereo for this channel
  1472.     lds (NR51),a
  1473.     JR ENDNOISE
  1474.  
  1475. NONOISE:    CP C        ;noise bit off in this channel
  1476.     JR NZ,PULSE    ;but noise in another channel
  1477.     PUSH BC    ;no noise and this was noise channel
  1478.     PUSH DE
  1479.     PUSH HL
  1480.     CALL NSOFF    ;so switch off noise
  1481. ENDNOISE:    POP HL    ;H=CTRLAD/ L=ENVAL
  1482.     POP DE    ;DE=frequency word
  1483.     POP BC    ;B=unused/ C=current channel
  1484.  
  1485. ;-----------------------------------------------------------------------------
  1486. PULSE:    LD A,H    ;A=current waveform
  1487.     AND 040H    ;check for pulse wave
  1488.     JR Z,FREQOFF    ;no other waveforms (set freq = 0)
  1489.  
  1490.     LD B,L    ;B=ENVAL
  1491.     LD L,E    ;transfer DE to HL
  1492.     LD H,D
  1493.     JR SETFREQ    ;other waveforms needed
  1494.  
  1495. ;-----------------------------------------------------------------------------
  1496. NOVOLUME:    LD A,(NCHAN)    ;envelope level=0
  1497.     CP C        ;was this the noise channel?
  1498.     JR NZ,FREQOFF    ;no, so just set tone=0/level=0
  1499.  
  1500.     CALL FREQOFF    ;yes, so set tone=0/level=0
  1501. NSOFF:    LD A,0FFH    ;cancel noise channel
  1502.     LD (NCHAN),A
  1503.     LD C,3    ;& set noise freq = 0/level=0 (chan 3)
  1504.  
  1505. ;-----------------------------------------------------------------------------
  1506. ;SET FREQUENCY
  1507. ;B=ENVAL
  1508. ;C=channel 0,1,2 or 3
  1509. ;HL=11 bit frequency value (FREQOFF sets HL=0)
  1510. ;A=unused
  1511. ;-----------------------------------------------------------------------------
  1512. FREQOFF:    LD HL,0
  1513.     LD B,H    ;force 0 volume
  1514.  
  1515. SETFREQ:    PUSH BC    ;save ENVAL and current channel
  1516.     LD A,C
  1517.     LD BC,NR13    ;low byte freq (sound 1)
  1518.     AND A    ;set flags
  1519.     JR Z,SETFR2    ;channel 1
  1520.     LD BC,NR23
  1521.     DEC A
  1522.     JR Z,SETFR2    ;channel 2
  1523.     LD BC,NR33
  1524.     DEC A
  1525.     JR Z,SETFR2    ;channel 3
  1526.     LD BC,NR43    ;channel 4
  1527.  
  1528. SETFR2:    LD A,L    ;L=low byte value
  1529.     LD (BC),A    ;save low byte (NR13/23/33/43)
  1530.     INC C    ;now move to high byte freq. register
  1531.     LD A,H
  1532.     AND 07H    ;only 3 bits used for frequency high
  1533.     LD (BC),A    ;save high byte (NR14/24/34/44)
  1534.  
  1535.     POP HL    ;retreive ENVAL (PUSH BC)
  1536.     LD L,A    ;L=high byte of freq
  1537.     LD A,H    ;A=ENVAL
  1538.     AND 0F0H    ;isolate envelope level
  1539.     LD H,A    ;H=current envelope level
  1540.     LD A,C
  1541.     CP NR34 AND 255    ;channel 3 ?
  1542.     JR Z,SETWAVE    ;yes
  1543.  
  1544.     dec c
  1545.     dec c
  1546.     cp NR44 and 255    ;channel 4 ?
  1547.     jr z,SETENV    ;yes,so ignore
  1548.     push hl
  1549.     ld hl,CTRLAD    ;channel 1 & 2 current waveform
  1550.     cp NR14 and 255
  1551.     jr z,SETPW
  1552.     ld hl,CTRLAD+SDLN
  1553. SETPW:    ld a,(hl)    ;get current waveform
  1554.     and 030h    ;pulse width bits only
  1555.     add a,a
  1556.     add a,a    ;move to bit 7 & 6
  1557.          dec c
  1558.          ld (bc),a    ;save waveform (NR11/21)
  1559.          pop hl
  1560.          inc c
  1561.  
  1562. SETENV:    LD A,(BC)    ;NR12/22/42 envelope
  1563.     AND 0F0H    ;current envelope level
  1564.     CP H        ;desired envelope level
  1565.     RET Z    ;don't change if same
  1566.     LD A,H
  1567.     LD (BC),A    ;save new envelope level
  1568.     INC C
  1569.     INC C
  1570. SETINIT:    LD A,L    ;high 3 bits of frequency
  1571.     OR 80H    ;set restart bit
  1572.     LD (BC),A    ;save to NR14/24/34/44
  1573.     AND 07H    ;extract freq high bits only
  1574.     LD (BC),A    ;freq hi only (already restarted)
  1575.     RET
  1576.  
  1577.  
  1578. SETWAVE:    LD A,(ENC3)    ;channel 3 only (wave table)
  1579.     CP H        ;is desired same as current level ?
  1580.     RET Z    ;don't change if same level
  1581.     XOR A
  1582.     LDS (NR30),A    ;sound 3 off
  1583.     LD A,H
  1584.     LD (ENC3),A    ;save desired as new volume level
  1585.     SWAP A    ;each nibble is same level
  1586.     OR H        ;A has level in each nibble
  1587.  
  1588.     push hl
  1589.     push af
  1590.     ld hl,CTRLAD+SDLN+SDLN
  1591.     ld a,(hl)
  1592.     swap a
  1593.     and 03h    ;pulse width bits only
  1594.     inc a    ;1-4
  1595.     ld l,a
  1596.  
  1597.     pop af    ;retreive volume level
  1598.     lds (WAVE),a
  1599.     lds (WAVE+8),a    ;12.%5 width
  1600.     dec l
  1601.     call z,SE70    ;if l=1
  1602.     lds (WAVE+1),a
  1603.     lds (WAVE+9),a    ;25% width (l=2)
  1604.     dec l
  1605.     call z,SE70
  1606.     lds (WAVE+2),a
  1607.     lds (WAVE+3),a
  1608.     lds (WAVE+10),a
  1609.     lds (WAVE+11),a    ;50% width (l=3)
  1610.     dec l
  1611.     call z,SE70
  1612.     lds (WAVE+4),a
  1613.     lds (WAVE+5),a
  1614.     lds (WAVE+12),a
  1615.     lds (WAVE+13),a    ;75% width (l=4)
  1616.     pop hl
  1617.     LD A,80H
  1618.     LDS (NR30),A    ;sound 3 on
  1619.     JR SETINIT    ;now restart sound
  1620.  
  1621. SE70:    xor a
  1622.     ret
  1623.  
  1624.  
  1625. ;-----------------------------------------------------------------------------
  1626. ;A=ENAD (gate on)
  1627. ;A=ENSR (gate off)
  1628. ;-----------------------------------------------------------------------------
  1629. EXENVF:    PUSH DE    ;save SDLN*1,2,3
  1630.  
  1631.     push af
  1632.     LD HL,ATKLVL
  1633.     ADD HL,DE
  1634.     LD A,(HL)
  1635.     LD (MAXVOL),A
  1636.     pop af
  1637.  
  1638.     LD HL,ENVAL
  1639.     ADD HL,DE
  1640.     PUSH HL
  1641.     LD E,(HL)
  1642.     INC HL
  1643.     LD H,(HL)
  1644.     LD L,E    ;HL=ENVAL (word)
  1645.  
  1646.     CALL EXENV    ;exits with HL=new ENVAL
  1647.  
  1648.     POP DE    ;ENVAL address (push HL)
  1649.     LD A,L
  1650.     LD (DE),A
  1651.     INC DE
  1652.     LD A,H
  1653.     LD (DE),A    ;final value of ENVAL (word)
  1654.     POP DE    ;restore channel offset
  1655.     RET
  1656.  
  1657. ;-----------------------------------------------------------------------------
  1658. ;CREATE ENVELOPES
  1659. ;A=ENAD/B=sustain value 00-F0 (gate on)
  1660. ;A=ENSR/B=0                   (gate off)
  1661. ;C=ENSEQ    0=attack/1=decay/2=sustain phase
  1662.  
  1663. ;HL=ENVAL (word)
  1664. ;-----------------------------------------------------------------------------
  1665. EXENV:    PUSH HL    ;HL=ENVAL (word)
  1666.     BIT 0,C    ;C=ENSEQ
  1667.     JR NZ,EX10
  1668.     RRCA        ;attack times are shorter
  1669.     RRCA
  1670.     RRCA        ;divide by 8
  1671.     JR EX20
  1672. EX10:    ADD A,A    ;decay times are longer
  1673. EX20:    AND 01EH    ;only 15*2 bytes in table
  1674.     ADD A,ADRTABLE AND 255
  1675.     LD L,A
  1676.     ADC A,ADRTABLE/256
  1677.     SUB L
  1678.     LD H,A    ;HL=ADRTABLE entry address
  1679.     LD E,(HL)
  1680.     INC HL
  1681.     LD D,(HL)    ;DE=envelope time (word)
  1682.     POP HL    ;HL=ENVAL (word)
  1683.     BIT 0,C    ;ENSEQ
  1684.     JR NZ,ENV_DEC    ;if decay phase
  1685.  
  1686. ENV_ATK:    ADD HL,DE    ;ENVAL+(envelope time)
  1687.     JR C,ENV_ATK2
  1688.     ADD HL,DE
  1689.     JR C,ENV_ATK2
  1690.     ADD HL,DE
  1691.     JR C,ENV_ATK2
  1692.     LD A,H
  1693.  
  1694.     push hl    ;save new ENVAL
  1695.     LD HL,MAXVOL    ;previously found 00-0F
  1696.     CP (HL)    ;maximum value for this voice
  1697.     pop hl
  1698.     RET C    ;not reached peak yet
  1699.  
  1700. ENV_ATK2:    LD HL,MAXVOL
  1701.     LD A,(HL)
  1702.     LD H,A
  1703.     LD L,0
  1704.     INC C    ;move to decay phase next
  1705.     RET
  1706.  
  1707. ENV_DEC:    LD A,B    ;(or forced release)
  1708.     AND 0F0H    ;B=00-F0 isolate sustain nibble
  1709.     OR 07H
  1710.     LD B,A
  1711.     SCF        ;set carry
  1712.     LD A,L
  1713.     SBC A,E
  1714.     LD L,A
  1715.     LD A,H
  1716.     SBC A,D
  1717.     LD H,A    ;HL=ENVAL-(envelope time)
  1718.     LD A,B    ;A=(sustain OR 7)
  1719.     JR C,ENV_SUS
  1720.     CP H
  1721.     INC HL
  1722.     RET C    ;not reached sustain phase
  1723.  
  1724. ENV_SUS:    INC A    ;sustain
  1725.     LD H,A
  1726.     LD L,0
  1727.     INC C    ;move to sustain phase next
  1728.     RET
  1729.  
  1730.  
  1731.  
  1732.  
  1733. ;-------------------------------------------------------------------------------
  1734. ;START OF MUSIC CODE
  1735. ;-------------------------------------------------------------------------------
  1736.  
  1737. SENDMUS:
  1738.     BIT 7,A        ;Enter with A = tracknum or (80H+fader count)
  1739.     JR Z,SMUSIC2
  1740.     AND 07FH        ;negative value = fade value
  1741.     LD (FADER),A
  1742.     RET        ;nothing this time
  1743.  
  1744. SMUSIC2:
  1745.     ld l,a
  1746.     ld h,0
  1747.     add hl,hl
  1748.     add hl,hl
  1749.     add hl,hl    ;8 bytes each track
  1750.     ld a,l
  1751.     ld b,h        ;save high byte of word offset
  1752.     LD HL,TRKOFF    ;get pointer for this musicdata
  1753.     ADD A,(HL)    ;add low byte of trkoffset
  1754.     LD E,A        ;save low byte of final address
  1755.     INC HL
  1756.     ld a,b        ;retreive high byte
  1757.     ADC A,(HL)    ;add high byte of trkoffset
  1758.     LD H,A        ;final high byte of address
  1759.     LD L,E        ;final low bytes of address
  1760.     LD A,(HLI)    ;A points to 1st low byte
  1761.  
  1762.     LD (TRACK),A
  1763.     LD A,(HLI)
  1764.     LD (TRACK+1),A
  1765.     LD A,(HLI)
  1766.     LD (SDLN+TRACK),A
  1767.     LD A,(HLI)
  1768.     LD (SDLN+TRACK+1),A
  1769.     LD A,(HLI)
  1770.     LD (2*SDLN+TRACK),A
  1771.     LD A,(HLI)
  1772.     LD (2*SDLN+TRACK+1),A
  1773.  
  1774.     LD DE,0
  1775.     LD B,3        ;3 channels
  1776. SM20:    PUSH BC
  1777.     LD HL,VCEMUTE
  1778.     ADD HL,DE
  1779.     XOR A
  1780.     LD (HL),A
  1781.     LD HL,LOOPFLAG
  1782.     ADD HL,DE
  1783.     LD (HL),A
  1784.     LD HL,SEQSTEP
  1785.     ADD HL,DE
  1786.     LD (HL),A
  1787.     LD HL,CTRLAD
  1788.     ADD HL,DE
  1789.     LD (HL),A
  1790.     LD HL,ENSR
  1791.     ADD HL,DE
  1792.     LD (HL),A
  1793.     LD HL,DURATION
  1794.     ADD HL,DE
  1795.     LD (HL),1
  1796.     ld a,0FFh
  1797.     LD HL,VOICENUM
  1798.     ADD HL,DE
  1799.     ld (hl),a
  1800.     ld hl,THRESHOLD
  1801.     add hl,de
  1802.     ld (hl),a
  1803.     ld hl,TRKSTEP
  1804.     add hl,de
  1805.     ld (hl),a
  1806.     CALL READTK
  1807.     LD HL,SDLN
  1808.     ADD HL,DE
  1809.     LD D,H
  1810.     LD E,L
  1811.     POP BC
  1812.     DEC B
  1813.     JR NZ,SM20
  1814.     XOR A
  1815.     LD (FADECNT),A
  1816.     ld (GLOBOFFSET),a
  1817.     DEC A
  1818.     LD (FADER),A
  1819.     LD (STATUS),A
  1820.     LD (TEMPOCNTR),A
  1821.     ld (CLOCK_L),a    ;starts @ 0FFFFh 1st inc to 0000h
  1822.     ld (CLOCK_H),a
  1823.     ld a,07h
  1824.     LD (VOLUME),A
  1825.     LD A,077H    ;max volume in both left & right
  1826.     LDS (NR50),A
  1827.     RET
  1828.  
  1829.  
  1830.  
  1831.  
  1832. ;-------------------------------------------------------------------------------
  1833. INTMUSIC:
  1834.     LD A,(STATUS)
  1835.     RLA
  1836.     RET NC    ;if not minus
  1837.  
  1838.     LD A,(FADER)    ;fadetest
  1839.     BIT 7,A
  1840.     JR NZ,TEMPOTEST
  1841.  
  1842.     OR A        ;set flags
  1843.     JR Z,TRKSTOP    ;080H fader value = stop immediately
  1844.     LD HL,FADECNT    ;fader active
  1845.     DEC (HL)
  1846.     BIT 7,(HL)
  1847.     JR Z,TEMPOTEST
  1848.     LD (HL),A    ;save FADER value back into FADECNT
  1849.     LD HL,VOLUME    ;end of fade count so dec volume (inits to 07h)
  1850.     DEC (HL)
  1851.     JR Z,TRKSTOP    ;end of fade
  1852.     LD A,(HL)    ;get current VOLUME
  1853.     LD C,A
  1854.     SWAP A
  1855.     OR C        ;put into both nibbles
  1856.     LDS (NR50),A
  1857.  
  1858. TEMPOTEST:    LD A,(TEMPOCNTR)
  1859.     LD    HL,TEMPOVAL
  1860.     ADD    A,(HL)
  1861.     LD    (TEMPOCNTR),A
  1862.     JR    NC,TEMPO2
  1863.     ld    hl,CLOCK_L    ;now update tempo clock
  1864.     inc    (hl)
  1865.     jp    nz,TEMPO1
  1866.     inc    hl
  1867.     inc    (hl)
  1868. TEMPO1:    XOR A
  1869.     JR TEMPO3
  1870. TEMPO2:    LD A,0FFH
  1871. TEMPO3:    LD (TEMPOFLAG),A
  1872.  
  1873. MUSIC1:    XOR A
  1874.     LD D,A
  1875.     LD E,A
  1876.     LD (CURCHAN),A
  1877. MUSICLOOP:    LD HL,SFXHOLD
  1878.     ADD HL,DE
  1879.     LD A,(HL)
  1880.     AND A
  1881.     JR Z,MUSIC1B    ;past critical portion/ no effect
  1882.     LD HL,VCEMUTE
  1883.     ADD HL,DE
  1884.     LD (HL),0FFH    ;mute music channel during effect
  1885.  
  1886. MUSIC1B:    LD A,(TEMPOFLAG)
  1887.     AND A
  1888.     JP NZ,TREATMENT
  1889.  
  1890.     ld hl,NOTELENGTH    ;music2
  1891.     add hl,de
  1892.     inc (hl)
  1893.     inc hl
  1894.     dec (hl)    ;DURATION
  1895.     jp nz,TREATMENT
  1896.  
  1897.     LD HL,SEQNUM    ;trkread
  1898.     ADD HL,DE
  1899.     LD A,(HLD)    ;HL now points to SEQSTEP
  1900.     CP 0FEH
  1901.     JR C,SEQREAD
  1902.     JR NZ,TRKLOOP
  1903.  
  1904. TRKSTOP:
  1905.     ld a,00h
  1906.     LD (VOLUME),A
  1907.     LD A,000H    ;force min volume in left & right chan
  1908.     LDS (NR50),A
  1909.  
  1910.     XOR A
  1911.     LD (STATUS),A    ;force STATUS=0
  1912.     LD D,A
  1913.     LD E,A
  1914.     CALL KILLS    ;kill channel 1
  1915.     LD DE,SDLN
  1916.     CALL KILLS    ;kill channel 2
  1917.     LD DE,2*SDLN
  1918. KILLS:    LD HL,VCEMUTE    ;kill channel 3
  1919.     ADD HL,DE
  1920.     BIT 7,(HL)
  1921.     LD (HL),0FFH
  1922.     RET NZ    ;still effects
  1923.     LD HL,ENVAL+1
  1924.     ADD HL,DE
  1925.     XOR A
  1926.     LD (HL),A    ;no effects, so ENVAL+1=0
  1927.     LD HL,CTRLAD
  1928.     ADD HL,DE
  1929.     LD (HL),A    ;& CTRLAD=0
  1930.     RET
  1931.  
  1932. TRKLOOP:    LD (HL),0
  1933.     CALL READTK
  1934.  
  1935. SEQREAD:    ADD A,A    ;word table
  1936.     LD C,A    ;A = SEQNUM
  1937.     LD B,0
  1938.     JR NC,SEQREAD1
  1939.     LD B,1    ;for seq 80h or greater
  1940. SEQREAD1:    LD A,(SEQOFF)    ;get lo byte of offset table address
  1941.     ADD A,C    ;add seqnumber*2
  1942.     LD L,A    ;store result, low
  1943.     LD A,(SEQOFF+1)    ;get hi byte of address
  1944.     ADC A,B    ;add carry only
  1945.     LD H,A    ;HL points to word in offset table
  1946.     LD A,(SEQDATA)    ;get low byte of SEQDATA address
  1947.     ADD A,(HL)    ;add offset for this sequence
  1948.     LD C,A
  1949.     LD A,(SEQDATA+1)
  1950.     INC HL
  1951.     ADC A,(HL)
  1952.     LD B,A    ;BC=address of 1st byte of sequence
  1953.  
  1954.     LD HL,SEQSTEP
  1955.     ADD HL,DE
  1956.     LD A,(HL)    ;A = seqstep for this channel
  1957.     cp 0
  1958.     jr nz,seqread2
  1959.     ld hl,THRESHOLD
  1960.     add hl,de
  1961.     ld (hl),0FFh    ;reset THRESHOLD to 0FFh at start
  1962. seqread2:    ADD A,C
  1963.     LD C,A
  1964.     ADC A,B
  1965.     SUB C
  1966.     LD B,A    ;BC points to sequence byte
  1967.  
  1968.     LD A,0FFH
  1969.     LD (VCETEMP),A    ;VCETEMP=0ffh
  1970.     LD HL,GATEMASK
  1971.     ADD HL,DE
  1972.     LD (HL),A    ;GATEMASK=0ffh
  1973.     LD HL,BENDBYTE
  1974.     ADD HL,DE
  1975.     LD (HL),0    ;set BENDBYTE=0
  1976.     LD HL,ATTKEND
  1977.     ADD HL,DE
  1978.     LD (HL),0    ;set ATTKEND=0
  1979.     ld hl,TIED_NOTE
  1980.     add hl,de
  1981.     ld (hl),0    ;set TIED_NOTE=0
  1982.  
  1983. newpair:    LD A,(BC)    ;get next sequence byte
  1984.     BIT 7,A
  1985.     JR Z,NOTEREAD    ;bpl
  1986.     INC BC    ;ready for 2nd byte in pair
  1987.  
  1988. param80:    cp 080h    ;voice change
  1989.     jr nz,param81
  1990.     ld a,(bc)
  1991.     ld (VCETEMP),a    ;VCETEMP was = 0ffh
  1992.     jp paramexit
  1993.  
  1994. param81:    cp 081h    ;rest
  1995.     jr nz,param82
  1996.     ld hl,GATEMASK
  1997.     add hl,de
  1998.     ld (hl),0feh    ;release & fade
  1999.     ld hl,TIED_NOTE
  2000.     add hl,de
  2001.     ld (hl),0ffh
  2002.     jp duraread
  2003.  
  2004.  
  2005. param82:    cp 082h    ;bend
  2006.     jr nz,param83
  2007.     ld a,(bc)
  2008.     ld hl,BENDBYTE
  2009.     add hl,de
  2010.     ld (hl),a
  2011.     jp paramexit
  2012.  
  2013. param83:    cp 083h    ;tempo
  2014.     jr nz,param84
  2015.     ld a,(bc)
  2016.     LD hl,TEMPOVAL
  2017.     LD (hl),A    ;temp fixed value
  2018.     jp paramexit
  2019.  
  2020. param84:    cp 084h    ;tied
  2021.     jr nz,param85
  2022.     ld hl,TIED_NOTE
  2023.     add hl,de
  2024.     ld (hl),0ffh
  2025.     jp paramexit
  2026.  
  2027. param85:    cp 085h    ;gate
  2028.     jr nz,param86
  2029.     ld a,(bc)
  2030.     ld hl,THRESHOLD
  2031.     add hl,de
  2032.     ld (hl),a
  2033.     jp    paramexit
  2034.     
  2035. param86:    cp 086h    ;global offset
  2036.     jr nz,paramexit
  2037.     ld a,(bc)
  2038.     ld hl,GLOBOFFSET
  2039.     ld (hl),a
  2040.  
  2041.  
  2042. paramexit:    inc bc    ;ready for note
  2043.     ld hl,seqstep    ;HL=seqstep for this channel
  2044.     add hl,de
  2045.     inc (hl)
  2046.     inc (hl)    ;add 2 to SEQSTEP
  2047.     jp newpair
  2048.  
  2049.  
  2050. NOTEREAD:    LD HL,NOTEVALUE
  2051.     ADD HL,DE
  2052.     LD (HL),A    ;save notevalue
  2053.     INC BC
  2054.  
  2055. DURAREAD:    LD A,(BC)    ;get next sequence byte
  2056.     ld hl,DURATION
  2057.     ADD HL,DE
  2058.     LD (HLD),A
  2059.     LD (HL),0    ;NOTELENGTH=0
  2060.     LD HL,SEQSTEP    ;HL=seqstep for this channel
  2061.     ADD HL,DE
  2062.     INC    (HL)
  2063.     INC    (HL)    ;ADD 2 TO SEQSTEP
  2064.     INC BC
  2065.     PUSH BC    ;save seq address for READEND
  2066.  
  2067. ;-----------------------------------------------------------------------------
  2068.     LD HL,VCEMUTE    ;Check for effect in this channel
  2069.     ADD HL,DE
  2070.     BIT 7,(HL)
  2071.     JR Z,NEWSTART    ;no effects
  2072.     LD HL,SFXHOLD
  2073.     ADD HL,DE
  2074.     LD A,(HL)
  2075.     AND A
  2076.     JR NZ,NEWSTART    ;still effects in critical portion
  2077.     LD HL,TIED_NOTE
  2078.     ADD HL,DE
  2079.     LD (HL),A    ;past critical - force tie off
  2080.  
  2081. ;-----------------------------------------------------------------------------
  2082. NEWSTART:    LD A,(VCETEMP)
  2083.     BIT 7,A
  2084.     JR NZ,MODREAD    ;0ffh= no new voice
  2085.     LD HL,VOICENUM
  2086.     ADD HL,DE
  2087.     CP (HL)    ;existing voice
  2088.     JR Z,MODREAD    ;ignore if same voice
  2089.     LD (HL),A    ;save new voice
  2090.     LD HL,TIED_NOTE
  2091.     ADD HL,DE
  2092.     LD (HL),A    ;and force envelope restart
  2093.  
  2094. MODREAD:    LD HL,TIED_NOTE
  2095.     ADD HL,DE
  2096.     BIT 7,(HL)
  2097.     JR NZ,READEND    ;tied note - ignore new mods
  2098.  
  2099.     LD HL,VOICENUM
  2100.     ADD HL,DE
  2101.     ld l,(hl)
  2102.     ld h,0
  2103.     add hl,hl
  2104.     add hl,hl
  2105.     add hl,hl
  2106.     add hl,hl    ;16 bytes each voice
  2107.     ld c,l
  2108.     ld b,h    ;move to bc (=0000 to 01F0)
  2109.     LD HL,VOICEOFFSET
  2110.     ADD HL,DE
  2111.     LD (HL),c    ;save offset to this voice
  2112.     inc hl
  2113.     ld (hl),b
  2114.  
  2115.     XOR A    ;atkdec
  2116.     CALL GETVOICE
  2117.     LD (ADTEMP),A
  2118.     INC BC
  2119.     LD A,(BC)    ;susrel
  2120.     LD (SRTEMP),A
  2121.     INC BC
  2122.     LD A,(BC)    ;wvefrm
  2123.     LD HL,NOTECTRL
  2124.     ADD HL,DE
  2125.     LD (HL),A
  2126.     INC BC
  2127.     LD A,(BC)    ;specls
  2128.     LD HL,SPECIAL
  2129.     ADD HL,DE
  2130.     LD (HL),A
  2131.     inc bc
  2132.     ld a,(bc)    ;stereo
  2133.     ld (STEREOTEMP),a
  2134.     ld hl,TRANSPOSE
  2135.     add hl,de
  2136.     inc bc
  2137.     ld a,(bc)
  2138.     ld (hl),a    ;offset (TRANSPOSE)
  2139.     inc bc
  2140.     ld a,(bc)
  2141.     ld (pktemp),a    ;ATKLVL
  2142.     INC BC
  2143.     ld hl,SPECNTDN
  2144.     add hl,de
  2145.     LD A,(BC)    ;atkcnt
  2146.     LD (HL),A
  2147.     LD A,15    ;vdelay
  2148.     CALL GETVOICE
  2149.     LD HL,VIBDELAY
  2150.     ADD HL,DE
  2151.     LD (HL),A
  2152.  
  2153. ;-----------------------------------------------------------------------------
  2154.     LD HL,SFXHOLD    ;any effect on ?
  2155.     ADD HL,DE
  2156.     LD A,(HL)
  2157.     AND A
  2158.     JR NZ,READEND    ;yes, so ignore
  2159.     
  2160.     LD HL,VCEMUTE
  2161.     ADD HL,DE
  2162.     LD (HL),A    ;else clear any mute
  2163.     LD HL,ENAD
  2164.     ADD HL,DE
  2165.     LD A,(ADTEMP)
  2166.     LD (HLI),A    ;music ADTEMP to ENAD
  2167.     LD A,(SRTEMP)
  2168.     LD (HLI),A    ;music SRTEMP to ENSR
  2169.     ld a,(PKTEMP)
  2170.     swap a
  2171.     and 0F0h
  2172.     or 08h
  2173.     ld (hl),a    ;music PKTEMP to ATKLVL
  2174.     ld a,(STEREOTEMP)
  2175.     and 11h    ;L/R bits only
  2176.     ld hl,STEREO
  2177.     add hl,de
  2178.     ld (hl),a    ;music STEREOTEMP to STEREO
  2179.  
  2180. ;-----------------------------------------------------------------------------
  2181. READEND:
  2182.     ld hl,NOTEVALUE
  2183.     add hl,de
  2184.     ld a,(hl)    ;get notevalue
  2185.     push hl
  2186.     ld hl,TRANSPOSE
  2187.     add hl,de
  2188.     add a,(hl)
  2189.  
  2190.     LD HL,SPECIAL
  2191.     ADD HL,DE
  2192.     LD C,(HL)
  2193.     bit 7,c        ;special (fixed)
  2194.     jr nz,rdend2
  2195.  
  2196.     ld hl,GLOBOFFSET
  2197.     add a,(hl)
  2198. rdend2:    pop hl
  2199.     ld (hl),a    ;save transposed notevalue
  2200.  
  2201.     ld hl,NOTE    ;find freq word value for this note
  2202.     add hl,de
  2203.     inc hl    ;high byte of note
  2204.     ADD A,A    ;word table access
  2205.     ADD A,NOTETABLE+1 AND 255
  2206.     LD C,A
  2207.     ADC A,(NOTETABLE+1)/256
  2208.     SUB C
  2209.     LD B,A
  2210.     LD A,(BC)
  2211.     LD (HLD),A    ;save high byte of NOTE
  2212.     DEC BC
  2213.     LD A,(BC)
  2214.     LD (HL),A    ;save low byte of NOTE
  2215.  
  2216.     POP BC    ;retrieve (zseq)
  2217.     LD A,(BC)    ;look at next byte
  2218.     INC A    ;0ffh to 0
  2219.     JR NZ,READEXIT
  2220.     LD HL,SEQSTEP    ;end of sequence
  2221.     ADD HL,DE
  2222.     LD (HLI),A    ;SEQSTEP=0
  2223.     INC HL
  2224.     DEC (HL)    ;seqrepeat
  2225.     CALL Z,READTK
  2226.  
  2227. READEXIT:    LD HL,VCEMUTE
  2228.     ADD HL,DE
  2229.     LD A,(HL)
  2230.     AND A
  2231.     JP NZ,NEXTCHAN    ;effect, so ignore other music code
  2232.     LD HL,SPECNTUP
  2233.     ADD HL,DE
  2234.     LD (HL),A
  2235.     PUSH HL
  2236.     LD HL,VIBSPEED
  2237.     ADD HL,DE
  2238.     LD (HL),A
  2239.     POP HL
  2240.     DEC HL
  2241.     DEC HL
  2242.     LD C,(HL)    ;C=SPECIAL
  2243.     INC HL
  2244.     JP spec40
  2245.  
  2246.  
  2247. TREATMENT:    LD HL,VCEMUTE
  2248.     ADD HL,DE
  2249.     BIT 7,(HL)
  2250.     JP NZ,NEXTCHAN    ;ignore all treatment if sound effect
  2251.  
  2252. vibrato:    LD HL,VIBDELAY
  2253.     ADD HL,DE
  2254.     LD A,(HL)
  2255.     AND A
  2256.     JR Z,vib2    ;delay finished, so test for vibrato
  2257.     DEC (HL)
  2258.     JP bending
  2259.  
  2260. vib2:    LD HL,SPECNTDN
  2261.     ADD HL,DE
  2262.     OR (HL)
  2263.     JP NZ,bending
  2264.     LD A,14    ;vibrto
  2265.     CALL GETVOICE
  2266.     AND A
  2267.     JP Z,bending
  2268.     LD C,A
  2269.     LD HL,VIBSPEED
  2270.     ADD HL,DE
  2271.     BIT 7,(HL)
  2272.     JR NZ,vib4
  2273.  
  2274.     LD B,0
  2275.     LD HL,VIBTB1
  2276.     ADD HL,BC
  2277.     LD A,(HL)
  2278.     LD HL,VIBLIMIT
  2279.     ADD HL,DE
  2280.     LD (HLD),A
  2281.     XOR A
  2282.     LD (HLD),A
  2283.     LD (HLD),A
  2284.     PUSH HL
  2285.     LD HL,VIBTB2
  2286.     ADD HL,BC
  2287.     LD A,(HL)
  2288.     POP HL
  2289.     LD (HL),A
  2290.  
  2291.     LD HL,NOTEVALUE
  2292.     ADD HL,DE
  2293.     LD A,(HL)
  2294.     ADD A,A
  2295.     ADD A,NOTETABLE AND 255
  2296.     LD L,A
  2297.     ADC A,NOTETABLE/256
  2298.     SUB L
  2299.     LD H,A
  2300.     LD C,(HL)
  2301.     INC HL
  2302.     LD B,(HL)
  2303.     INC HL
  2304.     PUSH HL
  2305.     LD HL,NOTE
  2306.     ADD HL,DE
  2307.     LD (HL),C
  2308.     INC HL
  2309.     LD (HL),B
  2310.     POP HL
  2311.     LD A,(HLI)
  2312.     SUB C
  2313.     LD C,A
  2314.     LD A,(HL)
  2315.     SBC A,B
  2316.     LD B,A
  2317.     LD HL,VIBINC
  2318.     ADD HL,DE
  2319.     LD (HL),C
  2320.     INC HL
  2321.     LD (HL),B
  2322.  
  2323. vibloop1:    LD HL,VIBSPEED
  2324.     ADD HL,DE
  2325.     DEC (HL)
  2326.     BIT 7,(HL)
  2327.     JR NZ,bending
  2328.     LD HL,VIBINC+1
  2329.     ADD HL,DE
  2330.     SRL (HL)
  2331.     DEC HL
  2332.     RR (HL)
  2333.     JR vibloop1
  2334.  
  2335. vib4:    LD HL,FREQDIR
  2336.     ADD HL,DE
  2337.     BIT 7,(HL)
  2338.     LD HL,VIBINC
  2339.     ADD HL,DE
  2340.     JR NZ,vib5
  2341.     LD A,(HLI)
  2342.     LD B,(HL)
  2343.     INC HL
  2344.     ADD A,(HL)
  2345.     LD (HLI),A
  2346.     LD A,B
  2347.     ADC A,(HL)
  2348.     JR vib6
  2349.  
  2350. vib5:    LD C,(HL)
  2351.     INC HL
  2352.     LD B,(HL)
  2353.     INC HL
  2354.     LD A,(HL)
  2355.     SUB C
  2356.     LD (HLI),A
  2357.     LD A,(HL)
  2358.     SBC A,B
  2359.  
  2360. vib6:    LD (HL),A
  2361.     LD HL,VIBDIR
  2362.     ADD HL,DE
  2363.     BIT 7,(HL)
  2364.     INC HL
  2365.     JR NZ,vib7
  2366.     INC (HL)
  2367.     LD A,(HLI)
  2368.     CP (HL)
  2369.     JR C,bending
  2370.     DEC HL
  2371.     DEC HL
  2372.     LD (HL),0FFH
  2373.     DEC HL
  2374.     DEC HL
  2375.     DEC HL
  2376.     LD A,(HL)
  2377.     CPL
  2378.     LD (HL),A
  2379.     JR bending
  2380.  
  2381. vib7:    DEC (HL)    ;vib7
  2382.     JR NZ,bending
  2383.     DEC HL
  2384.     LD (HL),0
  2385.  
  2386.  
  2387. bending:    LD HL,BENDBYTE    ;bending
  2388.     ADD HL,DE
  2389.     LD A,(HL)
  2390.     AND A
  2391.     JR Z,specials
  2392.     CP 080H
  2393.     JR NC,bending2
  2394.  
  2395.     LD HL,NOTE    ;bend up
  2396.     ADD HL,DE
  2397.     ADD A,(HL)
  2398.     LD (HLI),A
  2399.     JR NC,specials
  2400.     INC (HL)
  2401.     JR specials
  2402.  
  2403. bending2:    AND 07FH    ;bend down
  2404.     LD C,A
  2405.     LD HL,NOTE
  2406.     ADD HL,DE
  2407.     LD A,(HL)
  2408.     SUB C
  2409.     LD (HLI),A
  2410.     JR NC,specials
  2411.     DEC (HL)
  2412.  
  2413.  
  2414. specials:    LD HL,SPECIAL
  2415.     ADD HL,DE
  2416.     LD C,(HL)
  2417.     INC HL
  2418.     INC HL
  2419.     bit 0,c        ;arpeggio
  2420.     jr z,spec02
  2421.     ld a,(hl)    ;specntup
  2422.     and 07h
  2423.     rr a
  2424.     jp spec20a
  2425.  
  2426.  
  2427. spec02:    BIT 1,C    ;trill note
  2428.     JR Z,spec04
  2429.     PUSH BC
  2430.     PUSH HL
  2431.     BIT 0,(HL)    ;specntup
  2432.     JR NZ,spec02b
  2433.     LD HL,NOTEVALUE
  2434.     ADD HL,DE
  2435.     LD A,(HL)
  2436.     JR spec02c
  2437. spec02b:    LD A,13    ;trlnote
  2438.     CALL GETVOICE
  2439.     BIT 7,A
  2440.     JR Z,spec02c
  2441.     AND 07FH
  2442.     LD HL,NOTEVALUE
  2443.     ADD HL,DE
  2444.     ADD A,(HL)
  2445. spec02c:    ADD A,A
  2446.     ADD A,NOTETABLE AND 255
  2447.     LD C,A
  2448.     ADC A,NOTETABLE/256
  2449.     SUB C
  2450.     LD B,A
  2451.     LD HL,NOTE
  2452.     ADD HL,DE
  2453.     LD A,(BC)
  2454.     LD (HLI),A
  2455.     INC BC
  2456.     LD A,(BC)
  2457.     LD (HL),A
  2458.     POP HL
  2459.     POP BC
  2460.  
  2461.  
  2462. spec04:    BIT 2,C        ;drum
  2463.     JR Z,spec08
  2464.     PUSH BC
  2465.     PUSH HL
  2466.     BIT 0,(HL)    ;specntup
  2467.     JR NZ,spec04b
  2468.     LD A,2    ;wvefrm
  2469.     CALL GETVOICE
  2470.     JR spec04c
  2471. spec04b:    LD A,081H
  2472. spec04c:    LD HL,NOTECTRL    ;noise/ normal waveform alternately
  2473.     ADD HL,DE
  2474.     LD (HL),A
  2475.     LD HL,NOTELENGTH
  2476.     ADD HL,DE
  2477.     LD A,(HL)
  2478.     CP 02H
  2479.     JR C,spec04d
  2480.     LD HL,GATEMASK    ;gate drums off after duration 2
  2481.     ADD HL,DE
  2482.     LD (HL),0FEH
  2483. spec04d:
  2484.     LD HL,NOTE+1    ;freq decay
  2485.     ADD HL,DE
  2486.     DEC (HL)
  2487.     BIT 7,(HL)
  2488.     JR Z,spec04e
  2489.     INC (HL)
  2490. spec04e:
  2491.     POP HL
  2492.     POP BC
  2493.  
  2494.  
  2495. spec08:    BIT 3,C        ;spec08 (chord)
  2496.     JR Z,spec08b
  2497.     LD A,(HL)    ;specntup
  2498.     AND 03h
  2499.     JR spec20a
  2500. spec08b:    DEC HL
  2501.  
  2502.  
  2503. spec40:    BIT 6,C        ;drumbend
  2504.     JR  Z,spec10
  2505.     PUSH BC
  2506.     PUSH HL
  2507.     LD A,9        ;note1
  2508.     CALL GETVOICE
  2509.     ld hl,BENDBYTE
  2510.     add hl,de
  2511.     ld (hl),a    ;save drumbend value to bendbyte
  2512.     POP HL
  2513.     POP BC
  2514.  
  2515.  
  2516. spec10:    BIT 4,C        ;atkwave
  2517.     JR Z,spec20
  2518.     PUSH BC
  2519.     PUSH HL
  2520.     LD A,(HL)    ;SPECNTDN
  2521.     AND A
  2522.     JR Z,spec10b
  2523.     LD A,8        ;atkwave
  2524.     JR spec10c
  2525. spec10b:
  2526.     LD HL,ATTKEND    ;1 frame after attack
  2527.     ADD HL,DE
  2528.     BIT 7,(HL)
  2529.     JR NZ,spec10d
  2530.     LD A,2        ;waveform
  2531. spec10c:
  2532.     CALL GETVOICE
  2533.     LD HL,NOTECTRL
  2534.     ADD HL,DE
  2535.     LD (HL),A
  2536. spec10d:
  2537.     POP HL
  2538.     POP BC
  2539.  
  2540.  
  2541. spec20:    BIT 5,C        ;atknote
  2542.     JR Z,finalbit
  2543.     LD A,(HLI)    ;specntdn
  2544.     AND A
  2545.     JR Z,spec20c
  2546.     LD A,(HL)
  2547. spec20a:
  2548.     ADD A,9        ;chord note 0/1/2/3 to note1/2/3/4
  2549.     CALL GETVOICE
  2550.     LD HL,NOTEVALUE
  2551.     ADD HL,DE
  2552.     BIT 7,A
  2553.     JR Z,spec20d
  2554.     AND 07FH
  2555.     CP 040H
  2556.     JR NC,spec20b
  2557.     ADD A,(HL)
  2558.     JR spec20d
  2559.  
  2560. spec20b:
  2561.     AND 03FH
  2562.     LD C,A
  2563.     LD A,(HL)
  2564.     SUB C
  2565.     JR spec20d
  2566.  
  2567. spec20c:
  2568.     LD HL,ATTKEND    ;1 frame after attack
  2569.     ADD HL,DE
  2570.     BIT 7,(HL)
  2571.     JR NZ,finalbit
  2572.     LD HL,NOTEVALUE    ;restore proper note
  2573.     ADD HL,DE
  2574.     LD A,(HL)
  2575.  
  2576. spec20d:
  2577.     ADD A,A
  2578.     ADD A,NOTETABLE AND 255
  2579.     LD L,A
  2580.     ADC A,NOTETABLE/256
  2581.     SUB L
  2582.     LD H,A
  2583.     LD C,(HL)
  2584.     INC HL
  2585.     LD B,(HL)
  2586.     LD HL,NOTE
  2587.     ADD HL,DE
  2588.     LD (HL),C
  2589.     INC HL
  2590.     LD (HL),B
  2591.  
  2592.  
  2593. ;-----------------------------------------------------------------------------
  2594. finalbit:    ld hl,NOTELENGTH    ;check gate
  2595.     add hl,de
  2596.     ld a,(hl)
  2597.     ld hl,THRESHOLD
  2598.     add hl,de
  2599.     cp (hl)
  2600.     jr nz,final0
  2601.     ld hl,GATEMASK    ;end of gated note
  2602.     add hl,de
  2603.     ld (hl),0FEH    ;release and fade
  2604.  
  2605. final0:    LD HL,TIED_NOTE
  2606.     ADD HL,DE
  2607.     BIT 7,(HL)
  2608.     JR NZ,SL200    ;tied, so ignore new gate
  2609.     LD HL,SPECNTUP
  2610.     ADD HL,DE
  2611.     LD A,(HL)
  2612.     AND A    ;set flags only
  2613.     JR NZ,SL200    ;not 1st frame of this note
  2614.  
  2615.     ld a,(CURCHAN)    ;STEREO (1st frame only)
  2616.     inc a
  2617.     ld c,a    ;C=1,2,3 (current channel+1)
  2618.     ld hl,stereo
  2619.     add hl,de
  2620.     ld a,(hl)
  2621.     ld b,0EEh
  2622.     dec c
  2623.     jr z,SL190    ;channel 1
  2624.     add a,a    ;11h to 22h
  2625.     ld b,0DDh
  2626.     dec c
  2627.     jr z,SL190    ;channel 2
  2628.     add a,a    ;channel 3   (22h to 44h)
  2629.     ld b,0BBh
  2630.  
  2631. SL190:    ld c,a    ;C=stereo bits
  2632.     lds a,(NR51)    ;get assignment
  2633.     and b    ;mask out this channel
  2634.     or c        ;add stereo for this channel
  2635.     lds (NR51),a
  2636.  
  2637.     LD A,0FEH
  2638.     JR SL210
  2639. SL200:    LD A,0FFH    ;final0
  2640. SL210:    LD HL,NOTECTRL
  2641.     ADD HL,DE
  2642.     AND (HL)
  2643.     LD HL,GATEMASK
  2644.     ADD HL,DE
  2645.     AND (HL)
  2646.     LD HL,CTRLAD
  2647.     ADD HL,DE
  2648.     LD (HL),A    ;NOTECTRL  to CTRLAD
  2649.  
  2650.     LD HL,NOTE    ;transfer NOTE (music data)
  2651.     ADD HL,DE
  2652.     LD C,(HL)
  2653.     INC HL
  2654.     LD B,(HL)
  2655.     LD HL,FREQ    ;to FREQ (overwrites effects data)
  2656.     ADD HL,DE
  2657.     LD (HL),C
  2658.     INC HL
  2659.     LD (HL),B
  2660.  
  2661.     LD HL,SPECNTDN
  2662.     ADD HL,DE
  2663.     LD A,(HL)
  2664.     AND A
  2665.     JR NZ,final1
  2666.     PUSH HL
  2667.     LD HL,ATTKEND
  2668.     ADD HL,DE
  2669.     LD (HL),0FFH
  2670.     POP HL
  2671.     JR final2
  2672. final1:    DEC (HL)    ;SPECNTDN
  2673. final2:    INC HL
  2674.     INC (HL)    ;SPECNTUP
  2675.  
  2676.  
  2677. ;-----------------------------------------------------------------------------
  2678. NEXTCHAN:    LD HL,SDLN
  2679.     ADD HL,DE
  2680.     LD D,H
  2681.     LD E,L
  2682.     LD HL,CURCHAN
  2683.     INC (HL)
  2684.     LD A,(HL)
  2685.     CP 3
  2686.     JP C,MUSICLOOP
  2687.  
  2688.     RET
  2689.  
  2690.  
  2691. ;-------------------------------------------------------------------------------
  2692. READTK:    LD HL,TRACK    ;read track
  2693.     ADD HL,DE
  2694.     LD A,(TRKDAT)    ;get TRKDATA address
  2695.     ADD A,(HL)
  2696.     LD C,A
  2697.     INC HL
  2698.     LD A,(TRKDAT+1)
  2699.     ADC A,(HL)
  2700.     LD B,A
  2701.     PUSH BC
  2702.     LD HL,TRKSTEP
  2703.     ADD HL,DE
  2704.     INC (HL)
  2705.     LD A,(HL)
  2706.     ADD A,C
  2707.     LD C,A
  2708.     ADC A,B
  2709.     SUB C
  2710.     LD B,A
  2711.  
  2712. readt0:    LD A,(BC)
  2713.     CP 0FDH
  2714.     JR C,readt1
  2715.     JR Z,readfade
  2716.     PUSH HL    ;trkstep
  2717.     LD HL,SEQNUM
  2718.     ADD HL,DE
  2719.     LD (HL),A
  2720.     POP HL    ;trkstep
  2721.     INC BC
  2722.     LD A,(BC)
  2723.     DEC A
  2724.     LD (HL),A
  2725.     INC A
  2726.     POP BC
  2727.     RET
  2728.  
  2729. readfade:    INC (HL)
  2730.     INC BC
  2731.     LD A,(BC)
  2732.     LD (FADER),A
  2733. RT30:    INC (HL)
  2734.     INC BC
  2735.     JR readt0
  2736.  
  2737. readt1:    BIT 6,A
  2738.     JR Z,RT80
  2739.     PUSH HL
  2740.  
  2741.     LD HL,LOOPFLAG    ;readl0
  2742.     ADD HL,DE
  2743.     BIT 7,(HL)
  2744.     JR NZ,readl1
  2745.  
  2746.     LD (HL),0FFH
  2747.     AND 03FH
  2748.     INC HL
  2749.     LD (HL),A
  2750.     POP HL
  2751.     INC (HL)
  2752.     LD A,(HL)
  2753.     INC BC
  2754.     PUSH HL
  2755.     LD HL,LOOPMEM
  2756.     ADD HL,DE
  2757.     LD (HL),A
  2758.     POP HL
  2759.     JR readt2
  2760.  
  2761. readl1:    INC HL
  2762.     DEC (HL)
  2763.     JR NZ,readl2
  2764.     DEC HL
  2765.     LD (HL),0
  2766.     POP HL
  2767.     JR RT30
  2768.  
  2769. readl2:    INC HL
  2770.     LD A,(HL)
  2771.     POP HL
  2772.     LD (HL),A
  2773.     POP BC
  2774.     PUSH BC
  2775.     ADD A,C
  2776.     LD C,A
  2777.     ADC A,B
  2778.     SUB C
  2779.     LD B,A
  2780.  
  2781. readt2:    LD A,(BC)
  2782. RT80:    INC (HL)    ;trkstep
  2783.     LD HL,SEQREPEAT
  2784.     ADD HL,DE
  2785.     LD (HL),A    ;store seqrepeat
  2786.  
  2787.     INC BC
  2788.     LD A,(BC)
  2789.     DEC HL
  2790.     LD (HL),A    ;seqnumber
  2791.     POP BC
  2792.     RET
  2793.  
  2794.  
  2795. ;-------------------------------------------------------------------------------
  2796. ;Enter with A = parameter 00 -0Fh
  2797. ;Exit with A = voice data byte required
  2798. ;BC = address of voice data byte
  2799. ;-------------------------------------------------------------------------------
  2800. GETVOICE:    LD HL,VOICEOFFSET
  2801.     ADD HL,DE
  2802.     ADD A,(HL)    ;offset for current voice 0000-01F0
  2803.     inc hl
  2804.     ld b,(hl)    ;save high byte for later
  2805.     LD HL,VCEBANK    ;point to voice bank data
  2806.     ADD A,(HL)
  2807.     LD C,A    ;C=low byte of address required
  2808.     INC HL
  2809.     ld a,b    ;retrieve high byte of voiceoffset
  2810.     ADC A,(HL)
  2811.     LD B,A    ;B= high byte of address required
  2812.     LD A,(BC)    ;A=voice byte required
  2813.     RET
  2814.  
  2815.  
  2816.  
  2817.  
  2818. ;-------------------------------------------------------------------------------
  2819. ;START OF ROM DATA
  2820. ;-------------------------------------------------------------------------------
  2821.  
  2822. ADRTABLE:    DW 61440,61440,30720,15360 ;envelope times
  2823.         DW 10240,7680,6144,5120
  2824.         DW 4096,1661,842,526
  2825.         DW 418,140,84,53
  2826.  
  2827. VIBTB1:        DB 0,1,1,1,1,4,3,2
  2828.         DB 4,3,2,1,3,2,1,3,2,2,1
  2829. VIBTB2:        DB 0,5,4,3,2,5,5,4
  2830.         DB 4,4,3,1,3,2,0,1,1,0,0
  2831. NOTETABLE:    dw 000h,000h,000h,000h,000h,000h    ;C-2 00h (too low)
  2832.         dw 000h,000h,000h,000h,000h,000h
  2833.         dw 000h,000h,000h,000h,000h,000h    ;C-1 0Ch (too low)
  2834.         dw 000h,000h,000h,000h,000h,000h
  2835.         dw 000h,000h,000h,000h,000h,000h    ;C0 18h (too low)
  2836.         dw 000h,000h,000h,000h,000h,000h
  2837.         dw 02Ch,09Ch,107h,16Bh,1C9h,223h    ;C1 24h 65Hz
  2838.         dw 277h,2C7h,312h,358h,39Bh,3DAh
  2839.         dw 416h,44Eh,483h,4B5h,4E5h,511h    ;C2 30h 130Hz
  2840.         dw 53Bh,563h,589h,5ACh,5CEh,5EDh
  2841.         dw 60Bh,627h,642h,65Bh,672h,689h    ;C3 3Ch 262Hz(MID)
  2842.         dw 69Eh,6B2h,6C4h,6D6h,6E7h,6F7h
  2843.         dw 706h,714h,721h,72Dh,739h,744h    ;C4 48h 523Hz
  2844.         dw 74Fh,759h,762h,76Bh,773h,77Bh
  2845.         dw 783h,78Ah,790h,797h,79Dh,7A2h    ;C5 54h 1046Hz
  2846.         dw 7A7h,7ACh,7B1h,7B6h,7BAh,7BEh
  2847.         dw 7C1h,7C5h,7C8h,7CBh,7CEh,7D1h    ;C6 60h 2093Hz
  2848.         dw 7D4h,7D6h,7D9h,7DBh,7DDh,7DFh
  2849.         dw 7E1h,7E2h,7E4h,7E6h,7E7h,7E9h    ;C7 6Ch 4186Hz
  2850.         dw 7EAh,7EBh,7ECh,7EDh,7EEh,7EFh
  2851.         dw 7F0h,7F1h,7F2h,7F3h,7F4h,7F4h    ;C8 78h 8372Hz
  2852.         dw 7F5h,7F6h            ;G8 7Fh 12542Hz
  2853.  
  2854. CODESIZE    equ $-JUMPTABLE
  2855.  
  2856. ;*****************************************************************************
  2857.         ORG 1200h
  2858.  
  2859. GAMEDAT1:    INCLUDE BLANK-GB.SND (BIN)    ;7 WORD VECTOR TABLE @ START
  2860. ;*****************************************************************************
  2861.  
  2862. MUSICEND:
  2863.  
  2864.  
  2865. ;-------------------------------------------------------------------------------
  2866. ;DRIVER RAM VARIABLES
  2867. ;-------------------------------------------------------------------------------
  2868.         ORG    MUSICRAM
  2869.  
  2870. MUSICVAR:
  2871. sfxno        DS    1
  2872. tuneno        DS    1
  2873. STATUS:        DS    1
  2874.  
  2875. ;-----------------------------------------------------------------------------
  2876. SFXCHAN1    DS    1
  2877. PRIORTEST    DS    1
  2878. SFXHOLD        DS    1
  2879. SFXCHOP        DS    1
  2880. CTRLAD        DS    1 ;current waveform for music/effects
  2881. CTRLSR        DS    1
  2882. FREQ        DS    2
  2883. BENDTYPE    DS    1
  2884. BEND        DS    2
  2885. SFXEXTRA:    DS    1
  2886. CNTDOWN:    DS    1
  2887. CNTVAL:        DS    1
  2888. NEWVAL:        DS    1
  2889. NEWVAL2        DS    1
  2890. PRIORITY:    DS    1
  2891. DIRFLAG:    DS    1
  2892.  
  2893. ENAD:        DS    1
  2894. ENSR:        DS    1
  2895. ATKLVL        DS    1 ;08-F8 peak attack level (forced to F8 if effect)
  2896. ATKHOLD:    DS    1
  2897. ENSEQ:        DS    1 ;0=attack/1=decay/2=sustain phase
  2898. ENVAL:        DS    2 ;envelope value (high nibble is current envelope level)
  2899. FQOFF:        DS    1 ;freqoffset: 0 if music/ 8 if effect (00-0F for waver)
  2900.  
  2901. TRACK:        DS    2
  2902. VOICEOFFSET:    DS    2
  2903. TRKSTEP:    DS    1
  2904. LOOPFLAG:    DS    1
  2905. LOOPCNTR:    DS    1
  2906. LOOPMEM:    DS    1
  2907. SEQSTEP:    DS    1
  2908. SEQNUM:        DS    1
  2909. SEQREPEAT:    DS    1
  2910. NOTELENGTH:    DS    1 ;0 at start of each note/increases as DURATION decreases
  2911. DURATION:    DS    1
  2912. NOTECTRL:    DS    1
  2913. NOTEVALUE:    DS    1
  2914. ATTKEND:    DS    1 ;0 at start of each note
  2915. VOICENUM:    DS    1
  2916. GATEMASK:    DS    1
  2917. BENDBYTE:    DS    1
  2918. FREQDIR:    DS    1
  2919. VIBDELAY:    DS    1
  2920. VIBSPEED:    DS    1
  2921. VIBDIR:        DS    1
  2922. VIBSTEP:    DS    1
  2923. VIBLIMIT:    DS    1
  2924. VIBINC:        DS    2
  2925. NOTE:        DS    2
  2926. TIED_NOTE:    DS    1
  2927. SPECIAL:    DS    1
  2928. SPECNTDN:    DS    1
  2929. SPECNTUP:    DS    1
  2930. STEREO        DS    1
  2931. TRANSPOSE    DS    1
  2932. THRESHOLD    DS    1    ;sets length before gate off (init to $FF)
  2933.  
  2934.  
  2935. VCEMUTE:    DS    1
  2936.  
  2937. SDLN        equ    $-SFXCHAN1
  2938.         DS    2*SDLN    ;3 channels for each
  2939.  
  2940. FADER:        DS    1
  2941. VOLUME:        DS    1
  2942. FADECNT:    DS    1
  2943. TEMPOVAL:    DS    1
  2944. TEMPOFLAG:    DS    1
  2945. TEMPOCNTR:    DS    1
  2946. VCETEMP:    DS    1
  2947. ADTEMP:        DS    1
  2948. SRTEMP:        DS    1
  2949. PKTEMP        DS    1
  2950. STEREOTEMP    DS    1
  2951. GLOBOFFSET    DS    1
  2952. CLOCK_L        DS    1
  2953. CLOCK_H        DS    1
  2954.  
  2955.  
  2956. NCHAN:        DS    1 ;current noise channel 0,1,2 (FF=no noise)
  2957. CURCHAN:    DS    1 ;current channel
  2958. SEED:        DS    1 ;for random number
  2959. ENC3:        DS    1 ;envelope value for channel 3
  2960. MAXVOL:        DS    1 ;maximum envelope attack value
  2961. EFFSND        DS    1 ;FF=effect in current channel
  2962.  
  2963.  
  2964. FXBANK:        DS    2 ;address of 1st byte of effects
  2965. FXTABLE:    DS    2 ;address of 1st byte of call table
  2966. VCEBANK:    DS    2
  2967. SEQOFF:        DS    2
  2968. SEQDATA:    DS    2
  2969. TRKOFF:        DS    2
  2970. TRKDAT:        DS    2
  2971.  
  2972. VARSIZE        equ    $-MUSICVAR
  2973.  
  2974.  
  2975.  
  2976.  
  2977. ;-------------------------------------------------------------------------------
  2978. ;DEMO RAM VARIABLES
  2979. ;-------------------------------------------------------------------------------
  2980.         IF DEMO
  2981. CNT1        DS    1
  2982. TRG1        DS    1
  2983. editnum        DS    1
  2984. selectflag    DS    1
  2985. vbi_flag    DS    1
  2986. PCnewdata    ds    1
  2987. PCbuffer    ds    24    ;6 + (6 * 3)
  2988.         ENDIF
  2989.  
  2990.         END
  2991.