home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 4: Demo 1 / almathera_demo1.bin / sourcecode / noisetracker1.1 / noise.s < prev    next >
Text File  |  1995-03-17  |  146KB  |  6,709 lines

  1. *--------------------------------------------------------------*
  2. *                                *
  3. *        NOISETRACKER 1.1 SOURCE CODE            *
  4. *                                *
  5. *          Program (C)1989 Mahoney & Kaktus            *
  6. *                                *
  7. *      Disassembled and Commented by JMP in Nov 89        *
  8. *                                *
  9. *    A program worth using is a program worth documenting !    *
  10. *                                *
  11. *---------------------------------------------------------------*
  12.  
  13. *------------------------------
  14. * JMP'S ALTERATIONS AND EXTENSIONS
  15.  
  16. * 1) Noisetracker has a bug in the installation of the keyboard interrupt.
  17. *    The interrupt handler is patched into the input-device vector of the
  18. *    cia interrupt structure rather than the irq-structure vector.
  19. *    These vectors have the same value on an unexpanded system but with
  20. *    a A590 hard disk attached the input-device vector is re-directed,
  21. *    hence Noisetracker corrupts the hard disk driver and crashes as soon
  22. *    as the first disk access occurs !
  23.  
  24. A590_version equ 1    0=original/1=hard disk compatibility
  25.  
  26. * 2) This patch alters the 'select drive' request when loading a sample so
  27. *    that clicking DF1: selects ST-01: instead, which is my hard disk
  28. *    samples directory.
  29.  
  30. ST01_version equ 1    0=original/1=use ST-01: instead of DF1:
  31.  
  32. *------------------------------
  33. * MACROS
  34.  
  35. align    macro
  36.     cnop    0,4    MUST ensure DOS info blocks are divisible by 4
  37.     endm
  38.  
  39. *------------------------------
  40. * EQUATES
  41.  
  42. * hardware
  43.  
  44. _custom    EQU    $DFF000
  45.  
  46. vposr    EQU    $04
  47. joy0dat    EQU    $0A
  48. adkconr    EQU    $10
  49. potinp    EQU    $16
  50. intenar    EQU    $1C
  51. intreqr    EQU    $1E
  52. cop1lch    EQU    $80
  53. copjmp1    EQU    $88
  54. diwstrt EQU    $8E
  55. diwstop EQU    $90
  56. ddfstrt EQU    $92
  57. ddfstop EQU    $94
  58. dmacon    EQU    $96
  59. aud0    EQU    $A0
  60. aud1    EQU    $B0
  61. aud2    EQU    $C0
  62. aud3    EQU    $D0
  63. bpl1pth    EQU    $E0
  64. bpl1ptl    EQU    $E2
  65. bpl2pth    EQU    $E4
  66. bpl2ptl    EQU    $E6
  67. bpl3pth    EQU    $E8
  68. bpl3ptl    EQU    $EA
  69. bplcon0    EQU    $100
  70. bplcon1    EQU    $102
  71. bplcon2    EQU    $104
  72. bpl1mod    EQU    $108
  73. bpl2mod    EQU    $10A
  74. spr0pth    EQU    $120
  75. spr0ptl    EQU    $122
  76. spr1pth    EQU    $124
  77. spr1ptl    EQU    $126
  78. spr2pth    EQU    $128
  79. spr2ptl    EQU    $12A
  80. spr3pth    EQU    $12C
  81. spr3ptl    EQU    $12E
  82. spr4pth    EQU    $130
  83. spr4ptl    EQU    $132
  84. spr5pth    EQU    $134
  85. spr5ptl    EQU    $136
  86. spr6pth    EQU    $138
  87. spr6ptl    EQU    $13A
  88. spr7pth    EQU    $13C
  89. spr7ptl    EQU    $13E
  90. color0    EQU    $180
  91.  
  92. ac_ptr    EQU    0
  93. ac_len    EQU    4
  94. ac_per    EQU    6
  95. ac_vol    EQU    8
  96. ac_dat    EQU    10
  97.  
  98. * memory
  99.  
  100. MEMF_CLEAR    EQU    $10000
  101. MEMF_FAST    EQU    4
  102. MEMF_CHIP    EQU    2
  103.  
  104. * exec library
  105.  
  106. _LVOExitIntr    EQU    -36
  107. _LVOForbid    EQU    -132
  108. _LVOOldOpenLibrary EQU    -408
  109. _LVOWaitPort    EQU    -384
  110. _LVOGetMsg    EQU    -372
  111. _LVOFreeMem    EQU    -210
  112. _LVOCloseLibrary EQU    -414
  113. _LVOAvailMem    EQU    -216
  114. _LVOAllocMem    EQU    -198
  115. _LVOReplyMsg    EQU    -378
  116. _LVOFindTask    EQU    -294
  117.  
  118. * vectors
  119.  
  120. tv_Lev2IntVect    EQU    $68
  121. tv_Lev3IntVect    EQU    $6C
  122.  
  123. * dos library
  124.  
  125. _LVOOpen    EQU    -30
  126. _LVOClose    EQU    -36
  127. _LVORead    EQU    -42
  128. _LVOWrite    EQU    -48
  129. _LVOSeek    EQU    -66
  130. _LVODeleteFile    EQU    -72
  131. _LVOLock    EQU    -84
  132. _LVOUnLock    EQU    -90
  133. _LVOExamine    EQU    -102
  134. _LVOExNext    EQU    -108
  135.  
  136. * gfx library
  137.  
  138. gb_copinit    EQU    $26
  139.  
  140. * intuition library
  141.  
  142. _LVOAutoRequest    EQU    -348
  143.  
  144. * process structure
  145.  
  146. pr_CLI    EQU    $AC
  147. pr_MsgPort EQU    $5C
  148.  
  149. *------------------------------
  150. * SONG/MODULE format
  151. *
  152. *    offset    size    meaning
  153. *
  154. *    0    20    song name (ascii padded with $00)
  155. *    $14    31*30    info for 31 instruments
  156. *            30 bytes each:
  157. *                0    22 character name padded with $00
  158. *                22 w    length of sample in words
  159. *                24 w    volume 0..64
  160. *                26 w    repeat offset
  161. *                28 w    repeat length in words (1=single)
  162. *    $03B6    1    no. of parts
  163. *    $03B7    1    restart = 120
  164. *    $03B8    128    pattern no. for each part (up to 128)
  165. *    $0438    4    identifier = 'M.K.'
  166. *    $043C    n*1024    pattern definitions
  167. *            1024 bytes each consisting of 64 16-byte rows
  168. *            each row contains 4 longs (1 per voice):
  169. *                $spppsfnn
  170. *                where:    ppp = note (period value)
  171. *                    ss  = instrument no. (0 or $01..$1F)
  172. *                    f   = special function (0..$F)
  173. *                    nn  = parameter for function
  174. *
  175. *    followed by sample data (contiguous)
  176.  
  177. sf_instr equ $14        song file offsets
  178. sf_length equ $3B6
  179. sf_restart equ $3B7
  180. sf_parts equ $3B8
  181. sf_ident equ $438
  182. sf_patterns equ $43C
  183. sf_size    equ sf_patterns+68*1024
  184.  
  185. in_length equ 22        instrument offsets
  186. in_volume equ 24
  187. in_repeat equ 26
  188. in_replen equ 28
  189. in_size equ 30
  190.  
  191. *------------------------------
  192. * CODE
  193.  
  194.     SECTION noisetracker1.1,CODE_C
  195.  
  196.     BRA.S    start
  197.  
  198.     dc.b    ' Noisetracker V1.1 by Mahoney & Kaktus. '
  199.  
  200. start    CLR.L    _WBenchMsg
  201.     MOVE.L    4.w,a6            start from cli/workbench
  202.     SUB.L    A1,A1
  203.     JSR    _LVOFindTask(A6)    get self
  204.     MOVE.L    D0,A4
  205.     TST.L    pr_CLI(A4)
  206.     BEQ.S    wb_start
  207.     BRA    cli_start
  208. wb_start
  209.     LEA    pr_MsgPort(A4),A0    if started from workbench
  210.     MOVE.L    4.w,a6
  211.     JSR    _LVOWaitPort(A6)        get message
  212.     LEA    pr_MsgPort(A4),A0
  213.     JSR    _LVOGetMsg(A6)
  214.     MOVE.L    D0,_WBenchMsg
  215. cli_start
  216.     BSR    main            call main program
  217.     MOVE.L    D0,-(SP)
  218.     TST.L    _WBenchMsg        if started from workbench
  219.     BEQ.S    exit
  220.     MOVE.L    4.w,a6
  221.     JSR    _LVOForbid(A6)            reply to message
  222.     MOVE.L    _WBenchMsg,A1
  223.     JSR    _LVOReplyMsg(A6)
  224. exit    MOVE.L    (SP)+,D0        exit to cli/workbench
  225.     RTS
  226.  
  227. * main program
  228.  
  229. main    MOVE.L    SP,initialSP        save stack
  230.     CLR.L    0.w            no break in
  231.     BSET    #1,$BFE001        led off
  232.     BSR    save_irq2_3        setup irqs/memory/screen
  233.     BSR    setup
  234.     BSR    backup_edit_icons    make copy of edit functions
  235.     BSR    use_normal_colours
  236.     MOVE.L    clist_ptr,_custom+cop1lch
  237.  
  238.     TST.L    alloc7k_ptr    ]    UNUSED
  239.     BEQ.S    .no7k        ]
  240.     MOVE.L    4.w,a6        ]
  241.     MOVE.L    #7000,D0    ]
  242.     MOVE.L    alloc7k_ptr,A1    ]
  243.     JSR    _LVOFreeMem(A6)    ]
  244. .no7k
  245.  
  246.     BSR    set_play_scroller    draw pattern scroller
  247.     BSR    arrow_is_grey
  248.     BSR    refresh_on_off        refresh channel on/off icons
  249.     BSR    print_allright
  250.     BSR    plst_scan_search    flag plst files in current disks
  251.  
  252. main_loop
  253.     BSR    check_escape        escape quits diskops/plst
  254.     BSR    check_capslock        capslock changes colour scheme
  255.     BSR    refresh_memory_usage
  256.     CMP.W    #1,fscroll_pending    diskop file list scrolling
  257.     BNE.S    .dscr2
  258.     BSR    scroll_up_files
  259. .dscr2    CMP.W    #2,fscroll_pending
  260.     BNE.S    .pscr
  261.     BSR    scroll_down_files
  262. .pscr    MOVE.W    pscroll_pending,D0    plst file list scrolling
  263.     BEQ.S    .pscr3
  264.     MOVE.W    #1,alter_dir
  265.     CMPI.W    #1,D0
  266.     BNE.S    .pscr2
  267.     MOVE.W    #$FFFF,alter_dir
  268. .pscr2    BSR    scroll_plst
  269.     CLR.W    pscroll_pending
  270. .pscr3    BSR    check_play_edit_keys    check key functions
  271.     BSR    check_instr_keys
  272.     BSR    check_transpose_keys
  273.     BSR    check_pat_or_pos
  274.     BSR    check_edit_pattern
  275.     BSR    check_octave_keys
  276.     BSR    check_cut_paste
  277.     BSR    check_f6_to_f10
  278.     BSR    check_help
  279.     CMP.L    #'patp',play_mode    if play mode then
  280.     BNE.S    .noplay
  281.     BSR    refresh_song_position        update position
  282.     TST.W    new_pat_flag            if new pattern then
  283.     BEQ.S    .noplay
  284.     MOVE.L    new_pat_no,pattern_no            update pattern
  285.     BSR    refresh_pattern_display
  286. .noplay    BTST    #6,$BFE001        loop until left button pressed
  287.     BNE    main_loop
  288.     TST.W    mode            if mode=entry then
  289.     BNE.S    .not1st
  290.     BSR    goto_editor_mode        goto editor
  291. .not1st    BRA    check_arrow_and_cursor    check arrow/cursor functions
  292.  
  293.  
  294.  
  295. check_escape
  296.     CMP.B    #$45,key_code        if key = ESC then
  297.     BNE    return
  298.     CLR.B    key_code            clear key
  299.     MOVE.W    mode,D0
  300.     CMPI.W    #3,D0                if mode=diskops then
  301.     BEQ    goto_editor_mode            goto editor
  302.     CMPI.W    #4,D0                if mode= then
  303.     BEQ    cancel_plst_mode
  304.     RTS                else ignore
  305.  
  306. check_capslock
  307.     MOVE.B    key_code,D0        if no key then return
  308.     BEQ    return
  309.     CMPI.B    #$62,D0
  310.     BEQ.S    use_other_colours
  311.     CMPI.B    #$E2,D0            if caps lock then colour set 2
  312.     BNE    return
  313. use_normal_colours
  314.     MOVE.L    #chaneq_colours2,chaneq_colours_ptr
  315.     MOVE.L    #spect_colours2,spect_colours_ptr
  316.     MOVE.W    #$444,cl_col1+2        set colours 1..7
  317.     MOVE.W    #$777,cl_col1+6
  318.     MOVE.W    #$AAA,cl_col1+10
  319.     MOVE.W    #$CCC,cl_col1+14
  320.     MOVE.W    #$700,cl_col1+18
  321.     MOVE.W    #$400,cl_col1+22
  322.     MOVE.W    #$A00,cl_col1+26
  323.     MOVE.W    #$04D,cl_col4b            colour 4 in lower half
  324.     CLR.B    key_code
  325.     BSR    set_chaneq_copper
  326.     BRA    set_spect_copper
  327. use_other_colours
  328.     MOVE.L    #chaneq_colours1,chaneq_colours_ptr    else colour set 1
  329.     MOVE.L    #spect_colours1,spect_colours_ptr
  330.     MOVE.W    #$733,cl_col1+2        set colours 1..7
  331.     MOVE.W    #$A66,cl_col1+6
  332.     MOVE.W    #$C99,cl_col1+10
  333.     MOVE.W    #$AFB,cl_col1+14
  334.     MOVE.W    #$900,cl_col1+18
  335.     MOVE.W    #$600,cl_col1+22
  336.     MOVE.W    #$E00,cl_col1+26
  337.     MOVE.W    #$990,cl_col4b            colour 4 in lower half
  338.     CLR.B    key_code
  339.     BSR    set_chaneq_copper
  340.     BRA    set_spect_copper
  341.  
  342. * exit    d0=-1 cancel
  343. *        0  DF0:
  344. *        1  DF1:
  345.  
  346. check_which_drive
  347.     BSR    wait_no_buttons
  348.     BSR    arrow_is_grey
  349.     BSR    wipe_spectrum
  350.     BSR.S    toggle_drive_icon    display drive icon (df0/df1)
  351.     BSR    wait_no_buttons
  352. .wait    BTST    #6,$BFE001        wait for mouse
  353.     BNE.S    .wait
  354.     MOVEM.W    mouse_x,D0/D1        check mouse coords for df0/df1/cancel
  355.     CMPI.W    #$F0,D0
  356.     BLT.S    .cancel
  357.     CMPI.W    #$137,D0
  358.     BGT.S    .cancel
  359.     CMPI.W    #2,D1
  360.     BLT.S    .cancel
  361.     CMPI.W    #$23,D1
  362.     BGT.S    .cancel
  363.     CMPI.W    #$15,D1
  364.     BLT.S    .wait
  365.     CMPI.W    #$1F,D1
  366.     BGT.S    .wait
  367.     CMPI.W    #$F5,D0
  368.     BLT.S    .wait
  369.     CMPI.W    #$113,D0
  370.     BLT.S    .df0
  371.     CMPI.W    #$117,D0
  372.     BLT.S    .wait
  373.     CMPI.W    #$132,D0
  374.     BGT.S    .wait
  375.     BSR.S    toggle_drive_icon
  376.     MOVEQ    #1,D0
  377.     RTS
  378. .df0    BSR.S    toggle_drive_icon
  379.     MOVEQ    #0,D0
  380.     RTS
  381. .cancel    BSR.S    toggle_drive_icon
  382.     MOVEQ    #-1,D0
  383.     RTS
  384.  
  385. toggle_drive_icon
  386.     LEA    main_screen+2*40+30,A0
  387.     LEA    drive_icon,A1
  388.     MOVEQ    #34-1,D0
  389. .row    MOVEQ    #9-1,D1
  390. .column    MOVE.B    10240(A0),D2
  391.     MOVE.B    34*10(A1),10240(A0)
  392.     MOVE.B    D2,34*10(A1)
  393.     MOVE.B    (A0),D2
  394.     MOVE.B    (A1),(A0)+
  395.     MOVE.B    D2,(A1)+
  396.     DBRA    D1,.column
  397.     ADD.L    #40-9,A0
  398.     ADDQ.L    #1,A1
  399.     DBRA    D0,.row
  400.     MOVE.W    #20480,D7
  401. .wait    DBRA    D7,.wait
  402.     RTS
  403.  
  404. fn_load_sample_abort
  405.     MOVE.W    #20480,D7
  406. .wait    DBRA    D7,.wait
  407.     BRA    restore_arrow_colours
  408.  
  409. * LOAD SAMPLE
  410.  
  411. fn_load_sample
  412.     BSR    save_arrow_colours
  413.     BSR    wait_no_buttons
  414.     CLR.B    key_code
  415.     CLR.W    disk_fn
  416.     BSR    wipe_spectrum
  417.     BSR    check_which_drive    drive 0/1
  418.     TST.L    D0
  419.     BMI.S    fn_load_sample_abort    skip if aborted
  420.  
  421.     ifeq    ST01_version
  422.     ADD.B    #'0',D0
  423.     MOVE.B    D0,DF_msg+2        patch drive no.
  424.     MOVE.W    #2,ffi_type
  425.     LEA    DF_msg(PC),A4
  426.     elseif
  427.     LEA    DF_msg(PC),A4        choose
  428.     MOVE.W    #2,ffi_type        drive DF0:
  429.     TST.L    D0
  430.     BEQ.S    .df0
  431.     LEA    DF_msg1(PC),A4        drive ST-01:
  432.     MOVE.W    #2,ffi_type
  433. .df0
  434.     endc
  435.  
  436.     LEA    dir_buffer(PC),A5    find disk
  437.     BSR    find_file_info
  438.     BEQ.S    .ok
  439.     MOVE.W    FileInfoBlock+8,D0    error if not an ST-.. disk
  440.     MOVE.W    #'ST',D1
  441.     AND.W    #$1F1F,D0
  442.     AND.W    #$1F1F,D1
  443.     CMP.W    D0,D1
  444.     BNE.S    .error
  445.     LEA    sample_filename,A1    clear name buffer
  446.     MOVEQ    #16-1,D7
  447. .wipe    CLR.B    (A1)+
  448.     DBRA    D7,.wipe
  449.     LEA    FileInfoBlock+8,A0    get disk name
  450.     LEA    sample_filename,A1
  451.     MOVEQ    #16-1,D7
  452. .copy    MOVE.B    (A0)+,D0
  453.     BEQ.S    .copied
  454.     MOVE.B    D0,(A1)+
  455.     DBRA    D7,.copy
  456. .copied    MOVE.B    #':',(A1)+        add :
  457.     BSR    cancel_directory
  458.     BSR    read_directory
  459.     BEQ.S    .ok
  460. .error    BSR    cancel_directory
  461.     BRA    arrow_flash_red
  462. .ok    MOVE.W    diskop_cursor,D0
  463.     MOVE.W    #5,disk_fn
  464.     BSR    refresh_diskop_filelist
  465.     BRA    arrow_is_grey
  466.  
  467.     ifeq    ST01_version 
  468. DF_msg    dc.b    'DF1:',0
  469.     even
  470.     elseif
  471. DF_msg    dc.b    'DF0:',0
  472.     even
  473. DF_msg1    dc.b    'ST-01:',0
  474.     even
  475.     endc
  476.  
  477. load_sample
  478.     BSR    save_arrow_colours
  479.     TST.W    current_instr
  480.     BEQ.S    .skip
  481.     CLR.B    key_code
  482.     MOVE.W    current_instr,D0
  483.     MULU    #in_size,D0
  484.     MOVE.L    song_file_ptr,A1
  485.     LEA    sf_instr-in_size(A1,D0.W),A1
  486.     MOVE.L    A1,A2            wipe instrument in song file
  487.     MOVEQ    #in_size-1,D0
  488. .wipe    CLR.B    (A1)+
  489.     DBRA    D0,.wipe
  490.     MOVE.L    A2,A1
  491.     MOVEQ    #22-1,D1        ** BUG ** used d0 for loop counter !!
  492.     LEA    sample_filename,A0
  493. .disk    MOVE.B    (A0)+,D0        copy disk name
  494.     BEQ.S    .disk2
  495.     MOVE.B    D0,(A1)+        ** loop counter goes splat....
  496.     DBRA    D1,.disk
  497. .disk2    MOVE.L    dir_entry_ptr,A0        copy file name
  498.     MOVE.L    A0,A3
  499. .file    MOVE.B    (A0)+,D0
  500.     BEQ.S    .file2
  501.     MOVE.B    D0,(A1)+
  502.     DBRA    D0,.file
  503. .file2    MOVE.W    $1A(A3),D0
  504.     LSR.W    #1,D0
  505.     MOVE.W    D0,in_length(A2)        sample length (in words)
  506.     MOVE.W    #64,in_volume(A2)        volume=64
  507.     CLR.W    in_repeat(A2)            repeat=0
  508.     MOVE.W    #1,in_replen(A2)        replen=1
  509.     BSR    load_sample_file
  510. .skip    BSR    refresh_instr_parameters
  511.     BRA    restore_arrow_colours
  512.  
  513. check_transpose_keys
  514.     MOVEQ    #2,D4
  515.     CMP.B    #$42,key_code    if key = TAB then d4=2
  516.     BEQ.S    .trans
  517.     MOVEQ    #-2,D4
  518.     CMP.B    #$63,key_code    if key = CTRL then d4=-2 else return
  519.     BNE    return
  520. .trans    TST.W    key_lshift    skip if neither SHIFT nor ALT
  521.     BNE.S    .trans0
  522.     TST.W    key_lalt
  523.     BEQ    return
  524.     MOVEQ    #0,D0        if ALT then transpose each voice
  525.     MOVE.L    D0,A0
  526.     BSR.S    transpose
  527.     MOVEQ    #4,D0
  528.     MOVE.L    D0,A0
  529.     BSR.S    transpose
  530.     MOVEQ    #8,D0
  531.     MOVE.L    D0,A0
  532.     BSR.S    transpose
  533.     MOVEQ    #12,D0
  534.     MOVE.L    D0,A0
  535.     BSR.S    transpose
  536.     BRA    refresh_pattern_display
  537. .trans0    CMP.W    #18,edit_cursor_x    if SHIFT then transpose current voice
  538.     BNE.S    .trans1
  539.     MOVEQ    #12,D0
  540.     MOVE.L    D0,A0
  541.     BSR.S    transpose
  542.     BRA    refresh_pattern_display
  543. .trans1    CMP.W    #12,edit_cursor_x
  544.     BNE.S    .trans2
  545.     MOVEQ    #8,D0
  546.     MOVE.L    D0,A0
  547.     BSR.S    transpose
  548.     BRA    refresh_pattern_display
  549. .trans2    CMP.W    #6,edit_cursor_x
  550.     BNE.S    .trans3
  551.     MOVEQ    #4,D0
  552.     MOVE.L    D0,A0
  553.     BSR.S    transpose
  554.     BRA    refresh_pattern_display
  555. .trans3    TST.W    edit_cursor_x
  556.     BNE    return
  557.     MOVEQ    #0,D0
  558.     MOVE.L    D0,A0
  559.     BSR.S    transpose
  560.     BRA    refresh_pattern_display
  561.  
  562. * entry    d4=tranpose offset -2/+2
  563. *    a0=voice offset 0/4/8/12
  564.  
  565. transpose
  566.     CLR.B    key_code        clear key
  567.     ADD.L    song_file_ptr,A0    a0=song+offset+1024*pattern+voice
  568.     ADD.L    #sf_patterns,A0
  569.     MOVE.L    pattern_no,D0
  570.     LSL.L    #8,D0
  571.     LSL.L    #2,D0
  572.     ADD.L    D0,A0
  573.     MOVEQ    #64-1,D7        d7=length of pattern-1
  574.     MOVE.W    current_instr,D6    d6=8*(instrument div 16)
  575.     MOVE.W    D6,D5
  576.     AND.W    #$10,D6
  577.     ASL.W    #3,D6
  578.     AND.W    #15,D5            d5=16*(instrument mod 16)
  579.     ASL.W    #4,D5
  580.     LEA    oct1_2_3_periods,A1    a1=periods
  581. .loop    MOVE.B    2(A0),D0        for each note
  582.     AND.B    #$F0,D0            skip if wrong instrument
  583.     CMP.B    D0,D5
  584.     BNE.S    .next
  585.     MOVE.B    (A0),D0
  586.     AND.B    #$80,D0
  587.     CMP.B    D6,D0
  588.     BNE.S    .next
  589.     MOVEQ    #0,D3            skip if rest
  590.     MOVE.W    (A0),D2
  591.     AND.W    #$FFF,D2
  592.     BEQ.S    .next
  593.     MOVEQ    #$26,D1            search period table
  594. .search    CMP.W    0(A1,D3.W),D2
  595.     BEQ.S    .found
  596.     ADDQ.W    #2,D3
  597.     DBRA    D1,.search
  598.     BRA.S    .next
  599. .found    AND.W    #$F000,(A0)        skip if period+offset < 0
  600.     ADD.L    D4,D3
  601.     BMI.S    .next
  602.     MOVE.W    0(A1,D3.W),D3        store new period
  603.     OR.W    D3,(A0)
  604. .next    ADD.L    #16,A0            next note
  605.     DBRA    D7,.loop
  606.     RTS
  607.  
  608. input_module_dir
  609.     MOVE.L    cptr_arrow_col,A0    if arrow<>cyan then save colours
  610.     CMP.W    #$0AA,2(A0)
  611.     BEQ.S    .cyan
  612.     BSR    save_arrow_colours
  613. .cyan    BSR    arrow_is_magenta
  614.     CLR.L    edit_mode        cancel edit mode
  615.     LEA    modules_dir,A6
  616.     BSR    print_modules_dir    edit string
  617.     MOVE.W    #$C4,input_cursor_x
  618.     MOVE.W    #$2A,input_cursor_y
  619.     BSR    set_input_cursor
  620.     MOVE.L    A6,input_end_addr
  621.     ADD.L    #15,input_end_addr
  622.     BSR    input_routine
  623.     CLR.L    input_end_addr
  624.     CLR.W    disk_fn
  625.     BSR    wipe_spectrum
  626.     BRA    restore_arrow_colours
  627.  
  628. check_instr_keys
  629.     MOVE.B    key_code,D0        if no key then return
  630.     BEQ    return
  631.     CMPI.B    #$43,D0            if key = ENTER then
  632.     BNE.S    .tst0
  633.     MOVE.W    #16,current_instr            instrument 16
  634.     BSR    refresh_instr_parameters
  635.     CLR.B    key_code
  636.     RTS
  637. .tst0    CMPI.B    #$F,D0            if key = 0 (pad) then
  638.     BNE.S    .tstall
  639.     CLR.W    current_instr            instrument 0
  640.     BSR    refresh_instr_parameters
  641.     CLR.B    key_code
  642.     RTS
  643. .tstall    LEA    .pad_keys,A0        else scan pad
  644.     MOVEQ    #0,D1
  645.     MOVEQ    #16-1,D7
  646. .scan    CMP.B    0(A0,D1.W),D0
  647.     BEQ.S    .found
  648.     ADDQ.W    #1,D1
  649.     DBRA    D7,.scan
  650.     RTS
  651. .found    TST.W    key_enter        if ENTER pressed then
  652.     BEQ.S    .noent
  653.     ADD.W    #$10,D1                plus 16
  654. .noent    MOVE.W    D1,current_instr        set instrument number
  655.     BSR    refresh_instr_parameters
  656.     CLR.B    key_code
  657.     RTS
  658.  
  659. .pad_keys
  660.     dc.b    0
  661.     dc.b    $5A,$5B,$5C,$5D
  662.     dc.b    $3D,$3E,$3F,$4A
  663.     dc.b    $2D,$2E,$2F,$5E
  664.     dc.b    $1D,$1E,$1F
  665.  
  666. check_play_edit_keys
  667.     MOVE.B    key_code,D0        if key = SPACE then
  668.     CMPI.B    #$40,D0
  669.     BNE.S    .amiga
  670.     CLR.B    key_code            clear key
  671.     TST.L    edit_mode
  672.     BNE    fn_stop                if edit or play mode then
  673.     TST.L    play_mode                stop
  674.     BNE    fn_stop
  675.     CMP.W    #3,mode                if mode=diskops then
  676.     BEQ    fn_stop                stop
  677.     BSR    fn_edit            else mode=edit
  678.     RTS
  679. .amiga    CMPI.B    #$67,D0            if key = RIGHT AMIGA then
  680.     BNE.S    .alt
  681. .plypat    BSR    fn_play_pattern            play pattern
  682.     CLR.B    key_code            clear key
  683.     RTS
  684. .alt    CMPI.B    #$65,D0            if key = RIGHT ALT then
  685.     BNE.S    .shift
  686.     BSR    fn_play_song            play song
  687.     CLR.B    key_code            clear key
  688.     RTS
  689. .shift    CMPI.B    #$61,D0            if key = RIGHT SHIFT then
  690.     BNE.S    .skip
  691.     CMP.W    #3,mode            if mode=diskops then
  692.     BEQ    .plypat                play pattern
  693.     BSR    fn_record            else record
  694.     CLR.B    key_code            clear key
  695.     RTS
  696. .skip    RTS
  697.  
  698. refresh_memory_usage
  699.     TST.W    memory_flag
  700.     BEQ    return
  701.     CLR.W    memory_flag
  702.     BSR.S    refresh_song_size
  703.     MOVE.L    4.w,a6
  704.     MOVE.L    #MEMF_CHIP!MEMF_CLEAR,D1    get available chip memory
  705.     JSR    _LVOAvailMem(A6)
  706.     CMP.L    memory_free,D0            if same size then skip
  707.     BEQ.S    return
  708.     MOVE.L    D0,memory_free            save size
  709.     MOVE.L    D0,D6
  710.     MOVE.L    #131*40+34,char_offset        print 5-digit hex
  711.     SWAP    D0
  712.     AND.W    #15,D0
  713.     ASL.W    #1,D0
  714.     LEA    hex2ascii+1,A0
  715.     MOVE.B    0(A0,D0.W),word_to_print
  716.     CLR.B    word_to_print+1
  717.     MOVE.L    #word_to_print,string_addr
  718.     MOVE.L    #1,string_size
  719.     BSR    print_string
  720.     MOVE.W    D6,word_to_print
  721.     BSR    print_hex4
  722. return    RTS
  723.  
  724. refresh_song_size
  725.     MOVE.L    song_file_ptr,A0
  726.     ADD.L    #sf_instr+in_length,A0
  727.     MOVEQ    #31-1,D7        sum sample sizes
  728.     MOVEQ    #0,D0
  729. .sample    MOVEQ    #0,D1
  730.     MOVE.W    (A0),D1
  731.     ASL.W    #1,D1
  732.     ADD.L    D1,D0
  733.     ADD.L    #in_size,A0
  734.     DBRA    D7,.sample
  735.     ADD.L    #sf_patterns,D0
  736.     MOVE.L    song_file_ptr,A0    +pattern size
  737.     MOVEQ    #128-1,D7
  738.     ADD.L    #sf_parts,A0
  739.     MOVEQ    #0,D6
  740. .patts    MOVE.B    (A0)+,D5        (find largest pattern no)
  741.     CMP.B    D5,D6
  742.     BGT.S    .next
  743.     MOVE.B    D5,D6
  744. .next    DBRA    D7,.patts
  745.     ADDQ.W    #1,D6
  746.     ASL.L    #8,D6            *1024
  747.     ASL.L    #2,D6
  748.     ADD.L    D6,D0
  749.     CMP.L    memory_used,D0            update song size
  750.     BEQ.S    return
  751.     MOVE.L    D0,memory_used            print if not same
  752.     MOVE.L    D0,D6
  753.     MOVE.L    #131*40+28,char_offset
  754.     SWAP    D0
  755.     AND.W    #15,D0
  756.     ASL.W    #1,D0
  757.     LEA    hex2ascii+1,A0            5-digit hex
  758.     MOVE.B    0(A0,D0.W),word_to_print
  759.     CLR.B    word_to_print+1
  760.     MOVE.L    #word_to_print,string_addr
  761.     MOVE.L    #1,string_size
  762.     BSR    print_string
  763.     MOVE.W    D6,word_to_print
  764.     BSR    print_hex4
  765.     RTS
  766.  
  767. save_irq2_3
  768.     MOVE.L    (tv_Lev3IntVect).w,old_irq3_vect    save level 3 vector
  769.     MOVE.L    4.w,a6
  770.     MOVE.L    $78(A6),A0
  771.  
  772.     ifeq    A590_version
  773.     MOVE.L    (A0),A0        old version only valid if no expansion
  774.     elseif
  775.     MOVE.L    8(A0),A0    jmp's alteration
  776.     endc
  777.  
  778.     MOVE.L    14(A0),A0
  779.     ADD.L    #$68,A0
  780.     MOVE.L    (A0),old_irq2_patch
  781.     MOVE.L    #keyboard_irq,(A0)
  782.     MOVE.L    A0,old_irq2_addr
  783.     RTS
  784.  
  785. backup_edit_icons
  786.     MOVE.L    #9800,D0
  787.     MOVE.L    #MEMF_CLEAR,D1
  788.     JSR    _LVOAllocMem(A6)    allocate 9800 bytes
  789.     MOVE.L    D0,dir_buffer
  790.     LEA    main_screen+40+15,A0    save top_right of screen
  791.     LEA    edit_icons_copy,A1    to restore after diskops/plst
  792.     MOVEQ    #44-1,D0
  793. .row    MOVEQ    #25-1,D1
  794. .column    MOVE.B    (A0)+,(A1)+
  795.     MOVE.B    10240-1(A0),1100-1(A1)
  796.     DBRA    D1,.column
  797.     ADD.L    #40-25,A0
  798.     DBRA    D0,.row
  799.     RTS
  800.  
  801. restore_and_exit
  802.     MOVE.L    initialSP,SP            restore SP
  803.     MOVE.L    copper_init,_custom+cop1lch    restore copper list
  804.     CLR.W    _custom+copjmp1
  805.     MOVE.L    4.w,a6
  806.     MOVE.L    GFXbase,A1
  807.     JSR    _LVOCloseLibrary(A6)
  808.     MOVE.L    INTbase,A1
  809.     MOVE.L    request_patch+2,_LVOAutoRequest+2(A1)
  810.     JSR    _LVOCloseLibrary(A6)
  811.     MOVE.L    screen_ptr,A1            free screen memory
  812.     MOVE.L    #27760,D0
  813.     JSR    _LVOFreeMem(A6)
  814.     MOVE.L    DOSbase,A1
  815.     JSR    _LVOCloseLibrary(A6)
  816.     MOVE.L    song_file_ptr,A1
  817.     MOVE.L    #sf_size,D0
  818.     JSR    _LVOFreeMem(A6)
  819.     MOVE.L    dir_buffer,A1
  820.     MOVE.L    #9800,D0
  821.     JSR    _LVOFreeMem(A6)
  822.     BSR    free_instr_memory
  823.     TST.L    plst_ptr
  824.     BEQ.S    .noplst
  825.     MOVE.L    plst_ptr,A1
  826.     MOVE.L    plst_size,D0
  827.     JSR    _LVOFreeMem(A6)
  828. .noplst    MOVE.L    old_irq3_vect,(tv_Lev3IntVect).w    restore vectors
  829.     MOVE.W    #15,_custom+dmacon        cancel audio dma
  830.     MOVE.L    old_irq2_addr,A0
  831.     MOVE.L    old_irq2_patch,(A0)
  832.     BCLR    #1,$BFE001            restore power led
  833.     MOVEQ    #0,D0                ok
  834.     RTS
  835.  
  836. goto_editor_mode
  837.     MOVE.L    cptr_arrow_col,A0    if arrow=cyan then
  838.     CMP.W    #$0AA,2(A0)
  839.     BNE.S    .nocyan
  840.     BSR    arrow_is_grey            arrow=grey
  841. .nocyan    BSR    wait_no_buttons        wait for release
  842.     LEA    spectrum_old,A0        clear spectrum
  843.     LEA    spectrum_new,A1
  844.     MOVEQ    #23-1,D7
  845. .wipe    CLR.W    (A0)+
  846.     CLR.W    (A1)+
  847.     DBRA    D7,.wipe
  848.     BSR    clear_screen_topright    setup editor icons/spectrum analyser
  849.     LEA    spectrum_screen,A0
  850.     BSR    setup_topright
  851.     MOVE.W    #1,mode            mode=editor
  852.  
  853. upspec_skip
  854.     BRA    set_spect_colours
  855.  
  856. update_spectrum_analyser
  857.     CMP.W    #1,mode            if mode<>editor then set spectrum
  858.     BNE.S    upspec_skip
  859.     TST.W    plst_flag        if plst flag set then set spectrum
  860.     BNE.S    upspec_skip
  861.     MOVEQ    #40,D5
  862.     MOVEQ    #126,D6
  863.     LEA    spectrum_new,A0
  864.     LEA    spectrum_old,A1
  865.     LEA    spectrum_offsets_table,A2
  866.     MOVE.L    screen_ptr,A3
  867.     ADD.W    #49*40+16,A3
  868.     MOVEQ    #23-1,D7        update 23 columns
  869. .column
  870.     MOVE.W    (A0)+,D0        get new value
  871.     CMPI.W    #36,D0
  872.     BLT.S    .clip
  873.     MOVE.W    #36,D0            max 36
  874. .clip    MOVE.W    (A1)+,D1        get old value
  875.     CMP.W    D0,D1
  876.     BEQ.S    .next            if same then don't refresh
  877.     BLT.S    .up            else clear/fill changes
  878.     SUB.W    D0,D1
  879.     SUBQ.W    #1,D1
  880.     LSL.W    #1,D0
  881.     MOVE.W    0(A2,D0.W),D0
  882. .wipe    CLR.B    0(A3,D0.W)
  883.     SUB.W    D5,D0
  884.     DBRA    D1,.wipe
  885.     BRA.S    .next
  886. .up    SUB.W    D1,D0
  887.     SUBQ.W    #1,D0
  888.     LSL.W    #1,D1
  889.     MOVE.W    0(A2,D1.W),D1
  890. .fill    MOVE.B    D6,0(A3,D1.W)
  891.     SUB.W    D5,D1
  892.     DBRA    D0,.fill
  893. .next    ADDQ.W    #1,A3            next column
  894.     DBRA    D7,.column
  895.     LEA    spectrum_new,A0        copy new to old with auto fade
  896.     LEA    spectrum_old,A1
  897.     MOVEQ    #23-1,D7
  898. .copy    MOVE.W    (A0),D0
  899.     MOVE.W    D0,(A1)+
  900.     BEQ.S    .zero
  901.     SUBQ.W    #1,D0
  902. .zero    MOVE.W    D0,(A0)+
  903.     DBRA    D7,.copy
  904.     RTS
  905.  
  906. add_keyplay_to_spectrum
  907.     MOVEM.L    D0-D3/A0,-(SP)
  908.     MOVEQ    #0,D2
  909.     MOVE.W    instr_volume-instr_length(A6),D2
  910.     BRA.S    add_to_spectrum
  911.  
  912. add_note_to_spectrum
  913.     MOVEM.L    D0-D3/A0,-(SP)
  914.     MOVEQ    #0,D2
  915.     MOVE.W    $12(A6),D2
  916.  
  917. add_to_spectrum
  918.     BSR    update_channel_level    check if value>previous
  919.     BEQ.S    .skip            if < then ignore
  920.     ASL.W    #8,D2            d2=0..24 (main band)
  921.     DIVU    #682,D2
  922.     MOVE.W    D2,D3
  923.     LSR.W    #1,D3            d3=0..12 (side bands)
  924.     LEA    spectrum_new,A0        index spectrum
  925.     SUB.W    #113,D0
  926.     MOVE.W    #743,D1
  927.     SUB.W    D0,D1
  928.     MULU    D1,D1
  929.     DIVU    #25093,D1
  930.     MOVE.W    D1,D0
  931.     CMPI.W    #46,D0
  932.     BLT.S    .main
  933.     MOVEQ    #45,D0
  934. .main    LSL.W    #1,D0
  935.     ADD.W    D2,0(A0,D0.W)        add to main and side bands
  936.     CMP.W    #36,0(A0,D0.W)
  937.     BLT.S    .left
  938.     MOVE.W    #36,0(A0,D0.W)
  939. .left    TST.W    D0
  940.     BEQ.S    .right
  941.     ADD.W    D3,-2(A0,D0.W)
  942.     CMP.W    #36,-2(A0,D0.W)
  943.     BLT.S    .right
  944.     MOVE.W    #36,-2(A0,D0.W)
  945. .right    CMPI.W    #44,D0
  946.     BEQ.S    .skip
  947.     ADD.W    D3,2(A0,D0.W)
  948.     CMP.W    #36,2(A0,D0.W)
  949.     BLT.S    .skip
  950.     MOVE.W    #36,2(A0,D0.W)
  951. .skip    MOVEM.L    (SP)+,D0-D3/A0
  952.     RTS
  953.  
  954. spectrum_offsets_table
  955. i    set    46*40
  956.     rept    41
  957.     dc.w    i
  958. i    set    i-40
  959.     endr
  960.  
  961. check_toggle_on_off
  962.     MOVE.W    mouse_y2,D0
  963.     CMP.W    #3,mode            if mode=diskops then
  964.     BNE.S    .notm3
  965.     CMPI.W    #44,D0                if y>44 then
  966.     BGE    diskop_file_select            file select
  967. .notm3    CMPI.W    #44,D0            check which icon
  968.     BGE.S    .skip
  969.     CMPI.W    #34,D0
  970.     BGE.S    .chan4
  971.     CMPI.W    #23,D0
  972.     BGE.S    .chan3
  973.     CMPI.W    #12,D0
  974.     BGE.S    .chan2
  975.     TST.W    D0
  976.     BGE.S    .chan1
  977. .skip    RTS
  978. .chan1    LEA    onoff_1(PC),A0
  979.     BRA.S    .rel
  980. .chan2    LEA    onoff_2(PC),A0
  981.     BRA.S    .rel
  982. .chan3    LEA    onoff_3(PC),A0
  983.     BRA.S    .rel
  984. .chan4    LEA    onoff_4(PC),A0
  985. .rel    BTST    #6,$BFE001        wait till button released
  986.     BEQ.S    .rel
  987.     LEA    main_screen,A1
  988.     MOVEQ    #0,D0            toggle on/off
  989.     MOVE.W    2(A0),D0
  990.     ADD.L    D0,A1
  991.     EOR.W    #1,(A0)
  992.     TST.W    (A0)
  993.     BNE.S    .on            if off then clear level
  994.     CLR.W    4(A0)
  995.     LEA    onoff_icon+24,A0
  996.     BSR.S    draw_on_off        redraw
  997.     BRA.S    .sum
  998. .on    LEA    onoff_icon,A0
  999.     BSR.S    draw_on_off
  1000. .sum    CLR.W    D0            form 4-bit mask of states
  1001.     MOVE.W    onoff_4,D0
  1002.     LSL.B    #1,D0
  1003.     OR.W    onoff_3,D0
  1004.     LSL.B    #1,D0
  1005.     OR.W    onoff_2,D0
  1006.     LSL.B    #1,D0
  1007.     OR.W    onoff_1,D0
  1008.     MOVE.W    D0,onoff_states
  1009.     MOVE.W    #32768,D0        wait 3 frames
  1010. .wait    DBRA    D0,.wait
  1011.     BSR    wait_20ms
  1012.     RTS
  1013.  
  1014. refresh_on_off
  1015.     LEA    onoff_1(PC),A0    refresh all on/off icons
  1016.     BSR.S    .ref
  1017.     LEA    onoff_2(PC),A0
  1018.     BSR.S    .ref
  1019.     LEA    onoff_3(PC),A0
  1020.     BSR.S    .ref
  1021.     LEA    onoff_4(PC),A0
  1022. .ref    LEA    main_screen,A1
  1023.     MOVEQ    #0,D0
  1024.     MOVE.W    2(A0),D0        offset
  1025.     ADD.L    D0,A1
  1026.     TST.W    (A0)            state
  1027.     BNE.S    .on
  1028.     LEA    onoff_icon+24,A0
  1029.     BRA.S    draw_on_off
  1030. .on    LEA    onoff_icon,A0
  1031.  
  1032. draw_on_off
  1033.     MOVEQ    #6-1,D4
  1034. .row    MOVE.B    (A0),(A1)
  1035.     MOVE.B    1(A0),1(A1)
  1036.     MOVE.B    2(A0),2(A1)
  1037.     MOVE.B    48(A0),10240(A1)
  1038.     MOVE.B    49(A0),10241(A1)
  1039.     MOVE.B    50(A0),10242(A1)
  1040.     ADDQ.L    #4,A0
  1041.     ADD.L    #40,A1
  1042.     DBRA    D4,.row
  1043.     RTS
  1044.  
  1045. update_chaneq_levels
  1046.     MOVEM.L    D0-D7/A0-A6,-(SP)
  1047.     LEA    volume_1(PC),A0
  1048.     LEA    audio_info_1(PC),A1
  1049.     LEA    s_chaneq1,A2
  1050.     BSR.S    .update
  1051.     LEA    volume_2(PC),A0
  1052.     LEA    audio_info_2(PC),A1
  1053.     LEA    s_chaneq2,A2
  1054.     BSR.S    .update
  1055.     LEA    volume_3(PC),A0
  1056.     LEA    audio_info_3(PC),A1
  1057.     LEA    s_chaneq3,A2
  1058.     BSR.S    .update
  1059.     LEA    volume_4(PC),A0
  1060.     LEA    audio_info_4(PC),A1
  1061.     LEA    s_chaneq4,A2
  1062.     BSR.S    .update
  1063.     MOVEM.L    (SP)+,D0-D7/A0-A6
  1064.     RTS
  1065.  
  1066. .update    TST.L    play_mode    if not playing or channel off then fade
  1067.     BEQ.S    .fade
  1068.     TST.W    onoff_1-volume_1(A0)
  1069.     BEQ.S    .fade
  1070.     TST.W    (A0)
  1071.     BEQ.S    .fade        if volume=0 then fade
  1072.     TST.W    (A1)
  1073.     BEQ.S    .fade        if no note then fade
  1074.     TST.L    frame_count
  1075.     BNE.S    .fade        if no new note then fade
  1076.     MOVEQ    #0,D0
  1077.     MOVE.W    (A0),D0        get volume
  1078.     CMPI.W    #64,D0
  1079.     BLE.S    .vol_ok
  1080.     MOVEQ    #64,D0
  1081. .vol_ok    MOVE.B    #233,D7        sprite start = 233-47*(volume/64)
  1082.     LEA    scale_64_47(PC),A3
  1083.     SUB.B    0(A3,D0.W),D7
  1084.     MOVE.B    D7,(A2)
  1085.     RTS
  1086. .fade    CMP.B    #233,(A2)    if not playing then
  1087.     BEQ.S    .faded            sprite start + 1 until = 233
  1088.     ADDQ.B    #1,(A2)            i.e. fade out
  1089. .faded    RTS
  1090.  
  1091. onoff_1    dc.w    1        icon state
  1092.     dc.w    4*40+37        screen offset
  1093.     dc.w    0        channel level 0..127 (for spectrum analyser)
  1094. onoff_2    dc.w    1
  1095.     dc.w    15*40+37
  1096.     dc.w    0
  1097. onoff_3    dc.w    1
  1098.     dc.w    26*40+37
  1099.     dc.w    0
  1100. onoff_4    dc.w    1
  1101.     dc.w    37*40+37
  1102.     dc.w    0
  1103.  
  1104. volume_1 dc.w    0,0,0        current volumes (2nd & 3rd 0's are padding)
  1105. volume_2 dc.w    0,0,0
  1106. volume_3 dc.w    0,0,0
  1107. volume_4 dc.w    0,0,0
  1108.  
  1109. onoff_states
  1110.     dc.w    %1111
  1111.  
  1112. scale_64_47
  1113.     dc.b    0,0,1,2,2,3,4,5        rescale 0..64 -> 0..47
  1114.     dc.b    5,6,7,8,8,9,10,11
  1115.     dc.b    11,12,13,14,14,15,16,17
  1116.     dc.b    17,18,19,20,20,21,22,23
  1117.     dc.b    23,24,25,26,26,27,28,29
  1118.     dc.b    29,30,31,32,32,33,34,35
  1119.     dc.b    35,36,37,38,38,39,40,41
  1120.     dc.b    41,42,43,44,44,45,46,47
  1121.     dc.b    47
  1122.     even
  1123.  
  1124. update_channel_level
  1125.     MOVEM.L    D0-D3/A0,-(SP)        d2=volume,a5=audio channel
  1126.     LSL.W    #8,D2            *256/640
  1127.     DIVU    #640,D2
  1128.     CMP.L    #_custom+aud0,A5    find channel
  1129.     BNE.S    .try2
  1130.     TST.W    onoff_1
  1131.     BEQ.S    .no
  1132.     CMP.W    onoff_1+4,D2        if >previous level then update
  1133.     BLT.S    .try2
  1134.     MOVE.W    D2,onoff_1+4
  1135. .try2    CMP.L    #_custom+aud1,A5
  1136.     BNE.S    .try3
  1137.     TST.W    onoff_2
  1138.     BEQ.S    .no
  1139.     CMP.W    onoff_2+4,D2
  1140.     BLT.S    .try3
  1141.     MOVE.W    D2,onoff_2+4
  1142. .try3    CMP.L    #_custom+aud2,A5
  1143.     BNE.S    .try4
  1144.     TST.W    onoff_3
  1145.     BEQ.S    .no
  1146.     CMP.W    onoff_3+4,D2
  1147.     BLT.S    .try4
  1148.     MOVE.W    D2,onoff_3+4
  1149. .try4    CMP.L    #_custom+aud3,A5
  1150.     BNE.S    .yes
  1151.     TST.W    onoff_4
  1152.     BEQ.S    .no
  1153.     CMP.W    onoff_4+4,D2
  1154.     BLT.S    .yes
  1155.     MOVE.W    D2,onoff_4+4
  1156. .yes    MOVEM.L    (SP)+,D0-D3/A0
  1157.     MOVEQ    #1,D4            new level
  1158.     RTS
  1159. .no    MOVEM.L    (SP)+,D0-D3/A0
  1160.     MOVEQ    #0,D4            ignore
  1161.     RTS
  1162.  
  1163. * GOTO DISKOPS SCREEN
  1164.  
  1165. fn_goto_diskops
  1166.     BSR    wait_no_buttons
  1167.     CMP.L    #'edit',play_mode    cancel edit mode
  1168.     BNE.S    .clr1
  1169.     CLR.L    play_mode
  1170.     BSR    arrow_is_grey
  1171. .clr1    CMP.L    #'edit',edit_mode
  1172.     BNE.S    .clr2
  1173.     CLR.L    edit_mode
  1174.     BSR    arrow_is_grey
  1175. .clr2    MOVE.W    #3,mode            mode=diskops
  1176.     BSR    clear_screen_topright
  1177.     BSR    copy_diskops_screen
  1178.     CLR.W    disk_fn
  1179.     BSR    wait_no_buttons
  1180.     BSR    print_modules_dir
  1181.     BSR    refresh_pack_icon
  1182.     MOVE.W    #$8000,D0
  1183. .delay    DBRA    D0,.delay
  1184.     BRA    clear_spect_colours
  1185.  
  1186. print_modules_dir
  1187.     CMP.W    #3,mode            if mode<>diskops then return
  1188.     BNE    return
  1189.     MOVE.L    #modules_dir,string_addr    else print modules dir
  1190.     MOVE.L    #$5E0,char_offset
  1191.     MOVE.L    #15,string_size
  1192.     BRA    print_string
  1193.  
  1194. diskop_file_select
  1195.     MOVEM.W    mouse_x2,D0/D1
  1196.     SUB.W    #120,D0            d0=mouse_x-120
  1197.     SUB.W    #44,D1            d1=mouse_y-44
  1198.     CMP.W    #3,mode            skip if mode<>diskops
  1199.     BEQ.S    .diskop
  1200.     RTS
  1201. .diskop    CMPI.W    #189,D0            if x<189 then
  1202.     BLT    select_file
  1203.     CMPI.W    #12,D1            if y<12 then scroll up list
  1204.     BLT    scroll_up_files
  1205.     CMPI.W    #45,D1            if x>=189 and 12<=y<45 then
  1206.     BLT    goto_editor_mode        exit to editor
  1207.     BRA    scroll_down_files    else scroll down list
  1208.  
  1209. * LOAD SONG
  1210.  
  1211. fn_load_song
  1212.     BSR    wait_no_buttons
  1213.     CLR.W    disk_fn
  1214.     BSR    wipe_spectrum
  1215.     CLR.W    ffi_type
  1216.     LEA    st00_name(PC),A4
  1217.     LEA    dir_buffer(PC),A5
  1218.     BSR    find_file_info
  1219.     BEQ.S    .ok
  1220.     BSR    cancel_directory
  1221.     BSR    read_directory
  1222.     BEQ.S    .ok
  1223.     BRA    arrow_flash_red
  1224. .ok    MOVE.W    diskop_cursor,D0
  1225.     MOVE.W    #1,disk_fn
  1226.     BSR    refresh_diskop_filelist
  1227.     BRA    arrow_is_grey
  1228.  
  1229. * SAVE SONG
  1230.  
  1231. fn_save_song
  1232.     BSR    save_arrow_colours
  1233.     BSR    arrow_is_magenta
  1234.     BSR    check_are_you_sure
  1235.     BNE    arrow_flash_red
  1236.     BSR    wipe_spectrum
  1237.     BSR    fn_stop
  1238.     CLR.W    disk_fn
  1239.     BSR    save_song
  1240.     BRA    arrow_is_grey
  1241.  
  1242. * DELETE SONG
  1243.  
  1244. fn_delete_song
  1245.     BSR    wait_no_buttons
  1246.     CLR.W    disk_fn
  1247.     MOVE.L    cptr_arrow_col,A4    if arrow<>cyan then save colours
  1248.     CMP.W    #$0AA,2(A4)
  1249.     BEQ.S    .cyan
  1250.     BSR    save_arrow_colours
  1251. .cyan    BSR    wipe_spectrum
  1252.     CLR.W    ffi_type
  1253.     LEA    st00_name(PC),A4
  1254.     LEA    dir_buffer(PC),A5
  1255.     BSR    find_file_info
  1256.     BEQ.S    .ok
  1257.     BSR    cancel_directory
  1258.     BSR    read_directory
  1259.     BEQ.S    .ok
  1260.     BRA    arrow_flash_red
  1261. .ok    MOVE.W    diskop_cursor,D0
  1262.     MOVE.W    #2,disk_fn
  1263.     BSR    refresh_diskop_filelist
  1264.     BRA    arrow_is_cyan
  1265.  
  1266. * DELETE MODULE
  1267.  
  1268. fn_delete_module
  1269.     BSR    wait_no_buttons
  1270.     CLR.W    disk_fn
  1271.     MOVE.L    cptr_arrow_col,A4    if arrow<>cyan then save colours
  1272.     CMP.W    #$0AA,2(A4)
  1273.     BEQ.S    .cyan
  1274.     BSR    save_arrow_colours
  1275. .cyan    BSR    wipe_spectrum
  1276.     MOVE.W    #1,ffi_type
  1277.     LEA    modules_dir(PC),A4
  1278.     LEA    dir_buffer(PC),A5
  1279.     BSR    find_file_info
  1280.     BEQ.S    .ok
  1281.     BSR    cancel_directory
  1282.     BSR    read_directory
  1283.     BEQ.S    .ok
  1284.     BRA    arrow_flash_red
  1285. .ok    MOVE.W    diskop_cursor,D0
  1286.     MOVE.W    #4,disk_fn
  1287.     BSR    refresh_diskop_filelist
  1288.     BRA    arrow_is_cyan
  1289.  
  1290. * LOAD MODULE
  1291.  
  1292. fn_load_module
  1293.     BSR    wait_no_buttons
  1294.     CLR.W    disk_fn
  1295.     BSR    wipe_spectrum
  1296.     MOVE.W    #1,ffi_type
  1297.     LEA    modules_dir(PC),A4
  1298.     LEA    dir_buffer(PC),A5
  1299.     BSR    find_file_info
  1300.     BEQ.S    .ok
  1301.     BSR    cancel_directory
  1302.     BSR    read_directory
  1303.     BEQ.S    .ok
  1304.     BRA    arrow_flash_red
  1305. .ok    MOVE.W    diskop_cursor,D0
  1306.     MOVE.W    #3,disk_fn
  1307.     BSR    refresh_diskop_filelist
  1308.     BRA    arrow_is_grey
  1309.  
  1310. * SAVE MODULE
  1311.  
  1312. fn_save_module
  1313.     BSR    arrow_is_magenta
  1314.     BSR    check_are_you_sure
  1315.     BNE    arrow_flash_red
  1316.     BSR    save_module
  1317.     BRA    arrow_is_grey
  1318.  
  1319. scroll_up_files
  1320.     TST.W    disk_fn            skip if no function selected
  1321.     BEQ.S    .skip
  1322.     LEA    dir_buffer(PC),A5
  1323.     MOVE.W    diskop_cursor,D0
  1324.     BEQ.S    .skip
  1325.     SUBQ.W    #1,D0
  1326.     BSR    refresh_diskop_filelist
  1327. .skip    CLR.W    fscroll_pending
  1328.     RTS
  1329.  
  1330. scroll_down_files
  1331.     TST.W    disk_fn
  1332.     BEQ.S    .skip
  1333.     LEA    dir_buffer(PC),A5
  1334.     MOVE.W    diskop_cursor,D0
  1335.     ADDQ.W    #1,D0
  1336.     MOVE.W    16(A5),D1
  1337.     SUBQ.W    #7,D1
  1338.     CMP.W    D1,D0
  1339.     BGT.S    .skip
  1340.     BSR    refresh_diskop_filelist
  1341. .skip    CLR.W    fscroll_pending
  1342.     RTS
  1343.  
  1344. select_file
  1345.     MOVE.W    #1,memory_flag
  1346.     TST.W    disk_fn
  1347.     BEQ.S    .skip
  1348.     CMPI.W    #7,D1
  1349.     BLT.S    .skip
  1350.     CMPI.W    #48,D1
  1351.     BGT.S    .skip
  1352.     SUBQ.W    #7,D1
  1353.     AND.L    #$FFFF,D1
  1354.     DIVU    #6,D1
  1355.     LEA    dir_buffer(PC),A5
  1356.     MOVE.W    diskop_cursor,D0
  1357.     ADD.W    D1,D0
  1358.     CMP.W    16(A5),D0
  1359.     BGE.S    .skip
  1360.     MULU    #28,D0            index directory
  1361.     ADD.L    (A5),D0
  1362.     MOVE.L    D0,A0
  1363.     MOVE.L    A0,dir_entry_ptr    save ptr to dir entry
  1364.     MOVE.W    26(A5),D0
  1365.     LEA    selected_filename,A1        copy filename
  1366.     SUBQ.W    #1,D0
  1367. .name    MOVE.B    (A0)+,(A1)+
  1368.     DBRA    D0,.name
  1369.     CMP.W    #2,disk_fn
  1370.     BEQ    delete_song
  1371.     CMP.W    #3,disk_fn
  1372.     BEQ    load_module
  1373.     CMP.W    #4,disk_fn
  1374.     BEQ    delete_module
  1375.     CMP.W    #5,disk_fn
  1376.     BEQ    load_sample
  1377.     BRA    load_song
  1378. .skip    RTS
  1379.  
  1380. dir_buffer
  1381. .0    dc.l    0        ptr to directory list
  1382. .4    dc.l    0        date
  1383. .8    dc.l    0        minute
  1384. .12    dc.l    0        tick
  1385. .16    dc.w    0        no. of entries
  1386. .18    dc.l    selected_filename
  1387. .22    dc.l    load_song
  1388. .26    dc.w    28        length of each entry
  1389.  
  1390. diskop_cursor
  1391.     dc.w    0
  1392.  
  1393. st00_name
  1394.     dc.b    'st-00:songs/',0
  1395.     even
  1396.  
  1397. modules_dir
  1398.     dc.b    'st-00:modules/',0,0,0,0,0,0
  1399.  
  1400. * PLAY SONG
  1401.  
  1402. fn_play_song
  1403.     BTST    #6,$BFE001        wait till button released
  1404.     BEQ.S    fn_play_song
  1405.     BSR    fn_stop            stop tune
  1406.     BSR    arrow_is_yellow
  1407.     MOVE.L    #'patp',play_mode    mode=play song
  1408.     CLR.W    keyplay_channel        clear keyboard note
  1409.     CLR.W    quantize_flag
  1410.     MOVE.L    #$FFFFFFFF,prev_pat_no
  1411.     CLR.L    play_cursor
  1412.     CLR.W    edit_cursor_y        reset scroller
  1413.     BSR    set_edit_scroller
  1414.     MOVEQ    #0,D1
  1415.     MOVE.W    song_length,D1        make sure position valid
  1416.     MOVE.L    song_position,D0
  1417.     CMP.L    D1,D0
  1418.     BPL.S    .reset
  1419.     RTS
  1420. .reset    CLR.L    song_position
  1421.     RTS
  1422.  
  1423. * RECORD SONG
  1424.  
  1425. fn_record
  1426.     BTST    #6,$BFE001
  1427.     BEQ.S    fn_record
  1428.     BSR    fn_stop            reset scroller
  1429.     BSR    set_edit_scroller
  1430.     MOVE.L    #'patt',play_mode    mode=play pattern
  1431.     BSR    arrow_is_blue
  1432.     MOVE.L    #'edit',edit_mode    mode=edit
  1433.     BRA    enable_scroller
  1434.  
  1435. * entry    A4=ptr to directory name
  1436. *    A5=dir_buffer
  1437. *    find_file_type=0 file/1=dir/2=disk
  1438.  
  1439. find_file_info
  1440.     MOVE.W    #1,memory_flag
  1441.     MOVE.L    DOSbase,A6
  1442.     MOVE.L    A4,D1
  1443.     MOVEQ    #-2,D2            read
  1444.     JSR    _LVOLock(A6)        lock file
  1445.     MOVE.L    D0,lock_ptr        fail if error
  1446.     BEQ    .error
  1447.     MOVE.L    lock_ptr,D1
  1448.     MOVE.L    #FileInfoBlock,D2    get info block
  1449.     JSR    _LVOExamine(A6)
  1450.     TST.L    D0            fail if error
  1451.     BEQ.S    .error
  1452.     LEA    FileInfoBlock,A0
  1453.     MOVE.L    132(A0),D0        if date, time and type match then
  1454.     CMP.L    4(A5),D0
  1455.     BNE.S    .new
  1456.     MOVE.L    136(A0),D0
  1457.     CMP.L    8(A5),D0
  1458.     BNE.S    .new
  1459.     MOVE.L    140(A0),D0
  1460.     CMP.L    12(A5),D0
  1461.     BNE.S    .new
  1462.     MOVE.W    ffi_type,D0
  1463.     CMP.W    ffi_type_prev,D0
  1464.     BNE.S    .new
  1465.     MOVE.L    lock_ptr,D1            then unlock
  1466.     JSR    _LVOUnLock(A6)
  1467.     MOVEQ    #0,D0                return true
  1468.     RTS
  1469. .new    MOVE.L    132(A0),4(A5)        else    copy date/time/type
  1470.     MOVE.L    136(A0),8(A5)
  1471.     MOVE.L    140(A0),12(A5)
  1472.     MOVE.W    ffi_type,ffi_type_prev
  1473.     MOVE.L    lock_ptr,D1            unlock
  1474.     JSR    _LVOUnLock(A6)
  1475.     MOVEQ    #-1,D0                return fail
  1476.     RTS
  1477. .error    CLR.L    4(A5)            else    clear date
  1478.     MOVEQ    #-1,D0                return fail
  1479.     RTS
  1480.  
  1481. read_directory
  1482.     BSR    save_arrow_colours    entry a4=name ptr, a5=dir_buffer
  1483.     BSR    arrow_is_green
  1484.     CLR.W    diskop_cursor
  1485.     MOVE.L    DOSbase,A6
  1486.     MOVE.L    A4,D1
  1487.     MOVEQ    #-2,D2
  1488.     JSR    _LVOLock(A6)        get info
  1489.     MOVE.L    D0,lock_ptr
  1490.     BEQ.S    .error
  1491.     MOVE.L    lock_ptr,D1
  1492.     MOVE.L    #FileInfoBlock,D2
  1493.     JSR    _LVOExamine(A6)
  1494.     TST.L    D0
  1495.     BEQ.S    .error
  1496. .loop    MOVE.L    lock_ptr,D1        get filenames
  1497.     MOVE.L    #FileInfoBlock,D2
  1498.     JSR    _LVOExNext(A6)
  1499.     TST.L    D0
  1500.     BEQ.S    .done
  1501.     CMP.B    #'.',FileInfoBlock+32    name+24 ??
  1502.     BSR.S    read_filename
  1503.     BRA.S    .loop
  1504. .done    MOVE.L    lock_ptr,D1
  1505.     JSR    _LVOUnLock(A6)
  1506.     BSR    restore_arrow_colours
  1507.     MOVEQ    #0,D0
  1508.     RTS
  1509. .error    BSR    restore_arrow_colours
  1510.     MOVEQ    #-1,D0
  1511.     RTS
  1512.  
  1513. cancel_directory
  1514.     CLR.W    16(A5)            no. of entries = 0
  1515.     RTS
  1516.  
  1517. read_filename
  1518.     TST.W    ffi_type
  1519.     BEQ.S    .file
  1520.     CMP.W    #2,ffi_type
  1521.     BNE.S    .dir
  1522.     CMP.L    #'.fas',FileInfoBlock+8        ignore .fastdir
  1523.     BEQ    return
  1524.     LEA    FileInfoBlock+8,A0
  1525. .getend    TST.B    (A0)+                ignore .info files
  1526.     BNE.S    .getend
  1527.     CMP.B    #'.',-6(A0)
  1528.     BNE.S    .notinf
  1529.     CMP.B    #'i',-5(A0)
  1530.     BNE.S    .notinf
  1531.     CMP.B    #'n',-4(A0)
  1532.     BNE.S    .notinf
  1533.     CMP.B    #'f',-3(A0)
  1534.     BNE.S    .notinf
  1535.     CMP.B    #'o',-2(A0)
  1536.     BEQ    return
  1537. .notinf    TST.L    FileInfoBlock+124        size
  1538.     BEQ    return
  1539.     BRA.S    .file
  1540. .dir    CMP.L    #'mod.',FileInfoBlock+8        allow mod./MOD.
  1541.     BEQ.S    .file
  1542.     CMP.L    #'MOD.',FileInfoBlock+8
  1543.     BNE    return
  1544. .file    MOVE.W    16(A5),D6        if 1st file then
  1545.     BEQ.S    .first                 insert at start of list
  1546.     SUBQ.W    #1,D6
  1547.     LEA    FileInfoBlock+8,A0    a0=filename
  1548.     MOVE.L    (A5),A1            a1=filelist
  1549. .loop    MOVEQ    #0,D2            insert into list in alpha order
  1550.     MOVEQ    #0,D3
  1551. .char    MOVE.B    0(A0,D2.W),D0        get filename char
  1552.     BEQ.S    .found            if end then found position
  1553.     CMPI.B    #$60,D0            upper case
  1554.     BLT.S    .upper
  1555.     SUB.B    #$20,D0
  1556. .upper    MOVE.B    0(A1,D3.W),D1        get filelist char
  1557.     BEQ.S    .next            if end then try next name
  1558.     CMPI.B    #$60,D1
  1559.     BLT.S    .upper2
  1560.     SUB.B    #$20,D1
  1561. .upper2    CMP.B    D0,D1
  1562.     BGT.S    .found            if < then found position
  1563.     BEQ.S    .same            if = then try next chars
  1564. .next    ADD.L    #28,A1
  1565.     DBRA    D6,.loop
  1566.     MOVE.L    (A5),A1            if > all then
  1567.     MOVE.W    16(A5),D0            insert at end of list
  1568.     MULU    #28,D0
  1569.     ADD.W    D0,A1
  1570.     BRA.S    .insert
  1571. .same    ADDQ.W    #1,D2
  1572.     ADDQ.W    #1,D3
  1573.     BRA.S    .char
  1574. .found    MOVE.L    (A5),A2            shift up following names
  1575.     MOVE.W    16(A5),D0
  1576.     MULU    #28,D0
  1577.     ADD.L    D0,A2
  1578.     MOVE.L    A2,A3
  1579.     ADD.L    #28,A3
  1580. .shift    MOVE.W    -(A2),-(A3)
  1581.     CMP.L    A2,A1
  1582.     BNE.S    .shift
  1583.     BRA.S    .insert
  1584. .first    MOVE.L    (A5),A1
  1585. .insert    LEA    FileInfoBlock+8,A0        copy name (23 chars+0)
  1586.     MOVE.L    A1,A3
  1587.     MOVEQ    #28-1,D0
  1588. .wname    CLR.B    (A3)+
  1589.     DBRA    D0,.wname
  1590.     MOVEQ    #28-1,D0
  1591. .cname    MOVE.B    (A0)+,D1
  1592.     MOVE.B    D1,(A1)+
  1593.     TST.B    D1
  1594.     BEQ.S    .csize
  1595.     DBRA    D0,.cname
  1596. .csize    CLR.B    -5(A3)
  1597.     MOVE.L    FileInfoBlock+124,-4(A3)    copy size (4 bytes)
  1598.     ADDQ.W    #1,16(A5)            bump no. of entries
  1599.     RTS
  1600.  
  1601. refresh_diskop_filelist
  1602.     MOVE.W    D0,-(SP)        entry d0=new diskop cursor
  1603.     BSR    wipe_spectrum
  1604.     MOVE.W    (SP)+,D0
  1605.     MOVE.W    D0,diskop_cursor    update cursor position
  1606.     TST.W    16(A5)            skip if no dir
  1607.     BEQ.S    .skip
  1608.     MOVE.L    #51*40+16,A6
  1609.     MOVE.L    A6,char_offset        top line
  1610.     MOVE.L    (A5),D6
  1611.     MULU    #28,D0
  1612.     ADD.L    D0,D6            d6=filelist+28*cursor
  1613.     MOVE.W    16(A5),D0        d0=no. of entries - cursor
  1614.     SUB.W    diskop_cursor,D0
  1615.     CMPI.W    #7,D0
  1616.     BGE.S    .clip            if d0>=7 then count=7 else count=d0-1
  1617.     SUBQ.W    #1,D0
  1618.     MOVE.W    D0,D7
  1619.     BRA.S    .ok
  1620. .clip    MOVEQ    #7-1,D7
  1621. .ok    CMP.W    #3,disk_fn
  1622.     BEQ.S    .modules
  1623.     CMP.W    #4,disk_fn
  1624.     BEQ.S    .modules
  1625.     CMP.W    #5,disk_fn
  1626.     BEQ    .samples
  1627. .songs    MOVE.L    D6,string_addr        for songs
  1628.     MOVE.L    A6,char_offset        print song name only
  1629.     MOVE.L    #22,string_size
  1630.     BSR    print_string_spc
  1631.     ADD.L    #28,D6
  1632.     ADD.L    #6*40,A6
  1633.     DBRA    D7,.songs
  1634. .skip    RTS
  1635. .modules
  1636.     ADDQ.L    #4,D6            for modules
  1637. .mod2    MOVE.L    D6,string_addr        print module name without mod.
  1638.     MOVE.L    A6,char_offset        print length
  1639.     MOVE.L    #17,string_size
  1640.     BSR    print_string_spc
  1641.     MOVE.L    D6,A0
  1642.     CLR.W    D0
  1643.     MOVE.B    21(A0),D0
  1644.     ASL.W    #1,D0
  1645.     LEA    hex2ascii+1,A0
  1646.     MOVE.B    0(A0,D0.W),word_to_print
  1647.     CLR.B    word_to_print+1
  1648.     MOVE.L    #word_to_print,string_addr
  1649.     MOVE.L    #1,string_size
  1650.     BSR    print_string
  1651.     MOVE.L    D6,A0
  1652.     MOVE.W    22(A0),word_to_print
  1653.     BSR    print_hex4
  1654.     ADD.L    #28,D6
  1655.     ADD.L    #6*40,A6
  1656.     DBRA    D7,.mod2
  1657.     RTS
  1658. .samples
  1659.     MOVE.L    D6,string_addr        for samples
  1660.     MOVE.L    A6,char_offset        print name and length
  1661.     MOVE.L    #18,string_size
  1662.     BSR    print_string_spc
  1663.     MOVE.L    D6,A0
  1664.     MOVE.W    26(A0),word_to_print
  1665.     BSR    print_hex4
  1666.     ADD.L    #28,D6
  1667.     ADD.L    #6*40,A6
  1668.     DBRA    D7,.samples
  1669.     RTS
  1670.  
  1671. setup_topright
  1672.     MOVE.W    #145,D0            entry a0=spectrum screen
  1673.     BSR    wait_for_vpos
  1674.     LEA    main_screen+45*40+15,A1
  1675.     MOVEQ    #2-1,D7            copy spectrum to screen
  1676. .plane    MOVEQ    #55-1,D6
  1677. .row    MOVEQ    #25-1,D5
  1678. .column    MOVE.B    (A0)+,(A1)+
  1679.     DBRA    D5,.column
  1680.     ADDQ.L    #1,A0
  1681.     ADD.L    #40-25,A1
  1682.     DBRA    D6,.row
  1683.     ADD.L    #10240-55*40,A1
  1684.     DBRA    D7,.plane
  1685.     LEA    main_screen+40+15,A0    copy edit icons to screen
  1686.     LEA    edit_icons_copy,A1
  1687.     MOVEQ    #44-1,D0
  1688. .row2    MOVEQ    #25-1,D1
  1689. .colum2    MOVE.B    (A1)+,(A0)+
  1690.     MOVE.B    1100-1(A1),10240-1(A0)
  1691.     DBRA    D1,.colum2
  1692.     ADD.L    #40-25,A0
  1693.     DBRA    D0,.row2
  1694.     BSR    refresh_on_off        update on/off icons
  1695.     RTS
  1696.  
  1697. copy_diskops_screen
  1698.     LEA    diskops_screen,A0    copy to main screen
  1699.     MOVE.W    #145,D0
  1700.     BSR    wait_for_vpos
  1701.     LEA    main_screen+40+15,A1
  1702.     MOVEQ    #1,D7
  1703. .plane    MOVEQ    #99-1,D6
  1704. .row    MOVEQ    #25-1,D5
  1705. .column    MOVE.B    (A0)+,(A1)+
  1706.     DBRA    D5,.column
  1707.     ADDQ.L    #1,A0
  1708.     ADD.L    #15,A1
  1709.     DBRA    D6,.row
  1710.     ADD.L    #(256-99)*40,A1
  1711.     DBRA    D7,.plane
  1712.     RTS
  1713.  
  1714. clear_screen_topright
  1715.     MOVE.W    #145,D0
  1716.     BSR    wait_for_vpos
  1717.     MOVE.L    screen_ptr,A1
  1718.     ADD.L    #15,A1
  1719.     MOVEQ    #100-1,D6
  1720. .row    MOVEQ    #25-1,D5
  1721. .column    CLR.B    (A1)+
  1722.     DBRA    D5,.column
  1723.     ADD.L    #15,A1
  1724.     DBRA    D6,.row
  1725.     RTS
  1726.  
  1727. wipe_spectrum
  1728.     MOVE.W    #145,D0
  1729.     BSR    wait_for_vpos
  1730.     MOVE.L    screen_ptr,A1
  1731.     ADD.L    #45*40+15,A1
  1732.     MOVEQ    #56-1,D6
  1733. .row    MOVEQ    #25-1,D5
  1734. .column    CLR.B    (A1)+
  1735.     DBRA    D5,.column
  1736.     ADD.L    #40-25,A1
  1737.     DBRA    D6,.row
  1738.     RTS
  1739.  
  1740.     CLR.W    D0
  1741.     MOVE.B    _custom+joy0dat,D0
  1742.     MOVE.W    D0,mouse_oldy
  1743.     MOVE.B    _custom+joy0dat+1,D0
  1744.     MOVE.W    D0,mouse_oldx
  1745.     RTS
  1746.  
  1747. wait_no_buttons
  1748.     BTST    #6,$BFE001
  1749.     BEQ.S    wait_no_buttons
  1750.     BTST    #2,_custom+potinp
  1751.     BEQ.S    wait_no_buttons
  1752.     MOVE.W    #145,D0
  1753.     BRA    wait_for_vpos
  1754.  
  1755. check_are_you_sure
  1756.     BSR.S    wait_no_buttons
  1757.     MOVE.W    #$4000,D7
  1758. .delay    DBRA    D7,.delay
  1759.     BSR    wipe_spectrum
  1760.     BSR.S    toggle_rusure_icon    show 'are you sure?' icon
  1761.     BSR.S    wait_no_buttons
  1762. .wait    BTST    #6,$BFE001        wait for left button
  1763.     BNE.S    .wait
  1764.     MOVEM.W    mouse_x,D0/D1        get mouse coords
  1765.     CMPI.W    #$AB,D0
  1766.     BLT.S    .wait
  1767.     CMPI.W    #$FC,D0
  1768.     BGT.S    .wait
  1769.     CMPI.W    #$48,D1
  1770.     BLT.S    .wait
  1771.     CMPI.W    #$52,D1
  1772.     BGT.S    .wait
  1773.     CMPI.W    #$C5,D0            loop if not on yes or no buttons
  1774.     BLT.S    .yes
  1775.     CMPI.W    #$EA,D0
  1776.     BLT.S    .wait
  1777.     BSR.S    toggle_rusure_icon    restore screen
  1778.     MOVEQ    #-1,D0
  1779.     RTS
  1780. .yes    BSR.S    toggle_rusure_icon
  1781.     MOVEQ    #0,D0
  1782.     RTS
  1783.  
  1784. toggle_rusure_icon
  1785.     LEA    main_screen+$834,A0    toggle 'are you sure?' message
  1786.     LEA    rusure_icon,A1        on to screen
  1787.     MOVEQ    #39-1,D0
  1788. .row    MOVEQ    #13-1,D1
  1789. .column    MOVE.B    10240(A0),D2
  1790.     MOVE.B    39*14(A1),10240(A0)
  1791.     MOVE.B    D2,39*14(A1)
  1792.     MOVE.B    (A0),D2
  1793.     MOVE.B    (A1),(A0)+
  1794.     MOVE.B    D2,(A1)+
  1795.     DBRA    D1,.column
  1796.     ADD.L    #40-13,A0
  1797.     ADDQ.L    #1,A1
  1798.     DBRA    D0,.row
  1799.     RTS
  1800.  
  1801. wait_for_vpos
  1802.     MOVE.L    _custom+vposr,D1    wait till vpos = d0
  1803.     LSR.L    #8,D1
  1804.     AND.W    #511,D1
  1805.     CMP.W    D1,D0
  1806.     BNE.S    wait_for_vpos
  1807.     RTS
  1808.  
  1809. arrow_is_cyan
  1810.     MOVE.L    cptr_arrow_col,A0
  1811.     MOVE.W    #$0AA,2(A0)
  1812.     MOVE.W    #$077,6(A0)
  1813.     MOVE.W    #$044,10(A0)
  1814.     RTS
  1815. arrow_is_grey
  1816.     MOVE.L    cptr_arrow_col,A0
  1817.     MOVE.W    #$AAA,2(A0)
  1818.     MOVE.W    #$777,6(A0)
  1819.     MOVE.W    #$444,10(A0)
  1820.     RTS
  1821. arrow_is_green
  1822.     MOVE.L    cptr_arrow_col,A0
  1823.     MOVE.W    #$0A0,2(A0)
  1824.     MOVE.W    #$070,6(A0)
  1825.     MOVE.W    #$040,10(A0)
  1826.     RTS
  1827. arrow_is_yellow
  1828.     MOVE.L    cptr_arrow_col,A0
  1829.     MOVE.W    #$BA0,2(A0)
  1830.     MOVE.W    #$970,6(A0)
  1831.     MOVE.W    #$740,10(A0)
  1832.     RTS
  1833. arrow_is_blue
  1834.     MOVE.L    cptr_arrow_col,A0
  1835.     MOVE.W    #$05B,2(A0)
  1836.     MOVE.W    #$049,6(A0)
  1837.     MOVE.W    #$006,10(A0)
  1838.     RTS
  1839. arrow_is_magenta
  1840.     MOVE.L    cptr_arrow_col,A0
  1841.     MOVE.W    #$A5A,2(A0)
  1842.     MOVE.W    #$727,6(A0)
  1843.     MOVE.W    #$404,10(A0)
  1844.     RTS
  1845.  
  1846. arrow_flash_red
  1847.     MOVE.W    #1,memory_flag
  1848.     MOVE.L    cptr_arrow_col,A0
  1849.     MOVE.W    #$C00,2(A0)
  1850.     MOVE.W    #$900,6(A0)
  1851.     MOVE.W    #$700,10(A0)
  1852.     MOVEQ    #15,D1
  1853. .wait    BSR    wait_20ms    wait 1/3 second
  1854.     DBRA    D1,.wait
  1855.     BRA    arrow_is_grey    back to grey mouse
  1856.  
  1857. check_help
  1858.     BSR    check_hallonsoft_mode    check for hallonsoft typed
  1859.     CMP.B    #$5F,key_code        if key = HELP then
  1860.     BNE.S    return2
  1861.  
  1862. * GOTO PLST SCREEN
  1863.  
  1864. fn_goto_plst
  1865.     CMP.W    #3,mode                skip if mode=diskops
  1866.     BEQ.S    return2
  1867.     CLR.B    key_code            clear key
  1868.     TST.W    plst_flag            if plst flag set then
  1869.     BEQ.S    set_plst_mode
  1870.  
  1871. cancel_plst_mode
  1872.     MOVE.W    #1,mode                    editor mode
  1873.     BSR    clear_screen_topright
  1874.     BSR    toggle_plst_screen            remove plst screen
  1875.     BSR    goto_editor_mode
  1876.     NOT.W    plst_flag                clear plst flag
  1877.     MOVE.W    #13107,D0                wait 15ms
  1878. .wait    DBRA    D0,.wait
  1879.     RTS
  1880.  
  1881. set_plst_mode
  1882.     MOVE.W    #4,mode                else mode=plst
  1883.     NOT.W    plst_flag                set plst flag
  1884.     BSR    clear_screen_topright
  1885.     BSR    toggle_plst_screen            show plst screen
  1886.     BSR    refresh_plst_screen
  1887.     MOVE.W    #$F21A,D0                wait 70ms
  1888. .wait    DBRA    D0,.wait
  1889. return2    RTS
  1890.  
  1891. * GET INSTR FROM PLST
  1892. * entry    d1=file 0..11 from menu
  1893.  
  1894. plst_file_select
  1895.     LEA    plst_indices,A0        get index
  1896.     ASL.W    #2,D1
  1897.     MOVE.L    0(A0,D1.W),D1
  1898.     BMI.S    .skip
  1899.     DIVU    #in_size,D1        /size+1=entry no.
  1900.     ADDQ.W    #1,D1
  1901.     MOVE.W    D1,plst_entry_no
  1902.     BSR    get_plst_file
  1903. .skip    RTS
  1904.  
  1905. mountlist_getdrive
  1906.     CLR.L    FileInfoBlock+8        clear name
  1907.     CLR.L    FileInfoBlock+12
  1908.     CLR.L    FileInfoBlock+16
  1909.     MOVE.L    DOSbase,A6
  1910.     MOVE.L    A4,D1
  1911.     MOVEQ    #-2,D2
  1912.     JSR    _LVOLock(A6)        lock file
  1913.     MOVE.L    D0,lock_ptr
  1914.     BEQ.S    .error
  1915.     MOVE.L    lock_ptr,D1
  1916.     MOVE.L    #FileInfoBlock,D2    get info
  1917.     JSR    _LVOExamine(A6)
  1918.     TST.L    D0
  1919.     BEQ.S    .error
  1920.     MOVE.L    lock_ptr,D1
  1921.     JSR    _LVOUnLock(A6)
  1922.     MOVEQ    #-1,D0
  1923.     RTS
  1924. .error    MOVEQ    #-1,D0
  1925.     RTS
  1926.  
  1927. DF0_msg    dc.b    'DF0:',0
  1928.     even
  1929. DF1_msg    dc.b    'DF1:',0
  1930.     even
  1931. DF2_msg    dc.b    'DF2:',0
  1932.     even
  1933.  
  1934. mountlist_nodisk
  1935.     MOVEQ    #-1,D0
  1936.     RTS
  1937.  
  1938. mountlist_getname
  1939.     MOVE.W    FileInfoBlock+8,D0    name
  1940.     BEQ.S    mountlist_nodisk    skip if no disk in drive
  1941.     MOVE.W    #'ST',D1        check for ST disk
  1942.     AND.W    #$1F1F,D0
  1943.     AND.W    #$1F1F,D1
  1944.     CMP.W    D0,D1
  1945.     BNE.S    .notst            if so then copy number
  1946.     MOVE.B    FileInfoBlock+11,3(A0)    to search disk
  1947.     MOVE.B    FileInfoBlock+12,4(A0)
  1948.     MOVEQ    #0,D0
  1949.     RTS
  1950. .notst    CLR.B    3(A0)            else cancel search disk
  1951.     CLR.B    4(A0)
  1952.     RTS
  1953.  
  1954. * MOUNTLIST
  1955.  
  1956. fn_mountlist
  1957.     MOVEQ    #0,D0            cancel search disks
  1958.     MOVE.B    D0,search1+3
  1959.     MOVE.B    D0,search1+4
  1960.     MOVE.B    D0,search2+3
  1961.     MOVE.B    D0,search2+4
  1962.     MOVE.B    D0,search3+3
  1963.     MOVE.B    D0,search3+4
  1964.     MOVE.W    #1,stop_request        disable auto_request for empty drives
  1965.     LEA    DF0_msg(PC),A4        check each drive and
  1966.     LEA    dir_buffer(PC),A5    mount any ST disks
  1967.     BSR    mountlist_getdrive
  1968.     LEA    search1(PC),A0
  1969.     BSR    mountlist_getname
  1970.     LEA    DF1_msg(PC),A4
  1971.     LEA    dir_buffer(PC),A5
  1972.     BSR    mountlist_getdrive
  1973.     LEA    search2(PC),A0
  1974.     BSR    mountlist_getname
  1975.     LEA    DF2_msg(PC),A4
  1976.     LEA    dir_buffer(PC),A5
  1977.     BSR    mountlist_getdrive
  1978.     LEA    search3(PC),A0
  1979.     BSR    mountlist_getname
  1980.     CLR.W    stop_request        enable auto_request
  1981.     BSR    plst_scan_search
  1982.     BSR    refresh_plst_screen
  1983.     RTS
  1984.  
  1985. alter_search1
  1986.     LEA    search1+3,A6
  1987.     MOVE.W    #$9C,input_cursor_x
  1988.     BRA.S    alter_search_disk
  1989. alter_search2
  1990.     LEA    search2+3,A6
  1991.     MOVE.W    #$CC,input_cursor_x
  1992.     BRA.S    alter_search_disk
  1993. alter_search3
  1994.     LEA    search3+3,A6
  1995.     MOVE.W    #$FC,input_cursor_x
  1996. alter_search_disk
  1997.     CLR.B    (A6)            cancel name, ST-__
  1998.     CLR.B    1(A6)
  1999.     BSR    save_arrow_colours
  2000.     BSR    arrow_is_magenta
  2001.     BSR    print_plst_search_disks
  2002.     MOVE.W    #$14,input_cursor_y
  2003.     BSR    set_input_cursor
  2004.     BSR    wait_number_or_enter    if enter then clear & exit
  2005.     CMPI.B    #$44,D1
  2006.     BEQ.S    .abort
  2007.     ADD.B    #'0',D1
  2008.     MOVE.B    D1,(A6)
  2009.     ADDQ.W    #8,input_cursor_x
  2010.     BSR    print_plst_search_disks
  2011.     BSR    set_input_cursor
  2012.     BSR    wait_number_or_enter
  2013.     CMPI.B    #$44,D1
  2014.     BEQ.S    .abort
  2015.     ADD.B    #'0',D1
  2016.     MOVE.B    D1,1(A6)
  2017.     BSR    plst_scan_search
  2018.     BSR    refresh_plst_screen
  2019.     CLR.W    input_cursor_x
  2020.     MOVE.W    #$10E,input_cursor_y
  2021.     BSR    set_input_cursor
  2022.     BRA    restore_arrow_colours
  2023. .abort    CLR.B    (A6)
  2024.     CLR.B    1(A6)
  2025.     BSR    restore_arrow_colours
  2026.     CLR.W    input_cursor_x
  2027.     MOVE.W    #$10E,input_cursor_y
  2028.     BSR    set_input_cursor
  2029.     BSR    plst_scan_search
  2030.     BRA    refresh_plst_screen
  2031.  
  2032. * exit    d1=0..9 : number key
  2033. *       $44  : ENTER/RIGHT BUTTON
  2034.  
  2035. wait_number_or_enter
  2036.     CLR.B    key_code        clear key
  2037. .wait    BTST    #2,_custom+potinp    if right button then return ENTER
  2038.     BEQ.S    .enter
  2039.     TST.B    key_code        loop if key = '
  2040.     BEQ.S    .wait
  2041.     MOVE.B    key_code,D1        if key = ENTER then return
  2042.     CMPI.B    #$44,D1
  2043.     BEQ    .key
  2044.     CMPI.B    #10,D1            if key = '0'..'9' then
  2045.     BHI.S    .wait                return 0..9
  2046.     BNE.S    .key
  2047.     CLR.B    D1
  2048. .key    CLR.B    key_code
  2049.     RTS
  2050. .enter    MOVE.B    #$44,D1
  2051.     RTS
  2052.  
  2053. scroll_plst_up
  2054.     MOVE.W    plst_cursor,D0
  2055.     MOVE.W    D0,D2
  2056.     ADD.W    alter_dir,D0
  2057.     TST.W    key_lshift
  2058.     BNE.S    .fast
  2059.     BTST    #2,_custom+potinp
  2060.     BNE.S    .slow
  2061. .fast    SUB.W    #9,D0
  2062. .slow    TST.W    D0
  2063.     BPL.S    scroll_plst_update
  2064.     CLR.W    D0
  2065.     BRA.S    scroll_plst_update
  2066.  
  2067. scroll_plst
  2068.     TST.W    alter_dir
  2069.     BMI.S    scroll_plst_up
  2070.     MOVE.W    plst_cursor,D0
  2071.     MOVE.W    D0,D2
  2072.     ADD.W    alter_dir,D0
  2073.     TST.W    key_lshift
  2074.     BNE.S    .fast
  2075.     BTST    #2,_custom+potinp
  2076.     BNE.S    .slow
  2077. .fast    ADD.W    #9,D0
  2078. .slow    MOVE.W    plst_active_entries,D1
  2079.     SUB.W    #12,D1
  2080.     CMP.W    D0,D1
  2081.     BGE.S    scroll_plst_update
  2082.     MOVE.W    D1,D0
  2083.     NOP    
  2084. scroll_plst_update
  2085.     BSR.S    .getfirst
  2086.     BRA    refresh_plst_screen
  2087. .getfirst
  2088.     MOVE.W    plst_cursor,D1
  2089.     MOVE.W    D0,plst_cursor
  2090.     CMP.W    D0,D1
  2091.     BEQ    return
  2092.     TST.W    D0
  2093.     BEQ.S    .clear
  2094.     SUBQ.W    #1,D0
  2095.     MOVE.L    plst_ptr,A0
  2096.     MOVEQ    #0,D6
  2097. .loop    CMP.W    #'ST',0(A0,D6.L)
  2098.     BEQ.S    .active
  2099.     ADD.L    #in_size,D6
  2100.     BRA.S    .loop
  2101. .active    ADD.L    #in_size,D6
  2102.     DBRA    D0,.loop
  2103.     MOVE.L    D6,plst_indices
  2104.     RTS
  2105. .clear    CLR.L    plst_indices
  2106.     RTS
  2107.  
  2108. search1    dc.b    'ST-',0,0,':'        plst search disks
  2109. search2    dc.b    'ST-',0,0,':'
  2110. search3    dc.b    'ST-',0,0,':'
  2111.  
  2112. plst_scan_all_on
  2113.     MOVE.W    #'ST',(A0)        if no active search disks then
  2114.     ADD.L    #in_size,A0            flag all entries active
  2115.     DBRA    D7,plst_scan_all_on
  2116.     MOVE.W    plst_entries,plst_active_entries    full plst
  2117.     MOVE.L    plst_size,plst_active_size
  2118.     CLR.W    plst_cursor
  2119.     CLR.L    plst_indices
  2120.     RTS
  2121.  
  2122. plst_scan_all_off
  2123.     CLR.W    plst_active_entries    clear plst
  2124.     CLR.L    plst_active_size
  2125.     CLR.W    plst_cursor
  2126.     CLR.L    plst_indices
  2127.     RTS
  2128.  
  2129. plst_scan_search
  2130.     TST.L    plst_ptr        skip if on plst
  2131.     BEQ.S    plst_scan_all_off
  2132.     MOVE.L    plst_ptr,A0        else scan plst
  2133.     MOVE.W    plst_entries,D7
  2134.     SUBQ.W    #1,D7
  2135.     TST.B    search1+3        if any active search disks then
  2136.     BNE.S    .look
  2137.     TST.B    search2+3
  2138.     BNE.S    .look
  2139.     TST.B    search3+3
  2140.     BEQ.S    plst_scan_all_on
  2141. .look    MOVE.L    search1+2,A3
  2142.     MOVE.L    search2+2,A4
  2143.     MOVE.L    search3+2,A5
  2144.     MOVEQ    #0,D6            d6=count of active entries
  2145. .loop    MOVE.W    #'st',(A0)        inactive = st....
  2146.     MOVE.L    2(A0),D0
  2147.     CMP.L    A3,D0            if disk name match then
  2148.     BNE.S    .try2
  2149.     MOVE.W    #'ST',(A0)            set active = ST....
  2150.     ADDQ.W    #1,D6
  2151.     BRA.S    .next
  2152. .try2    CMP.L    A4,D0
  2153.     BNE.S    .try3
  2154.     MOVE.W    #'ST',(A0)
  2155.     ADDQ.W    #1,D6
  2156.     BRA.S    .next
  2157. .try3    CMP.L    A5,D0
  2158.     BNE.S    .next
  2159.     MOVE.W    #'ST',(A0)
  2160.     ADDQ.W    #1,D6
  2161. .next    ADD.L    #in_size,A0
  2162.     DBRA    D7,.loop
  2163.     MOVE.W    D6,plst_active_entries
  2164.     MULU    #in_size,D6
  2165.     MOVE.L    D6,plst_active_size
  2166.     CLR.W    plst_cursor
  2167.     CLR.L    plst_indices
  2168.     RTS
  2169.  
  2170. print_plst_search_disks
  2171.     TST.W    plst_flag        if plst flag set then
  2172.     BEQ    return2
  2173.     MOVE.L    #15*40+16,char_offset        print search disks
  2174.     MOVE.L    #5,string_size
  2175.     MOVE.L    #search1,string_addr
  2176.     BSR    print_string
  2177.     ADDQ.L    #1,char_offset
  2178.     MOVE.L    #search2,string_addr
  2179.     BSR    print_string
  2180.     ADDQ.L    #1,char_offset
  2181.     MOVE.L    #search3,string_addr
  2182.     BRA    print_string
  2183.  
  2184. refresh_plst_screen
  2185.     TST.W    plst_flag        if plst flag set then
  2186.     BEQ    return2
  2187.     MOVE.W    plst_active_entries,word_to_print
  2188.     MOVE.L    #4*40+25,char_offset        no. of active samples in plst
  2189.     BSR    print_dec4
  2190.     BSR    print_plst_search_disks        print search disks
  2191.     TST.L    plst_ptr            skip if no plst loaded
  2192.     BEQ    return2                print sample names in list
  2193.     MOVE.L    plst_indices,D6            d6=1st sample index
  2194.     MOVE.L    plst_ptr,A6            a6=plst
  2195.     MOVE.L    #24*40+16,A5            a5=char_offset
  2196.     LEA    plst_indices,A4            a4=indices of shown samples
  2197.     MOVEQ    #12-1,D7            show up to 12 names
  2198. .names    CMP.W    #'ST',0(A6,D6.L)        if name=ST... then
  2199.     BNE.S    .notst
  2200.     MOVE.L    D6,(A4)+            store sample index
  2201.     MOVE.L    A5,char_offset            print sample name
  2202.     MOVE.L    #19,string_size
  2203.     LEA    0(A6,D6.L),A3
  2204.     ADDQ.L    #3,A3
  2205.     MOVE.L    A3,string_addr
  2206.     BSR    print_string_spc
  2207.     MOVE.W    22(A6,D6.L),word_to_print    print size in bytes
  2208.     ASL    word_to_print
  2209.     BSR    print_hex4
  2210.     ADD.L    #in_size,D6            next index
  2211.     CMP.L    plst_size,D6
  2212.     BGT.S    .nomore
  2213.     ADD.L    #6*40,A5
  2214.     DBRA    D7,.names
  2215.     RTS
  2216. .notst    ADD.L    #in_size,D6            if name<>ST.. then
  2217.     CMP.L    plst_size,D6                skip over
  2218.     BGT.S    .nomore
  2219.     BRA.S    .names
  2220. .nomore    MOVE.L    #-1,(A4)+            remaining indices empty
  2221.     MOVE.L    A5,char_offset
  2222.     MOVE.L    #23,string_size
  2223.     MOVE.L    #null_string,string_addr    print spaces
  2224.     BSR    print_string_spc
  2225.     ADD.L    #6*40,A5
  2226.     DBRA    D7,.nomore
  2227.     RTS
  2228.  
  2229. toggle_plst_screen
  2230.     LEA    main_screen+40+15,A0
  2231.     LEA    plst_screen,A1
  2232.     MOVEQ    #99-1,D0
  2233. .row    MOVEQ    #25-1,D1
  2234. .column    MOVE.B    10240(A0),D2
  2235.     MOVE.B    99*26(A1),10240(A0)
  2236.     MOVE.B    D2,99*26(A1)
  2237.     MOVE.B    (A0),D2
  2238.     MOVE.B    (A1),(A0)+
  2239.     MOVE.B    D2,(A1)+
  2240.     DBRA    D1,.column
  2241.     ADD.L    #40-25,A0
  2242.     ADDQ.L    #1,A1
  2243.     DBRA    D0,.row
  2244.     RTS
  2245.  
  2246. plst_flash_error
  2247.     BSR    refresh_plst_screen
  2248.     BRA    arrow_flash_red
  2249.  
  2250. * LOAD PLST
  2251.  
  2252. fn_load_plst
  2253.     MOVE.W    #145,D0
  2254.     BSR    wait_for_vpos
  2255.     MOVE.L    screen_ptr,A1        clear filenames window
  2256.     ADD.L    #23*40+15,A1
  2257.     MOVEQ    #75-1,D6
  2258. .row    MOVEQ    #25-1,D5
  2259. .column    CLR.B    (A1)+
  2260.     DBRA    D5,.column
  2261.     ADD.L    #40-25,A1
  2262.     DBRA    D6,.row
  2263.     BSR    check_are_you_sure    make sure
  2264.     TST.L    D0
  2265.     BNE.S    plst_flash_error
  2266.     CLR.B    search1+3        cancel search disks
  2267.     CLR.B    search1+4
  2268.     CLR.B    search2+3
  2269.     CLR.B    search2+4
  2270.     CLR.B    search3+3
  2271.     CLR.B    search3+4
  2272.     BSR    save_arrow_colours
  2273.     BSR    arrow_is_green
  2274.     MOVE.L    plst_ptr,A1        free old list memory
  2275.     BEQ.S    .free
  2276.     MOVE.L    plst_size,D0
  2277.     MOVE.L    4.w,a6
  2278.     JSR    _LVOFreeMem(A6)
  2279.     CLR.L    plst_ptr
  2280.     CLR.L    plst_size
  2281.     CLR.W    plst_entries
  2282.     BSR    clear_screen_topright
  2283. .free    MOVE.L    DOSbase,A6        check for plst
  2284.     MOVE.L    #plst_name,D1
  2285.     MOVEQ    #-2,D2
  2286.     JSR    _LVOLock(A6)
  2287.     MOVE.L    D0,D7
  2288.     BEQ    .error
  2289.     MOVE.L    D7,D1
  2290.     MOVE.L    #FileInfoBlock,D2
  2291.     JSR    _LVOExamine(A6)
  2292.     TST.L    D0
  2293.     BEQ    .error
  2294.     MOVE.L    D7,D1
  2295.     JSR    _LVOUnLock(A6)
  2296.     LEA    FileInfoBlock,A0
  2297.     MOVE.L    124(A0),D0        size
  2298.     MOVE.L    D0,plst_size
  2299.     DIVU    #in_size,D0
  2300.     MOVE.W    D0,plst_entries        no. of filenames
  2301.     MOVE.L    plst_size,D0
  2302.     CLR.L    plst_ptr
  2303.     MOVEQ    #0,D1
  2304.     MOVE.L    4.w,a6
  2305.     JSR    _LVOAllocMem(A6)    allocate
  2306.     BEQ.S    .error
  2307.     MOVE.L    D0,plst_ptr
  2308.     MOVE.L    #plst_name,D1
  2309.     MOVE.L    #1005,D2        read
  2310.     MOVE.L    DOSbase,A6
  2311.     JSR    _LVOOpen(A6)
  2312.     MOVE.L    D0,D7
  2313.     BEQ.S    .error
  2314.     MOVE.L    D7,D1
  2315.     MOVE.L    plst_ptr,D2
  2316.     MOVE.L    plst_size,D3
  2317.     JSR    _LVORead(A6)
  2318.     CMP.L    plst_size,D0
  2319.     BNE    .error
  2320.     MOVE.L    D7,D1
  2321.     JSR    _LVOClose(A6)
  2322.     MOVE.W    #1,plst_entry_no
  2323.     BSR    refresh_song_parameters
  2324.     BSR    plst_scan_search
  2325.     BSR    refresh_plst_screen
  2326.     BRA    restore_arrow_colours
  2327. .error    BSR    arrow_flash_red
  2328.     BSR    plst_scan_search
  2329.     BSR    refresh_plst_screen
  2330.     BRA    restore_arrow_colours
  2331.  
  2332. check_f6_to_f10
  2333.     TST.L    play_mode
  2334.     BEQ.S    .f6
  2335.     RTS
  2336. .f6    CMP.B    #$55,key_code        if key = F6 then
  2337.     BNE.S    .f7
  2338.     CLR.W    edit_cursor_y            goto top
  2339.     BSR    set_edit_scroller
  2340.     CLR.B    key_code
  2341.     RTS
  2342. .f7    CMP.B    #$56,key_code        if key = F7 then
  2343.     BNE.S    .f8
  2344.     MOVE.W    #16,edit_cursor_y        goto pos 16
  2345.     BSR    set_edit_scroller
  2346.     CLR.B    key_code
  2347.     RTS
  2348. .f8    CMP.B    #$57,key_code        if key = F8 then
  2349.     BNE.S    .f9
  2350.     MOVE.W    #32,edit_cursor_y        goto pos 32
  2351.     BSR    set_edit_scroller
  2352.     CLR.B    key_code
  2353.     RTS
  2354. .f9    CMP.B    #$58,key_code        if key = F9 then
  2355.     BNE.S    .f10
  2356.     MOVE.W    #48,edit_cursor_y        goto pos 48
  2357.     BSR    set_edit_scroller
  2358.     CLR.B    key_code
  2359.     RTS
  2360. .f10    CMP.B    #$59,key_code        if key = F10 then
  2361.     BNE.S    .skip
  2362.     MOVE.W    #63,edit_cursor_y        goto pos 63
  2363.     BSR    set_edit_scroller
  2364.     CLR.B    key_code
  2365. .skip    RTS
  2366.  
  2367. check_cut_paste
  2368.     TST.W    key_lshift
  2369.     BNE.S    .voice4
  2370.     MOVEQ    #0,D0
  2371.     MOVE.L    D0,A0
  2372.     TST.W    key_lalt
  2373.     BNE.S    .got
  2374.     RTS
  2375. .voice4    CMP.W    #18,edit_cursor_x
  2376.     BNE.S    .voice3
  2377.     MOVEQ    #12,D0
  2378.     MOVE.L    D0,A0
  2379.     BRA.S    .got
  2380. .voice3    CMP.W    #12,edit_cursor_x
  2381.     BNE.S    .voice2
  2382.     MOVEQ    #8,D0
  2383.     MOVE.L    D0,A0
  2384.     BRA.S    .got
  2385. .voice2    CMP.W    #6,edit_cursor_x
  2386.     BNE.S    .voice1
  2387.     MOVEQ    #4,D0
  2388.     MOVE.L    D0,A0
  2389.     BRA.S    .got
  2390. .voice1    TST.W    edit_cursor_x
  2391.     BNE.S    .skip
  2392.     MOVEQ    #0,D0
  2393.     MOVE.L    D0,A0
  2394.     BRA.S    .got
  2395. .skip    RTS
  2396. .got    ADD.L    song_file_ptr,A0    a0=address of voice in pattern
  2397.     ADD.L    #sf_patterns,A0
  2398.     MOVE.L    pattern_no,D0
  2399.     LSL.L    #8,D0
  2400.     LSL.L    #2,D0
  2401.     ADD.L    D0,A0
  2402.     TST.W    key_lalt
  2403.     BNE.S    .whole
  2404.     CMP.B    #$52,key_code        F3
  2405.     BEQ    cut_voice
  2406.     CMP.B    #$53,key_code        F4
  2407.     BEQ    copy_voice
  2408.     CMP.B    #$54,key_code        F5
  2409.     BEQ    paste_voice
  2410.     RTS
  2411. .whole    CMP.B    #$52,key_code        F3
  2412.     BEQ.S    cut_whole
  2413.     CMP.B    #$53,key_code        F4
  2414.     BEQ.S    copy_whole
  2415.     CMP.B    #$54,key_code        F5
  2416.     BEQ.S    paste_whole
  2417.     RTS
  2418.  
  2419. cut_whole
  2420.     LEA    cutwhole_buffer,A1
  2421.     CLR.W    D0
  2422. .loop    MOVE.L    0(A0,D0.W),(A1)+
  2423.     CLR.L    0(A0,D0.W)
  2424.     ADDQ.W    #4,D0
  2425.     CMPI.W    #1024,D0
  2426.     BNE.S    .loop
  2427.     CLR.B    key_code
  2428.     BRA    refresh_pattern_display
  2429.  
  2430. copy_whole
  2431.     LEA    cutwhole_buffer,A1
  2432.     CLR.W    D0
  2433. .loop    MOVE.L    0(A0,D0.W),(A1)+
  2434.     ADDQ.W    #4,D0
  2435.     CMPI.W    #1024,D0
  2436.     BNE.S    .loop
  2437.     CLR.B    key_code
  2438.     RTS
  2439.  
  2440. paste_whole
  2441.     LEA    cutwhole_buffer,A1
  2442.     CLR.W    D0
  2443. .loop    MOVE.L    (A1)+,0(A0,D0.W)
  2444.     ADDQ.W    #4,D0
  2445.     CMPI.W    #1024,D0
  2446.     BNE.S    .loop
  2447.     CLR.B    key_code
  2448.     BRA    refresh_pattern_display
  2449.  
  2450. cut_voice
  2451.     LEA    cutvoice_buffer,A1
  2452.     CLR.W    D0
  2453. .loop    MOVE.L    0(A0,D0.W),(A1)+
  2454.     CLR.L    0(A0,D0.W)
  2455.     ADD.W    #16,D0
  2456.     CMPI.W    #1024,D0
  2457.     BNE.S    .loop
  2458.     CLR.B    key_code
  2459.     BRA    refresh_pattern_display
  2460.  
  2461. copy_voice
  2462.     LEA    cutvoice_buffer,A1
  2463.     CLR.W    D0
  2464. .loop    MOVE.L    0(A0,D0.W),(A1)+
  2465.     ADD.W    #16,D0
  2466.     CMPI.W    #1024,D0
  2467.     BNE.S    .loop
  2468.     CLR.B    key_code
  2469.     RTS
  2470.  
  2471. paste_voice
  2472.     LEA    cutvoice_buffer,A1
  2473.     CLR.W    D0
  2474. .loop    MOVE.L    (A1)+,0(A0,D0.W)
  2475.     ADD.W    #16,D0
  2476.     CMPI.W    #1024,D0
  2477.     BNE.S    .loop
  2478.     CLR.B    key_code
  2479.     BRA    refresh_pattern_display
  2480.  
  2481. check_octave_keys
  2482.     CMP.B    #$50,key_code        if key = F1 then octave 1-2
  2483.     BEQ.S    .oct12
  2484.     CMP.B    #$51,key_code        if key = F2 then octave 2-3
  2485.     BEQ.S    .oct23
  2486.     RTS
  2487. .oct12    MOVE.L    #oct1_2_periods,octave_periods
  2488.     MOVE.L    #oct1_2_names,octave_names
  2489.     CLR.B    key_code
  2490.     RTS
  2491. .oct23    MOVE.L    #oct2_3_periods,octave_periods
  2492.     MOVE.L    #oct2_3_names,octave_names
  2493.     CLR.B    key_code
  2494.     RTS
  2495.  
  2496. set_arrow_position
  2497.     MOVE.W    mouse_x,D0
  2498.     ADDQ.W    #3,D0
  2499.     MOVE.W    mouse_y,D1
  2500.     MOVEQ    #17,D2
  2501.     MOVE.L    arrow_spr_ptr,A0
  2502.     BRA    position_sprite
  2503.  
  2504. edit_hex_parameters
  2505.     CMP.L    #'edit',edit_mode
  2506.     BEQ.S    .edit
  2507.     RTS
  2508. .edit    LEA    hex_keys,A0        allow 0..9A..F only
  2509.     MOVEQ    #0,D0
  2510.     MOVEQ    #0,D1
  2511.     MOVE.B    key_code,D0
  2512. .find    CMP.B    (A0)+,D0
  2513.     BEQ.S    .pos1
  2514.     ADDQ.B    #1,D1
  2515.     CMPI.B    #$10,D1
  2516.     BEQ.S    .skip
  2517.     BRA.S    .find
  2518. .skip    RTS
  2519. .pos1    CMP.W    #1,edit_cursor_x
  2520.     BNE.S    .pos2
  2521.     CMPI.W    #1,D1
  2522.     BGT.S    .skip
  2523.     MOVE.L    #$FFF,D2
  2524.     CLR.W    edh_index
  2525.     LSL.W    #4,D1
  2526.     LSL.W    #8,D1
  2527.     BRA    .done
  2528. .pos2    CMP.W    #2,edit_cursor_x
  2529.     BNE.S    .pos3
  2530.     MOVE.L    #$FFF,D2
  2531.     MOVE.W    #2,edh_index
  2532.     LSL.W    #4,D1
  2533.     LSL.W    #8,D1
  2534.     BRA    .done
  2535. .pos3    CMP.W    #3,edit_cursor_x
  2536.     BNE.S    .pos4
  2537.     MOVE.L    #$F0FF,D2
  2538.     MOVE.W    #2,edh_index
  2539.     LSL.W    #8,D1
  2540.     BRA    .done
  2541. .pos4    CMP.W    #4,edit_cursor_x
  2542.     BNE.S    .pos5
  2543.     MOVE.L    #$FF0F,D2
  2544.     MOVE.W    #2,edh_index
  2545.     LSL.W    #4,D1
  2546.     BRA    .done
  2547. .pos5    CMP.W    #5,edit_cursor_x
  2548.     BNE.S    .pos7
  2549.     MOVE.L    #$FFF0,D2
  2550.     MOVE.W    #2,edh_index
  2551.     BRA    .done
  2552. .pos7    CMP.W    #7,edit_cursor_x
  2553.     BNE.S    .pos8
  2554.     CMPI.W    #1,D1
  2555.     BGT    .skip
  2556.     MOVE.L    #$FFF,D2
  2557.     MOVE.W    #4,edh_index
  2558.     LSL.W    #4,D1
  2559.     LSL.W    #8,D1
  2560.     BRA    .done
  2561. .pos8    CMP.W    #8,edit_cursor_x
  2562.     BNE.S    .pos9
  2563.     MOVE.L    #$FFF,D2
  2564.     MOVE.W    #6,edh_index
  2565.     LSL.W    #4,D1
  2566.     LSL.W    #8,D1
  2567.     BRA    .done
  2568. .pos9    CMP.W    #9,edit_cursor_x
  2569.     BNE.S    .pos10
  2570.     MOVE.L    #$F0FF,D2
  2571.     MOVE.W    #6,edh_index
  2572.     LSL.W    #8,D1
  2573.     BRA    .done
  2574. .pos10    CMP.W    #10,edit_cursor_x
  2575.     BNE.S    .pos11
  2576.     MOVE.L    #$FF0F,D2
  2577.     MOVE.W    #6,edh_index
  2578.     LSL.W    #4,D1
  2579.     BRA    .done
  2580. .pos11    CMP.W    #11,edit_cursor_x
  2581.     BNE.S    .pos13
  2582.     MOVE.L    #$FFF0,D2
  2583.     MOVE.W    #6,edh_index
  2584.     BRA    .done
  2585. .pos13    CMP.W    #13,edit_cursor_x
  2586.     BNE.S    .pos14
  2587.     CMPI.W    #1,D1
  2588.     BGT    .skip
  2589.     MOVE.L    #$FFF,D2
  2590.     MOVE.W    #8,edh_index
  2591.     LSL.W    #4,D1
  2592.     LSL.W    #8,D1
  2593.     BRA    .done
  2594. .pos14    CMP.W    #14,edit_cursor_x
  2595.     BNE.S    .pos15
  2596.     MOVE.L    #$FFF,D2
  2597.     MOVE.W    #10,edh_index
  2598.     LSL.W    #4,D1
  2599.     LSL.W    #8,D1
  2600.     BRA    .done
  2601. .pos15    CMP.W    #15,edit_cursor_x
  2602.     BNE.S    .pos16
  2603.     MOVE.L    #$F0FF,D2
  2604.     MOVE.W    #10,edh_index
  2605.     LSL.W    #8,D1
  2606.     BRA    .done
  2607. .pos16    CMP.W    #16,edit_cursor_x
  2608.     BNE.S    .pos17
  2609.     MOVE.L    #$FF0F,D2
  2610.     MOVE.W    #10,edh_index
  2611.     LSL.W    #4,D1
  2612.     BRA    .done
  2613. .pos17    CMP.W    #17,edit_cursor_x
  2614.     BNE.S    .pos19
  2615.     MOVE.L    #$FFF0,D2
  2616.     MOVE.W    #10,edh_index
  2617.     BRA    .done
  2618. .pos19    CMP.W    #19,edit_cursor_x
  2619.     BNE.S    .pos20
  2620.     CMPI.W    #1,D1
  2621.     BGT    .skip
  2622.     MOVE.L    #$FFF,D2
  2623.     MOVE.W    #12,edh_index
  2624.     LSL.W    #4,D1
  2625.     LSL.W    #8,D1
  2626.     BRA.S    .done
  2627. .pos20    CMP.W    #20,edit_cursor_x
  2628.     BNE.S    .pos21
  2629.     MOVE.L    #$FFF,D2
  2630.     MOVE.W    #14,edh_index
  2631.     LSL.W    #4,D1
  2632.     LSL.W    #8,D1
  2633.     BRA.S    .done
  2634. .pos21    CMP.W    #21,edit_cursor_x
  2635.     BNE.S    .pos22
  2636.     MOVE.L    #$F0FF,D2
  2637.     MOVE.W    #14,edh_index
  2638.     LSL.W    #8,D1
  2639.     BRA.S    .done
  2640. .pos22    CMP.W    #22,edit_cursor_x
  2641.     BNE.S    .pos23
  2642.     MOVE.L    #$FF0F,D2
  2643.     MOVE.W    #14,edh_index
  2644.     LSL.W    #4,D1
  2645.     BRA.S    .done
  2646. .pos23    MOVE.L    #$FFF0,D2
  2647.     MOVE.W    #14,edh_index
  2648. .done    MOVE.L    song_file_ptr,A0    index pattern
  2649.     ADD.L    #sf_patterns,A0
  2650.     MOVE.L    pattern_no,D0
  2651.     LSL.L    #8,D0
  2652.     LSL.L    #2,D0
  2653.     ADD.L    D0,A0
  2654.     MOVEQ    #0,D0
  2655.     MOVE.W    edit_cursor_y,D0
  2656.     LSL.W    #4,D0
  2657.     EXT.L    D0
  2658.     ADD.L    D0,A0
  2659.     ADD.W    edh_index,A0        + parameter index
  2660.     AND.W    D2,(A0)            mask old value
  2661.     ADD.W    D1,(A0)            add new value
  2662.     MOVE.W    (A0),word_to_print
  2663.     MOVEQ    #0,D0
  2664.     MOVE.W    edit_cursor_y,D0
  2665.     MULU    #$118,D0
  2666.     MOVE.W    edit_cursor_x,D1
  2667.     DIVU    #6,D1
  2668.     MULU    #9,D1
  2669.     ADD.L    D1,D0
  2670.     ADD.L    #$1D68,D0
  2671.     MOVE.L    D0,char_offset
  2672.     TST.W    edh_index        print value
  2673.     BEQ.S    .print1
  2674.     CMP.W    #4,edh_index
  2675.     BEQ.S    .print1
  2676.     CMP.W    #8,edh_index
  2677.     BEQ.S    .print1
  2678.     CMP.W    #12,edh_index
  2679.     BEQ.S    .print1
  2680.     BSR    print_hex4
  2681. .exit    BSR    edit_cursor_down
  2682.     CLR.B    key_code
  2683.     RTS
  2684. .print1    SUBQ.L    #1,char_offset
  2685.     MOVE.L    #1,string_size
  2686.     MOVEQ    #0,D0
  2687.     MOVE.W    (A0),D0
  2688.     AND.W    #$F000,D0
  2689.     LSR.W    #4,D0
  2690.     LSR.W    #7,D0
  2691.     ADD.L    #hex2ascii+1,D0
  2692.     MOVE.L    D0,string_addr
  2693.     BSR    print_string
  2694.     BRA.S    .exit
  2695.  
  2696. check_edit_pattern
  2697.     TST.B    key_code
  2698.     BNE.S    .key
  2699.     RTS
  2700. .key    MOVE.W    edit_cursor_x,D0    if position 0,6,12,18 then
  2701.     BEQ.S    .piano                piano key else hex key
  2702.     CMPI.W    #6,D0
  2703.     BEQ.S    .piano
  2704.     CMPI.W    #12,D0
  2705.     BEQ.S    .piano
  2706.     CMPI.W    #18,D0
  2707.     BEQ.S    .piano
  2708.     CMP.L    #'edit',edit_mode
  2709.     BEQ    edit_hex_parameters
  2710.     RTS
  2711. .piano    MOVEQ    #0,D1
  2712.     LEA    piano_keys,A0
  2713.     MOVE.B    key_code,D1
  2714.     MOVEQ    #0,D0
  2715. .find    MOVE.L    D0,D4            check if piano key
  2716.     CMP.B    0(A0,D0.W),D1
  2717.     BEQ.S    .found
  2718.     ADDQ.B    #1,D0
  2719.     CMPI.B    #39,D0
  2720.     BNE.S    .find
  2721.     RTS
  2722. .found    CLR.B    key_code        cancel key
  2723.     ASL.W    #1,D0
  2724.     ASL.W    #1,D4
  2725.     MOVEQ    #0,D3
  2726.     MOVE.L    octave_periods,A1    convert to period
  2727.     MOVE.W    0(A1,D0.L),D3
  2728.     MOVE.W    D3,keyplay_period
  2729.     TST.L    edit_mode
  2730.     BEQ    .play
  2731.     MOVE.L    song_file_ptr,A0    if edit mode then
  2732.     ADD.L    #sf_patterns,A0            insert into pattern
  2733.     MOVE.L    pattern_no,D0
  2734.     LSL.L    #8,D0
  2735.     LSL.L    #2,D0
  2736.     ADD.L    D0,A0
  2737.     MOVEQ    #0,D0
  2738.     MOVE.W    edit_cursor_y,D0
  2739.     BSR    quantize
  2740.     LSL.W    #4,D0
  2741.     EXT.L    D0
  2742.     ADD.L    D0,A0
  2743.     MOVE.W    edit_cursor_x,D0
  2744.     DIVU    #6,D0
  2745.     LSL.W    #2,D0
  2746.     EXT.L    D0
  2747.     ADD.L    D0,A0
  2748.     MOVE.W    D3,(A0)
  2749.     TST.W    keyplay_period        if no note then clear instr no.
  2750.     BEQ.S    .nonote            else set
  2751.     MOVEQ    #0,D0
  2752.     MOVE.W    current_instr,D0
  2753.     LSL.W    #4,D0
  2754.     AND.B    #15,2(A0)
  2755.     ADD.B    D0,2(A0)
  2756.     LSL.W    #4,D0
  2757.     AND.W    #$F000,D0
  2758.     OR.W    D0,(A0)
  2759.     BRA.S    .print
  2760. .nonote    AND.W    #$FFF,2(A0)
  2761. .print    MOVE.W    2(A0),temp        print note
  2762.     MOVE.L    octave_names,A0
  2763.     LSL.W    #1,D4
  2764.     EXT.L    D4
  2765.     ADD.L    D4,A0
  2766.     MOVE.L    A0,string_addr
  2767.     MOVE.L    #3,string_size
  2768.     MOVEQ    #0,D0
  2769.     MOVE.W    edit_cursor_y,D0
  2770.     BSR    quantize
  2771.     MULU    #$118,D0
  2772.     MOVEQ    #0,D1
  2773.     MOVE.W    edit_cursor_x,D1
  2774.     DIVU    #6,D1
  2775.     MULU    #9,D1
  2776.     ADD.L    D1,D0
  2777.     ADD.L    #$1D64,D0
  2778.     MOVE.L    D0,char_offset
  2779.     BSR    print_string
  2780.     BSR    print_hex_instr
  2781.     MOVE.W    temp,word_to_print
  2782.     BSR    print_hex4
  2783.     BSR    edit_cursor_down
  2784. .play    TST.W    quantize_flag        if note this time slot then play
  2785.     BNE.S    .exit
  2786.     TST.W    keyplay_period
  2787.     BNE.S    .voice4
  2788. .exit    RTS
  2789. .voice4    MOVE.L    #0,A5
  2790.     CMP.W    #18,edit_cursor_x
  2791.     BNE.S    .voice3
  2792.     LEA    _custom+aud3,A5
  2793.     LEA    audio_info_4,A4
  2794.     MOVE.W    #8,keyplay_channel
  2795.     BRA    play_editkey
  2796. .voice3    CMP.W    #12,edit_cursor_x
  2797.     BNE.S    .voice2
  2798.     LEA    _custom+aud2,A5
  2799.     LEA    audio_info_3,A4
  2800.     MOVE.W    #4,keyplay_channel
  2801.     BRA.S    play_editkey
  2802. .voice2    CMP.W    #6,edit_cursor_x
  2803.     BNE.S    .voice1
  2804.     LEA    _custom+aud1,A5
  2805.     LEA    audio_info_2,A4
  2806.     MOVE.W    #2,keyplay_channel
  2807.     BRA.S    play_editkey
  2808. .voice1    TST.W    edit_cursor_x
  2809.     BNE.S    .skip
  2810.     LEA    _custom+aud0,A5
  2811.     LEA    audio_info_1,A4
  2812.     MOVE.W    #1,keyplay_channel
  2813.     BRA.S    play_editkey
  2814. .skip    RTS
  2815.  
  2816. quantize
  2817.     TST.L    play_mode        if play mode then
  2818.     BEQ.S    .ok
  2819.     MOVE.L    tempo,D1            if note played over half-way
  2820.     ASR.L    #1,D1                thru a note duration then
  2821.     CMP.L    frame_count,D1            note in next slot, no sound
  2822.     BLE.S    .over
  2823. .ok    CLR.W    quantize_flag
  2824.     RTS
  2825. .over    ADDQ.W    #1,D0
  2826.     AND.W    #$3F,D0
  2827.     MOVE.W    #1,quantize_flag
  2828.     RTS
  2829.  
  2830. play_editkey
  2831.     LEA    instr_length,A6
  2832.     MOVE.W    instr_repeat-instr_length(A6),D0
  2833.     BNE.S    .rep
  2834.     MOVE.W    (A6),D0
  2835.     BRA.S    .norep
  2836. .rep    ADD.W    instr_replen-instr_length(A6),D0
  2837. .norep    MOVE.W    instr_volume-instr_length(A6),ac_vol(A5)
  2838.     MOVE.W    keyplay_period,$10(A4)
  2839.     CLR.B    $1B(A4)
  2840.     CLR.W    $18(A4)
  2841.     MOVE.W    keyplay_period,ac_per(A5)
  2842.     MOVE.W    keyplay_channel,D2
  2843.     MOVE.W    D2,_custom+dmacon
  2844.     MOVE.L    instr_addr-instr_length(A6),(A5)
  2845.     MOVE.W    D0,ac_len(A5)
  2846.     MOVEQ    #0,D1
  2847.     MOVE.W    instr_repeat-instr_length(A6),D1
  2848.     ASL.W    #1,D1
  2849.     ADD.L    instr_addr-instr_length(A6),D1
  2850.     MOVE.L    D1,10(A4)
  2851.     MOVE.W    instr_replen-instr_length(A6),14(A4)
  2852.     MOVE.W    keyplay_period,D0
  2853.     BSR    add_keyplay_to_spectrum
  2854.     MOVE.W    #$12C,D0
  2855. .wait    DBRA    D0,.wait
  2856.     MOVE.W    keyplay_channel,D0
  2857.     AND.W    onoff_states,D0
  2858.     OR.W    #$8000,D0
  2859.     MOVE.W    D0,_custom+dmacon
  2860.     MOVE.W    #$12C,D0
  2861. .wait2    DBRA    D0,.wait2
  2862.     LEA    instr_length,A6
  2863.     MOVE.L    D1,(A5)
  2864.     MOVE.W    instr_replen-instr_length(A6),ac_len(A5)
  2865.     CLR.W    keyplay_channel
  2866.     RTS
  2867.  
  2868. check_cursor_keys
  2869.     MOVE.B    key_code,D0
  2870.     CMPI.B    #$4E,D0
  2871.     BEQ    cursor_right
  2872.     CMPI.B    #$4F,D0
  2873.     BEQ    cursor_left
  2874.     CMPI.B    #$4C,D0
  2875.     BEQ.S    cursor_up
  2876.     CMPI.B    #$4D,D0
  2877.     BEQ    cursor_down
  2878.     CLR.W    cursor_rep_flag
  2879.     RTS
  2880.  
  2881. fscroll_up
  2882.     MOVE.W    #1,fscroll_pending    diskop scroll up/down
  2883.     RTS
  2884. fscroll_down
  2885.     MOVE.W    #2,fscroll_pending
  2886.     RTS
  2887. pscroll_up
  2888.     MOVE.W    #1,pscroll_pending    plst scroll up/down
  2889.     RTS
  2890. pscroll_down
  2891.     MOVE.W    #2,pscroll_pending
  2892.     RTS
  2893.  
  2894. cursor_up
  2895.     CMP.W    #3,mode            if diskops then scroll files
  2896.     BEQ.S    fscroll_up
  2897.     TST.W    plst_flag        if plst then scroll files
  2898.     BNE.S    pscroll_up
  2899.     TST.W    cursor_rep_flag        if already pressed then
  2900.     BEQ.S    .move                auto repeat
  2901.     ADDQ.W    #1,cursor_rep_count
  2902.     TST.W    key_lshift        faster if shift/alt
  2903.     BNE.S    .shift
  2904.     TST.W    key_lalt
  2905.     BNE.S    .alt
  2906.     CMP.W    #6,cursor_rep_count
  2907.     BPL.S    .move
  2908.     RTS
  2909. .shift    CMP.W    #3,cursor_rep_count
  2910.     BPL.S    .move
  2911.     RTS
  2912. .alt    CMP.W    #1,cursor_rep_count
  2913.     BPL.S    .move
  2914.     RTS
  2915. .move    CLR.W    cursor_rep_count
  2916.     MOVE.W    #$FFFF,cursor_rep_flag
  2917.     CMP.L    #'patt',play_mode    if not playing then
  2918.     BEQ.S    .skip
  2919.     CMP.L    #'patp',play_mode
  2920.     BEQ.S    .skip
  2921.     SUBQ.W    #1,edit_cursor_y        edit cursor up
  2922.     AND.W    #$3F,edit_cursor_y
  2923.     BRA    set_edit_scroller
  2924. .skip    RTS
  2925.  
  2926. cursor_down
  2927.     CMP.W    #3,mode
  2928.     BEQ    fscroll_down
  2929.     TST.W    plst_flag
  2930.     BNE    pscroll_down
  2931.     TST.W    cursor_rep_flag
  2932.     BEQ.S    edit_cursor_down
  2933.     ADDQ.W    #1,cursor_rep_count
  2934.     TST.W    key_lshift
  2935.     BNE.S    .shift
  2936.     TST.W    key_lalt
  2937.     BNE.S    .alt
  2938.     CMP.W    #6,cursor_rep_count
  2939.     BPL.S    edit_cursor_down
  2940.     RTS
  2941. .shift    CMP.W    #3,cursor_rep_count
  2942.     BPL.S    edit_cursor_down
  2943.     RTS
  2944. .alt    CMP.W    #1,cursor_rep_count
  2945.     BPL.S    edit_cursor_down
  2946.     RTS
  2947. edit_cursor_down
  2948.     CLR.W    cursor_rep_count
  2949.     MOVE.W    #$FFFF,cursor_rep_flag
  2950.     CMP.L    #'patt',play_mode
  2951.     BEQ.S    ecd_skip
  2952.     CMP.L    #'patp',play_mode
  2953.     BEQ.S    ecd_skip
  2954.     ADDQ.W    #1,edit_cursor_y        edit cursor down
  2955.     AND.W    #$3F,edit_cursor_y
  2956.     BRA    set_edit_scroller
  2957. ecd_skip
  2958.     RTS
  2959.  
  2960. cursor_right
  2961.     TST.W    input_in_progress
  2962.     BNE.S    ecd_skip
  2963.     TST.W    key_lshift
  2964.     BNE.S    cursor_position_right
  2965.     TST.W    key_lalt
  2966.     BNE.S    cursor_pattern_right
  2967.     TST.W    cursor_rep_flag
  2968.     BEQ    cursor_right_move
  2969.     ADDQ.W    #1,cursor_rep_count
  2970.     CMP.W    #6,cursor_rep_count
  2971.     BPL    cursor_right_move
  2972. .skip    RTS
  2973.  
  2974. cursor_position_left
  2975.     MOVEQ    #-1,D0
  2976.     BRA.S    cursor_position_lr
  2977. cursor_position_right
  2978.     MOVEQ    #1,D0
  2979. cursor_position_lr
  2980.     TST.W    cursor_rep_flag
  2981.     BEQ.S    .move
  2982.     ADDQ.W    #1,cursor_rep_count
  2983.     CMP.W    #5,cursor_rep_count
  2984.     BPL.S    .move
  2985.     RTS
  2986. .move    CLR.W    cursor_rep_count
  2987.     MOVE.W    #$FFFF,cursor_rep_flag
  2988.     CMP.L    #'patp',play_mode
  2989.     BEQ    return
  2990.     MOVE.L    D0,pat_pos_dir
  2991.     MOVE.W    #1,pat_pos_flag
  2992.     RTS
  2993.  
  2994. cursor_pattern_left
  2995.     MOVEQ    #-1,D0
  2996.     BRA.S    cursor_pattern_lr
  2997. cursor_pattern_right
  2998.     MOVEQ    #1,D0
  2999. cursor_pattern_lr
  3000.     CMP.L    #'patp',play_mode
  3001.     BEQ    return
  3002.     MOVE.L    D0,pat_pos_dir
  3003.     MOVE.W    #2,pat_pos_flag
  3004.     CLR.B    key_code
  3005.     RTS
  3006.  
  3007. change_pattern
  3008.     MOVE.L    pat_pos_dir,D0
  3009.     ADD.L    D0,pattern_no
  3010.     AND.L    #$3F,pattern_no
  3011.     BSR    refresh_pattern_display
  3012.     CLR.W    pat_pos_flag
  3013.     RTS
  3014.  
  3015. check_pat_or_pos
  3016.     MOVE.W    pat_pos_flag,D0
  3017.     BEQ    return
  3018.     CMPI.W    #2,D0
  3019.     BEQ.S    change_pattern
  3020.     CLR.W    pat_pos_flag
  3021.     MOVE.L    pat_pos_dir,D0
  3022.     BMI.S    .left
  3023.     CMP.L    #$7F,song_position
  3024.     BEQ    return
  3025.     ADD.L    D0,song_position
  3026.     AND.L    #$7F,song_position
  3027.     BSR    refresh_song_position
  3028.     RTS
  3029. .left    TST.L    song_position
  3030.     BEQ    return
  3031.     ADD.L    D0,song_position
  3032.     AND.L    #$7F,song_position
  3033.     BSR    refresh_song_position
  3034.     RTS
  3035.  
  3036. cursor_right_move
  3037.     CLR.W    cursor_rep_count
  3038.     MOVE.W    #$FFFF,cursor_rep_flag
  3039.     ADDQ.W    #1,edit_cursor_x        edit cursor right
  3040.     CMP.W    #24,edit_cursor_x
  3041.     BMI.S    .ok
  3042.     CLR.W    edit_cursor_x
  3043. .ok    BRA.S    set_edit_cursor
  3044.  
  3045. cursor_left
  3046.     TST.W    input_in_progress
  3047.     BNE    return
  3048.     TST.W    key_lshift
  3049.     BNE    cursor_position_left
  3050.     TST.W    key_lalt
  3051.     BNE    cursor_pattern_left
  3052.     TST.W    cursor_rep_flag
  3053.     BEQ.S    .move
  3054.     ADDQ.W    #1,cursor_rep_count
  3055.     CMP.W    #6,cursor_rep_count
  3056.     BPL.S    .move
  3057.     RTS
  3058. .move    CLR.W    cursor_rep_count
  3059.     MOVE.W    #$FFFF,cursor_rep_flag
  3060.     SUBQ.W    #1,edit_cursor_x        edit cursor left
  3061.     TST.W    edit_cursor_x
  3062.     BPL.S    set_edit_cursor
  3063.     MOVE.W    #23,edit_cursor_x
  3064.  
  3065. set_edit_cursor
  3066.     MOVE.W    edit_cursor_x,D0        convert xpos to sprite x
  3067.     LEA    xpos2column,A0
  3068.     MOVE.B    0(A0,D0.W),D0
  3069.     LSL.W    #3,D0
  3070.     ADD.W    #9,D0
  3071.     MOVE.W    #189,D1
  3072.     MOVEQ    #14,D2
  3073.     LEA    s_editcursor,A0
  3074.     BRA    position_sprite
  3075.  
  3076. set_input_cursor
  3077.     MOVE.W    input_cursor_x,D0
  3078.     MOVE.W    input_cursor_y,D1
  3079.     SUBQ.W    #1,D0
  3080.     MOVEQ    #2,D2
  3081.     LEA    s_inputcursor,A0
  3082.     BRA    position_sprite
  3083.  
  3084. check_arrow_and_cursor
  3085.     BSR    set_arrow_position
  3086.     BSR    check_cursor_keys
  3087.     BSR.S    check_arrow_functions
  3088.     CMP.W    #-1,rep_delay        if =0 then
  3089.     BEQ.S    .nodel
  3090.     MOVEQ    #0,D0
  3091. .del    ADDQ.L    #1,D0
  3092.     CMPI.L    #40000,D0
  3093.     BEQ.S    .nodel
  3094.     BTST    #6,$BFE001            if button not released then
  3095.     BEQ.S    .del                auto-repeat after 1/4 second
  3096.     CLR.W    alter_dir
  3097.     BRA    main_loop
  3098. .nodel    MOVE.W    #-1,rep_delay        if =-1 then
  3099.     BTST    #6,$BFE001            if button not released then
  3100.     BEQ.S    check_arrow_and_cursor        auto-repeat without delay
  3101.     CLR.W    rep_delay            clear flag
  3102.     CLR.W    alter_dir
  3103.     BRA    main_loop
  3104.  
  3105. check_arrow_functions
  3106.     MOVE.W    mouse_x,mouse_x2    if mouse x=0,y=0 then
  3107.     BNE.S    .noquit
  3108.     TST.W    mouse_y
  3109.     BNE.S    .noquit
  3110.     BSR    fn_stop
  3111.     BSR    arrow_is_magenta
  3112.     BSR    check_are_you_sure        quit if sure
  3113.     BEQ    restore_and_exit
  3114.     BSR    arrow_flash_red
  3115. .noquit    MOVE.W    mouse_y,mouse_y2
  3116.     MOVE.W    mouse_y2,D0
  3117.     CMPI.W    #122,D0            if y>=122 then edit pattern no
  3118.     BGE    input_pattern_no
  3119.     CMPI.W    #111,D0            if y>=111 then edit samplename
  3120.     BGE    input_instr_name
  3121.     CMPI.W    #100,D0            if y>=100 then edit songname
  3122.     BGE    input_song_name
  3123.     MOVE.W    mouse_x2,D0
  3124.     TST.W    plst_flag        plst ?
  3125.     BNE.S    .plst
  3126.     CMP.W    #3,mode            if mode=diskops then
  3127.     BNE.S    .nod
  3128.     CMPI.W    #120,D0                if x>=120 then diskops
  3129.     BGE    .diskop
  3130. .nod    CMPI.W    #244,D0            if x>=244 then toggle on/off icons
  3131.     BGE    check_toggle_on_off
  3132.     CMPI.W    #181,D0            if x>=181 then 2nd column
  3133.     BGE    .col2nd
  3134.     CMPI.W    #120,D0            if x>=120 then 1st column
  3135.     BGE    .col1st
  3136. .param
  3137.     CMPI.W    #120,D0        alter parameters
  3138.     BGE.S    .skip
  3139.     CMPI.W    #109,D0            if 109<=x<120 then parameter down
  3140.     BGE    alter_parameter_down
  3141.     CMPI.W    #98,D0            if 98<=x<109 then parameter up
  3142.     BGE    alter_parameter_up
  3143. .skip    RTS                else skip
  3144.  
  3145. .plst    MOVEQ    #0,D1        plst functions
  3146.     MOVEM.W    mouse_x2,D0/D1
  3147.     CMPI.W    #120,D0            if x<120 then alter parameters
  3148.     BLT.S    .param2
  3149.     CMPI.W    #11,D1            if y<=11 then
  3150.     BGT.S    .plst2
  3151.     CMPI.W    #$C1,D0                if x<=193 then load plst
  3152.     BLE    fn_load_plst
  3153.     CMPI.W    #$11C,D0            if x>=284 then exit plst
  3154.     BGE    cancel_plst_mode
  3155.     RTS                    else skip
  3156. .plst2    CMPI.W    #22,D1            if 11<y<=22 then
  3157.     BGT.S    .plst3
  3158.     CMPI.W    #268,D0                if x>=268 then mountlist
  3159.     BGE    fn_mountlist
  3160.     CMPI.W    #220,D0                if x>=220 then edit search3
  3161.     BGE    alter_search3
  3162.     CMPI.W    #172,D0                if x>=172 then edit search2
  3163.     BGE    alter_search2
  3164.     CMPI.W    #120,D0                if x>=120 then edit search1
  3165.     BGE    alter_search1
  3166.     RTS                    else skip
  3167. .plst3    CMPI.W    #312,D0            if 128<=x<=312
  3168.     BGT.S    .param2            and 24<=y<=95 then
  3169.     CMPI.W    #128,D0
  3170.     BLT.S    .param2
  3171.     CMPI.W    #24,D1
  3172.     BLT.S    .param2
  3173.     CMPI.W    #95,D1
  3174.     BGT.S    .param2
  3175.     SUB.W    #24,D1                d1=(y-24)/6=0..11
  3176.     AND.L    #$FF,D1
  3177.     DIVU    #6,D1
  3178.     BRA    plst_file_select        file select
  3179. .param2    MOVE.W    mouse_x2,D0        else alter parameters
  3180.     BRA    .param
  3181.  
  3182. .col2nd    MOVE.W    mouse_y2,D0    2nd column functions
  3183.     CMP.W    #3,mode            if mode=diskops then
  3184.     BNE.S    .nod2
  3185.     CMPI.W    #44,D0                if y>=44 then file select
  3186.     BGE    diskop_file_select
  3187. .nod2    CMPI.W    #44,D0
  3188.     BGE.S    .skip2
  3189.     CMPI.W    #34,D0            if 34<=y<44 then goto diskops
  3190.     BGE    fn_goto_diskops
  3191.     CMPI.W    #23,D0            if y>=23 then goto plst
  3192.     BGE    fn_goto_plst
  3193.     CMPI.W    #12,D0            if y>=12 then clear song
  3194.     BGE    fn_clear
  3195.     TST.W    D0            if y>=0 then stop
  3196.     BGE    fn_stop
  3197. .skip2    RTS
  3198.  
  3199. .col1st    MOVE.W    mouse_y2,D0    1st column functions
  3200.     CMP.W    #3,mode            if mode=diskops then
  3201.     BNE.S    .nod3
  3202.     CMPI.W    #44,D0                if y>=44 then file select
  3203.     BGE    diskop_file_select
  3204. .nod3    CMPI.W    #44,D0
  3205.     BGE.S    .skip2
  3206.     CMPI.W    #34,D0            if 34<=y<44 then record
  3207.     BGE    fn_record
  3208.     CMPI.W    #23,D0            if y>=23 then edit
  3209.     BGE    fn_edit
  3210.     CMPI.W    #12,D0            if y>=12 then play pattern
  3211.     BGE    fn_play_pattern
  3212.     TST.W    D0            if y>=0 then play song
  3213.     BGE    fn_play_song
  3214.     RTS
  3215.  
  3216. .diskop    MOVEM.W    mouse_x2,D0/D1    diskop functions
  3217.     CMP.W    #3,mode
  3218.     BNE.S    .nodisk
  3219.     CMPI.W    #44,D1
  3220.     BGE    diskop_file_select
  3221. .nodisk    CMPI.W    #44,D1            if y>=44 then file select
  3222.     BGE    diskop_file_select
  3223.     CMPI.W    #34,D1            if y>=34 then edit module dir
  3224.     BGE    input_module_dir
  3225.     CMPI.W    #252,D0            if x<252 then song/module functions
  3226.     BLT.S    songmod_functions
  3227.     CMPI.W    #22,D1            if 22<=y<44 then toggle pack
  3228.     BGE    toggle_pack_icon
  3229.     CMPI.W    #11,D1            if y>=11 then save sample
  3230.     BGE    fn_save_sample
  3231.     BRA    fn_load_sample            else load sample
  3232.  
  3233. toggle_pack_icon
  3234.     EOR.W    #1,pack_flag
  3235.     BSR.S    refresh_pack_icon
  3236.     MOVE.W    #$C800,D0
  3237. .wait    DBRA    D0,.wait
  3238.     RTS
  3239.  
  3240. refresh_pack_icon
  3241.     CMP.W    #3,mode            skip if mode<>diskops
  3242.     BNE    return
  3243.     LEA    main_screen+26*40+37,A1
  3244.     LEA    onoff_icon,A0        pack on/off
  3245.     TST.W    pack_flag
  3246.     BNE.S    .on
  3247.     LEA    onoff_icon+24,A0
  3248. .on    BSR    draw_on_off
  3249.     RTS
  3250.  
  3251. pack_flag
  3252.     dc.w    1        0=off/1=on
  3253.  
  3254. songmod_functions
  3255.     CMPI.W    #186,D0        songs/module functions
  3256.     BLT.S    .song        if x>=186 then
  3257.     CMPI.W    #22,D1
  3258.     BGE    fn_delete_module    if y>=22 then delete module
  3259.     CMPI.W    #11,D1
  3260.     BGE    fn_save_module        if y>=11 then save module
  3261.     BRA    fn_load_module            else load module
  3262. .song    CMPI.W    #22,D1        else
  3263.     BGE    fn_delete_song        if y>=22 then delete song
  3264.     CMPI.W    #11,D1
  3265.     BGE    fn_save_song        if y>=11 then save song
  3266.     BRA    fn_load_song            else load song
  3267.  
  3268. * SAVE SAMPLE
  3269.  
  3270. fn_save_sample
  3271.     BSR    save_arrow_colours
  3272.     CLR.B    key_code
  3273.     MOVEQ    #0,D0
  3274.     MOVE.W    current_instr,D0    index instrument in song file
  3275.     SUBQ.W    #1,D0
  3276.     MULU    #in_size,D0
  3277.     MOVE.L    song_file_ptr,A0
  3278.     ADD.L    #sf_instr,A0
  3279.     ADD.L    D0,A0
  3280.     MOVEQ    #0,D0
  3281.     MOVE.W    in_length(A0),D0    byte length
  3282.     ADD.L    D0,D0
  3283.     MOVE.L    D0,file_length
  3284.     LEA    st01_msg+6(PC),A1
  3285.     MOVEQ    #22-1,D0
  3286. .name    MOVE.B    (A0)+,(A1)+
  3287.     DBRA    D0,.name
  3288.     MOVE.L    #st01_msg+6,file_nameptr
  3289.     CMP.B    #':',st01_msg+11    if no drive specifier then st-01
  3290.     BEQ.S    .drive
  3291.     MOVE.L    #st01_msg,file_nameptr
  3292. .drive    LEA    instr_addr_list,A0    get address
  3293.     MOVEQ    #0,D1
  3294.     MOVE.W    current_instr,D1
  3295.     LSL.L    #2,D1
  3296.     MOVE.L    0(A0,D1.W),file_addr
  3297.     BSR    arrow_is_green
  3298.     MOVE.L    DOSbase,A6
  3299.     MOVE.L    file_nameptr,D1
  3300.     MOVE.L    #1006,D2        write
  3301.     JSR    _LVOOpen(A6)
  3302.     MOVE.L    D0,file_handle
  3303.     BNE.S    .ok            error if can't open
  3304.     BRA    arrow_flash_red
  3305. .ok    MOVE.L    file_handle,D1
  3306.     MOVE.L    file_addr,D2
  3307.     MOVE.L    file_length,D3
  3308.     JSR    _LVOWrite(A6)
  3309.     MOVE.L    file_handle,D1
  3310.     JSR    _LVOClose(A6)
  3311.     CLR.L    file_handle
  3312.     BSR    restore_arrow_colours
  3313.     RTS
  3314.  
  3315. * CLEAR SONG
  3316.  
  3317. fn_clear
  3318.     MOVE.W    #1,memory_flag
  3319.     BSR    fn_stop            stop tune
  3320.     BSR    arrow_is_magenta
  3321.     BSR    check_are_you_sure    make sure
  3322.     BNE    clear_aborted
  3323.  
  3324. fn_clear_nocheck
  3325.     BSR    free_instr_memory    wipe instruments
  3326.     MOVE.L    song_file_ptr,A0
  3327.     MOVE.L    A0,A1
  3328.     MOVE.L    A1,A2
  3329.     ADD.L    #sf_size,A2        wipe song
  3330. .wpsong    CLR.L    (A1)+
  3331.     CMP.L    A1,A2
  3332.     BNE.S    .wpsong
  3333.     LEA    songs_dir_name(PC),A1    wipe name
  3334.     MOVEQ    #28-1,D0
  3335. .wpname    CLR.B    (A1)+
  3336.     DBRA    D0,.wpname
  3337.     MOVE.L    A0,A1            valid replen values
  3338.     ADD.L    #sf_instr,A1
  3339.     MOVEQ    #31-1,D0
  3340. .wpinst    MOVE.W    #1,in_replen(A1)
  3341.     ADD.L    #in_size,A1
  3342.     DBRA    D0,.wpinst
  3343.     LEA    st01_msg+6(PC),A1    wipe instrument filename
  3344.     MOVEQ    #28-1,D0
  3345. .wpfnam    CLR.B    (A1)+
  3346.     DBRA    D0,.wpfnam
  3347.     MOVE.L    song_file_ptr,A0    init song file
  3348.     MOVE.W    #1*256+0,sf_length(A0)    length=1,restart=0
  3349.     MOVE.L    #'M.K.',sf_ident(A0)
  3350.     CLR.L    song_position        reset and refresh display
  3351.     CLR.L    play_cursor
  3352.     CLR.L    play_row_index
  3353.     MOVE.W    #1,current_instr
  3354.     MOVE.L    #6,tempo
  3355.     BSR    refresh_song_position
  3356.     CLR.L    pattern_no
  3357.     CLR.W    edit_cursor_y
  3358.     BSR    refresh_pattern_display
  3359.     BSR    set_edit_scroller
  3360.     BSR    refresh_song_parameters
  3361.     BSR    refresh_instr_parameters
  3362.     BSR    refresh_song_name
  3363. clear_aborted
  3364.     BSR    arrow_is_grey
  3365.     RTS
  3366.  
  3367. free_instr_memory
  3368.     MOVE.W    #1,memory_flag
  3369.     MOVEQ    #1,D7            for 31 instruments
  3370.     MOVE.L    4.w,a6
  3371. .loop    MOVE.W    D7,D2
  3372.     LSL.W    #2,D2
  3373.     LEA    instr_alloc_list-4,A0
  3374.     LEA    instr_header,A1
  3375.     CLR.L    0(A1,D2.W)
  3376.     LEA    instr_addr_list,A2    clear ptrs
  3377.     CLR.L    0(A2,D2.W)
  3378.     MOVE.L    0(A0,D2.W),D1        if memory allocated then
  3379.     BEQ.S    .free
  3380.     MOVE.L    31*4(A0,D2.W),D0        clear addr,size
  3381.     CLR.L    0(A0,D2.W)
  3382.     CLR.L    31*4(A0,D2.W)
  3383.     MOVE.L    D1,A1
  3384.     JSR    _LVOFreeMem(A6)            free memory
  3385. .free    ADDQ.W    #1,D7            next
  3386.     CMPI.W    #32,D7
  3387.     BNE.S    .loop
  3388.     RTS
  3389.  
  3390. alter_parameter_down
  3391.     MOVE.W    #-1,alter_dir        set direction down/up
  3392.     BRA.S    alter_parameter
  3393. alter_parameter_up
  3394.     CLR.W    alter_dir
  3395. alter_parameter
  3396.     MOVE.W    #1,memory_flag
  3397.     MOVE.W    mouse_y2,D0
  3398.     CMPI.W    #100,D0            skip if y<0 or y>=100
  3399.     BGE.S    .skip
  3400.     CMPI.W    #89,D0            alter selected parameter
  3401.     BGE    alter_replen
  3402.     CMPI.W    #78,D0
  3403.     BGE    alter_repeat
  3404.     CMPI.W    #67,D0
  3405.     BGE    alter_instr_length
  3406.     CMPI.W    #56,D0
  3407.     BGE    alter_volume
  3408.     CMPI.W    #45,D0
  3409.     BGE    alter_instr_number
  3410.     CMPI.W    #34,D0
  3411.     BGE    alter_restart
  3412.     CMPI.W    #23,D0
  3413.     BGE    alter_song_length
  3414.     CMPI.W    #12,D0
  3415.     BGE    alter_song_pattern
  3416.     TST.W    mouse_y2
  3417.     BGE    alter_song_position
  3418. .skip    RTS
  3419.  
  3420. save_arrow_colours
  3421.     MOVE.L    cptr_arrow_col,A0
  3422.     MOVE.W    2(A0),old_arrow_colours
  3423.     MOVE.W    6(A0),old_arrow_colours+2
  3424.     MOVE.W    10(A0),old_arrow_colours+4
  3425.     RTS
  3426.  
  3427. restore_arrow_colours
  3428.     MOVE.W    #1,memory_flag
  3429.     MOVE.L    cptr_arrow_col,A0
  3430.     MOVE.W    old_arrow_colours,2(A0)
  3431.     MOVE.W    old_arrow_colours+2,6(A0)
  3432.     MOVE.W    old_arrow_colours+4,10(A0)
  3433.     RTS
  3434.  
  3435. input_pattern_no
  3436.     CMP.L    #'patp',play_mode        skip if playing song
  3437.     BNE.S    .ok
  3438.     RTS
  3439. .ok    BSR.S    save_arrow_colours
  3440.     BSR    arrow_is_magenta
  3441.     CLR.B    key_code
  3442.     MOVE.W    #12,input_cursor_x        input 1st digit
  3443.     MOVE.W    #134,input_cursor_y
  3444.     BSR    set_input_cursor
  3445.     MOVE.L    #128*40+1,char_offset
  3446.     BSR.S    wait_number_key
  3447.     MOVE.B    D1,D0
  3448.     MULU    #10,D0
  3449.     MOVE.B    D0,ipn_temp+1
  3450.     BSR.S    print_dec1
  3451.     MOVE.W    #20,input_cursor_x        input 2nd digit
  3452.     MOVE.W    #134,input_cursor_y
  3453.     BSR    set_input_cursor
  3454.     BSR.S    wait_number_key
  3455.     MOVE.B    ipn_temp+1,pattern_no+3
  3456.     ADD.B    D1,pattern_no+3
  3457.     AND.L    #$3F,pattern_no            pattern no = 0..63
  3458.     CLR.W    input_cursor_x            cursor off screen
  3459.     MOVE.W    #270,input_cursor_y
  3460.     BSR    set_input_cursor
  3461.     BSR    refresh_pattern_display
  3462.     BSR    set_edit_cursor
  3463.     BRA    restore_arrow_colours
  3464.  
  3465. * exit    d1=0..9
  3466.  
  3467. wait_number_key
  3468.     MOVEQ    #0,D0        wait for key 0..9
  3469.     MOVE.B    key_code,D0
  3470.     BEQ.S    wait_number_key
  3471.     CLR.B    key_code
  3472.     CMPI.B    #10,D0
  3473.     BEQ.S    .zero
  3474.     BGT.S    wait_number_key
  3475.     CMPI.B    #1,D0
  3476.     BLT.S    wait_number_key
  3477.     MOVE.L    D0,D1
  3478.     RTS
  3479. .zero    MOVEQ    #0,D1
  3480.     RTS
  3481.  
  3482. print_dec1
  3483.     ADD.B    #'0',D1        entry d1.w=0..9,exit d1 swapped
  3484.     MOVE.B    D1,temp_str
  3485.     CLR.W    D1
  3486.     SWAP    D1
  3487.     MOVE.L    #1,string_size
  3488.     MOVE.L    #temp_str,string_addr
  3489.     BSR    print_string
  3490.     CLR.L    temp_str
  3491.     CLR.W    word_to_print
  3492.     RTS
  3493.  
  3494. input_clear
  3495.     CMP.W    input_cursor_x,D5    step cursor back to start
  3496.     BEQ.S    .start
  3497.     SUBQ.L    #1,A6
  3498.     SUBQ.W    #8,input_cursor_x
  3499.     BRA.S    input_clear
  3500. .start    MOVE.L    A6,A4        clear line to end
  3501. .wipe    CLR.B    (A4)+
  3502.     CMP.L    input_end_addr,A4
  3503.     BNE.S    .wipe
  3504.     BSR    refresh_all_parameters
  3505.     BRA    input_exit
  3506.  
  3507. refresh_all_parameters
  3508.     BSR    refresh_instr_parameters
  3509.     BSR    refresh_song_parameters
  3510.     BRA    print_modules_dir
  3511.  
  3512. input_routine
  3513.     MOVE.W    #1,input_in_progress
  3514.     MOVE.W    input_cursor_x,D5
  3515.     MOVE.W    mouse_x,D0
  3516.     ADDQ.L    #3,D0
  3517.     MOVE.W    #270,D1
  3518.     MOVEQ    #17,D2
  3519.     MOVE.L    arrow_spr_ptr,A0
  3520.     BSR    position_sprite
  3521.     LEA    valid_name_keycodes,A5
  3522.     CLR.B    key_code
  3523.     BSR.S    refresh_all_parameters
  3524. .loop    BTST    #2,_custom+potinp    if right button then clear line
  3525.     BEQ    input_clear
  3526.     CLR.W    D1
  3527.     MOVE.B    key_code,D1
  3528.     BEQ.S    .loop
  3529.     CMPI.B    #$4E,D1        CRIGHT
  3530.     BEQ    .right
  3531.     CMPI.B    #$4F,D1        CLEFT
  3532.     BEQ    .left
  3533.     CMPI.B    #$46,D1        DEL
  3534.     BEQ    .delete
  3535.     CMPI.B    #$41,D1        BACKSPACE
  3536.     BEQ    .backsp
  3537.     CMPI.B    #$44,D1        RETURN
  3538.     BEQ    input_exit
  3539.     BTST    #7,D1        loop if key release
  3540.     BNE.S    .loop
  3541.  
  3542.     TST.W    key_lshift    if shift then add 128
  3543.     BEQ.S    .noshft
  3544.     BSET    #7,D1
  3545. .noshft    MOVEQ    #0,D0
  3546. .search    CMP.B    0(A5,D0.W),D1    search valid keycodes
  3547.     BEQ.S    .found
  3548.     ADDQ.B    #1,D0
  3549.     CMPI.B    #46,D0
  3550.     BGT.S    .loop
  3551.     BRA.S    .search
  3552. .found    CMP.L    input_end_addr,A6    skip if end of line
  3553.     BEQ.S    .loop
  3554.     MOVE.L    input_end_addr,A4
  3555. .shiftr    MOVE.B    -(A4),1(A4)        shift chars right
  3556.     CMP.L    A4,a6
  3557.     BNE.S    .shiftr
  3558.     MOVE.L    input_end_addr,A4    make sure line terminated
  3559.     CLR.B    (A4)
  3560.     LEA    valid_name_chars,A0    insert ascii
  3561.     MOVE.B    0(A0,D0.W),D1
  3562.     MOVE.B    D1,(A6)+
  3563.     ADDQ.W    #8,input_cursor_x    cursor right
  3564.     BSR    set_input_cursor
  3565.     BSR    refresh_all_parameters
  3566.     CLR.B    key_code
  3567.     BRA    .loop
  3568.  
  3569. .backsp    CMP.W    input_cursor_x,D5    backspace
  3570.     BNE.S    .back2
  3571.     BRA    .loop
  3572. .back2    SUBQ.L    #1,A6
  3573.     MOVE.L    A6,A4
  3574. .back3    MOVE.B    1(A4),(A4)+        shift left
  3575.     CMP.L    input_end_addr,A4
  3576.     BNE.S    .back3
  3577.     SUBQ.W    #8,input_cursor_x    cursor left
  3578.     BSR    set_input_cursor
  3579.     BSR    refresh_all_parameters
  3580.     BSR    wait_20ms
  3581.     BSR    wait_20ms
  3582.     BSR    wait_20ms
  3583.     BRA    .loop
  3584.  
  3585. .delete    MOVE.L    A6,A4            delete char
  3586. .del2    MOVE.B    1(A4),(A4)+        shift left
  3587.     CMP.L    input_end_addr,A4
  3588.     BNE.S    .del2
  3589.     BSR    refresh_all_parameters
  3590.     BSR    wait_20ms
  3591.     BSR    wait_20ms
  3592.     BSR    wait_20ms
  3593.     BRA    .loop
  3594.  
  3595. .right    CMP.L    input_end_addr,A6    cursor right
  3596.     BEQ    .loop
  3597.     ADDQ.L    #1,A6
  3598.     ADDQ.W    #8,input_cursor_x
  3599.     BSR    set_input_cursor
  3600.     BSR    wait_20ms
  3601.     BSR    wait_20ms
  3602.     BSR    wait_20ms
  3603.     BRA    .loop
  3604.  
  3605. .left    CMP.W    input_cursor_x,D5    cursor left
  3606.     BEQ    .loop
  3607.     SUBQ.L    #1,A6
  3608.     SUBQ.W    #8,input_cursor_x
  3609.     BSR    set_input_cursor
  3610.     BSR    wait_20ms
  3611.     BSR    wait_20ms
  3612.     BSR    wait_20ms
  3613.     BRA    .loop
  3614.  
  3615. input_exit
  3616.     CMP.W    input_cursor_x,D5    goto start of line
  3617.     BEQ.S    .start
  3618.     SUBQ.L    #1,A6
  3619.     SUBQ.W    #8,input_cursor_x
  3620.     BRA.S    input_exit
  3621. .start    MOVE.L    A6,A4
  3622. .find0    TST.B    (A4)+            find terminator
  3623.     BNE.S    .find0
  3624.     SUBQ.L    #1,A4
  3625. .pad0    CMP.L    input_end_addr,A4    pad with 0's to end
  3626.     BEQ.S    .done
  3627.     CLR.B    (A4)+
  3628.     BRA.S    .pad0
  3629. .done    CLR.W    input_cursor_x        cursor off screen
  3630.     MOVE.W    #270,input_cursor_y
  3631.     BSR    set_input_cursor
  3632.     CLR.W    input_in_progress
  3633.     CLR.B    key_code
  3634.     BRA    refresh_all_parameters
  3635.  
  3636. input_song_name
  3637.     BSR    save_arrow_colours
  3638.     BSR    arrow_is_magenta
  3639.     CLR.L    edit_mode
  3640.     MOVE.L    song_file_ptr,A6
  3641.     MOVE.W    #108,input_cursor_x
  3642.     MOVE.W    #108,input_cursor_y
  3643.     BSR    set_input_cursor
  3644.     MOVE.L    A6,input_end_addr
  3645.     ADD.L    #19,input_end_addr
  3646.     BSR    input_routine
  3647.     CLR.L    input_end_addr
  3648.     BRA    restore_arrow_colours
  3649.  
  3650. input_instr_name
  3651.     BSR    save_arrow_colours
  3652.     BSR    arrow_is_magenta
  3653.     CLR.L    edit_mode
  3654.     MOVE.L    song_file_ptr,A6
  3655.     LEA    sf_instr-in_size(A6),A6
  3656.     MOVE.W    current_instr,D7
  3657.     MULU    #in_size,D7
  3658.     ADD.L    D7,A6
  3659.     MOVE.W    #108,input_cursor_x
  3660.     MOVE.W    #119,input_cursor_y
  3661.     BSR    set_input_cursor
  3662.     MOVE.L    A6,input_end_addr
  3663.     ADD.L    #21,input_end_addr
  3664.     BSR    input_routine
  3665.     BSR    refresh_instr_parameters
  3666.     CLR.L    input_end_addr
  3667.     BRA    restore_arrow_colours
  3668.  
  3669. load_sample_file
  3670.     MOVE.W    #15,_custom+dmacon    cancel audio dma
  3671.     CLR.B    key_code
  3672.     LEA    st01_msg+6(PC),A0    wipe instrument filename
  3673.     MOVEQ    #28-1,D0
  3674. .wname    CLR.B    (A0)+
  3675.     DBRA    D0,.wname
  3676.     LEA    instr_alloc_list-4,A0    free previous memory
  3677.     MOVEQ    #0,D0
  3678.     MOVE.W    current_instr,D0
  3679.     ASL.W    #2,D0
  3680.     MOVE.L    0(A0,D0.W),D1
  3681.     BEQ.S    .free
  3682.     MOVE.L    $7C(A0,D0.W),D0
  3683.     MOVE.L    D1,A1
  3684.     MOVE.L    4.w,a6
  3685.     JSR    _LVOFreeMem(A6)
  3686. .free    LEA    instr_alloc_list-4,A0
  3687.     MOVE.W    current_instr,D0
  3688.     ASL.W    #2,D0
  3689.     CLR.L    0(A0,D0.W)        clear addr,size
  3690.     CLR.L    $7C(A0,D0.W)
  3691.     LEA    instr_addr_list,A0
  3692.     CLR.L    0(A0,D0.W)
  3693.     MOVEQ    #0,D0
  3694.     MOVE.W    current_instr,D0
  3695.     MULU    #in_size,D0
  3696.     MOVE.L    song_file_ptr,A0    get length from song
  3697.     ADD.L    #sf_instr-in_size+in_length,A0
  3698.     ADD.L    D0,A0
  3699.     MOVEQ    #0,D0
  3700.     MOVE.W    (A0),D0
  3701.     ADD.L    D0,D0
  3702.     MOVE.L    D0,file_length
  3703.     SUB.L    #in_length,A0
  3704.     MOVE.W    in_volume(A0),old_volume    preserve volume
  3705.     CLR.W    in_volume(A0)
  3706.     LEA    st01_msg+6(PC),A1        copy name
  3707.     MOVEQ    #22-1,D0
  3708. .cname    MOVE.B    (A0)+,(A1)+
  3709.     DBRA    D0,.cname
  3710.     MOVE.L    #st01_msg+6,file_nameptr    if no drive spec then st-01
  3711.     CMP.B    #':',st01_msg+11
  3712.     BEQ.S    .diskok
  3713.     MOVE.L    #st01_msg,file_nameptr
  3714. .diskok    MOVE.L    file_length,D0
  3715.     BEQ.S    .noaloc
  3716.     MOVE.L    #MEMF_CHIP!MEMF_CLEAR,D1    allocate memory
  3717.     MOVE.L    4.w,a6
  3718.     JSR    _LVOAllocMem(A6)
  3719.     TST.L    D0
  3720.     BEQ    .error
  3721. .noaloc    MOVE.L    D0,file_addr
  3722.     BSR    refresh_instr_parameters    update display
  3723.     LEA    instr_alloc_list-4,A0
  3724.     MOVEQ    #0,D1
  3725.     MOVE.W    current_instr,D1
  3726.     ASL.W    #2,D1
  3727.     MOVE.L    file_addr,0(A0,D1.W)        save addr,length
  3728.     MOVE.L    file_length,$7C(A0,D1.W)
  3729.     BSR    load_a_file            load it
  3730.     MOVE.L    file_addr,A0
  3731.     MOVE.W    #257-1,D0
  3732. .find_body
  3733.     CMP.L    #'BODY',(A0)            IFF ?
  3734.     BEQ.S    .is_iff
  3735.     ADDQ.L    #2,A0
  3736.     DBRA    D0,.find_body
  3737.     BRA    .not_iff
  3738. .error    MOVE.W    #1,memory_flag
  3739.     BRA    arrow_flash_red
  3740.  
  3741. .is_iff    MOVE.L    file_addr,A1        IFF file
  3742.     MOVE.L    A0,A2            extract header
  3743.     SUB.L    A1,A2
  3744.     ADDQ.L    #8,A2
  3745.     MOVE.L    file_length,A1
  3746.     SUB.L    A2,A1
  3747.     MOVE.L    A1,iff_length
  3748.     ADDQ.L    #8,A0
  3749.     MOVE.L    A0,instr_addr_list
  3750.     MOVE.W    current_instr,D0
  3751.     ASL.W    #2,D0
  3752.     LEA    instr_header,A0        save header length
  3753.     MOVE.L    A2,0(A0,D0.W)
  3754.     LEA    instr_addr_list,A0
  3755.     MOVE.L    instr_addr_list,0(A0,D0.W)    adjust sample length
  3756.     MOVEQ    #0,D0                in song
  3757.     MOVE.W    current_instr,D0
  3758.     MULU    #in_size,D0
  3759.     MOVE.L    song_file_ptr,A0
  3760.     SUB.L    #in_size-sf_instr,A0
  3761.     ADD.L    D0,A0
  3762.     MOVE.L    iff_length,D7
  3763.     LSR.W    #1,D7
  3764.     MOVE.W    D7,in_length(A0)
  3765.     BRA.S    .ptrs_set
  3766.  
  3767. .not_iff
  3768.     MOVE.W    current_instr,D0    non-IFF file
  3769.     ASL.W    #2,D0
  3770.     LEA    instr_header,A0        no header
  3771.     CLR.L    0(A0,D0.W)
  3772.     LEA    instr_alloc_list-4,A1    address=start of file
  3773.     LEA    instr_addr_list,A0
  3774.     MOVE.L    0(A1,D0.W),D1
  3775.     MOVE.L    D1,0(A0,D0.W)
  3776. .ptrs_set
  3777.     MOVEQ    #0,D0
  3778.     MOVE.W    current_instr,D0
  3779.     MULU    #in_size,D0
  3780.     MOVE.L    song_file_ptr,A0
  3781.     SUB.L    #in_size-sf_instr,A0
  3782.     ADD.L    D0,A0
  3783.     MOVE.W    old_volume,D0        restore volume
  3784.     MOVE.W    D0,in_volume(A0)
  3785.     LEA    instr_addr_list+4,A0
  3786.     MOVEQ    #0,D0            clear 1st 4-bytes of each sample
  3787. .clr_1st
  3788.     MOVE.L    0(A0,D0.W),A1
  3789.     CLR.L    (A1)
  3790.     ADDQ.W    #4,D0
  3791.     CMPI.W    #31*4,D0
  3792.     BNE.S    .clr_1st
  3793.     CLR.W    ain_disable
  3794.     MOVE.W    #1,memory_flag
  3795.     BSR    refresh_memory_usage
  3796.     RTS
  3797.  
  3798. delete_song
  3799.     BSR    arrow_is_magenta
  3800.     BSR    check_are_you_sure
  3801.     BNE.S    .abort
  3802.     CLR.B    key_code
  3803.     LEA    selected_filename,A0
  3804.     LEA    songs_dir_name(PC),A1    name=songs_dir+filename
  3805.     MOVEQ    #20-1,D0
  3806. .name    MOVE.B    (A0)+,(A1)+
  3807.     DBRA    D0,.name
  3808.     MOVE.L    #songs_dir,file_nameptr
  3809.     MOVE.L    DOSbase,A6
  3810.     MOVE.L    file_nameptr,D1
  3811.     MOVE.L    D1,A0
  3812.     JSR    _LVODeleteFile(A6)
  3813.     TST.L    D0
  3814.     BEQ.S    .error
  3815.     BSR    wipe_spectrum
  3816.     CLR.W    disk_fn
  3817.     BRA    restore_arrow_colours
  3818. .error    BSR    wipe_spectrum
  3819. .abort    CLR.W    disk_fn
  3820.     BSR    arrow_flash_red
  3821.     BRA    restore_arrow_colours
  3822.  
  3823. delete_module
  3824.     BSR    arrow_is_magenta
  3825.     BSR    check_are_you_sure
  3826.     BNE.S    .abort
  3827.     CLR.B    key_code
  3828.     LEA    modules_dir,A0        name=modules_dir+filename
  3829.     LEA    modname_buffer,A1
  3830.     MOVEQ    #16-1,D1
  3831. .dir    MOVE.B    (A0)+,D0
  3832.     BEQ.S    .plus
  3833.     MOVE.B    D0,(A1)+
  3834.     DBRA    D1,.dir
  3835. .plus    LEA    selected_filename,A0
  3836.     MOVEQ    #28-1,D0
  3837. .fname    MOVE.B    (A0)+,(A1)+
  3838.     DBRA    D0,.fname
  3839.     MOVE.L    #modname_buffer,file_nameptr
  3840.     MOVE.L    DOSbase,A6
  3841.     MOVE.L    file_nameptr,D1
  3842.     MOVE.L    D1,A0
  3843.     JSR    _LVODeleteFile(A6)
  3844.     TST.L    D0
  3845.     BEQ.S    .error
  3846.     BSR    wipe_spectrum
  3847.     CLR.W    disk_fn
  3848.     BRA    restore_arrow_colours
  3849. .error    BSR    wipe_spectrum
  3850. .abort    CLR.W    disk_fn
  3851.     BSR    arrow_flash_red
  3852.     BRA    restore_arrow_colours
  3853.  
  3854. load_song
  3855.     BSR    fn_stop
  3856.     CLR.B    key_code
  3857.     MOVE.L    song_file_ptr,A0        wipe 64K, patterns
  3858.     ADD.L    #sf_patterns,A0
  3859.     MOVE.W    #(64*1024)/4-1,D0
  3860. .wpat    CLR.L    (A0)+
  3861.     DBRA    D0,.wpat
  3862.     LEA    songs_dir_name(PC),A0        wipe song name
  3863.     MOVEQ    #28-1,D0
  3864. .wname    CLR.B    (A0)+
  3865.     DBRA    D0,.wname
  3866.     LEA    selected_filename,A0
  3867.     LEA    songs_dir_name(PC),A1        copy name
  3868.     MOVEQ    #$13,D0
  3869. .cname    MOVE.B    (A0)+,(A1)+
  3870.     DBRA    D0,.cname
  3871.     MOVE.L    song_file_ptr,file_addr        load file
  3872.     MOVE.L    #songs_dir,file_nameptr
  3873.     MOVE.L    #sf_size,file_length        (max length)
  3874.     BSR    load_a_file
  3875.     TST.L    D0
  3876.     BEQ    load_error
  3877.     MOVE.L    song_file_ptr,A0        unpack if packed
  3878.     CMP.L    #'PACK',(A0)
  3879.     BNE.S    .nopack
  3880.     MOVE.L    4(A0),packed_size
  3881.     MOVE.L    8(A0),unpacked_size
  3882.     MOVE.L    song_file_ptr,D0        unpack at top of song area
  3883.     ADD.L    #sf_size,D0
  3884.     SUB.L    unpacked_size,D0
  3885.     MOVE.L    D0,pack_buffer_ptr
  3886.     BSR    unpack_song
  3887. .nopack    MOVE.L    song_file_ptr,A0
  3888.     CMP.L    #'M.K.',sf_ident(A0)        if old soundtracker file
  3889.     BEQ.S    .is_mk                    then adjust
  3890.     BSR    convert_old_format
  3891. .is_mk    MOVE.L    song_file_ptr,A0
  3892.     CMP.B    #120,sf_restart(A0)        if restart=120 then clear
  3893.     BNE.S    .not120
  3894.     CLR.B    sf_restart(A0)
  3895. .not120    CLR.L    pattern_no            setup display
  3896.     CLR.L    song_position
  3897.     BSR    refresh_song_position
  3898.     BSR    refresh_pattern_display
  3899.     CLR.W    edit_cursor_y
  3900.     BSR    set_edit_scroller
  3901.     BSR    refresh_instr_parameters
  3902.     BSR    refresh_song_parameters
  3903.     BSR.S    sort_for_min_swaps
  3904.     LEA    load_sort_list,A0
  3905.     MOVEQ    #31-1,D0
  3906. .load    MOVE.L    (A0)+,D1            load instruments
  3907.     MOVE.W    D1,current_instr
  3908.     MOVEM.L    D0/D1/A0,-(SP)
  3909.     BSR    load_sample_file
  3910.     MOVEM.L    (SP)+,D0/D1/A0
  3911.     DBRA    D0,.load
  3912.     MOVE.W    #1,current_instr
  3913.     MOVE.L    #6,tempo
  3914.     BRA    refresh_instr_parameters
  3915.  
  3916. sort_for_min_swaps
  3917.     MOVEM.L    D0/D1/D3/D4/A0/A1,-(SP)        sort samples for loading
  3918.     MOVE.L    song_file_ptr,A0        with minimum disk swaps
  3919.     ADD.L    #sf_instr+3,A0
  3920.     LEA    load_sort_list,A1        get ST no. and sample no.
  3921.     MOVEQ    #1,D0
  3922. .list    MOVE.B    (A0)+,(A1)+
  3923.     MOVE.B    (A0),(A1)+
  3924.     MOVE.W    D0,(A1)+
  3925.     ADD.L    #in_size-1,A0
  3926.     ADDQ.L    #1,D0
  3927.     CMPI.L    #32,D0
  3928.     BNE.S    .list
  3929. .outer    CLR.W    load_sort_flag        bubble sort according to ST no.
  3930.     LEA    load_sort_list,A0
  3931.     MOVEQ    #30-1,D2
  3932. .inner    MOVE.W    (A0),D0
  3933.     MOVE.W    4(A0),D1
  3934.     CMP.W    D1,D0
  3935.     BGT.S    .swapem
  3936. .next    ADDQ.L    #4,A0
  3937.     DBRA    D2,.inner
  3938.     TST.W    load_sort_flag
  3939.     BNE.S    .outer
  3940.     LEA    load_sort_list,A0    clear ST nos. leaving sample nos.
  3941.     MOVEQ    #31-1,D0
  3942. .tidy    CLR.W    (A0)
  3943.     ADDQ.L    #4,A0
  3944.     DBRA    D0,.tidy
  3945.     MOVEM.L    (SP)+,D0/D1/D3/D4/A0/A1
  3946.     RTS
  3947. .swapem    MOVE.W    #1,load_sort_flag
  3948.     MOVE.L    (A0),D3
  3949.     MOVE.L    4(A0),D4
  3950.     MOVE.L    D4,(A0)
  3951.     MOVE.L    D3,4(A0)
  3952.     BRA.S    .next
  3953.  
  3954. convert_old_format
  3955.     MOVE.L    song_file_ptr,A0    convert old files
  3956.     MOVE.L    A0,A1            shift up patterns for 16 extra
  3957.     ADD.L    #sf_instr+15*in_size+64*1024,A0        instruments
  3958.     ADD.L    #sf_instr+15*in_size-4,A1
  3959. .copyup    MOVE.L    (A0),16*in_size+4(A0)
  3960.     CLR.L    (A0)
  3961.     SUBQ.L    #4,A0
  3962.     CMP.L    A0,A1
  3963.     BNE.S    .copyup
  3964.     MOVE.L    song_file_ptr,A0
  3965.     MOVE.L    A0,A1
  3966.     ADD.L    #sf_length,A0        insert M.K. identifier
  3967.     ADD.L    #sf_ident,A1
  3968. .copydn    MOVE.W    4(A0),(A0)+
  3969.     CMP.L    A0,A1
  3970.     BNE.S    .copydn
  3971.     MOVE.L    #'M.K.',(A0)
  3972.     RTS
  3973.  
  3974. * STOP PLAYING/EDITING
  3975.  
  3976. fn_stop
  3977.     BSR    arrow_is_grey        arrow grey
  3978.     CLR.B    key_code        cancel keyboard
  3979.     CLR.L    edit_mode        leave edit mode
  3980.     CLR.L    play_mode        stop playing
  3981.     CLR.W    keyplay_channel        cancel keyboard note playing
  3982.     MOVE.W    #15,_custom+dmacon    cancel audio dma
  3983.     RTS
  3984.  
  3985. get_plst_file
  3986.     BSR    save_arrow_colours
  3987.     TST.L    plst_ptr        skip if no plst or instr 0
  3988.     BEQ.S    .skip
  3989.     TST.W    current_instr
  3990.     BEQ.S    .skip
  3991.     CLR.B    key_code
  3992.     MOVE.W    plst_entry_no,D0
  3993.     SUBQ.W    #1,D0
  3994.     MULU    #in_size,D0
  3995.     MOVE.L    plst_ptr,A0        a0=entry in plst
  3996.     ADD.L    D0,A0
  3997.     MOVE.W    current_instr,D0
  3998.     MULU    #in_size,D0
  3999.     MOVE.L    song_file_ptr,A1    a1=instr entry in song
  4000.     LEA    sf_instr-in_size(A1,D0.W),A1
  4001.     MOVE.L    A1,A2
  4002.     MOVEQ    #in_size-1,D0        copy params
  4003. .copy    MOVE.B    (A0)+,(A1)+
  4004.     DBRA    D0,.copy
  4005.     TST.W    in_replen(A2)        if replen=0 then =1
  4006.     BNE.S    .not0
  4007.     MOVE.W    #1,in_replen(A2)
  4008. .not0    BSR    load_sample_file
  4009. .skip    BSR    refresh_instr_parameters
  4010.     BRA    restore_arrow_colours
  4011.  
  4012. * EDIT SONG
  4013.  
  4014. fn_edit    BSR    fn_stop            stop tune
  4015.     BSR    arrow_is_blue        reset scroller
  4016.     BSR    set_edit_scroller
  4017.     MOVE.L    #'edit',edit_mode    mode=edit
  4018.     RTS
  4019.  
  4020. save_song
  4021.     BSR    fn_stop
  4022.     CLR.B    key_code
  4023.     MOVE.L    song_file_ptr,A0
  4024.     ADD.L    #sf_parts,A0        find maximum pattern no. used
  4025.     MOVEQ    #0,D0
  4026.     MOVEQ    #0,D1
  4027.     MOVEQ    #0,D2
  4028.     CLR.W    max_pat_no
  4029. .getmax    MOVE.B    0(A0,D0.W),D1
  4030.     ADDQ.W    #1,D0
  4031.     CMPI.W    #128,D0
  4032.     BGT.S    .gotmax
  4033.     MOVE.W    max_pat_no,D2
  4034.     CMP.W    D2,D1
  4035.     BLE.S    .getmax
  4036.     MOVE.W    D1,max_pat_no
  4037.     BRA.S    .getmax
  4038. .gotmax    MOVE.L    song_file_ptr,A0
  4039.     LEA    songs_dir_name(PC),A1    copy song name to filename
  4040.     MOVEQ    #20-1,D0
  4041. .cname    MOVE.B    (A0)+,(A1)+
  4042.     DBRA    D0,.cname
  4043.     MOVE.L    #songs_dir,file_nameptr
  4044.     MOVE.L    song_file_ptr,file_addr
  4045.     MOVE.L    #sf_patterns,file_length    length=header+1024*(max+1)
  4046.     MOVEQ    #0,D0
  4047.     MOVE.W    max_pat_no,D0
  4048.     ADDQ.L    #1,D0
  4049.     LSL.L    #8,D0
  4050.     LSL.L    #2,D0
  4051.     ADD.L    D0,file_length
  4052.     BSR.S    external_lengths
  4053.     TST.W    pack_flag        pack if required
  4054.     BEQ.S    .nopack
  4055.     BSR.S    pack_song
  4056.     BSR    save_a_file
  4057.     BSR    unpack_song        (unpack after save)
  4058.     BSR.S    internal_lengths
  4059.     BRA    arrow_is_grey
  4060. .nopack    BSR    save_a_file
  4061.     BSR.S    internal_lengths
  4062.     BRA    arrow_is_grey
  4063.  
  4064. external_lengths
  4065.     LEA    instr_header+4,A1
  4066.     MOVE.L    song_file_ptr,A0    add header lengths for save
  4067.     ADD.L    #sf_instr+in_length,A0
  4068.     MOVEQ    #31-1,D7
  4069. .loop    MOVE.L    (A1)+,D0        /2 for word length
  4070.     LSR.L    #1,D0
  4071.     ADD.W    D0,(A0)
  4072.     ADD.L    #in_size,A0
  4073.     DBRA    D7,.loop
  4074.     RTS
  4075.  
  4076. internal_lengths
  4077.     LEA    instr_header+4,A1
  4078.     MOVE.L    song_file_ptr,A0    sub header lengths for internal use
  4079.     ADD.L    #sf_instr+in_length,A0
  4080.     MOVEQ    #31-1,D7
  4081. .loop    MOVE.L    (A1)+,D0
  4082.     LSR.L    #1,D0
  4083.     SUB.W    D0,(A0)
  4084.     ADD.L    #in_size,A0
  4085.     DBRA    D7,.loop
  4086.     RTS
  4087.  
  4088. pack_song
  4089.     BSR    arrow_is_grey
  4090.     MOVE.L    song_file_ptr,A0
  4091.     MOVE.L    A0,A1
  4092.     ADD.L    #12,A1
  4093.     MOVE.L    A1,pack_dest_start    dest for packed file
  4094.     MOVE.L    A0,A1
  4095.     ADD.L    #sf_size,A1
  4096.     MOVE.L    A1,pack_source_end    end of workspace
  4097.     MOVE.L    A0,A1
  4098.     ADD.L    #sf_size,A1
  4099.     SUB.L    file_length,A1
  4100.     MOVE.L    A1,pack_buffer_ptr    start of unpacked file
  4101.     MOVE.L    file_length,unpacked_size
  4102.     MOVE.L    song_file_ptr,A0
  4103.     ADD.L    file_length,A0        copy up unpacked file
  4104.     MOVE.L    song_file_ptr,A1
  4105.     ADD.L    #sf_size,A1
  4106.     MOVE.L    file_length,D0
  4107. .copyup    MOVE.B    -(A0),-(A1)
  4108.     SUBQ.L    #1,D0
  4109.     BNE.S    .copyup
  4110.     BSR.S    cruncher
  4111.     SUB.L    pack_dest_start,A2        packed size
  4112.     MOVE.L    A2,D0
  4113.     MOVE.L    D0,packed_size
  4114.     MOVE.L    D0,D1
  4115.     ADD.L    pack_dest_start,D1
  4116.     MOVE.L    D1,pack_dest_end        end of packed file (UNUSED)
  4117.     MOVE.L    song_file_ptr,A0
  4118.     MOVE.L    #'PACK',(A0)            set id,sizes
  4119.     MOVE.L    packed_size,4(A0)
  4120.     MOVE.L    unpacked_size,8(A0)
  4121.     MOVE.L    song_file_ptr,file_addr        file address,length
  4122.     MOVE.L    packed_size,D0
  4123.     ADD.L    #12,D0
  4124.     MOVE.L    D0,file_length
  4125.     RTS
  4126.  
  4127. *------------------------------
  4128. * FILE CRUNCHER
  4129. * entry    pack_buffer_ptr = source start
  4130. *    pack_source_end = source end +1
  4131. *    pack_dest_start = dest
  4132.  
  4133. cruncher
  4134.     MOVE.L    pack_buffer_ptr,A0    a0=source
  4135.     MOVE.L    pack_source_end,A1    a1=source end+1
  4136.     MOVE.L    pack_dest_start,A2    a2=dest
  4137.     MOVEQ    #1,D2            d2=dest long bit buffer
  4138.     CLR.W    D1            d1=count of unpackable bytes
  4139. .loop    BSR.S    .scan            try to pack
  4140.     TST.B    D0
  4141.     BEQ.S    .next
  4142.     ADDQ.W    #1,D1            if byte not packed then
  4143.     CMPI.W    #264,D1                count+1
  4144.     BNE.S    .next                if count=264 then
  4145.     BSR    .put_fill                save fill
  4146. .next    CMP.L    A0,A1            if source<end then loop
  4147.     BGT.S    .loop
  4148.     BSR    .put_fill        save fill
  4149.     BRA    .put_last_long        empty bit buffer
  4150.  
  4151. .scan    MOVE.L    A0,A3            a3=source+127
  4152.     ADD.L    #127,A3
  4153.     CMP.L    A1,A3            if a3>end then a3=end
  4154.     BLE.S    .scan2
  4155.     MOVE.L    A1,A3
  4156. .scan2    MOVEQ    #1,D5            d5=longest match, init 1
  4157.     MOVE.L    A0,A5            a5=source+1
  4158.     ADDQ.L    #1,A5
  4159. .get_pair
  4160.     MOVE.B    (A0),D3            d3,d4=next 2 source bytes
  4161.     MOVE.B    1(A0),D4
  4162. .compare
  4163.     CMP.B    (A5)+,D3        search for match
  4164.     BNE.S    .compare2
  4165.     CMP.B    (A5),D4
  4166.     BEQ.S    .matched_pair
  4167. .compare2
  4168.     CMP.L    A5,A3            if none then loop
  4169.     BGT.S    .compare        if all tried then no match
  4170.     BRA.S    .no_match
  4171. .matched_pair
  4172.     SUBQ.L    #1,A5            if match then
  4173.     MOVE.L    A0,A4            a4=source,a5=matched string
  4174. .find_length
  4175.     MOVE.B    (A4)+,D3        find length of matched string
  4176.     CMP.B    (A5)+,D3
  4177.     BNE.S    .found_length
  4178.     CMP.L    A5,A3
  4179.     BGT.S    .find_length
  4180. .found_length
  4181.     MOVE.L    A4,D3            d3=length
  4182.     SUB.L    A0,D3
  4183.     SUBQ.L    #1,D3
  4184.     CMP.L    D3,D5            if <= previous best then skip
  4185.     BGE.S    .no_good
  4186.     MOVE.L    A5,D4            d4=distance
  4187.     SUB.L    A0,D4
  4188.     SUB.L    D3,D4
  4189.     SUBQ.L    #1,D4
  4190.     CMPI.L    #4,D3            if distance>4 then
  4191.     BLE.S    .small
  4192.     MOVEQ    #6,D6                mode 3
  4193.     CMPI.L    #257,D3                limit length to 256
  4194.     BLT.S    .big
  4195.     MOVE.W    #256,D3
  4196. .big    BRA.S    .usable
  4197. .small    MOVE.W    D3,D6            if distance=1,2 or 3 then
  4198.     SUBQ.W    #2,D6                mode 0,1 or 2
  4199.     LSL.W    #1,D6
  4200. .usable    LEA    .copy_table,A6        if distance usable then
  4201.     CMP.W    0(A6,D6.W),D4
  4202.     BGE.S    .no_good
  4203.     MOVE.L    D3,D5                d5=best length
  4204.     MOVE.L    D4,pack_best_distance        save distance
  4205.     MOVE.B    D6,pack_best_mode        save mode
  4206. .no_good
  4207.     CMP.L    A5,A3            repeat
  4208.     BGT.S    .get_pair
  4209. .no_match
  4210.     CMPI.L    #1,D5            if best length=1 then
  4211.     BEQ.S    .put_byte            save byte for fill
  4212.     BSR.S    .put_fill        else save previous fill
  4213.     MOVE.B    pack_best_mode,D6
  4214.     MOVE.L    pack_best_distance,D3
  4215.     MOVE.W    8(A6,D6.W),D0
  4216.     BSR    .put_bits        put mode bits
  4217.     MOVE.W    16(A6,D6.W),D0
  4218.     BEQ.S    .no_count
  4219.     MOVE.L    D5,D3            put count bits (if any)
  4220.     SUBQ.W    #1,D3
  4221.     BSR    .put_bits
  4222. .no_count
  4223.     MOVE.W    24(A6,D6.W),D0
  4224.     MOVE.W    32(A6,D6.W),D3
  4225.     BSR.S    .put_bits        put distance bits
  4226.     ADD.W    #1,40(A6,D6.W)
  4227.     ADD.L    D5,A0
  4228.     CLR.B    D0
  4229.     RTS
  4230.  
  4231. .put_byte
  4232.     MOVE.B    (A0)+,D3
  4233.     MOVEQ    #8,D0
  4234.     BSR.S    .put_bits
  4235.     MOVEQ    #1,D0
  4236.     RTS
  4237.  
  4238. .copy_table
  4239.     dc.w    256,512,1024,4096    max distance
  4240.     dc.w    8,9,10,8        address bits
  4241.     dc.w    0,0,0,8            count bits
  4242.     dc.w    2,3,3,3            no. of header bits
  4243.     dc.w    %01,%100,%101,%110    header code
  4244.     dc.w    0,0,0,0            no. of times command used
  4245.  
  4246. .put_fill
  4247.     TST.W    D1            d1=count
  4248.     BEQ.S    .pf2
  4249.     MOVE.W    D1,D3
  4250.     CLR.W    D1
  4251.     CMPI.W    #9,D3            if count<9 then
  4252.     BGE.S    .pf3
  4253.     ADDQ.W    #1,pack_used_00            bump usage count (UNUSED)
  4254.     SUBQ.W    #1,D3                1..8 => 0..7
  4255.     MOVEQ    #5,D0                put bits : 00nnn
  4256.     BRA.S    .put_bits
  4257. .pf2    RTS                if count>=9 then
  4258. .pf3    ADDQ.W    #1,pack_used_111        bump usage count (UNUSED)
  4259.     SUB.W    #9,D3                9..264 => 0..255
  4260.     OR.W    #$700,D3            put bits : 111nnnnnnnn
  4261.     MOVEQ    #11,D0
  4262.  
  4263. .put_bits
  4264.     SUBQ.W    #1,D0        d0=no. of bits, d3=bits
  4265. .pb2    LSR.L    #1,D3
  4266.     ROXL.L    #1,D2
  4267.     BCS.S    .put_long
  4268.     DBRA    D0,.pb2
  4269.     RTS
  4270.  
  4271. .put_last_long
  4272.     CLR.W    D0
  4273. .put_long
  4274.     MOVE.L    D2,(A2)+
  4275.     MOVEQ    #1,D2
  4276.     DBRA    D0,.pb2
  4277.     RTS
  4278.  
  4279. *------------------------------
  4280.  
  4281. unpack_song
  4282.     MOVE.L    song_file_ptr,A0
  4283.     ADD.L    #12,A0            skip header
  4284.     MOVE.L    pack_buffer_ptr,A1    decrunch
  4285.     MOVE.L    packed_size,D0
  4286.     MOVE.L    unpacked_size,D1
  4287.     BSR.S    decruncher
  4288.     MOVE.L    pack_buffer_ptr,A0    copy down
  4289.     MOVE.L    song_file_ptr,A1
  4290.     MOVE.L    unpacked_size,D0
  4291. .down    MOVE.B    (A0)+,(A1)+
  4292.     SUBQ.L    #1,D0
  4293.     BNE.S    .down
  4294.     MOVE.L    song_file_ptr,A0    clear rest of song file
  4295.     ADD.L    #sf_size,A0
  4296.     MOVE.L    song_file_ptr,A1
  4297.     ADD.L    unpacked_size,A1
  4298.     SUB.L    A1,A0
  4299.     MOVE.L    A0,D0
  4300. .tidy    CLR.B    (A1)+
  4301.     SUBQ.L    #1,D0
  4302.     BNE.S    .tidy
  4303.     RTS
  4304.  
  4305. *------------------------------
  4306. * FILE DECRUNCHER
  4307. * entry    a0=source
  4308. *    a1=dest
  4309. *    d0=packed size
  4310. *    d1=unpacked size
  4311. * format
  4312. *    00nnn            : fill next 1..8 bytes
  4313. *    01aaaaaaaa        : copy 2 bytes from dest+0..255
  4314. *    100aaaaaaaaa        : copy 3 bytes from dest+0..511
  4315. *    101aaaaaaaaaa        : copy 4 bytes from dest+0..1023
  4316. *    110nnnnnnnnaaaaaaaa    : copy 1..256 bytes from dest+0..255
  4317. *    111nnnnnnnn        : fill next 9..264 bytes
  4318.  
  4319. decruncher
  4320.     ADD.L    D0,A0        a0=source ptr
  4321.     MOVE.L    D1,A2        a2=dest ptr
  4322.     ADD.L    A1,A2
  4323.     MOVE.L    -(A0),D0
  4324. .loop    LSR.L    #1,D0
  4325.     BNE.S    .ok
  4326.     BSR.S    .get_long
  4327. .ok    BCS.S    .com1xx
  4328.     MOVEQ    #8,D1
  4329.     MOVEQ    #2-1,D3
  4330.     LSR.L    #1,D0
  4331.     BNE.S    .ok2
  4332.     BSR.S    .get_long
  4333. .ok2    BCS.S    .copy
  4334.     MOVEQ    #3,D1
  4335.     CLR.W    D4
  4336. .fill    BSR.S    .get_bits
  4337.     MOVE.W    D2,D3
  4338.     ADD.W    D4,D3
  4339. .fill2    MOVEQ    #8-1,D1
  4340. .fill3    LSR.L    #1,D0
  4341.     BNE.S    .ok3
  4342.     BSR.S    .get_long
  4343. .ok3    ROXL.L    #1,D2
  4344.     DBRA    D1,.fill3
  4345.     MOVE.B    D2,-(A2)
  4346.     DBRA    D3,.fill2
  4347.     BRA.S    .next
  4348. .com111    MOVEQ    #8,D1
  4349.     MOVEQ    #8,D4
  4350.     BRA.S    .fill
  4351. .com1xx    MOVEQ    #2,D1
  4352.     BSR.S    .get_bits
  4353.     CMPI.B    #2,D2
  4354.     BLT.S    .com10x
  4355.     CMPI.B    #3,D2
  4356.     BEQ.S    .com111
  4357.     MOVEQ    #8,D1
  4358.     BSR.S    .get_bits
  4359.     MOVE.W    D2,D3
  4360.     MOVE.W    #8,D1
  4361.     BRA.S    .copy
  4362. .com10x    MOVE.W    #9,D1
  4363.     ADD.W    D2,D1
  4364.     ADDQ.W    #2,D2
  4365.     MOVE.W    D2,D3
  4366. .copy    BSR.S    .get_bits
  4367. .copy2    SUBQ.W    #1,A2
  4368.     MOVE.B    0(A2,D2.W),(A2)
  4369.     DBRA    D3,.copy2
  4370. .next    CMP.L    A2,A1
  4371.     BLT.S    .loop
  4372.     RTS
  4373.  
  4374. .get_long
  4375.     MOVE.L    -(A0),D0
  4376.     MOVE    #$10,CCR
  4377.     ROXR.L    #1,D0
  4378.     RTS
  4379.  
  4380. .get_bits
  4381.     SUBQ.W    #1,D1
  4382.     CLR.W    D2
  4383. .get_bits2
  4384.     LSR.L    #1,D0
  4385.     BNE.S    .get_bits3
  4386.     MOVE.L    -(A0),D0
  4387.     MOVE    #$10,CCR
  4388.     ROXR.L    #1,D0
  4389. .get_bits3
  4390.     ROXL.L    #1,D2
  4391.     DBRA    D1,.get_bits2
  4392.     RTS
  4393.  
  4394. *------------------------------
  4395.  
  4396. load_module
  4397.     BSR    fn_stop
  4398.     BSR    arrow_is_green
  4399.     CLR.B    key_code
  4400.     BSR    free_instr_memory    clear instruments
  4401.     MOVE.L    song_file_ptr,A0
  4402.     ADD.L    #sf_patterns,A0
  4403.     MOVE.W    #(64*1024)/4-1,D0
  4404. .wipe    CLR.L    (A0)+
  4405.     DBRA    D0,.wipe
  4406.     LEA    modules_dir,A0        name=dir+name
  4407.     LEA    modname_buffer,A1
  4408.     MOVEQ    #16-1,D1
  4409. .dir    MOVE.B    (A0)+,D0
  4410.     BEQ.S    .plus
  4411.     MOVE.B    D0,(A1)+
  4412.     DBRA    D1,.dir
  4413. .plus    LEA    selected_filename,A0
  4414.     MOVEQ    #28-1,D0
  4415. .name    MOVE.B    (A0)+,(A1)+
  4416.     DBRA    D0,.name
  4417.     MOVE.L    DOSbase,A6
  4418.     MOVE.L    #modname_buffer,D1
  4419.     MOVE.L    #1005,D2        read
  4420.     JSR    _LVOOpen(A6)
  4421.     TST.L    D0            error if fail
  4422.     BEQ    load_error
  4423.     MOVE.L    D0,file_handle
  4424.     MOVE.L    D0,D1
  4425.     MOVE.L    song_file_ptr,D2    read header
  4426.     MOVE.L    #sf_patterns,D3
  4427.     JSR    _LVORead(A6)
  4428.     MOVE.L    song_file_ptr,A0
  4429.     CMP.L    #'M.K.',sf_ident(A0)    if not M.K. file then
  4430.     BEQ.S    .is_mk
  4431.     MOVE.L    file_handle,D1            back to start
  4432.     MOVEQ    #0,D2
  4433.     MOVEQ    #-1,D3
  4434.     JSR    _LVOSeek(A6)
  4435.     MOVE.L    file_handle,D1
  4436.     MOVE.L    song_file_ptr,D2        read smaller header
  4437.     MOVE.L    #$258,D3
  4438.     JSR    _LVORead(A6)
  4439.     BSR    convert_old_format        convert to MK format
  4440. .is_mk    MOVE.L    song_file_ptr,A0
  4441.     CMP.B    #120,sf_restart(A0)    if restart<>120 then =0
  4442.     BNE.S    .not120
  4443.     CLR.B    sf_restart(A0)
  4444. .not120    ADD.L    #sf_parts,A0
  4445.     MOVEQ    #128-1,D0            find maximum pattern no.
  4446.     MOVEQ    #0,D3
  4447. .getmax    CMP.B    (A0)+,D3
  4448.     BGT.S    .gotmax
  4449.     MOVE.B    -1(A0),D3
  4450. .gotmax    DBRA    D0,.getmax
  4451.     ADDQ.W    #1,D3
  4452.     MULU    #1024,D3            read patterns
  4453.     MOVE.L    file_handle,D1
  4454.     MOVE.L    song_file_ptr,D2
  4455.     ADD.L    #sf_patterns,D2
  4456.     JSR    _LVORead(A6)
  4457.     CLR.L    pattern_no            setup display
  4458.     CLR.L    song_position
  4459.     BSR    refresh_song_position
  4460.     BSR    refresh_pattern_display
  4461.     CLR.W    edit_cursor_y
  4462.     BSR    set_edit_scroller
  4463.     BSR    refresh_instr_parameters
  4464.     BSR    refresh_song_parameters
  4465.     MOVE.W    #1,current_instr        load instruments
  4466. .iloop    BSR    refresh_instr_parameters
  4467.     MOVE.L    song_file_ptr,A0
  4468.     MOVE.W    current_instr,D7
  4469.     MULU    #in_size,D7
  4470.     MOVEQ    #0,D0
  4471.     MOVE.W    sf_instr+in_length-in_size(A0,D7.W),D0    skip if empty
  4472.     BEQ.S    .inext
  4473.     ADD.L    D0,D0
  4474.     MOVE.L    4.w,a6
  4475.     MOVE.L    #MEMF_CLEAR+MEMF_CHIP,D1    allocate memory
  4476.     MOVE.L    D0,-(SP)
  4477.     JSR    _LVOAllocMem(A6)
  4478.     MOVE.L    (SP)+,D6
  4479.     MOVE.W    current_instr,D7
  4480.     LSL.W    #2,D7
  4481.     LEA    instr_addr_list,A0
  4482.     MOVE.L    D0,0(A0,D7.W)
  4483.     TST.L    D0                skip if no room
  4484.     BEQ.S    .inext
  4485.     LEA    instr_alloc_list-4,A0
  4486.     MOVE.L    D0,0(A0,D7.W)            save addr,size
  4487.     MOVE.L    D6,$7C(A0,D7.W)
  4488.     LEA    instr_alloc_list-4,A0
  4489.     MOVE.L    DOSbase,A6
  4490.     MOVE.L    file_handle,D1
  4491.     MOVE.L    D0,D2
  4492.     MOVE.L    D6,D3
  4493.     JSR    _LVORead(A6)
  4494. .inext    MOVE.W    #1,memory_flag            memory usage changed
  4495.     ADDQ.W    #1,current_instr        next instrument
  4496.     CMP.W    #32,current_instr
  4497.     BNE    .iloop
  4498.     MOVE.L    file_handle,D1
  4499.     JSR    _LVOClose(A6)
  4500.     MOVE.W    #1,current_instr        setup
  4501.     MOVE.L    #6,tempo
  4502.     BSR    arrow_is_grey
  4503.     BRA    refresh_instr_parameters
  4504.  
  4505. load_error
  4506.     MOVE.L    cptr_arrow_col,A0
  4507.     MOVE.W    #$C00,2(A0)        arrow red
  4508.     MOVE.W    #$900,6(A0)
  4509.     MOVE.W    #$700,10(A0)
  4510.     BSR    fn_clear_nocheck    clear song
  4511.     BRA    arrow_is_grey
  4512.  
  4513. save_module
  4514.     BSR    arrow_is_green
  4515.     MOVE.L    song_file_ptr,A0    find maximum pattern no.
  4516.     ADD.L    #sf_parts,A0
  4517.     MOVEQ    #0,D0
  4518.     MOVEQ    #0,D1
  4519.     MOVEQ    #0,D2
  4520.     CLR.W    max_pat_no
  4521. .getmax    MOVE.B    0(A0,D0.W),D1
  4522.     ADDQ.W    #1,D0
  4523.     CMPI.W    #128,D0
  4524.     BGT.S    .gotmax
  4525.     MOVE.W    max_pat_no,D2
  4526.     CMP.W    D2,D1
  4527.     BLE.S    .getmax
  4528.     MOVE.W    D1,max_pat_no
  4529.     BRA.S    .getmax
  4530. .gotmax    LEA    save_mod_name(PC),A0    name=dir+'mod.'+songname
  4531.     MOVEQ    #56-1,D0
  4532. .wname    CLR.B    (A0)+
  4533.     DBRA    D0,.wname
  4534.     LEA    modules_dir,A0
  4535.     LEA    save_mod_name,A1
  4536.     MOVEQ    #16-1,D1
  4537. .dir    MOVE.B    (A0)+,D0
  4538.     BEQ.S    .mod
  4539.     MOVE.B    D0,(A1)+
  4540.     DBRA    D1,.dir
  4541. .mod    MOVE.B    #'m',(A1)+
  4542.     MOVE.B    #'o',(A1)+
  4543.     MOVE.B    #'d',(A1)+
  4544.     MOVE.B    #'.',(A1)+
  4545.     MOVE.L    song_file_ptr,A0
  4546.     MOVEQ    #28-1,D0
  4547. .name    MOVE.B    (A0)+,(A1)+
  4548.     DBRA    D0,.name
  4549.     MOVE.L    song_file_ptr,file_addr
  4550.     MOVE.L    #sf_patterns,file_length
  4551.     MOVEQ    #0,D0
  4552.     MOVE.W    max_pat_no,D0
  4553.     ADDQ.L    #1,D0
  4554.     LSL.L    #8,D0
  4555.     LSL.L    #2,D0
  4556.     ADD.L    D0,file_length
  4557.     BSR.S    .open            save header, patterns
  4558.     BNE.S    .error
  4559.     BSR    .write
  4560.     BNE.S    .error
  4561.     MOVEQ    #1,D6
  4562. .instr    BSR.S    .save_instr        save instruments
  4563.     ADDQ.B    #1,D6
  4564.     CMPI.B    #32,D6
  4565.     BNE.S    .instr
  4566.     BSR    .close
  4567.     BRA    arrow_is_grey
  4568. .error    BRA    arrow_flash_red
  4569.  
  4570. .save_instr
  4571.     MOVE.W    D6,D0            index instrument info
  4572.     LSL.W    #2,D0
  4573.     LEA    instr_alloc_list-4,A0
  4574.     MOVE.L    0(A0,D0.W),D1
  4575.     BEQ.S    .no_instr
  4576.     TST.L    $7C(A0,D0.W)        skip if empty
  4577.     BEQ.S    .no_instr
  4578.     LEA    instr_addr_list,A0
  4579.     MOVE.L    0(A0,D0.W),D1
  4580.     MOVE.L    D1,file_addr
  4581.     MOVE.L    song_file_ptr,A0    save it
  4582.     ADD.L    #sf_instr+in_length-in_size,A0
  4583.     MOVE.W    D6,D0
  4584.     MULU    #in_size,D0
  4585.     ADD.L    D0,A0
  4586.     MOVEQ    #0,D0
  4587.     MOVE.W    (A0),D0
  4588.     ASL.L    #1,D0
  4589.     MOVE.L    D0,file_length
  4590.     BNE.S    .write
  4591. .no_instr
  4592.     RTS
  4593.  
  4594. .open    MOVE.L    DOSbase,A6
  4595.     MOVE.L    #save_mod_name,D1
  4596.     MOVE.L    #1006,D2
  4597.     JSR    _LVOOpen(A6)
  4598.     MOVE.L    D0,D7
  4599.     BEQ.S    .ferror
  4600.     MOVEQ    #0,D0
  4601.     RTS
  4602. .ferror    MOVEQ    #-1,D0
  4603.     RTS
  4604.  
  4605. .write    MOVE.L    DOSbase,A6
  4606.     MOVE.L    D7,D1
  4607.     MOVE.L    file_addr,D2
  4608.     MOVE.L    file_length,D3
  4609.     JSR    _LVOWrite(A6)
  4610.     TST.L    D0
  4611.     BEQ.S    .ferror
  4612.     MOVEQ    #0,D0
  4613.     RTS
  4614.  
  4615. .close    MOVE.L    DOSbase,A6
  4616.     MOVE.L    D7,D1
  4617.     JMP    _LVOClose(A6)
  4618.  
  4619. save_mod_name
  4620.     ds.b    56
  4621.  
  4622. * PLAY PATTERN
  4623.  
  4624. fn_play_pattern
  4625.     BTST    #6,$BFE001        wait till button released
  4626.     BEQ.S    fn_play_pattern
  4627.     CLR.L    edit_mode        cancel edit mode
  4628.     BSR    fn_stop
  4629.     BSR    arrow_is_yellow
  4630.     MOVE.L    #'patt',play_mode    mode=play pattern
  4631.  
  4632. enable_scroller
  4633.     CLR.W    keyplay_channel
  4634.     MOVE.L    cptr_con0c,A0        enable plane 3
  4635.     MOVE.W    #$3200,(A0)
  4636.     CLR.L    play_cursor
  4637.     RTS
  4638.  
  4639. alter_repeat
  4640.     MOVE.L    song_file_ptr,A0
  4641.     ADD.L    #sf_instr+in_length-in_size,A0
  4642.     MOVEQ    #0,D0
  4643.     MOVE.W    current_instr,D0
  4644.     TST.W    D0
  4645.     BEQ.S    .skip
  4646.     MULU    #in_size,D0
  4647.     ADD.L    D0,A0
  4648.     CMP.W    #-1,alter_dir
  4649.     BEQ.S    .down
  4650.     ADDQ.W    #1,in_repeat-in_length(A0)
  4651.     BTST    #2,_custom+potinp
  4652.     BNE.S    .slow
  4653.     ADDQ.W    #7,in_repeat-in_length(A0)
  4654. .slow    MOVE.W    (A0),D0
  4655.     SUB.W    in_replen-in_length(A0),D0
  4656.     CMP.W    in_repeat-in_length(A0),D0
  4657.     BGT.S    .skip
  4658.     TST.W    D0
  4659.     BPL.S    .ok
  4660.     CLR.W    in_repeat-in_length(A0)
  4661.     BRA    refresh_instr_parameters
  4662. .ok    MOVE.W    D0,in_repeat-in_length(A0)
  4663. .skip    BRA    refresh_instr_parameters
  4664. .down    SUBQ.W    #1,in_repeat-in_length(A0)
  4665.     BTST    #2,_custom+potinp
  4666.     BNE.S    .slow2
  4667.     SUBQ.W    #7,in_repeat-in_length(A0)
  4668. .slow2    TST.W    in_repeat-in_length(A0)
  4669.     BPL.S    .skip
  4670.     CLR.W    in_repeat-in_length(A0)
  4671.     BRA.S    .skip
  4672.  
  4673. alter_replen
  4674.     MOVE.L    song_file_ptr,A0
  4675.     ADD.L    #sf_instr+in_length-in_size,A0
  4676.     MOVEQ    #0,D0
  4677.     MOVE.W    current_instr,D0
  4678.     TST.W    D0
  4679.     BEQ.S    .skip
  4680.     MULU    #in_size,D0
  4681.     ADD.L    D0,A0
  4682.     CMP.W    #-1,alter_dir
  4683.     BEQ.S    .down
  4684.     ADDQ.W    #1,in_replen-in_length(A0)
  4685.     BTST    #2,_custom+potinp
  4686.     BNE.S    .slow
  4687.     ADDQ.W    #7,in_replen-in_length(A0)
  4688. .slow    MOVE.W    (A0),D0
  4689.     SUB.W    in_repeat-in_length(A0),D0
  4690.     CMP.W    in_replen-in_length(A0),D0
  4691.     BGT.S    .skip
  4692.     TST.W    D0
  4693.     BNE.S    .ok
  4694.     MOVE.W    #1,in_replen-in_length(A0)
  4695.     BRA    refresh_instr_parameters
  4696. .ok    MOVE.W    D0,in_replen-in_length(A0)
  4697. .skip    BRA    refresh_instr_parameters
  4698. .down    SUBQ.W    #1,in_replen-in_length(A0)
  4699.     BTST    #2,_custom+potinp
  4700.     BNE.S    .slow2
  4701.     SUBQ.W    #7,in_replen-in_length(A0)
  4702. .slow2    CMP.W    #1,in_replen-in_length(A0)
  4703.     BGE.S    .skip
  4704.     MOVE.W    #1,in_replen-in_length(A0)
  4705.     BRA.S    .skip
  4706.  
  4707. alter_instr_length
  4708.     MOVE.L    song_file_ptr,A0
  4709.     ADD.L    #sf_instr+in_length-in_size,A0
  4710.     MOVEQ    #0,D0
  4711.     MOVE.W    current_instr,D0
  4712.     TST.W    D0
  4713.     BEQ.S    .skip
  4714.     MULU    #in_size,D0
  4715.     ADD.L    D0,A0
  4716.     CMP.W    #-1,alter_dir
  4717.     BEQ.S    .down
  4718.     ADDQ.W    #1,(A0)
  4719.     BTST    #2,_custom+potinp
  4720.     BNE.S    .slow
  4721.     ADDQ.W    #7,(A0)
  4722. .slow    CMP.W    #$3FFF,(A0)
  4723.     BLE.S    .skip
  4724.     MOVE.W    #$3FFF,(A0)
  4725. .skip    BRA    refresh_instr_parameters
  4726. .down    SUBQ.W    #1,(A0)
  4727.     BTST    #2,_custom+potinp
  4728.     BNE.S    .slow2
  4729.     SUBQ.W    #7,(A0)
  4730. .slow2    MOVE.W    in_repeat-in_length(A0),D0
  4731.     ADD.W    in_replen-in_length(A0),D0
  4732.     CMP.W    (A0),D0
  4733.     BLE.S    .skip
  4734.     TST.W    in_repeat-in_length(A0)
  4735.     BEQ.S    .clip
  4736. .ok    MOVE.W    D0,(A0)
  4737.     BRA.S    .skip
  4738. .clip    CMP.W    #1,in_replen-in_length(A0)
  4739.     BNE.S    .ok
  4740.     CLR.W    (A0)
  4741.     BRA.S    .skip
  4742.  
  4743. alter_volume
  4744.     CMP.W    #-1,alter_dir
  4745.     BEQ.S    .down
  4746.     MOVE.L    song_file_ptr,A0
  4747.     ADD.L    #sf_instr+in_length-in_size,A0
  4748.     MOVEQ    #0,D0
  4749.     MOVE.W    current_instr,D0
  4750.     TST.W    D0
  4751.     BEQ.S    .skip
  4752.     MULU    #in_size,D0
  4753.     ADD.L    D0,A0
  4754.     ADDQ.W    #1,in_volume-in_length(A0)
  4755.     CMP.W    #64,in_volume-in_length(A0)
  4756.     BMI.S    .notmax
  4757.     MOVE.W    #64,in_volume-in_length(A0)
  4758. .notmax    BSR    refresh_instr_parameters
  4759.     BTST    #2,_custom+potinp
  4760.     BNE.S    .wait
  4761. .skip    RTS
  4762. .wait    MOVE.W    #$2000,D0
  4763. .wait2    DBRA    D0,.wait2
  4764.     RTS
  4765. .down    MOVE.L    song_file_ptr,A0
  4766.     ADD.L    #sf_instr+in_length-in_size,A0
  4767.     MOVEQ    #0,D0
  4768.     MOVE.W    current_instr,D0
  4769.     MULU    #in_size,D0
  4770.     ADD.L    D0,A0
  4771.     SUBQ.W    #1,in_volume-in_length(A0)
  4772.     TST.W    in_volume-in_length(A0)
  4773.     BPL.S    .notmin
  4774.     CLR.W    in_volume-in_length(A0)
  4775. .notmin    BSR    refresh_instr_parameters
  4776.     BTST    #2,_custom+potinp
  4777.     BEQ.S    .skip
  4778.     BRA.S    .wait
  4779.  
  4780. alter_instr_number
  4781.     TST.W    ain_disable        ?? (UNUSED)
  4782.     BEQ.S    .do_it
  4783.     BSR    refresh_instr_parameters
  4784.     CLR.W    ain_disable
  4785.     RTS
  4786. .do_it    BTST    #2,_custom+potinp    if right button then instr 0
  4787.     BNE.S    .no_rgt
  4788.     CLR.W    current_instr
  4789.     BRA    refresh_instr_parameters
  4790. .no_rgt    CMP.W    #-1,alter_dir
  4791.     BEQ.S    .down
  4792.     ADDQ.W    #1,current_instr
  4793.     CMP.W    #31,current_instr
  4794.     BMI.S    .notmax
  4795.     MOVE.W    #31,current_instr
  4796. .notmax    BSR    wait_20ms
  4797.     BSR    wait_20ms
  4798.     BRA    refresh_instr_parameters
  4799. .down    TST.W    current_instr
  4800.     BEQ.S    .notmin
  4801.     SUBQ.W    #1,current_instr
  4802.     CMP.W    #1,current_instr
  4803.     BPL.S    .notmin
  4804.     MOVE.W    #1,current_instr
  4805. .notmin    BSR    wait_20ms
  4806.     BSR    wait_20ms
  4807.     BRA    refresh_instr_parameters
  4808.  
  4809. alter_restart
  4810.     CMP.W    #-1,alter_dir
  4811.     BEQ.S    .down
  4812.     MOVE.L    song_file_ptr,A0
  4813.     ADD.L    #sf_length,A0
  4814.     ADDQ.B    #1,sf_restart-sf_length(A0)
  4815.     MOVE.B    sf_restart-sf_length(A0),D0
  4816.     CMP.B    (A0),D0
  4817.     BMI.S    .notmax
  4818.     MOVE.B    (A0),sf_restart-sf_length(A0)
  4819.     SUBQ.B    #1,sf_restart-sf_length(A0)
  4820. .notmax    BSR    refresh_song_parameters
  4821.     BTST    #2,_custom+potinp
  4822.     BEQ    wait_20ms
  4823.     BSR    wait_20ms
  4824.     BRA    wait_20ms
  4825. .down    MOVE.L    song_file_ptr,A0
  4826.     ADD.L    #sf_restart,A0
  4827.     SUBQ.B    #1,(A0)
  4828.     TST.B    (A0)
  4829.     BPL.S    .notmin
  4830.     CLR.B    (A0)
  4831. .notmin    BSR    refresh_song_parameters
  4832.     BTST    #2,_custom+potinp
  4833.     BEQ    wait_20ms
  4834.     BSR    wait_20ms
  4835.     BRA    wait_20ms
  4836.  
  4837. alter_song_length
  4838.     BSR    fn_stop
  4839.     CMP.W    #-1,alter_dir
  4840.     BEQ.S    .down
  4841.     MOVE.L    song_file_ptr,A0
  4842.     ADD.L    #sf_length,A0
  4843.     ADDQ.B    #1,(A0)
  4844.     CMP.B    #127,(A0)
  4845.     BMI.S    .notmax
  4846.     MOVE.B    #127,(A0)
  4847. .notmax    BSR    refresh_song_parameters
  4848.     BTST    #2,_custom+potinp
  4849.     BEQ    wait_20ms
  4850.     BSR    wait_20ms
  4851.     BRA    wait_20ms
  4852. .down    MOVE.L    song_file_ptr,A0
  4853.     ADD.L    #sf_length,A0
  4854.     SUBQ.B    #1,(A0)
  4855.     CMP.B    #1,(A0)
  4856.     BPL.S    .notmin
  4857.     MOVE.B    #1,(A0)
  4858. .notmin    MOVE.B    sf_restart-sf_length(A0),D0
  4859.     CMP.B    (A0),D0
  4860.     BNE.S    .notres
  4861.     ADDQ.B    #1,(A0)
  4862. .notres    BSR    refresh_song_parameters
  4863.     BTST    #2,_custom+potinp
  4864.     BEQ    wait_20ms
  4865.     BSR    wait_20ms
  4866.     BRA    wait_20ms
  4867.  
  4868. alter_song_pattern
  4869.     BSR    fn_stop
  4870.     CMP.W    #-1,alter_dir
  4871.     BEQ.S    .down
  4872.     MOVE.L    song_file_ptr,A0
  4873.     ADD.L    #sf_parts,A0
  4874.     ADD.L    song_position,A0
  4875.     ADDQ.B    #1,(A0)
  4876.     CMP.B    #63,(A0)
  4877.     BMI.S    .notmax
  4878.     MOVE.B    #63,(A0)
  4879. .notmax    BSR    refresh_song_position
  4880.     BTST    #2,_custom+potinp
  4881.     BEQ    wait_20ms
  4882.     BSR    wait_20ms
  4883.     BSR    wait_20ms
  4884.     BRA    wait_20ms
  4885. .down    MOVE.L    song_file_ptr,A0
  4886.     ADD.L    #sf_parts,A0
  4887.     ADD.L    song_position,A0
  4888.     SUBQ.B    #1,(A0)
  4889.     TST.B    (A0)
  4890.     BPL.S    .notmin
  4891.     CLR.B    (A0)
  4892. .notmin    BSR    refresh_song_position
  4893.     BTST    #2,_custom+potinp
  4894.     BEQ    wait_20ms
  4895.     BSR.S    wait_20ms
  4896.     BSR.S    wait_20ms
  4897.     BRA.S    wait_20ms
  4898.  
  4899. alter_song_position
  4900.     CMP.W    #-1,alter_dir
  4901.     BEQ.S    .down
  4902.     ADDQ.L    #1,song_position
  4903.     CMP.L    #127,song_position
  4904.     BMI.S    .notmax
  4905.     MOVE.L    #127,song_position
  4906. .notmax    BSR    refresh_song_position
  4907.     BTST    #2,_custom+potinp
  4908.     BEQ.S    wait_20ms
  4909.     BSR.S    wait_20ms
  4910.     BSR.S    wait_20ms
  4911.     BRA.S    wait_20ms
  4912. .down    SUBQ.L    #1,song_position
  4913.     TST.L    song_position
  4914.     BPL.S    .notmin
  4915.     CLR.L    song_position
  4916. .notmin    BSR    refresh_song_position
  4917.     BTST    #2,_custom+potinp
  4918.     BEQ.S    wait_20ms
  4919.     BSR.S    wait_20ms
  4920.     BSR    wait_20ms
  4921. wait_20ms
  4922.     MOVE.W    #17920,D0
  4923. .wait    DBRA    D0,.wait
  4924.     RTS
  4925.  
  4926. *------------------------------
  4927. * SONG PLAYER
  4928.  
  4929. player    MOVEM.L    D0-D7/A0-A6,-(SP)
  4930.     MOVE.L    song_file_ptr,A0
  4931.     MOVE.B    sf_length(A0),song_length+1    save length
  4932.     TST.L    play_mode        skip if not playing
  4933.     BEQ    player_done
  4934.     ADDQ.L    #1,frame_count        frame+1
  4935.     MOVE.L    frame_count,D0        if frame>=tempo then
  4936.     CMP.L    tempo,D0            frame=0, update song
  4937.     BLT.S    .midcyc
  4938.     CLR.L    frame_count
  4939.     BRA    player_nextnote
  4940. .midcyc    LEA    audio_info_1,A6        else update continuous effects
  4941.     LEA    _custom+aud0,A5
  4942.     BSR    songcomm_1234A
  4943.     LEA    audio_info_2,A6
  4944.     LEA    _custom+aud1,A5
  4945.     BSR    songcomm_1234A
  4946.     LEA    audio_info_3,A6
  4947.     LEA    _custom+aud2,A5
  4948.     BSR    songcomm_1234A
  4949.     LEA    audio_info_4,A6
  4950.     LEA    _custom+aud3,A5
  4951.     BSR    songcomm_1234A
  4952.     BRA    player_done
  4953.  
  4954. songcomm_arpeggio
  4955.     MOVE.L    frame_count,D0
  4956.     DIVS    #3,D0        d0=frame mod 3
  4957.     SWAP    D0
  4958.     TST.W    D0
  4959.     BEQ.S    .cycle0
  4960.     CMPI.W    #2,D0
  4961.     BEQ.S    .cycle2
  4962. .cycle1    MOVEQ    #0,D0
  4963.     MOVE.B    3(A6),D0
  4964.     LSR.B    #4,D0
  4965.     BRA.S    .index
  4966. .cycle2    MOVEQ    #0,D0
  4967.     MOVE.B    3(A6),D0
  4968.     AND.B    #15,D0
  4969.     BRA.S    .index
  4970. .cycle0    MOVE.W    16(A6),D2
  4971.     BRA.S    .set
  4972. .index    ASL.W    #1,D0
  4973.     MOVEQ    #0,D1
  4974.     MOVE.W    16(A6),D1
  4975.     AND.W    #$FFF,D1
  4976.     LEA    oct1_2_3_periods,A0
  4977.     MOVEQ    #55-1,D7
  4978. .search    MOVE.W    0(A0,D0.W),D2
  4979.     CMP.W    (A0),D1
  4980.     BGE.S    .set
  4981.     ADDQ.L    #2,A0
  4982.     DBRA    D7,.search
  4983.     RTS
  4984. .set    MOVE.W    D2,6(A5)
  4985.     RTS
  4986.  
  4987. player_nextnote
  4988.     MOVE.L    song_file_ptr,A0
  4989.     MOVE.L    A0,A3
  4990.     ADD.L    #sf_instr+in_length-in_size,A3    a3=instruments info
  4991.     MOVE.L    A0,A2
  4992.     ADD.L    #sf_parts,A2        a2=song positions
  4993.     ADD.L    #sf_patterns,A0        a0=patterns
  4994.     CMP.L    #'patp',play_mode    if play pattern then
  4995.     BEQ.S    .song
  4996.     MOVE.L    pattern_no,D1            index current pattern
  4997.     BRA.S    .patt
  4998. .song    MOVEQ    #0,D1            if playing song then
  4999.     MOVE.L    song_position,D0        index pattern at position
  5000.     MOVE.B    0(A2,D0.L),D1
  5001. .patt    LSL.L    #8,D1
  5002.     LSL.L    #2,D1
  5003.     ADD.L    play_cursor,D1
  5004.     MOVE.L    D1,play_row_index    index to current play row
  5005.     CLR.W    player_channels        clear channel flags
  5006.     LEA    _custom+aud0,A5        update each voice
  5007.     LEA    audio_info_1,A6
  5008.     LEA    volume_1(PC),A2
  5009.     BSR.S    player_update
  5010.     LEA    _custom+aud1,A5
  5011.     LEA    audio_info_2,A6
  5012.     LEA    volume_2(PC),A2
  5013.     BSR.S    player_update
  5014.     LEA    _custom+aud2,A5
  5015.     LEA    audio_info_3,A6
  5016.     LEA    volume_3(PC),A2
  5017.     BSR.S    player_update
  5018.     LEA    _custom+aud3,A5
  5019.     LEA    audio_info_4,A6
  5020.     LEA    volume_4(PC),A2
  5021.     BSR.S    player_update
  5022.     BRA    player_set
  5023.  
  5024. player_update
  5025.     MOVE.L    0(A0,D1.L),(A6)        get note info for this voice
  5026.     ADDQ.L    #4,D1            bump index
  5027.     MOVEQ    #0,D2
  5028.     MOVE.B    2(A6),D2        get instrument no.
  5029.     AND.B    #$F0,D2
  5030.     LSR.B    #4,D2
  5031.     MOVE.B    (A6),D0
  5032.     AND.B    #$F0,D0
  5033.     OR.B    D0,D2
  5034.     TST.B    D2
  5035.     BEQ.S    .tstper            if instrument<>0 then
  5036.     MOVEQ    #0,D3
  5037.     LEA    instr_addr_list,A1
  5038.     MOVE.L    D2,D4
  5039.     LSL.L    #2,D2
  5040.     MULU    #in_size,D4
  5041.     MOVE.L    0(A1,D2.L),4(A6)        get address,length,volume
  5042.     MOVE.W    (A3,D4.L),8(A6)
  5043.     MOVE.W    in_volume-in_length(A3,D4.L),18(A6)
  5044.     MOVE.W    in_repeat-in_length(A3,D4.L),D3
  5045.     TST.W    D3
  5046.     BEQ.S    .no_rep                if repeat then
  5047.     MOVE.L    4(A6),D2
  5048.     ASL.W    #1,D3
  5049.     ADD.L    D3,D2
  5050.     MOVE.L    D2,10(A6)                repeat addr
  5051.     MOVE.W    in_repeat-in_length(A3,D4.L),D0
  5052.     ADD.W    in_replen-in_length(A3,D4.L),D0
  5053.     MOVE.W    D0,8(A6)                initial length
  5054.     MOVE.W    in_replen-in_length(A3,D4.L),14(A6)    repeat length
  5055.     MOVE.W    18(A6),ac_vol(A5)            set volume
  5056.     MOVE.W    18(A6),(A2)                set volume for eq
  5057.     BRA.S    .tstper
  5058. .no_rep    MOVE.L    4(A6),D2            if no repeat then
  5059.     ADD.L    D3,D2
  5060.     MOVE.L    D2,10(A6)                repeat addr=addr
  5061.     MOVE.W    in_replen-in_length(A3,D4.L),14(A6)    repeat length=1
  5062.     MOVE.W    18(A6),ac_vol(A5)            set volume
  5063.     MOVE.W    18(A6),(A2)                set volume for eq
  5064. .tstper    MOVE.W    (A6),D0        if period<>0 then
  5065.     AND.W    #$FFF,D0
  5066.     BEQ.S    .no_period
  5067.     MOVE.B    2(A6),D0        if tone portamento then
  5068.     AND.B    #15,D0
  5069.     CMPI.B    #3,D0
  5070.     BNE.S    .noport
  5071.     BSR    init_toneporta            initialize
  5072.     BRA    songcomm_B_to_F            do commands
  5073. .noport    MOVE.W    (A6),16(A6)        else
  5074.     AND.W    #$FFF,16(A6)            get period
  5075.     MOVE.W    20(A6),D0
  5076.     MOVE.W    D0,_custom+dmacon        disable channel
  5077.     CLR.B    27(A6)
  5078.     MOVE.L    4(A6),(A5)            set address
  5079.     MOVE.W    8(A6),ac_len(A5)        set length
  5080.     MOVE.W    16(A6),D0            set period
  5081.     AND.W    #$FFF,D0
  5082.     MOVE.W    D0,ac_per(A5)
  5083.     BSR    add_note_to_spectrum        send to spectrum analyser
  5084.     MOVE.W    20(A6),D0            flag channel
  5085.     OR.W    D0,player_channels
  5086. .no_period
  5087.     BRA    songcomm_B_to_F        do commands
  5088.  
  5089. player_set
  5090.     MOVE.W    #$12C,D0            wait 350us
  5091. .wait    DBRA    D0,.wait
  5092.     MOVE.W    player_channels,D0        enable active channels
  5093.     AND.W    onoff_states,D0
  5094.     OR.W    #$8000,D0
  5095.     MOVE.W    D0,_custom+dmacon
  5096.     MOVE.W    #$12C,D0            wait 350us
  5097. .wait2    DBRA    D0,.wait2
  5098.     LEA    audio_info_4,A6
  5099.     MOVE.L    10(A6),_custom+aud3+ac_ptr    set addr,length for repeats
  5100.     MOVE.W    14(A6),_custom+aud3+ac_len
  5101.     LEA    audio_info_3,A6
  5102.     MOVE.L    10(A6),_custom+aud2+ac_ptr
  5103.     MOVE.W    14(A6),_custom+aud2+ac_len
  5104.     LEA    audio_info_2,A6
  5105.     MOVE.L    10(A6),_custom+aud1+ac_ptr
  5106.     MOVE.W    14(A6),_custom+aud1+ac_len
  5107.     LEA    audio_info_1,A6
  5108.     MOVE.L    10(A6),_custom+aud0+ac_ptr
  5109.     MOVE.W    14(A6),_custom+aud0+ac_len
  5110.     CMP.L    #'patp',play_mode        if playing song then
  5111.     BNE.S    .notply
  5112.     BSR    set_play_scroller            scroll pattern
  5113. .notply    CMP.L    #'patt',play_mode        if playing pattern then
  5114.     BNE.S    .notpat
  5115.     BSR    set_play_scroller            scroll pattern
  5116.     CMP.L    #'edit',edit_mode        if recording then
  5117.     BNE.S    .notpat
  5118.     MOVE.L    play_cursor,D0                update cursor
  5119.     LSR.L    #4,D0
  5120.     MOVE.W    D0,edit_cursor_y
  5121. .notpat    ADD.L    #16,play_cursor            step down 1 row
  5122.     CMP.L    #64*16,play_cursor
  5123.     BNE.S    player_done        if end then new pattern
  5124.  
  5125. player_newpat
  5126.     CLR.L    play_cursor            reset cursor
  5127.     CLR.W    pattern_break_flag        cancel break
  5128.     CMP.L    #'patp',play_mode        if playing pattern then
  5129.     BNE.S    player_done                repeat
  5130.     ADDQ.L    #1,song_position        else
  5131.     AND.L    #$7F,song_position            next
  5132.     MOVEQ    #0,D0
  5133.     MOVE.W    song_length,D0                if end of song then
  5134.     MOVE.L    song_position,D1                restart
  5135.     CMP.L    D0,D1
  5136.     BNE.S    player_done
  5137.     MOVEQ    #0,D0
  5138.     MOVE.L    song_file_ptr,A0
  5139.     MOVE.B    sf_restart(A0),D0
  5140.     MOVE.L    D0,song_position
  5141.  
  5142. player_done
  5143.     TST.W    pattern_break_flag    if break/jump then new pattern
  5144.     BNE.S    player_newpat
  5145.     MOVEM.L    (SP)+,D0-D7/A0-A6
  5146.     RTS
  5147.  
  5148. check_hallonsoft_mode
  5149.     TST.W    hsoft_flag        if 'hallonsoft' typed in then
  5150.     BEQ    return
  5151.     CLR.W    hsoft_flag
  5152.     LEA    _custom+$10,A0            setup new screen
  5153.     MOVE.L    #hallon_logo,D0            set copper list
  5154.     MOVE.W    D0,cl_hallon+30
  5155.     SWAP    D0
  5156.     MOVE.W    D0,cl_hallon+26
  5157.     MOVE.L    #hallon_logo+1024,D0
  5158.     MOVE.W    D0,cl_hallon+38
  5159.     SWAP    D0
  5160.     MOVE.W    D0,cl_hallon+34
  5161.     MOVE.L    #cl_hallon,cop1lch-$10(A0)
  5162. .wait    BTST    #6,$BFE001            wait for left button
  5163.     BNE.S    .wait
  5164.     BSR    wait_no_buttons            wait till release
  5165.     BSR    wait_20ms            wait 1/5 second
  5166.     BSR    wait_20ms
  5167.     BSR    wait_20ms
  5168.     BSR    wait_20ms
  5169.     BSR    wait_20ms
  5170.     MOVE.L    clist_ptr,cop1lch-$10(A0)    restore copper list
  5171.     MOVE.W    #$8020,dmacon-$10(A0)        enable sprite dma
  5172.     CLR.B    key_code            cancel any keys
  5173.     RTS
  5174.  
  5175. set_play_scroller
  5176.     MOVE.L    play_cursor,D0        play ptr = 0..1023
  5177.     LSR.L    #4,D0            /16 for row 0..63
  5178.     BRA.S    set_scroller
  5179. set_edit_scroller
  5180.     MOVE.W    edit_cursor_y,D0    edit cursor = 0..63
  5181. set_scroller
  5182.     MULU    #7*40,D0        set pattern screen scroll addr
  5183.     MOVE.L    screen_ptr,A0
  5184.     ADD.L    #139*40,A0
  5185.     ADD.L    A0,D0
  5186.     MOVE.L    cptr_plane3b,A1
  5187.     MOVE.W    D0,6(A1)
  5188.     SWAP    D0
  5189.     MOVE.W    D0,2(A1)
  5190.     RTS
  5191.  
  5192. * exit    mouse_x=0..319/mouse_y=0..255
  5193.  
  5194. scan_mouse_coords
  5195.     MOVE.W    _custom+joy0dat,D0    d0=mouse data yyyyyyyyxxxxxxxx
  5196.     MOVE.W    D0,D2            save in d2
  5197.     AND.W    #$FF,D0            d0=new_x
  5198.     MOVE.W    D0,D1
  5199.     SUB.W    mouse_oldx,D0        d0=new_x - old_x
  5200.     MOVE.W    D1,mouse_oldx        old_x=new_x
  5201.     EXT.W    D0
  5202.     CMPI.W    #127,D0            if overflow then
  5203.     BMI.S    .underx
  5204.     MOVE.W    #255,D1                d0=255-d0
  5205.     SUB.W    D0,D1
  5206.     MOVE.W    D1,D0
  5207.     BRA.S    .sumx
  5208. .underx    CMPI.W    #-127,D0        if underflow then
  5209.     BPL.S    .sumx
  5210.     ADD.W    #255,D0                d0=255+d0
  5211. .sumx    ADD.W    D0,mouse_sumx        sum_x+d0
  5212.     MOVE.W    D2,D0            d0=new_y
  5213.     LSR.W    #8,D0
  5214.     MOVE.W    D0,D1
  5215.     SUB.W    mouse_oldy,D0        d0=new_y-old_y
  5216.     MOVE.W    D1,mouse_oldy        old_y=new_y
  5217.     EXT.W    D0
  5218.     CMPI.W    #127,D0            if overflow then
  5219.     BMI.S    .undery
  5220.     MOVE.W    #255,D1                d0=255-d0
  5221.     SUB.W    D0,D1
  5222.     MOVE.W    D1,D0
  5223.     BRA.S    .sumy
  5224. .undery    CMPI.W    #-127,D0        if underflow then
  5225.     BPL.S    .sumy
  5226.     ADD.W    #255,D0                d0=255+d0
  5227. .sumy    ADD.W    D0,mouse_sumy        sum_y+d0
  5228.     TST.W    mouse_sumx        if sum_x<0 then =0
  5229.     BPL.S    .xok
  5230.     CLR.W    mouse_sumx
  5231. .xok    CMP.W    #1,mouse_sumy        if sum_y<1 then =1
  5232.     BPL.S    .yok
  5233.     MOVE.W    #1,mouse_sumy
  5234. .yok    CMP.W    #639,mouse_sumx        if sum_x>639 then =639
  5235.     BMI.S    .xok2
  5236.     MOVE.W    #639,mouse_sumx
  5237. .xok2    CMP.W    #511,mouse_sumy        if sum_y>511 then =511
  5238.     BMI.S    .yok2
  5239.     MOVE.W    #511,mouse_sumy
  5240. .yok2    MOVEQ    #0,D0
  5241.     MOVE.W    mouse_sumx,D0
  5242.     LSR.W    #1,D0
  5243.     MOVE.W    D0,mouse_x        mouse_x=sum_x/2=0..319
  5244.     MOVEQ    #0,D0
  5245.     MOVE.W    mouse_sumy,D0
  5246.     LSR.W    #1,D0
  5247.     MOVE.W    D0,mouse_y        mouse_y=sum_y/2=0..255
  5248.     RTS
  5249.  
  5250. vbl_irq
  5251.     MOVEM.L    D0/D1/A0/A1/A5/A6,-(SP)
  5252.     LEA    _custom,A0
  5253.     MOVE.L    4.w,a6
  5254.     MOVE.W    intenar(A0),D1        skip if no irq's enabled
  5255.     BTST    #14,D1
  5256.     BEQ.S    .exit
  5257.     AND.W    intreqr(A0),D1        if blitter irq then
  5258.     BTST    #6,D1
  5259.     BEQ.S    .vbl
  5260.     MOVEM.L    $9C(A6),A1/A5            goto exec's handler
  5261.     PEA    _LVOExitIntr(A6)
  5262.     JMP    (A5)
  5263. .vbl    BTST    #5,D1            if vbl irq then
  5264.     BEQ.S    .copper
  5265.     MOVEM.L    D0-D7/A0-A6,-(SP)        save all regs
  5266.     BSR    scan_mouse_coords        update mouse
  5267.     BSR    set_arrow_position        update arrow
  5268.     BSR    update_chaneq_levels        channel levels
  5269.     BSR    player                play song
  5270.     BSR    check_cursor_keys        cursor functions
  5271.     BSR    update_spectrum_analyser    spectrum
  5272.     MOVEM.L    (SP)+,D0-D7/A0-A6        restore regs
  5273.     MOVEM.L    $90(A6),A1/A5            goto exec's handler
  5274.     PEA    _LVOExitIntr(A6)
  5275.     JMP    (A5)
  5276. .copper    BTST    #4,D1            if copper irq then
  5277.     BEQ.S    .exit
  5278.     MOVEM.L    $84(A6),A1/A5            goto exec's handler
  5279.     PEA    _LVOExitIntr(A6)
  5280.     JMP    (A5)
  5281. .exit    MOVEM.L    (SP)+,D0-D1/A0-A1/A5-A6
  5282.     RTE    
  5283.  
  5284. keyboard_irq
  5285.     MOVEM.L    D0-D7/A0-A6,-(SP)
  5286.     LEA    $BFE001,A0            get key
  5287.     MOVE.B    $C00(A0),D0
  5288.     MOVEQ    #0,D1
  5289.     MOVE.B    D1,$E00(A0)
  5290.     MOVE.B    D1,$E00(A0)
  5291.     OR.B    #$40,$E00(A0)
  5292.     NOT.B    D0                normalize
  5293.     ROR.B    #1,D0
  5294.     MOVEQ    #100,D7
  5295. .wait    DBRA    D7,.wait            delay
  5296.     AND.B    #$BF,$E00(A0)
  5297.     CMPI.B    #$60,D0                check for left shift/alt
  5298.     BEQ.S    .pre_ls
  5299.     CMPI.B    #$64,D0
  5300.     BEQ.S    .pre_la
  5301.     CMPI.B    #$64+$80,D0
  5302.     BEQ.S    .rel_la
  5303.     CMPI.B    #$60+$80,D0
  5304.     BEQ.S    .rel_ls
  5305.     CMPI.B    #$43,D0                check for ENTER
  5306.     BNE.S    .noent
  5307.     MOVE.W    #1,key_enter
  5308. .noent    CMPI.B    #$43+$80,D0
  5309.     BNE.S    .noent2
  5310.     CLR.W    key_enter
  5311. .noent2    MOVE.B    D0,key_code            save keycode
  5312.     BSR.S    check_for_hsoft
  5313. .exit    MOVEM.L    (SP)+,D0-D7/A0-A6
  5314.     RTS
  5315.  
  5316. .pre_ls    MOVE.W    #1,key_lshift
  5317.     BRA.S    .exit
  5318. .rel_ls    CLR.W    key_lshift
  5319.     BRA.S    .exit
  5320. .pre_la    MOVE.W    #1,key_lalt
  5321.     BRA.S    .exit
  5322. .rel_la    CLR.W    key_lalt
  5323.     BRA.S    .exit
  5324.  
  5325. check_for_hsoft
  5326.     TST.B    D0        sets a flag if 'HALLONSOFT'
  5327.     BMI    return        typed in at any time
  5328.     MOVE.L    hsoft_ptr,A0
  5329.     CMP.B    (A0)+,D0
  5330.     BEQ.S    .gotchr
  5331.     MOVE.L    #hallonsoft,hsoft_ptr
  5332.     RTS
  5333. .gotchr    MOVE.L    A0,hsoft_ptr
  5334.     TST.B    (A0)
  5335.     BMI.S    .gotall
  5336.     RTS
  5337. .gotall    MOVE.L    #hallonsoft,hsoft_ptr
  5338.     LEA    hsoft_flag+138,A0        set flag
  5339.     MOVE.W    #1,-138(A0)
  5340.     RTS
  5341.  
  5342. hex_chars
  5343.     dc.b    '0123456789abcdef'
  5344.  
  5345. setup    LEA    hex2ascii,A0            make string table '00'..'FF'
  5346.     LEA    hex_chars,A1
  5347.     MOVEQ    #0,D0
  5348.     MOVE.W    #256-1,D7
  5349. .makeha    MOVE.W    D0,D1
  5350.     LSR.W    #4,D1
  5351.     MOVE.B    0(A1,D1.W),(A0)+
  5352.     MOVE.W    D0,D1
  5353.     AND.W    #15,D1
  5354.     MOVE.B    0(A1,D1.W),(A0)+
  5355.     ADDQ.B    #1,D0
  5356.     DBRA    D7,.makeha
  5357.     LEA    DOSname,A1            open dos
  5358.     JSR    _LVOOldOpenLibrary(A6)
  5359.     MOVE.L    D0,DOSbase
  5360.     MOVE.L    4.w,a6                  top half   scroller
  5361.     MOVE.L    #27760,D0            = 2*123*40 + 64*7*40
  5362.     MOVE.L    #MEMF_CHIP!MEMF_CLEAR,D1    allocate memory for screen
  5363.     JSR    _LVOAllocMem(A6)        used for printing and for
  5364.     MOVE.L    D0,screen_ptr            pattern scroller
  5365.     MOVE.W    D0,cl_plane3+4            patch plane 3 addr in copper
  5366.     SWAP    D0
  5367.     MOVE.W    D0,cl_plane3
  5368.     MOVE.L    DOSbase,A6
  5369.     MOVE.L    #plst_name,D1            check for PLST file
  5370.     MOVEQ    #-2,D2
  5371.     JSR    _LVOLock(A6)
  5372.     MOVE.L    D0,D7
  5373.     BEQ    .noplst
  5374.     MOVE.L    D7,D1
  5375.     MOVE.L    #FileInfoBlock,D2        get info block
  5376.     JSR    _LVOExamine(A6)
  5377.     TST.L    D0
  5378.     BEQ.S    .noplst
  5379.     MOVE.L    D7,D1
  5380.     JSR    _LVOUnLock(A6)
  5381.     LEA    FileInfoBlock,A0
  5382.     MOVE.L    124(A0),D0            save size
  5383.     MOVE.L    D0,plst_size
  5384.     DIVU    #in_size,D0            no. of entries=size/30
  5385.     MOVE.W    D0,plst_entries
  5386.     MOVE.L    plst_size,D0
  5387.     CLR.L    plst_ptr
  5388.     MOVEQ    #0,D1
  5389.     MOVE.L    4.w,a6
  5390.     JSR    _LVOAllocMem(A6)        allocate memory
  5391.     MOVE.L    D0,plst_ptr
  5392.     BEQ.S    .noplst
  5393.     MOVE.L    #plst_name,D1
  5394.     MOVE.L    #1005,D2            read file
  5395.     MOVE.L    DOSbase,A6
  5396.     JSR    _LVOOpen(A6)
  5397.     MOVE.L    D0,D7
  5398.     BEQ.S    .noplst
  5399.     MOVE.L    D7,D1
  5400.     MOVE.L    plst_ptr,D2
  5401.     MOVE.L    plst_size,D3
  5402.     JSR    _LVORead(A6)
  5403.     CMP.L    plst_size,D0
  5404.     BNE.S    .noplst
  5405.     MOVE.L    D7,D1
  5406.     JSR    _LVOClose(A6)
  5407.     BRA.S    .plstok
  5408. .noplst    TST.L    plst_ptr            if error then
  5409.     BEQ.S    .plstok                free any memory alloc'd
  5410.     MOVE.L    4.w,a6
  5411.     MOVE.L    plst_ptr,A1
  5412.     MOVE.L    plst_size,D0
  5413.     JSR    _LVOFreeMem(A6)
  5414. .plstok    MOVE.W    _custom+joy0dat,D0        init mouse x,y
  5415.     MOVE.W    D0,D1
  5416.     AND.W    #$FF,D0
  5417.     MOVE.W    D0,mouse_oldx
  5418.     LSR.W    #8,D1
  5419.     MOVE.W    D1,mouse_oldy
  5420.     MOVE.L    #sf_size,D0
  5421.     MOVE.L    #MEMF_CLEAR,D1
  5422.     MOVE.L    4.w,a6
  5423.     JSR    _LVOAllocMem(A6)        allocate song file memory
  5424.     MOVE.L    D0,song_file_ptr
  5425.     MOVE.L    D0,A0
  5426.     ADD.L    #sf_instr,A0            valid replen values
  5427.     MOVEQ    #31-1,D0
  5428. .wipe    MOVE.W    #1,in_replen(A0)
  5429.     ADD.L    #in_size,A0
  5430.     DBRA    D0,.wipe
  5431.     MOVE.L    song_file_ptr,A0
  5432.     MOVE.W    #1*256+0,sf_length(A0)        length=1,restart=0
  5433.     MOVE.L    #'M.K.',sf_ident(A0)        store id
  5434.     CLR.W    _custom+aud0+ac_vol        audio off
  5435.     CLR.W    _custom+aud1+ac_vol
  5436.     CLR.W    _custom+aud2+ac_vol
  5437.     CLR.W    _custom+aud3+ac_vol
  5438.     MOVE.W    #1,plst_entry_no
  5439.     CLR.L    song_position            reset cursor & mode
  5440.     CLR.L    play_cursor
  5441.     CLR.L    play_row_index
  5442.     CLR.L    play_mode
  5443.     CLR.L    edit_mode
  5444.     MOVEQ    #6,D0                default tempo
  5445.     MOVE.L    D0,tempo
  5446.     MOVE.L    #copper_list,D0            set copper list ptr
  5447.     MOVE.L    D0,clist_ptr
  5448.     MOVE.L    D0,clist_ptr2
  5449.     MOVE.L    #cl_plane1_2,cptr_plane1_2    various copper patch addrs
  5450.     MOVE.L    #cl_arrow_col,cptr_arrow_col
  5451.     MOVE.L    #cl_plane3b,cptr_plane3b
  5452.     MOVE.L    #cl_con0c,cptr_con0c
  5453.     MOVE.L    #oct1_2_periods,octave_periods    set keyboard octave
  5454.     MOVE.L    #oct1_2_names,octave_names
  5455.     MOVE.L    #s_arrow,arrow_spr_ptr        arrow sprite
  5456.     MOVE.L    arrow_spr_ptr,sprite_addrs    note: sprite 2 not used
  5457.     MOVE.L    #s_inputcursor,sprite_addrs+4
  5458.     MOVE.L    #s_editcursor,sprite_addrs+12
  5459.     MOVE.L    #s_chaneq1,sprite_addrs+16
  5460.     MOVE.L    #s_chaneq2,sprite_addrs+20
  5461.     MOVE.L    #s_chaneq3,sprite_addrs+24
  5462.     MOVE.L    #s_chaneq4,sprite_addrs+28
  5463.     LEA    sprite_addrs,A0
  5464.     LEA    copper_list,A1            patch sprite addresses
  5465.     MOVEQ    #16-1,D2            into copper list
  5466. .setspr    MOVE.W    (A0)+,2(A1)
  5467.     ADDQ.L    #4,A1
  5468.     DBRA    D2,.setspr
  5469.     BSR    set_edit_cursor
  5470.     CLR.L    pattern_no
  5471.     BSR    refresh_pattern_display
  5472.     BSR    refresh_song_position
  5473.     BSR    refresh_song_parameters
  5474.     MOVE.W    #1,current_instr
  5475.     BSR    refresh_instr_parameters
  5476.     MOVE.L    #vbl_irq,(tv_Lev3IntVect).w
  5477.     MOVE.L    #main_screen,D0            patch plane 1,2 addrs
  5478.     LEA    cl_plane1_2,A1            in copper list
  5479.     MOVE.W    D0,6(A1)
  5480.     SWAP    D0
  5481.     MOVE.W    D0,2(A1)
  5482.     SWAP    D0
  5483.     ADD.L    #10240,D0
  5484.     MOVE.W    D0,14(A1)
  5485.     SWAP    D0
  5486.     MOVE.W    D0,10(A1)
  5487.     MOVE.L    4.w,a6
  5488.     LEA    GFXname,A1            get old copper list
  5489.     JSR    _LVOOldOpenLibrary(A6)
  5490.     MOVE.L    D0,GFXbase
  5491.     MOVE.L    D0,A0
  5492.     MOVE.L    gb_copinit(A0),copper_init
  5493.     LEA    INTname,A1            open intuition
  5494.     JSR    _LVOOldOpenLibrary(A6)
  5495.     MOVE.L    D0,INTbase            patch auto_request
  5496.     MOVE.L    D0,A0
  5497.     MOVE.L    _LVOAutoRequest+2(A0),request_patch+2
  5498.     MOVE.L    #new_auto_request,_LVOAutoRequest+2(A0)
  5499.     BSR.S    set_chaneq_copper
  5500.     BRA    set_spect_copper
  5501.  
  5502. chaneq_colours_ptr
  5503.     dc.l    chaneq_colours2
  5504. spect_colours_ptr
  5505.     dc.l    spect_colours2
  5506.  
  5507. set_chaneq_copper
  5508.     LEA    cl_chaneq,A0
  5509.     MOVE.L    chaneq_colours_ptr,A5
  5510.     MOVE.L    #$B807FFFE,D0
  5511.     MOVEQ    #48-1,D7
  5512. .loop    MOVE.L    D0,(A0)+        CWAIT v184,h3
  5513.     LEA    .colnos(PC),A1
  5514.     MOVEQ    #2-1,D5
  5515. .loop2    MOVEQ    #3-1,D6
  5516. .loop3    MOVE.W    (A1)+,(A0)+        set colours 25..27,29..31
  5517.     MOVE.W    (A5)+,(A0)+
  5518.     DBRA    D6,.loop3
  5519.     LEA    -6(A5),A5
  5520.     DBRA    D5,.loop2
  5521.     LEA    6(A5),A5
  5522.     ADD.L    #$1000000,D0        vert+1
  5523.     DBRA    D7,.loop
  5524.     RTS
  5525.  
  5526. .colnos    dc.w    color0+2*25
  5527.     dc.w    color0+2*26
  5528.     dc.w    color0+2*27
  5529.     dc.w    color0+2*29
  5530.     dc.w    color0+2*30
  5531.     dc.w    color0+2*31
  5532.  
  5533. chaneq_colours2
  5534.     dc.l    $F000B00,$7000F00,$B000700    red->yellow->green
  5535.     dc.l    $F100B10,$7100F10,$B100710
  5536.     dc.l    $F200B20,$7200F20,$B200720
  5537.     dc.l    $F300B30,$7300F30,$B300730
  5538.     dc.l    $F400B40,$7400F50,$B500750
  5539.     dc.l    $F600B60,$7600F70,$B700770
  5540.     dc.l    $F800B80,$7800F90,$B900790
  5541.     dc.l    $FA00BA0,$7A00FB0,$BB007B0
  5542.     dc.l    $FC00BC0,$7C00FD0,$BD007D0
  5543.     dc.l    $FE00BE0,$7E00FF0,$BF007F0
  5544.     dc.l    $FF00BF0,$7F00EF0,$AF006F0
  5545.     dc.l    $EF00AF0,$6F00DF0,$9F005F0
  5546.     dc.l    $DF009F0,$5F00CF0,$8F004F0
  5547.     dc.l    $CF008F0,$4F00BF0,$7F003F0
  5548.     dc.l    $BF007F0,$3F00AF0,$6F002F0
  5549.     dc.l    $9F005F0,$1F009F0,$5F001F0
  5550.     dc.l    $8F004F0,$0F008F0,$4F000F0
  5551.     dc.l    $7F003F0,$0E007F0,$3F000E0
  5552.     dc.l    $6F002F0,$0D006F0,$2F000D0
  5553.     dc.l    $5F001F0,$0C005F0,$1F000C0
  5554.     dc.l    $4F000F0,$0B004F0,$0F000B0
  5555.     dc.l    $3F000E0,$0A003F0,$0E000A0
  5556.     dc.l    $2F000D0,$09001F0,$0C00080
  5557.     dc.l    $0F000B0,$07000E0,$0A00060
  5558.  
  5559. chaneq_colours1
  5560.     dc.l    $00E000C,$008000E,$00C0009    blue->cyan
  5561.     dc.l    $00E000C,$009000F,$00D0009
  5562.     dc.l    $00F000D,$00A001F,$00D000A
  5563.     dc.l    $01F001D,$00A001F,$01D000B
  5564.     dc.l    $02F001D,$00B002F,$02D000B
  5565.     dc.l    $03F002D,$01B003F,$02D001B
  5566.     dc.l    $03F003D,$01B004F,$03D002B
  5567.     dc.l    $04F003D,$02B005F,$04D002B
  5568.     dc.l    $05F004D,$03B005F,$04D003B
  5569.     dc.l    $06F005D,$03B006F,$05D004B
  5570.     dc.l    $07F005D,$04B007F,$06D004B
  5571.     dc.l    $07F006D,$05B008F,$06D005B
  5572.     dc.l    $08F007D,$05B009F,$07D006B
  5573.     dc.l    $09F007D,$06B009F,$08D006B
  5574.     dc.l    $0AF008D,$07B00AF,$08D007B
  5575.     dc.l    $0BF009D,$07B00BF,$09D008B
  5576.     dc.l    $0BF009D,$08B00CF,$0AD008B
  5577.     dc.l    $0CF00AD,$09B00DF,$0AD009B
  5578.     dc.l    $0DF00BD,$09B00DF,$0BD00AB
  5579.     dc.l    $0EF00BD,$0AB00EF,$0CD00AB
  5580.     dc.l    $0FF00CD,$0BB00FF,$0CD00BB
  5581.     dc.l    $1FF00DD,$0BB01FF,$0DD00BB
  5582.     dc.l    $2FF01DD,$1BB02FF,$1DD01BB
  5583.     dc.l    $3FF02DD,$1BB03FF,$2DD01BB
  5584.  
  5585. set_spect_copper
  5586.     LEA    cl_spectrum,A5
  5587.     MOVE.L    spect_colours_ptr,A4
  5588.     MOVEQ    #40-1,D0        40 rows
  5589.     MOVE.L    #$687DFFFE,D1
  5590. .loop    MOVE.L    D1,(A5)+        CWAIT v104,h62
  5591.     MOVE.W    #color0+2*6,(A5)+    color6=spectrum colour
  5592.     MOVE.W    (A4)+,(A5)+
  5593.     ADD.L    #$00600000,D1        CWAIT v104,h110
  5594.     MOVE.L    D1,(A5)+
  5595.     MOVE.L    #$018C0000,(A5)+    color6=0
  5596.     ADD.L    #$01000000,D1        vert wait+1
  5597.     SUB.L    #$00600000,D1
  5598.     DBRA    D0,.loop
  5599.     RTS
  5600.  
  5601. set_spect_colours
  5602.     LEA    cl_spectrum+6,A1
  5603.     MOVE.L    spect_colours_ptr,A0
  5604.     MOVEQ    #40-1,D0
  5605. .loop    MOVE.W    (A0)+,(A1)
  5606.     ADD.L    #16,A1
  5607.     DBRA    D0,.loop
  5608.     RTS
  5609.  
  5610. clear_spect_colours
  5611.     LEA    cl_spectrum+6,A0
  5612.     MOVEQ    #40-1,D0
  5613. .loop    CLR.W    (A0)
  5614.     ADD.L    #16,A0
  5615.     DBRA    D0,.loop
  5616.     RTS
  5617.  
  5618. spect_colours1
  5619.     dc.l    $01F002F,$02F002F,$03F003F    blue->cyan
  5620.     dc.l    $03F004F,$04F004F,$05F005F
  5621.     dc.l    $05F006F,$06F006F,$07F007F
  5622.     dc.l    $07F008F,$08F008F,$09F009F
  5623.     dc.l    $09F00AF,$0AF00AF,$0BF00BF
  5624.     dc.l    $0BF00CF,$0CF00CF,$0DF00DF
  5625.     dc.w    $0DF
  5626. spect_colours2
  5627.     dc.l    $F000F10,$F200F30,$F400F50    red->yellow->green
  5628.     dc.l    $F600F70,$F800F90,$FA00FB0
  5629.     dc.l    $FC00FD0,$FE00FF0,$EF00DF0
  5630.     dc.l    $CF00BF0,$AF009F0,$8F007F0
  5631.     dc.l    $6F005F0,$4F003F0,$2F001F0
  5632.     dc.l    $0F000E0,$0D000C0,$0B000A0
  5633.     dc.w    $090
  5634.  
  5635. plst_name
  5636.     dc.b    'ST-00:PLST',0
  5637.     dc.b    0
  5638.  
  5639. INTname    dc.b    'intuition.library',0
  5640.  
  5641. new_auto_request
  5642.     TST.W    stop_request        if request enabled then
  5643.     BNE.S    no_request
  5644.     MOVE.L    copper_init,_custom+cop1lch    set old copper list
  5645. request_patch
  5646.     JSR    0                do request
  5647.     MOVE.L    clist_ptr,_custom+cop1lch    set my copper list
  5648.     RTS
  5649. no_request
  5650.     MOVEQ    #0,D0
  5651.     RTS
  5652.  
  5653. print_allright
  5654.     MOVEM.L    D0-D7/A0-A6,-(SP)
  5655.     MOVE.L    #12,string_size
  5656.     MOVE.L    #127*40+15,char_offset
  5657.     MOVE.L    #allright_msg,string_addr
  5658.     BSR    print_string
  5659.     CLR.L    string_size
  5660.     MOVEM.L    (SP)+,D0-D7/A0-A6
  5661.     RTS
  5662.  
  5663. allright_msg
  5664.     dc.b    'all right   ',0
  5665.     even
  5666.  
  5667. refresh_pattern_display
  5668.     CLR.W    new_pat_flag
  5669.     MOVE.L    cptr_con0c,A0        disable plane 3
  5670.     MOVE.W    #$2200,(A0)
  5671.     MOVE.L    #128*40+1,char_offset
  5672.     MOVE.L    pattern_no,D1        print pattern no.
  5673.     LEA    temp_str,A0
  5674.     DIVU    #10,D1
  5675.     ADD.W    #'0',D1
  5676.     MOVE.B    D1,(A0)+
  5677.     CLR.W    D1
  5678.     SWAP    D1
  5679.     ADD.W    #'0',D1
  5680.     MOVE.B    D1,(A0)+
  5681.     CLR.W    D1
  5682.     SWAP    D1
  5683.     MOVE.L    #2,string_size
  5684.     MOVE.L    #temp_str,string_addr
  5685.     BSR    print_string
  5686.     CLR.L    temp_str
  5687.     MOVE.L    #188*40+1,char_offset
  5688.     MOVE.L    song_file_ptr,A6    a6=song+offset+1024*pattern
  5689.     ADD.L    #sf_patterns,A6
  5690.     MOVE.L    pattern_no,D6
  5691.     LSL.L    #8,D6
  5692.     LSL.L    #2,D6
  5693.     ADD.L    D6,A6
  5694.     CLR.L    rpd_row            row no.
  5695.     MOVEQ    #0,D6
  5696. .row    MOVEQ    #0,D7            print row no.
  5697.     MOVE.L    #2,string_size
  5698.     MOVE.L    rpd_row,D1
  5699.     LEA    temp_str,A0
  5700.     DIVU    #10,D1
  5701.     ADD.W    #'0',D1
  5702.     MOVE.B    D1,(A0)+
  5703.     CLR.W    D1
  5704.     SWAP    D1
  5705.     ADD.W    #'0',D1
  5706.     MOVE.B    D1,(A0)+
  5707.     CLR.W    D1
  5708.     SWAP    D1
  5709.     MOVE.L    #2,string_size
  5710.     MOVE.L    #temp_str,string_addr
  5711.     BSR    print_string
  5712.     CLR.L    temp_str
  5713.     ADDQ.L    #1,char_offset        skip 1 char
  5714.     ADDQ.L    #1,rpd_row        row no. + 1
  5715. .voice    MOVEQ    #0,D0            for each voice
  5716.     MOVEQ    #0,D1            print note name
  5717.     MOVE.L    #3,string_size
  5718.     MOVE.W    (A6),D1
  5719.     AND.W    #$FFF,D1
  5720.     MOVE.L    #oct1_2_3_periods,A0
  5721. .search    CMP.W    0(A0,D0.L),D1
  5722.     BEQ.S    .found
  5723.     ADDQ.L    #2,D0
  5724.     BRA.S    .search
  5725. .found    LSL.L    #1,D0
  5726.     ADD.L    #oct1_2_3_names,D0
  5727.     MOVE.L    D0,string_addr
  5728.     BSR    print_string
  5729.     MOVEQ    #0,D0            print parameters
  5730.     MOVE.W    (A6),D0
  5731.     AND.W    #$F000,D0
  5732.     LSR.W    #8,D0
  5733.     BSR    print_hex1
  5734.     MOVE.L    #2,string_size
  5735.     MOVEQ    #0,D0
  5736.     MOVE.B    2(A6),D0
  5737.     LSL.L    #1,D0
  5738.     LEA    hex2ascii,A0
  5739.     ADD.L    D0,A0
  5740.     MOVE.L    A0,string_addr
  5741.     BSR    print_string
  5742.     MOVEQ    #0,D0
  5743.     MOVE.B    3(A6),D0
  5744.     LSL.L    #1,D0
  5745.     MOVE.L    #hex2ascii,A0
  5746.     ADD.L    D0,A0
  5747.     MOVE.L    A0,string_addr
  5748.     BSR    print_string
  5749.     ADDQ.L    #1,char_offset        skip char
  5750.     ADDQ.L    #4,a6            next voice
  5751.     ADDQ.L    #1,D7
  5752.     CMPI.L    #4,D7
  5753.     BNE    .voice
  5754.     ADD.L    #6*40+1,char_offset    next row
  5755.     ADDQ.L    #1,D6
  5756.     CMPI.L    #64,D6
  5757.     BNE    .row
  5758.     MOVE.L    cptr_con0c,A0        enable plane 3
  5759.     MOVE.W    #$3200,(A0)
  5760.     RTS
  5761.  
  5762. refresh_song_position
  5763.     MOVE.W    song_position+2,word_to_print    print song position
  5764.     MOVE.L    #4*40+8,char_offset
  5765.     BSR    print_dec4
  5766.     MOVE.L    song_file_ptr,A0        print pattern no. at position
  5767.     ADD.L    #sf_parts,A0
  5768.     ADD.L    song_position,A0
  5769.     MOVE.B    (A0),word_to_print+1
  5770.     MOVE.B    (A0),new_pat_no+3
  5771.     MOVEQ    #0,D1
  5772.     MOVE.B    (A0),D1
  5773.     CMP.B    prev_pat_no+3,D1        flag if new pattern
  5774.     BEQ.S    .same
  5775.     MOVE.W    #1,new_pat_flag
  5776. .same    MOVE.L    #$260,char_offset
  5777.     MOVE.B    (A0),prev_pat_no+3
  5778.     BRA    print_dec4
  5779.  
  5780. refresh_song_parameters
  5781.     MOVE.L    song_file_ptr,A0        print song length
  5782.     ADD.L    #sf_length,A0
  5783.     MOVE.L    A0,temp
  5784.     MOVE.B    (A0),word_to_print+1
  5785.     MOVE.L    #26*40+8,char_offset
  5786.     BSR    print_dec4
  5787.     MOVE.L    temp,A0                print song restart
  5788.     MOVE.B    sf_restart-sf_length(A0),word_to_print+1
  5789.     MOVE.L    #37*40+8,char_offset
  5790.     BSR    print_dec4
  5791. refresh_song_name
  5792.     MOVE.L    song_file_ptr,string_addr    print song name
  5793.     MOVE.L    #103*40+13,char_offset
  5794.     MOVE.L    #$14,string_size
  5795.     BRA    print_string
  5796.  
  5797. refresh_instr_parameters
  5798.     MOVE.W    current_instr,word_to_print    print instrument no.
  5799.     MOVE.L    #$788,char_offset
  5800.     BSR    print_hex4
  5801.     MOVEQ    #0,D0
  5802.     MOVE.W    current_instr,D0
  5803.     TST.W    D0
  5804.     BEQ    .skip
  5805.     ASL.L    #2,D0
  5806.     LEA    instr_addr_list,A0
  5807.     MOVE.L    0(A0,D0.L),instr_addr
  5808.     MOVE.L    song_file_ptr,A0
  5809.     SUB.L    #in_size-sf_instr,A0
  5810.     MOVE.W    current_instr,D0
  5811.     MULU    #in_size,D0
  5812.     ADD.L    D0,A0
  5813.     MOVE.L    A0,temp
  5814.     MOVE.W    in_length(A0),instr_length
  5815.     MOVE.W    in_volume(A0),instr_volume
  5816.     MOVE.W    in_repeat(A0),instr_repeat
  5817.     MOVE.W    in_replen(A0),instr_replen
  5818.     MOVE.W    in_volume(A0),word_to_print
  5819.     MOVE.L    #$940,char_offset        print volume
  5820.     BSR    print_hex4
  5821.     MOVE.W    instr_length,D0
  5822.     ADD.W    D0,D0
  5823.     MOVE.W    D0,word_to_print
  5824.     MOVE.L    #$AF8,char_offset        print length
  5825.     BSR    print_hex4
  5826.     MOVE.W    instr_repeat,D0
  5827.     ADD.W    D0,D0
  5828.     MOVE.W    D0,word_to_print
  5829.     MOVE.L    #$CB0,char_offset        print repeat
  5830.     BSR    print_hex4
  5831.     MOVE.W    instr_replen,D0
  5832.     ADD.W    D0,D0
  5833.     MOVE.W    D0,word_to_print
  5834.     MOVE.L    #$E68,char_offset        print replen
  5835.     BSR    print_hex4
  5836.     MOVE.L    temp,string_addr
  5837.     MOVE.L    #$11DD,char_offset        print name string
  5838.     MOVE.L    #22,string_size
  5839.     BSR    print_string
  5840. .skip    RTS
  5841.  
  5842. * entry    word_to_print = word
  5843.  
  5844. print_dec4
  5845.     MOVEQ    #0,D1
  5846.     MOVE.W    word_to_print,D1
  5847.     LEA    temp_str,A0
  5848.     DIVU    #1000,D1
  5849.     BSR.S    .digit
  5850.     DIVU    #100,D1
  5851.     BSR.S    .digit
  5852.     DIVU    #10,D1
  5853.     BSR.S    .digit
  5854.     BSR.S    .digit
  5855.     MOVE.L    #4,string_size
  5856.     MOVE.L    #temp_str,string_addr
  5857.     BSR    print_string
  5858.     CLR.L    temp_str
  5859.     CLR.W    word_to_print
  5860.     RTS
  5861. .digit    ADD.W    #'0',D1
  5862.     MOVE.B    D1,(A0)+
  5863.     CLR.W    D1
  5864.     SWAP    D1
  5865.     RTS
  5866.  
  5867. print_hex_instr
  5868.     MOVEQ    #0,D0
  5869.     TST.W    keyplay_period
  5870.     BEQ.S    print_hex1
  5871.     MOVE.W    current_instr,D0
  5872.  
  5873. print_hex1
  5874.     LSL.L    #1,D0
  5875.     LEA    hex2ascii,A0
  5876.     ADD.L    D0,A0
  5877.     MOVE.L    A0,string_addr
  5878.     MOVE.L    #1,string_size
  5879.     BSR.S    print_string
  5880.     CLR.W    word_to_print
  5881.     RTS
  5882.  
  5883. * entry    word_to_print = word
  5884.  
  5885. print_hex4
  5886.     LEA    word_to_print,A0
  5887.     MOVEQ    #0,D0
  5888.     MOVE.B    (A0),D0
  5889.     LSL.L    #1,D0
  5890.     LEA    hex2ascii,A0
  5891.     ADD.L    D0,A0
  5892.     MOVE.L    A0,string_addr
  5893.     MOVE.L    #2,string_size
  5894.     BSR.S    print_string
  5895.     LEA    word_to_print,A0
  5896.     MOVEQ    #0,D0
  5897.     MOVE.B    1(A0),D0
  5898.     LSL.L    #1,D0
  5899.     MOVE.L    #hex2ascii,A0
  5900.     ADD.L    D0,A0
  5901.     MOVE.L    A0,string_addr
  5902.     MOVE.L    #2,string_size
  5903.     BSR.S    print_string
  5904.     CLR.W    word_to_print
  5905.     RTS
  5906.  
  5907. print_string
  5908.     CLR.L    string_index    index=0
  5909.     MOVE.L    string_size,D3    d3=length
  5910. .loop    MOVE.L    string_addr,A0    index char
  5911.     ADD.L    string_index,A0
  5912.     MOVEQ    #0,D1
  5913.     MOVE.B    (A0),D1        if =0 then print null char (e.g. '_')
  5914.     BNE.S    .notnul
  5915.     MOVE.B    null_char,D1
  5916. .notnul    CMPI.B    #96,D1        lower->upper
  5917.     BLT.S    .upp
  5918.     SUB.B    #32,D1
  5919. .upp    SUB.B    #32,D1
  5920.     LSL.W    #4,D1
  5921.     LEA    charset,A0    index char
  5922.     ADD.L    D1,A0
  5923.     MOVE.L    screen_ptr,A1    row ptr
  5924.     ADD.L    char_offset,A1    +column index
  5925.     MOVE.B    (A0),(A1)    print char
  5926.     MOVE.B    2(A0),40(A1)
  5927.     MOVE.B    4(A0),80(A1)
  5928.     MOVE.B    6(A0),120(A1)
  5929.     MOVE.B    8(A0),160(A1)
  5930.     ADDQ.L    #1,string_index    index+1
  5931.     ADDQ.L    #1,char_offset    column+1
  5932.     CMP.L    string_index,D3    until index=length
  5933.     BNE.S    .loop
  5934.     RTS
  5935.  
  5936. print_string_spc
  5937.     MOVE.W    null_char,-(SP)
  5938.     MOVE.B    #' ',null_char
  5939.     BSR    print_string
  5940.     MOVE.W    (SP)+,null_char
  5941.     RTS
  5942.  
  5943. null_char dc.b    $7F,0
  5944.  
  5945. * entry    d0=x coord
  5946. *    d1=y coord
  5947. *    d2=height
  5948. *    a0=sprite ptr
  5949.  
  5950. position_sprite
  5951.     ADD.W    #44,D1        x+125,y+44
  5952.     ADD.W    D1,D2        put msb's in right place
  5953.     ROL.W    #7,D2
  5954.     ASL.W    #1,D2
  5955.     BCC.S    .lmsb0
  5956.     OR.W    #2,D2
  5957. .lmsb0    ROL.W    #7,D1
  5958.     ASL.W    #1,D1
  5959.     BCC.S    .fmsb0
  5960.     OR.W    #4,D2
  5961. .fmsb0    ADD.W    #125,D0
  5962.     ASR.W    #1,D0
  5963.     BCC.S    .hmsb0
  5964.     OR.W    #1,D2
  5965. .hmsb0    OR.W    D0,D1
  5966.     MOVE.W    D1,(A0)        store control words
  5967.     MOVE.W    D2,2(A0)
  5968.     RTS
  5969.  
  5970. * load/save file
  5971. * entry    file_nameptr = filename ptr
  5972. *    file_addr = addr
  5973. *    file_length = length
  5974.  
  5975. load_a_file
  5976.     TST.L    file_length
  5977.     BEQ.S    .skip
  5978.     BSR    arrow_is_green
  5979.     MOVE.L    DOSbase,A6
  5980.     MOVE.L    file_nameptr,D1
  5981.     MOVE.L    #1005,D2    read
  5982.     JSR    _LVOOpen(A6)
  5983.     MOVE.L    D0,file_handle
  5984.     BNE.S    .ok
  5985.     BSR    arrow_flash_red
  5986.     MOVEQ    #0,D0
  5987.     RTS
  5988. .ok    MOVE.L    file_handle,D1
  5989.     MOVE.L    file_addr,D2
  5990.     MOVE.L    file_length,D3
  5991.     JSR    _LVORead(A6)
  5992.     MOVE.L    file_handle,D1
  5993.     JSR    _LVOClose(A6)
  5994. .skip    CLR.L    file_handle
  5995.     BRA    arrow_is_grey
  5996.  
  5997. save_a_file
  5998.     BSR    arrow_is_green
  5999.     MOVE.L    DOSbase,A6
  6000.     MOVE.L    file_nameptr,D1
  6001.     MOVE.L    #1006,D2    write
  6002.     JSR    _LVOOpen(A6)
  6003.     MOVE.L    D0,file_handle
  6004.     BNE.S    .ok
  6005.     BRA    arrow_flash_red
  6006. .ok    MOVE.L    file_handle,D1
  6007.     MOVE.L    file_addr,D2
  6008.     MOVE.L    file_length,D3
  6009.     JSR    _LVOWrite(A6)
  6010.     MOVE.L    file_handle,D1
  6011.     JSR    _LVOClose(A6)
  6012.     CLR.L    file_handle
  6013.     BRA    arrow_is_grey
  6014.  
  6015. init_toneporta
  6016.     MOVE.W    (A6),D2        set start period
  6017.     AND.W    #$FFF,D2
  6018.     MOVE.W    D2,24(A6)
  6019.     MOVE.W    16(A6),D0    if = current then no portamento
  6020.     CLR.B    22(A6)        else set flag up/down
  6021.     CMP.W    D0,D2
  6022.     BEQ.S    .cancel
  6023.     BGE.S    .up
  6024.     MOVE.B    #1,22(A6)
  6025. .up    RTS
  6026. .cancel    CLR.W    24(A6)
  6027.     RTS
  6028.  
  6029. songcomm_toneporta
  6030.     MOVE.B    3(A6),D0
  6031.     BEQ.S    .continue
  6032.     MOVE.B    D0,23(A6)
  6033.     CLR.B    3(A6)
  6034. .continue
  6035.     TST.W    24(A6)
  6036.     BEQ.S    .skip
  6037.     MOVEQ    #0,D0
  6038.     MOVE.B    23(A6),D0
  6039.     TST.B    22(A6)
  6040.     BNE.S    .down
  6041.     ADD.W    D0,16(A6)
  6042.     MOVE.W    24(A6),D0
  6043.     CMP.W    16(A6),D0
  6044.     BGT.S    .ok
  6045.     MOVE.W    24(A6),16(A6)
  6046.     CLR.W    24(A6)
  6047. .ok    MOVE.W    16(A6),ac_per(A5)
  6048.     RTS
  6049. .down    SUB.W    D0,16(A6)
  6050.     MOVE.W    24(A6),D0
  6051.     CMP.W    16(A6),D0
  6052.     BLT.S    .ok
  6053.     MOVE.W    24(A6),16(A6)
  6054.     CLR.W    24(A6)
  6055.     MOVE.W    16(A6),ac_per(A5)
  6056. .skip    RTS
  6057.  
  6058. songcomm_vibrato
  6059.     MOVE.B    3(A6),D0
  6060.     BEQ.S    .continue
  6061.     MOVE.B    D0,26(A6)
  6062. .continue
  6063.     MOVE.B    27(A6),D0
  6064.     LEA    small_sine(PC),A4
  6065.     LSR.W    #2,D0
  6066.     AND.W    #$1F,D0
  6067.     MOVEQ    #0,D2
  6068.     MOVE.B    0(A4,D0.W),D2
  6069.     MOVE.B    26(A6),D0
  6070.     AND.W    #15,D0
  6071.     MULU    D0,D2
  6072.     LSR.W    #6,D2
  6073.     MOVE.W    16(A6),D0
  6074.     TST.B    27(A6)
  6075.     BMI.S    .minus
  6076.     ADD.W    D2,D0
  6077.     BRA.S    .plus
  6078. .minus    SUB.W    D2,D0
  6079. .plus    MOVE.W    D0,ac_per(A5)
  6080.     MOVE.B    26(A6),D0
  6081.     LSR.W    #2,D0
  6082.     AND.W    #$3C,D0
  6083.     ADD.B    D0,27(A6)
  6084.     RTS
  6085.  
  6086. small_sine
  6087.     dc.l    $0018314A    =255*sin(n*180/32),n=0..31
  6088.     dc.l    $61788DA1
  6089.     dc.l    $B4C5D4E0
  6090.     dc.l    $EBF4FAFD
  6091.     dc.l    $FFFDFAF4
  6092.     dc.l    $EBE0D4C5
  6093.     dc.l    $B4A18D78
  6094.     dc.l    $614A3118
  6095.  
  6096. no_songcomm
  6097.     MOVE.W    16(A6),ac_per(A5)
  6098.     RTS
  6099.  
  6100. songcomm_1234A
  6101.     MOVE.W    2(A6),D0
  6102.     AND.W    #$FFF,D0
  6103.     BEQ    no_songcomm
  6104.     MOVE.B    2(A6),D0
  6105.     AND.B    #15,D0
  6106.     TST.B    D0
  6107.     BEQ    songcomm_arpeggio
  6108.     CMPI.B    #1,D0
  6109.     BEQ.S    songcomm_portaup
  6110.     CMPI.B    #2,D0
  6111.     BEQ    songcomm_portadown
  6112.     CMPI.B    #3,D0
  6113.     BEQ    songcomm_toneporta
  6114.     CMPI.B    #4,D0
  6115.     BEQ    songcomm_vibrato
  6116.     MOVE.W    16(A6),ac_per(A5)
  6117.     CMPI.B    #$A,D0
  6118.     BEQ.S    songcomm_volslide
  6119.     RTS
  6120.  
  6121. songcomm_volslide
  6122.     MOVEQ    #0,D0
  6123.     MOVE.B    3(A6),D0
  6124.     LSR.B    #4,D0
  6125.     TST.B    D0
  6126.     BEQ.S    .down
  6127. .up    ADD.W    D0,18(A6)
  6128.     CMP.W    #64,18(A6)
  6129.     BMI.S    .up2
  6130.     MOVE.W    #64,18(A6)
  6131. .up2    MOVE.W    18(A6),ac_vol(A5)
  6132.     RTS
  6133. .down    MOVEQ    #0,D0
  6134.     MOVE.B    3(A6),D0
  6135.     AND.B    #15,D0
  6136.     SUB.W    D0,18(A6)
  6137.     BPL.S    .down2
  6138.     CLR.W    18(A6)
  6139. .down2    MOVE.W    18(A6),ac_vol(A5)
  6140.     RTS
  6141.  
  6142. songcomm_portaup
  6143.     MOVEQ    #0,D0
  6144.     MOVE.B    3(A6),D0
  6145.     SUB.W    D0,16(A6)
  6146.     MOVE.W    16(A6),D0
  6147.     CMPI.W    #$71,D0
  6148.     BPL.S    .ok
  6149.     MOVE.W    #$71,16(A6)
  6150. .ok    MOVE.W    16(A6),ac_per(A5)
  6151.     RTS
  6152.  
  6153. songcomm_portadown
  6154.     CLR.W    D0
  6155.     MOVE.B    3(A6),D0
  6156.     ADD.W    D0,16(A6)
  6157.     MOVE.W    16(A6),D0
  6158.     CMPI.W    #$358,D0
  6159.     BMI.S    .ok
  6160.     MOVE.W    #$358,16(A6)
  6161. .ok    MOVE.W    16(A6),ac_per(A5)
  6162.     RTS
  6163.  
  6164. songcomm_B_to_F
  6165.     MOVE.B    2(A6),D0
  6166.     AND.B    #15,D0
  6167.     CMPI.B    #$E,D0
  6168.     BEQ.S    .set_filter
  6169.     CMPI.B    #$D,D0
  6170.     BEQ.S    .pattern_break
  6171.     CMPI.B    #$B,D0
  6172.     BEQ.S    .position_jump
  6173.     CMPI.B    #$C,D0
  6174.     BEQ.S    .set_volume
  6175.     CMPI.B    #$F,D0
  6176.     BEQ.S    .set_speed
  6177.     RTS
  6178. .set_filter
  6179.     MOVE.B    3(A6),D0
  6180.     AND.B    #1,D0
  6181.     ASL.B    #1,D0
  6182.     AND.B    #$FD,$BFE001
  6183.     OR.B    D0,$BFE001
  6184.     RTS
  6185. .pattern_break
  6186.     MOVE.W    #1,pattern_break_flag
  6187.     RTS
  6188. .position_jump
  6189.     MOVE.W    #1,pattern_break_flag
  6190.     CMP.L    #'patt',play_mode    only if playing song
  6191.     BEQ.S    .pj2
  6192.     MOVE.B    3(A6),D0
  6193.     SUBQ.B    #1,D0
  6194.     MOVE.B    D0,song_position+3
  6195. .pj2    RTS
  6196. .set_volume
  6197.     CMP.B    #64,3(A6)        max 64
  6198.     BLE.S    .sv2
  6199.     MOVE.B    #64,3(A6)
  6200. .sv2    MOVE.B    3(A6),ac_vol(A5)
  6201.     MOVE.B    3(A6),1(A2)
  6202.     MOVE.B    3(A6),19(A6)
  6203.     RTS
  6204. .set_speed
  6205.     CMP.B    #31,3(A6)        max 31
  6206.     BLE.S    .ss2
  6207.     MOVE.B    #31,3(A6)
  6208. .ss2    MOVEQ    #0,D0
  6209.     MOVE.B    3(A6),D0
  6210.     MOVE.L    D0,tempo
  6211.     CLR.L    frame_count
  6212.     RTS
  6213.  
  6214. songs_dir
  6215.     dc.b    'st-00:songs/'
  6216. songs_dir_name
  6217.     ds.b    28
  6218.  
  6219. st01_msg
  6220.     dc.b    'st-01:'
  6221.     ds.b    28
  6222.  
  6223. modname_buffer
  6224.     ds.b    50
  6225.  
  6226. song_length
  6227.     dc.w    1
  6228.  
  6229. DOSname    dc.b    'dos.library',0
  6230. GFXname    dc.b    'graphics.library',0
  6231.  
  6232.     dc.b    0
  6233. audio_info_1
  6234.     dc.l    0,0,0,0,0,$10000,0
  6235. audio_info_2
  6236.     dc.l    0,0,0,0,0,$20000,0
  6237. audio_info_3
  6238.     dc.l    0,0,0,0,0,$40000,0
  6239. audio_info_4
  6240.     dc.l    0,0,0,0,0,$80000,0
  6241.  
  6242. hex_keys
  6243.     dc.b    $0A,$01,$02,$03        keys    0..9,A..F
  6244.     dc.b    $04,$05,$06,$07
  6245.     dc.b    $08,$09,$20,$35
  6246.     dc.b    $33,$22,$12,$23
  6247.  
  6248. piano_keys
  6249.     dc.b    $31,$21,$32,$22        keys     ZSXDCVGB
  6250.     dc.b    $33,$34,$24,$35
  6251.     dc.b    $25,$36,$26,$37            HNJM,L.;
  6252.     dc.b    $38,$28,$39,$29
  6253.     dc.b    $3A,$10,$02,$11            /Q2W3ER5
  6254.     dc.b    $03,$12,$13,$05
  6255.     dc.b    $14,$06,$15,$07            T6Y7UI9O
  6256.     dc.b    $16,$17,$09,$18
  6257.     dc.b    $0A,$19,$1A,$0C            0P[=]\{BS}
  6258.     dc.b    $1B,$0D,$46
  6259.     dc.b    $00
  6260.  
  6261. oct1_2_periods
  6262.     dc.l    $3580328,$2FA02D0,$2A60280,$25C023A
  6263.     dc.l    $21A01FC,$1E001C5,$1AC0194,$17D0168
  6264.     dc.l    $15301AC,$194017D,$1680153,$140012E
  6265.     dc.l    $11D010D,$0FE00F0,$0E200D6,$0CA00BE
  6266.     dc.l    $0B400AA,$0A00097,$08F0087
  6267.     dc.w    0
  6268.  
  6269. oct1_2_names
  6270.     dc.b    'c-1 c#1 d-1 d#1 e-1 f-1 f#1 g-1 g#1 a-1 a#1 b-1 '
  6271.     dc.b    'c-2 c#2 d-2 d#2 e-2 '
  6272.     dc.b    'c-2 c#2 d-2 d#2 e-2 f-2 f#2 g-2 g#2 a-2 a#2 b-2 '
  6273.     dc.b    'c-3 c#3 d-3 d#3 e-3 f-3 f#3 g-3 g#3 '
  6274.     dc.b    '--- '
  6275.  
  6276. oct2_3_periods
  6277.     dc.l    $1AC0194,$17D0168,$1530140,$12E011D
  6278.     dc.l    $10D00FE,$0F000E2,$0D600CA,$0BE00B4
  6279.     dc.l    $0AA00D6,$0CA00BE,$0B400AA,$0A00097
  6280.     dc.l    $08F0087,$07F0078,$0710000,0
  6281.     dc.l    0,0,0
  6282.     dc.w    0
  6283.  
  6284. oct2_3_names
  6285.     dc.b    'c-2 c#2 d-2 d#2 e-2 f-2 f#2 g-2 g#2 a-2 a#2 b-2 '
  6286.     dc.b    'c-3 c#3 d-3 d#3 e-3 '
  6287.     dc.b    'c-3 c#3 d-3 d#3 e-3 f-3 f#3 g-3 g#3 a-3 a#3 b-3 '
  6288.     dc.b    '--- --- --- --- --- --- --- --- --- --- '
  6289.  
  6290. oct1_2_3_periods
  6291.     dc.l    $3580328,$2FA02D0,$2A60280,$25C023A
  6292.     dc.l    $21A01FC,$1E001C5,$1AC0194,$17D0168
  6293.     dc.l    $1530140,$12E011D,$10D00FE,$0F000E2
  6294.     dc.l    $0D600CA,$0BE00B4,$0AA00A0,$097008F
  6295.     dc.l    $087007F,$0780071,0,0
  6296.     dc.l    0,0,0,0
  6297.     dc.l    0,0,0
  6298.  
  6299. oct1_2_3_names
  6300.     dc.b    'c-1 c#1 d-1 d#1 e-1 f-1 f#1 g-1 g#1 a-1 a#1 b-1 '
  6301.     dc.b    'c-2 c#2 d-2 d#2 e-2 f-2 f#2 g-2 g#2 a-2 a#2 b-2 '
  6302.     dc.b    'c-3 c#3 d-3 d#3 e-3 f-3 f#3 g-3 g#3 a-3 a#3 b-3 '
  6303.     dc.b    '--- '
  6304.  
  6305. valid_name_keycodes
  6306.     dc.b    $40                    SPACE
  6307.     dc.b    $20,$35,$33,$22,$12,$23,$24,$25        A..Z
  6308.     dc.b    $17,$26,$27,$28,$37,$36,$18,$19
  6309.     dc.b    $10,$13,$21,$14,$16,$34,$11,$32
  6310.     dc.b    $15,$31
  6311.     dc.b    $0A,$01,$02,$03,$04,$05,$06,$07        0..9
  6312.     dc.b    $08,$09
  6313.     dc.b    $88,$89,$39,$0B,$2A,$AA,$A9,$87,$8B    *(.-#@:&_
  6314.  
  6315.     dc.w    $54,$59,$5E,$63,$6A,$70,$76,$7E
  6316.     dc.w    $85,$8C,$95,$9E,$A7,$B1,$BC,$C6
  6317.     dc.w    $D3,$DF,$ED,$FB,$10A,$11A,$12A,$13D
  6318.     dc.w    $14F,$162,$179,$18E,$1A5,$1C0,$1DA,$1F4
  6319.     dc.w    $212,$234,$25A,$284
  6320.  
  6321. xpos2column
  6322.     dc.b    3,6,7,8,9,10        convert edit cursor xpos to column
  6323.     dc.b    12,15,16,17,18,19
  6324.     dc.b    21,24,25,26,27,28
  6325.     dc.b    30,33,34,35,36,37
  6326.  
  6327. valid_name_chars
  6328.     dc.b    ' abcdefghijklmno'
  6329.     dc.b    'pqrstuvwxyz01234'
  6330.     dc.b    '56789().-',$27,'#:/',0
  6331.  
  6332. hallonsoft
  6333.     dc.b    $25,$20,$28,$28        keycodes for 'HALLONSOFT'
  6334.     dc.b    $18,$36,$21,$18
  6335.     dc.b    $23,$14,$FF,$FF
  6336.  
  6337. *------------------------------
  6338. * GRAPHICS FILES
  6339.  
  6340. charset    incbin    charset.dat    64 chars 8*8 pixels 2 plane
  6341. spectrum_screen
  6342.     incbin spectrum.img    55 rows * 13 words 2 plane
  6343. diskops_screen
  6344.     incbin    diskops.img    99 rows * 13 words 2 plane
  6345. onoff_icon
  6346.     incbin    onoff.img    12 rows * 2 words 2 plane
  6347.  
  6348.     dc.w    $000,$555    (UNUSED)
  6349.     dc.w    $AAA,$FFF
  6350.  
  6351. rusure_icon
  6352.     incbin    rusure.img    39 rows * 7 words 2 plane
  6353.  
  6354. hsoft_ptr dc.l    hallonsoft    ptr to 'cheat mode' key-string
  6355.  
  6356. plst_screen
  6357.     incbin    plst.img    99 rows * 13 words 2 plane
  6358. drive_icon
  6359.     incbin    seldrive.img    34 rows * 5 words 2 plane
  6360.  
  6361.     dc.w    $FFFF,0        (UNUSED)
  6362.  
  6363. *------------------------------
  6364. * VARIABLES
  6365.  
  6366. cutvoice_buffer    ds.b    256    cut/paste voice buffer
  6367. cutwhole_buffer    ds.b    1024    cut/paste pattern buffer
  6368. fscroll_pending    dc.w    0    diskop file scroll 0=none/1=up/2=down
  6369. pscroll_pending    dc.w    0    plst file scroll
  6370. sprite_addrs    ds.l    8    only used to setup
  6371. copper_init    dc.l    0    old copper
  6372. screen_ptr    dc.l    0    ptr to 3rd plane of screen (info+scroller)
  6373. char_offset    dc.l    0    screen offset for character printer
  6374. rpd_row        dc.l    0    local
  6375. edit_mode    dc.l    0    0=off/'edit'=on
  6376. play_mode    dc.l    0    0=off/'patt'=pattern/'patp'=play
  6377. temp        dc.l    0
  6378. string_index    dc.l    0    index to printed string
  6379. string_addr    dc.l    0    ptr to printed string
  6380. string_size    dc.l    0    size of printed string
  6381. pattern_no    dc.l    0    current pattern displayed
  6382. tempo        dc.l    0    default playback tempo
  6383. octave_periods    dc.l    0    ptrs to periods and names of currently
  6384. octave_names    dc.l    0    selected keyboard octave (1..2 or 2..3)
  6385. ain_disable    dc.w    0    (UNALTERED)
  6386. edh_index    dc.w    0    local
  6387. key_code    dc.w    0    latest key pressed
  6388. keyplay_period    dc.w    0    period of note played from keyboard
  6389. input_cursor_x    dc.w    0    for inputroutine
  6390. input_cursor_y    dc.w    0    :
  6391. input_end_addr    dc.l    0    :
  6392. edit_cursor_y    dc.w    0    pattern edit cursor y = row 0..63
  6393. edit_cursor_x    dc.w    0    cursor x = 0..5/6..11/12..17/18..23
  6394. rep_delay    dc.w    0    (UNALTERED) 0=delay/-1=no delay
  6395. word_to_print    dc.w    0    word to print in hex
  6396. max_pat_no    dc.w    0    max pattern no. in song file
  6397. current_instr    dc.w    0    current instrument
  6398. plst_entry_no    dc.w    0    entry no. selected in plst
  6399. alter_dir    dc.w    0    direction for altering parameters
  6400. mouse_oldx    dc.w    0    mouse update vars (local)
  6401. mouse_oldy    dc.w    0    :
  6402. mouse_sumx    dc.w    0    :
  6403. mouse_sumy    dc.w    0    :
  6404. mouse_x        dc.w    0    current mouse x=0..319
  6405. mouse_y        dc.w    0    current mouse y=0..255
  6406. mouse_x2    dc.w    0    copy of mouse_x
  6407. mouse_y2    dc.w    0    copy of mouse_y
  6408. instr_length    dc.w    0    parameters of current instrument
  6409. instr_volume    dc.w    0    :
  6410. instr_repeat    dc.w    0    :
  6411. instr_replen    dc.w    0    :
  6412. instr_addr    dc.l    0    :
  6413. new_pat_flag    dc.w    0    set if new pattern to display
  6414. prev_pat_no    dc.l    0    used to check if update required
  6415. pattern_break_flag dc.w    0    set if pattern break/position jump in song
  6416. new_pat_no    dc.l    0    pattern to use after break/jump
  6417. quantize_flag    dc.w    0    set if note was played within quantize time
  6418. alloc7k_ptr    dc.l    0    (UNUSED)
  6419. DOSbase        dc.l    0    DOS library base
  6420. file_nameptr    dc.l    0    filename vars
  6421. file_addr    dc.l    0    :
  6422. file_handle    dc.l    0    :
  6423. file_length    dc.l    0    :
  6424. selected_filename ds.b    30    :
  6425. play_cursor    dc.l    0    pattern index while playing = 16*row+column
  6426. song_position    dc.l    0    current position in song
  6427. frame_count    dc.l    0    50Hz counter for song update
  6428. play_row_index    dc.l    0    index to pattern row played (UNUSED)
  6429. song_file_ptr    dc.l    0    ptr to current song file
  6430. keyplay_channel    dc.w    0    audio channel played from keyboard
  6431. instr_alloc_list ds.l    2*31    alloc'd instrument memory (31 addrs,31 sizes)
  6432. instr_addr_list    ds.l    32    ptrs to instrument samples
  6433. player_channels    dc.w    0    audio channels active in player
  6434. old_irq2_addr    dc.l    0    old keyboard irq vector
  6435. old_irq2_patch    dc.l    0    :
  6436. initialSP    dc.l    0    old SP
  6437. old_irq3_vect    dc.l    0    old vbl irq vector
  6438.     dc.l    0,0        (UNUSED)
  6439. spectrum_new    ds.w    23    new/old spectrum analyser lists
  6440. spectrum_old    ds.w    23    :
  6441. disk_fn        dc.w    0    disk function awaiting file selection
  6442. *                0=none/1=load song/2=delete song
  6443. *                3=load module/4=delete module/5=load sample
  6444.     dc.l    0        (UNUSED)
  6445. lock_ptr    dc.l    0    ptr from Lock
  6446.  
  6447.     align            must be divisible by 4 !!!!
  6448. FileInfoBlock    ds.b    256    file info block from Examine
  6449.  
  6450. mode        dc.w    0    0=entry/1=editor/3=diskops/
  6451. old_arrow_colours ds.w    3    saved arrow colours
  6452. ipn_temp    dc.w    0    local
  6453. load_sort_flag    dc.w    0    sort list for loading samples
  6454. load_sort_list    ds.l    31    with a minimum of disk swapping
  6455. plst_size    dc.l    0    preset list
  6456. plst_ptr    dc.l    0    :
  6457. plst_entries    dc.w    0    :
  6458. GFXbase        dc.l    0    Graphics library base
  6459. INTbase        dc.l    0    Intuition library base
  6460. _WBenchMsg    dc.l    0    Message ptr for WB startup
  6461. plst_flag    dc.w    0    0=off/-1=on
  6462. edit_icons_copy ds.b    2200    copy of edit icons
  6463. old_volume    dc.w    0    local
  6464. instr_header    ds.l    32    sample header lengths
  6465. sample_filename    ds.b    16    filename
  6466. dir_entry_ptr    dc.l    0    ptr to file selected from directory
  6467. key_enter    dc.w    0    set if enter key pressed
  6468. memory_free    dc.l    0    memory free
  6469. memory_used    dc.l    0    memory used
  6470. ffi_type    dc.w    0    for find_file_type, 0=file/1=dir/2=disk
  6471. ffi_type_prev    dc.w    0    previous value
  6472. plst_active_entries dc.w 0    no. of entries matching search disks
  6473. plst_cursor    dc.w    0    top row of preset list displayed
  6474. plst_active_size dc.l    0    size of above (no.*in_size)
  6475. plst_indices    ds.l    15    indices of displayed plst entries
  6476. cursor_rep_flag    dc.w    0    auto-repeat for cursor keys
  6477. cursor_rep_count dc.w    0    :
  6478. pat_pos_dir    dc.l    0    change pattern/position with cursor
  6479. pat_pos_flag    dc.w    0    :
  6480. input_in_progress dc.w    0    =1 if inputroutine active
  6481. iff_length    dc.l    0    length of sample in IFF file
  6482. hsoft_flag    dc.w    0    flag set if 'HALLONSOFT' typed in
  6483. key_lshift    dc.w    0    set if left-shift pressed
  6484. stop_request    dc.w    0    set to disable Intuition Requester
  6485. temp_str    ds.b    6    local
  6486. arrow_spr_ptr    dc.l    0    ptr to arrow sprite
  6487. pack_buffer_ptr    dc.l    0    cruncher/decruncher vars
  6488. pack_source_end    dc.l    0    :
  6489. unpacked_size    dc.l    0    :
  6490. pack_dest_start    dc.l    0    :
  6491. pack_dest_end    dc.l    0    :
  6492. packed_size    dc.l    0    :
  6493. pack_best_distance dc.l    0    :
  6494. pack_best_mode    dc.w    0    :
  6495. pack_used_00    dc.w    0    :
  6496. pack_used_111    dc.w    0    :
  6497. key_lalt    dc.w    0    :
  6498. cptr_plane3b    dc.l    0    ptr to 2nd plane3 addr in copper list
  6499. clist_ptr    dc.l    0    ptr to copper list
  6500. cptr_con0c    dc.l    0    ptr to bplcon0 lower screen in copper list
  6501. clist_ptr2    dc.l    0    copy of clist_ptr, (UNUSED)
  6502. cptr_plane1_2    dc.l    0    (UNUSED)
  6503. cptr_arrow_col    dc.l    0    ptr to arrow colours in copper list
  6504. hex2ascii    ds.w    256    converts 0..255 => '00'..'FF'
  6505. null_string    ds.b    24    string of 0's
  6506. memory_flag    dc.w    1    set if memory usage changed (init=1)
  6507.  
  6508. *------------------------------
  6509.  
  6510. copper_list
  6511.     DC.W    spr0pth,0,spr0ptl,0        set sprites
  6512.     DC.W    spr1pth,0,spr1ptl,0
  6513.     DC.W    spr2pth,0,spr2ptl,0
  6514.     DC.W    spr3pth,0,spr3ptl,0
  6515.     DC.W    spr4pth,0,spr4ptl,0
  6516.     DC.W    spr5pth,0,spr5ptl,0
  6517.     DC.W    spr6pth,0,spr6ptl,0
  6518.     DC.W    spr7pth,0,spr7ptl,0
  6519. cl_plane1_2
  6520.     DC.W    bpl1pth,0,bpl1ptl,0        set planes 1..3
  6521.     DC.W    bpl2pth,0,bpl2ptl,0
  6522.     DC.W    bpl3pth
  6523. cl_plane3
  6524.     DC.W    0
  6525.     DC.W    bpl3ptl
  6526.     DC.W    0
  6527. cl_arrow_col
  6528.     DC.W    color0+2*17,$E00,color0+2*18,$B00    colours
  6529.     DC.W    color0+2*19,$800,color0+2*16,0
  6530.     DC.W    color0,0
  6531. cl_col1    DC.W    color0+2*1,$733
  6532.     DC.W    color0+2*2,$A66,color0+2*3,$C99
  6533.     DC.W    color0+2*4,$AFB,color0+2*21,$900
  6534.     DC.W    color0+2*22,$600,color0+2*23,$E00
  6535.     DC.W    diwstrt,$2C81,diwstop,$2CC1    standard 256*320
  6536.     DC.W    ddfstrt,$38,ddfstop,$D0
  6537.     DC.W    bplcon1,0            no scroll
  6538.     DC.W    bplcon2,$24            sprite priority
  6539.     DC.W    $2C07,$FFFE            wait v44
  6540.     DC.W    bplcon0,$3200            3 planes
  6541. cl_spectrum
  6542.     DS.W    320                spectrum analyser
  6543.     DC.W    $B807,$FFFE            wait v184
  6544.     DC.W    bplcon0,$2200            2 planes
  6545. cl_plane3b
  6546.     DC.W    bpl3pth,0,bpl3ptl,0        set plane 3
  6547.     DC.W    color0+2*4
  6548. cl_col4b
  6549.     DC.W    $990                set colour 4 lower half
  6550.     DC.W    $B907,$FFFE            wait v185
  6551.     DC.W    bplcon0
  6552. cl_con0c
  6553.     DC.W    $3200                3 planes
  6554. cl_chaneq
  6555.     DS.W    672                channel eq's
  6556.     DC.W    $E907,$FFFE            wait v233
  6557.     DC.W    bpl2mod,-40,bpl1mod,-40        magnify edit line
  6558.     DC.W    $EA07,$FFFE            by changing modulos
  6559.     DC.W    bplcon2,$10            change priority
  6560.     DC.W    bpl2mod,0,bpl1mod,0
  6561.     DC.W    $EB07,$FFFE
  6562.     DC.W    bpl2mod,-40,bpl1mod,-40
  6563.     DC.W    $EC07,$FFFE
  6564.     DC.W    bpl2mod,0,bpl1mod,0
  6565.     DC.W    $ED07,$FFFE
  6566.     DC.W    bpl2mod,-40,bpl1mod,-40
  6567.     DC.W    $EE07,$FFFE
  6568.     DC.W    bpl2mod,0,bpl1mod,0
  6569.     DC.W    $EF07,$FFFE
  6570.     DC.W    bpl2mod,-40,bpl1mod,-40
  6571.     DC.W    $F007,$FFFE
  6572.     DC.W    bpl2mod,0,bpl1mod,0
  6573.     DC.W    $F107,$FFFE
  6574.     DC.W    bpl2mod,-40,bpl1mod,-40
  6575.     DC.W    $F207,$FFFE
  6576.     DC.W    bpl2mod,0,bpl1mod,0
  6577.     DC.W    $F307,$FFFE
  6578.     DC.W    bpl2mod,-40,bpl1mod,-40
  6579.     DC.W    $F407,$FFFE
  6580.     DC.W    bpl2mod,0,bpl1mod,0
  6581.     DC.W    $F507,$FFFE
  6582.     DC.W    bpl2mod,-40,bpl1mod,-40
  6583.     DC.W    $F607,$FFFE            wait v246
  6584.     DC.W    bpl2mod,0,bpl1mod,0        reset modulos
  6585.     DC.W    color0+2*25,0,color0+2*26,0,color0+2*27,0 clear sprites
  6586.     DC.W    color0+2*29,0,color0+2*30,0,color0+2*31,0
  6587.     DC.W    $FFDF,$FFFE            wait v255
  6588.     DC.W    $2907,$FFFE            wait v297
  6589.     DC.W    bplcon0,$2200            2 planes
  6590.     DC.W    $2C07,$FFFE            wait v300
  6591.     DC.W    bplcon0,$200            0 planes
  6592.     DC.W    $FFFF,$FFFE
  6593.  
  6594. s_arrow    DC.W    0,0
  6595.     DC.W    %1111111111111111,%1111111111111111    arrow
  6596.     DC.W    %1000000000000010,%1111111111111110
  6597.     DC.W    %1011111111110100,%1100000000001100
  6598.     DC.W    %1011111111101000,%1100000000011000
  6599.     DC.W    %1011111111010000,%1100000000110000
  6600.     DC.W    %1011111111101000,%1100000000011000
  6601.     DC.W    %1011111111110100,%1100000000001100
  6602.     DC.W    %1011111111111010,%1100000000000110
  6603.     DC.W    %1011111111111101,%1100000000000011
  6604.     DC.W    %1011111111111010,%1100000000000110
  6605.     DC.W    %1011011111110100,%1100100000001100
  6606.     DC.W    %1010101111101000,%1101110000011000
  6607.     DC.W    %1001010111010000,%1111011000110000
  6608.     DC.W    %1010001010100000,%1110001101100000
  6609.     DC.W    %1100000101000000,%1100000111000000
  6610.     DC.W    %1000000010000000,%1000000010000000
  6611.     DC.W    0,0
  6612.     DC.W    0
  6613.  
  6614. s_editcursor
  6615.     DC.W    0,0
  6616.     DC.W    %1111111111100000,%1111111111100000    edit cursor
  6617.     DC.W    %1111111111100000,%1111111111100000
  6618.     REPT    10
  6619.     DC.W    %1000000000100000,%0000000000000000
  6620.     ENDR
  6621.     DC.W    %0000000000000000,%1111111111100000
  6622.     DC.W    %0000000000000000,%1111111111100000
  6623.     DC.W    0,0
  6624.  
  6625. s_inputcursor
  6626.     DC.W    0,0
  6627.     DC.W    %0000000000000000,%1111111000000000    input cursor
  6628.     DC.W    %0000000000000000,%1111111000000000
  6629.     DC.W    0,0
  6630.     DC.W    0,0
  6631.  
  6632. s_chaneq1
  6633.     DC.W    $E95B,$EA01
  6634.     REPT    48
  6635.     DC.W    %1100000011000000,%0011111111000000    channel eq's 1..4
  6636.     ENDR
  6637.     DC.W    0,0
  6638. s_chaneq2
  6639.     DC.W    $E97F,$EA01
  6640.     REPT    48
  6641.     DC.W    %1100000011000000,%0011111111000000
  6642.     ENDR
  6643.     DC.W    0,0
  6644. s_chaneq3
  6645.     DC.W    $E9A3,$EA01
  6646.     REPT    48
  6647.     DC.W    %1100000011000000,%0011111111000000
  6648.     ENDR
  6649.     DC.W    0,0
  6650. s_chaneq4
  6651.     DC.W    $E9C7,$EA01
  6652.     REPT    48
  6653.     DC.W    %1100000011000000,%0011111111000000
  6654.     ENDR
  6655.     DC.W    0,0
  6656.  
  6657. cl_hallon
  6658.     DC.W    bplcon0,$2000,bplcon1,$CC,bplcon2,0    hallonsoft copper
  6659.     DC.W    bpl1mod,0,bpl2mod,0
  6660.     DC.W    dmacon,$20
  6661.     DC.W    bpl1pth,0,bpl1ptl,0
  6662.     DC.W    bpl2pth,0,bpl2ptl,0
  6663.     DC.W    color0,$4BF,color0+2*1,$166
  6664.     DC.W    color0+2*2,$5AA,color0+2*3,$AFF
  6665.     DC.W    diwstrt,$5071,diwstop,$90C7
  6666.     DC.W    ddfstrt,$60,ddfstop,$98
  6667.     DC.W    $6373,$FFFE,color0+2*3,$3FF
  6668.     DC.W    $63A9,$FFFE,color0+2*3,$AFF
  6669.     DC.W    $6473,$FFFE,color0+2*3,$4FF
  6670.     DC.W    $64A9,$FFFE,color0+2*3,$AFF
  6671.     DC.W    $6573,$FFFE,color0+2*3,$5FF
  6672.     DC.W    $65A9,$FFFE,color0+2*3,$AFF
  6673.     DC.W    $6673,$FFFE,color0+2*3,$6FF
  6674.     DC.W    $66A9,$FFFE,color0+2*3,$AFF
  6675.     DC.W    $6773,$FFFE,color0+2*3,$7FF
  6676.     DC.W    $67A9,$FFFE,color0+2*3,$AFF
  6677.     DC.W    $6873,$FFFE,color0+2*3,$8FF
  6678.     DC.W    $68A9,$FFFE,color0+2*3,$AFF
  6679.     DC.W    $6973,$FFFE,color0+2*3,$9FF
  6680.     DC.W    $69A9,$FFFE,color0+2*3,$AFF
  6681.     DC.W    $6A73,$FFFE,color0+2*3,$AFF
  6682.     DC.W    $6AA9,$FFFE,color0+2*3,$AFF
  6683.     DC.W    $6B73,$FFFE,color0+2*3,$AEF
  6684.     DC.W    $6BA9,$FFFE,color0+2*3,$AFF
  6685.     DC.W    $6C73,$FFFE,color0+2*3,$ADF
  6686.     DC.W    $6CA9,$FFFE,color0+2*3,$AFF
  6687.     DC.W    $6D73,$FFFE,color0+2*3,$ACF
  6688.     DC.W    $6DA9,$FFFE,color0+2*3,$AFF
  6689.     DC.W    $6E73,$FFFE,color0+2*3,$ABF
  6690.     DC.W    $6EA9,$FFFE,color0+2*3,$AFF
  6691.     DC.W    $6F73,$FFFE,color0+2*3,$AAF
  6692.     DC.W    $6FA9,$FFFE,color0+2*3,$AFF
  6693.     DC.W    $7073,$FFFE,color0+2*3,$A9F
  6694.     DC.W    $70A9,$FFFE,color0+2*3,$AFF
  6695.     DC.W    $7173,$FFFE,color0+2*3,$A8F
  6696.     DC.W    $71A9,$FFFE,color0+2*3,$AFF
  6697.     DC.W    $FFFF,$FFFE
  6698.  
  6699. *------------------------------
  6700.  
  6701. hallon_logo
  6702.     incbin    hallogo.img    64 rows * 8 words 2 plane
  6703.  
  6704. main_screen
  6705.     incbin    tracker.img    256 rows * 20 words 2 plane
  6706.  
  6707. *------------------------------
  6708.  
  6709.