Changeset 4f508e6 in buchla-68k


Ignore:
Timestamp:
07/01/2017 02:34:46 PM (7 years ago)
Author:
Thomas Lopatic <thomas@…>
Branches:
master
Children:
08e1da1
Parents:
f40a309
Message:

Converted assembly language files.

Files:
2 added
50 edited

Legend:

Unmodified
Added
Removed
  • iolib/hwdefs.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * hwdefs.s --  External definitions of Buchla 700 I/O addresses
    3 * Version 14 -- 1988-08-15 -- D.N. Lynx Crowe
    4 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| hwdefs.s --  External definitions of Buchla 700 I/O addresses
     3| Version 14 -- 1988-08-15 -- D.N. Lynx Crowe
     4| ------------------------------------------------------------------------------
    55                .text
    6 *
     6
    77                .xdef   _io_time,_io_lcd,_io_ser,_io_midi
    88                .xdef   _io_disk,_io_tone,_io_leds,_io_kbrd
    99                .xdef   _io_vreg,_io_vraw,_io_vram,_io_fpu
    1010                .xdef   _lcd_a0,_lcd_a1
    11 *
     11
    1212                .xdef   _v_regs,_v_odtab,_v_actab
    1313                .xdef   _v_ct0
    1414                .xdef   _v_gt1
    1515                .xdef   _v_score,_v_cgtab
    16 *
     16
    1717                .xdef   _v_curs0,_v_curs1,_v_curs2,_v_curs3
    1818                .xdef   _v_curs4,_v_curs5,_v_curs6,_v_curs7
     
    2020                .xdef   _v_win0
    2121                .xdef   _v_cur
    22 *
     22
    2323                .xdef   _fc_sw,_fc_val
    24 *
    25 * ------------------------------------------------------------------------------
    26 *
    27 * Hardware base addresses
    28 * -----------------------
    29 _io_fpu         .equ    $180000         * FPU base address
    30 *
    31 VB              .equ    $200000         * VSDD base address
    32 *
    33 _io_time        .equ    $3A0001         * Timer chip
    34 _io_lcd         .equ    $3A4001         * LCD controller
    35 _io_ser         .equ    $3A8001         * Serial ports  (RS232)
    36 _io_midi        .equ    $3AC001         * MIDI ports
    37 _io_disk        .equ    $3B0001         * Disk controller
    38 _io_tone        .equ    $3B4001         * Sound generator chip
    39 _io_leds        .equ    $3B8001         * LED driver
    40 _io_kbrd        .equ    $3BC001         * Keyboard / panel processor
    41 *
    42 _lcd_a0         .equ    _io_lcd         * LCD port a0
    43 _lcd_a1         .equ    _io_lcd+2       * LCD port a1
    44 *
     24
     25| ------------------------------------------------------------------------------
     26
     27| Hardware base addresses
     28| -----------------------
     29_io_fpu         =       0x180000        | FPU base address
     30
     31VB              =       0x200000        | VSDD base address
     32
     33_io_time        =       0x3A0001        | Timer chip
     34_io_lcd         =       0x3A4001        | LCD controller
     35_io_ser         =       0x3A8001        | Serial ports  (RS232)
     36_io_midi        =       0x3AC001        | MIDI ports
     37_io_disk        =       0x3B0001        | Disk controller
     38_io_tone        =       0x3B4001        | Sound generator chip
     39_io_leds        =       0x3B8001        | LED driver
     40_io_kbrd        =       0x3BC001        | Keyboard / panel processor
     41
     42_lcd_a0         =       _io_lcd         | LCD port a0
     43_lcd_a1         =       _io_lcd+2       | LCD port a1
     44
    4545                .page
    46 *
    47 * Video definitions
    48 * -----------------
    49 _io_vreg        .equ    VB              * Relocated video registers after setup
    50 _io_vraw        .equ    VB+$400         * Raw video registers at RESET
    51 _io_vram        .equ    VB              * Video RAM base address
    52 *
    53 * Name                  Offset            Usage                        Bank
    54 * -------               ---------         -------------------------    ----
    55 _v_regs         .equ    VB              * Video registers              0,1
    56 *
    57 _v_odtab        .equ    VB+128          * Object Descriptor Table       0
    58 _v_actab        .equ    VB+256          * Access Table                  0
    59 _v_ct0          .equ    VB+1024         * Character Text-0              0
    60 _v_gt1          .equ    VB+1304         * Graphics Text-1               0
    61 _v_score        .equ    VB+8192         * Score object                  0
    62 _v_cgtab        .equ    VB+122880       * Character Generator Table     0
    63 *
    64 _v_curs0        .equ    VB+1024         * Cursor object 0  (arrow ULE)  1
    65 _v_curs1        .equ    VB+1152         * Cursor object 1  (arrow ULO)  1
    66 _v_curs2        .equ    VB+1280         * Cursor object 2  (arrow URE)  1
    67 _v_curs3        .equ    VB+1408         * Cursor object 3  (arrow URO)  1
    68 _v_curs4        .equ    VB+1536         * Cursor object 4  (arrow LLE)  1
    69 _v_curs5        .equ    VB+1664         * Cursor object 5  (arrow LLO)  1
    70 _v_curs6        .equ    VB+1792         * Cursor object 6  (arrow LRE)  1
    71 _v_curs7        .equ    VB+1920         * Cursor object 7  (arrow LRO)  1
    72 _v_tcur         .equ    VB+2048         * Typewriter cursor             1
    73 _v_kbobj        .equ    VB+2880         * Keyboard object               1
    74 _v_lnobj        .equ    VB+4672         * Line object                   1
    75 _v_cur          .equ    VB+6464         * Underline cursor              1
    76 _v_win0         .equ    VB+16384        * Window-0 object               1
    77 *
    78 * BIOS RAM definitions
    79 * --------------------
    80 * WARNING: the following addresses must match those of the corresponding
    81 * variables defined in bios.s or chaos is guaranteed.
    82 *
    83 _fc_sw          .equ    $420            * word - Frame counter switch
    84 _fc_val         .equ    $422            * long - Frame counter value
    85 *
     46
     47| Video definitions
     48| -----------------
     49_io_vreg        =       VB              | Relocated video registers after setup
     50_io_vraw        =       VB+0x400        | Raw video registers at RESET
     51_io_vram        =       VB              | Video RAM base address
     52
     53| Name                  Offset            Usage                        Bank
     54| -------               ---------         -------------------------    ----
     55_v_regs         =       VB              | Video registers              0,1
     56
     57_v_odtab        =       VB+128          | Object Descriptor Table       0
     58_v_actab        =       VB+256          | Access Table                  0
     59_v_ct0          =       VB+1024         | Character Text-0              0
     60_v_gt1          =       VB+1304         | Graphics Text-1               0
     61_v_score        =       VB+8192         | Score object                  0
     62_v_cgtab        =       VB+122880       | Character Generator Table     0
     63
     64_v_curs0        =       VB+1024         | Cursor object 0  (arrow ULE)  1
     65_v_curs1        =       VB+1152         | Cursor object 1  (arrow ULO)  1
     66_v_curs2        =       VB+1280         | Cursor object 2  (arrow URE)  1
     67_v_curs3        =       VB+1408         | Cursor object 3  (arrow URO)  1
     68_v_curs4        =       VB+1536         | Cursor object 4  (arrow LLE)  1
     69_v_curs5        =       VB+1664         | Cursor object 5  (arrow LLO)  1
     70_v_curs6        =       VB+1792         | Cursor object 6  (arrow LRE)  1
     71_v_curs7        =       VB+1920         | Cursor object 7  (arrow LRO)  1
     72_v_tcur         =       VB+2048         | Typewriter cursor             1
     73_v_kbobj        =       VB+2880         | Keyboard object               1
     74_v_lnobj        =       VB+4672         | Line object                   1
     75_v_cur          =       VB+6464         | Underline cursor              1
     76_v_win0         =       VB+16384        | Window-0 object               1
     77
     78| BIOS RAM definitions
     79| --------------------
     80| WARNING: the following addresses must match those of the corresponding
     81| variables defined in bios.s or chaos is guaranteed.
     82
     83_fc_sw          =       0x420           | word - Frame counter switch
     84_fc_val         =       0x422           | long - Frame counter value
     85
    8686                .end
  • iolib/rtraps.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * rtraps.s -- define ROMP debug trap
    3 * Version 7 -- 1988-01-12 -- Copyright 1987, 1988 by D.N. Lynx Crowe
    4 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| rtraps.s -- define ROMP debug trap
     3| Version 7 -- 1988-01-12 -- Copyright 1987, 1988 by D.N. Lynx Crowe
     4| ------------------------------------------------------------------------------
    55                .text
    6 *
     6
    77                .xdef   _trap15
    8 *
     8
    99                .xref   _rompbp
    10 *
     10
    1111                .xref   tr1sav,tr13sav,tr14sav
    1212                .xref   tr1rmp,tr13rmp,tr14rmp
    13 *
    14 BUCHLA          .equ    1               * IPL value:  0 = NASA , 1 = Buchla
    15 *
     13
     14BUCHLA          =       1               | IPL value:  0 = NASA , 1 = Buchla
     15
    1616                .ifeq   BUCHLA
    17 IPLEVEL         .equ    $0400           * NASA IPL = 4    (enable 5 and above)
     17IPLEVEL         =       0x0400          | NASA IPL = 4    (enable 5 and above)
    1818                .endc
    19 *
     19
    2020                .ifne   BUCHLA
    21 IPLEVEL         .equ    $0200           * Buchla IPL = 2  (enable 3 and above)
     21IPLEVEL         =       0x0200          | Buchla IPL = 2  (enable 3 and above)
    2222                .endc
    23 *
    24 IPL7            .equ    $0700           * IPL 7
    25 *
    26 * _trap15 -- ROMP debug trap  (used to implement breakpoints)
    27 * -------    ------------------------------------------------
    28 _trap15:        ori.w   #IPL7,sr                * Disable interrupts
    29                 move.w  #0,-(a7)                * Keep stack long aligned
    30                 movem.l d0-d7/a0-a7,-(a7)       * Save regs on stack
    31                 move.l  tr1sav,tr1rmp           * Save trap save areas
    32                 move.l  tr13sav,tr13rmp         * ...
    33                 move.l  tr14sav,tr14rmp         * ...
    34                 move.w  sr,d0                   * Get status register
    35                 andi.w  #$F8FF,d0               * Enable serial I/O interrupts
    36                 ori.w   #IPLEVEL,d0             * ...
    37                 move.w  d0,sr                   * ...
    38                 jsr     _rompbp                 * Pass control to ROMP
    39 *
    40                 ori.w   #IPL7,sr                * Disable interrupts
    41                 move.l  tr14rmp,tr14sav         * Restore trap save areas
    42                 move.l  tr13rmp,tr13sav         * ...
    43                 move.l  tr1rmp,tr1sav           * ...
    44                 movem.l (a7)+,d0-d7/a0-a7       * Restore regs
    45                 addq.l  #2,a7                   * Discard alignment filler word
    46                 rte                             * Back to what we interrupted
    47 *
     23
     24IPL7            =       0x0700          | IPL 7
     25
     26| _trap15 -- ROMP debug trap  (used to implement breakpoints)
     27| -------    ------------------------------------------------
     28_trap15:        ori.w   #IPL7,sr                | Disable interrupts
     29                move.w  #0,-(a7)                | Keep stack long aligned
     30                movem.l d0-d7/a0-a7,-(a7)       | Save regs on stack
     31                move.l  tr1sav,tr1rmp           | Save trap save areas
     32                move.l  tr13sav,tr13rmp         | ...
     33                move.l  tr14sav,tr14rmp         | ...
     34                move.w  sr,d0                   | Get status register
     35                andi.w  #0xF8FF,d0              | Enable serial I/O interrupts
     36                ori.w   #IPLEVEL,d0             | ...
     37                move.w  d0,sr                   | ...
     38                jsr     _rompbp                 | Pass control to ROMP
     39
     40                ori.w   #IPL7,sr                | Disable interrupts
     41                move.l  tr14rmp,tr14sav         | Restore trap save areas
     42                move.l  tr13rmp,tr13sav         | ...
     43                move.l  tr1rmp,tr1sav           | ...
     44                movem.l (a7)+,d0-d7/a0-a7       | Restore regs
     45                addq.l  #2,a7                   | Discard alignment filler word
     46                rte                             | Back to what we interrupted
     47
    4848                .end
  • iolib/setipl.s

    rf40a309 r4f508e6  
    1 *
    2 * setipl.s -- Set internal processor interrupt level
    3 * --------    --------------------------------------
    4 * Version 2 -- 1988-06-29 -- D.N. Lynx Crowe
    5 *
    6 *       short
    7 *       setipl(arg);
    8 *       short arg;
    9 *
    10 *       Sets processor interrupt level to arg.
    11 *       Returns old interrupt level, or -1 if arg < 0 or > 7
    12 *
    13 *       Assumes you are in supervisor mode.
    14 *       You get a Privelege Violation TRAP if you aren't.
    15 *
     1
     2| setipl.s -- Set internal processor interrupt level
     3| --------    --------------------------------------
     4| Version 2 -- 1988-06-29 -- D.N. Lynx Crowe
     5
     6|       short
     7|       setipl(arg);
     8|       short arg;
     9
     10|       Sets processor interrupt level to arg.
     11|       Returns old interrupt level, or -1 if arg < 0 or > 7
     12
     13|       Assumes you are in supervisor mode.
     14|       You get a Privelege Violation TRAP if you aren't.
     15
    1616                .text
    17 *
     17
    1818                .xdef   _setipl
    19 *
    20 _setipl:        link    a6,#0                   * Link up stack frames
    21                 move.w  8(a6),d0                * Get argument
    22                 tst.w   d0                      * Check lower limit
    23                 bmi     setipler                * Jump if < 0  (error)
    24 *
    25                 cmpi.w  #7,d0                   * Check upper limit
    26                 bgt     setipler                * Jump if > 7  (error)
    27 *
    28                 move.w  sr,d1                   * Get current level
    29                 move.w  d1,d2                   * ... save for later
    30                 lsl.w   #8,d0                   * Shift argument into position
    31                 andi.w  #$F8FF,d1               * Mask out old level
    32                 or.w    d0,d1                   * OR in new level
    33                 move.w  d2,d0                   * Setup return of old level
    34                 lsr.w   #8,d0                   * ...
    35                 andi.l  #$7,d0                  * ...
    36                 move.w  d1,sr                   * Set the new interrupt level
    37                 unlk    a6                      * Unlink stack frames
    38                 rts                             * Return to caller
    39 *
    40 setipler:       moveq.l #-1,d0                  * Setup to return error code
    41                 unlk    a6                      * Unlink stack frames
    42                 rts                             * Return to caller
    43 *
     19
     20_setipl:        link    a6,#0                   | Link up stack frames
     21                move.w  8(a6),d0                | Get argument
     22                tst.w   d0                      | Check lower limit
     23                bmi     setipler                | Jump if < 0  (error)
     24
     25                cmpi.w  #7,d0                   | Check upper limit
     26                bgt     setipler                | Jump if > 7  (error)
     27
     28                move.w  sr,d1                   | Get current level
     29                move.w  d1,d2                   | ... save for later
     30                lsl.w   #8,d0                   | Shift argument into position
     31                andi.w  #0xF8FF,d1              | Mask out old level
     32                or.w    d0,d1                   | OR in new level
     33                move.w  d2,d0                   | Setup return of old level
     34                lsr.w   #8,d0                   | ...
     35                andi.l  #0x7,d0                 | ...
     36                move.w  d1,sr                   | Set the new interrupt level
     37                unlk    a6                      | Unlink stack frames
     38                rts                             | Return to caller
     39
     40setipler:       moveq.l #-1,d0                  | Setup to return error code
     41                unlk    a6                      | Unlink stack frames
     42                rts                             | Return to caller
     43
    4444                .end
  • iolib/setsr.s

    rf40a309 r4f508e6  
    1 *
    2 * setsr.s -- Set processor status register
    3 * -------    -----------------------------
    4 * Version 1 -- 1988-06-29 -- D.N. Lynx Crowe
    5 *
    6 *       short
    7 *       setsr(arg);
    8 *       short arg;
    9 *
    10 *       Sets processor status register to 'arg'.
    11 *       Returns old status register value.
    12 *
    13 *       Assumes you are in supervisor mode.
    14 *       You get a Privelege Violation TRAP if you aren't.
    15 *
    16 *       Coded for speed -- this is as fast as you can get.
    17 *       No error checking is done -- assumes you know what you're doing.
    18 *
     1
     2| setsr.s -- Set processor status register
     3| -------    -----------------------------
     4| Version 1 -- 1988-06-29 -- D.N. Lynx Crowe
     5
     6|       short
     7|       setsr(arg);
     8|       short arg;
     9
     10|       Sets processor status register to 'arg'.
     11|       Returns old status register value.
     12
     13|       Assumes you are in supervisor mode.
     14|       You get a Privelege Violation TRAP if you aren't.
     15
     16|       Coded for speed -- this is as fast as you can get.
     17|       No error checking is done -- assumes you know what you're doing.
     18
    1919                .text
    20 *
     20
    2121                .xdef   _setsr
    22 *
    23 _setsr:         move.w  sr,d0                   * Get current sr
    24                 move.w  4(sp),sr                * Set new sr
    25                 rts                             * Return to caller
    26 *
     22
     23_setsr:         move.w  sr,d0                   | Get current sr
     24                move.w  4(sp),sr                | Set new sr
     25                rts                             | Return to caller
     26
    2727                .end
  • iolib/traps.s

    rf40a309 r4f508e6  
    1 *
    2 * traps.s -- define trap linkages for C routines
    3 * -------    -----------------------------------
    4 * Version 8 -- 1987-06-08 -- D.N. Lynx Crowe
    5 *
    6 * Caution:  these are serially re-useable, but NOT reentrant, so
    7 * don't use them in interrupt processing code.
    8 *
    9 * An exception is made for ROMP in _trap15 for breakpoints so that the
    10 * debug code can be debugged.
    11 *
     1
     2| traps.s -- define trap linkages for C routines
     3| -------    -----------------------------------
     4| Version 8 -- 1987-06-08 -- D.N. Lynx Crowe
     5
     6| Caution:  these are serially re-useable, but NOT reentrant, so
     7| don't use them in interrupt processing code.
     8
     9| An exception is made for ROMP in _trap15 for breakpoints so that the
     10| debug code can be debugged.
     11
    1212                .text
    13 *
     13
    1414                .xdef   _trap1
    1515                .xdef   _trap13,_trap14
    1616                .xdef   _xtrap15
    17 *
     17
    1818                .xdef   tr1sav,tr13sav,tr14sav
    1919                .xdef   tr1rmp,tr13rmp,tr14rmp
    20 *
    21 * _trap1 -- provide access to BDOS functions
    22 * ------    --------------------------------
    23 _trap1:         move.l  (a7)+,tr1sav            * Save return address
    24                 trap    #1                      * Do the trap
    25                 move.l  tr1sav,-(a7)            * Restore return address
    26                 rts                             * Return to caller
    27 *
    28 * _trap13 -- provide access to BIOS functions
    29 * -------    --------------------------------
    30 _trap13:        move.l  (a7)+,tr13sav           * Save return address
    31                 trap    #13                     * Do the trap
    32                 move.l  tr13sav,-(a7)           * Restore return address
    33                 rts                             * Return to caller
    34 *
    35 * _trap14 -- provide access to extended BIOS functions
    36 * -------    -----------------------------------------
    37 _trap14:        move.l  (a7)+,tr14sav           * Save return address
    38                 trap    #14                     * Do the trap
    39                 move.l  tr14sav,-(a7)           * Restore return address
    40                 rts                             * Return to caller
    41 *
    42 * _xtrap15 -- Setup initial register trap for ROMP
    43 * --------    ------------------------------------
    44 _xtrap15:       trap    #15                     * TRAP into ROMP
    45                 rts                             * Return  (usually won't happen)
    46 *
     20
     21| _trap1 -- provide access to BDOS functions
     22| ------    --------------------------------
     23_trap1:         move.l  (a7)+,tr1sav            | Save return address
     24                trap    #1                      | Do the trap
     25                move.l  tr1sav,-(a7)            | Restore return address
     26                rts                             | Return to caller
     27
     28| _trap13 -- provide access to BIOS functions
     29| -------    --------------------------------
     30_trap13:        move.l  (a7)+,tr13sav           | Save return address
     31                trap    #13                     | Do the trap
     32                move.l  tr13sav,-(a7)           | Restore return address
     33                rts                             | Return to caller
     34
     35| _trap14 -- provide access to extended BIOS functions
     36| -------    -----------------------------------------
     37_trap14:        move.l  (a7)+,tr14sav           | Save return address
     38                trap    #14                     | Do the trap
     39                move.l  tr14sav,-(a7)           | Restore return address
     40                rts                             | Return to caller
     41
     42| _xtrap15 -- Setup initial register trap for ROMP
     43| --------    ------------------------------------
     44_xtrap15:       trap    #15                     | TRAP into ROMP
     45                rts                             | Return  (usually won't happen)
     46
    4747                .page
    48 *
    49 * RAM storage areas
    50 * -----------------
     48
     49| RAM storage areas
     50| -----------------
    5151                .bss
    5252                .even
    53 *
    54 tr1sav:         ds.l    1               * Return address for trap1
    55 tr13sav:        ds.l    1               * Return address for trap13
    56 tr14sav:        ds.l    1               * Return address for trap14
    57 *
    58 tr1rmp:         ds.l    1               * Save area for tr1sav for ROMP
    59 tr13rmp:        ds.l    1               * Save area for tr13sav for ROMP
    60 tr14rmp:        ds.l    1               * Save area for tr14sav for ROMP
    61 *
     53
     54tr1sav:         ds.l    1               | Return address for trap1
     55tr13sav:        ds.l    1               | Return address for trap13
     56tr14sav:        ds.l    1               | Return address for trap14
     57
     58tr1rmp:         ds.l    1               | Save area for tr1sav for ROMP
     59tr13rmp:        ds.l    1               | Save area for tr13sav for ROMP
     60tr14rmp:        ds.l    1               | Save area for tr14sav for ROMP
     61
    6262                .end
  • lib700/aldiv.s

    rf40a309 r4f508e6  
    1 *
    2 * aldiv.s -- indirect long divide
    3 * Version 1 -- 1989-01-24 -- D.N. Lynx Crowe
    4 *
     1
     2| aldiv.s -- indirect long divide
     3| Version 1 -- 1989-01-24 -- D.N. Lynx Crowe
     4
    55        .text
    6 *
     6
    77        .xdef   aldiv
    88        .xdef   _aldiv
    9 *
     9
    1010        .xref   _ldiv
    11 *
     11
    1212aldiv:
    1313_aldiv:
    14 *
     14
    1515        link    a6,#-2
    1616        move.l  12(a6),-(a7)
     
    2323        unlk    a6
    2424        rts
    25 *
     25
    2626        .end
  • lib700/almul.s

    rf40a309 r4f508e6  
    1 *
    2 * almul.s -- indirect long multiply
    3 * Version 1 -- 1989-01-24 -- D.N. Lynx Crowe
    4 *
     1
     2| almul.s -- indirect long multiply
     3| Version 1 -- 1989-01-24 -- D.N. Lynx Crowe
     4
    55                .text
    6 *
     6
    77                .xdef   almul
    8 *
     8
    99                .xref   lmul
    10 *
     10
    1111almul:          move.l  a5,-(a7)
    1212                movea.l 8(a7),a5
     
    1818                movea.l (a7)+,a5
    1919                rts
    20 *
     20
    2121                .end
  • lib700/alrem.s

    rf40a309 r4f508e6  
    1 *
    2 * alrem.s -- indirect long modulus
    3 * Version 1 -- 1989-01-24 -- D.N. Lynx Crowe
    4 *
     1
     2| alrem.s -- indirect long modulus
     3| Version 1 -- 1989-01-24 -- D.N. Lynx Crowe
     4
    55                .text
    6 *
     6
    77                .xdef   alrem
    88                .xdef   _alrem
    9 *
     9
    1010                .xref   _ldiv
    1111                .xref   _ldivr
    12 *
     12
    1313alrem:
    1414_alrem:
    15 *
     15
    1616                link    a6,#-2
    1717                move.l  12(a6),-(a7)
     
    2525                unlk    a6
    2626                rts
    27 *
     27
    2828                .end
  • lib700/blkfill.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * blkfill.s -- block fill function
    3 * Version 1 -- 1987-08-28 -- D.N. Lynx Crowe
    4 *
    5 *       void
    6 *       blkfill(where, what, count)
    7 *       char *where;
    8 *       char what;
    9 *       short count;
    10 *
    11 *               Fills 'count' bytes at 'where' with 'what'.
    12 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| blkfill.s -- block fill function
     3| Version 1 -- 1987-08-28 -- D.N. Lynx Crowe
     4
     5|       void
     6|       blkfill(where, what, count)
     7|       char |where;
     8|       char what;
     9|       short count;
     10
     11|               Fills 'count' bytes at 'where' with 'what'.
     12| ------------------------------------------------------------------------------
    1313                .text
    14 *
     14
    1515                .xdef   _blkfill
    16 *
     16
    1717_blkfill:       link    a6,#0
    1818                movem.l d5-d7/a5-a5,-(a7)
     
    2121                move.w  14(a6),d6
    2222                bra     blkf2
    23 *
     23
    2424blkf1:          move.b  d7,(a5)+
    25 *
     25
    2626blkf2:          move.w  d6,d0
    2727                subq.w  #1,d6
    2828                tst.w   d0
    2929                bgt     blkf1
    30 *
     30
    3131                tst     (a7)+
    3232                movem.l (a7)+,d6-d7/a5-a5
    3333                unlk    a6
    3434                rts
    35 *
     35
    3636                .end
  • lib700/blkmove.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * blkmove.s -- block move function
    3 * Version 1 -- 1987-08-28 -- D.N. Lynx Crowe
    4 *
    5 *       void
    6 *       blkmove(to, from, n)
    7 *       char *to, *from;
    8 *       short n;
    9 *
    10 *               Copies 'n' bytes from address 'from' to address 'to'.
    11 *               Treats overlaps of from and to areas intelligently.
    12 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| blkmove.s -- block move function
     3| Version 1 -- 1987-08-28 -- D.N. Lynx Crowe
     4
     5|       void
     6|       blkmove(to, from, n)
     7|       char |to, |from;
     8|       short n;
     9
     10|               Copies 'n' bytes from address 'from' to address 'to'.
     11|               Treats overlaps of from and to areas intelligently.
     12| ------------------------------------------------------------------------------
    1313                .text
    14 *
     14
    1515                .xdef   _blkmove
    16 *
    17 _blkmove:       link    a6,#$FFFC
     16
     17_blkmove:       link    a6,#-4
    1818                move.l  8(a6),d0
    1919                cmp.l   12(a6),d0
    2020                bcc     blkm3
    21 *
     21
    2222                bra     blkm2
    23 *
     23
    2424blkm1:          movea.l 8(a6),a0
    2525                movea.l 12(a6),a1
     
    2727                addq.l  #1,8(a6)
    2828                addq.l  #1,12(a6)
    29 *
     29
    3030blkm2:          move.w  16(a6),d0
    3131                subq.w  #1,16(a6)
    3232                tst.w   d0
    3333                bne     blkm1
    34 *
     34
    3535                bra     blkm6
    36 *
     36
    3737blkm3:          move.w  16(a6),d0
    3838                ext.l   d0
     
    4040                add.l   d0,12(a6)
    4141                bra     blkm5
    42 *
     42
    4343blkm4:          subq.l  #1,8(a6)
    4444                subq.l  #1,12(a6)
     
    4646                movea.l 12(a6),a1
    4747                move.b  (a1),(a0)
    48 *
     48
    4949blkm5:          move.w  16(a6),d0
    5050                subq.w  #1,16(a6)
    5151                tst.w   d0
    5252                bne     blkm4
    53 *
     53
    5454blkm6:          unlk    a6
    5555                rts
    56 *
     56
    5757                .end
  • lib700/finalone.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * finalone.s -- the last stuff to get loaded
    3 * Version 4 -- 1987-06-30 -- D.N. Lynx Crowe
    4 *
    5 * This is so we can figure out where things got loaded.
    6 * ------------------------------------------------------------------------------
    7 *
     1| ------------------------------------------------------------------------------
     2| finalone.s -- the last stuff to get loaded
     3| Version 4 -- 1987-06-30 -- D.N. Lynx Crowe
     4
     5| This is so we can figure out where things got loaded.
     6| ------------------------------------------------------------------------------
     7
    88                .text
    9 *
     9
    1010                .xdef   FinalOne
    1111                .xdef   The_Fini
    1212                .xdef   Text_End
    13 *
    14 *
    15 * This is the last piece of code in the 'text' segment.
    16 *
    17 FinalOne:       rts                     * we just need the address here
    18 *
    19 Text_End:       rts                     * we just need the address here
    20 *
    21 * ------------------------------------------------------------------------------
    22 *
     13
     14
     15| This is the last piece of code in the 'text' segment.
     16
     17FinalOne:       rts                     | we just need the address here
     18
     19Text_End:       rts                     | we just need the address here
     20
     21| ------------------------------------------------------------------------------
     22
    2323                .data
    2424                .even
    25 *
    26 The_Fini:       dc.w    $FFFF           * last thing in the 'data' segment
    27 *
    28 * ------------------------------------------------------------------------------
    29 *
     25
     26The_Fini:       dc.w    0xFFFF          | last thing in the 'data' segment
     27
     28| ------------------------------------------------------------------------------
     29
    3030                .end
  • lib700/jumpto.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * jumpto.s -- miscellaneous ROMP support functions
    3 * Version 4 -- 1987-10-14 -- D.N. Lynx Crowe
    4 *
    5 *       WARNING:
    6 *       --------
    7 *               These functions, in general, assume supervisor mode and
    8 *               'sane' arguments, so no error checking is done.
    9 *
    10 *       halt()
    11 *
    12 *               Brings the processor to a grinding halt.  Requires external
    13 *               reset to restart things.  Use only for catastrophic hard halts.
    14 *
    15 *       jumpto(addr)
    16 *       long addr;
    17 *
    18 *               Jumps to 'addr'.  No error check is done on 'addr'.
    19 *
    20 *       rjumpto(addr)
    21 *       long addr;
    22 *
    23 *               Performs the 68000 'RESET' command, then jumps to 'addr'.
    24 *               No error check is made on 'addr'.
    25 *
    26 *       sjumpto(addr, stack)
    27 *       long addr, stack;
    28 *
    29 *               Sets a7 to 'stack', then jumps to 'addr'.
    30 *               No error check is done on 'addr'.
    31 *
    32 *       xreset()
    33 *
    34 *               Performs the 68000 'RESET' command.  This is very dangerous,
    35 *               and should be used with extreme care regarding such
    36 *               things as interrupts, device initialization, vectors,
    37 *               and sundry other reset-related things.
    38 *
    39 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| jumpto.s -- miscellaneous ROMP support functions
     3| Version 4 -- 1987-10-14 -- D.N. Lynx Crowe
     4
     5|       WARNING:
     6|       --------
     7|               These functions, in general, assume supervisor mode and
     8|               'sane' arguments, so no error checking is done.
     9
     10|       halt()
     11
     12|               Brings the processor to a grinding halt.  Requires external
     13|               reset to restart things.  Use only for catastrophic hard halts.
     14
     15|       jumpto(addr)
     16|       long addr;
     17
     18|               Jumps to 'addr'.  No error check is done on 'addr'.
     19
     20|       rjumpto(addr)
     21|       long addr;
     22
     23|               Performs the 68000 'RESET' command, then jumps to 'addr'.
     24|               No error check is made on 'addr'.
     25
     26|       sjumpto(addr, stack)
     27|       long addr, stack;
     28
     29|               Sets a7 to 'stack', then jumps to 'addr'.
     30|               No error check is done on 'addr'.
     31
     32|       xreset()
     33
     34|               Performs the 68000 'RESET' command.  This is very dangerous,
     35|               and should be used with extreme care regarding such
     36|               things as interrupts, device initialization, vectors,
     37|               and sundry other reset-related things.
     38
     39| ------------------------------------------------------------------------------
    4040                .text
    41 *
     41
    4242                .xdef   _halt,_jumpto,_rjumpto,_sjumpto,_xreset
    43 *
     43
    4444                .page
    45 *
    46 _halt:          stop    #$2700                  * stop dead, interrupts disabled
    47                 jmp     _halt                   * stay stopped if stepped thru
    48 *
    49 _jumpto:        movea.l 4(a7),a0                * get jump address
    50                 jmp     (a0)                    * go to the jump address
    51 *
    52 _rjumpto:       reset                           * reset external devices
    53                 movea.l 4(a7),a0                * get jump address
    54                 jmp     (a0)                    * go to the jump address
    55 *
    56 _sjumpto:       movea.l 4(a7),a0                * get jump address
    57                 movea.l 8(a7),a7                * set stack pointer
    58                 jmp     (a0)                    * go to the jump address
    59 *
    60 _xreset:        reset                           * reset external devices
    61                 rts                             * return to caller
    62 *
     45
     46_halt:          stop    #0x2700                 | stop dead, interrupts disabled
     47                jmp     _halt                   | stay stopped if stepped thru
     48
     49_jumpto:        movea.l 4(a7),a0                | get jump address
     50                jmp     (a0)                    | go to the jump address
     51
     52_rjumpto:       reset                           | reset external devices
     53                movea.l 4(a7),a0                | get jump address
     54                jmp     (a0)                    | go to the jump address
     55
     56_sjumpto:       movea.l 4(a7),a0                | get jump address
     57                movea.l 8(a7),a7                | set stack pointer
     58                jmp     (a0)                    | go to the jump address
     59
     60_xreset:        reset                           | reset external devices
     61                rts                             | return to caller
     62
    6363                .end
  • lib700/ldiv.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * ldiv.s -- long division
    3 * Version 1 -- 1988-01-22
    4 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| ldiv.s -- long division
     3| Version 1 -- 1988-01-22
     4| ------------------------------------------------------------------------------
    55                .text
    6 *
     6
    77                .xdef   _ldiv
    88                .xdef   ldiv
    9 *
     9
    1010                .xdef   _ldivr
    11 *
    12 ARG1            .equ    8
    13 ARG2            .equ    12
    14 *
     11
     12ARG1            =       8
     13ARG2            =       12
     14
    1515_ldiv:
    1616ldiv:           link    a6,#-2
     
    2121                move.l  ARG2(a6),d6
    2222                bne     ldiv1
    23 *
    24                 move.l  #$80000000,_ldivr
    25                 move.l  #$80000000,d0
     23
     24                move.l  #0x80000000,_ldivr
     25                move.l  #0x80000000,d0
    2626                divs    #0,d0
    2727                bra     ldiv11
    28 *
     28
    2929ldiv1:          bge     ldiv2
    30 *
     30
    3131                neg.l   d6
    3232                addq.w  #1,d3
    33 *
     33
    3434ldiv2:          tst.l   d7
    3535                bge     ldiv3
    36 *
     36
    3737                neg.l   d7
    3838                addq.w  #1,d3
    39 *
     39
    4040ldiv3:          cmp.l   d7,d6
    4141                bgt     ldiv9
    42 *
     42
    4343                bne     ldiv4
    44 *
     44
    4545                moveq.l #1,d5
    4646                clr.l   d7
    4747                bra     ldiv9
    48 *
    49 ldiv4:          cmp.l   #$10000,d7
     48
     49ldiv4:          cmp.l   #0x10000,d7
    5050                bge     ldiv5
    51 *
     51
    5252                divu    d6,d7
    5353                move.w  d7,d5
     
    5555                ext.l   d7
    5656                bra     ldiv9
    57 *
     57
    5858ldiv5:          moveq.l #1,d4
    59 *
     59
    6060ldiv6:          cmp.l   d6,d7
    6161                bcs     ldiv7
    62 *
     62
    6363                asl.l   #1,d6
    6464                asl.l   #1,d7
    6565                bra     ldiv6
    66 *
     66
    6767ldiv7:          tst.l   d4
    6868                beq     ldiv9
    69 *
     69
    7070                cmp.l   d6,d7
    7171                bcs     ldiv8
    72 *
     72
    7373                or.l    d4,d5
    7474                sub.l   d6,d7
    75 *
     75
    7676ldiv8:          lsr.l   #1,d4
    7777                lsr.l   #1,d6
    7878                bra     ldiv7
    79 *
     79
    8080ldiv9:          cmp.w   #1,d3
    8181                bne     ldiv10
    82 *
     82
    8383                neg.l   d7
    8484                move.l  d7,_ldivr
     
    8686                neg.l   d0
    8787                bra     ldiv11
    88 *
     88
    8989ldiv10:         move.l  d7,_ldivr
    9090                move.l  d5,d0
    91 *
     91
    9292ldiv11:         tst.l   (a7)+
    9393                movem.l (a7)+,d3-d7
    9494                unlk    a6
    9595                rts
    96 *
     96
    9797                .bss
    98 *
     98
    9999_ldivr:         .ds.l   1
    100 *
     100
    101101                .end
  • lib700/lmul.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * lmul.s -- long multiply
    3 * Version 2 -- 1989-07-18
    4 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| lmul.s -- long multiply
     3| Version 2 -- 1989-07-18
     4| ------------------------------------------------------------------------------
    55                .text
    6 *
     6
    77                .xdef   lmul
    8 *
    9 ARG1            .equ    8
    10 ARG2            .equ    12
    11 *
    12 TEMP            .equ    -4
    13 *
     8
     9ARG1            =       8
     10ARG2            =       12
     11
     12TEMP            =       -4
     13
    1414lmul:           link    a6,#-4
    1515                clr.w   d2
    1616                tst.l   ARG1(a6)
    1717                bge     lmul1
    18 *
     18
    1919                neg.l   ARG1(a6)
    2020                addq.w  #1,d2
    21 *
     21
    2222lmul1:          tst.l   ARG2(a6)
    2323                bge     lmul2
    24 *
     24
    2525                neg.l   ARG2(a6)
    2626                addq.w  #1,d2
    27 *
     27
    2828lmul2:          move.w  ARG1+2(a6),d0
    2929                mulu    ARG2+2(a6),d0
     
    3939                btst    #0,d2
    4040                beq     lmul3
    41 *
     41
    4242                neg.l   d0
    43 *
     43
    4444lmul3:          unlk    a6
    4545                rts
    46 *
     46
    4747                .end
  • lib700/lrem.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * lrem.s -- long modulo
    3 * Version 1 -- 1988-01-22
    4 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| lrem.s -- long modulo
     3| Version 1 -- 1988-01-22
     4| ------------------------------------------------------------------------------
    55                .text
    6 *
     6
    77                .xdef   _lrem
    88                .xdef   lrem
    9 *
     9
    1010                .xref   ldiv
    1111                .xref   _ldivr
    12 *
    13 ARG1            .equ    8
    14 ARG2            .equ    12
    15 *
     12
     13ARG1            =       8
     14ARG2            =       12
     15
    1616_lrem:
    1717lrem:           link    a6,#-2
     
    2323                unlk    a6
    2424                rts
    25 *
     25
    2626                .end
  • lib700/rand24.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * rand24.s -- generate a 24 bit random number
    3 * Version 3 -- 1988-04-29 -- D.N. Lynx Crowe
    4 * ------------------------------------------------------------------------------
    5 * Synopsis:
    6 *               long
    7 *               rand24()
    8 *
    9 * Based on:
    10 *               Knuth, Donald E.
    11 *               The Art of Computer Programming,
    12 *               Volume 2: Semi-Numerical Algorithms
    13 *
    14 * Computes:
    15 *               S = [S * C] + K
    16 *
    17 * Where:
    18 *               K = 1
    19 *               C = 3141592621
    20 *               S = the seed  (if zero, it gets set from the 200 Hz clock)
    21 *
    22 * Returns:
    23 *               S >> 8  (a 24 bit pseudo-random number)
    24 *
    25 * Note:  this function has an LSB with an exactly 50% distribution,  so using
    26 * individual bits is probably not a good idea.  Using more bits makes things
    27 * appear more random.
    28 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| rand24.s -- generate a 24 bit random number
     3| Version 3 -- 1988-04-29 -- D.N. Lynx Crowe
     4| ------------------------------------------------------------------------------
     5| Synopsis:
     6|               long
     7|               rand24()
     8
     9| Based on:
     10|               Knuth, Donald E.
     11|               The Art of Computer Programming,
     12|               Volume 2: Semi-Numerical Algorithms
     13
     14| Computes:
     15|               S = [S | C] + K
     16
     17| Where:
     18|               K = 1
     19|               C = 3141592621
     20|               S = the seed  (if zero, it gets set from the 200 Hz clock)
     21
     22| Returns:
     23|               S >> 8  (a 24 bit pseudo-random number)
     24
     25| Note:  this function has an LSB with an exactly 50% distribution,  so using
     26| individual bits is probably not a good idea.  Using more bits makes things
     27| appear more random.
     28| ------------------------------------------------------------------------------
    2929                .text
    30 *
     30
    3131                .xdef   _rand24
    32 *
     32
    3333                .xdef   _rseed
    34 *
    35 * equates for things in the BIOS
    36 *
    37 RCLOCK          .equ    $49E                    * LONG - 200 Hz clock
    38 *
    39 * equates for stack offsets
    40 *
    41 ARG1            .equ    8                       * LONG / WORD - arg1 / MS bits
    42 ARG1L           .equ    10                      * WORD - arg1 LS bits
    43 ARG2            .equ    12                      * LONG / WORD - arg2 / MS bits
    44 ARG2L           .equ    14                      * WORD - arg2 LS bits
    45 *
    46 PART            .equ    -4                      * LONG - partial product
    47 *
    48 PI              .equ    $BB40E62D               * LONG - PI as a hex value
    49 *
     34
     35| equates for things in the BIOS
     36
     37RCLOCK          =       0x49E                   | LONG - 200 Hz clock
     38
     39| equates for stack offsets
     40
     41ARG1            =       8                       | LONG / WORD - arg1 / MS bits
     42ARG1L           =       10                      | WORD - arg1 LS bits
     43ARG2            =       12                      | LONG / WORD - arg2 / MS bits
     44ARG2L           =       14                      | WORD - arg2 LS bits
     45
     46PART            =       -4                      | LONG - partial product
     47
     48PI              =       0xBB40E62D              | LONG - PI as a hex value
     49
    5050                .page
    51 *
    52 * mult32 -- 32 bit signed multiply
    53 * ------    ----------------------
    54 mult32:         link    a6,#-4                  * link stack frames
    55                 clr.w   d2                      * clear sign flags
    56                 tst.l   ARG1(a6)                * check sign of 1st argument
    57                 bge     mult32a                 * ...
    58 *
    59                 neg.l   ARG1(a6)                * make 1st argument positive
    60                 addq.w  #1,d2                   * log its sign as negative
    61 *
    62 mult32a:        tst.l   ARG2(a6)                * check sign of 2nd argument
    63                 bge     mult32b                 * ...
    64 *
    65                 neg.l   ARG2(a6)                * make 2nd argument positive
    66                 addq.w  #1,d2                   * log its sign as negative
    67 *
    68 mult32b:        move.w  ARG1L(a6),d0            * generate 1st partial product
    69                 mulu    ARG2L(a6),d0            * ...
    70                 move.l  d0,PART(a6)             * ...
    71                 move.w  ARG1(a6),d0             * generate 2nd partial product
    72                 mulu    ARG2L(a6),d0            * ...
    73                 move.w  ARG2(a6),d1             * generate 3rd partial product
    74                 mulu    ARG1L(a6),d1            * ...
    75                 add.w   d1,d0                   * add partial products
    76                 add.w   PART(a6),d0             * ...
    77                 move.w  d0,PART(a6)             * ...
    78                 move.l  PART(a6),d0             * ...
    79                 btst    #0,d2                   * adjust sign of result
    80                 beq     mult32c                 * ...
    81 *
    82                 neg.l   d0                      * ...
    83 *
    84 mult32c:        unlk    a6                      * unlink stack frames
    85                 rts                             * return
    86 *
     51
     52| mult32 -- 32 bit signed multiply
     53| ------    ----------------------
     54mult32:         link    a6,#-4                  | link stack frames
     55                clr.w   d2                      | clear sign flags
     56                tst.l   ARG1(a6)                | check sign of 1st argument
     57                bge     mult32a                 | ...
     58
     59                neg.l   ARG1(a6)                | make 1st argument positive
     60                addq.w  #1,d2                   | log its sign as negative
     61
     62mult32a:        tst.l   ARG2(a6)                | check sign of 2nd argument
     63                bge     mult32b                 | ...
     64
     65                neg.l   ARG2(a6)                | make 2nd argument positive
     66                addq.w  #1,d2                   | log its sign as negative
     67
     68mult32b:        move.w  ARG1L(a6),d0            | generate 1st partial product
     69                mulu    ARG2L(a6),d0            | ...
     70                move.l  d0,PART(a6)             | ...
     71                move.w  ARG1(a6),d0             | generate 2nd partial product
     72                mulu    ARG2L(a6),d0            | ...
     73                move.w  ARG2(a6),d1             | generate 3rd partial product
     74                mulu    ARG1L(a6),d1            | ...
     75                add.w   d1,d0                   | add partial products
     76                add.w   PART(a6),d0             | ...
     77                move.w  d0,PART(a6)             | ...
     78                move.l  PART(a6),d0             | ...
     79                btst    #0,d2                   | adjust sign of result
     80                beq     mult32c                 | ...
     81
     82                neg.l   d0                      | ...
     83
     84mult32c:        unlk    a6                      | unlink stack frames
     85                rts                             | return
     86
    8787                .page
    88 *
    89 * _rand24 -- Generate a random number
    90 * -------    ------------------------
    91 _rand24:        link    a6,#0                   * Link stack frames
    92                 tst.l   _rseed                  * See if the seed is zero
    93                 bne     rand01                  * Jump if not
    94 *
    95                 move.l  RCLOCK,d0               * Pick up the 200 Hz clock
    96                 moveq.l #16,d1                  * Shift it left
    97                 asl.l   d1,d0                   * ...
    98                 or.l    RCLOCK,d0               * OR in current 200 Hz clock
    99                 move.l  d0,_rseed               * Use that as the seed
    100 *
    101 rand01:         move.l  #PI,-(a7)               * Put PI on the stack
    102                 move.l  _rseed,-(a7)            * ... and _rseed, too
    103                 bsr     mult32                  * Multiply them
    104                 addq.l  #8,a7                   * Cleanup stack
    105                 addq.l  #1,d0                   * Add 1 to the result
    106                 move.l  d0,_rseed               * Save as new seed
    107                 asr.l   #8,d0                   * Make it a 24 bit number
    108                 and.l   #$00FFFFFF,d0           * ...
    109                 unlk    a6                      * Unlink stack frames
    110                 rts                             * Return to caller
    111 *
    112 * ------------------------------------------------------------------------------
     88
     89| _rand24 -- Generate a random number
     90| -------    ------------------------
     91_rand24:        link    a6,#0                   | Link stack frames
     92                tst.l   _rseed                  | See if the seed is zero
     93                bne     rand01                  | Jump if not
     94
     95                move.l  RCLOCK,d0               | Pick up the 200 Hz clock
     96                moveq.l #16,d1                  | Shift it left
     97                asl.l   d1,d0                   | ...
     98                or.l    RCLOCK,d0               | OR in current 200 Hz clock
     99                move.l  d0,_rseed               | Use that as the seed
     100
     101rand01:         move.l  #PI,-(a7)               | Put PI on the stack
     102                move.l  _rseed,-(a7)            | ... and _rseed, too
     103                bsr     mult32                  | Multiply them
     104                addq.l  #8,a7                   | Cleanup stack
     105                addq.l  #1,d0                   | Add 1 to the result
     106                move.l  d0,_rseed               | Save as new seed
     107                asr.l   #8,d0                   | Make it a 24 bit number
     108                and.l   #0x00FFFFFF,d0          | ...
     109                unlk    a6                      | Unlink stack frames
     110                rts                             | Return to caller
     111
     112| ------------------------------------------------------------------------------
    113113                .bss
    114 * ------------------------------------------------------------------------------
    115 *
    116 _rseed:         .ds.l   1                       * random number seed
    117 *
     114| ------------------------------------------------------------------------------
     115
     116_rseed:         .ds.l   1                       | random number seed
     117
    118118                .end
  • lib700/setjmp.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * setjmp.s -- Unix(tm) compatible setjmp(env) and longjmp(env,ret)
    3 * Version 3 -- 1987-06-16 -- D.N. Lynx Crowe
    4 * ------------------------------------------------------------------------------
    5 *
     1| ------------------------------------------------------------------------------
     2| setjmp.s -- Unix(tm) compatible setjmp(env) and longjmp(env,ret)
     3| Version 3 -- 1987-06-16 -- D.N. Lynx Crowe
     4| ------------------------------------------------------------------------------
     5
    66                .text
    7 *
     7
    88                .xdef   _setjmp,_longjmp
    9 *
    10 _setjmp:        movea.l 4(a7),a0                * Get env pointer
    11                 move.l  (a7),(a0)               * Put return address in env
    12                 movem.l d1-d7/a1-a7,4(a0)       * Save registers in env
    13                 moveq.l #0,d0                   * Set return value to 0
    14                 rts                             * Return to caller
    15 *
    16 _longjmp:       move.w  8(a7),d0                * Get ret value
    17                 bne     lj1                     * Jump if non-zero
    18 *
    19                 moveq.l #1,d0                   * Force return value to 1
    20 *
    21 lj1:            movea.l 4(a7),a0                * Get env pointer
    22                 movem.l 4(a0),d1-d7/a1-a7       * Restore registers from env
    23                 move.l  (a0),(a7)               * Get return address from env
    24                 rts                             * Return to caller
    25 *
     9
     10_setjmp:        movea.l 4(a7),a0                | Get env pointer
     11                move.l  (a7),(a0)               | Put return address in env
     12                movem.l d1-d7/a1-a7,4(a0)       | Save registers in env
     13                moveq.l #0,d0                   | Set return value to 0
     14                rts                             | Return to caller
     15
     16_longjmp:       move.w  8(a7),d0                | Get ret value
     17                bne     lj1                     | Jump if non-zero
     18
     19                moveq.l #1,d0                   | Force return value to 1
     20
     21lj1:            movea.l 4(a7),a0                | Get env pointer
     22                movem.l 4(a0),d1-d7/a1-a7       | Restore registers from env
     23                move.l  (a0),(a7)               | Get return address from env
     24                rts                             | Return to caller
     25
    2626                .end
  • lib700/uldiv.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * uldiv.s -- unsigned long division, with remainder
    3 * Version 2 -- 1987-06-08 -- D.N. Lynx Crowe
    4 * Lifted from the Alcyon C library by disassembly so I could fix a bug -
    5 *       _uldivr must be in the bss segment so the code will work in PROM.
    6 *
    7 *       long
    8 *       uldiv(dividnd, divisor)
    9 *       long dividnd, divisor;
    10 *
    11 *       extern long uldivr;
    12 *
    13 *               Divides 'dividnd' by 'divisor', treating both as unsigned
    14 *               long integers.  Returns the quotient and leaves the
    15 *               remainder in 'uldivr'.  Produces a divide check on division
    16 *               by zero, with $80000000 returned for both quotient and
    17 *               remainder.
    18 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| uldiv.s -- unsigned long division, with remainder
     3| Version 2 -- 1987-06-08 -- D.N. Lynx Crowe
     4| Lifted from the Alcyon C library by disassembly so I could fix a bug -
     5|       _uldivr must be in the bss segment so the code will work in PROM.
     6
     7|       long
     8|       uldiv(dividnd, divisor)
     9|       long dividnd, divisor;
     10
     11|       extern long uldivr;
     12
     13|               Divides 'dividnd' by 'divisor', treating both as unsigned
     14|               long integers.  Returns the quotient and leaves the
     15|               remainder in 'uldivr'.  Produces a divide check on division
     16|               by zero, with 0x80000000 returned for both quotient and
     17|               remainder.
     18| ------------------------------------------------------------------------------
    1919                .text
    20 *
     20
    2121                .xdef   _uldiv,_uldivr
    22 *
    23 DIVIDEND        .equ    8
    24 DIVISOR         .equ    12
    25 *
    26 _uldiv:         link    a6,#0                   * Link stack frames
    27                 movem.l d3-d7,-(a7)             * Save registers
    28                 move.l  DIVIDEND(a6),d7         * d7 = DIVIDEND
    29                 move.l  DIVISOR(a6),d6          * d6 = DIVISOR
    30                 tst.l   d6                      * Divide by zero ?
    31                 bne     notdzero                * Jump if not
    32 *
    33                 move.l  #$80000000,_uldivr      * Force error result
    34                 move.l  #$80000000,d0           * ... by dividing
    35                 divu    #0,d0                   * ... by zero
    36                 bra     ulexit                  * ... then exit
    37 *
    38 notdzero:       cmp.l   d7,d6                   * Divide underflow ?
    39                 bls     notunflo                * Jump if not
    40 *
    41                 move.l  d7,_uldivr              * Remainder = dividend
    42                 clr.l   d0                      * Quotient = 0
    43                 bra     ulexit                  * Exit
    44 *
    45 notunflo:       cmp.l   d6,d7                   * Is dividend = divisor ?
    46                 bne     startdiv                * Go start dividing if not
    47 *
    48                 moveq.l #1,d5                   * Quotient = 1
    49                 clr.l   d7                      * Remainder = 0
    50                 bra     setreslt                * Go set result
    51 *
     22
     23DIVIDEND        =       8
     24DIVISOR         =       12
     25
     26_uldiv:         link    a6,#0                   | Link stack frames
     27                movem.l d3-d7,-(a7)             | Save registers
     28                move.l  DIVIDEND(a6),d7         | d7 = DIVIDEND
     29                move.l  DIVISOR(a6),d6          | d6 = DIVISOR
     30                tst.l   d6                      | Divide by zero ?
     31                bne     notdzero                | Jump if not
     32
     33                move.l  #0x80000000,_uldivr     | Force error result
     34                move.l  #0x80000000,d0          | ... by dividing
     35                divu    #0,d0                   | ... by zero
     36                bra     ulexit                  | ... then exit
     37
     38notdzero:       cmp.l   d7,d6                   | Divide underflow ?
     39                bls     notunflo                | Jump if not
     40
     41                move.l  d7,_uldivr              | Remainder = dividend
     42                clr.l   d0                      | Quotient = 0
     43                bra     ulexit                  | Exit
     44
     45notunflo:       cmp.l   d6,d7                   | Is dividend = divisor ?
     46                bne     startdiv                | Go start dividing if not
     47
     48                moveq.l #1,d5                   | Quotient = 1
     49                clr.l   d7                      | Remainder = 0
     50                bra     setreslt                | Go set result
     51
    5252                .page
    53 *
    54 startdiv:       moveq.l #1,d4                   * Set result bit in d4
    55 *
    56 divloop1:       cmp.l   d6,d7                   * Divisor aligned OK ?
    57                 bcs     divloop2                * Jump if so
    58 *
    59                 move.l  d6,d0                   * Can we align things better ?
    60                 asl.l   #1,d0                   * ...
    61                 cmp.l   d0,d6                   * ...
    62                 bhi     divloop2                * Jump if not
    63 *
    64                 asl.l   #1,d6                   * Shift the divisor
    65                 asl.l   #1,d4                   * Shift the result bit
    66                 bra     divloop1                * Loop for next bit
    67 *
    68 divloop2:       clr.l   d5                      * Clear quotient
    69 *
    70 divloop3:       tst.l   d4                      * More bits to do ?
    71                 beq     setreslt                * Go set result if not
    72 *
    73                 cmp.l   d6,d7                   * Can we subtract ?
    74                 bcs     divloop4                * Jump if not
    75 *
    76                 or.l    d4,d5                   * Set a bit in the quotient
    77                 sub.l   d6,d7                   * Subtract divisor from dividend
    78 *
    79 divloop4:       lsr.l   #1,d4                   * Shift the result bit
    80                 lsr.l   #1,d6                   * Shift the divisor
    81                 bra     divloop3                * Loop for next bit
    82 *
    83 setreslt:       move.l  d7,_uldivr              * Store remainder
    84                 move.l  d5,d0                   * Put quotient in d0
    85 *
    86 ulexit:         tst.l   (a7)+                   * Discard top of stack
    87                 movem.l (a7)+,d4-d7             * Restore registers
    88                 unlk    a6                      * Unlink stack frames
    89                 rts                             * Return to caller
    90 *
     53
     54startdiv:       moveq.l #1,d4                   | Set result bit in d4
     55
     56divloop1:       cmp.l   d6,d7                   | Divisor aligned OK ?
     57                bcs     divloop2                | Jump if so
     58
     59                move.l  d6,d0                   | Can we align things better ?
     60                asl.l   #1,d0                   | ...
     61                cmp.l   d0,d6                   | ...
     62                bhi     divloop2                | Jump if not
     63
     64                asl.l   #1,d6                   | Shift the divisor
     65                asl.l   #1,d4                   | Shift the result bit
     66                bra     divloop1                | Loop for next bit
     67
     68divloop2:       clr.l   d5                      | Clear quotient
     69
     70divloop3:       tst.l   d4                      | More bits to do ?
     71                beq     setreslt                | Go set result if not
     72
     73                cmp.l   d6,d7                   | Can we subtract ?
     74                bcs     divloop4                | Jump if not
     75
     76                or.l    d4,d5                   | Set a bit in the quotient
     77                sub.l   d6,d7                   | Subtract divisor from dividend
     78
     79divloop4:       lsr.l   #1,d4                   | Shift the result bit
     80                lsr.l   #1,d6                   | Shift the divisor
     81                bra     divloop3                | Loop for next bit
     82
     83setreslt:       move.l  d7,_uldivr              | Store remainder
     84                move.l  d5,d0                   | Put quotient in d0
     85
     86ulexit:         tst.l   (a7)+                   | Discard top of stack
     87                movem.l (a7)+,d4-d7             | Restore registers
     88                unlk    a6                      | Unlink stack frames
     89                rts                             | Return to caller
     90
    9191                .bss
    9292                .even
    93 *
     93
    9494_uldivr:        ds.l    1
    95 *
     95
    9696                .end
  • libcio/ptcl12.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * ptcl12.s -- store a cluster entry into the FAT
    3 * Version 2 -- 1987-10-27 -- D.N. Lynx Crowe
    4 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| ptcl12.s -- store a cluster entry into the FAT
     3| Version 2 -- 1987-10-27 -- D.N. Lynx Crowe
     4| ------------------------------------------------------------------------------
    55                .text
    66                .xdef   __ptcl12
    7 *
    8 CL              .equ    12
    9 VAL             .equ    14
    10 CLA             .equ    d7
    11 CLP             .equ    d6
    12 CLT             .equ    d5
    13 FAT             .equ    a5
    14 *
     7
     8CL              =       12
     9VAL             =       14
     10CLA             =       d7
     11CLP             =       d6
     12CLT             =       d5
     13FAT             =       a5
     14
    1515__ptcl12:       link    A6,#0
    1616                movem.l CLT-CLA/FAT-FAT,-(sp)
    1717                move.l  8(A6),FAT
    1818                move.w  CL(A6),CLA
    19                 lsr.w   CLA
     19                lsr.w   #1,CLA
    2020                add.w   CL(A6),CLA
    2121                move.b  1(FAT,CLA.W),CLP
     
    2424                btst    #0,CL+1(A6)
    2525                beq     L2
    26 *
     26
    2727                move.w  CLP,CLT
    28                 and.w   #$000F,CLT
     28                and.w   #0x000F,CLT
    2929                move.w  VAL(A6),D0
    3030                lsl.w   #4,D0
    3131                or.w    D0,CLT
    3232                bra     L3
    33 *
     33
    3434L2:             move.w  CLP,CLT
    35                 and.w   #$F000,CLT
     35                and.w   #0xF000,CLT
    3636                move.w  VAL(A6),D0
    37                 and.w   #$0FFF,D0
     37                and.w   #0x0FFF,D0
    3838                or.w    D0,CLT
    39 *
     39
    4040L3:             move.b  CLT,0(FAT,CLA.W)
    4141                move.w  CLT,D0
    4242                lsr.w   #8,D0
    4343                move.b  D0,1(FAT,CLA.W)
    44 *
     44
    4545L1:             movem.l (sp)+,CLT-CLA/FAT-FAT
    4646                unlk    A6
    4747                rts
    48 *
     48
    4949                .end
  • prolog/fsmain.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * fsmain.s -- startup code for the Buchla 700 standalone C runtime library
    3 * Version 3 -- 1987-06-29 -- D.N. Lynx Crowe
    4 *
    5 *       This code clears 'bss' space, sets up some global variables,
    6 *       and calls Croot(), which sets up the file system and calls main().
    7 *
    8 *       This routine should be entered with the address of the basepage
    9 *       as its parameter.
    10 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| fsmain.s -- startup code for the Buchla 700 standalone C runtime library
     3| Version 3 -- 1987-06-29 -- D.N. Lynx Crowe
     4
     5|       This code clears 'bss' space, sets up some global variables,
     6|       and calls Croot(), which sets up the file system and calls main().
     7
     8|       This routine should be entered with the address of the basepage
     9|       as its parameter.
     10| ------------------------------------------------------------------------------
    1111                .text
    12 *
     12
    1313                .xdef   start_
    14 *
     14
    1515                .xref   _Croot
    16 *
     16
    1717                .xdef   _panic
    1818                .xdef   _brk
    19 *
     19
    2020                .xdef   __heap
    2121                .xdef   __break
    2222                .xdef   __pmesg
    23 *
     23
    2424                .xdef   _errno
    25 *
    26 p_bbase         .equ    $18             * bss base
    27 p_blen          .equ    $1C             * bss length
    28 *
     25
     26p_bbase         =       0x18            | bss base
     27p_blen          =       0x1C            | bss length
     28
    2929                .page
    30 *
    31 * start_ -- Initial entry point -- Must be first object file in link statement
    32 * ------    ------------------------------------------------------------------
    33 *
    34 * WARNING:  Hazardous assumptions
    35 *
    36 * We assume that:
    37 *
    38 *       the system has set the stack pointer for us.
    39 *       the system passed us a pointer to a valid basepage.
    40 *       the stack is above the heap.
    41 *       BSS is located in RAM.
    42 *
    43 * If any of these assumptions is in error, we're in for serious trouble.
    44 *
    45 start_:         clr.l   a6              * Clear frame pointer
    46                 movea.l 4(a7),a1        * Set pointer to base page
    47                 movea.l p_bbase(a1),a0  * Setup to clear bss space
    48 *
    49 start1:         clr.w   (a0)+           * Clear a word
    50                 cmpa.l  a0,a7           * See if we're done
    51                 bne     start1          * Loop if not done yet
    52 *
    53                 move.l  p_bbase(a1),d0  * Calculate break address
    54                 add.l   p_blen(a1),d0   * ...
    55                 move.l  d0,__break      * Set initial break
    56                 move.l  d0,__heap       * Set heap start
    57 *
    58                 move.l  #0,-(a7)        * Pass NULL to Croot  (no command line)
    59                 jsr     _Croot          * call Croot() routine
    60                 addq.l  #4,a7           * ...
    61 *
    62                 move.l  #pmsg1,-(a7)    * panic(pmsg1);
    63                 jsr     _panic          * ...
    64                 addq.l  #4,a7           * ...
    65 *
    66 hstop:          stop    #$2000          * "Die, sucker!"
     30
     31| start_ -- Initial entry point -- Must be first object file in link statement
     32| ------    ------------------------------------------------------------------
     33
     34| WARNING:  Hazardous assumptions
     35
     36| We assume that:
     37
     38|       the system has set the stack pointer for us.
     39|       the system passed us a pointer to a valid basepage.
     40|       the stack is above the heap.
     41|       BSS is located in RAM.
     42
     43| If any of these assumptions is in error, we're in for serious trouble.
     44
     45start_:         movea.l #0,a6           | Clear frame pointer
     46                movea.l 4(a7),a1        | Set pointer to base page
     47                movea.l p_bbase(a1),a0  | Setup to clear bss space
     48
     49start1:         clr.w   (a0)+           | Clear a word
     50                cmpa.l  a0,a7           | See if we're done
     51                bne     start1          | Loop if not done yet
     52
     53                move.l  p_bbase(a1),d0  | Calculate break address
     54                add.l   p_blen(a1),d0   | ...
     55                move.l  d0,__break      | Set initial break
     56                move.l  d0,__heap       | Set heap start
     57
     58                move.l  #0,-(a7)        | Pass NULL to Croot  (no command line)
     59                jsr     _Croot          | call Croot() routine
     60                addq.l  #4,a7           | ...
     61
     62                move.l  #pmsg1,-(a7)    | panic(pmsg1);
     63                jsr     _panic          | ...
     64                addq.l  #4,a7           | ...
     65
     66hstop:          stop    #0x2000         | "Die, sucker!"
    6767                bra     hstop
    68 *
     68
    6969                .page
    70 *
    71 * _panic -- hard halt for fatal errors
    72 * ------    --------------------------
    73 _panic:         movea.l 4(a7),a0        * Save panic message address
    74                 move.l  a0,__pmesg      * ...
    75 *
    76                 trap    #15             * Invoke ROMP  (we hope ...)
    77 *
    78 pstop:          stop    #$2700          * HARD HALT
     70
     71| _panic -- hard halt for fatal errors
     72| ------    --------------------------
     73_panic:         movea.l 4(a7),a0        | Save panic message address
     74                move.l  a0,__pmesg      | ...
     75
     76                trap    #15             | Invoke ROMP  (we hope ...)
     77
     78pstop:          stop    #0x2700         | HARD HALT
    7979                bra     pstop
    80 *
     80
    8181                .page
    82 *
    83 * _brk -- set break value
    84 * ----    ---------------
    85 * WARNING:  This only works if the stack is above the heap.
    86 *
    87 _brk:           cmpa.l  __break,a7      * compare current break with stack
    88                 bcs     pstop           * actual stack overflow!
    89 *
    90                 movea.l 4(sp),a0        * get new break
    91                 move.l  a0,d0           * compare with current stack,
    92                 adda.l  #$100,a0        * ... including 256-byte slop factor
    93                 cmpa.l  a0,a7           * if (sp < a0+256)
    94                 bcs     badbrk          *       bad break;
    95 *
    96                 move.l  d0,__break      * OK break: save the break
    97                 clr.l   d0              * Set OK return
    98                 rts                     * return
    99 *
    100 badbrk:         moveq.l #-1,d0          * Load return reg
    101                 rts                     * Return
    102 *
     82
     83| _brk -- set break value
     84| ----    ---------------
     85| WARNING:  This only works if the stack is above the heap.
     86
     87_brk:           cmpa.l  __break,a7      | compare current break with stack
     88                bcs     pstop           | actual stack overflow!
     89
     90                movea.l 4(sp),a0        | get new break
     91                move.l  a0,d0           | compare with current stack,
     92                adda.l  #0x100,a0       | ... including 256-byte slop factor
     93                cmpa.l  a0,a7           | if (sp < a0+256)
     94                bcs     badbrk          |       bad break;
     95
     96                move.l  d0,__break      | OK break: save the break
     97                clr.l   d0              | Set OK return
     98                rts                     | return
     99
     100badbrk:         moveq.l #-1,d0          | Load return reg
     101                rts                     | Return
     102
    103103                .page
    104 *
    105 *************************************************************************
    106 *               Data Area                                               *
    107 *************************************************************************
    108 *
     104
     105|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     106|               Data Area                                               |
     107|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     108
    109109                .data
    110 *
    111 pmsg1:          dc.b    '  returned from Croot() ',0
    112 *
    113 *************************************************************************
    114 *               BSS Area                                                *
    115 *************************************************************************
    116 *
     110
     111pmsg1:          dc.b    "  returned from Croot() ",0
     112
     113|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     114|               BSS Area                                                |
     115|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     116
    117117                .bss
    118118                .even
    119 *
    120 __pmesg:        ds.l    1       * panic() message string address
    121 __heap:         ds.l    1       * Heap start  (initial break)
    122 __break:        ds.l    1       * Current break location
    123 _errno:         ds.w    1       * System error number
    124 *
     119
     120__pmesg:        ds.l    1       | panic() message string address
     121__heap:         ds.l    1       | Heap start  (initial break)
     122__break:        ds.l    1       | Current break location
     123_errno:         ds.w    1       | System error number
     124
    125125        .end
  • ram/execins.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * execins.s -- execute an instrument selection
    3 * Version 9 -- 1988-09-09 -- D.N. Lynx Crowe
    4 *
    5 * Hand optimized C object code from:  execins.c -- ver 2 -- 1988-06-29
    6 * ------------------------------------------------------------------------------
    7 *
     1| ------------------------------------------------------------------------------
     2| execins.s -- execute an instrument selection
     3| Version 9 -- 1988-09-09 -- D.N. Lynx Crowe
     4
     5| Hand optimized C object code from:  execins.c -- ver 2 -- 1988-06-29
     6| ------------------------------------------------------------------------------
     7
    88                .text
    9 *
    10 DOUBLED         .equ    1                       * double output to WS table
    11 *
     9
     10DOUBLED         =       1                       | double output to WS table
     11
    1212                .xdef   _execins
    13 *
     13
    1414                .xref   _clrvce
    1515                .xref   _execkey
    16 *
     16
    1717                .xref   _io_fpu
    1818                .xref   _instmod
     
    2020                .xref   _idefs
    2121                .xref   _vbufs
    22 *
    23 * register equates
    24 * ----------------
    25 SYNC            .equ    D4
    26 OLDSR           .equ    D5
    27 VCE             .equ    D7
    28 *
    29 IP              .equ    A5
    30 P1              .equ    A4
    31 P2              .equ    A3
    32 *
    33 P3              .equ    A2
    34 P4              .equ    A1
    35 *
    36 * parameter offsets
    37 * -----------------
    38 VOICE           .equ    8
    39 INS             .equ    10
    40 TAG             .equ    12
    41 *
    42                 .page
    43 *
    44 _execins:       link    A6,#0                   * link stack frames
    45                 movem.l D3-VCE/P2-IP,-(sp)      * preserve registers
    46                 move.w  VOICE(A6),VCE           * get voice number
    47                 move.w  VCE,D0                  * calculate IP
    48                 add.w   D0,D0                   * ...
    49                 add.w   D0,D0                   * ...
    50                 lea     vibtabl,A0              * ...
    51                 movea.l 0(A0,D0.W),IP           * ...
    52                 add.l   #_vbufs,IP              * ...
    53                 move.w  VCE,(sp)                * clrvce(vce)
    54                 jsr     _clrvce                 * ...
    55                 tst.w   TAG(A6)                 * if (tag) {
    56                 beq     L2                      * ...
    57 *
    58                 move.l  IP,P1                   * p1 = ip;
    59                 move.w  INS(A6),D0              * p2 = &idefs[ins]
    60                 add.w   D0,D0                   * ...
    61                 add.w   D0,D0                   * ...
    62                 lea     vibtabl,A0              * ...
    63                 movea.l 0(A0,D0.W),P2           * ...
    64                 add.l   #_idefs,P2              * ...
    65                 move.w  #1968,D0                * set move count
    66 *
    67 L6:             move.w  (P2)+,(P1)+             * load voice buffer
    68                 dbra    D0,L6                   * ...
    69 *
    70                 .page
    71 *
    72                 move.w  VCE,D0                  * calculate FPU offset for voice
    73                 move.w  #9,D1                   * ...
    74                 asl.w   D1,D0                   * ...
    75                 asl.w   #1,D0                   * ...
    76                 ext.l   D0                      * ...
    77                 move.l  D0,P1                   * ...
    78                 move.l  D0,P3                   * ...
    79                 add.l   #_io_fpu,P1             * point P1 at FPU WS A
    80                 add.l   #$202,P1                * ...
    81                 lea     1778(IP),P2             * point P2 at instdef WS A
    82                 add.l   #_io_fpu,P3             * point P3 at FPU WS B
    83                 add.l   #2,P3                   * ...
    84                 lea     2858(IP),P4             * point P4 at instdef WS B
    85                 move.w  #253,D0                 * setup move count
    86 *
     22
     23| register equates
     24| ----------------
     25SYNC            =       D4
     26OLDSR           =       D5
     27VCE             =       D7
     28
     29IP              =       A5
     30P1              =       A4
     31P2              =       A3
     32
     33P3              =       A2
     34P4              =       A1
     35
     36| parameter offsets
     37| -----------------
     38VOICE           =       8
     39INS             =       10
     40TAG             =       12
     41
     42                .page
     43
     44_execins:       link    A6,#0                   | link stack frames
     45                movem.l D3-VCE/P2-IP,-(sp)      | preserve registers
     46                move.w  VOICE(A6),VCE           | get voice number
     47                move.w  VCE,D0                  | calculate IP
     48                add.w   D0,D0                   | ...
     49                add.w   D0,D0                   | ...
     50                lea     vibtabl,A0              | ...
     51                movea.l 0(A0,D0.W),IP           | ...
     52                add.l   #_vbufs,IP              | ...
     53                move.w  VCE,(sp)                | clrvce(vce)
     54                jsr     _clrvce                 | ...
     55                tst.w   TAG(A6)                 | if (tag) {
     56                beq     L2                      | ...
     57
     58                move.l  IP,P1                   | p1 = ip;
     59                move.w  INS(A6),D0              | p2 = &idefs[ins]
     60                add.w   D0,D0                   | ...
     61                add.w   D0,D0                   | ...
     62                lea     vibtabl,A0              | ...
     63                movea.l 0(A0,D0.W),P2           | ...
     64                add.l   #_idefs,P2              | ...
     65                move.w  #1968,D0                | set move count
     66
     67L6:             move.w  (P2)+,(P1)+             | load voice buffer
     68                dbra    D0,L6                   | ...
     69
     70                .page
     71
     72                move.w  VCE,D0                  | calculate FPU offset for voice
     73                move.w  #9,D1                   | ...
     74                asl.w   D1,D0                   | ...
     75                asl.w   #1,D0                   | ...
     76                ext.l   D0                      | ...
     77                move.l  D0,P1                   | ...
     78                move.l  D0,P3                   | ...
     79                add.l   #_io_fpu,P1             | point P1 at FPU WS A
     80                add.l   #0x202,P1               | ...
     81                lea     1778(IP),P2             | point P2 at instdef WS A
     82                add.l   #_io_fpu,P3             | point P3 at FPU WS B
     83                add.l   #2,P3                   | ...
     84                lea     2858(IP),P4             | point P4 at instdef WS B
     85                move.w  #253,D0                 | setup move count
     86
    8787                .ifne   DOUBLED
    88                 move.l  P1,-(a7)                * save P1 on stack
    89                 move.l  P2,-(a7)                * save P2 on stack
    90                 move.l  P3,-(a7)                * save P3 on stack
    91                 move.l  P4,-(a7)                * save P4 on stack
    92                 move.w  D0,-(a7)                * save D0 on stack
     88                move.l  P1,-(a7)                | save P1 on stack
     89                move.l  P2,-(a7)                | save P2 on stack
     90                move.l  P3,-(a7)                | save P3 on stack
     91                move.l  P4,-(a7)                | save P4 on stack
     92                move.w  D0,-(a7)                | save D0 on stack
    9393                .endc
    94 *
    95                 move.w  SR,OLDSR                * turn off FPU interrupts
    96                 move.w  #$2200,SR               * ...
    97 *
    98 L10:            move.w  (P2)+,(P1)+             * set FPU WS A from instdef
    99                 nop                             * delay for FPU timing
    100                 nop                             * ...
    101                 nop                             * ...
    102                 move.w  (P4)+,(P3)+             * set FPU WS B from instdef
    103                 nop                             * delay for FPU timing
    104                 nop                             * ...
    105                 dbra    D0,L10                  * loop until done
    106 *
     94
     95                move.w  SR,OLDSR                | turn off FPU interrupts
     96                move.w  #0x2200,SR              | ...
     97
     98L10:            move.w  (P2)+,(P1)+             | set FPU WS A from instdef
     99                nop                             | delay for FPU timing
     100                nop                             | ...
     101                nop                             | ...
     102                move.w  (P4)+,(P3)+             | set FPU WS B from instdef
     103                nop                             | delay for FPU timing
     104                nop                             | ...
     105                dbra    D0,L10                  | loop until done
     106
    107107                .ifne   DOUBLED
    108                 move.w  (a7)+,D0                * restore D0 from stack
    109                 movea.l (a7)+,P4                * restore P4 from stack
    110                 movea.l (a7)+,P3                * restore P3 from stack
    111                 movea.l (a7)+,P2                * restore P2 from stack
    112                 movea.l (a7)+,P1                * restore P1 from stack
    113 *
    114 L10A:           move.w  (P2)+,(P1)+             * set FPU WS A from instdef
    115                 nop                             * delay for FPU timing
    116                 nop                             * ...
    117                 nop                             * ...
    118                 move.w  (P4)+,(P3)+             * set FPU WS B from instdef
    119                 nop                             * delay for FPU timing
    120                 nop                             * ...
    121                 dbra    D0,L10A                 * loop until done
    122 *
     108                move.w  (a7)+,D0                | restore D0 from stack
     109                movea.l (a7)+,P4                | restore P4 from stack
     110                movea.l (a7)+,P3                | restore P3 from stack
     111                movea.l (a7)+,P2                | restore P2 from stack
     112                movea.l (a7)+,P1                | restore P1 from stack
     113
     114L10A:           move.w  (P2)+,(P1)+             | set FPU WS A from instdef
     115                nop                             | delay for FPU timing
     116                nop                             | ...
     117                nop                             | ...
     118                move.w  (P4)+,(P3)+             | set FPU WS B from instdef
     119                nop                             | delay for FPU timing
     120                nop                             | ...
     121                dbra    D0,L10A                 | loop until done
     122
    123123                .endc
    124 *
    125                 move.w  OLDSR,SR                * enable FPU interrupts
    126 *
    127                 .page
    128 *
    129                 move.w  VCE,A0                  * instmod[vce] = FALSE
    130                 add.l   A0,A0                   * ...
    131                 add.l   #_instmod,A0            * ...
    132                 clr.w   (A0)                    * ...
    133                 move.w  VCE,A0                  * s_inst[vce] = ins
    134                 add.l   A0,A0                   * ...
    135                 add.l   #_s_inst,A0             * ...
    136                 move.w  INS(A6),(A0)            * ...
    137                 move.b  70(IP),SYNC             * get config bits
    138                 ext.w   SYNC                    * ...
    139                 asl.w   #8,SYNC                 * ...
    140                 btst    #2,74(IP)               * sync 2nd osc
    141                 beq     L15                     * ...
    142 *
    143                 ori.w   #$2000,SYNC             * ...
    144 *
    145 L15:            btst    #2,75(IP)               * sync 3rd osc
    146                 beq     L16                     * ...
    147 *
    148                 ori.w   #$4000,SYNC             * ...
    149 *
    150 L16:            btst    #2,76(IP)               * sync 4th osc
    151                 beq     L17                     * ...
    152 *
    153                 ori.w   #$8000,SYNC             * ...
    154 *
    155 L17:            move.w  VCE,A0                  * send sync to FPU
    156                 add.l   A0,A0                   * ...
    157                 add.l   #_io_fpu,A0             * ...
    158                 add.l   #$5FE0,A0               * ...
    159                 move.w  SYNC,(A0)               * ...
    160 *
    161 L2:             move.w  #1,(sp)                 * execkey(-1, 0, vce, 1)
    162                 move.w  VCE,-(sp)               * ...
    163                 clr.w   -(sp)                   * ...
    164                 move.w  #-1,-(sp)               * ...
    165                 jsr     _execkey                * ...
    166                 addq.l  #6,sp                   * ...
    167                 tst.l   (sp)+                   * clean up stack
    168                 movem.l (sp)+,SYNC-VCE/P2-IP    * restore registers
    169                 unlk    A6                      * unlink stack frames
    170                 rts                             * return
    171 *
    172                 .page
    173 *
     124
     125                move.w  OLDSR,SR                | enable FPU interrupts
     126
     127                .page
     128
     129                move.w  VCE,A0                  | instmod[vce] = FALSE
     130                add.l   A0,A0                   | ...
     131                add.l   #_instmod,A0            | ...
     132                clr.w   (A0)                    | ...
     133                move.w  VCE,A0                  | s_inst[vce] = ins
     134                add.l   A0,A0                   | ...
     135                add.l   #_s_inst,A0             | ...
     136                move.w  INS(A6),(A0)            | ...
     137                move.b  70(IP),SYNC             | get config bits
     138                ext.w   SYNC                    | ...
     139                asl.w   #8,SYNC                 | ...
     140                btst    #2,74(IP)               | sync 2nd osc
     141                beq     L15                     | ...
     142
     143                ori.w   #0x2000,SYNC            | ...
     144
     145L15:            btst    #2,75(IP)               | sync 3rd osc
     146                beq     L16                     | ...
     147
     148                ori.w   #0x4000,SYNC            | ...
     149
     150L16:            btst    #2,76(IP)               | sync 4th osc
     151                beq     L17                     | ...
     152
     153                ori.w   #0x8000,SYNC            | ...
     154
     155L17:            move.w  VCE,A0                  | send sync to FPU
     156                add.l   A0,A0                   | ...
     157                add.l   #_io_fpu,A0             | ...
     158                add.l   #0x5FE0,A0              | ...
     159                move.w  SYNC,(A0)               | ...
     160
     161L2:             move.w  #1,(sp)                 | execkey(-1, 0, vce, 1)
     162                move.w  VCE,-(sp)               | ...
     163                clr.w   -(sp)                   | ...
     164                move.w  #-1,-(sp)               | ...
     165                jsr     _execkey                | ...
     166                addq.l  #6,sp                   | ...
     167                tst.l   (sp)+                   | clean up stack
     168                movem.l (sp)+,SYNC-VCE/P2-IP    | restore registers
     169                unlk    A6                      | unlink stack frames
     170                rts                             | return
     171
     172                .page
     173
    174174                .data
    175 *
    176 * vibtabl -- voice and instrument buffer offset table
    177 * -------    ----------------------------------------
    178 vibtabl:        .dc.l   0               * 0
    179                 .dc.l   3938            * 1
    180                 .dc.l   7876            * 2
    181                 .dc.l   11814           * 3
    182                 .dc.l   15752           * 4
    183                 .dc.l   19690           * 5
    184                 .dc.l   23628           * 6
    185                 .dc.l   27566           * 7
    186                 .dc.l   31504           * 8
    187                 .dc.l   35442           * 9
    188                 .dc.l   39380           * 10
    189                 .dc.l   43318           * 11
    190                 .dc.l   47256           * 12
    191                 .dc.l   51194           * 13
    192                 .dc.l   55132           * 14
    193                 .dc.l   59070           * 15
    194                 .dc.l   63008           * 16
    195                 .dc.l   66946           * 17
    196                 .dc.l   70884           * 18
    197                 .dc.l   74822           * 19
    198                 .dc.l   78760           * 20
    199                 .dc.l   82698           * 21
    200                 .dc.l   86636           * 22
    201                 .dc.l   90574           * 23
    202                 .dc.l   94512           * 24
    203                 .dc.l   98450           * 25
    204                 .dc.l   102388          * 26
    205                 .dc.l   106326          * 27
    206                 .dc.l   110264          * 28
    207                 .dc.l   114202          * 29
    208                 .dc.l   118140          * 30
    209                 .dc.l   122078          * 31
    210                 .dc.l   126016          * 32
    211                 .dc.l   129954          * 33
    212                 .dc.l   133892          * 34
    213                 .dc.l   137830          * 35
    214                 .dc.l   141768          * 36
    215                 .dc.l   145706          * 37
    216                 .dc.l   149644          * 38
    217                 .dc.l   153582          * 39
    218                 .dc.l   157520          * 40
    219 *
     175
     176| vibtabl -- voice and instrument buffer offset table
     177| -------    ----------------------------------------
     178vibtabl:        .dc.l   0               | 0
     179                .dc.l   3938            | 1
     180                .dc.l   7876            | 2
     181                .dc.l   11814           | 3
     182                .dc.l   15752           | 4
     183                .dc.l   19690           | 5
     184                .dc.l   23628           | 6
     185                .dc.l   27566           | 7
     186                .dc.l   31504           | 8
     187                .dc.l   35442           | 9
     188                .dc.l   39380           | 10
     189                .dc.l   43318           | 11
     190                .dc.l   47256           | 12
     191                .dc.l   51194           | 13
     192                .dc.l   55132           | 14
     193                .dc.l   59070           | 15
     194                .dc.l   63008           | 16
     195                .dc.l   66946           | 17
     196                .dc.l   70884           | 18
     197                .dc.l   74822           | 19
     198                .dc.l   78760           | 20
     199                .dc.l   82698           | 21
     200                .dc.l   86636           | 22
     201                .dc.l   90574           | 23
     202                .dc.l   94512           | 24
     203                .dc.l   98450           | 25
     204                .dc.l   102388          | 26
     205                .dc.l   106326          | 27
     206                .dc.l   110264          | 28
     207                .dc.l   114202          | 29
     208                .dc.l   118140          | 30
     209                .dc.l   122078          | 31
     210                .dc.l   126016          | 32
     211                .dc.l   129954          | 33
     212                .dc.l   133892          | 34
     213                .dc.l   137830          | 35
     214                .dc.l   141768          | 36
     215                .dc.l   145706          | 37
     216                .dc.l   149644          | 38
     217                .dc.l   153582          | 39
     218                .dc.l   157520          | 40
     219
    220220                .end
  • ram/execkey.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * execkey.s -- execute key -- FPU function start subroutine
    3 * Version 15 -- 1988-08-29 -- D.N. Lynx Crowe
    4 * Hand optimized version of execkey() and fnstart() from C compiler output
    5 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| execkey.s -- execute key -- FPU function start subroutine
     3| Version 15 -- 1988-08-29 -- D.N. Lynx Crowe
     4| Hand optimized version of execkey() and fnstart() from C compiler output
     5| ------------------------------------------------------------------------------
    66                .text
    7 *
    8 LOC_EOR         .equ    0
    9 LOC_SUB         .equ    1
    10 *
     7
     8LOC_EOR         =       0
     9LOC_SUB         =       1
     10
    1111                .xdef   _execkey
    12 *
     12
    1313                .xref   _xgetran
    14 *
     14
    1515                .xref   _rsntab
    1616                .xref   _expbit
     
    2626                .xref   _veltab
    2727                .xref   _vpsms
    28 *
    29                 .page
    30 *
    31 * Offsets for execkey() parameters
    32 * --------------------------------
    33 TRG             .equ    8               * WORD -- trigger
    34 PCH             .equ    10              * WORD -- pitch
    35 VCE             .equ    12              * WORD -- voice  (0..11)
    36 TAG             .equ    14              * WORD -- I_TM_... inversion tag
    37 *
    38 * Register variables
    39 * ------------------
    40 A_FP            .equ    A5              * LONG -- struct idfnhdr *
    41 A_FPU           .equ    A4              * LONG -- FPU base address
    42 A_SMP           .equ    A3              * LONG -- struct sment *
    43 *
    44 R_FPMANT        .equ    D7              * WORD -- FPU time mantissa
    45 R_FPEXP         .equ    D6              * WORD -- FPU time exponent
    46 R_FPCTL         .equ    D5              * WORD -- FPU control word
    47 R_I             .equ    D4              * WORD -- loop index
    48 R_FPVAL         .equ    D3              * WORD -- FPU value
    49 *
    50 * Local (stack) variables
    51 * -----------------------
    52 PT              .equ    -4              * LONG -- instpnt *
    53 VEP             .equ    -8              * LONG -- struct valent *
    54 OLDI            .equ    -10             * WORD -- old IPL  (sr)
    55 OCTYPE          .equ    -12             * WORD -- oscillator 1 mode / scratch
    56 VP              .equ    -14             * WORD -- voice # + function # index
    57 SRCNUM          .equ    -16             * WORD -- general source #
    58 SRCVAL          .equ    -18             * WORD -- general source value
    59 TSRCVAL         .equ    -20             * WORD -- temporary general source value
    60 MLTVAL          .equ    -22             * WORD -- general source multiplier
    61 TFPVAL          .equ    -24             * WORD -- temporary FPU value
    62 LTMP            .equ    -28             * LONG -- long temporary
    63 IP              .equ    -32             * LONG -- struct instdef *
    64 GROUP           .equ    -34             * WORD -- group number << 4
    65 *
    66 * Symbolic constants
    67 * ------------------
    68 LASTLOCL        .equ    GROUP           * last local on the stack
    69 *
    70 FPU_DI          .equ    $2200           * sr value for disabling FPU interrupts
    71 PITCHMAX        .equ    21920           * maximum pitch value
    72 VALMAX          .equ    $00007D00       * maximum FPU value
    73 VALMIN          .equ    $FFFF8300       * minimum FPU value
    74 VBLEN           .equ    3938            * length of a voice buffer
    75 LSPCH           .equ    2               * left shift for pitch sources
    76 *
    77                 .page
    78 *
    79 * execkey(trg, pch, vce)
    80 * short trg, pch, vce;
    81 * {
    82 *
     28
     29                .page
     30
     31| Offsets for execkey() parameters
     32| --------------------------------
     33TRG             =       8               | WORD -- trigger
     34PCH             =       10              | WORD -- pitch
     35VCE             =       12              | WORD -- voice  (0..11)
     36TAG             =       14              | WORD -- I_TM_... inversion tag
     37
     38| Register variables
     39| ------------------
     40A_FP            =       A5              | LONG -- struct idfnhdr |
     41A_FPU           =       A4              | LONG -- FPU base address
     42A_SMP           =       A3              | LONG -- struct sment |
     43
     44R_FPMANT        =       D7              | WORD -- FPU time mantissa
     45R_FPEXP         =       D6              | WORD -- FPU time exponent
     46R_FPCTL         =       D5              | WORD -- FPU control word
     47R_I             =       D4              | WORD -- loop index
     48R_FPVAL         =       D3              | WORD -- FPU value
     49
     50| Local (stack) variables
     51| -----------------------
     52PT              =       -4              | LONG -- instpnt |
     53VEP             =       -8              | LONG -- struct valent |
     54OLDI            =       -10             | WORD -- old IPL  (sr)
     55OCTYPE          =       -12             | WORD -- oscillator 1 mode / scratch
     56VP              =       -14             | WORD -- voice # + function # index
     57SRCNUM          =       -16             | WORD -- general source #
     58SRCVAL          =       -18             | WORD -- general source value
     59TSRCVAL         =       -20             | WORD -- temporary general source value
     60MLTVAL          =       -22             | WORD -- general source multiplier
     61TFPVAL          =       -24             | WORD -- temporary FPU value
     62LTMP            =       -28             | LONG -- long temporary
     63IP              =       -32             | LONG -- struct instdef |
     64GROUP           =       -34             | WORD -- group number << 4
     65
     66| Symbolic constants
     67| ------------------
     68LASTLOCL        =       GROUP           | last local on the stack
     69
     70FPU_DI          =       0x2200          | sr value for disabling FPU interrupts
     71PITCHMAX        =       21920           | maximum pitch value
     72VALMAX          =       0x00007D00      | maximum FPU value
     73VALMIN          =       0xFFFF8300      | minimum FPU value
     74VBLEN           =       3938            | length of a voice buffer
     75LSPCH           =       2               | left shift for pitch sources
     76
     77                .page
     78
     79| execkey(trg, pch, vce)
     80| short trg, pch, vce;
     81| {
     82
    8383_execkey:       link    A6,#LASTLOCL
    8484                movem.l D2-R_FPMANT/A_SMP-A_FP,-(sp)
    85 *
    86 *       ip = &vbufs[vce];
    87 *
     85
     86|       ip = &vbufs[vce];
     87
    8888                move.w  VCE(A6),D0
    8989                asl.w   #2,D0
    9090                lea     vbtab,A0
    9191                move.l  0(A0,D0.W),IP(A6)
    92 *
    93 *       vce2trg[vce] = trg;
    94 *
     92
     93|       vce2trg[vce] = trg;
     94
    9595                lsr.w   #1,D0
    9696                lea     _vce2trg,A0
    9797                move.w  TRG(A6),0(A0,D0.W)
    98 *
    99 *       group = (vce2grp[vce] - 1) << 4;
    100 *
     98
     99|       group = (vce2grp[vce] - 1) << 4;
     100
    101101                move.w  VCE(A6),A0
    102102                add.l   A0,A0
     
    107107                asl.w   #4,D0
    108108                move.w  D0,GROUP(A6)
    109 *
    110                 .page
    111 * ------------------------------------------------------------------------------
    112 * Start function 0 -- Frq 1
    113 * ------------------------------------------------------------------------------
    114 *
    115 *    if (ip->idhfnc[0].idftmd & I_TM_KEY) {
    116 *
     109
     110                .page
     111| ------------------------------------------------------------------------------
     112| Start function 0 -- Frq 1
     113| ------------------------------------------------------------------------------
     114
     115|    if (ip->idhfnc[0].idftmd & I_TM_KEY) {
     116
    117117                move.l  IP(A6),A0
    118118                move.b  93(A0),D0
     
    121121                btst    #0,D0
    122122                bne     FN00A
    123 *
     123
    124124                jmp     FN01
    125 *
    126 *       vp = (vce << 4) + 1;
    127 *
     125
     126|       vp = (vce << 4) + 1;
     127
    128128FN00A:          move    VCE(A6),D0
    129129                asl     #4,D0
    130130                add.w   #1,D0
    131131                move    D0,VP(A6)
    132 *
    133 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    134 *
     132
     133|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     134
    135135                asl     #5,D0
    136136                ext.l   D0
    137137                move.l  D0,A_FPU
    138                 add.l   #_io_fpu+$4000,A_FPU
    139 *
    140 *       fp = &ip->idhfnc[0];
    141 *
     138                add.l   #_io_fpu+0x4000,A_FPU
     139
     140|       fp = &ip->idhfnc[0];
     141
    142142                move.l  IP(A6),A_FP
    143143                add.l   #86,A_FP
    144 *
    145 *       pt = &ip->idhpnt[fp->idfpt1];
    146 *
     144
     145|       pt = &ip->idhpnt[fp->idfpt1];
     146
    147147                clr.l   D0
    148148                move.b  6(A_FP),D0
     
    154154                add.l   #242,D0
    155155                move.l  D0,PT(A6)
    156 *
    157                 .page
    158 *
    159 *       srcnum = group | fp->idfsrc;
    160 *
     156
     157                .page
     158
     159|       srcnum = group | fp->idfsrc;
     160
    161161                move.w  GROUP(A6),D0
    162162                ext.l   D0
     
    165165                or      D1,D0
    166166                move    D0,SRCNUM(A6)
    167 *
    168 *       vep = &valents[srcnum];
    169 *
     167
     168|       vep = &valents[srcnum];
     169
    170170                add.l   D0,D0
    171171                move.l  D0,D1
     
    174174                add.l   #_valents,D0
    175175                move.l  D0,VEP(A6)
    176 *
    177 *       smp = vpsms[vp];
    178 *
     176
     177|       smp = vpsms[vp];
     178
    179179                move    VP(A6),A0
    180180                add.l   A0,A0
     
    182182                add.l   #_vpsms,A0
    183183                move.l  (A0),A_SMP
    184 *
    185 *       if (srcnum NE smp->sm) {
    186 *
     184
     185|       if (srcnum NE smp->sm) {
     186
    187187                clr     D0
    188188                move    10(A_SMP),D0
    189189                cmp     SRCNUM(A6),D0
    190190                beq     F00L113
    191 *
    192 *               (smp->prv)->nxt = smp->nxt;
    193 *
     191
     192|               (smp->prv)->nxt = smp->nxt;
     193
    194194                move.l  4(A_SMP),A0
    195195                move.l  (A_SMP),(A0)
    196 *
    197 *               (smp->nxt)->prv = smp->prv;
    198 *
     196
     197|               (smp->nxt)->prv = smp->prv;
     198
    199199                move.l  (A_SMP),A0
    200200                move.l  4(A_SMP),4(A0)
    201 *
    202 *               smp->prv = (struct sment *)vep;
    203 *
     201
     202|               smp->prv = (struct sment |)vep;
     203
    204204                move.l  VEP(A6),4(A_SMP)
    205 *
    206 *               smp->nxt = vep->nxt;
    207 *
     205
     206|               smp->nxt = vep->nxt;
     207
    208208                move.l  VEP(A6),A0
    209209                move.l  (A0),(A_SMP)
    210 *
    211 *               (vep->nxt)->prv = smp;
    212 *
     210
     211|               (vep->nxt)->prv = smp;
     212
    213213                move.l  VEP(A6),A0
    214214                move.l  (A0),A0
    215215                move.l  A_SMP,4(A0)
    216 *
    217 *               vep->nxt = smp;
    218 *
     216
     217|               vep->nxt = smp;
     218
    219219                move.l  VEP(A6),A0
    220220                move.l  A_SMP,(A0)
    221 *
    222 *               smp->sm = srcnum;
    223 *
     221
     222|               smp->sm = srcnum;
     223
    224224                move    SRCNUM(A6),10(A_SMP)
    225 *
    226 *       }
    227 *
    228 *       mltval = fp->idfmlt;
    229 *
     225
     226|       }
     227
     228|       mltval = fp->idfmlt;
     229
    230230F00L113:        move    2(A_FP),MLTVAL(A6)
    231 *
    232                 .page
    233 *
    234 *       switch (fp->idfsrc) {
    235 *
     231
     232                .page
     233
     234|       switch (fp->idfsrc) {
     235
    236236                move.b  4(A_FP),D0
    237237                ext.w   d0
    238238                cmp     #10,D0
    239239                bhi     F00L122
    240 *
     240
    241241                asl     #2,D0
    242242                lea     F00L123,A0
    243243                movea.l 0(A0,D0.W),A0
    244244                jmp     (A0)
    245 *
    246 *       case SM_NONE:
    247 *               mltval = 0;
    248 *
     245
     246|       case SM_NONE:
     247|               mltval = 0;
     248
    249249F00L116:        clr     MLTVAL(A6)
    250 *
    251 *               tsrcval = 0;
    252 *
     250
     251|               tsrcval = 0;
     252
    253253                clr     TSRCVAL(A6)
    254 *
    255 *               break;
    256 *
     254
     255|               break;
     256
    257257                bra     F00L114
    258 *
    259 *       case SM_RAND:
    260 *               tsrcval = xgetran(mltval);
    261 *
     258
     259|       case SM_RAND:
     260|               tsrcval = xgetran(mltval);
     261
    262262F00L117:        move    MLTVAL(A6),(sp)
    263263                jsr     _xgetran
    264264                move    D0,TSRCVAL(A6)
    265 *
    266 *               break;
    267 *
     265
     266|               break;
     267
    268268                bra     F00L114
    269 *
    270 *       case SM_PTCH:
    271 *               tsrcval = pch;
    272 *
     269
     270|       case SM_PTCH:
     271|               tsrcval = pch;
     272
    273273F00L118:        move    PCH(A6),TSRCVAL(A6)
    274 *
    275 *               break;
    276 *
     274
     275|               break;
     276
    277277                bra     F00L114
    278 *
    279                 .page
    280 *
    281 *       case SM_FREQ:
    282 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    283 *
     278
     279                .page
     280
     281|       case SM_FREQ:
     282|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     283
    284284F00L119:        move.w  PCH(A6),D0
    285285                asr.w   #7,D0
    286                 and.w   #$00FF,D0
     286                and.w   #0x00FF,D0
    287287                move.w  D0,A0
    288288                add.l   A0,A0
    289289                add.l   #_ptoftab,A0
    290290                move.w  (A0),TSRCVAL(A6)
    291 *
    292 *               break;
    293 *
     291
     292|               break;
     293
    294294                bra     F00L114
    295 *
    296 *       case SM_KVEL:
    297 *               tsrcval = veltab[trg];
    298 *
     295
     296|       case SM_KVEL:
     297|               tsrcval = veltab[trg];
     298
    299299F00L120:        move.w  TRG(A6),A0
    300300                add.l   A0,A0
    301301                add.l   #_veltab,A0
    302302                move.w  (A0),TSRCVAL(A6)
    303 *
    304 *               break;
    305 *
     303
     304|               break;
     305
    306306                bra     F00L114
    307 *
    308 *       case SM_KPRS:
    309 *               tsrcval = prstab[trg];
    310 *
     307
     308|       case SM_KPRS:
     309|               tsrcval = prstab[trg];
     310
    311311F00L121:        move.w  TRG(A6),A0
    312312                add.l   A0,A0
    313313                add.l   #_prstab,A0
    314314                move.w  (A0),TSRCVAL(A6)
    315 *
    316 *               break;
    317 *
     315
     316|               break;
     317
    318318                bra     F00L114
    319 *
    320 *       default:
    321 *               tsrcval = vep->val;
    322 *
     319
     320|       default:
     321|               tsrcval = vep->val;
     322
    323323F00L122:        move.l  VEP(A6),A0
    324324                move.w  8(A0),TSRCVAL(A6)
    325 *
    326 *       }
    327 *
    328                 .page
    329 *
    330 *               srcval = addpch(tsrcval, 0);
    331 *
     325
     326|       }
     327
     328                .page
     329
     330|               srcval = addpch(tsrcval, 0);
     331
    332332F00L114:        move.w  TSRCVAL(A6),D0
    333333                ext.l   D0
    334334                asr.l   #5,D0
    335 *               sub.l   #500,D0
     335|               sub.l   #500,D0
    336336                asl.l   #LSPCH,D0
    337337                cmp.l   #PITCHMAX,D0
    338338                ble     F00L129A
    339 *
     339
    340340                move.l  #PITCHMAX,D0
    341 *
     341
    342342F00L129A:       move    D0,SRCVAL(A6)
    343 *
    344                 .page
    345 *
    346 *       if (pt->ipvsrc) {
    347 *
     343
     344                .page
     345
     346|       if (pt->ipvsrc) {
     347
    348348F00L124:        move.l  PT(A6),A0
    349349                tst.b   6(A0)
    350350                beq     F00L136
    351 *
    352 *               switch (pt->ipvsrc) {
    353 *
     351
     352|               switch (pt->ipvsrc) {
     353
    354354                move.l  PT(A6),A0
    355355                move.b  6(A0),D0
     
    358358                cmp     #9,D0
    359359                bhi     F00L144
    360 *
     360
    361361                asl     #2,D0
    362362                lea     F00L145,A0
    363363                move.l  0(A0,D0.W),A0
    364364                jmp     (A0)
    365 *
    366 *               case SM_RAND:
    367 *                       ltmp = xgetran(pt_>ipvmlt);
    368 *
     365
     366|               case SM_RAND:
     367|                       ltmp = xgetran(pt_>ipvmlt);
     368
    369369F00L139:        move.l  PT(A6),A0
    370370                move    4(A0),(sp)
     
    372372                ext.l   D0
    373373                move.l  D0,LTMP(A6)
    374 *
    375 *                       break;
    376 *
     374
     375|                       break;
     376
    377377                bra     F00L137
    378 *
    379 *               case SM_PTCH:
    380 *                       ltmp = pch;
    381 *
     378
     379|               case SM_PTCH:
     380|                       ltmp = pch;
     381
    382382F00L140:        move    PCH(A6),A0
    383383                move.l  A0,LTMP(A6)
    384 *
    385 *                       break;
    386 *
     384
     385|                       break;
     386
    387387                bra     F00L137
    388 *
    389                 .page
    390 *
    391 *               case SM_FREQ:
    392 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    393 *
     388
     389                .page
     390
     391|               case SM_FREQ:
     392|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     393
    394394F00L141:        move    PCH(A6),D0
    395395                asr     #7,D0
     
    401401                ext.l   D0
    402402                move.l  D0,LTMP(A6)
    403 *
    404 *                       break;
    405 *
     403
     404|                       break;
     405
    406406                bra     F00L137
    407 *
    408 *               case SM_KVEL:
    409 *                       ltmp = veltab[trg];
    410 *
     407
     408|               case SM_KVEL:
     409|                       ltmp = veltab[trg];
     410
    411411F00L142:        move    TRG(A6),A0
    412412                add.l   A0,A0
     
    415415                ext.l   D0
    416416                move.l  D0,LTMP(A6)
    417 *
    418 *                       break;
    419 *
     417
     418|                       break;
     419
    420420                bra     F00L137
    421 *
    422                 .page
    423 *
    424 *               case SM_KPRS:
    425 *                       ltmp = prstab[trg];
    426 *
     421
     422                .page
     423
     424|               case SM_KPRS:
     425|                       ltmp = prstab[trg];
     426
    427427F00L143:        move    TRG(A6),A0
    428428                add.l   A0,A0
     
    431431                ext.l   D0
    432432                move.l  D0,LTMP(A6)
    433 *
    434 *                       break;
    435 *
     433
     434|                       break;
     435
    436436                bra     F00L137
    437 *
    438                 .page
    439 *
    440 *               default:
    441 *                       ltmp = valents[group | pt->ipvsrc].val;
    442 *
     437
     438                .page
     439
     440|               default:
     441|                       ltmp = valents[group | pt->ipvsrc].val;
     442
    443443F00L144:        move.l  PT(A6),A0
    444444                clr.l   D0
     
    454454                move    8(A0,A1.l),D0
    455455                move.l  D0,LTMP(A6)
    456 *
    457 *               }
    458 *
    459 *
    460                 .page
    461 *
    462 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    463 *
     456
     457|               }
     458
     459
     460                .page
     461
     462|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     463
    464464F00L137:        move.l  PT(A6),A0
    465465                move.w  4(A0),D0
     
    469469                asr.l   D1,D0
    470470                move.l  D0,LTMP(A6)
    471 *
    472 *               ltmp += (long)pt->ipval;
    473 *
     471
     472|               ltmp += (long)pt->ipval;
     473
    474474                move.l  PT(A6),A0
    475475                move    2(A0),D0
    476476                ext.l   D0
    477477                add.l   D0,LTMP(A6)
    478 *
    479 *               if (ltmp GT (long)VALMAX)
    480 *                       ltmp = (long)VALMAX;
    481 *
     478
     479|               if (ltmp GT (long)VALMAX)
     480|                       ltmp = (long)VALMAX;
     481
    482482                cmp.l   #VALMAX,LTMP(A6)
    483483                ble     F00L146
    484 *
     484
    485485                move.l  #VALMAX,LTMP(A6)
    486486                bra     F00L147
    487 *
    488 *               else if (ltmp LT (long)VALMIN)
    489 *                       ltmp = (long)VALMIN;
    490 *
     487
     488|               else if (ltmp LT (long)VALMIN)
     489|                       ltmp = (long)VALMIN;
     490
    491491F00L146:        cmp.l   #VALMIN,LTMP(A6)
    492492                bge     F00L147
    493 *
     493
    494494                move.l  #VALMIN,LTMP(A6)
    495 *
    496 *               tfpval = (short)ltmp;
    497 *
     495
     496|               tfpval = (short)ltmp;
     497
    498498F00L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    499499                bra     F00L149
    500 *
    501 *       } else {
    502 *
    503 *               tfpval = pt->ipval;
    504 *
     500
     501|       } else {
     502
     503|               tfpval = pt->ipval;
     504
    505505F00L136:        move.l  PT(A6),A0
    506506                move    2(A0),TFPVAL(A6)
    507 *
    508 *       }
    509 *
    510                 .page
    511 *
    512 *       fpmant = (((long)pt->iptim & 0x0000FFF0L)
    513 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    514 *
     507
     508|       }
     509
     510                .page
     511
     512|       fpmant = (((long)pt->iptim & 0x0000FFF0L)
     513|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     514
    515515F00L149:        move.l  PT(A6),A0
    516516                move.w  (A0),D0
    517517                move.w  D0,D2
    518                 andi.w  #$FFF0,D0
     518                andi.w  #0xFFF0,D0
    519519                move.w  _timemlt,D1
    520520                muls    D1,D0
     
    522522                asr.l   D1,D0
    523523                move    D0,R_FPMANT
    524 *
    525 *       fpexp = expbit[pt->iptim & 0x000F];
    526 *
    527                 and     #$000F,D2
     524
     525|       fpexp = expbit[pt->iptim & 0x000F];
     526
     527                and     #0x000F,D2
    528528                move    D2,A0
    529529                add.l   A0,A0
    530530                add.l   #_expbit,A0
    531531                move    (A0),R_FPEXP
    532 *
    533                 .page
    534 *
    535 *               octype = ip->idhos1c & OC_MOD;
    536 *
     532
     533                .page
     534
     535|               octype = ip->idhos1c & OC_MOD;
     536
    537537F00L152:        move.l  IP(A6),A0
    538538                move.b  74(A0),D0
    539539                and     #3,D0
    540 *
    541 *               if ((octype EQ OC_FRQ) OR (octype EQ OC_PCH))
    542 *
     540
     541|               if ((octype EQ OC_FRQ) OR (octype EQ OC_PCH))
     542
    543543                cmp     #2,D0
    544544                beq     F00L1001
    545 *
     545
    546546                cmp     #3,D0
    547547                bne     F00L153
    548 *
    549 *                       fp->idfpch = ip->idhos1v;
    550 *
     548
     549|                       fp->idfpch = ip->idhos1v;
     550
    551551F00L1001:       move.l  IP(A6),A0
    552552                move    78(A0),(A_FP)
    553553                bra     F00L154
    554 *
    555 *               else
    556 *                       fp->idfpch = pch + ip->idhos1v;
    557 *
     554
     555|               else
     556|                       fp->idfpch = pch + ip->idhos1v;
     557
    558558F00L153:        move.w  PCH(A6),D0
    559559                ext.l   D0
     
    561561                ext.l   D1
    562562                add.l   d1,d0
    563 *
    564 *               if (fp->idfpch > PITCHMAX)
    565 *                       fp->idfpch = PITCHMAX;
    566 *
     563
     564|               if (fp->idfpch > PITCHMAX)
     565|                       fp->idfpch = PITCHMAX;
     566
    567567                cmp.l   #PITCHMAX,d0
    568568                ble     F00153A
    569 *
     569
    570570                move.l  #PITCHMAX,d0
    571 *
     571
    572572F00153A:        move.w  d0,(A_FP)
    573 *
    574 *               fpval = addpch(tfpval, fp->idfpch);
    575 *
     573
     574|               fpval = addpch(tfpval, fp->idfpch);
     575
    576576F00L154:        move.w  TFPVAL(A6),D1
    577577                ext.l   D1
     
    584584                cmp.l   #PITCHMAX,D0
    585585                ble     F00L154A
    586 *
     586
    587587                move.l  #PITCHMAX,D0
    588 *
     588
    589589F00L154A:       move    D0,R_FPVAL
    590 *
    591                 .page
    592 *
     590
     591                .page
     592
    593593                move.b  5(A_FP),D0
    594594                ext.w   D0
    595595                sub.w   #1,D0
    596596                movea.l PT(A6),A0
    597 *
    598 *       oldi = setipl(FPU_DI);
    599 *
     597
     598|       oldi = setipl(FPU_DI);
     599
    600600                move    sr,OLDI(A6)
    601601                move    #FPU_DI,sr
    602 *
     602
    603603F00L168:        clr.b   10(A0)
    604604                add.l   #12,A0
    605605                dbra    D0,F00L168
    606 *
    607                 .page
    608 *
    609 *       fp->idftmd ^= I_NVBITS;
    610 *
     606
     607                .page
     608
     609|       fp->idftmd ^= I_NVBITS;
     610
    611611F00L165:        eor.b   #24,7(A_FP)
    612 *
    613 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    614 *
     612
     613|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     614
    615615                move.b  7(A_FP),R_FPCTL
    616616                and     #28,R_FPCTL
    617617                or      #3,R_FPCTL
    618 *
    619 *       fp->idfcpt = fp->idfpt1;
    620 *
     618
     619|       fp->idfcpt = fp->idfpt1;
     620
    621621                move.b  6(A_FP),8(A_FP)
    622 *
    623 *       fp->idftmd |= I_ACTIVE;
    624 *
     622
     623|       fp->idftmd |= I_ACTIVE;
     624
    625625                or.b    #2,7(A_FP)
    626 *
    627 *       fp->idftrf = trg;
    628 *
     626
     627|       fp->idftrf = trg;
     628
    629629                move    TRG(A6),10(A_FP)
    630 *
    631 *       *(fpu + (long)FPU_TCV1) = srcval;
    632 *
    633                 move    SRCVAL(A6),$8(A_FPU)
    634 *
    635 *       ++octype;
    636 *
     630
     631|       |(fpu + (long)FPU_TCV1) = srcval;
     632
     633                move    SRCVAL(A6),0x8(A_FPU)
     634
     635|       ++octype;
     636
    637637                add     #1,OCTYPE(A6)
    638 *
    639 *       *(fpu + (long)FPU_TSF1) = mltval;
    640 *
    641                 move    MLTVAL(A6),$A(A_FPU)
    642 *
    643 *       ++octype;
    644 *
     638
     639|       |(fpu + (long)FPU_TSF1) = mltval;
     640
     641                move    MLTVAL(A6),0xA(A_FPU)
     642
     643|       ++octype;
     644
    645645                add     #1,OCTYPE(A6)
    646 *
    647 *       *(fpu + (long)FPU_TMNT) = fpmant;
    648 *
    649                 move    R_FPMANT,$14(A_FPU)
    650 *
    651 *       ++octype;
    652 *
     646
     647|       |(fpu + (long)FPU_TMNT) = fpmant;
     648
     649                move    R_FPMANT,0x14(A_FPU)
     650
     651|       ++octype;
     652
    653653                add     #1,OCTYPE(A6)
    654 *
    655 *       *(fpu + (long)FPU_TEXP) = fpexp;
    656 *
    657                 move    R_FPEXP,$16(A_FPU)
    658 *
    659 *       ++octype;
    660 *
     654
     655|       |(fpu + (long)FPU_TEXP) = fpexp;
     656
     657                move    R_FPEXP,0x16(A_FPU)
     658
     659|       ++octype;
     660
    661661                add     #1,OCTYPE(A6)
    662 *
    663                 .page
    664 *
    665 *       if (fp->idftmd & I_VNSUBN)
    666 *
     662
     663                .page
     664
     665|       if (fp->idftmd & I_VNSUBN)
     666
    667667                btst    #3,7(A_FP)
    668668                beq     F00L169
    669 *
    670 *               *(fpu + (long)FPU_TNV1) = fpval;
    671 *
    672                 move    R_FPVAL,$1C(A_FPU)
     669
     670|               |(fpu + (long)FPU_TNV1) = fpval;
     671
     672                move    R_FPVAL,0x1C(A_FPU)
    673673                bra     F00L170
    674 *
    675 *       else
    676 *               *(fpu + (long)FPU_TNV0) = fpval;
    677 *
     674
     675|       else
     676|               |(fpu + (long)FPU_TNV0) = fpval;
     677
    678678F00L169:        move    R_FPVAL,2(A_FPU)
    679 *
    680 *       ++octype;
    681 *
     679
     680|       ++octype;
     681
    682682F00L170:        add     #1,OCTYPE(A6)
    683 *
    684 *       *(fpu + (long)FPU_TCTL) = fpctl;
    685 *
     683
     684|       |(fpu + (long)FPU_TCTL) = fpctl;
     685
    686686                move    R_FPCTL,(A_FPU)
    687 *
    688 *       setipl(oldi);
    689 *
     687
     688|       setipl(oldi);
     689
    690690                move    OLDI(A6),sr
    691 *    }
    692 *
    693                 .page
    694 * ------------------------------------------------------------------------------
    695 * Start function 1 -- Frq 2
    696 * ------------------------------------------------------------------------------
    697 *    if (legato) {
    698 *
    699 *       legato = 0;
    700 *       return;
    701 *    }
     691|    }
     692
     693                .page
     694| ------------------------------------------------------------------------------
     695| Start function 1 -- Frq 2
     696| ------------------------------------------------------------------------------
     697|    if (legato) {
     698
     699|       legato = 0;
     700|       return;
     701|    }
    702702FN01:           tst.w   _legato
    703703                beq     FN01AA
    704 *
     704
    705705                clr.w   _legato
    706706                bra     FNEXIT
    707 *
    708 *    if (ip->idhfnc[1].idftmd & I_TM_KEY) {
    709 *
     707
     708|    if (ip->idhfnc[1].idftmd & I_TM_KEY) {
     709
    710710FN01AA:         move.l  IP(A6),A0
    711711                move.b  105(A0),D0
     
    714714                btst    #0,D0
    715715                bne     FN01A
    716 *
     716
    717717                jmp     FN02
    718 *
    719 *       vp = (vce << 4) + 3;
    720 *
     718
     719|       vp = (vce << 4) + 3;
     720
    721721FN01A:          move    VCE(A6),D0
    722722                asl     #4,D0
    723723                add.w   #3,D0
    724724                move    D0,VP(A6)
    725 *
    726 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    727 *
     725
     726|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     727
    728728                asl     #5,D0
    729729                ext.l   D0
    730730                move.l  D0,A_FPU
    731                 add.l   #_io_fpu+$4000,A_FPU
    732 *
    733 *       fp = &ip->idhfnc[1];
    734 *
     731                add.l   #_io_fpu+0x4000,A_FPU
     732
     733|       fp = &ip->idhfnc[1];
     734
    735735                move.l  #12,A_FP
    736736                add.l   IP(A6),A_FP
    737737                add.l   #86,A_FP
    738 *
    739 *       pt = &ip->idhpnt[fp->idfpt1];
    740 *
     738
     739|       pt = &ip->idhpnt[fp->idfpt1];
     740
    741741                clr.l   D0
    742742                move.b  6(A_FP),D0
     
    748748                add.l   #242,D0
    749749                move.l  D0,PT(A6)
    750 *
    751                 .page
    752 *
    753 *       srcnum = group | fp->idfsrc;
    754 *
     750
     751                .page
     752
     753|       srcnum = group | fp->idfsrc;
     754
    755755                move.w  GROUP(A6),D0
    756756                ext.l   D0
     
    759759                or      D1,D0
    760760                move    D0,SRCNUM(A6)
    761 *
    762 *       vep = &valents[srcnum];
    763 *
     761
     762|       vep = &valents[srcnum];
     763
    764764                add.l   D0,D0
    765765                move.l  D0,D1
     
    768768                add.l   #_valents,D0
    769769                move.l  D0,VEP(A6)
    770 *
    771 *       smp = vpsms[vp];
    772 *
     770
     771|       smp = vpsms[vp];
     772
    773773                move    VP(A6),A0
    774774                add.l   A0,A0
     
    776776                add.l   #_vpsms,A0
    777777                move.l  (A0),A_SMP
    778 *
    779 *       if (srcnum NE smp->sm) {
    780 *
     778
     779|       if (srcnum NE smp->sm) {
     780
    781781                clr     D0
    782782                move    10(A_SMP),D0
    783783                cmp     SRCNUM(A6),D0
    784784                beq     F01L113
    785 *
    786 *               (smp->prv)->nxt = smp->nxt;
    787 *
     785
     786|               (smp->prv)->nxt = smp->nxt;
     787
    788788                move.l  4(A_SMP),A0
    789789                move.l  (A_SMP),(A0)
    790 *
    791 *               (smp->nxt)->prv = smp->prv;
    792 *
     790
     791|               (smp->nxt)->prv = smp->prv;
     792
    793793                move.l  (A_SMP),A0
    794794                move.l  4(A_SMP),4(A0)
    795 *
    796 *               smp->prv = (struct sment *)vep;
    797 *
     795
     796|               smp->prv = (struct sment |)vep;
     797
    798798                move.l  VEP(A6),4(A_SMP)
    799 *
    800 *               smp->nxt = vep->nxt;
    801 *
     799
     800|               smp->nxt = vep->nxt;
     801
    802802                move.l  VEP(A6),A0
    803803                move.l  (A0),(A_SMP)
    804 *
    805 *               (vep->nxt)->prv = smp;
    806 *
     804
     805|               (vep->nxt)->prv = smp;
     806
    807807                move.l  VEP(A6),A0
    808808                move.l  (A0),A0
    809809                move.l  A_SMP,4(A0)
    810 *
    811 *               vep->nxt = smp;
    812 *
     810
     811|               vep->nxt = smp;
     812
    813813                move.l  VEP(A6),A0
    814814                move.l  A_SMP,(A0)
    815 *
    816 *               smp->sm = srcnum;
    817 *
     815
     816|               smp->sm = srcnum;
     817
    818818                move    SRCNUM(A6),10(A_SMP)
    819 *
    820 *       }
    821 *
    822 *       mltval = fp->idfmlt;
    823 *
     819
     820|       }
     821
     822|       mltval = fp->idfmlt;
     823
    824824F01L113:        move    2(A_FP),MLTVAL(A6)
    825 *
    826                 .page
    827 *
    828 *       switch (fp->idfsrc) {
    829 *
     825
     826                .page
     827
     828|       switch (fp->idfsrc) {
     829
    830830                move.b  4(A_FP),D0
    831831                ext.w   d0
    832832                cmp     #10,D0
    833833                bhi     F01L122
    834 *
     834
    835835                asl     #2,D0
    836836                lea     F01L123,A0
    837837                movea.l 0(A0,D0.W),A0
    838838                jmp     (A0)
    839 *
    840 *       case SM_NONE:
    841 *               mltval = 0;
    842 *
     839
     840|       case SM_NONE:
     841|               mltval = 0;
     842
    843843F01L116:        clr     MLTVAL(A6)
    844 *
    845 *               tsrcval = 0;
    846 *
     844
     845|               tsrcval = 0;
     846
    847847                clr     TSRCVAL(A6)
    848 *
    849 *               break;
    850 *
     848
     849|               break;
     850
    851851                bra     F01L114
    852 *
    853 *       case SM_RAND:
    854 *               tsrcval = xgetran(mltval);
    855 *
     852
     853|       case SM_RAND:
     854|               tsrcval = xgetran(mltval);
     855
    856856F01L117:        move    MLTVAL(A6),(sp)
    857857                jsr     _xgetran
    858858                move    D0,TSRCVAL(A6)
    859 *
    860 *               break;
    861 *
     859
     860|               break;
     861
    862862                bra     F01L114
    863 *
    864 *       case SM_PTCH:
    865 *               tsrcval = pch;
    866 *
     863
     864|       case SM_PTCH:
     865|               tsrcval = pch;
     866
    867867F01L118:        move    PCH(A6),TSRCVAL(A6)
    868 *
    869 *               break;
    870 *
     868
     869|               break;
     870
    871871                bra     F01L114
    872 *
    873                 .page
    874 *
    875 *       case SM_FREQ:
    876 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    877 *
     872
     873                .page
     874
     875|       case SM_FREQ:
     876|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     877
    878878F01L119:        move    PCH(A6),D0
    879879                asr     #7,D0
     
    883883                add.l   #_ptoftab,A0
    884884                move    (A0),TSRCVAL(A6)
    885 *
    886 *               break;
    887 *
     885
     886|               break;
     887
    888888                bra     F01L114
    889 *
    890 *       case SM_KVEL:
    891 *               tsrcval = veltab[trg];
    892 *
     889
     890|       case SM_KVEL:
     891|               tsrcval = veltab[trg];
     892
    893893F01L120:        move    TRG(A6),A0
    894894                add.l   A0,A0
    895895                add.l   #_veltab,A0
    896896                move    (A0),TSRCVAL(A6)
    897 *
    898 *               break;
    899 *
     897
     898|               break;
     899
    900900                bra     F01L114
    901 *
    902 *       case SM_KPRS:
    903 *               tsrcval = prstab[trg];
    904 *
     901
     902|       case SM_KPRS:
     903|               tsrcval = prstab[trg];
     904
    905905F01L121:        move    TRG(A6),A0
    906906                add.l   A0,A0
    907907                add.l   #_prstab,A0
    908908                move    (A0),TSRCVAL(A6)
    909 *
    910 *               break;
    911 *
     909
     910|               break;
     911
    912912                bra     F01L114
    913 *
    914 *       default:
    915 *               tsrcval = vep->val;
    916 *
     913
     914|       default:
     915|               tsrcval = vep->val;
     916
    917917F01L122:        move.l  VEP(A6),A0
    918918                move    8(A0),TSRCVAL(A6)
    919 *
    920 *       }
    921 *
    922                 .page
    923 *
    924 *               srcval = addpch(tsrcval, 0);
    925 *
     919
     920|       }
     921
     922                .page
     923
     924|               srcval = addpch(tsrcval, 0);
     925
    926926F01L114:        move.w  TSRCVAL(A6),D0
    927927                ext.l   D0
    928928                asr.l   #5,D0
    929 *               sub.l   #500,D0
     929|               sub.l   #500,D0
    930930                asl.l   #LSPCH,D0
    931931                cmp.l   #PITCHMAX,D0
    932932                ble     F01L129A
    933 *
     933
    934934                move.l  #PITCHMAX,D0
    935 *
     935
    936936F01L129A:       move    D0,SRCVAL(A6)
    937 *
    938                 .page
    939 *
    940 *       if (pt->ipvsrc) {
    941 *
     937
     938                .page
     939
     940|       if (pt->ipvsrc) {
     941
    942942F01L124:        move.l  PT(A6),A0
    943943                tst.b   6(A0)
    944944                beq     F01L136
    945 *
    946 *               switch (pt->ipvsrc) {
    947 *
     945
     946|               switch (pt->ipvsrc) {
     947
    948948                move.l  PT(A6),A0
    949949                move.b  6(A0),D0
     
    952952                cmp     #9,D0
    953953                bhi     F01L144
    954 *
     954
    955955                asl     #2,D0
    956956                lea     F01L145,A0
    957957                move.l  0(A0,D0.W),A0
    958958                jmp     (A0)
    959 *
    960 *               case SM_RAND:
    961 *                       ltmp = xgetran(pt_>ipvmlt);
    962 *
     959
     960|               case SM_RAND:
     961|                       ltmp = xgetran(pt_>ipvmlt);
     962
    963963F01L139:        move.l  PT(A6),A0
    964964                move    4(A0),(sp)
     
    966966                ext.l   D0
    967967                move.l  D0,LTMP(A6)
    968 *
    969 *                       break;
    970 *
     968
     969|                       break;
     970
    971971                bra     F01L137
    972 *
    973 *               case SM_PTCH:
    974 *                       ltmp = pch;
    975 *
     972
     973|               case SM_PTCH:
     974|                       ltmp = pch;
     975
    976976F01L140:        move    PCH(A6),A0
    977977                move.l  A0,LTMP(A6)
    978 *
    979 *                       break;
    980 *
     978
     979|                       break;
     980
    981981                bra     F01L137
    982 *
    983                 .page
    984 *
    985 *               case SM_FREQ:
    986 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    987 *
     982
     983                .page
     984
     985|               case SM_FREQ:
     986|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     987
    988988F01L141:        move    PCH(A6),D0
    989989                asr     #7,D0
     
    995995                ext.l   D0
    996996                move.l  D0,LTMP(A6)
    997 *
    998 *                       break;
    999 *
     997
     998|                       break;
     999
    10001000                bra     F01L137
    1001 *
    1002 *               case SM_KVEL:
    1003 *                       ltmp = veltab[trg];
    1004 *
     1001
     1002|               case SM_KVEL:
     1003|                       ltmp = veltab[trg];
     1004
    10051005F01L142:        move    TRG(A6),A0
    10061006                add.l   A0,A0
     
    10091009                ext.l   D0
    10101010                move.l  D0,LTMP(A6)
    1011 *
    1012 *                       break;
    1013 *
     1011
     1012|                       break;
     1013
    10141014                bra     F01L137
    1015 *
    1016                 .page
    1017 *
    1018 *               case SM_KPRS:
    1019 *                       ltmp = prstab[trg];
    1020 *
     1015
     1016                .page
     1017
     1018|               case SM_KPRS:
     1019|                       ltmp = prstab[trg];
     1020
    10211021F01L143:        move    TRG(A6),A0
    10221022                add.l   A0,A0
     
    10251025                ext.l   D0
    10261026                move.l  D0,LTMP(A6)
    1027 *
    1028 *                       break;
    1029 *
     1027
     1028|                       break;
     1029
    10301030                bra     F01L137
    1031 *
    1032                 .page
    1033 *
    1034 *               default:
    1035 *                       ltmp = valents[group | pt->ipvsrc].val;
    1036 *
     1031
     1032                .page
     1033
     1034|               default:
     1035|                       ltmp = valents[group | pt->ipvsrc].val;
     1036
    10371037F01L144:        move.l  PT(A6),A0
    10381038                clr.l   D0
     
    10481048                move    8(A0,A1.l),D0
    10491049                move.l  D0,LTMP(A6)
    1050 *
    1051 *               }
    1052 *
    1053 *
    1054                 .page
    1055 *
    1056 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    1057 *
     1050
     1051|               }
     1052
     1053
     1054                .page
     1055
     1056|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     1057
    10581058F01L137:        move.l  PT(A6),A0
    10591059                move.w  4(A0),D0
     
    10631063                asr.l   D1,D0
    10641064                move.l  D0,LTMP(A6)
    1065 *
    1066 *               ltmp += (long)pt->ipval;
    1067 *
     1065
     1066|               ltmp += (long)pt->ipval;
     1067
    10681068                move.l  PT(A6),A0
    10691069                move    2(A0),D0
    10701070                ext.l   D0
    10711071                add.l   D0,LTMP(A6)
    1072 *
    1073 *               if (ltmp GT (long)VALMAX)
    1074 *                       ltmp = (long)VALMAX;
    1075 *
     1072
     1073|               if (ltmp GT (long)VALMAX)
     1074|                       ltmp = (long)VALMAX;
     1075
    10761076                cmp.l   #VALMAX,LTMP(A6)
    10771077                ble     F01L146
    1078 *
     1078
    10791079                move.l  #VALMAX,LTMP(A6)
    10801080                bra     F01L147
    1081 *
    1082 *               else if (ltmp LT (long)VALMIN)
    1083 *                       ltmp = (long)VALMIN;
    1084 *
     1081
     1082|               else if (ltmp LT (long)VALMIN)
     1083|                       ltmp = (long)VALMIN;
     1084
    10851085F01L146:        cmp.l   #VALMIN,LTMP(A6)
    10861086                bge     F01L147
    1087 *
     1087
    10881088                move.l  #VALMIN,LTMP(A6)
    1089 *
    1090 *               tfpval = (short)ltmp;
    1091 *
     1089
     1090|               tfpval = (short)ltmp;
     1091
    10921092F01L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    10931093                bra     F01L149
    1094 *
    1095 *       } else {
    1096 *
    1097 *               tfpval = pt->ipval;
    1098 *
     1094
     1095|       } else {
     1096
     1097|               tfpval = pt->ipval;
     1098
    10991099F01L136:        move.l  PT(A6),A0
    11001100                move    2(A0),TFPVAL(A6)
    1101 *
    1102 *       }
    1103 *
    1104                 .page
    1105 *
    1106 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    1107 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    1108 *
     1101
     1102|       }
     1103
     1104                .page
     1105
     1106|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     1107|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     1108
    11091109F01L149:        move.l  PT(A6),A0
    11101110                move.w  (A0),D0
    11111111                move.w  D0,D2
    1112                 andi.w  #$FFF0,D0
     1112                andi.w  #0xFFF0,D0
    11131113                move.w  _timemlt,D1
    11141114                muls    D1,D0
     
    11161116                asr.l   D1,D0
    11171117                move    D0,R_FPMANT
    1118 *
    1119 *       fpexp = expbit[pt->iptim & 0x000F];
    1120 *
    1121                 and     #$000F,D2
     1118
     1119|       fpexp = expbit[pt->iptim & 0x000F];
     1120
     1121                and     #0x000F,D2
    11221122                move    D2,A0
    11231123                add.l   A0,A0
    11241124                add.l   #_expbit,A0
    11251125                move    (A0),R_FPEXP
    1126 *
    1127                 .page
    1128 *
    1129 *               fp->idfpch = ip->idhos2v;
    1130 *
     1126
     1127                .page
     1128
     1129|               fp->idfpch = ip->idhos2v;
     1130
    11311131F01L155:        move.l  IP(A6),A0
    11321132                move.w  80(A0),(A_FP)
    1133 *
    1134 *               fpval = addpch(tfpval, fp_>idfpch);
    1135 *
     1133
     1134|               fpval = addpch(tfpval, fp_>idfpch);
     1135
    11361136                move.w  TFPVAL(A6),D1
    11371137                ext.l   D1
     
    11441144                cmp.l   #PITCHMAX,D0
    11451145                ble     F01L155A
    1146 *
     1146
    11471147                move.l  #PITCHMAX,D0
    1148 *
     1148
    11491149F01L155A:       move    D0,R_FPVAL
    1150 *
    1151                 .page
    1152 *
     1150
     1151                .page
     1152
    11531153                move.b  5(A_FP),D0
    11541154                ext.w   D0
    11551155                sub.w   #1,D0
    11561156                movea.l PT(A6),A0
    1157 *
    1158 *       oldi = setipl(FPU_DI);
    1159 *
     1157
     1158|       oldi = setipl(FPU_DI);
     1159
    11601160                move    sr,OLDI(A6)
    11611161                move    #FPU_DI,sr
    1162 *
     1162
    11631163F01L168:        clr.b   10(A0)
    11641164                add.l   #12,a0
    11651165                dbra    D0,F01L168
    1166 *
    1167                 .page
    1168 *
    1169 *       fp->idftmd ^= I_NVBITS;
    1170 *
     1166
     1167                .page
     1168
     1169|       fp->idftmd ^= I_NVBITS;
     1170
    11711171F01L165:        eor.b   #24,7(A_FP)
    1172 *
    1173 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    1174 *
     1172
     1173|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     1174
    11751175                move.b  7(A_FP),R_FPCTL
    11761176                and     #28,R_FPCTL
    11771177                or      #3,R_FPCTL
    1178 *
    1179 *       fp->idfcpt = fp->idfpt1;
    1180 *
     1178
     1179|       fp->idfcpt = fp->idfpt1;
     1180
    11811181                move.b  6(A_FP),8(A_FP)
    1182 *
    1183 *       fp->idftmd |= I_ACTIVE;
    1184 *
     1182
     1183|       fp->idftmd |= I_ACTIVE;
     1184
    11851185                or.b    #2,7(A_FP)
    1186 *
    1187 *       fp->idftrf = trg;
    1188 *
     1186
     1187|       fp->idftrf = trg;
     1188
    11891189                move    TRG(A6),10(A_FP)
    1190 *
    1191 *       *(fpu + (long)FPU_TCV1) = srcval;
    1192 *
    1193                 move    SRCVAL(A6),$8(A_FPU)
    1194 *
    1195 *       ++octype;
    1196 *
     1190
     1191|       |(fpu + (long)FPU_TCV1) = srcval;
     1192
     1193                move    SRCVAL(A6),0x8(A_FPU)
     1194
     1195|       ++octype;
     1196
    11971197                add     #1,OCTYPE(A6)
    1198 *
    1199 *       *(fpu + (long)FPU_TSF1) = mltval;
    1200 *
    1201                 move    MLTVAL(A6),$A(A_FPU)
    1202 *
    1203 *       ++octype;
    1204 *
     1198
     1199|       |(fpu + (long)FPU_TSF1) = mltval;
     1200
     1201                move    MLTVAL(A6),0xA(A_FPU)
     1202
     1203|       ++octype;
     1204
    12051205                add     #1,OCTYPE(A6)
    1206 *
    1207 *       *(fpu + (long)FPU_TMNT) = fpmant;
    1208 *
    1209                 move    R_FPMANT,$14(A_FPU)
    1210 *
    1211 *       ++octype;
    1212 *
     1206
     1207|       |(fpu + (long)FPU_TMNT) = fpmant;
     1208
     1209                move    R_FPMANT,0x14(A_FPU)
     1210
     1211|       ++octype;
     1212
    12131213                add     #1,OCTYPE(A6)
    1214 *
    1215 *       *(fpu + (long)FPU_TEXP) = fpexp;
    1216 *
    1217                 move    R_FPEXP,$16(A_FPU)
    1218 *
    1219 *       ++octype;
    1220 *
     1214
     1215|       |(fpu + (long)FPU_TEXP) = fpexp;
     1216
     1217                move    R_FPEXP,0x16(A_FPU)
     1218
     1219|       ++octype;
     1220
    12211221                add     #1,OCTYPE(A6)
    1222 *
    1223                 .page
    1224 *
    1225 *       if (fp->idftmd & I_VNSUBN)
    1226 *
     1222
     1223                .page
     1224
     1225|       if (fp->idftmd & I_VNSUBN)
     1226
    12271227                btst    #3,7(A_FP)
    12281228                beq     F01L169
    1229 *
    1230 *               *(fpu + (long)FPU_TNV1) = fpval;
    1231 *
    1232                 move    R_FPVAL,$1C(A_FPU)
     1229
     1230|               |(fpu + (long)FPU_TNV1) = fpval;
     1231
     1232                move    R_FPVAL,0x1C(A_FPU)
    12331233                bra     F01L170
    1234 *
    1235 *       else
    1236 *               *(fpu + (long)FPU_TNV0) = fpval;
    1237 *
     1234
     1235|       else
     1236|               |(fpu + (long)FPU_TNV0) = fpval;
     1237
    12381238F01L169:        move    R_FPVAL,2(A_FPU)
    1239 *
    1240 *       ++octype;
    1241 *
     1239
     1240|       ++octype;
     1241
    12421242F01L170:        add     #1,OCTYPE(A6)
    1243 *
    1244 *       *(fpu + (long)FPU_TCTL) = fpctl;
    1245 *
     1243
     1244|       |(fpu + (long)FPU_TCTL) = fpctl;
     1245
    12461246                move    R_FPCTL,(A_FPU)
    1247 *
    1248 *       setipl(oldi);
    1249 *
     1247
     1248|       setipl(oldi);
     1249
    12501250                move    OLDI(A6),sr
    1251 *
    1252                 .page
    1253 * ------------------------------------------------------------------------------
    1254 * Start function 2 -- Frq 3
    1255 * ------------------------------------------------------------------------------
    1256 *
    1257 *    if (ip->idhfnc[2].idftmd & I_TM_KEY) {
    1258 *
     1251
     1252                .page
     1253| ------------------------------------------------------------------------------
     1254| Start function 2 -- Frq 3
     1255| ------------------------------------------------------------------------------
     1256
     1257|    if (ip->idhfnc[2].idftmd & I_TM_KEY) {
     1258
    12591259FN02:           move.l  IP(A6),A0
    12601260                move.b  117(A0),D0
     
    12631263                btst    #0,D0
    12641264                bne     FN02A
    1265 *
     1265
    12661266                jmp     FN03
    1267 *
    1268 *       vp = (vce << 4) + 5;
    1269 *
     1267
     1268|       vp = (vce << 4) + 5;
     1269
    12701270FN02A:          move    VCE(A6),D0
    12711271                asl     #4,D0
    12721272                add.w   #5,D0
    12731273                move    D0,VP(A6)
    1274 *
    1275 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    1276 *
     1274
     1275|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     1276
    12771277                asl     #5,D0
    12781278                ext.l   D0
    12791279                move.l  D0,A_FPU
    1280                 add.l   #_io_fpu+$4000,A_FPU
    1281 *
    1282 *       fp = &ip->idhfnc[2];
    1283 *
     1280                add.l   #_io_fpu+0x4000,A_FPU
     1281
     1282|       fp = &ip->idhfnc[2];
     1283
    12841284                move.l  #24,A_FP
    12851285                add.l   IP(A6),A_FP
    12861286                add.l   #86,A_FP
    1287 *
    1288 *       pt = &ip->idhpnt[fp->idfpt1];
    1289 *
     1287
     1288|       pt = &ip->idhpnt[fp->idfpt1];
     1289
    12901290                clr.l   D0
    12911291                move.b  6(A_FP),D0
     
    12971297                add.l   #242,D0
    12981298                move.l  D0,PT(A6)
    1299 *
    1300                 .page
    1301 *
    1302 *       srcnum = group | fp->idfsrc;
    1303 *
     1299
     1300                .page
     1301
     1302|       srcnum = group | fp->idfsrc;
     1303
    13041304                move.w  GROUP(A6),D0
    13051305                ext.l   D0
     
    13081308                or      D1,D0
    13091309                move    D0,SRCNUM(A6)
    1310 *
    1311 *       vep = &valents[srcnum];
    1312 *
     1310
     1311|       vep = &valents[srcnum];
     1312
    13131313                add.l   D0,D0
    13141314                move.l  D0,D1
     
    13171317                add.l   #_valents,D0
    13181318                move.l  D0,VEP(A6)
    1319 *
    1320 *       smp = vpsms[vp];
    1321 *
     1319
     1320|       smp = vpsms[vp];
     1321
    13221322                move    VP(A6),A0
    13231323                add.l   A0,A0
     
    13251325                add.l   #_vpsms,A0
    13261326                move.l  (A0),A_SMP
    1327 *
    1328 *       if (srcnum NE smp->sm) {
    1329 *
     1327
     1328|       if (srcnum NE smp->sm) {
     1329
    13301330                clr     D0
    13311331                move    10(A_SMP),D0
    13321332                cmp     SRCNUM(A6),D0
    13331333                beq     F02L113
    1334 *
    1335 *               (smp->prv)->nxt = smp->nxt;
    1336 *
     1334
     1335|               (smp->prv)->nxt = smp->nxt;
     1336
    13371337                move.l  4(A_SMP),A0
    13381338                move.l  (A_SMP),(A0)
    1339 *
    1340 *               (smp->nxt)->prv = smp->prv;
    1341 *
     1339
     1340|               (smp->nxt)->prv = smp->prv;
     1341
    13421342                move.l  (A_SMP),A0
    13431343                move.l  4(A_SMP),4(A0)
    1344 *
    1345 *               smp->prv = (struct sment *)vep;
    1346 *
     1344
     1345|               smp->prv = (struct sment |)vep;
     1346
    13471347                move.l  VEP(A6),4(A_SMP)
    1348 *
    1349 *               smp->nxt = vep->nxt;
    1350 *
     1348
     1349|               smp->nxt = vep->nxt;
     1350
    13511351                move.l  VEP(A6),A0
    13521352                move.l  (A0),(A_SMP)
    1353 *
    1354 *               (vep->nxt)->prv = smp;
    1355 *
     1353
     1354|               (vep->nxt)->prv = smp;
     1355
    13561356                move.l  VEP(A6),A0
    13571357                move.l  (A0),A0
    13581358                move.l  A_SMP,4(A0)
    1359 *
    1360 *               vep->nxt = smp;
    1361 *
     1359
     1360|               vep->nxt = smp;
     1361
    13621362                move.l  VEP(A6),A0
    13631363                move.l  A_SMP,(A0)
    1364 *
    1365 *               smp->sm = srcnum;
    1366 *
     1364
     1365|               smp->sm = srcnum;
     1366
    13671367                move    SRCNUM(A6),10(A_SMP)
    1368 *
    1369 *       }
    1370 *
    1371 *       mltval = fp->idfmlt;
    1372 *
     1368
     1369|       }
     1370
     1371|       mltval = fp->idfmlt;
     1372
    13731373F02L113:        move    2(A_FP),MLTVAL(A6)
    1374 *
    1375                 .page
    1376 *
    1377 *       switch (fp->idfsrc) {
    1378 *
     1374
     1375                .page
     1376
     1377|       switch (fp->idfsrc) {
     1378
    13791379                move.b  4(A_FP),D0
    13801380                ext.w   d0
    13811381                cmp     #10,D0
    13821382                bhi     F02L122
    1383 *
     1383
    13841384                asl     #2,D0
    13851385                lea     F02L123,A0
    13861386                movea.l 0(A0,D0.W),A0
    13871387                jmp     (A0)
    1388 *
    1389 *       case SM_NONE:
    1390 *               mltval = 0;
    1391 *
     1388
     1389|       case SM_NONE:
     1390|               mltval = 0;
     1391
    13921392F02L116:        clr     MLTVAL(A6)
    1393 *
    1394 *               tsrcval = 0;
    1395 *
     1393
     1394|               tsrcval = 0;
     1395
    13961396                clr     TSRCVAL(A6)
    1397 *
    1398 *               break;
    1399 *
     1397
     1398|               break;
     1399
    14001400                bra     F02L114
    1401 *
    1402 *       case SM_RAND:
    1403 *               tsrcval = xgetran(mltval);
    1404 *
     1401
     1402|       case SM_RAND:
     1403|               tsrcval = xgetran(mltval);
     1404
    14051405F02L117:        move    MLTVAL(A6),(sp)
    14061406                jsr     _xgetran
    14071407                move    D0,TSRCVAL(A6)
    1408 *
    1409 *               break;
    1410 *
     1408
     1409|               break;
     1410
    14111411                bra     F02L114
    1412 *
    1413 *       case SM_PTCH:
    1414 *               tsrcval = pch;
    1415 *
     1412
     1413|       case SM_PTCH:
     1414|               tsrcval = pch;
     1415
    14161416F02L118:        move    PCH(A6),TSRCVAL(A6)
    1417 *
    1418 *               break;
    1419 *
     1417
     1418|               break;
     1419
    14201420                bra     F02L114
    1421 *
    1422                 .page
    1423 *
    1424 *       case SM_FREQ:
    1425 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    1426 *
     1421
     1422                .page
     1423
     1424|       case SM_FREQ:
     1425|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     1426
    14271427F02L119:        move    PCH(A6),D0
    14281428                asr     #7,D0
     
    14321432                add.l   #_ptoftab,A0
    14331433                move    (A0),TSRCVAL(A6)
    1434 *
    1435 *               break;
    1436 *
     1434
     1435|               break;
     1436
    14371437                bra     F02L114
    1438 *
    1439 *       case SM_KVEL:
    1440 *               tsrcval = veltab[trg];
    1441 *
     1438
     1439|       case SM_KVEL:
     1440|               tsrcval = veltab[trg];
     1441
    14421442F02L120:        move    TRG(A6),A0
    14431443                add.l   A0,A0
    14441444                add.l   #_veltab,A0
    14451445                move    (A0),TSRCVAL(A6)
    1446 *
    1447 *               break;
    1448 *
     1446
     1447|               break;
     1448
    14491449                bra     F02L114
    1450 *
    1451 *       case SM_KPRS:
    1452 *               tsrcval = prstab[trg];
    1453 *
     1450
     1451|       case SM_KPRS:
     1452|               tsrcval = prstab[trg];
     1453
    14541454F02L121:        move    TRG(A6),A0
    14551455                add.l   A0,A0
    14561456                add.l   #_prstab,A0
    14571457                move    (A0),TSRCVAL(A6)
    1458 *
    1459 *               break;
    1460 *
     1458
     1459|               break;
     1460
    14611461                bra     F02L114
    1462 *
    1463 *       default:
    1464 *               tsrcval = vep->val;
    1465 *
     1462
     1463|       default:
     1464|               tsrcval = vep->val;
     1465
    14661466F02L122:        move.l  VEP(A6),A0
    14671467                move    8(A0),TSRCVAL(A6)
    1468 *
    1469 *       }
    1470 *
    1471                 .page
    1472 *
    1473 *               srcval = addpch(tsrcval, 0);
    1474 *
     1468
     1469|       }
     1470
     1471                .page
     1472
     1473|               srcval = addpch(tsrcval, 0);
     1474
    14751475F02L114:        move.w  TSRCVAL(A6),D0
    14761476                ext.l   D0
    14771477                asr.l   #5,D0
    1478 *               sub.l   #500,D0
     1478|               sub.l   #500,D0
    14791479                asl.l   #LSPCH,D0
    14801480                cmp.l   #PITCHMAX,D0
    14811481                ble     F02L129A
    1482 *
     1482
    14831483                move.l  #PITCHMAX,D0
    1484 *
     1484
    14851485F02L129A:       move    D0,SRCVAL(A6)
    1486 *
    1487                 .page
    1488 *
    1489 *       if (pt->ipvsrc) {
    1490 *
     1486
     1487                .page
     1488
     1489|       if (pt->ipvsrc) {
     1490
    14911491F02L124:        move.l  PT(A6),A0
    14921492                tst.b   6(A0)
    14931493                beq     F02L136
    1494 *
    1495 *               switch (pt->ipvsrc) {
    1496 *
     1494
     1495|               switch (pt->ipvsrc) {
     1496
    14971497                move.l  PT(A6),A0
    14981498                move.b  6(A0),D0
     
    15011501                cmp     #9,D0
    15021502                bhi     F02L144
    1503 *
     1503
    15041504                asl     #2,D0
    15051505                lea     F02L145,A0
    15061506                move.l  0(A0,D0.W),A0
    15071507                jmp     (A0)
    1508 *
    1509 *               case SM_RAND:
    1510 *                       ltmp = xgetran(pt_>ipvmlt);
    1511 *
     1508
     1509|               case SM_RAND:
     1510|                       ltmp = xgetran(pt_>ipvmlt);
     1511
    15121512F02L139:        move.l  PT(A6),A0
    15131513                move    4(A0),(sp)
     
    15151515                ext.l   D0
    15161516                move.l  D0,LTMP(A6)
    1517 *
    1518 *                       break;
    1519 *
     1517
     1518|                       break;
     1519
    15201520                bra     F02L137
    1521 *
    1522 *               case SM_PTCH:
    1523 *                       ltmp = pch;
    1524 *
     1521
     1522|               case SM_PTCH:
     1523|                       ltmp = pch;
     1524
    15251525F02L140:        move    PCH(A6),A0
    15261526                move.l  A0,LTMP(A6)
    1527 *
    1528 *                       break;
    1529 *
     1527
     1528|                       break;
     1529
    15301530                bra     F02L137
    1531 *
    1532                 .page
    1533 *
    1534 *               case SM_FREQ:
    1535 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    1536 *
     1531
     1532                .page
     1533
     1534|               case SM_FREQ:
     1535|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     1536
    15371537F02L141:        move    PCH(A6),D0
    15381538                asr     #7,D0
     
    15441544                ext.l   D0
    15451545                move.l  D0,LTMP(A6)
    1546 *
    1547 *                       break;
    1548 *
     1546
     1547|                       break;
     1548
    15491549                bra     F02L137
    1550 *
    1551 *               case SM_KVEL:
    1552 *                       ltmp = veltab[trg];
    1553 *
     1550
     1551|               case SM_KVEL:
     1552|                       ltmp = veltab[trg];
     1553
    15541554F02L142:        move    TRG(A6),A0
    15551555                add.l   A0,A0
     
    15581558                ext.l   D0
    15591559                move.l  D0,LTMP(A6)
    1560 *
    1561 *                       break;
    1562 *
     1560
     1561|                       break;
     1562
    15631563                bra     F02L137
    1564 *
    1565                 .page
    1566 *
    1567 *               case SM_KPRS:
    1568 *                       ltmp = prstab[trg];
    1569 *
     1564
     1565                .page
     1566
     1567|               case SM_KPRS:
     1568|                       ltmp = prstab[trg];
     1569
    15701570F02L143:        move    TRG(A6),A0
    15711571                add.l   A0,A0
     
    15741574                ext.l   D0
    15751575                move.l  D0,LTMP(A6)
    1576 *
    1577 *                       break;
    1578 *
     1576
     1577|                       break;
     1578
    15791579                bra     F02L137
    1580 *
    1581                 .page
    1582 *
    1583 *               default:
    1584 *                       ltmp = valents[group | pt->ipvsrc].val;
    1585 *
     1580
     1581                .page
     1582
     1583|               default:
     1584|                       ltmp = valents[group | pt->ipvsrc].val;
     1585
    15861586F02L144:        move.l  PT(A6),A0
    15871587                clr.l   D0
     
    15971597                move    8(A0,A1.l),D0
    15981598                move.l  D0,LTMP(A6)
    1599 *
    1600 *               }
    1601 *
    1602 *
    1603                 .page
    1604 *
    1605 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    1606 *
     1599
     1600|               }
     1601
     1602
     1603                .page
     1604
     1605|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     1606
    16071607F02L137:        move.l  PT(A6),A0
    16081608                move.w  4(A0),D0
     
    16121612                asr.l   D1,D0
    16131613                move.l  D0,LTMP(A6)
    1614 *
    1615 *               ltmp += (long)pt->ipval;
    1616 *
     1614
     1615|               ltmp += (long)pt->ipval;
     1616
    16171617                move.l  PT(A6),A0
    16181618                move    2(A0),D0
    16191619                ext.l   D0
    16201620                add.l   D0,LTMP(A6)
    1621 *
    1622 *               if (ltmp GT (long)VALMAX)
    1623 *                       ltmp = (long)VALMAX;
    1624 *
     1621
     1622|               if (ltmp GT (long)VALMAX)
     1623|                       ltmp = (long)VALMAX;
     1624
    16251625                cmp.l   #VALMAX,LTMP(A6)
    16261626                ble     F02L146
    1627 *
     1627
    16281628                move.l  #VALMAX,LTMP(A6)
    16291629                bra     F02L147
    1630 *
    1631 *               else if (ltmp LT (long)VALMIN)
    1632 *                       ltmp = (long)VALMIN;
    1633 *
     1630
     1631|               else if (ltmp LT (long)VALMIN)
     1632|                       ltmp = (long)VALMIN;
     1633
    16341634F02L146:        cmp.l   #VALMIN,LTMP(A6)
    16351635                bge     F02L147
    1636 *
     1636
    16371637                move.l  #VALMIN,LTMP(A6)
    1638 *
    1639 *               tfpval = (short)ltmp;
    1640 *
     1638
     1639|               tfpval = (short)ltmp;
     1640
    16411641F02L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    16421642                bra     F02L149
    1643 *
    1644 *       } else {
    1645 *
    1646 *               tfpval = pt->ipval;
    1647 *
     1643
     1644|       } else {
     1645
     1646|               tfpval = pt->ipval;
     1647
    16481648F02L136:        move.l  PT(A6),A0
    16491649                move    2(A0),TFPVAL(A6)
    1650 *
    1651 *       }
    1652 *
    1653                 .page
    1654 *
    1655 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    1656 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    1657 *
     1650
     1651|       }
     1652
     1653                .page
     1654
     1655|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     1656|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     1657
    16581658F02L149:        move.l  PT(A6),A0
    16591659                move.w  (A0),D0
    16601660                move.w  D0,D2
    1661                 andi.w  #$FFF0,D0
     1661                andi.w  #0xFFF0,D0
    16621662                move.w  _timemlt,D1
    16631663                muls    D1,D0
     
    16651665                asr.l   D1,D0
    16661666                move    D0,R_FPMANT
    1667 *
    1668 *       fpexp = expbit[pt->iptim & 0x000F];
    1669 *
    1670                 and     #$000F,D2
     1667
     1668|       fpexp = expbit[pt->iptim & 0x000F];
     1669
     1670                and     #0x000F,D2
    16711671                move    D2,A0
    16721672                add.l   A0,A0
    16731673                add.l   #_expbit,A0
    16741674                move    (A0),R_FPEXP
    1675 *
    1676                 .page
    1677 *
    1678 *               fp->idfpch = ip->idhos3v;
    1679 *
     1675
     1676                .page
     1677
     1678|               fp->idfpch = ip->idhos3v;
     1679
    16801680F02L156:        move.l  IP(A6),A0
    16811681                move.w  82(A0),(A_FP)
    1682 *
    1683 *               fpval = addpch(tfpval, fp->idfpch);
    1684 *
     1682
     1683|               fpval = addpch(tfpval, fp->idfpch);
     1684
    16851685                move.w  TFPVAL(A6),D1
    16861686                ext.l   D1
     
    16931693                cmp.l   #PITCHMAX,D0
    16941694                ble     F02L156A
    1695 *
     1695
    16961696                move.l  #PITCHMAX,D0
    1697 *
     1697
    16981698F02L156A:       move    D0,R_FPVAL
    1699 *
    1700                 .page
    1701 *
     1699
     1700                .page
     1701
    17021702                move.b  5(A_FP),D0
    17031703                ext.w   D0
    17041704                sub.w   #1,D0
    17051705                movea.l PT(A6),A0
    1706 *
    1707 *       oldi = setipl(FPU_DI);
    1708 *
     1706
     1707|       oldi = setipl(FPU_DI);
     1708
    17091709                move    sr,OLDI(A6)
    17101710                move    #FPU_DI,sr
    1711 *
     1711
    17121712F02L168:        clr.b   10(A0)
    17131713                add.l   #12,a0
    17141714                dbra    D0,F02L168
    1715 *
    1716                 .page
    1717 *
    1718 *       fp->idftmd ^= I_NVBITS;
    1719 *
     1715
     1716                .page
     1717
     1718|       fp->idftmd ^= I_NVBITS;
     1719
    17201720F02L165:        eor.b   #24,7(A_FP)
    1721 *
    1722 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    1723 *
     1721
     1722|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     1723
    17241724                move.b  7(A_FP),R_FPCTL
    17251725                and     #28,R_FPCTL
    17261726                or      #3,R_FPCTL
    1727 *
    1728 *       fp->idfcpt = fp->idfpt1;
    1729 *
     1727
     1728|       fp->idfcpt = fp->idfpt1;
     1729
    17301730                move.b  6(A_FP),8(A_FP)
    1731 *
    1732 *       fp->idftmd |= I_ACTIVE;
    1733 *
     1731
     1732|       fp->idftmd |= I_ACTIVE;
     1733
    17341734                or.b    #2,7(A_FP)
    1735 *
    1736 *       fp->idftrf = trg;
    1737 *
     1735
     1736|       fp->idftrf = trg;
     1737
    17381738                move    TRG(A6),10(A_FP)
    1739 *
    1740 *       *(fpu + (long)FPU_TCV1) = srcval;
    1741 *
    1742                 move    SRCVAL(A6),$8(A_FPU)
    1743 *
    1744 *       ++octype;
    1745 *
     1739
     1740|       |(fpu + (long)FPU_TCV1) = srcval;
     1741
     1742                move    SRCVAL(A6),0x8(A_FPU)
     1743
     1744|       ++octype;
     1745
    17461746                add     #1,OCTYPE(A6)
    1747 *
    1748 *       *(fpu + (long)FPU_TSF1) = mltval;
    1749 *
    1750                 move    MLTVAL(A6),$A(A_FPU)
    1751 *
    1752 *       ++octype;
    1753 *
     1747
     1748|       |(fpu + (long)FPU_TSF1) = mltval;
     1749
     1750                move    MLTVAL(A6),0xA(A_FPU)
     1751
     1752|       ++octype;
     1753
    17541754                add     #1,OCTYPE(A6)
    1755 *
    1756 *       *(fpu + (long)FPU_TMNT) = fpmant;
    1757 *
    1758                 move    R_FPMANT,$14(A_FPU)
    1759 *
    1760 *       ++octype;
    1761 *
     1755
     1756|       |(fpu + (long)FPU_TMNT) = fpmant;
     1757
     1758                move    R_FPMANT,0x14(A_FPU)
     1759
     1760|       ++octype;
     1761
    17621762                add     #1,OCTYPE(A6)
    1763 *
    1764 *       *(fpu + (long)FPU_TEXP) = fpexp;
    1765 *
    1766                 move    R_FPEXP,$16(A_FPU)
    1767 *
    1768 *       ++octype;
    1769 *
     1763
     1764|       |(fpu + (long)FPU_TEXP) = fpexp;
     1765
     1766                move    R_FPEXP,0x16(A_FPU)
     1767
     1768|       ++octype;
     1769
    17701770                add     #1,OCTYPE(A6)
    1771 *
    1772                 .page
    1773 *
    1774 *       if (fp->idftmd & I_VNSUBN)
    1775 *
     1771
     1772                .page
     1773
     1774|       if (fp->idftmd & I_VNSUBN)
     1775
    17761776                btst    #3,7(A_FP)
    17771777                beq     F02L169
    1778 *
    1779 *               *(fpu + (long)FPU_TNV1) = fpval;
    1780 *
    1781                 move    R_FPVAL,$1C(A_FPU)
     1778
     1779|               |(fpu + (long)FPU_TNV1) = fpval;
     1780
     1781                move    R_FPVAL,0x1C(A_FPU)
    17821782                bra     F02L170
    1783 *
    1784 *       else
    1785 *               *(fpu + (long)FPU_TNV0) = fpval;
    1786 *
     1783
     1784|       else
     1785|               |(fpu + (long)FPU_TNV0) = fpval;
     1786
    17871787F02L169:        move    R_FPVAL,2(A_FPU)
    1788 *
    1789 *       ++octype;
    1790 *
     1788
     1789|       ++octype;
     1790
    17911791F02L170:        add     #1,OCTYPE(A6)
    1792 *
    1793 *       *(fpu + (long)FPU_TCTL) = fpctl;
    1794 *
     1792
     1793|       |(fpu + (long)FPU_TCTL) = fpctl;
     1794
    17951795                move    R_FPCTL,(A_FPU)
    1796 *
    1797 *       setipl(oldi);
    1798 *
     1796
     1797|       setipl(oldi);
     1798
    17991799                move    OLDI(A6),sr
    1800 *
    1801                 .page
    1802 * ------------------------------------------------------------------------------
    1803 * Start function 3 -- Frq 4
    1804 * ------------------------------------------------------------------------------
    1805 *
    1806 *    if (ip->idhfnc[3].idftmd & I_TM_KEY) {
    1807 *
     1800
     1801                .page
     1802| ------------------------------------------------------------------------------
     1803| Start function 3 -- Frq 4
     1804| ------------------------------------------------------------------------------
     1805
     1806|    if (ip->idhfnc[3].idftmd & I_TM_KEY) {
     1807
    18081808FN03:           move.l  IP(A6),A0
    18091809                move.b  129(A0),D0
     
    18121812                btst    #0,D0
    18131813                bne     FN03A
    1814 *
     1814
    18151815                jmp     FN04
    1816 *
    1817 *       vp = (vce << 4) + 7;
    1818 *
     1816
     1817|       vp = (vce << 4) + 7;
     1818
    18191819FN03A:          move    VCE(A6),D0
    18201820                asl     #4,D0
    18211821                add.w   #7,D0
    18221822                move    D0,VP(A6)
    1823 *
    1824 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    1825 *
     1823
     1824|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     1825
    18261826                asl     #5,D0
    18271827                ext.l   D0
    18281828                move.l  D0,A_FPU
    1829                 add.l   #_io_fpu+$4000,A_FPU
    1830 *
    1831 *       fp = &ip->idhfnc[3];
    1832 *
     1829                add.l   #_io_fpu+0x4000,A_FPU
     1830
     1831|       fp = &ip->idhfnc[3];
     1832
    18331833                move.l  #36,A_FP
    18341834                add.l   IP(A6),A_FP
    18351835                add.l   #86,A_FP
    1836 *
    1837 *       pt = &ip->idhpnt[fp->idfpt1];
    1838 *
     1836
     1837|       pt = &ip->idhpnt[fp->idfpt1];
     1838
    18391839                clr.l   D0
    18401840                move.b  6(A_FP),D0
     
    18461846                add.l   #242,D0
    18471847                move.l  D0,PT(A6)
    1848 *
    1849                 .page
    1850 *
    1851 *       srcnum = group | fp->idfsrc;
    1852 *
     1848
     1849                .page
     1850
     1851|       srcnum = group | fp->idfsrc;
     1852
    18531853                move.w  GROUP(A6),D0
    18541854                ext.l   D0
     
    18571857                or      D1,D0
    18581858                move    D0,SRCNUM(A6)
    1859 *
    1860 *       vep = &valents[srcnum];
    1861 *
     1859
     1860|       vep = &valents[srcnum];
     1861
    18621862                add.l   D0,D0
    18631863                move.l  D0,D1
     
    18661866                add.l   #_valents,D0
    18671867                move.l  D0,VEP(A6)
    1868 *
    1869 *       smp = vpsms[vp];
    1870 *
     1868
     1869|       smp = vpsms[vp];
     1870
    18711871                move    VP(A6),A0
    18721872                add.l   A0,A0
     
    18741874                add.l   #_vpsms,A0
    18751875                move.l  (A0),A_SMP
    1876 *
    1877 *       if (srcnum NE smp->sm) {
    1878 *
     1876
     1877|       if (srcnum NE smp->sm) {
     1878
    18791879                clr     D0
    18801880                move    10(A_SMP),D0
    18811881                cmp     SRCNUM(A6),D0
    18821882                beq     F03L113
    1883 *
    1884 *               (smp->prv)->nxt = smp->nxt;
    1885 *
     1883
     1884|               (smp->prv)->nxt = smp->nxt;
     1885
    18861886                move.l  4(A_SMP),A0
    18871887                move.l  (A_SMP),(A0)
    1888 *
    1889 *               (smp->nxt)->prv = smp->prv;
    1890 *
     1888
     1889|               (smp->nxt)->prv = smp->prv;
     1890
    18911891                move.l  (A_SMP),A0
    18921892                move.l  4(A_SMP),4(A0)
    1893 *
    1894 *               smp->prv = (struct sment *)vep;
    1895 *
     1893
     1894|               smp->prv = (struct sment |)vep;
     1895
    18961896                move.l  VEP(A6),4(A_SMP)
    1897 *
    1898 *               smp->nxt = vep->nxt;
    1899 *
     1897
     1898|               smp->nxt = vep->nxt;
     1899
    19001900                move.l  VEP(A6),A0
    19011901                move.l  (A0),(A_SMP)
    1902 *
    1903 *               (vep->nxt)->prv = smp;
    1904 *
     1902
     1903|               (vep->nxt)->prv = smp;
     1904
    19051905                move.l  VEP(A6),A0
    19061906                move.l  (A0),A0
    19071907                move.l  A_SMP,4(A0)
    1908 *
    1909 *               vep->nxt = smp;
    1910 *
     1908
     1909|               vep->nxt = smp;
     1910
    19111911                move.l  VEP(A6),A0
    19121912                move.l  A_SMP,(A0)
    1913 *
    1914 *               smp->sm = srcnum;
    1915 *
     1913
     1914|               smp->sm = srcnum;
     1915
    19161916                move    SRCNUM(A6),10(A_SMP)
    1917 *
    1918 *       }
    1919 *
    1920 *       mltval = fp->idfmlt;
    1921 *
     1917
     1918|       }
     1919
     1920|       mltval = fp->idfmlt;
     1921
    19221922F03L113:        move    2(A_FP),MLTVAL(A6)
    1923 *
    1924                 .page
    1925 *
    1926 *       switch (fp->idfsrc) {
    1927 *
     1923
     1924                .page
     1925
     1926|       switch (fp->idfsrc) {
     1927
    19281928                move.b  4(A_FP),D0
    19291929                ext.w   d0
    19301930                cmp     #10,D0
    19311931                bhi     F03L122
    1932 *
     1932
    19331933                asl     #2,D0
    19341934                lea     F03L123,A0
    19351935                movea.l 0(A0,D0.W),A0
    19361936                jmp     (A0)
    1937 *
    1938 *       case SM_NONE:
    1939 *               mltval = 0;
    1940 *
     1937
     1938|       case SM_NONE:
     1939|               mltval = 0;
     1940
    19411941F03L116:        clr     MLTVAL(A6)
    1942 *
    1943 *               tsrcval = 0;
    1944 *
     1942
     1943|               tsrcval = 0;
     1944
    19451945                clr     TSRCVAL(A6)
    1946 *
    1947 *               break;
    1948 *
     1946
     1947|               break;
     1948
    19491949                bra     F03L114
    1950 *
    1951 *       case SM_RAND:
    1952 *               tsrcval = xgetran(mltval);
    1953 *
     1950
     1951|       case SM_RAND:
     1952|               tsrcval = xgetran(mltval);
     1953
    19541954F03L117:        move    MLTVAL(A6),(sp)
    19551955                jsr     _xgetran
    19561956                move    D0,TSRCVAL(A6)
    1957 *
    1958 *               break;
    1959 *
     1957
     1958|               break;
     1959
    19601960                bra     F03L114
    1961 *
    1962 *       case SM_PTCH:
    1963 *               tsrcval = pch;
    1964 *
     1961
     1962|       case SM_PTCH:
     1963|               tsrcval = pch;
     1964
    19651965F03L118:        move    PCH(A6),TSRCVAL(A6)
    1966 *
    1967 *               break;
    1968 *
     1966
     1967|               break;
     1968
    19691969                bra     F03L114
    1970 *
    1971                 .page
    1972 *
    1973 *       case SM_FREQ:
    1974 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    1975 *
     1970
     1971                .page
     1972
     1973|       case SM_FREQ:
     1974|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     1975
    19761976F03L119:        move    PCH(A6),D0
    19771977                asr     #7,D0
     
    19811981                add.l   #_ptoftab,A0
    19821982                move    (A0),TSRCVAL(A6)
    1983 *
    1984 *               break;
    1985 *
     1983
     1984|               break;
     1985
    19861986                bra     F03L114
    1987 *
    1988 *       case SM_KVEL:
    1989 *               tsrcval = veltab[trg];
    1990 *
     1987
     1988|       case SM_KVEL:
     1989|               tsrcval = veltab[trg];
     1990
    19911991F03L120:        move    TRG(A6),A0
    19921992                add.l   A0,A0
    19931993                add.l   #_veltab,A0
    19941994                move    (A0),TSRCVAL(A6)
    1995 *
    1996 *               break;
    1997 *
     1995
     1996|               break;
     1997
    19981998                bra     F03L114
    1999 *
    2000 *       case SM_KPRS:
    2001 *               tsrcval = prstab[trg];
    2002 *
     1999
     2000|       case SM_KPRS:
     2001|               tsrcval = prstab[trg];
     2002
    20032003F03L121:        move    TRG(A6),A0
    20042004                add.l   A0,A0
    20052005                add.l   #_prstab,A0
    20062006                move    (A0),TSRCVAL(A6)
    2007 *
    2008 *               break;
    2009 *
     2007
     2008|               break;
     2009
    20102010                bra     F03L114
    2011 *
    2012 *       default:
    2013 *               tsrcval = vep->val;
    2014 *
     2011
     2012|       default:
     2013|               tsrcval = vep->val;
     2014
    20152015F03L122:        move.l  VEP(A6),A0
    20162016                move    8(A0),TSRCVAL(A6)
    2017 *
    2018 *       }
    2019 *
    2020                 .page
    2021 *
    2022 *               srcval = addpch(tsrcval, 0);
    2023 *
     2017
     2018|       }
     2019
     2020                .page
     2021
     2022|               srcval = addpch(tsrcval, 0);
     2023
    20242024F03L114:        move.w  TSRCVAL(A6),D0
    20252025                ext.l   D0
    20262026                asr.l   #5,D0
    2027 *               sub.l   #500,D0
     2027|               sub.l   #500,D0
    20282028                asl.l   #LSPCH,D0
    20292029                cmp.l   #PITCHMAX,D0
    20302030                ble     F03L129A
    2031 *
     2031
    20322032                move.l  #PITCHMAX,D0
    20332033
    20342034F03L129A:       move    D0,SRCVAL(A6)
    2035 *
    2036                 .page
    2037 *
    2038 *       if (pt->ipvsrc) {
    2039 *
     2035
     2036                .page
     2037
     2038|       if (pt->ipvsrc) {
     2039
    20402040F03L124:        move.l  PT(A6),A0
    20412041                tst.b   6(A0)
    20422042                beq     F03L136
    2043 *
    2044 *               switch (pt->ipvsrc) {
    2045 *
     2043
     2044|               switch (pt->ipvsrc) {
     2045
    20462046                move.l  PT(A6),A0
    20472047                move.b  6(A0),D0
     
    20502050                cmp     #9,D0
    20512051                bhi     F03L144
    2052 *
     2052
    20532053                asl     #2,D0
    20542054                lea     F03L145,A0
    20552055                move.l  0(A0,D0.W),A0
    20562056                jmp     (A0)
    2057 *
    2058 *               case SM_RAND:
    2059 *                       ltmp = xgetran(pt_>ipvmlt);
    2060 *
     2057
     2058|               case SM_RAND:
     2059|                       ltmp = xgetran(pt_>ipvmlt);
     2060
    20612061F03L139:        move.l  PT(A6),A0
    20622062                move    4(A0),(sp)
     
    20642064                ext.l   D0
    20652065                move.l  D0,LTMP(A6)
    2066 *
    2067 *                       break;
    2068 *
     2066
     2067|                       break;
     2068
    20692069                bra     F03L137
    2070 *
    2071 *               case SM_PTCH:
    2072 *                       ltmp = pch;
    2073 *
     2070
     2071|               case SM_PTCH:
     2072|                       ltmp = pch;
     2073
    20742074F03L140:        move    PCH(A6),A0
    20752075                move.l  A0,LTMP(A6)
    2076 *
    2077 *                       break;
    2078 *
     2076
     2077|                       break;
     2078
    20792079                bra     F03L137
    2080 *
    2081                 .page
    2082 *
    2083 *               case SM_FREQ:
    2084 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    2085 *
     2080
     2081                .page
     2082
     2083|               case SM_FREQ:
     2084|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     2085
    20862086F03L141:        move    PCH(A6),D0
    20872087                asr     #7,D0
     
    20932093                ext.l   D0
    20942094                move.l  D0,LTMP(A6)
    2095 *
    2096 *                       break;
    2097 *
     2095
     2096|                       break;
     2097
    20982098                bra     F03L137
    2099 *
    2100 *               case SM_KVEL:
    2101 *                       ltmp = veltab[trg];
    2102 *
     2099
     2100|               case SM_KVEL:
     2101|                       ltmp = veltab[trg];
     2102
    21032103F03L142:        move    TRG(A6),A0
    21042104                add.l   A0,A0
     
    21072107                ext.l   D0
    21082108                move.l  D0,LTMP(A6)
    2109 *
    2110 *                       break;
    2111 *
     2109
     2110|                       break;
     2111
    21122112                bra     F03L137
    2113 *
    2114                 .page
    2115 *
    2116 *               case SM_KPRS:
    2117 *                       ltmp = prstab[trg];
    2118 *
     2113
     2114                .page
     2115
     2116|               case SM_KPRS:
     2117|                       ltmp = prstab[trg];
     2118
    21192119F03L143:        move    TRG(A6),A0
    21202120                add.l   A0,A0
     
    21232123                ext.l   D0
    21242124                move.l  D0,LTMP(A6)
    2125 *
    2126 *                       break;
    2127 *
     2125
     2126|                       break;
     2127
    21282128                bra     F03L137
    2129 *
    2130                 .page
    2131 *
    2132 *               default:
    2133 *                       ltmp = valents[group | pt->ipvsrc].val;
    2134 *
     2129
     2130                .page
     2131
     2132|               default:
     2133|                       ltmp = valents[group | pt->ipvsrc].val;
     2134
    21352135F03L144:        move.l  PT(A6),A0
    21362136                clr.l   D0
     
    21462146                move    8(A0,A1.l),D0
    21472147                move.l  D0,LTMP(A6)
    2148 *
    2149 *               }
    2150 *
    2151 *
    2152                 .page
    2153 *
    2154 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    2155 *
     2148
     2149|               }
     2150
     2151
     2152                .page
     2153
     2154|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     2155
    21562156F03L137:        move.l  PT(A6),A0
    21572157                move.w  4(A0),D0
     
    21612161                asr.l   D1,D0
    21622162                move.l  D0,LTMP(A6)
    2163 *
    2164 *               ltmp += (long)pt->ipval;
    2165 *
     2163
     2164|               ltmp += (long)pt->ipval;
     2165
    21662166                move.l  PT(A6),A0
    21672167                move    2(A0),D0
    21682168                ext.l   D0
    21692169                add.l   D0,LTMP(A6)
    2170 *
    2171 *               if (ltmp GT (long)VALMAX)
    2172 *                       ltmp = (long)VALMAX;
    2173 *
     2170
     2171|               if (ltmp GT (long)VALMAX)
     2172|                       ltmp = (long)VALMAX;
     2173
    21742174                cmp.l   #VALMAX,LTMP(A6)
    21752175                ble     F03L146
    2176 *
     2176
    21772177                move.l  #VALMAX,LTMP(A6)
    21782178                bra     F03L147
    2179 *
    2180 *               else if (ltmp LT (long)VALMIN)
    2181 *                       ltmp = (long)VALMIN;
    2182 *
     2179
     2180|               else if (ltmp LT (long)VALMIN)
     2181|                       ltmp = (long)VALMIN;
     2182
    21832183F03L146:        cmp.l   #VALMIN,LTMP(A6)
    21842184                bge     F03L147
    2185 *
     2185
    21862186                move.l  #VALMIN,LTMP(A6)
    2187 *
    2188 *               tfpval = (short)ltmp;
    2189 *
     2187
     2188|               tfpval = (short)ltmp;
     2189
    21902190F03L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    21912191                bra     F03L149
    2192 *
    2193 *       } else {
    2194 *
    2195 *               tfpval = pt->ipval;
    2196 *
     2192
     2193|       } else {
     2194
     2195|               tfpval = pt->ipval;
     2196
    21972197F03L136:        move.l  PT(A6),A0
    21982198                move    2(A0),TFPVAL(A6)
    2199 *
    2200 *       }
    2201 *
    2202                 .page
    2203 *
    2204 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    2205 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    2206 *
     2199
     2200|       }
     2201
     2202                .page
     2203
     2204|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     2205|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     2206
    22072207F03L149:        move.l  PT(A6),A0
    22082208                move.w  (A0),D0
    22092209                move.w  D0,D2
    2210                 andi.w  #$FFF0,D0
     2210                andi.w  #0xFFF0,D0
    22112211                move.w  _timemlt,D1
    22122212                muls    D1,D0
     
    22142214                asr.l   D1,D0
    22152215                move    D0,R_FPMANT
    2216 *
    2217 *       fpexp = expbit[pt->iptim & 0x000F];
    2218 *
    2219                 and     #$000F,D2
     2216
     2217|       fpexp = expbit[pt->iptim & 0x000F];
     2218
     2219                and     #0x000F,D2
    22202220                move    D2,A0
    22212221                add.l   A0,A0
    22222222                add.l   #_expbit,A0
    22232223                move    (A0),R_FPEXP
    2224 *
    2225                 .page
    2226 *
    2227 *               fp->idfpch = ip->idhos4v;
    2228 *
     2224
     2225                .page
     2226
     2227|               fp->idfpch = ip->idhos4v;
     2228
    22292229F03L157:        move.l  IP(A6),A0
    22302230                move.w  84(A0),(A_FP)
    2231 *
    2232 *               fpval = addpch(tfpval, fp->idfpch);
    2233 *
     2231
     2232|               fpval = addpch(tfpval, fp->idfpch);
     2233
    22342234                move.w  TFPVAL(A6),D1
    22352235                ext.l   D1
     
    22422242                cmp.l   #PITCHMAX,D0
    22432243                ble     F03L157A
    2244 *
     2244
    22452245                move.l  #PITCHMAX,D0
    2246 *
     2246
    22472247F03L157A:       move    D0,R_FPVAL
    2248 *
    2249                 .page
    2250 *
     2248
     2249                .page
     2250
    22512251                move.b  5(A_FP),D0
    22522252                ext.w   D0
    22532253                sub.w   #1,D0
    22542254                movea.l PT(A6),A0
    2255 *
    2256 *       oldi = setipl(FPU_DI);
    2257 *
     2255
     2256|       oldi = setipl(FPU_DI);
     2257
    22582258                move    sr,OLDI(A6)
    22592259                move    #FPU_DI,sr
    2260 *
     2260
    22612261F03L168:        clr.b   10(A0)
    22622262                add.l   #12,a0
    22632263                dbra    D0,F03L168
    2264 *
    2265                 .page
    2266 *
    2267 *       fp->idftmd ^= I_NVBITS;
    2268 *
     2264
     2265                .page
     2266
     2267|       fp->idftmd ^= I_NVBITS;
     2268
    22692269F03L165:        eor.b   #24,7(A_FP)
    2270 *
    2271 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    2272 *
     2270
     2271|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     2272
    22732273                move.b  7(A_FP),R_FPCTL
    22742274                and     #28,R_FPCTL
    22752275                or      #3,R_FPCTL
    2276 *
    2277 *       fp->idfcpt = fp->idfpt1;
    2278 *
     2276
     2277|       fp->idfcpt = fp->idfpt1;
     2278
    22792279                move.b  6(A_FP),8(A_FP)
    2280 *
    2281 *       fp->idftmd |= I_ACTIVE;
    2282 *
     2280
     2281|       fp->idftmd |= I_ACTIVE;
     2282
    22832283                or.b    #2,7(A_FP)
    2284 *
    2285 *       fp->idftrf = trg;
    2286 *
     2284
     2285|       fp->idftrf = trg;
     2286
    22872287                move    TRG(A6),10(A_FP)
    2288 *
    2289 *       *(fpu + (long)FPU_TCV1) = srcval;
    2290 *
    2291                 move    SRCVAL(A6),$8(A_FPU)
    2292 *
    2293 *       ++octype;
    2294 *
     2288
     2289|       |(fpu + (long)FPU_TCV1) = srcval;
     2290
     2291                move    SRCVAL(A6),0x8(A_FPU)
     2292
     2293|       ++octype;
     2294
    22952295                add     #1,OCTYPE(A6)
    2296 *
    2297 *       *(fpu + (long)FPU_TSF1) = mltval;
    2298 *
    2299                 move    MLTVAL(A6),$A(A_FPU)
    2300 *
    2301 *       ++octype;
    2302 *
     2296
     2297|       |(fpu + (long)FPU_TSF1) = mltval;
     2298
     2299                move    MLTVAL(A6),0xA(A_FPU)
     2300
     2301|       ++octype;
     2302
    23032303                add     #1,OCTYPE(A6)
    2304 *
    2305 *       *(fpu + (long)FPU_TMNT) = fpmant;
    2306 *
    2307                 move    R_FPMANT,$14(A_FPU)
    2308 *
    2309 *       ++octype;
    2310 *
     2304
     2305|       |(fpu + (long)FPU_TMNT) = fpmant;
     2306
     2307                move    R_FPMANT,0x14(A_FPU)
     2308
     2309|       ++octype;
     2310
    23112311                add     #1,OCTYPE(A6)
    2312 *
    2313 *       *(fpu + (long)FPU_TEXP) = fpexp;
    2314 *
    2315                 move    R_FPEXP,$16(A_FPU)
    2316 *
    2317 *       ++octype;
    2318 *
     2312
     2313|       |(fpu + (long)FPU_TEXP) = fpexp;
     2314
     2315                move    R_FPEXP,0x16(A_FPU)
     2316
     2317|       ++octype;
     2318
    23192319                add     #1,OCTYPE(A6)
    2320 *
    2321                 .page
    2322 *
    2323 *       if (fp->idftmd & I_VNSUBN)
    2324 *
     2320
     2321                .page
     2322
     2323|       if (fp->idftmd & I_VNSUBN)
     2324
    23252325                btst    #3,7(A_FP)
    23262326                beq     F03L169
    2327 *
    2328 *               *(fpu + (long)FPU_TNV1) = fpval;
    2329 *
    2330                 move    R_FPVAL,$1C(A_FPU)
     2327
     2328|               |(fpu + (long)FPU_TNV1) = fpval;
     2329
     2330                move    R_FPVAL,0x1C(A_FPU)
    23312331                bra     F03L170
    2332 *
    2333 *       else
    2334 *               *(fpu + (long)FPU_TNV0) = fpval;
    2335 *
     2332
     2333|       else
     2334|               |(fpu + (long)FPU_TNV0) = fpval;
     2335
    23362336F03L169:        move    R_FPVAL,2(A_FPU)
    2337 *
    2338 *       ++octype;
    2339 *
     2337
     2338|       ++octype;
     2339
    23402340F03L170:        add     #1,OCTYPE(A6)
    2341 *
    2342 *       *(fpu + (long)FPU_TCTL) = fpctl;
    2343 *
     2341
     2342|       |(fpu + (long)FPU_TCTL) = fpctl;
     2343
    23442344                move    R_FPCTL,(A_FPU)
    2345 *
    2346 *       setipl(oldi);
    2347 *
     2345
     2346|       setipl(oldi);
     2347
    23482348                move    OLDI(A6),sr
    2349 *
    2350                 .page
    2351 * ------------------------------------------------------------------------------
    2352 * Start function 4 -- Filtr
    2353 * ------------------------------------------------------------------------------
    2354 *
    2355 *    if (ip->idhfnc[4].idftmd & I_TM_KEY) {
    2356 *
     2349
     2350                .page
     2351| ------------------------------------------------------------------------------
     2352| Start function 4 -- Filtr
     2353| ------------------------------------------------------------------------------
     2354
     2355|    if (ip->idhfnc[4].idftmd & I_TM_KEY) {
     2356
    23572357FN04:           move.l  IP(A6),A0
    23582358                move.b  141(A0),D0
     
    23612361                btst    #0,D0
    23622362                bne     FN04A
    2363 *
     2363
    23642364                jmp     FN05
    2365 *
    2366 *       vp = (vce << 4) + 10;
    2367 *
     2365
     2366|       vp = (vce << 4) + 10;
     2367
    23682368FN04A:          move    VCE(A6),D0
    23692369                asl     #4,D0
    23702370                add.w   #10,D0
    23712371                move    D0,VP(A6)
    2372 *
    2373 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    2374 *
     2372
     2373|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     2374
    23752375                asl     #5,D0
    23762376                ext.l   D0
    23772377                move.l  D0,A_FPU
    2378                 add.l   #_io_fpu+$4000,A_FPU
    2379 *
    2380 *       fp = &ip->idhfnc[4];
    2381 *
     2378                add.l   #_io_fpu+0x4000,A_FPU
     2379
     2380|       fp = &ip->idhfnc[4];
     2381
    23822382                move.l  #48,A_FP
    23832383                add.l   IP(A6),A_FP
    23842384                add.l   #86,A_FP
    2385 *
    2386                 .page
    2387 *
    2388 *       Added code:
    2389 *
    2390 *               output resonance via table lookup with FPU interrupts off
    2391 *
     2385
     2386                .page
     2387
     2388|       Added code:
     2389
     2390|               output resonance via table lookup with FPU interrupts off
     2391
    23922392                lea     _rsntab,A0
    23932393                clr.w   D0
     
    24012401                ext.l   D0
    24022402                move.l  D0,A0
    2403                 add.l   #_io_fpu+$4000,A0
     2403                add.l   #_io_fpu+0x4000,A0
    24042404                move.w  sr,OLDI(A6)
    24052405                move.w  #FPU_DI,sr
    24062406                move.w  d1,2(A0)
    24072407                add.w   #1,OCTYPE(A6)
    2408                 move.w  d1,$1C(A0)
     2408                move.w  d1,0x1C(A0)
    24092409                add.w   #1,OCTYPE(A6)
    2410                 move.w  #$0015,(A0)
     2410                move.w  #0x0015,(A0)
    24112411                move.w  OLDI(A6),sr
    2412 *
    2413 *       pt = &ip->idhpnt[fp->idfpt1];
    2414 *
     2412
     2413|       pt = &ip->idhpnt[fp->idfpt1];
     2414
    24152415                clr.l   D0
    24162416                move.b  6(A_FP),D0
     
    24222422                add.l   #242,D0
    24232423                move.l  D0,PT(A6)
    2424 *
    2425                 .page
    2426 *
    2427 *       srcnum = group | fp->idfsrc;
    2428 *
     2424
     2425                .page
     2426
     2427|       srcnum = group | fp->idfsrc;
     2428
    24292429                move.w  GROUP(A6),D0
    24302430                ext.l   D0
     
    24332433                or      D1,D0
    24342434                move    D0,SRCNUM(A6)
    2435 *
    2436 *       vep = &valents[srcnum];
    2437 *
     2435
     2436|       vep = &valents[srcnum];
     2437
    24382438                add.l   D0,D0
    24392439                move.l  D0,D1
     
    24422442                add.l   #_valents,D0
    24432443                move.l  D0,VEP(A6)
    2444 *
    2445 *       smp = vpsms[vp];
    2446 *
     2444
     2445|       smp = vpsms[vp];
     2446
    24472447                move    VP(A6),A0
    24482448                add.l   A0,A0
     
    24502450                add.l   #_vpsms,A0
    24512451                move.l  (A0),A_SMP
    2452 *
    2453 *       if (srcnum NE smp->sm) {
    2454 *
     2452
     2453|       if (srcnum NE smp->sm) {
     2454
    24552455                clr     D0
    24562456                move    10(A_SMP),D0
    24572457                cmp     SRCNUM(A6),D0
    24582458                beq     F04L113
    2459 *
    2460 *               (smp->prv)->nxt = smp->nxt;
    2461 *
     2459
     2460|               (smp->prv)->nxt = smp->nxt;
     2461
    24622462                move.l  4(A_SMP),A0
    24632463                move.l  (A_SMP),(A0)
    2464 *
    2465 *               (smp->nxt)->prv = smp->prv;
    2466 *
     2464
     2465|               (smp->nxt)->prv = smp->prv;
     2466
    24672467                move.l  (A_SMP),A0
    24682468                move.l  4(A_SMP),4(A0)
    2469 *
    2470 *               smp->prv = (struct sment *)vep;
    2471 *
     2469
     2470|               smp->prv = (struct sment |)vep;
     2471
    24722472                move.l  VEP(A6),4(A_SMP)
    2473 *
    2474 *               smp->nxt = vep->nxt;
    2475 *
     2473
     2474|               smp->nxt = vep->nxt;
     2475
    24762476                move.l  VEP(A6),A0
    24772477                move.l  (A0),(A_SMP)
    2478 *
    2479 *               (vep->nxt)->prv = smp;
    2480 *
     2478
     2479|               (vep->nxt)->prv = smp;
     2480
    24812481                move.l  VEP(A6),A0
    24822482                move.l  (A0),A0
    24832483                move.l  A_SMP,4(A0)
    2484 *
    2485 *               vep->nxt = smp;
    2486 *
     2484
     2485|               vep->nxt = smp;
     2486
    24872487                move.l  VEP(A6),A0
    24882488                move.l  A_SMP,(A0)
    2489 *
    2490 *               smp->sm = srcnum;
    2491 *
     2489
     2490|               smp->sm = srcnum;
     2491
    24922492                move    SRCNUM(A6),10(A_SMP)
    2493 *
    2494 *       }
    2495 *
    2496 *       mltval = fp->idfmlt;
    2497 *
     2493
     2494|       }
     2495
     2496|       mltval = fp->idfmlt;
     2497
    24982498F04L113:        move    2(A_FP),MLTVAL(A6)
    2499 *
    2500                 .page
    2501 *
    2502 *       switch (fp->idfsrc) {
    2503 *
     2499
     2500                .page
     2501
     2502|       switch (fp->idfsrc) {
     2503
    25042504                move.b  4(A_FP),D0
    25052505                ext.w   d0
    25062506                cmp     #10,D0
    25072507                bhi     F04L122
    2508 *
     2508
    25092509                asl     #2,D0
    25102510                lea     F04L123,A0
    25112511                movea.l 0(A0,D0.W),A0
    25122512                jmp     (A0)
    2513 *
    2514 *       case SM_NONE:
    2515 *               mltval = 0;
    2516 *
     2513
     2514|       case SM_NONE:
     2515|               mltval = 0;
     2516
    25172517F04L116:        clr     MLTVAL(A6)
    2518 *
    2519 *               tsrcval = 0;
    2520 *
     2518
     2519|               tsrcval = 0;
     2520
    25212521                clr     TSRCVAL(A6)
    2522 *
    2523 *               break;
    2524 *
     2522
     2523|               break;
     2524
    25252525                bra     F04L114
    2526 *
    2527 *       case SM_RAND:
    2528 *               tsrcval = xgetran(mltval);
    2529 *
     2526
     2527|       case SM_RAND:
     2528|               tsrcval = xgetran(mltval);
     2529
    25302530F04L117:        move    MLTVAL(A6),(sp)
    25312531                jsr     _xgetran
    25322532                move    D0,TSRCVAL(A6)
    2533 *
    2534 *               break;
    2535 *
     2533
     2534|               break;
     2535
    25362536                bra     F04L114
    2537 *
    2538 *       case SM_PTCH:
    2539 *               tsrcval = pch;
    2540 *
     2537
     2538|       case SM_PTCH:
     2539|               tsrcval = pch;
     2540
    25412541F04L118:        move    PCH(A6),TSRCVAL(A6)
    2542 *
    2543 *               break;
    2544 *
     2542
     2543|               break;
     2544
    25452545                bra     F04L114
    2546 *
    2547                 .page
    2548 *
    2549 *       case SM_FREQ:
    2550 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    2551 *
     2546
     2547                .page
     2548
     2549|       case SM_FREQ:
     2550|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     2551
    25522552F04L119:        move    PCH(A6),D0
    25532553                asr     #7,D0
     
    25572557                add.l   #_ptoftab,A0
    25582558                move    (A0),TSRCVAL(A6)
    2559 *
    2560 *               break;
    2561 *
     2559
     2560|               break;
     2561
    25622562                bra     F04L114
    2563 *
    2564 *       case SM_KVEL:
    2565 *               tsrcval = veltab[trg];
    2566 *
     2563
     2564|       case SM_KVEL:
     2565|               tsrcval = veltab[trg];
     2566
    25672567F04L120:        move    TRG(A6),A0
    25682568                add.l   A0,A0
    25692569                add.l   #_veltab,A0
    25702570                move    (A0),TSRCVAL(A6)
    2571 *
    2572 *               break;
    2573 *
     2571
     2572|               break;
     2573
    25742574                bra     F04L114
    2575 *
    2576 *       case SM_KPRS:
    2577 *               tsrcval = prstab[trg];
    2578 *
     2575
     2576|       case SM_KPRS:
     2577|               tsrcval = prstab[trg];
     2578
    25792579F04L121:        move    TRG(A6),A0
    25802580                add.l   A0,A0
    25812581                add.l   #_prstab,A0
    25822582                move    (A0),TSRCVAL(A6)
    2583 *
    2584 *               break;
    2585 *
     2583
     2584|               break;
     2585
    25862586                bra     F04L114
    2587 *
    2588 *       default:
    2589 *               tsrcval = vep->val;
    2590 *
     2587
     2588|       default:
     2589|               tsrcval = vep->val;
     2590
    25912591F04L122:        move.l  VEP(A6),A0
    25922592                move    8(A0),TSRCVAL(A6)
    2593 *
    2594 *       }
    2595 *
    2596                 .page
    2597 *
    2598 *               ltmp = ((long)tsrcval >> 1) + ((long)tsrcval >> 2);
    2599 *
     2593
     2594|       }
     2595
     2596                .page
     2597
     2598|               ltmp = ((long)tsrcval >> 1) + ((long)tsrcval >> 2);
     2599
    26002600F04L114:        move    TSRCVAL(A6),D0
    26012601                ext.l   D0
     
    26062606                add.l   D1,D0
    26072607                move.l  D0,LTMP(A6)
    2608 *
    2609 *               if (ltmp GT (long)VALMAX)
    2610 *                       ltmp = (long)VALMAX;
    2611 *
     2608
     2609|               if (ltmp GT (long)VALMAX)
     2610|                       ltmp = (long)VALMAX;
     2611
    26122612                cmp.l   #VALMAX,LTMP(A6)
    26132613                ble     F04L131
    2614 *
     2614
    26152615                move.l  #VALMAX,LTMP(A6)
    26162616                bra     F04L132
    2617 *
    2618 *               else if (ltmp LT (long)VALMIN)
    2619 *                       ltmp = (long)VALMIN;
    2620 *
     2617
     2618|               else if (ltmp LT (long)VALMIN)
     2619|                       ltmp = (long)VALMIN;
     2620
    26212621F04L131:        cmp.l   #VALMIN,LTMP(A6)
    26222622                bge     F04L132
    2623 *
     2623
    26242624                move.l  #VALMIN,LTMP(A6)
    2625 *
    2626 *               srcval = (short)ltmp;
    2627 *
     2625
     2626|               srcval = (short)ltmp;
     2627
    26282628F04L132:        move.l  LTMP(A6),D0
    26292629                move    D0,SRCVAL(A6)
    2630 *
    2631                 .page
    2632 *
    2633 *       if (pt->ipvsrc) {
    2634 *
     2630
     2631                .page
     2632
     2633|       if (pt->ipvsrc) {
     2634
    26352635F04L124:        move.l  PT(A6),A0
    26362636                tst.b   6(A0)
    26372637                beq     F04L136
    2638 *
    2639 *               switch (pt->ipvsrc) {
    2640 *
     2638
     2639|               switch (pt->ipvsrc) {
     2640
    26412641                move.l  PT(A6),A0
    26422642                move.b  6(A0),D0
     
    26452645                cmp     #9,D0
    26462646                bhi     F04L144
    2647 *
     2647
    26482648                asl     #2,D0
    26492649                lea     F04L145,A0
    26502650                move.l  0(A0,D0.W),A0
    26512651                jmp     (A0)
    2652 *
    2653 *               case SM_RAND:
    2654 *                       ltmp = xgetran(pt_>ipvmlt);
    2655 *
     2652
     2653|               case SM_RAND:
     2654|                       ltmp = xgetran(pt_>ipvmlt);
     2655
    26562656F04L139:        move.l  PT(A6),A0
    26572657                move    4(A0),(sp)
     
    26592659                ext.l   D0
    26602660                move.l  D0,LTMP(A6)
    2661 *
    2662 *                       break;
    2663 *
     2661
     2662|                       break;
     2663
    26642664                bra     F04L137
    2665 *
    2666 *               case SM_PTCH:
    2667 *                       ltmp = pch;
    2668 *
     2665
     2666|               case SM_PTCH:
     2667|                       ltmp = pch;
     2668
    26692669F04L140:        move    PCH(A6),A0
    26702670                move.l  A0,LTMP(A6)
    2671 *
    2672 *                       break;
    2673 *
     2671
     2672|                       break;
     2673
    26742674                bra     F04L137
    2675 *
    2676                 .page
    2677 *
    2678 *               case SM_FREQ:
    2679 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    2680 *
     2675
     2676                .page
     2677
     2678|               case SM_FREQ:
     2679|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     2680
    26812681F04L141:        move    PCH(A6),D0
    26822682                asr     #7,D0
     
    26882688                ext.l   D0
    26892689                move.l  D0,LTMP(A6)
    2690 *
    2691 *                       break;
    2692 *
     2690
     2691|                       break;
     2692
    26932693                bra     F04L137
    2694 *
    2695 *               case SM_KVEL:
    2696 *                       ltmp = veltab[trg];
    2697 *
     2694
     2695|               case SM_KVEL:
     2696|                       ltmp = veltab[trg];
     2697
    26982698F04L142:        move    TRG(A6),A0
    26992699                add.l   A0,A0
     
    27022702                ext.l   D0
    27032703                move.l  D0,LTMP(A6)
    2704 *
    2705 *                       break;
    2706 *
     2704
     2705|                       break;
     2706
    27072707                bra     F04L137
    2708 *
    2709                 .page
    2710 *
    2711 *               case SM_KPRS:
    2712 *                       ltmp = prstab[trg];
    2713 *
     2708
     2709                .page
     2710
     2711|               case SM_KPRS:
     2712|                       ltmp = prstab[trg];
     2713
    27142714F04L143:        move    TRG(A6),A0
    27152715                add.l   A0,A0
     
    27182718                ext.l   D0
    27192719                move.l  D0,LTMP(A6)
    2720 *
    2721 *                       break;
    2722 *
     2720
     2721|                       break;
     2722
    27232723                bra     F04L137
    2724 *
    2725                 .page
    2726 *
    2727 *               default:
    2728 *                       ltmp = valents[group | pt->ipvsrc].val;
    2729 *
     2724
     2725                .page
     2726
     2727|               default:
     2728|                       ltmp = valents[group | pt->ipvsrc].val;
     2729
    27302730F04L144:        move.l  PT(A6),A0
    27312731                clr.l   D0
     
    27412741                move    8(A0,A1.l),D0
    27422742                move.l  D0,LTMP(A6)
    2743 *
    2744 *               }
    2745 *
    2746 *
    2747                 .page
    2748 *
    2749 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    2750 *
     2743
     2744|               }
     2745
     2746
     2747                .page
     2748
     2749|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     2750
    27512751F04L137:        move.l  PT(A6),A0
    27522752                move.w  4(A0),D0
     
    27562756                asr.l   D1,D0
    27572757                move.l  D0,LTMP(A6)
    2758 *
    2759 *               ltmp += (long)pt->ipval;
    2760 *
     2758
     2759|               ltmp += (long)pt->ipval;
     2760
    27612761                move.l  PT(A6),A0
    27622762                move    2(A0),D0
    27632763                ext.l   D0
    27642764                add.l   D0,LTMP(A6)
    2765 *
    2766 *               if (ltmp GT (long)VALMAX)
    2767 *                       ltmp = (long)VALMAX;
    2768 *
     2765
     2766|               if (ltmp GT (long)VALMAX)
     2767|                       ltmp = (long)VALMAX;
     2768
    27692769                cmp.l   #VALMAX,LTMP(A6)
    27702770                ble     F04L146
    2771 *
     2771
    27722772                move.l  #VALMAX,LTMP(A6)
    27732773                bra     F04L147
    2774 *
    2775 *               else if (ltmp LT (long)VALMIN)
    2776 *                       ltmp = (long)VALMIN;
    2777 *
     2774
     2775|               else if (ltmp LT (long)VALMIN)
     2776|                       ltmp = (long)VALMIN;
     2777
    27782778F04L146:        cmp.l   #VALMIN,LTMP(A6)
    27792779                bge     F04L147
    2780 *
     2780
    27812781                move.l  #VALMIN,LTMP(A6)
    2782 *
    2783 *               tfpval = (short)ltmp;
    2784 *
     2782
     2783|               tfpval = (short)ltmp;
     2784
    27852785F04L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    27862786                bra     F04L149
    2787 *
    2788 *       } else {
    2789 *
    2790 *               tfpval = pt->ipval;
    2791 *
     2787
     2788|       } else {
     2789
     2790|               tfpval = pt->ipval;
     2791
    27922792F04L136:        move.l  PT(A6),A0
    27932793                move    2(A0),TFPVAL(A6)
    2794 *
    2795 *       }
    2796 *
    2797                 .page
    2798 *
    2799 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    2800 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    2801 *
     2794
     2795|       }
     2796
     2797                .page
     2798
     2799|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     2800|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     2801
    28022802F04L149:        move.l  PT(A6),A0
    28032803                move.w  (A0),D0
    28042804                move.w  D0,D2
    2805                 andi.w  #$FFF0,D0
     2805                andi.w  #0xFFF0,D0
    28062806                move.w  _timemlt,D1
    28072807                muls    D1,D0
     
    28092809                asr.l   D1,D0
    28102810                move    D0,R_FPMANT
    2811 *
    2812 *       fpexp = expbit[pt->iptim & 0x000F];
    2813 *
    2814                 and     #$000F,D2
     2811
     2812|       fpexp = expbit[pt->iptim & 0x000F];
     2813
     2814                and     #0x000F,D2
    28152815                move    D2,A0
    28162816                add.l   A0,A0
    28172817                add.l   #_expbit,A0
    28182818                move    (A0),R_FPEXP
    2819 *
    2820                 .page
    2821 *
    2822 *               fp->idfpch = pch;
    2823 *
     2819
     2820                .page
     2821
     2822|               fp->idfpch = pch;
     2823
    28242824F04L158:        move    PCH(A6),(A_FP)
    2825 *
    2826 *               ltmp = ((long)tfpval >> 1) + ((longtfpval >>2)
    2827 *                       + (long)fp->idfpch;
    2828 *
     2825
     2826|               ltmp = ((long)tfpval >> 1) + ((longtfpval >>2)
     2827|                       + (long)fp->idfpch;
     2828
    28292829                move    TFPVAL(A6),D0
    28302830                ext.l   D0
     
    28382838                add.l   D1,D0
    28392839                move.l  D0,LTMP(A6)
    2840 *
    2841 *               if (ltmp GT (long)VALMAX)
    2842 *                       ltmp = (long)VALMAX;
    2843 *
     2840
     2841|               if (ltmp GT (long)VALMAX)
     2842|                       ltmp = (long)VALMAX;
     2843
    28442844                cmp.l   #VALMAX,LTMP(A6)
    28452845                ble     F04L159
    2846 *
     2846
    28472847                move.l  #VALMAX,LTMP(A6)
    28482848                bra     F04L160
    2849 *
    2850 *               else if (ltmp LT (long)VALMIN)
    2851 *                       ltmp = (long)VALMIN;
    2852 *
     2849
     2850|               else if (ltmp LT (long)VALMIN)
     2851|                       ltmp = (long)VALMIN;
     2852
    28532853F04L159:        cmp.l   #VALMIN,LTMP(A6)
    28542854                bge     F04L160
    2855 *
     2855
    28562856                move.l  #VALMIN,LTMP(A6)
    2857 *
    2858 *               fpval = (short)ltmp;
    2859 *
     2857
     2858|               fpval = (short)ltmp;
     2859
    28602860F04L160:        move.l  LTMP(A6),D0
    28612861                move    D0,R_FPVAL
    2862 *
    2863                 .page
    2864 *
     2862
     2863                .page
     2864
    28652865                move.b  5(A_FP),D0
    28662866                ext.w   D0
    28672867                sub.w   #1,D0
    28682868                movea.l PT(A6),A0
    2869 *
    2870 *       oldi = setipl(FPU_DI);
    2871 *
     2869
     2870|       oldi = setipl(FPU_DI);
     2871
    28722872                move    sr,OLDI(A6)
    28732873                move    #FPU_DI,sr
    2874 *
     2874
    28752875F04L168:        clr.b   10(A0)
    28762876                add.l   #12,a0
    28772877                dbra    D0,F04L168
    2878 *
    2879                 .page
    2880 *
    2881 *       fp->idftmd ^= I_NVBITS;
    2882 *
     2878
     2879                .page
     2880
     2881|       fp->idftmd ^= I_NVBITS;
     2882
    28832883F04L165:        eor.b   #24,7(A_FP)
    2884 *
    2885 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    2886 *
     2884
     2885|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     2886
    28872887                move.b  7(A_FP),R_FPCTL
    28882888                and     #28,R_FPCTL
    28892889                or      #3,R_FPCTL
    2890 *
    2891 *       fp->idfcpt = fp->idfpt1;
    2892 *
     2890
     2891|       fp->idfcpt = fp->idfpt1;
     2892
    28932893                move.b  6(A_FP),8(A_FP)
    2894 *
    2895 *       fp->idftmd |= I_ACTIVE;
    2896 *
     2894
     2895|       fp->idftmd |= I_ACTIVE;
     2896
    28972897                or.b    #2,7(A_FP)
    2898 *
    2899 *       fp->idftrf = trg;
    2900 *
     2898
     2899|       fp->idftrf = trg;
     2900
    29012901                move    TRG(A6),10(A_FP)
    2902 *
    2903 *       *(fpu + (long)FPU_TCV1) = srcval;
    2904 *
    2905                 move    SRCVAL(A6),$8(A_FPU)
    2906 *
    2907 *       ++octype;
    2908 *
     2902
     2903|       |(fpu + (long)FPU_TCV1) = srcval;
     2904
     2905                move    SRCVAL(A6),0x8(A_FPU)
     2906
     2907|       ++octype;
     2908
    29092909                add     #1,OCTYPE(A6)
    2910 *
    2911 *       *(fpu + (long)FPU_TSF1) = mltval;
    2912 *
    2913                 move    MLTVAL(A6),$A(A_FPU)
    2914 *
    2915 *       ++octype;
    2916 *
     2910
     2911|       |(fpu + (long)FPU_TSF1) = mltval;
     2912
     2913                move    MLTVAL(A6),0xA(A_FPU)
     2914
     2915|       ++octype;
     2916
    29172917                add     #1,OCTYPE(A6)
    2918 *
    2919 *       *(fpu + (long)FPU_TMNT) = fpmant;
    2920 *
    2921                 move    R_FPMANT,$14(A_FPU)
    2922 *
    2923 *       ++octype;
    2924 *
     2918
     2919|       |(fpu + (long)FPU_TMNT) = fpmant;
     2920
     2921                move    R_FPMANT,0x14(A_FPU)
     2922
     2923|       ++octype;
     2924
    29252925                add     #1,OCTYPE(A6)
    2926 *
    2927 *       *(fpu + (long)FPU_TEXP) = fpexp;
    2928 *
    2929                 move    R_FPEXP,$16(A_FPU)
    2930 *
    2931 *       ++octype;
    2932 *
     2926
     2927|       |(fpu + (long)FPU_TEXP) = fpexp;
     2928
     2929                move    R_FPEXP,0x16(A_FPU)
     2930
     2931|       ++octype;
     2932
    29332933                add     #1,OCTYPE(A6)
    2934 *
    2935                 .page
    2936 *
    2937 *       if (fp->idftmd & I_VNSUBN)
    2938 *
     2934
     2935                .page
     2936
     2937|       if (fp->idftmd & I_VNSUBN)
     2938
    29392939                btst    #3,7(A_FP)
    29402940                beq     F04L169
    2941 *
    2942 *               *(fpu + (long)FPU_TNV1) = fpval;
    2943 *
    2944                 move    R_FPVAL,$1C(A_FPU)
     2941
     2942|               |(fpu + (long)FPU_TNV1) = fpval;
     2943
     2944                move    R_FPVAL,0x1C(A_FPU)
    29452945                bra     F04L170
    2946 *
    2947 *       else
    2948 *               *(fpu + (long)FPU_TNV0) = fpval;
    2949 *
     2946
     2947|       else
     2948|               |(fpu + (long)FPU_TNV0) = fpval;
     2949
    29502950F04L169:        move    R_FPVAL,2(A_FPU)
    2951 *
    2952 *       ++octype;
    2953 *
     2951
     2952|       ++octype;
     2953
    29542954F04L170:        add     #1,OCTYPE(A6)
    2955 *
    2956 *       *(fpu + (long)FPU_TCTL) = fpctl;
    2957 *
     2955
     2956|       |(fpu + (long)FPU_TCTL) = fpctl;
     2957
    29582958                move    R_FPCTL,(A_FPU)
    2959 *
    2960 *       setipl(oldi);
    2961 *
     2959
     2960|       setipl(oldi);
     2961
    29622962                move    OLDI(A6),sr
    2963 *
    2964                 .page
    2965 * ------------------------------------------------------------------------------
    2966 * Start function 5 -- Loctn
    2967 * ------------------------------------------------------------------------------
    2968 *
    2969 *    if (ip->idhfnc[5].idftmd & I_TM_KEY) {
    2970 *
     2963
     2964                .page
     2965| ------------------------------------------------------------------------------
     2966| Start function 5 -- Loctn
     2967| ------------------------------------------------------------------------------
     2968
     2969|    if (ip->idhfnc[5].idftmd & I_TM_KEY) {
     2970
    29712971FN05:           move.l  IP(A6),A0
    29722972                move.b  153(A0),D0
     
    29752975                btst    #0,D0
    29762976                bne     FN05A
    2977 *
     2977
    29782978                jmp     FN06
    2979 *
    2980 *       vp = (vce << 4) + 4;
    2981 *
     2979
     2980|       vp = (vce << 4) + 4;
     2981
    29822982FN05A:          move    VCE(A6),D0
    29832983                asl     #4,D0
    29842984                add.w   #4,D0
    29852985                move    D0,VP(A6)
    2986 *
    2987 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    2988 *
     2986
     2987|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     2988
    29892989                asl     #5,D0
    29902990                ext.l   D0
    29912991                move.l  D0,A_FPU
    2992                 add.l   #_io_fpu+$4000,A_FPU
    2993 *
    2994 *       fp = &ip->idhfnc[5];
    2995 *
     2992                add.l   #_io_fpu+0x4000,A_FPU
     2993
     2994|       fp = &ip->idhfnc[5];
     2995
    29962996                move.l  #60,A_FP
    29972997                add.l   IP(A6),A_FP
    29982998                add.l   #86,A_FP
    2999 *
    3000 *       pt = &ip->idhpnt[fp->idfpt1];
    3001 *
     2999
     3000|       pt = &ip->idhpnt[fp->idfpt1];
     3001
    30023002                clr.l   D0
    30033003                move.b  6(A_FP),D0
     
    30093009                add.l   #242,D0
    30103010                move.l  D0,PT(A6)
    3011 *
    3012                 .page
    3013 *
    3014 *       srcnum = group | fp->idfsrc;
    3015 *
     3011
     3012                .page
     3013
     3014|       srcnum = group | fp->idfsrc;
     3015
    30163016                move.w  GROUP(A6),D0
    30173017                ext.l   D0
     
    30203020                or      D1,D0
    30213021                move    D0,SRCNUM(A6)
    3022 *
    3023 *       vep = &valents[srcnum];
    3024 *
     3022
     3023|       vep = &valents[srcnum];
     3024
    30253025                add.l   D0,D0
    30263026                move.l  D0,D1
     
    30293029                add.l   #_valents,D0
    30303030                move.l  D0,VEP(A6)
    3031 *
    3032 *       smp = vpsms[vp];
    3033 *
     3031
     3032|       smp = vpsms[vp];
     3033
    30343034                move    VP(A6),A0
    30353035                add.l   A0,A0
     
    30373037                add.l   #_vpsms,A0
    30383038                move.l  (A0),A_SMP
    3039 *
    3040 *       if (srcnum NE smp->sm) {
    3041 *
     3039
     3040|       if (srcnum NE smp->sm) {
     3041
    30423042                clr     D0
    30433043                move    10(A_SMP),D0
    30443044                cmp     SRCNUM(A6),D0
    30453045                beq     F05L113
    3046 *
    3047 *               (smp->prv)->nxt = smp->nxt;
    3048 *
     3046
     3047|               (smp->prv)->nxt = smp->nxt;
     3048
    30493049                move.l  4(A_SMP),A0
    30503050                move.l  (A_SMP),(A0)
    3051 *
    3052 *               (smp->nxt)->prv = smp->prv;
    3053 *
     3051
     3052|               (smp->nxt)->prv = smp->prv;
     3053
    30543054                move.l  (A_SMP),A0
    30553055                move.l  4(A_SMP),4(A0)
    3056 *
    3057 *               smp->prv = (struct sment *)vep;
    3058 *
     3056
     3057|               smp->prv = (struct sment |)vep;
     3058
    30593059                move.l  VEP(A6),4(A_SMP)
    3060 *
    3061 *               smp->nxt = vep->nxt;
    3062 *
     3060
     3061|               smp->nxt = vep->nxt;
     3062
    30633063                move.l  VEP(A6),A0
    30643064                move.l  (A0),(A_SMP)
    3065 *
    3066 *               (vep->nxt)->prv = smp;
    3067 *
     3065
     3066|               (vep->nxt)->prv = smp;
     3067
    30683068                move.l  VEP(A6),A0
    30693069                move.l  (A0),A0
    30703070                move.l  A_SMP,4(A0)
    3071 *
    3072 *               vep->nxt = smp;
    3073 *
     3071
     3072|               vep->nxt = smp;
     3073
    30743074                move.l  VEP(A6),A0
    30753075                move.l  A_SMP,(A0)
    3076 *
    3077 *               smp->sm = srcnum;
    3078 *
     3076
     3077|               smp->sm = srcnum;
     3078
    30793079                move    SRCNUM(A6),10(A_SMP)
    3080 *
    3081 *       }
    3082 *
    3083 *       mltval = fp->idfmlt;
    3084 *
     3080
     3081|       }
     3082
     3083|       mltval = fp->idfmlt;
     3084
    30853085F05L113:        move    2(A_FP),MLTVAL(A6)
    3086 *
    3087                 .page
    3088 *
    3089 *       switch (fp->idfsrc) {
    3090 *
     3086
     3087                .page
     3088
     3089|       switch (fp->idfsrc) {
     3090
    30913091                move.b  4(A_FP),D0
    30923092                ext.w   d0
    30933093                cmp     #10,D0
    30943094                bhi     F05L122
    3095 *
     3095
    30963096                asl     #2,D0
    30973097                lea     F05L123,A0
    30983098                movea.l 0(A0,D0.W),A0
    30993099                jmp     (A0)
    3100 *
    3101 *       case SM_NONE:
    3102 *               mltval = 0;
    3103 *
     3100
     3101|       case SM_NONE:
     3102|               mltval = 0;
     3103
    31043104F05L116:        clr     MLTVAL(A6)
    3105 *
    3106 *               tsrcval = 0;
    3107 *
     3105
     3106|               tsrcval = 0;
     3107
    31083108                clr     TSRCVAL(A6)
    3109 *
    3110 *               break;
    3111 *
     3109
     3110|               break;
     3111
    31123112                bra     F05L114
    3113 *
    3114 *       case SM_RAND:
    3115 *               tsrcval = xgetran(mltval);
    3116 *
     3113
     3114|       case SM_RAND:
     3115|               tsrcval = xgetran(mltval);
     3116
    31173117F05L117:        move    MLTVAL(A6),(sp)
    31183118                jsr     _xgetran
    31193119                move    D0,TSRCVAL(A6)
    3120 *
    3121 *               break;
    3122 *
     3120
     3121|               break;
     3122
    31233123                bra     F05L114
    3124 *
    3125 *       case SM_PTCH:
    3126 *               tsrcval = pch;
    3127 *
     3124
     3125|       case SM_PTCH:
     3126|               tsrcval = pch;
     3127
    31283128F05L118:        move    PCH(A6),TSRCVAL(A6)
    3129 *
    3130 *               break;
    3131 *
     3129
     3130|               break;
     3131
    31323132                bra     F05L114
    3133 *
    3134                 .page
    3135 *
    3136 *       case SM_FREQ:
    3137 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    3138 *
     3133
     3134                .page
     3135
     3136|       case SM_FREQ:
     3137|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     3138
    31393139F05L119:        move    PCH(A6),D0
    31403140                asr     #7,D0
     
    31443144                add.l   #_ptoftab,A0
    31453145                move    (A0),TSRCVAL(A6)
    3146 *
    3147 *               break;
    3148 *
     3146
     3147|               break;
     3148
    31493149                bra     F05L114
    3150 *
    3151 *       case SM_KVEL:
    3152 *               tsrcval = veltab[trg];
    3153 *
     3150
     3151|       case SM_KVEL:
     3152|               tsrcval = veltab[trg];
     3153
    31543154F05L120:        move    TRG(A6),A0
    31553155                add.l   A0,A0
    31563156                add.l   #_veltab,A0
    31573157                move    (A0),TSRCVAL(A6)
    3158 *
    3159 *               break;
    3160 *
     3158
     3159|               break;
     3160
    31613161                bra     F05L114
    3162 *
    3163 *       case SM_KPRS:
    3164 *               tsrcval = prstab[trg];
    3165 *
     3162
     3163|       case SM_KPRS:
     3164|               tsrcval = prstab[trg];
     3165
    31663166F05L121:        move    TRG(A6),A0
    31673167                add.l   A0,A0
    31683168                add.l   #_prstab,A0
    31693169                move    (A0),TSRCVAL(A6)
    3170 *
    3171 *               break;
    3172 *
     3170
     3171|               break;
     3172
    31733173                bra     F05L114
    3174 *
    3175 *       default:
    3176 *               tsrcval = vep->val;
    3177 *
     3174
     3175|       default:
     3176|               tsrcval = vep->val;
     3177
    31783178F05L122:        move.l  VEP(A6),A0
    31793179                move    8(A0),TSRCVAL(A6)
    3180 *
    3181 *       }
    3182 *
    3183                 .page
    3184 *
    3185 *               srcval = tsrcval;
    3186 *
     3180
     3181|       }
     3182
     3183                .page
     3184
     3185|               srcval = tsrcval;
     3186
    31873187F05L114:        move    TSRCVAL(A6),SRCVAL(A6)
    3188 *
    3189                 .page
    3190 *
    3191 *       if (pt->ipvsrc) {
    3192 *
     3188
     3189                .page
     3190
     3191|       if (pt->ipvsrc) {
     3192
    31933193F05L124:        move.l  PT(A6),A0
    31943194                tst.b   6(A0)
    31953195                beq     F05L136
    3196 *
    3197 *               switch (pt->ipvsrc) {
    3198 *
     3196
     3197|               switch (pt->ipvsrc) {
     3198
    31993199                move.l  PT(A6),A0
    32003200                move.b  6(A0),D0
     
    32033203                cmp     #9,D0
    32043204                bhi     F05L144
    3205 *
     3205
    32063206                asl     #2,D0
    32073207                lea     F05L145,A0
    32083208                move.l  0(A0,D0.W),A0
    32093209                jmp     (A0)
    3210 *
    3211 *               case SM_RAND:
    3212 *                       ltmp = xgetran(pt_>ipvmlt);
    3213 *
     3210
     3211|               case SM_RAND:
     3212|                       ltmp = xgetran(pt_>ipvmlt);
     3213
    32143214F05L139:        move.l  PT(A6),A0
    32153215                move    4(A0),(sp)
     
    32173217                ext.l   D0
    32183218                move.l  D0,LTMP(A6)
    3219 *
    3220 *                       break;
    3221 *
     3219
     3220|                       break;
     3221
    32223222                bra     F05L137
    3223 *
    3224 *               case SM_PTCH:
    3225 *                       ltmp = pch;
    3226 *
     3223
     3224|               case SM_PTCH:
     3225|                       ltmp = pch;
     3226
    32273227F05L140:        move    PCH(A6),A0
    32283228                move.l  A0,LTMP(A6)
    3229 *
    3230 *                       break;
    3231 *
     3229
     3230|                       break;
     3231
    32323232                bra     F05L137
    3233 *
    3234                 .page
    3235 *
    3236 *               case SM_FREQ:
    3237 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    3238 *
     3233
     3234                .page
     3235
     3236|               case SM_FREQ:
     3237|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     3238
    32393239F05L141:        move    PCH(A6),D0
    32403240                asr     #7,D0
     
    32463246                ext.l   D0
    32473247                move.l  D0,LTMP(A6)
    3248 *
    3249 *                       break;
    3250 *
     3248
     3249|                       break;
     3250
    32513251                bra     F05L137
    3252 *
    3253 *               case SM_KVEL:
    3254 *                       ltmp = veltab[trg];
    3255 *
     3252
     3253|               case SM_KVEL:
     3254|                       ltmp = veltab[trg];
     3255
    32563256F05L142:        move    TRG(A6),A0
    32573257                add.l   A0,A0
     
    32603260                ext.l   D0
    32613261                move.l  D0,LTMP(A6)
    3262 *
    3263 *                       break;
    3264 *
     3262
     3263|                       break;
     3264
    32653265                bra     F05L137
    3266 *
    3267                 .page
    3268 *
    3269 *               case SM_KPRS:
    3270 *                       ltmp = prstab[trg];
    3271 *
     3266
     3267                .page
     3268
     3269|               case SM_KPRS:
     3270|                       ltmp = prstab[trg];
     3271
    32723272F05L143:        move    TRG(A6),A0
    32733273                add.l   A0,A0
     
    32763276                ext.l   D0
    32773277                move.l  D0,LTMP(A6)
    3278 *
    3279 *                       break;
    3280 *
     3278
     3279|                       break;
     3280
    32813281                bra     F05L137
    3282 *
    3283                 .page
    3284 *
    3285 *               default:
    3286 *                       ltmp = valents[group | pt->ipvsrc].val;
    3287 *
     3282
     3283                .page
     3284
     3285|               default:
     3286|                       ltmp = valents[group | pt->ipvsrc].val;
     3287
    32883288F05L144:        move.l  PT(A6),A0
    32893289                clr.l   D0
     
    32993299                move    8(A0,A1.l),D0
    33003300                move.l  D0,LTMP(A6)
    3301 *
    3302 *               }
    3303 *
    3304 *
    3305                 .page
    3306 *
    3307 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    3308 *
     3301
     3302|               }
     3303
     3304
     3305                .page
     3306
     3307|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     3308
    33093309F05L137:        move.l  PT(A6),A0
    33103310                move.w  4(A0),D0
     
    33143314                asr.l   D1,D0
    33153315                move.l  D0,LTMP(A6)
    3316 *
    3317 *               ltmp += (long)pt->ipval;
    3318 *
     3316
     3317|               ltmp += (long)pt->ipval;
     3318
    33193319                move.l  PT(A6),A0
    33203320                move    2(A0),D0
    33213321                ext.l   D0
    33223322                add.l   D0,LTMP(A6)
    3323 *
    3324 *               if (ltmp GT (long)VALMAX)
    3325 *                       ltmp = (long)VALMAX;
    3326 *
     3323
     3324|               if (ltmp GT (long)VALMAX)
     3325|                       ltmp = (long)VALMAX;
     3326
    33273327                cmp.l   #VALMAX,LTMP(A6)
    33283328                ble     F05L146
    3329 *
     3329
    33303330                move.l  #VALMAX,LTMP(A6)
    33313331                bra     F05L147
    3332 *
    3333 *               else if (ltmp LT (long)VALMIN)
    3334 *                       ltmp = (long)VALMIN;
    3335 *
     3332
     3333|               else if (ltmp LT (long)VALMIN)
     3334|                       ltmp = (long)VALMIN;
     3335
    33363336F05L146:        cmp.l   #VALMIN,LTMP(A6)
    33373337                bge     F05L147
    3338 *
     3338
    33393339                move.l  #VALMIN,LTMP(A6)
    3340 *
    3341 *               tfpval = (short)ltmp;
    3342 *
     3340
     3341|               tfpval = (short)ltmp;
     3342
    33433343F05L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    33443344                bra     F05L149
    3345 *
    3346 *       } else {
    3347 *
    3348 *               tfpval = pt->ipval;
    3349 *
     3345
     3346|       } else {
     3347
     3348|               tfpval = pt->ipval;
     3349
    33503350F05L136:        move.l  PT(A6),A0
    33513351                move    2(A0),TFPVAL(A6)
    3352 *
    3353 *       }
    3354 *
    3355                 .page
    3356 *
    3357 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    3358 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    3359 *
     3352
     3353|       }
     3354
     3355                .page
     3356
     3357|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     3358|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     3359
    33603360F05L149:        move.l  PT(A6),A0
    33613361                move.w  (A0),D0
    33623362                move.w  D0,D2
    3363                 andi.w  #$FFF0,D0
     3363                andi.w  #0xFFF0,D0
    33643364                move.w  _timemlt,D1
    33653365                muls    D1,D0
     
    33673367                asr.l   D1,D0
    33683368                move    D0,R_FPMANT
    3369 *
    3370 *       fpexp = expbit[pt->iptim & 0x000F];
    3371 *
    3372                 and     #$000F,D2
     3369
     3370|       fpexp = expbit[pt->iptim & 0x000F];
     3371
     3372                and     #0x000F,D2
    33733373                move    D2,A0
    33743374                add.l   A0,A0
    33753375                add.l   #_expbit,A0
    33763376                move    (A0),R_FPEXP
    3377 *
    3378                 .page
    3379 *
    3380 *               fp->idfpch = pch;
    3381 *
     3377
     3378                .page
     3379
     3380|               fp->idfpch = pch;
     3381
    33823382F05L163:        move    PCH(A6),(A_FP)
    3383 *
    3384 *               if (tfpval > VALMAX)
    3385 *                       tfpval = VALMAX;
    3386 *               else if (tfpval < 0)
    3387 *                       tfpval = 0;
    3388 *
     3383
     3384|               if (tfpval > VALMAX)
     3385|                       tfpval = VALMAX;
     3386|               else if (tfpval < 0)
     3387|                       tfpval = 0;
     3388
    33893389                move.w  TFPVAL(A6),D0
    3390                 cmp.w   #$7D00,D0
     3390                cmp.w   #0x7D00,D0
    33913391                ble     F05L163B
    3392 *
    3393                 move.w  #$7D00,D0
     3392
     3393                move.w  #0x7D00,D0
    33943394                bra     F05L163A
    3395                
     3395
    33963396F05L163B:       tst.w   D0
    33973397                bpl     F05L163A
    3398 *
     3398
    33993399                clr.w   D0
    3400 *
    3401 *#if    LOC_EOR
    3402 *               fpval = (tfpval << 1) ^ 0x8000;
    3403 *#endif
    3404 *
     3400
     3401|#if    LOC_EOR
     3402|               fpval = (tfpval << 1) ^ 0x8000;
     3403|#endif
     3404
    34053405                .ifne   LOC_EOR
    34063406F05L163A:       add.w   D0,D0
    3407                 eor.w   #$8000,D0
     3407                eor.w   #0x8000,D0
    34083408                .endc
    3409 *
    3410 *#if    LOC_SUB
    3411 *               fpval = ((tfpval >> 5) - 500) << 6;
    3412 *#endif
    3413 *
     3409
     3410|#if    LOC_SUB
     3411|               fpval = ((tfpval >> 5) - 500) << 6;
     3412|#endif
     3413
    34143414                .ifne   LOC_SUB
    34153415F05L163A:       asr.w   #5,D0
     
    34173417                asl.w   #6,D0
    34183418                .endc
    3419 *
     3419
    34203420                move.w  D0,R_FPVAL
    3421 *
    3422                 .page
    3423 *
     3421
     3422                .page
     3423
    34243424                move.b  5(A_FP),D0
    34253425                ext.w   D0
    34263426                sub.w   #1,D0
    34273427                movea.l PT(A6),A0
    3428 *
    3429 *       oldi = setipl(FPU_DI);
    3430 *
     3428
     3429|       oldi = setipl(FPU_DI);
     3430
    34313431                move    sr,OLDI(A6)
    34323432                move    #FPU_DI,sr
    3433 *
     3433
    34343434F05L168:        clr.b   10(A0)
    34353435                add.l   #12,a0
    34363436                dbra    D0,F05L168
    3437 *
    3438                 .page
    3439 *
    3440 *       fp->idftmd ^= I_NVBITS;
    3441 *
     3437
     3438                .page
     3439
     3440|       fp->idftmd ^= I_NVBITS;
     3441
    34423442F05L165:        eor.b   #24,7(A_FP)
    3443 *
    3444 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    3445 *
     3443
     3444|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     3445
    34463446                move.b  7(A_FP),R_FPCTL
    34473447                and     #28,R_FPCTL
    34483448                or      #3,R_FPCTL
    3449 *
    3450 *       fp->idfcpt = fp->idfpt1;
    3451 *
     3449
     3450|       fp->idfcpt = fp->idfpt1;
     3451
    34523452                move.b  6(A_FP),8(A_FP)
    3453 *
    3454 *       fp->idftmd |= I_ACTIVE;
    3455 *
     3453
     3454|       fp->idftmd |= I_ACTIVE;
     3455
    34563456                or.b    #2,7(A_FP)
    3457 *
    3458 *       fp->idftrf = trg;
    3459 *
     3457
     3458|       fp->idftrf = trg;
     3459
    34603460                move    TRG(A6),10(A_FP)
    3461 *
    3462 *       *(fpu + (long)FPU_TCV1) = srcval;
    3463 *
    3464                 move    SRCVAL(A6),$8(A_FPU)
    3465 *
    3466 *       ++octype;
    3467 *
     3461
     3462|       |(fpu + (long)FPU_TCV1) = srcval;
     3463
     3464                move    SRCVAL(A6),0x8(A_FPU)
     3465
     3466|       ++octype;
     3467
    34683468                add     #1,OCTYPE(A6)
    3469 *
    3470 *       *(fpu + (long)FPU_TSF1) = mltval;
    3471 *
    3472                 move    MLTVAL(A6),$A(A_FPU)
    3473 *
    3474 *       ++octype;
    3475 *
     3469
     3470|       |(fpu + (long)FPU_TSF1) = mltval;
     3471
     3472                move    MLTVAL(A6),0xA(A_FPU)
     3473
     3474|       ++octype;
     3475
    34763476                add     #1,OCTYPE(A6)
    3477 *
    3478 *       *(fpu + (long)FPU_TMNT) = fpmant;
    3479 *
    3480                 move    R_FPMANT,$14(A_FPU)
    3481 *
    3482 *       ++octype;
    3483 *
     3477
     3478|       |(fpu + (long)FPU_TMNT) = fpmant;
     3479
     3480                move    R_FPMANT,0x14(A_FPU)
     3481
     3482|       ++octype;
     3483
    34843484                add     #1,OCTYPE(A6)
    3485 *
    3486 *       *(fpu + (long)FPU_TEXP) = fpexp;
    3487 *
    3488                 move    R_FPEXP,$16(A_FPU)
    3489 *
    3490 *       ++octype;
    3491 *
     3485
     3486|       |(fpu + (long)FPU_TEXP) = fpexp;
     3487
     3488                move    R_FPEXP,0x16(A_FPU)
     3489
     3490|       ++octype;
     3491
    34923492                add     #1,OCTYPE(A6)
    3493 *
    3494                 .page
    3495 *
    3496 *       if (fp->idftmd & I_VNSUBN)
    3497 *
     3493
     3494                .page
     3495
     3496|       if (fp->idftmd & I_VNSUBN)
     3497
    34983498                btst    #3,7(A_FP)
    34993499                beq     F05L169
    3500 *
    3501 *               *(fpu + (long)FPU_TNV1) = fpval;
    3502 *
    3503                 move    R_FPVAL,$1C(A_FPU)
     3500
     3501|               |(fpu + (long)FPU_TNV1) = fpval;
     3502
     3503                move    R_FPVAL,0x1C(A_FPU)
    35043504                bra     F05L170
    3505 *
    3506 *       else
    3507 *               *(fpu + (long)FPU_TNV0) = fpval;
    3508 *
     3505
     3506|       else
     3507|               |(fpu + (long)FPU_TNV0) = fpval;
     3508
    35093509F05L169:        move    R_FPVAL,2(A_FPU)
    3510 *
    3511 *       ++octype;
    3512 *
     3510
     3511|       ++octype;
     3512
    35133513F05L170:        add     #1,OCTYPE(A6)
    3514 *
    3515 *       *(fpu + (long)FPU_TCTL) = fpctl;
    3516 *
     3514
     3515|       |(fpu + (long)FPU_TCTL) = fpctl;
     3516
    35173517                move    R_FPCTL,(A_FPU)
    3518 *
    3519 *       setipl(oldi);
    3520 *
     3518
     3519|       setipl(oldi);
     3520
    35213521                move    OLDI(A6),sr
    3522 *
    3523                 .page
    3524 * ------------------------------------------------------------------------------
    3525 * Start function 6 -- Ind 1
    3526 * ------------------------------------------------------------------------------
    3527 *
    3528 *    if (ip->idhfnc[2].idftmd & I_TM_KEY) {
    3529 *
     3522
     3523                .page
     3524| ------------------------------------------------------------------------------
     3525| Start function 6 -- Ind 1
     3526| ------------------------------------------------------------------------------
     3527
     3528|    if (ip->idhfnc[2].idftmd & I_TM_KEY) {
     3529
    35303530FN06:           move.l  IP(A6),A0
    35313531                move.b  165(A0),D0
     
    35343534                btst    #0,D0
    35353535                bne     FN06A
    3536 *
     3536
    35373537                jmp     FN07
    3538 *
    3539 *       vp = (vce << 4) + 9;
    3540 *
     3538
     3539|       vp = (vce << 4) + 9;
     3540
    35413541FN06A:          move    VCE(A6),D0
    35423542                asl     #4,D0
    35433543                add.w   #9,D0
    35443544                move    D0,VP(A6)
    3545 *
    3546 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    3547 *
     3545
     3546|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     3547
    35483548                asl     #5,D0
    35493549                ext.l   D0
    35503550                move.l  D0,A_FPU
    3551                 add.l   #_io_fpu+$4000,A_FPU
    3552 *
    3553 *       fp = &ip->idhfnc[6];
    3554 *
     3551                add.l   #_io_fpu+0x4000,A_FPU
     3552
     3553|       fp = &ip->idhfnc[6];
     3554
    35553555                move.l  #72,A_FP
    35563556                add.l   IP(A6),A_FP
    35573557                add.l   #86,A_FP
    3558 *
    3559 *       pt = &ip->idhpnt[fp->idfpt1];
    3560 *
     3558
     3559|       pt = &ip->idhpnt[fp->idfpt1];
     3560
    35613561                clr.l   D0
    35623562                move.b  6(A_FP),D0
     
    35683568                add.l   #242,D0
    35693569                move.l  D0,PT(A6)
    3570 *
    3571                 .page
    3572 *
    3573 *       srcnum = group | fp->idfsrc;
    3574 *
     3570
     3571                .page
     3572
     3573|       srcnum = group | fp->idfsrc;
     3574
    35753575                move.w  GROUP(A6),D0
    35763576                ext.l   D0
     
    35793579                or      D1,D0
    35803580                move    D0,SRCNUM(A6)
    3581 *
    3582 *       vep = &valents[srcnum];
    3583 *
     3581
     3582|       vep = &valents[srcnum];
     3583
    35843584                add.l   D0,D0
    35853585                move.l  D0,D1
     
    35883588                add.l   #_valents,D0
    35893589                move.l  D0,VEP(A6)
    3590 *
    3591 *       smp = vpsms[vp];
    3592 *
     3590
     3591|       smp = vpsms[vp];
     3592
    35933593                move    VP(A6),A0
    35943594                add.l   A0,A0
     
    35963596                add.l   #_vpsms,A0
    35973597                move.l  (A0),A_SMP
    3598 *
    3599 *       if (srcnum NE smp->sm) {
    3600 *
     3598
     3599|       if (srcnum NE smp->sm) {
     3600
    36013601                clr     D0
    36023602                move    10(A_SMP),D0
    36033603                cmp     SRCNUM(A6),D0
    36043604                beq     F06L113
    3605 *
    3606 *               (smp->prv)->nxt = smp->nxt;
    3607 *
     3605
     3606|               (smp->prv)->nxt = smp->nxt;
     3607
    36083608                move.l  4(A_SMP),A0
    36093609                move.l  (A_SMP),(A0)
    3610 *
    3611 *               (smp->nxt)->prv = smp->prv;
    3612 *
     3610
     3611|               (smp->nxt)->prv = smp->prv;
     3612
    36133613                move.l  (A_SMP),A0
    36143614                move.l  4(A_SMP),4(A0)
    3615 *
    3616 *               smp->prv = (struct sment *)vep;
    3617 *
     3615
     3616|               smp->prv = (struct sment |)vep;
     3617
    36183618                move.l  VEP(A6),4(A_SMP)
    3619 *
    3620 *               smp->nxt = vep->nxt;
    3621 *
     3619
     3620|               smp->nxt = vep->nxt;
     3621
    36223622                move.l  VEP(A6),A0
    36233623                move.l  (A0),(A_SMP)
    3624 *
    3625 *               (vep->nxt)->prv = smp;
    3626 *
     3624
     3625|               (vep->nxt)->prv = smp;
     3626
    36273627                move.l  VEP(A6),A0
    36283628                move.l  (A0),A0
    36293629                move.l  A_SMP,4(A0)
    3630 *
    3631 *               vep->nxt = smp;
    3632 *
     3630
     3631|               vep->nxt = smp;
     3632
    36333633                move.l  VEP(A6),A0
    36343634                move.l  A_SMP,(A0)
    3635 *
    3636 *               smp->sm = srcnum;
    3637 *
     3635
     3636|               smp->sm = srcnum;
     3637
    36383638                move    SRCNUM(A6),10(A_SMP)
    3639 *
    3640 *       }
    3641 *
    3642 *       mltval = fp->idfmlt;
    3643 *
     3639
     3640|       }
     3641
     3642|       mltval = fp->idfmlt;
     3643
    36443644F06L113:        move    2(A_FP),MLTVAL(A6)
    3645 *
    3646                 .page
    3647 *
    3648 *       switch (fp->idfsrc) {
    3649 *
     3645
     3646                .page
     3647
     3648|       switch (fp->idfsrc) {
     3649
    36503650                move.b  4(A_FP),D0
    36513651                ext.w   d0
    36523652                cmp     #10,D0
    36533653                bhi     F06L122
    3654 *
     3654
    36553655                asl     #2,D0
    36563656                lea     F06L123,A0
    36573657                movea.l 0(A0,D0.W),A0
    36583658                jmp     (A0)
    3659 *
    3660 *       case SM_NONE:
    3661 *               mltval = 0;
    3662 *
     3659
     3660|       case SM_NONE:
     3661|               mltval = 0;
     3662
    36633663F06L116:        clr     MLTVAL(A6)
    3664 *
    3665 *               tsrcval = 0;
    3666 *
     3664
     3665|               tsrcval = 0;
     3666
    36673667                clr     TSRCVAL(A6)
    3668 *
    3669 *               break;
    3670 *
     3668
     3669|               break;
     3670
    36713671                bra     F06L114
    3672 *
    3673 *       case SM_RAND:
    3674 *               tsrcval = xgetran(mltval);
    3675 *
     3672
     3673|       case SM_RAND:
     3674|               tsrcval = xgetran(mltval);
     3675
    36763676F06L117:        move    MLTVAL(A6),(sp)
    36773677                jsr     _xgetran
    36783678                move    D0,TSRCVAL(A6)
    3679 *
    3680 *               break;
    3681 *
     3679
     3680|               break;
     3681
    36823682                bra     F06L114
    3683 *
    3684 *       case SM_PTCH:
    3685 *               tsrcval = pch;
    3686 *
     3683
     3684|       case SM_PTCH:
     3685|               tsrcval = pch;
     3686
    36873687F06L118:        move    PCH(A6),TSRCVAL(A6)
    3688 *
    3689 *               break;
    3690 *
     3688
     3689|               break;
     3690
    36913691                bra     F06L114
    3692 *
    3693                 .page
    3694 *
    3695 *       case SM_FREQ:
    3696 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    3697 *
     3692
     3693                .page
     3694
     3695|       case SM_FREQ:
     3696|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     3697
    36983698F06L119:        move    PCH(A6),D0
    36993699                asr     #7,D0
     
    37033703                add.l   #_ptoftab,A0
    37043704                move    (A0),TSRCVAL(A6)
    3705 *
    3706 *               break;
    3707 *
     3705
     3706|               break;
     3707
    37083708                bra     F06L114
    3709 *
    3710 *       case SM_KVEL:
    3711 *               tsrcval = veltab[trg];
    3712 *
     3709
     3710|       case SM_KVEL:
     3711|               tsrcval = veltab[trg];
     3712
    37133713F06L120:        move    TRG(A6),A0
    37143714                add.l   A0,A0
    37153715                add.l   #_veltab,A0
    37163716                move    (A0),TSRCVAL(A6)
    3717 *
    3718 *               break;
    3719 *
     3717
     3718|               break;
     3719
    37203720                bra     F06L114
    3721 *
    3722 *       case SM_KPRS:
    3723 *               tsrcval = prstab[trg];
    3724 *
     3721
     3722|       case SM_KPRS:
     3723|               tsrcval = prstab[trg];
     3724
    37253725F06L121:        move    TRG(A6),A0
    37263726                add.l   A0,A0
    37273727                add.l   #_prstab,A0
    37283728                move    (A0),TSRCVAL(A6)
    3729 *
    3730 *               break;
    3731 *
     3729
     3730|               break;
     3731
    37323732                bra     F06L114
    3733 *
    3734 *       default:
    3735 *               tsrcval = vep->val;
    3736 *
     3733
     3734|       default:
     3735|               tsrcval = vep->val;
     3736
    37373737F06L122:        move.l  VEP(A6),A0
    37383738                move    8(A0),TSRCVAL(A6)
    3739 *
    3740 *       }
    3741 *
    3742                 .page
    3743 *
    3744 *               srcval = tsrcval;
    3745 *
     3739
     3740|       }
     3741
     3742                .page
     3743
     3744|               srcval = tsrcval;
     3745
    37463746F06L114:        move    TSRCVAL(A6),SRCVAL(A6)
    3747 *
    3748                 .page
    3749 *
    3750 *       if (pt->ipvsrc) {
    3751 *
     3747
     3748                .page
     3749
     3750|       if (pt->ipvsrc) {
     3751
    37523752F06L124:        move.l  PT(A6),A0
    37533753                tst.b   6(A0)
    37543754                beq     F06L136
    3755 *
    3756 *               switch (pt->ipvsrc) {
    3757 *
     3755
     3756|               switch (pt->ipvsrc) {
     3757
    37583758                move.l  PT(A6),A0
    37593759                move.b  6(A0),D0
     
    37623762                cmp     #9,D0
    37633763                bhi     F06L144
    3764 *
     3764
    37653765                asl     #2,D0
    37663766                lea     F06L145,A0
    37673767                move.l  0(A0,D0.W),A0
    37683768                jmp     (A0)
    3769 *
    3770 *               case SM_RAND:
    3771 *                       ltmp = xgetran(pt_>ipvmlt);
    3772 *
     3769
     3770|               case SM_RAND:
     3771|                       ltmp = xgetran(pt_>ipvmlt);
     3772
    37733773F06L139:        move.l  PT(A6),A0
    37743774                move    4(A0),(sp)
     
    37763776                ext.l   D0
    37773777                move.l  D0,LTMP(A6)
    3778 *
    3779 *                       break;
    3780 *
     3778
     3779|                       break;
     3780
    37813781                bra     F06L137
    3782 *
    3783 *               case SM_PTCH:
    3784 *                       ltmp = pch;
    3785 *
     3782
     3783|               case SM_PTCH:
     3784|                       ltmp = pch;
     3785
    37863786F06L140:        move    PCH(A6),A0
    37873787                move.l  A0,LTMP(A6)
    3788 *
    3789 *                       break;
    3790 *
     3788
     3789|                       break;
     3790
    37913791                bra     F06L137
    3792 *
    3793                 .page
    3794 *
    3795 *               case SM_FREQ:
    3796 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    3797 *
     3792
     3793                .page
     3794
     3795|               case SM_FREQ:
     3796|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     3797
    37983798F06L141:        move    PCH(A6),D0
    37993799                asr     #7,D0
     
    38053805                ext.l   D0
    38063806                move.l  D0,LTMP(A6)
    3807 *
    3808 *                       break;
    3809 *
     3807
     3808|                       break;
     3809
    38103810                bra     F06L137
    3811 *
    3812 *               case SM_KVEL:
    3813 *                       ltmp = veltab[trg];
    3814 *
     3811
     3812|               case SM_KVEL:
     3813|                       ltmp = veltab[trg];
     3814
    38153815F06L142:        move    TRG(A6),A0
    38163816                add.l   A0,A0
     
    38193819                ext.l   D0
    38203820                move.l  D0,LTMP(A6)
    3821 *
    3822 *                       break;
    3823 *
     3821
     3822|                       break;
     3823
    38243824                bra     F06L137
    3825 *
    3826                 .page
    3827 *
    3828 *               case SM_KPRS:
    3829 *                       ltmp = prstab[trg];
    3830 *
     3825
     3826                .page
     3827
     3828|               case SM_KPRS:
     3829|                       ltmp = prstab[trg];
     3830
    38313831F06L143:        move    TRG(A6),A0
    38323832                add.l   A0,A0
     
    38353835                ext.l   D0
    38363836                move.l  D0,LTMP(A6)
    3837 *
    3838 *                       break;
    3839 *
     3837
     3838|                       break;
     3839
    38403840                bra     F06L137
    3841 *
    3842                 .page
    3843 *
    3844 *               default:
    3845 *                       ltmp = valents[group | pt->ipvsrc].val;
    3846 *
     3841
     3842                .page
     3843
     3844|               default:
     3845|                       ltmp = valents[group | pt->ipvsrc].val;
     3846
    38473847F06L144:        move.l  PT(A6),A0
    38483848                clr.l   D0
     
    38583858                move    8(A0,A1.l),D0
    38593859                move.l  D0,LTMP(A6)
    3860 *
    3861 *               }
    3862 *
    3863 *
    3864                 .page
    3865 *
    3866 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    3867 *
     3860
     3861|               }
     3862
     3863
     3864                .page
     3865
     3866|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     3867
    38683868F06L137:        move.l  PT(A6),A0
    38693869                move.w  4(A0),D0
     
    38733873                asr.l   D1,D0
    38743874                move.l  D0,LTMP(A6)
    3875 *
    3876 *               ltmp += (long)pt->ipval;
    3877 *
     3875
     3876|               ltmp += (long)pt->ipval;
     3877
    38783878                move.l  PT(A6),A0
    38793879                move    2(A0),D0
    38803880                ext.l   D0
    38813881                add.l   D0,LTMP(A6)
    3882 *
    3883 *               if (ltmp GT (long)VALMAX)
    3884 *                       ltmp = (long)VALMAX;
    3885 *
     3882
     3883|               if (ltmp GT (long)VALMAX)
     3884|                       ltmp = (long)VALMAX;
     3885
    38863886                cmp.l   #VALMAX,LTMP(A6)
    38873887                ble     F06L146
    3888 *
     3888
    38893889                move.l  #VALMAX,LTMP(A6)
    38903890                bra     F06L147
    3891 *
    3892 *               else if (ltmp LT (long)VALMIN)
    3893 *                       ltmp = (long)VALMIN;
    3894 *
     3891
     3892|               else if (ltmp LT (long)VALMIN)
     3893|                       ltmp = (long)VALMIN;
     3894
    38953895F06L146:        cmp.l   #VALMIN,LTMP(A6)
    38963896                bge     F06L147
    3897 *
     3897
    38983898                move.l  #VALMIN,LTMP(A6)
    3899 *
    3900 *               tfpval = (short)ltmp;
    3901 *
     3899
     3900|               tfpval = (short)ltmp;
     3901
    39023902F06L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    39033903                bra     F06L149
    3904 *
    3905 *       } else {
    3906 *
    3907 *               tfpval = pt->ipval;
    3908 *
     3904
     3905|       } else {
     3906
     3907|               tfpval = pt->ipval;
     3908
    39093909F06L136:        move.l  PT(A6),A0
    39103910                move    2(A0),TFPVAL(A6)
    3911 *
    3912 *       }
    3913 *
    3914                 .page
    3915 *
    3916 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    3917 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    3918 *
     3911
     3912|       }
     3913
     3914                .page
     3915
     3916|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     3917|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     3918
    39193919F06L149:        move.l  PT(A6),A0
    39203920                move.w  (A0),D0
    39213921                move.w  D0,D2
    3922                 andi.w  #$FFF0,D0
     3922                andi.w  #0xFFF0,D0
    39233923                move.w  _timemlt,D1
    39243924                muls    D1,D0
     
    39263926                asr.l   D1,D0
    39273927                move    D0,R_FPMANT
    3928 *
    3929 *       fpexp = expbit[pt->iptim & 0x000F];
    3930 *
    3931                 and     #$000F,D2
     3928
     3929|       fpexp = expbit[pt->iptim & 0x000F];
     3930
     3931                and     #0x000F,D2
    39323932                move    D2,A0
    39333933                add.l   A0,A0
    39343934                add.l   #_expbit,A0
    39353935                move    (A0),R_FPEXP
    3936 *
    3937                 .page
    3938 *
    3939 *               fp->idfpch = pch;
    3940 *
     3936
     3937                .page
     3938
     3939|               fp->idfpch = pch;
     3940
    39413941F06L163:        move    PCH(A6),(A_FP)
    3942 *
    3943 *               fpval = tfpval;
    3944 *
     3942
     3943|               fpval = tfpval;
     3944
    39453945                move    TFPVAL(A6),R_FPVAL
    3946 *
    3947                 .page
    3948 *
     3946
     3947                .page
     3948
    39493949                move.b  5(A_FP),D0
    39503950                ext.w   D0
    39513951                sub.w   #1,D0
    39523952                movea.l PT(A6),A0
    3953 *
    3954 *       oldi = setipl(FPU_DI);
    3955 *
     3953
     3954|       oldi = setipl(FPU_DI);
     3955
    39563956                move    sr,OLDI(A6)
    39573957                move    #FPU_DI,sr
    3958 *
     3958
    39593959F06L168:        clr.b   10(A0)
    39603960                add.l   #12,a0
    39613961                dbra    D0,F06L168
    3962 *
    3963                 .page
    3964 *
    3965 *       fp->idftmd ^= I_NVBITS;
    3966 *
     3962
     3963                .page
     3964
     3965|       fp->idftmd ^= I_NVBITS;
     3966
    39673967F06L165:        eor.b   #24,7(A_FP)
    3968 *
    3969 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    3970 *
     3968
     3969|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     3970
    39713971                move.b  7(A_FP),R_FPCTL
    39723972                and     #28,R_FPCTL
    39733973                or      #3,R_FPCTL
    3974 *
    3975 *       fp->idfcpt = fp->idfpt1;
    3976 *
     3974
     3975|       fp->idfcpt = fp->idfpt1;
     3976
    39773977                move.b  6(A_FP),8(A_FP)
    3978 *
    3979 *       fp->idftmd |= I_ACTIVE;
    3980 *
     3978
     3979|       fp->idftmd |= I_ACTIVE;
     3980
    39813981                or.b    #2,7(A_FP)
    3982 *
    3983 *       fp->idftrf = trg;
    3984 *
     3982
     3983|       fp->idftrf = trg;
     3984
    39853985                move    TRG(A6),10(A_FP)
    3986 *
    3987 *       *(fpu + (long)FPU_TCV1) = srcval;
    3988 *
    3989                 move    SRCVAL(A6),$8(A_FPU)
    3990 *
    3991 *       ++octype;
    3992 *
     3986
     3987|       |(fpu + (long)FPU_TCV1) = srcval;
     3988
     3989                move    SRCVAL(A6),0x8(A_FPU)
     3990
     3991|       ++octype;
     3992
    39933993                add     #1,OCTYPE(A6)
    3994 *
    3995 *       *(fpu + (long)FPU_TSF1) = mltval;
    3996 *
    3997                 move    MLTVAL(A6),$A(A_FPU)
    3998 *
    3999 *       ++octype;
    4000 *
     3994
     3995|       |(fpu + (long)FPU_TSF1) = mltval;
     3996
     3997                move    MLTVAL(A6),0xA(A_FPU)
     3998
     3999|       ++octype;
     4000
    40014001                add     #1,OCTYPE(A6)
    4002 *
    4003 *       *(fpu + (long)FPU_TMNT) = fpmant;
    4004 *
    4005                 move    R_FPMANT,$14(A_FPU)
    4006 *
    4007 *       ++octype;
    4008 *
     4002
     4003|       |(fpu + (long)FPU_TMNT) = fpmant;
     4004
     4005                move    R_FPMANT,0x14(A_FPU)
     4006
     4007|       ++octype;
     4008
    40094009                add     #1,OCTYPE(A6)
    4010 *
    4011 *       *(fpu + (long)FPU_TEXP) = fpexp;
    4012 *
    4013                 move    R_FPEXP,$16(A_FPU)
    4014 *
    4015 *       ++octype;
    4016 *
     4010
     4011|       |(fpu + (long)FPU_TEXP) = fpexp;
     4012
     4013                move    R_FPEXP,0x16(A_FPU)
     4014
     4015|       ++octype;
     4016
    40174017                add     #1,OCTYPE(A6)
    4018 *
    4019                 .page
    4020 *
    4021 *       if (fp->idftmd & I_VNSUBN)
    4022 *
     4018
     4019                .page
     4020
     4021|       if (fp->idftmd & I_VNSUBN)
     4022
    40234023                btst    #3,7(A_FP)
    40244024                beq     F06L169
    4025 *
    4026 *               *(fpu + (long)FPU_TNV1) = fpval;
    4027 *
    4028                 move    R_FPVAL,$1C(A_FPU)
     4025
     4026|               |(fpu + (long)FPU_TNV1) = fpval;
     4027
     4028                move    R_FPVAL,0x1C(A_FPU)
    40294029                bra     F06L170
    4030 *
    4031 *       else
    4032 *               *(fpu + (long)FPU_TNV0) = fpval;
    4033 *
     4030
     4031|       else
     4032|               |(fpu + (long)FPU_TNV0) = fpval;
     4033
    40344034F06L169:        move    R_FPVAL,2(A_FPU)
    4035 *
    4036 *       ++octype;
    4037 *
     4035
     4036|       ++octype;
     4037
    40384038F06L170:        add     #1,OCTYPE(A6)
    4039 *
    4040 *       *(fpu + (long)FPU_TCTL) = fpctl;
    4041 *
     4039
     4040|       |(fpu + (long)FPU_TCTL) = fpctl;
     4041
    40424042                move    R_FPCTL,(A_FPU)
    4043 *
    4044 *       setipl(oldi);
    4045 *
     4043
     4044|       setipl(oldi);
     4045
    40464046                move    OLDI(A6),sr
    4047 *
    4048                 .page
    4049 * ------------------------------------------------------------------------------
    4050 * Start function 7 -- Ind 2
    4051 * ------------------------------------------------------------------------------
    4052 *
    4053 *    if (ip->idhfnc[7].idftmd & I_TM_KEY) {
    4054 *
     4047
     4048                .page
     4049| ------------------------------------------------------------------------------
     4050| Start function 7 -- Ind 2
     4051| ------------------------------------------------------------------------------
     4052
     4053|    if (ip->idhfnc[7].idftmd & I_TM_KEY) {
     4054
    40554055FN07:           move.l  IP(A6),A0
    40564056                move.b  177(A0),D0
     
    40594059                btst    #0,D0
    40604060                bne     FN07A
    4061 *
     4061
    40624062                jmp     FN08
    4063 *
    4064 *       vp = (vce << 4) + 11;
    4065 *
     4063
     4064|       vp = (vce << 4) + 11;
     4065
    40664066FN07A:          move    VCE(A6),D0
    40674067                asl     #4,D0
    40684068                add.w   #11,D0
    40694069                move    D0,VP(A6)
    4070 *
    4071 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    4072 *
     4070
     4071|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     4072
    40734073                asl     #5,D0
    40744074                ext.l   D0
    40754075                move.l  D0,A_FPU
    4076                 add.l   #_io_fpu+$4000,A_FPU
    4077 *
    4078 *       fp = &ip->idhfnc[7];
    4079 *
     4076                add.l   #_io_fpu+0x4000,A_FPU
     4077
     4078|       fp = &ip->idhfnc[7];
     4079
    40804080                move.l  #84,A_FP
    40814081                add.l   IP(A6),A_FP
    40824082                add.l   #86,A_FP
    4083 *
    4084 *       pt = &ip->idhpnt[fp->idfpt1];
    4085 *
     4083
     4084|       pt = &ip->idhpnt[fp->idfpt1];
     4085
    40864086                clr.l   D0
    40874087                move.b  6(A_FP),D0
     
    40934093                add.l   #242,D0
    40944094                move.l  D0,PT(A6)
    4095 *
    4096                 .page
    4097 *
    4098 *       srcnum = group | fp->idfsrc;
    4099 *
     4095
     4096                .page
     4097
     4098|       srcnum = group | fp->idfsrc;
     4099
    41004100                move.w  GROUP(A6),D0
    41014101                ext.l   D0
     
    41044104                or      D1,D0
    41054105                move    D0,SRCNUM(A6)
    4106 *
    4107 *       vep = &valents[srcnum];
    4108 *
     4106
     4107|       vep = &valents[srcnum];
     4108
    41094109                add.l   D0,D0
    41104110                move.l  D0,D1
     
    41134113                add.l   #_valents,D0
    41144114                move.l  D0,VEP(A6)
    4115 *
    4116 *       smp = vpsms[vp];
    4117 *
     4115
     4116|       smp = vpsms[vp];
     4117
    41184118                move    VP(A6),A0
    41194119                add.l   A0,A0
     
    41214121                add.l   #_vpsms,A0
    41224122                move.l  (A0),A_SMP
    4123 *
    4124 *       if (srcnum NE smp->sm) {
    4125 *
     4123
     4124|       if (srcnum NE smp->sm) {
     4125
    41264126                clr     D0
    41274127                move    10(A_SMP),D0
    41284128                cmp     SRCNUM(A6),D0
    41294129                beq     F07L113
    4130 *
    4131 *               (smp->prv)->nxt = smp->nxt;
    4132 *
     4130
     4131|               (smp->prv)->nxt = smp->nxt;
     4132
    41334133                move.l  4(A_SMP),A0
    41344134                move.l  (A_SMP),(A0)
    4135 *
    4136 *               (smp->nxt)->prv = smp->prv;
    4137 *
     4135
     4136|               (smp->nxt)->prv = smp->prv;
     4137
    41384138                move.l  (A_SMP),A0
    41394139                move.l  4(A_SMP),4(A0)
    4140 *
    4141 *               smp->prv = (struct sment *)vep;
    4142 *
     4140
     4141|               smp->prv = (struct sment |)vep;
     4142
    41434143                move.l  VEP(A6),4(A_SMP)
    4144 *
    4145 *               smp->nxt = vep->nxt;
    4146 *
     4144
     4145|               smp->nxt = vep->nxt;
     4146
    41474147                move.l  VEP(A6),A0
    41484148                move.l  (A0),(A_SMP)
    4149 *
    4150 *               (vep->nxt)->prv = smp;
    4151 *
     4149
     4150|               (vep->nxt)->prv = smp;
     4151
    41524152                move.l  VEP(A6),A0
    41534153                move.l  (A0),A0
    41544154                move.l  A_SMP,4(A0)
    4155 *
    4156 *               vep->nxt = smp;
    4157 *
     4155
     4156|               vep->nxt = smp;
     4157
    41584158                move.l  VEP(A6),A0
    41594159                move.l  A_SMP,(A0)
    4160 *
    4161 *               smp->sm = srcnum;
    4162 *
     4160
     4161|               smp->sm = srcnum;
     4162
    41634163                move    SRCNUM(A6),10(A_SMP)
    4164 *
    4165 *       }
    4166 *
    4167 *       mltval = fp->idfmlt;
    4168 *
     4164
     4165|       }
     4166
     4167|       mltval = fp->idfmlt;
     4168
    41694169F07L113:        move    2(A_FP),MLTVAL(A6)
    4170 *
    4171                 .page
    4172 *
    4173 *       switch (fp->idfsrc) {
    4174 *
     4170
     4171                .page
     4172
     4173|       switch (fp->idfsrc) {
     4174
    41754175                move.b  4(A_FP),D0
    41764176                ext.w   d0
    41774177                cmp     #10,D0
    41784178                bhi     F07L122
    4179 *
     4179
    41804180                asl     #2,D0
    41814181                lea     F07L123,A0
    41824182                movea.l 0(A0,D0.W),A0
    41834183                jmp     (A0)
    4184 *
    4185 *       case SM_NONE:
    4186 *               mltval = 0;
    4187 *
     4184
     4185|       case SM_NONE:
     4186|               mltval = 0;
     4187
    41884188F07L116:        clr     MLTVAL(A6)
    4189 *
    4190 *               tsrcval = 0;
    4191 *
     4189
     4190|               tsrcval = 0;
     4191
    41924192                clr     TSRCVAL(A6)
    4193 *
    4194 *               break;
    4195 *
     4193
     4194|               break;
     4195
    41964196                bra     F07L114
    4197 *
    4198 *       case SM_RAND:
    4199 *               tsrcval = xgetran(mltval);
    4200 *
     4197
     4198|       case SM_RAND:
     4199|               tsrcval = xgetran(mltval);
     4200
    42014201F07L117:        move    MLTVAL(A6),(sp)
    42024202                jsr     _xgetran
    42034203                move    D0,TSRCVAL(A6)
    4204 *
    4205 *               break;
    4206 *
     4204
     4205|               break;
     4206
    42074207                bra     F07L114
    4208 *
    4209 *       case SM_PTCH:
    4210 *               tsrcval = pch;
    4211 *
     4208
     4209|       case SM_PTCH:
     4210|               tsrcval = pch;
     4211
    42124212F07L118:        move    PCH(A6),TSRCVAL(A6)
    4213 *
    4214 *               break;
    4215 *
     4213
     4214|               break;
     4215
    42164216                bra     F07L114
    4217 *
    4218                 .page
    4219 *
    4220 *       case SM_FREQ:
    4221 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    4222 *
     4217
     4218                .page
     4219
     4220|       case SM_FREQ:
     4221|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     4222
    42234223F07L119:        move    PCH(A6),D0
    42244224                asr     #7,D0
     
    42284228                add.l   #_ptoftab,A0
    42294229                move    (A0),TSRCVAL(A6)
    4230 *
    4231 *               break;
    4232 *
     4230
     4231|               break;
     4232
    42334233                bra     F07L114
    4234 *
    4235 *       case SM_KVEL:
    4236 *               tsrcval = veltab[trg];
    4237 *
     4234
     4235|       case SM_KVEL:
     4236|               tsrcval = veltab[trg];
     4237
    42384238F07L120:        move    TRG(A6),A0
    42394239                add.l   A0,A0
    42404240                add.l   #_veltab,A0
    42414241                move    (A0),TSRCVAL(A6)
    4242 *
    4243 *               break;
    4244 *
     4242
     4243|               break;
     4244
    42454245                bra     F07L114
    4246 *
    4247 *       case SM_KPRS:
    4248 *               tsrcval = prstab[trg];
    4249 *
     4246
     4247|       case SM_KPRS:
     4248|               tsrcval = prstab[trg];
     4249
    42504250F07L121:        move    TRG(A6),A0
    42514251                add.l   A0,A0
    42524252                add.l   #_prstab,A0
    42534253                move    (A0),TSRCVAL(A6)
    4254 *
    4255 *               break;
    4256 *
     4254
     4255|               break;
     4256
    42574257                bra     F07L114
    4258 *
    4259 *       default:
    4260 *               tsrcval = vep->val;
    4261 *
     4258
     4259|       default:
     4260|               tsrcval = vep->val;
     4261
    42624262F07L122:        move.l  VEP(A6),A0
    42634263                move    8(A0),TSRCVAL(A6)
    4264 *
    4265 *       }
    4266 *
    4267                 .page
    4268 *
    4269 *               srcval = tsrcval;
    4270 *
     4264
     4265|       }
     4266
     4267                .page
     4268
     4269|               srcval = tsrcval;
     4270
    42714271F07L114:        move    TSRCVAL(A6),SRCVAL(A6)
    4272 *
    4273                 .page
    4274 *
    4275 *       if (pt->ipvsrc) {
    4276 *
     4272
     4273                .page
     4274
     4275|       if (pt->ipvsrc) {
     4276
    42774277F07L124:        move.l  PT(A6),A0
    42784278                tst.b   6(A0)
    42794279                beq     F07L136
    4280 *
    4281 *               switch (pt->ipvsrc) {
    4282 *
     4280
     4281|               switch (pt->ipvsrc) {
     4282
    42834283                move.l  PT(A6),A0
    42844284                move.b  6(A0),D0
     
    42874287                cmp     #9,D0
    42884288                bhi     F07L144
    4289 *
     4289
    42904290                asl     #2,D0
    42914291                lea     F07L145,A0
    42924292                move.l  0(A0,D0.W),A0
    42934293                jmp     (A0)
    4294 *
    4295 *               case SM_RAND:
    4296 *                       ltmp = xgetran(pt_>ipvmlt);
    4297 *
     4294
     4295|               case SM_RAND:
     4296|                       ltmp = xgetran(pt_>ipvmlt);
     4297
    42984298F07L139:        move.l  PT(A6),A0
    42994299                move    4(A0),(sp)
     
    43014301                ext.l   D0
    43024302                move.l  D0,LTMP(A6)
    4303 *
    4304 *                       break;
    4305 *
     4303
     4304|                       break;
     4305
    43064306                bra     F07L137
    4307 *
    4308 *               case SM_PTCH:
    4309 *                       ltmp = pch;
    4310 *
     4307
     4308|               case SM_PTCH:
     4309|                       ltmp = pch;
     4310
    43114311F07L140:        move    PCH(A6),A0
    43124312                move.l  A0,LTMP(A6)
    4313 *
    4314 *                       break;
    4315 *
     4313
     4314|                       break;
     4315
    43164316                bra     F07L137
    4317 *
    4318                 .page
    4319 *
    4320 *               case SM_FREQ:
    4321 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    4322 *
     4317
     4318                .page
     4319
     4320|               case SM_FREQ:
     4321|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     4322
    43234323F07L141:        move    PCH(A6),D0
    43244324                asr     #7,D0
     
    43304330                ext.l   D0
    43314331                move.l  D0,LTMP(A6)
    4332 *
    4333 *                       break;
    4334 *
     4332
     4333|                       break;
     4334
    43354335                bra     F07L137
    4336 *
    4337 *               case SM_KVEL:
    4338 *                       ltmp = veltab[trg];
    4339 *
     4336
     4337|               case SM_KVEL:
     4338|                       ltmp = veltab[trg];
     4339
    43404340F07L142:        move    TRG(A6),A0
    43414341                add.l   A0,A0
     
    43444344                ext.l   D0
    43454345                move.l  D0,LTMP(A6)
    4346 *
    4347 *                       break;
    4348 *
     4346
     4347|                       break;
     4348
    43494349                bra     F07L137
    4350 *
    4351                 .page
    4352 *
    4353 *               case SM_KPRS:
    4354 *                       ltmp = prstab[trg];
    4355 *
     4350
     4351                .page
     4352
     4353|               case SM_KPRS:
     4354|                       ltmp = prstab[trg];
     4355
    43564356F07L143:        move    TRG(A6),A0
    43574357                add.l   A0,A0
     
    43604360                ext.l   D0
    43614361                move.l  D0,LTMP(A6)
    4362 *
    4363 *                       break;
    4364 *
     4362
     4363|                       break;
     4364
    43654365                bra     F07L137
    4366 *
    4367                 .page
    4368 *
    4369 *               default:
    4370 *                       ltmp = valents[group | pt->ipvsrc].val;
    4371 *
     4366
     4367                .page
     4368
     4369|               default:
     4370|                       ltmp = valents[group | pt->ipvsrc].val;
     4371
    43724372F07L144:        move.l  PT(A6),A0
    43734373                clr.l   D0
     
    43834383                move    8(A0,A1.l),D0
    43844384                move.l  D0,LTMP(A6)
    4385 *
    4386 *               }
    4387 *
    4388 *
    4389                 .page
    4390 *
    4391 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    4392 *
     4385
     4386|               }
     4387
     4388
     4389                .page
     4390
     4391|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     4392
    43934393F07L137:        move.l  PT(A6),A0
    43944394                move.w  4(A0),D0
     
    43984398                asr.l   D1,D0
    43994399                move.l  D0,LTMP(A6)
    4400 *
    4401 *               ltmp += (long)pt->ipval;
    4402 *
     4400
     4401|               ltmp += (long)pt->ipval;
     4402
    44034403                move.l  PT(A6),A0
    44044404                move    2(A0),D0
    44054405                ext.l   D0
    44064406                add.l   D0,LTMP(A6)
    4407 *
    4408 *               if (ltmp GT (long)VALMAX)
    4409 *                       ltmp = (long)VALMAX;
    4410 *
     4407
     4408|               if (ltmp GT (long)VALMAX)
     4409|                       ltmp = (long)VALMAX;
     4410
    44114411                cmp.l   #VALMAX,LTMP(A6)
    44124412                ble     F07L146
    4413 *
     4413
    44144414                move.l  #VALMAX,LTMP(A6)
    44154415                bra     F07L147
    4416 *
    4417 *               else if (ltmp LT (long)VALMIN)
    4418 *                       ltmp = (long)VALMIN;
    4419 *
     4416
     4417|               else if (ltmp LT (long)VALMIN)
     4418|                       ltmp = (long)VALMIN;
     4419
    44204420F07L146:        cmp.l   #VALMIN,LTMP(A6)
    44214421                bge     F07L147
    4422 *
     4422
    44234423                move.l  #VALMIN,LTMP(A6)
    4424 *
    4425 *               tfpval = (short)ltmp;
    4426 *
     4424
     4425|               tfpval = (short)ltmp;
     4426
    44274427F07L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    44284428                bra     F07L149
    4429 *
    4430 *       } else {
    4431 *
    4432 *               tfpval = pt->ipval;
    4433 *
     4429
     4430|       } else {
     4431
     4432|               tfpval = pt->ipval;
     4433
    44344434F07L136:        move.l  PT(A6),A0
    44354435                move    2(A0),TFPVAL(A6)
    4436 *
    4437 *       }
    4438 *
    4439                 .page
    4440 *
    4441 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    4442 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    4443 *
     4436
     4437|       }
     4438
     4439                .page
     4440
     4441|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     4442|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     4443
    44444444F07L149:        move.l  PT(A6),A0
    44454445                move.w  (A0),D0
    44464446                move.w  D0,D2
    4447                 andi.w  #$FFF0,D0
     4447                andi.w  #0xFFF0,D0
    44484448                move.w  _timemlt,D1
    44494449                muls    D1,D0
     
    44514451                asr.l   D1,D0
    44524452                move    D0,R_FPMANT
    4453 *
    4454 *       fpexp = expbit[pt->iptim & 0x000F];
    4455 *
    4456                 and     #$000F,D2
     4453
     4454|       fpexp = expbit[pt->iptim & 0x000F];
     4455
     4456                and     #0x000F,D2
    44574457                move    D2,A0
    44584458                add.l   A0,A0
    44594459                add.l   #_expbit,A0
    44604460                move    (A0),R_FPEXP
    4461 *
    4462                 .page
    4463 *
    4464 *               fp->idfpch = pch;
    4465 *
     4461
     4462                .page
     4463
     4464|               fp->idfpch = pch;
     4465
    44664466F07L163:        move    PCH(A6),(A_FP)
    4467 *
    4468 *               fpval = tfpval;
    4469 *
     4467
     4468|               fpval = tfpval;
     4469
    44704470                move    TFPVAL(A6),R_FPVAL
    4471 *
    4472                 .page
    4473 *
     4471
     4472                .page
     4473
    44744474                move.b  5(A_FP),D0
    44754475                ext.w   D0
    44764476                sub.w   #1,D0
    44774477                movea.l PT(A6),A0
    4478 *
    4479 *       oldi = setipl(FPU_DI);
    4480 *
     4478
     4479|       oldi = setipl(FPU_DI);
     4480
    44814481                move    sr,OLDI(A6)
    44824482                move    #FPU_DI,sr
    4483 *
     4483
    44844484F07L168:        clr.b   10(A0)
    44854485                add.l   #12,a0
    44864486                dbra    D0,F07L168
    4487 *
    4488                 .page
    4489 *
    4490 *       fp->idftmd ^= I_NVBITS;
    4491 *
     4487
     4488                .page
     4489
     4490|       fp->idftmd ^= I_NVBITS;
     4491
    44924492F07L165:        eor.b   #24,7(A_FP)
    4493 *
    4494 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    4495 *
     4493
     4494|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     4495
    44964496                move.b  7(A_FP),R_FPCTL
    44974497                and     #28,R_FPCTL
    44984498                or      #3,R_FPCTL
    4499 *
    4500 *       fp->idfcpt = fp->idfpt1;
    4501 *
     4499
     4500|       fp->idfcpt = fp->idfpt1;
     4501
    45024502                move.b  6(A_FP),8(A_FP)
    4503 *
    4504 *       fp->idftmd |= I_ACTIVE;
    4505 *
     4503
     4504|       fp->idftmd |= I_ACTIVE;
     4505
    45064506                or.b    #2,7(A_FP)
    4507 *
    4508 *       fp->idftrf = trg;
    4509 *
     4507
     4508|       fp->idftrf = trg;
     4509
    45104510                move    TRG(A6),10(A_FP)
    4511 *
    4512 *       *(fpu + (long)FPU_TCV1) = srcval;
    4513 *
    4514                 move    SRCVAL(A6),$8(A_FPU)
    4515 *
    4516 *       ++octype;
    4517 *
     4511
     4512|       |(fpu + (long)FPU_TCV1) = srcval;
     4513
     4514                move    SRCVAL(A6),0x8(A_FPU)
     4515
     4516|       ++octype;
     4517
    45184518                add     #1,OCTYPE(A6)
    4519 *
    4520 *       *(fpu + (long)FPU_TSF1) = mltval;
    4521 *
    4522                 move    MLTVAL(A6),$A(A_FPU)
    4523 *
    4524 *       ++octype;
    4525 *
     4519
     4520|       |(fpu + (long)FPU_TSF1) = mltval;
     4521
     4522                move    MLTVAL(A6),0xA(A_FPU)
     4523
     4524|       ++octype;
     4525
    45264526                add     #1,OCTYPE(A6)
    4527 *
    4528 *       *(fpu + (long)FPU_TMNT) = fpmant;
    4529 *
    4530                 move    R_FPMANT,$14(A_FPU)
    4531 *
    4532 *       ++octype;
    4533 *
     4527
     4528|       |(fpu + (long)FPU_TMNT) = fpmant;
     4529
     4530                move    R_FPMANT,0x14(A_FPU)
     4531
     4532|       ++octype;
     4533
    45344534                add     #1,OCTYPE(A6)
    4535 *
    4536 *       *(fpu + (long)FPU_TEXP) = fpexp;
    4537 *
    4538                 move    R_FPEXP,$16(A_FPU)
    4539 *
    4540 *       ++octype;
    4541 *
     4535
     4536|       |(fpu + (long)FPU_TEXP) = fpexp;
     4537
     4538                move    R_FPEXP,0x16(A_FPU)
     4539
     4540|       ++octype;
     4541
    45424542                add     #1,OCTYPE(A6)
    4543 *
    4544                 .page
    4545 *
    4546 *       if (fp->idftmd & I_VNSUBN)
    4547 *
     4543
     4544                .page
     4545
     4546|       if (fp->idftmd & I_VNSUBN)
     4547
    45484548                btst    #3,7(A_FP)
    45494549                beq     F07L169
    4550 *
    4551 *               *(fpu + (long)FPU_TNV1) = fpval;
    4552 *
    4553                 move    R_FPVAL,$1C(A_FPU)
     4550
     4551|               |(fpu + (long)FPU_TNV1) = fpval;
     4552
     4553                move    R_FPVAL,0x1C(A_FPU)
    45544554                bra     F07L170
    4555 *
    4556 *       else
    4557 *               *(fpu + (long)FPU_TNV0) = fpval;
    4558 *
     4555
     4556|       else
     4557|               |(fpu + (long)FPU_TNV0) = fpval;
     4558
    45594559F07L169:        move    R_FPVAL,2(A_FPU)
    4560 *
    4561 *       ++octype;
    4562 *
     4560
     4561|       ++octype;
     4562
    45634563F07L170:        add     #1,OCTYPE(A6)
    4564 *
    4565 *       *(fpu + (long)FPU_TCTL) = fpctl;
    4566 *
     4564
     4565|       |(fpu + (long)FPU_TCTL) = fpctl;
     4566
    45674567                move    R_FPCTL,(A_FPU)
    4568 *
    4569 *       setipl(oldi);
    4570 *
     4568
     4569|       setipl(oldi);
     4570
    45714571                move    OLDI(A6),sr
    4572 *
    4573                 .page
    4574 * ------------------------------------------------------------------------------
    4575 * Start function 8 -- Ind 3
    4576 * ------------------------------------------------------------------------------
    4577 *
    4578 *    if (ip->idhfnc[8].idftmd & I_TM_KEY) {
    4579 *
     4572
     4573                .page
     4574| ------------------------------------------------------------------------------
     4575| Start function 8 -- Ind 3
     4576| ------------------------------------------------------------------------------
     4577
     4578|    if (ip->idhfnc[8].idftmd & I_TM_KEY) {
     4579
    45804580FN08:           move.l  IP(A6),A0
    45814581                move.b  189(A0),D0
     
    45844584                btst    #0,D0
    45854585                bne     FN08A
    4586 *
     4586
    45874587                jmp     FN09
    4588 *
    4589 *       vp = (vce << 4) + 12;
    4590 *
     4588
     4589|       vp = (vce << 4) + 12;
     4590
    45914591FN08A:          move    VCE(A6),D0
    45924592                asl     #4,D0
    45934593                add.w   #12,D0
    45944594                move    D0,VP(A6)
    4595 *
    4596 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    4597 *
     4595
     4596|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     4597
    45984598                asl     #5,D0
    45994599                ext.l   D0
    46004600                move.l  D0,A_FPU
    4601                 add.l   #_io_fpu+$4000,A_FPU
    4602 *
    4603 *       fp = &ip->idhfnc[8];
    4604 *
     4601                add.l   #_io_fpu+0x4000,A_FPU
     4602
     4603|       fp = &ip->idhfnc[8];
     4604
    46054605                move.l  #96,A_FP
    46064606                add.l   IP(A6),A_FP
    46074607                add.l   #86,A_FP
    4608 *
    4609 *       pt = &ip->idhpnt[fp->idfpt1];
    4610 *
     4608
     4609|       pt = &ip->idhpnt[fp->idfpt1];
     4610
    46114611                clr.l   D0
    46124612                move.b  6(A_FP),D0
     
    46184618                add.l   #242,D0
    46194619                move.l  D0,PT(A6)
    4620 *
    4621                 .page
    4622 *
    4623 *       srcnum = group | fp->idfsrc;
    4624 *
     4620
     4621                .page
     4622
     4623|       srcnum = group | fp->idfsrc;
     4624
    46254625                move.w  GROUP(A6),D0
    46264626                ext.l   D0
     
    46294629                or      D1,D0
    46304630                move    D0,SRCNUM(A6)
    4631 *
    4632 *       vep = &valents[srcnum];
    4633 *
     4631
     4632|       vep = &valents[srcnum];
     4633
    46344634                add.l   D0,D0
    46354635                move.l  D0,D1
     
    46384638                add.l   #_valents,D0
    46394639                move.l  D0,VEP(A6)
    4640 *
    4641 *       smp = vpsms[vp];
    4642 *
     4640
     4641|       smp = vpsms[vp];
     4642
    46434643                move    VP(A6),A0
    46444644                add.l   A0,A0
     
    46464646                add.l   #_vpsms,A0
    46474647                move.l  (A0),A_SMP
    4648 *
    4649 *       if (srcnum NE smp->sm) {
    4650 *
     4648
     4649|       if (srcnum NE smp->sm) {
     4650
    46514651                clr     D0
    46524652                move    10(A_SMP),D0
    46534653                cmp     SRCNUM(A6),D0
    46544654                beq     F08L113
    4655 *
    4656 *               (smp->prv)->nxt = smp->nxt;
    4657 *
     4655
     4656|               (smp->prv)->nxt = smp->nxt;
     4657
    46584658                move.l  4(A_SMP),A0
    46594659                move.l  (A_SMP),(A0)
    4660 *
    4661 *               (smp->nxt)->prv = smp->prv;
    4662 *
     4660
     4661|               (smp->nxt)->prv = smp->prv;
     4662
    46634663                move.l  (A_SMP),A0
    46644664                move.l  4(A_SMP),4(A0)
    4665 *
    4666 *               smp->prv = (struct sment *)vep;
    4667 *
     4665
     4666|               smp->prv = (struct sment |)vep;
     4667
    46684668                move.l  VEP(A6),4(A_SMP)
    4669 *
    4670 *               smp->nxt = vep->nxt;
    4671 *
     4669
     4670|               smp->nxt = vep->nxt;
     4671
    46724672                move.l  VEP(A6),A0
    46734673                move.l  (A0),(A_SMP)
    4674 *
    4675 *               (vep->nxt)->prv = smp;
    4676 *
     4674
     4675|               (vep->nxt)->prv = smp;
     4676
    46774677                move.l  VEP(A6),A0
    46784678                move.l  (A0),A0
    46794679                move.l  A_SMP,4(A0)
    4680 *
    4681 *               vep->nxt = smp;
    4682 *
     4680
     4681|               vep->nxt = smp;
     4682
    46834683                move.l  VEP(A6),A0
    46844684                move.l  A_SMP,(A0)
    4685 *
    4686 *               smp->sm = srcnum;
    4687 *
     4685
     4686|               smp->sm = srcnum;
     4687
    46884688                move    SRCNUM(A6),10(A_SMP)
    4689 *
    4690 *       }
    4691 *
    4692 *       mltval = fp->idfmlt;
    4693 *
     4689
     4690|       }
     4691
     4692|       mltval = fp->idfmlt;
     4693
    46944694F08L113:        move    2(A_FP),MLTVAL(A6)
    4695 *
    4696                 .page
    4697 *
    4698 *       switch (fp->idfsrc) {
    4699 *
     4695
     4696                .page
     4697
     4698|       switch (fp->idfsrc) {
     4699
    47004700                move.b  4(A_FP),D0
    47014701                ext.w   d0
    47024702                cmp     #10,D0
    47034703                bhi     F08L122
    4704 *
     4704
    47054705                asl     #2,D0
    47064706                lea     F08L123,A0
    47074707                movea.l 0(A0,D0.W),A0
    47084708                jmp     (A0)
    4709 *
    4710 *       case SM_NONE:
    4711 *               mltval = 0;
    4712 *
     4709
     4710|       case SM_NONE:
     4711|               mltval = 0;
     4712
    47134713F08L116:        clr     MLTVAL(A6)
    4714 *
    4715 *               tsrcval = 0;
    4716 *
     4714
     4715|               tsrcval = 0;
     4716
    47174717                clr     TSRCVAL(A6)
    4718 *
    4719 *               break;
    4720 *
     4718
     4719|               break;
     4720
    47214721                bra     F08L114
    4722 *
    4723 *       case SM_RAND:
    4724 *               tsrcval = xgetran(mltval);
    4725 *
     4722
     4723|       case SM_RAND:
     4724|               tsrcval = xgetran(mltval);
     4725
    47264726F08L117:        move    MLTVAL(A6),(sp)
    47274727                jsr     _xgetran
    47284728                move    D0,TSRCVAL(A6)
    4729 *
    4730 *               break;
    4731 *
     4729
     4730|               break;
     4731
    47324732                bra     F08L114
    4733 *
    4734 *       case SM_PTCH:
    4735 *               tsrcval = pch;
    4736 *
     4733
     4734|       case SM_PTCH:
     4735|               tsrcval = pch;
     4736
    47374737F08L118:        move    PCH(A6),TSRCVAL(A6)
    4738 *
    4739 *               break;
    4740 *
     4738
     4739|               break;
     4740
    47414741                bra     F08L114
    4742 *
    4743                 .page
    4744 *
    4745 *       case SM_FREQ:
    4746 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    4747 *
     4742
     4743                .page
     4744
     4745|       case SM_FREQ:
     4746|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     4747
    47484748F08L119:        move    PCH(A6),D0
    47494749                asr     #7,D0
     
    47534753                add.l   #_ptoftab,A0
    47544754                move    (A0),TSRCVAL(A6)
    4755 *
    4756 *               break;
    4757 *
     4755
     4756|               break;
     4757
    47584758                bra     F08L114
    4759 *
    4760 *       case SM_KVEL:
    4761 *               tsrcval = veltab[trg];
    4762 *
     4759
     4760|       case SM_KVEL:
     4761|               tsrcval = veltab[trg];
     4762
    47634763F08L120:        move    TRG(A6),A0
    47644764                add.l   A0,A0
    47654765                add.l   #_veltab,A0
    47664766                move    (A0),TSRCVAL(A6)
    4767 *
    4768 *               break;
    4769 *
     4767
     4768|               break;
     4769
    47704770                bra     F08L114
    4771 *
    4772 *       case SM_KPRS:
    4773 *               tsrcval = prstab[trg];
    4774 *
     4771
     4772|       case SM_KPRS:
     4773|               tsrcval = prstab[trg];
     4774
    47754775F08L121:        move    TRG(A6),A0
    47764776                add.l   A0,A0
    47774777                add.l   #_prstab,A0
    47784778                move    (A0),TSRCVAL(A6)
    4779 *
    4780 *               break;
    4781 *
     4779
     4780|               break;
     4781
    47824782                bra     F08L114
    4783 *
    4784 *       default:
    4785 *               tsrcval = vep->val;
    4786 *
     4783
     4784|       default:
     4785|               tsrcval = vep->val;
     4786
    47874787F08L122:        move.l  VEP(A6),A0
    47884788                move    8(A0),TSRCVAL(A6)
    4789 *
    4790 *       }
    4791 *
    4792                 .page
    4793 *
    4794 *               srcval = tsrcval;
    4795 *
     4789
     4790|       }
     4791
     4792                .page
     4793
     4794|               srcval = tsrcval;
     4795
    47964796F08L114:        move    TSRCVAL(A6),SRCVAL(A6)
    4797 *
    4798                 .page
    4799 *
    4800 *       if (pt->ipvsrc) {
    4801 *
     4797
     4798                .page
     4799
     4800|       if (pt->ipvsrc) {
     4801
    48024802F08L124:        move.l  PT(A6),A0
    48034803                tst.b   6(A0)
    48044804                beq     F08L136
    4805 *
    4806 *               switch (pt->ipvsrc) {
    4807 *
     4805
     4806|               switch (pt->ipvsrc) {
     4807
    48084808                move.l  PT(A6),A0
    48094809                move.b  6(A0),D0
     
    48124812                cmp     #9,D0
    48134813                bhi     F08L144
    4814 *
     4814
    48154815                asl     #2,D0
    48164816                lea     F08L145,A0
    48174817                move.l  0(A0,D0.W),A0
    48184818                jmp     (A0)
    4819 *
    4820 *               case SM_RAND:
    4821 *                       ltmp = xgetran(pt_>ipvmlt);
    4822 *
     4819
     4820|               case SM_RAND:
     4821|                       ltmp = xgetran(pt_>ipvmlt);
     4822
    48234823F08L139:        move.l  PT(A6),A0
    48244824                move    4(A0),(sp)
     
    48264826                ext.l   D0
    48274827                move.l  D0,LTMP(A6)
    4828 *
    4829 *                       break;
    4830 *
     4828
     4829|                       break;
     4830
    48314831                bra     F08L137
    4832 *
    4833 *               case SM_PTCH:
    4834 *                       ltmp = pch;
    4835 *
     4832
     4833|               case SM_PTCH:
     4834|                       ltmp = pch;
     4835
    48364836F08L140:        move    PCH(A6),A0
    48374837                move.l  A0,LTMP(A6)
    4838 *
    4839 *                       break;
    4840 *
     4838
     4839|                       break;
     4840
    48414841                bra     F08L137
    4842 *
    4843                 .page
    4844 *
    4845 *               case SM_FREQ:
    4846 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    4847 *
     4842
     4843                .page
     4844
     4845|               case SM_FREQ:
     4846|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     4847
    48484848F08L141:        move    PCH(A6),D0
    48494849                asr     #7,D0
     
    48554855                ext.l   D0
    48564856                move.l  D0,LTMP(A6)
    4857 *
    4858 *                       break;
    4859 *
     4857
     4858|                       break;
     4859
    48604860                bra     F08L137
    4861 *
    4862 *               case SM_KVEL:
    4863 *                       ltmp = veltab[trg];
    4864 *
     4861
     4862|               case SM_KVEL:
     4863|                       ltmp = veltab[trg];
     4864
    48654865F08L142:        move    TRG(A6),A0
    48664866                add.l   A0,A0
     
    48694869                ext.l   D0
    48704870                move.l  D0,LTMP(A6)
    4871 *
    4872 *                       break;
    4873 *
     4871
     4872|                       break;
     4873
    48744874                bra     F08L137
    4875 *
    4876                 .page
    4877 *
    4878 *               case SM_KPRS:
    4879 *                       ltmp = prstab[trg];
    4880 *
     4875
     4876                .page
     4877
     4878|               case SM_KPRS:
     4879|                       ltmp = prstab[trg];
     4880
    48814881F08L143:        move    TRG(A6),A0
    48824882                add.l   A0,A0
     
    48854885                ext.l   D0
    48864886                move.l  D0,LTMP(A6)
    4887 *
    4888 *                       break;
    4889 *
     4887
     4888|                       break;
     4889
    48904890                bra     F08L137
    4891 *
    4892                 .page
    4893 *
    4894 *               default:
    4895 *                       ltmp = valents[group | pt->ipvsrc].val;
    4896 *
     4891
     4892                .page
     4893
     4894|               default:
     4895|                       ltmp = valents[group | pt->ipvsrc].val;
     4896
    48974897F08L144:        move.l  PT(A6),A0
    48984898                clr.l   D0
     
    49084908                move    8(A0,A1.l),D0
    49094909                move.l  D0,LTMP(A6)
    4910 *
    4911 *               }
    4912 *
    4913 *
    4914                 .page
    4915 *
    4916 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    4917 *
     4910
     4911|               }
     4912
     4913
     4914                .page
     4915
     4916|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     4917
    49184918F08L137:        move.l  PT(A6),A0
    49194919                move.w  4(A0),D0
     
    49234923                asr.l   D1,D0
    49244924                move.l  D0,LTMP(A6)
    4925 *
    4926 *               ltmp += (long)pt->ipval;
    4927 *
     4925
     4926|               ltmp += (long)pt->ipval;
     4927
    49284928                move.l  PT(A6),A0
    49294929                move    2(A0),D0
    49304930                ext.l   D0
    49314931                add.l   D0,LTMP(A6)
    4932 *
    4933 *               if (ltmp GT (long)VALMAX)
    4934 *                       ltmp = (long)VALMAX;
    4935 *
     4932
     4933|               if (ltmp GT (long)VALMAX)
     4934|                       ltmp = (long)VALMAX;
     4935
    49364936                cmp.l   #VALMAX,LTMP(A6)
    49374937                ble     F08L146
    4938 *
     4938
    49394939                move.l  #VALMAX,LTMP(A6)
    49404940                bra     F08L147
    4941 *
    4942 *               else if (ltmp LT (long)VALMIN)
    4943 *                       ltmp = (long)VALMIN;
    4944 *
     4941
     4942|               else if (ltmp LT (long)VALMIN)
     4943|                       ltmp = (long)VALMIN;
     4944
    49454945F08L146:        cmp.l   #VALMIN,LTMP(A6)
    49464946                bge     F08L147
    4947 *
     4947
    49484948                move.l  #VALMIN,LTMP(A6)
    4949 *
    4950 *               tfpval = (short)ltmp;
    4951 *
     4949
     4950|               tfpval = (short)ltmp;
     4951
    49524952F08L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    49534953                bra     F08L149
    4954 *
    4955 *       } else {
    4956 *
    4957 *               tfpval = pt->ipval;
    4958 *
     4954
     4955|       } else {
     4956
     4957|               tfpval = pt->ipval;
     4958
    49594959F08L136:        move.l  PT(A6),A0
    49604960                move    2(A0),TFPVAL(A6)
    4961 *
    4962 *       }
    4963 *
    4964                 .page
    4965 *
    4966 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    4967 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    4968 *
     4961
     4962|       }
     4963
     4964                .page
     4965
     4966|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     4967|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     4968
    49694969F08L149:        move.l  PT(A6),A0
    49704970                move.w  (A0),D0
    49714971                move.w  D0,D2
    4972                 andi.w  #$FFF0,D0
     4972                andi.w  #0xFFF0,D0
    49734973                move.w  _timemlt,D1
    49744974                muls    D1,D0
     
    49764976                asr.l   D1,D0
    49774977                move    D0,R_FPMANT
    4978 *
    4979 *       fpexp = expbit[pt->iptim & 0x000F];
    4980 *
    4981                 and     #$000F,D2
     4978
     4979|       fpexp = expbit[pt->iptim & 0x000F];
     4980
     4981                and     #0x000F,D2
    49824982                move    D2,A0
    49834983                add.l   A0,A0
    49844984                add.l   #_expbit,A0
    49854985                move    (A0),R_FPEXP
    4986 *
    4987                 .page
    4988 *
    4989 *               fp->idfpch = pch;
    4990 *
     4986
     4987                .page
     4988
     4989|               fp->idfpch = pch;
     4990
    49914991F08L163:        move    PCH(A6),(A_FP)
    4992 *
    4993 *               fpval = tfpval;
    4994 *
     4992
     4993|               fpval = tfpval;
     4994
    49954995                move    TFPVAL(A6),R_FPVAL
    4996 *
    4997                 .page
    4998 *
     4996
     4997                .page
     4998
    49994999                move.b  5(A_FP),D0
    50005000                ext.w   D0
    50015001                sub.w   #1,D0
    50025002                movea.l PT(A6),A0
    5003 *
    5004 *       oldi = setipl(FPU_DI);
    5005 *
     5003
     5004|       oldi = setipl(FPU_DI);
     5005
    50065006                move    sr,OLDI(A6)
    50075007                move    #FPU_DI,sr
    5008 *
     5008
    50095009F08L168:        clr.b   10(A0)
    50105010                add.l   #12,a0
    50115011                dbra    D0,F08L168
    5012 *
    5013                 .page
    5014 *
    5015 *       fp->idftmd ^= I_NVBITS;
    5016 *
     5012
     5013                .page
     5014
     5015|       fp->idftmd ^= I_NVBITS;
     5016
    50175017F08L165:        eor.b   #24,7(A_FP)
    5018 *
    5019 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    5020 *
     5018
     5019|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     5020
    50215021                move.b  7(A_FP),R_FPCTL
    50225022                and     #28,R_FPCTL
    50235023                or      #3,R_FPCTL
    5024 *
    5025 *       fp->idfcpt = fp->idfpt1;
    5026 *
     5024
     5025|       fp->idfcpt = fp->idfpt1;
     5026
    50275027                move.b  6(A_FP),8(A_FP)
    5028 *
    5029 *       fp->idftmd |= I_ACTIVE;
    5030 *
     5028
     5029|       fp->idftmd |= I_ACTIVE;
     5030
    50315031                or.b    #2,7(A_FP)
    5032 *
    5033 *       fp->idftrf = trg;
    5034 *
     5032
     5033|       fp->idftrf = trg;
     5034
    50355035                move    TRG(A6),10(A_FP)
    5036 *
    5037 *       *(fpu + (long)FPU_TCV1) = srcval;
    5038 *
    5039                 move    SRCVAL(A6),$8(A_FPU)
    5040 *
    5041 *       ++octype;
    5042 *
     5036
     5037|       |(fpu + (long)FPU_TCV1) = srcval;
     5038
     5039                move    SRCVAL(A6),0x8(A_FPU)
     5040
     5041|       ++octype;
     5042
    50435043                add     #1,OCTYPE(A6)
    5044 *
    5045 *       *(fpu + (long)FPU_TSF1) = mltval;
    5046 *
    5047                 move    MLTVAL(A6),$A(A_FPU)
    5048 *
    5049 *       ++octype;
    5050 *
     5044
     5045|       |(fpu + (long)FPU_TSF1) = mltval;
     5046
     5047                move    MLTVAL(A6),0xA(A_FPU)
     5048
     5049|       ++octype;
     5050
    50515051                add     #1,OCTYPE(A6)
    5052 *
    5053 *       *(fpu + (long)FPU_TMNT) = fpmant;
    5054 *
    5055                 move    R_FPMANT,$14(A_FPU)
    5056 *
    5057 *       ++octype;
    5058 *
     5052
     5053|       |(fpu + (long)FPU_TMNT) = fpmant;
     5054
     5055                move    R_FPMANT,0x14(A_FPU)
     5056
     5057|       ++octype;
     5058
    50595059                add     #1,OCTYPE(A6)
    5060 *
    5061 *       *(fpu + (long)FPU_TEXP) = fpexp;
    5062 *
    5063                 move    R_FPEXP,$16(A_FPU)
    5064 *
    5065 *       ++octype;
    5066 *
     5060
     5061|       |(fpu + (long)FPU_TEXP) = fpexp;
     5062
     5063                move    R_FPEXP,0x16(A_FPU)
     5064
     5065|       ++octype;
     5066
    50675067                add     #1,OCTYPE(A6)
    5068 *
    5069                 .page
    5070 *
    5071 *       if (fp->idftmd & I_VNSUBN)
    5072 *
     5068
     5069                .page
     5070
     5071|       if (fp->idftmd & I_VNSUBN)
     5072
    50735073                btst    #3,7(A_FP)
    50745074                beq     F08L169
    5075 *
    5076 *               *(fpu + (long)FPU_TNV1) = fpval;
    5077 *
    5078                 move    R_FPVAL,$1C(A_FPU)
     5075
     5076|               |(fpu + (long)FPU_TNV1) = fpval;
     5077
     5078                move    R_FPVAL,0x1C(A_FPU)
    50795079                bra     F08L170
    5080 *
    5081 *       else
    5082 *               *(fpu + (long)FPU_TNV0) = fpval;
    5083 *
     5080
     5081|       else
     5082|               |(fpu + (long)FPU_TNV0) = fpval;
     5083
    50845084F08L169:        move    R_FPVAL,2(A_FPU)
    5085 *
    5086 *       ++octype;
    5087 *
     5085
     5086|       ++octype;
     5087
    50885088F08L170:        add     #1,OCTYPE(A6)
    5089 *
    5090 *       *(fpu + (long)FPU_TCTL) = fpctl;
    5091 *
     5089
     5090|       |(fpu + (long)FPU_TCTL) = fpctl;
     5091
    50925092                move    R_FPCTL,(A_FPU)
    5093 *
    5094 *       setipl(oldi);
    5095 *
     5093
     5094|       setipl(oldi);
     5095
    50965096                move    OLDI(A6),sr
    5097 *
    5098                 .page
    5099 * ------------------------------------------------------------------------------
    5100 * Start function 9 -- Ind 4
    5101 * ------------------------------------------------------------------------------
    5102 *
    5103 *    if (ip->idhfnc[9].idftmd & I_TM_KEY) {
    5104 *
     5097
     5098                .page
     5099| ------------------------------------------------------------------------------
     5100| Start function 9 -- Ind 4
     5101| ------------------------------------------------------------------------------
     5102
     5103|    if (ip->idhfnc[9].idftmd & I_TM_KEY) {
     5104
    51055105FN09:           move.l  IP(A6),A0
    51065106                move.b  201(A0),D0
     
    51095109                btst    #0,D0
    51105110                bne     FN09A
    5111 *
     5111
    51125112                jmp     FN10
    5113 *
    5114 *       vp = (vce << 4) + 13;
    5115 *
     5113
     5114|       vp = (vce << 4) + 13;
     5115
    51165116FN09A:          move    VCE(A6),D0
    51175117                asl     #4,D0
    51185118                add.w   #13,D0
    51195119                move    D0,VP(A6)
    5120 *
    5121 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    5122 *
     5120
     5121|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     5122
    51235123                asl     #5,D0
    51245124                ext.l   D0
    51255125                move.l  D0,A_FPU
    5126                 add.l   #_io_fpu+$4000,A_FPU
    5127 *
    5128 *       fp = &ip->idhfnc[9];
    5129 *
     5126                add.l   #_io_fpu+0x4000,A_FPU
     5127
     5128|       fp = &ip->idhfnc[9];
     5129
    51305130                move.l  #108,A_FP
    51315131                add.l   IP(A6),A_FP
    51325132                add.l   #86,A_FP
    5133 *
    5134 *       pt = &ip->idhpnt[fp->idfpt1];
    5135 *
     5133
     5134|       pt = &ip->idhpnt[fp->idfpt1];
     5135
    51365136                clr.l   D0
    51375137                move.b  6(A_FP),D0
     
    51435143                add.l   #242,D0
    51445144                move.l  D0,PT(A6)
    5145 *
    5146                 .page
    5147 *
    5148 *       srcnum = group | fp->idfsrc;
    5149 *
     5145
     5146                .page
     5147
     5148|       srcnum = group | fp->idfsrc;
     5149
    51505150                move.w  GROUP(A6),D0
    51515151                ext.l   D0
     
    51545154                or      D1,D0
    51555155                move    D0,SRCNUM(A6)
    5156 *
    5157 *       vep = &valents[srcnum];
    5158 *
     5156
     5157|       vep = &valents[srcnum];
     5158
    51595159                add.l   D0,D0
    51605160                move.l  D0,D1
     
    51635163                add.l   #_valents,D0
    51645164                move.l  D0,VEP(A6)
    5165 *
    5166 *       smp = vpsms[vp];
    5167 *
     5165
     5166|       smp = vpsms[vp];
     5167
    51685168                move    VP(A6),A0
    51695169                add.l   A0,A0
     
    51715171                add.l   #_vpsms,A0
    51725172                move.l  (A0),A_SMP
    5173 *
    5174 *       if (srcnum NE smp->sm) {
    5175 *
     5173
     5174|       if (srcnum NE smp->sm) {
     5175
    51765176                clr     D0
    51775177                move    10(A_SMP),D0
    51785178                cmp     SRCNUM(A6),D0
    51795179                beq     F09L113
    5180 *
    5181 *               (smp->prv)->nxt = smp->nxt;
    5182 *
     5180
     5181|               (smp->prv)->nxt = smp->nxt;
     5182
    51835183                move.l  4(A_SMP),A0
    51845184                move.l  (A_SMP),(A0)
    5185 *
    5186 *               (smp->nxt)->prv = smp->prv;
    5187 *
     5185
     5186|               (smp->nxt)->prv = smp->prv;
     5187
    51885188                move.l  (A_SMP),A0
    51895189                move.l  4(A_SMP),4(A0)
    5190 *
    5191 *               smp->prv = (struct sment *)vep;
    5192 *
     5190
     5191|               smp->prv = (struct sment |)vep;
     5192
    51935193                move.l  VEP(A6),4(A_SMP)
    5194 *
    5195 *               smp->nxt = vep->nxt;
    5196 *
     5194
     5195|               smp->nxt = vep->nxt;
     5196
    51975197                move.l  VEP(A6),A0
    51985198                move.l  (A0),(A_SMP)
    5199 *
    5200 *               (vep->nxt)->prv = smp;
    5201 *
     5199
     5200|               (vep->nxt)->prv = smp;
     5201
    52025202                move.l  VEP(A6),A0
    52035203                move.l  (A0),A0
    52045204                move.l  A_SMP,4(A0)
    5205 *
    5206 *               vep->nxt = smp;
    5207 *
     5205
     5206|               vep->nxt = smp;
     5207
    52085208                move.l  VEP(A6),A0
    52095209                move.l  A_SMP,(A0)
    5210 *
    5211 *               smp->sm = srcnum;
    5212 *
     5210
     5211|               smp->sm = srcnum;
     5212
    52135213                move    SRCNUM(A6),10(A_SMP)
    5214 *
    5215 *       }
    5216 *
    5217 *       mltval = fp->idfmlt;
    5218 *
     5214
     5215|       }
     5216
     5217|       mltval = fp->idfmlt;
     5218
    52195219F09L113:        move    2(A_FP),MLTVAL(A6)
    5220 *
    5221                 .page
    5222 *
    5223 *       switch (fp->idfsrc) {
    5224 *
     5220
     5221                .page
     5222
     5223|       switch (fp->idfsrc) {
     5224
    52255225                move.b  4(A_FP),D0
    52265226                ext.w   d0
    52275227                cmp     #10,D0
    52285228                bhi     F09L122
    5229 *
     5229
    52305230                asl     #2,D0
    52315231                lea     F09L123,A0
    52325232                movea.l 0(A0,D0.W),A0
    52335233                jmp     (A0)
    5234 *
    5235 *       case SM_NONE:
    5236 *               mltval = 0;
    5237 *
     5234
     5235|       case SM_NONE:
     5236|               mltval = 0;
     5237
    52385238F09L116:        clr     MLTVAL(A6)
    5239 *
    5240 *               tsrcval = 0;
    5241 *
     5239
     5240|               tsrcval = 0;
     5241
    52425242                clr     TSRCVAL(A6)
    5243 *
    5244 *               break;
    5245 *
     5243
     5244|               break;
     5245
    52465246                bra     F09L114
    5247 *
    5248 *       case SM_RAND:
    5249 *               tsrcval = xgetran(mltval);
    5250 *
     5247
     5248|       case SM_RAND:
     5249|               tsrcval = xgetran(mltval);
     5250
    52515251F09L117:        move    MLTVAL(A6),(sp)
    52525252                jsr     _xgetran
    52535253                move    D0,TSRCVAL(A6)
    5254 *
    5255 *               break;
    5256 *
     5254
     5255|               break;
     5256
    52575257                bra     F09L114
    5258 *
    5259 *       case SM_PTCH:
    5260 *               tsrcval = pch;
    5261 *
     5258
     5259|       case SM_PTCH:
     5260|               tsrcval = pch;
     5261
    52625262F09L118:        move    PCH(A6),TSRCVAL(A6)
    5263 *
    5264 *               break;
    5265 *
     5263
     5264|               break;
     5265
    52665266                bra     F09L114
    5267 *
    5268                 .page
    5269 *
    5270 *       case SM_FREQ:
    5271 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    5272 *
     5267
     5268                .page
     5269
     5270|       case SM_FREQ:
     5271|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     5272
    52735273F09L119:        move    PCH(A6),D0
    52745274                asr     #7,D0
     
    52785278                add.l   #_ptoftab,A0
    52795279                move    (A0),TSRCVAL(A6)
    5280 *
    5281 *               break;
    5282 *
     5280
     5281|               break;
     5282
    52835283                bra     F09L114
    5284 *
    5285 *       case SM_KVEL:
    5286 *               tsrcval = veltab[trg];
    5287 *
     5284
     5285|       case SM_KVEL:
     5286|               tsrcval = veltab[trg];
     5287
    52885288F09L120:        move    TRG(A6),A0
    52895289                add.l   A0,A0
    52905290                add.l   #_veltab,A0
    52915291                move    (A0),TSRCVAL(A6)
    5292 *
    5293 *               break;
    5294 *
     5292
     5293|               break;
     5294
    52955295                bra     F09L114
    5296 *
    5297 *       case SM_KPRS:
    5298 *               tsrcval = prstab[trg];
    5299 *
     5296
     5297|       case SM_KPRS:
     5298|               tsrcval = prstab[trg];
     5299
    53005300F09L121:        move    TRG(A6),A0
    53015301                add.l   A0,A0
    53025302                add.l   #_prstab,A0
    53035303                move    (A0),TSRCVAL(A6)
    5304 *
    5305 *               break;
    5306 *
     5304
     5305|               break;
     5306
    53075307                bra     F09L114
    5308 *
    5309 *       default:
    5310 *               tsrcval = vep->val;
    5311 *
     5308
     5309|       default:
     5310|               tsrcval = vep->val;
     5311
    53125312F09L122:        move.l  VEP(A6),A0
    53135313                move    8(A0),TSRCVAL(A6)
    5314 *
    5315 *       }
    5316 *
    5317                 .page
    5318 *
    5319 *               srcval = tsrcval;
    5320 *
     5314
     5315|       }
     5316
     5317                .page
     5318
     5319|               srcval = tsrcval;
     5320
    53215321F09L114:        move    TSRCVAL(A6),SRCVAL(A6)
    5322 *
    5323                 .page
    5324 *
    5325 *       if (pt->ipvsrc) {
    5326 *
     5322
     5323                .page
     5324
     5325|       if (pt->ipvsrc) {
     5326
    53275327F09L124:        move.l  PT(A6),A0
    53285328                tst.b   6(A0)
    53295329                beq     F09L136
    5330 *
    5331 *               switch (pt->ipvsrc) {
    5332 *
     5330
     5331|               switch (pt->ipvsrc) {
     5332
    53335333                move.l  PT(A6),A0
    53345334                move.b  6(A0),D0
     
    53375337                cmp     #9,D0
    53385338                bhi     F09L144
    5339 *
     5339
    53405340                asl     #2,D0
    53415341                lea     F09L145,A0
    53425342                move.l  0(A0,D0.W),A0
    53435343                jmp     (A0)
    5344 *
    5345 *               case SM_RAND:
    5346 *                       ltmp = xgetran(pt_>ipvmlt);
    5347 *
     5344
     5345|               case SM_RAND:
     5346|                       ltmp = xgetran(pt_>ipvmlt);
     5347
    53485348F09L139:        move.l  PT(A6),A0
    53495349                move    4(A0),(sp)
     
    53515351                ext.l   D0
    53525352                move.l  D0,LTMP(A6)
    5353 *
    5354 *                       break;
    5355 *
     5353
     5354|                       break;
     5355
    53565356                bra     F09L137
    5357 *
    5358 *               case SM_PTCH:
    5359 *                       ltmp = pch;
    5360 *
     5357
     5358|               case SM_PTCH:
     5359|                       ltmp = pch;
     5360
    53615361F09L140:        move    PCH(A6),A0
    53625362                move.l  A0,LTMP(A6)
    5363 *
    5364 *                       break;
    5365 *
     5363
     5364|                       break;
     5365
    53665366                bra     F09L137
    5367 *
    5368                 .page
    5369 *
    5370 *               case SM_FREQ:
    5371 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    5372 *
     5367
     5368                .page
     5369
     5370|               case SM_FREQ:
     5371|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     5372
    53735373F09L141:        move    PCH(A6),D0
    53745374                asr     #7,D0
     
    53805380                ext.l   D0
    53815381                move.l  D0,LTMP(A6)
    5382 *
    5383 *                       break;
    5384 *
     5382
     5383|                       break;
     5384
    53855385                bra     F09L137
    5386 *
    5387 *               case SM_KVEL:
    5388 *                       ltmp = veltab[trg];
    5389 *
     5386
     5387|               case SM_KVEL:
     5388|                       ltmp = veltab[trg];
     5389
    53905390F09L142:        move    TRG(A6),A0
    53915391                add.l   A0,A0
     
    53945394                ext.l   D0
    53955395                move.l  D0,LTMP(A6)
    5396 *
    5397 *                       break;
    5398 *
     5396
     5397|                       break;
     5398
    53995399                bra     F09L137
    5400 *
    5401                 .page
    5402 *
    5403 *               case SM_KPRS:
    5404 *                       ltmp = prstab[trg];
    5405 *
     5400
     5401                .page
     5402
     5403|               case SM_KPRS:
     5404|                       ltmp = prstab[trg];
     5405
    54065406F09L143:        move    TRG(A6),A0
    54075407                add.l   A0,A0
     
    54105410                ext.l   D0
    54115411                move.l  D0,LTMP(A6)
    5412 *
    5413 *                       break;
    5414 *
     5412
     5413|                       break;
     5414
    54155415                bra     F09L137
    5416 *
    5417                 .page
    5418 *
    5419 *               default:
    5420 *                       ltmp = valents[group | pt->ipvsrc].val;
    5421 *
     5416
     5417                .page
     5418
     5419|               default:
     5420|                       ltmp = valents[group | pt->ipvsrc].val;
     5421
    54225422F09L144:        move.l  PT(A6),A0
    54235423                clr.l   D0
     
    54335433                move    8(A0,A1.l),D0
    54345434                move.l  D0,LTMP(A6)
    5435 *
    5436 *               }
    5437 *
    5438 *
    5439                 .page
    5440 *
    5441 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    5442 *
     5435
     5436|               }
     5437
     5438
     5439                .page
     5440
     5441|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     5442
    54435443F09L137:        move.l  PT(A6),A0
    54445444                move.w  4(A0),D0
     
    54485448                asr.l   D1,D0
    54495449                move.l  D0,LTMP(A6)
    5450 *
    5451 *               ltmp += (long)pt->ipval;
    5452 *
     5450
     5451|               ltmp += (long)pt->ipval;
     5452
    54535453                move.l  PT(A6),A0
    54545454                move    2(A0),D0
    54555455                ext.l   D0
    54565456                add.l   D0,LTMP(A6)
    5457 *
    5458 *               if (ltmp GT (long)VALMAX)
    5459 *                       ltmp = (long)VALMAX;
    5460 *
     5457
     5458|               if (ltmp GT (long)VALMAX)
     5459|                       ltmp = (long)VALMAX;
     5460
    54615461                cmp.l   #VALMAX,LTMP(A6)
    54625462                ble     F09L146
    5463 *
     5463
    54645464                move.l  #VALMAX,LTMP(A6)
    54655465                bra     F09L147
    5466 *
    5467 *               else if (ltmp LT (long)VALMIN)
    5468 *                       ltmp = (long)VALMIN;
    5469 *
     5466
     5467|               else if (ltmp LT (long)VALMIN)
     5468|                       ltmp = (long)VALMIN;
     5469
    54705470F09L146:        cmp.l   #VALMIN,LTMP(A6)
    54715471                bge     F09L147
    5472 *
     5472
    54735473                move.l  #VALMIN,LTMP(A6)
    5474 *
    5475 *               tfpval = (short)ltmp;
    5476 *
     5474
     5475|               tfpval = (short)ltmp;
     5476
    54775477F09L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    54785478                bra     F09L149
    5479 *
    5480 *       } else {
    5481 *
    5482 *               tfpval = pt->ipval;
    5483 *
     5479
     5480|       } else {
     5481
     5482|               tfpval = pt->ipval;
     5483
    54845484F09L136:        move.l  PT(A6),A0
    54855485                move    2(A0),TFPVAL(A6)
    5486 *
    5487 *       }
    5488 *
    5489                 .page
    5490 *
    5491 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    5492 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    5493 *
     5486
     5487|       }
     5488
     5489                .page
     5490
     5491|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     5492|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     5493
    54945494F09L149:        move.l  PT(A6),A0
    54955495                move.w  (A0),D0
    54965496                move.w  D0,D2
    5497                 andi.w  #$FFF0,D0
     5497                andi.w  #0xFFF0,D0
    54985498                move.w  _timemlt,D1
    54995499                muls    D1,D0
     
    55015501                asr.l   D1,D0
    55025502                move    D0,R_FPMANT
    5503 *
    5504 *       fpexp = expbit[pt->iptim & 0x000F];
    5505 *
    5506                 and     #$000F,D2
     5503
     5504|       fpexp = expbit[pt->iptim & 0x000F];
     5505
     5506                and     #0x000F,D2
    55075507                move    D2,A0
    55085508                add.l   A0,A0
    55095509                add.l   #_expbit,A0
    55105510                move    (A0),R_FPEXP
    5511 *
    5512                 .page
    5513 *
    5514 *               fp->idfpch = pch;
    5515 *
     5511
     5512                .page
     5513
     5514|               fp->idfpch = pch;
     5515
    55165516F09L163:        move    PCH(A6),(A_FP)
    5517 *
    5518 *               fpval = tfpval;
    5519 *
     5517
     5518|               fpval = tfpval;
     5519
    55205520                move    TFPVAL(A6),R_FPVAL
    5521 *
    5522                 .page
    5523 *
     5521
     5522                .page
     5523
    55245524                move.b  5(A_FP),D0
    55255525                ext.w   D0
    55265526                sub.w   #1,D0
    55275527                movea.l PT(A6),A0
    5528 *
    5529 *       oldi = setipl(FPU_DI);
    5530 *
     5528
     5529|       oldi = setipl(FPU_DI);
     5530
    55315531                move    sr,OLDI(A6)
    55325532                move    #FPU_DI,sr
    5533 *
     5533
    55345534F09L168:        clr.b   10(A0)
    55355535                add.l   #12,a0
    55365536                dbra    D0,F09L168
    5537 *
    5538                 .page
    5539 *
    5540 *       fp->idftmd ^= I_NVBITS;
    5541 *
     5537
     5538                .page
     5539
     5540|       fp->idftmd ^= I_NVBITS;
     5541
    55425542F09L165:        eor.b   #24,7(A_FP)
    5543 *
    5544 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    5545 *
     5543
     5544|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     5545
    55465546                move.b  7(A_FP),R_FPCTL
    55475547                and     #28,R_FPCTL
    55485548                or      #3,R_FPCTL
    5549 *
    5550 *       fp->idfcpt = fp->idfpt1;
    5551 *
     5549
     5550|       fp->idfcpt = fp->idfpt1;
     5551
    55525552                move.b  6(A_FP),8(A_FP)
    5553 *
    5554 *       fp->idftmd |= I_ACTIVE;
    5555 *
     5553
     5554|       fp->idftmd |= I_ACTIVE;
     5555
    55565556                or.b    #2,7(A_FP)
    5557 *
    5558 *       fp->idftrf = trg;
    5559 *
     5557
     5558|       fp->idftrf = trg;
     5559
    55605560                move    TRG(A6),10(A_FP)
    5561 *
    5562 *       *(fpu + (long)FPU_TCV1) = srcval;
    5563 *
    5564                 move    SRCVAL(A6),$8(A_FPU)
    5565 *
    5566 *       ++octype;
    5567 *
     5561
     5562|       |(fpu + (long)FPU_TCV1) = srcval;
     5563
     5564                move    SRCVAL(A6),0x8(A_FPU)
     5565
     5566|       ++octype;
     5567
    55685568                add     #1,OCTYPE(A6)
    5569 *
    5570 *       *(fpu + (long)FPU_TSF1) = mltval;
    5571 *
    5572                 move    MLTVAL(A6),$A(A_FPU)
    5573 *
    5574 *       ++octype;
    5575 *
     5569
     5570|       |(fpu + (long)FPU_TSF1) = mltval;
     5571
     5572                move    MLTVAL(A6),0xA(A_FPU)
     5573
     5574|       ++octype;
     5575
    55765576                add     #1,OCTYPE(A6)
    5577 *
    5578 *       *(fpu + (long)FPU_TMNT) = fpmant;
    5579 *
    5580                 move    R_FPMANT,$14(A_FPU)
    5581 *
    5582 *       ++octype;
    5583 *
     5577
     5578|       |(fpu + (long)FPU_TMNT) = fpmant;
     5579
     5580                move    R_FPMANT,0x14(A_FPU)
     5581
     5582|       ++octype;
     5583
    55845584                add     #1,OCTYPE(A6)
    5585 *
    5586 *       *(fpu + (long)FPU_TEXP) = fpexp;
    5587 *
    5588                 move    R_FPEXP,$16(A_FPU)
    5589 *
    5590 *       ++octype;
    5591 *
     5585
     5586|       |(fpu + (long)FPU_TEXP) = fpexp;
     5587
     5588                move    R_FPEXP,0x16(A_FPU)
     5589
     5590|       ++octype;
     5591
    55925592                add     #1,OCTYPE(A6)
    5593 *
    5594                 .page
    5595 *
    5596 *       if (fp->idftmd & I_VNSUBN)
    5597 *
     5593
     5594                .page
     5595
     5596|       if (fp->idftmd & I_VNSUBN)
     5597
    55985598                btst    #3,7(A_FP)
    55995599                beq     F09L169
    5600 *
    5601 *               *(fpu + (long)FPU_TNV1) = fpval;
    5602 *
    5603                 move    R_FPVAL,$1C(A_FPU)
     5600
     5601|               |(fpu + (long)FPU_TNV1) = fpval;
     5602
     5603                move    R_FPVAL,0x1C(A_FPU)
    56045604                bra     F09L170
    5605 *
    5606 *       else
    5607 *               *(fpu + (long)FPU_TNV0) = fpval;
    5608 *
     5605
     5606|       else
     5607|               |(fpu + (long)FPU_TNV0) = fpval;
     5608
    56095609F09L169:        move    R_FPVAL,2(A_FPU)
    5610 *
    5611 *       ++octype;
    5612 *
     5610
     5611|       ++octype;
     5612
    56135613F09L170:        add     #1,OCTYPE(A6)
    5614 *
    5615 *       *(fpu + (long)FPU_TCTL) = fpctl;
    5616 *
     5614
     5615|       |(fpu + (long)FPU_TCTL) = fpctl;
     5616
    56175617                move    R_FPCTL,(A_FPU)
    5618 *
    5619 *       setipl(oldi);
    5620 *
     5618
     5619|       setipl(oldi);
     5620
    56215621                move    OLDI(A6),sr
    5622 *
    5623                 .page
    5624 * ------------------------------------------------------------------------------
    5625 * Start function 10 -- Ind 5
    5626 * ------------------------------------------------------------------------------
    5627 *
    5628 *    if (ip->idhfnc[10].idftmd & I_TM_KEY) {
    5629 *
     5622
     5623                .page
     5624| ------------------------------------------------------------------------------
     5625| Start function 10 -- Ind 5
     5626| ------------------------------------------------------------------------------
     5627
     5628|    if (ip->idhfnc[10].idftmd & I_TM_KEY) {
     5629
    56305630FN10:           move.l  IP(A6),A0
    56315631                move.b  213(A0),D0
     
    56345634                btst    #0,D0
    56355635                bne     FN10A
    5636 *
     5636
    56375637                jmp     FN11
    5638 *
    5639 *       vp = (vce << 4) + 14;
    5640 *
     5638
     5639|       vp = (vce << 4) + 14;
     5640
    56415641FN10A:          move    VCE(A6),D0
    56425642                asl     #4,D0
    56435643                add.w   #14,D0
    56445644                move    D0,VP(A6)
    5645 *
    5646 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    5647 *
     5645
     5646|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     5647
    56485648                asl     #5,D0
    56495649                ext.l   D0
    56505650                move.l  D0,A_FPU
    5651                 add.l   #_io_fpu+$4000,A_FPU
    5652 *
    5653 *       fp = &ip->idhfnc[10];
    5654 *
     5651                add.l   #_io_fpu+0x4000,A_FPU
     5652
     5653|       fp = &ip->idhfnc[10];
     5654
    56555655                move.l  #120,A_FP
    56565656                add.l   IP(A6),A_FP
    56575657                add.l   #86,A_FP
    5658 *
    5659 *       pt = &ip->idhpnt[fp->idfpt1];
    5660 *
     5658
     5659|       pt = &ip->idhpnt[fp->idfpt1];
     5660
    56615661                clr.l   D0
    56625662                move.b  6(A_FP),D0
     
    56685668                add.l   #242,D0
    56695669                move.l  D0,PT(A6)
    5670 *
    5671                 .page
    5672 *
    5673 *       srcnum = group | fp->idfsrc;
    5674 *
     5670
     5671                .page
     5672
     5673|       srcnum = group | fp->idfsrc;
     5674
    56755675                move.w  GROUP(A6),D0
    56765676                ext.l   D0
     
    56795679                or      D1,D0
    56805680                move    D0,SRCNUM(A6)
    5681 *
    5682 *       vep = &valents[srcnum];
    5683 *
     5681
     5682|       vep = &valents[srcnum];
     5683
    56845684                add.l   D0,D0
    56855685                move.l  D0,D1
     
    56885688                add.l   #_valents,D0
    56895689                move.l  D0,VEP(A6)
    5690 *
    5691 *       smp = vpsms[vp];
    5692 *
     5690
     5691|       smp = vpsms[vp];
     5692
    56935693                move    VP(A6),A0
    56945694                add.l   A0,A0
     
    56965696                add.l   #_vpsms,A0
    56975697                move.l  (A0),A_SMP
    5698 *
    5699 *       if (srcnum NE smp->sm) {
    5700 *
     5698
     5699|       if (srcnum NE smp->sm) {
     5700
    57015701                clr     D0
    57025702                move    10(A_SMP),D0
    57035703                cmp     SRCNUM(A6),D0
    57045704                beq     F10L113
    5705 *
    5706 *               (smp->prv)->nxt = smp->nxt;
    5707 *
     5705
     5706|               (smp->prv)->nxt = smp->nxt;
     5707
    57085708                move.l  4(A_SMP),A0
    57095709                move.l  (A_SMP),(A0)
    5710 *
    5711 *               (smp->nxt)->prv = smp->prv;
    5712 *
     5710
     5711|               (smp->nxt)->prv = smp->prv;
     5712
    57135713                move.l  (A_SMP),A0
    57145714                move.l  4(A_SMP),4(A0)
    5715 *
    5716 *               smp->prv = (struct sment *)vep;
    5717 *
     5715
     5716|               smp->prv = (struct sment |)vep;
     5717
    57185718                move.l  VEP(A6),4(A_SMP)
    5719 *
    5720 *               smp->nxt = vep->nxt;
    5721 *
     5719
     5720|               smp->nxt = vep->nxt;
     5721
    57225722                move.l  VEP(A6),A0
    57235723                move.l  (A0),(A_SMP)
    5724 *
    5725 *               (vep->nxt)->prv = smp;
    5726 *
     5724
     5725|               (vep->nxt)->prv = smp;
     5726
    57275727                move.l  VEP(A6),A0
    57285728                move.l  (A0),A0
    57295729                move.l  A_SMP,4(A0)
    5730 *
    5731 *               vep->nxt = smp;
    5732 *
     5730
     5731|               vep->nxt = smp;
     5732
    57335733                move.l  VEP(A6),A0
    57345734                move.l  A_SMP,(A0)
    5735 *
    5736 *               smp->sm = srcnum;
    5737 *
     5735
     5736|               smp->sm = srcnum;
     5737
    57385738                move    SRCNUM(A6),10(A_SMP)
    5739 *
    5740 *       }
    5741 *
    5742 *       mltval = fp->idfmlt;
    5743 *
     5739
     5740|       }
     5741
     5742|       mltval = fp->idfmlt;
     5743
    57445744F10L113:        move    2(A_FP),MLTVAL(A6)
    5745 *
    5746                 .page
    5747 *
    5748 *       switch (fp->idfsrc) {
    5749 *
     5745
     5746                .page
     5747
     5748|       switch (fp->idfsrc) {
     5749
    57505750                move.b  4(A_FP),D0
    57515751                ext.w   d0
    57525752                cmp     #10,D0
    57535753                bhi     F10L122
    5754 *
     5754
    57555755                asl     #2,D0
    57565756                lea     F10L123,A0
    57575757                movea.l 0(A0,D0.W),A0
    57585758                jmp     (A0)
    5759 *
    5760 *       case SM_NONE:
    5761 *               mltval = 0;
    5762 *
     5759
     5760|       case SM_NONE:
     5761|               mltval = 0;
     5762
    57635763F10L116:        clr     MLTVAL(A6)
    5764 *
    5765 *               tsrcval = 0;
    5766 *
     5764
     5765|               tsrcval = 0;
     5766
    57675767                clr     TSRCVAL(A6)
    5768 *
    5769 *               break;
    5770 *
     5768
     5769|               break;
     5770
    57715771                bra     F10L114
    5772 *
    5773 *       case SM_RAND:
    5774 *               tsrcval = xgetran(mltval);
    5775 *
     5772
     5773|       case SM_RAND:
     5774|               tsrcval = xgetran(mltval);
     5775
    57765776F10L117:        move    MLTVAL(A6),(sp)
    57775777                jsr     _xgetran
    57785778                move    D0,TSRCVAL(A6)
    5779 *
    5780 *               break;
    5781 *
     5779
     5780|               break;
     5781
    57825782                bra     F10L114
    5783 *
    5784 *       case SM_PTCH:
    5785 *               tsrcval = pch;
    5786 *
     5783
     5784|       case SM_PTCH:
     5785|               tsrcval = pch;
     5786
    57875787F10L118:        move    PCH(A6),TSRCVAL(A6)
    5788 *
    5789 *               break;
    5790 *
     5788
     5789|               break;
     5790
    57915791                bra     F10L114
    5792 *
    5793                 .page
    5794 *
    5795 *       case SM_FREQ:
    5796 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    5797 *
     5792
     5793                .page
     5794
     5795|       case SM_FREQ:
     5796|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     5797
    57985798F10L119:        move    PCH(A6),D0
    57995799                asr     #7,D0
     
    58035803                add.l   #_ptoftab,A0
    58045804                move    (A0),TSRCVAL(A6)
    5805 *
    5806 *               break;
    5807 *
     5805
     5806|               break;
     5807
    58085808                bra     F10L114
    5809 *
    5810 *       case SM_KVEL:
    5811 *               tsrcval = veltab[trg];
    5812 *
     5809
     5810|       case SM_KVEL:
     5811|               tsrcval = veltab[trg];
     5812
    58135813F10L120:        move    TRG(A6),A0
    58145814                add.l   A0,A0
    58155815                add.l   #_veltab,A0
    58165816                move    (A0),TSRCVAL(A6)
    5817 *
    5818 *               break;
    5819 *
     5817
     5818|               break;
     5819
    58205820                bra     F10L114
    5821 *
    5822 *       case SM_KPRS:
    5823 *               tsrcval = prstab[trg];
    5824 *
     5821
     5822|       case SM_KPRS:
     5823|               tsrcval = prstab[trg];
     5824
    58255825F10L121:        move    TRG(A6),A0
    58265826                add.l   A0,A0
    58275827                add.l   #_prstab,A0
    58285828                move    (A0),TSRCVAL(A6)
    5829 *
    5830 *               break;
    5831 *
     5829
     5830|               break;
     5831
    58325832                bra     F10L114
    5833 *
    5834 *       default:
    5835 *               tsrcval = vep->val;
    5836 *
     5833
     5834|       default:
     5835|               tsrcval = vep->val;
     5836
    58375837F10L122:        move.l  VEP(A6),A0
    58385838                move    8(A0),TSRCVAL(A6)
    5839 *
    5840 *       }
    5841 *
    5842                 .page
    5843 *
    5844 *               srcval = tsrcval;
    5845 *
     5839
     5840|       }
     5841
     5842                .page
     5843
     5844|               srcval = tsrcval;
     5845
    58465846F10L114:        move    TSRCVAL(A6),SRCVAL(A6)
    5847 *
    5848                 .page
    5849 *
    5850 *       if (pt->ipvsrc) {
    5851 *
     5847
     5848                .page
     5849
     5850|       if (pt->ipvsrc) {
     5851
    58525852F10L124:        move.l  PT(A6),A0
    58535853                tst.b   6(A0)
    58545854                beq     F10L136
    5855 *
    5856 *               switch (pt->ipvsrc) {
    5857 *
     5855
     5856|               switch (pt->ipvsrc) {
     5857
    58585858                move.l  PT(A6),A0
    58595859                move.b  6(A0),D0
     
    58625862                cmp     #9,D0
    58635863                bhi     F10L144
    5864 *
     5864
    58655865                asl     #2,D0
    58665866                lea     F10L145,A0
    58675867                move.l  0(A0,D0.W),A0
    58685868                jmp     (A0)
    5869 *
    5870 *               case SM_RAND:
    5871 *                       ltmp = xgetran(pt_>ipvmlt);
    5872 *
     5869
     5870|               case SM_RAND:
     5871|                       ltmp = xgetran(pt_>ipvmlt);
     5872
    58735873F10L139:        move.l  PT(A6),A0
    58745874                move    4(A0),(sp)
     
    58765876                ext.l   D0
    58775877                move.l  D0,LTMP(A6)
    5878 *
    5879 *                       break;
    5880 *
     5878
     5879|                       break;
     5880
    58815881                bra     F10L137
    5882 *
    5883 *               case SM_PTCH:
    5884 *                       ltmp = pch;
    5885 *
     5882
     5883|               case SM_PTCH:
     5884|                       ltmp = pch;
     5885
    58865886F10L140:        move    PCH(A6),A0
    58875887                move.l  A0,LTMP(A6)
    5888 *
    5889 *                       break;
    5890 *
     5888
     5889|                       break;
     5890
    58915891                bra     F10L137
    5892 *
    5893                 .page
    5894 *
    5895 *               case SM_FREQ:
    5896 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    5897 *
     5892
     5893                .page
     5894
     5895|               case SM_FREQ:
     5896|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     5897
    58985898F10L141:        move    PCH(A6),D0
    58995899                asr     #7,D0
     
    59055905                ext.l   D0
    59065906                move.l  D0,LTMP(A6)
    5907 *
    5908 *                       break;
    5909 *
     5907
     5908|                       break;
     5909
    59105910                bra     F10L137
    5911 *
    5912 *               case SM_KVEL:
    5913 *                       ltmp = veltab[trg];
    5914 *
     5911
     5912|               case SM_KVEL:
     5913|                       ltmp = veltab[trg];
     5914
    59155915F10L142:        move    TRG(A6),A0
    59165916                add.l   A0,A0
     
    59195919                ext.l   D0
    59205920                move.l  D0,LTMP(A6)
    5921 *
    5922 *                       break;
    5923 *
     5921
     5922|                       break;
     5923
    59245924                bra     F10L137
    5925 *
    5926                 .page
    5927 *
    5928 *               case SM_KPRS:
    5929 *                       ltmp = prstab[trg];
    5930 *
     5925
     5926                .page
     5927
     5928|               case SM_KPRS:
     5929|                       ltmp = prstab[trg];
     5930
    59315931F10L143:        move    TRG(A6),A0
    59325932                add.l   A0,A0
     
    59355935                ext.l   D0
    59365936                move.l  D0,LTMP(A6)
    5937 *
    5938 *                       break;
    5939 *
     5937
     5938|                       break;
     5939
    59405940                bra     F10L137
    5941 *
    5942                 .page
    5943 *
    5944 *               default:
    5945 *                       ltmp = valents[group | pt->ipvsrc].val;
    5946 *
     5941
     5942                .page
     5943
     5944|               default:
     5945|                       ltmp = valents[group | pt->ipvsrc].val;
     5946
    59475947F10L144:        move.l  PT(A6),A0
    59485948                clr.l   D0
     
    59585958                move    8(A0,A1.l),D0
    59595959                move.l  D0,LTMP(A6)
    5960 *
    5961 *               }
    5962 *
    5963 *
    5964                 .page
    5965 *
    5966 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    5967 *
     5960
     5961|               }
     5962
     5963
     5964                .page
     5965
     5966|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     5967
    59685968F10L137:        move.l  PT(A6),A0
    59695969                move.w  4(A0),D0
     
    59735973                asr.l   D1,D0
    59745974                move.l  D0,LTMP(A6)
    5975 *
    5976 *               ltmp += (long)pt->ipval;
    5977 *
     5975
     5976|               ltmp += (long)pt->ipval;
     5977
    59785978                move.l  PT(A6),A0
    59795979                move    2(A0),D0
    59805980                ext.l   D0
    59815981                add.l   D0,LTMP(A6)
    5982 *
    5983 *               if (ltmp GT (long)VALMAX)
    5984 *                       ltmp = (long)VALMAX;
    5985 *
     5982
     5983|               if (ltmp GT (long)VALMAX)
     5984|                       ltmp = (long)VALMAX;
     5985
    59865986                cmp.l   #VALMAX,LTMP(A6)
    59875987                ble     F10L146
    5988 *
     5988
    59895989                move.l  #VALMAX,LTMP(A6)
    59905990                bra     F10L147
    5991 *
    5992 *               else if (ltmp LT (long)VALMIN)
    5993 *                       ltmp = (long)VALMIN;
    5994 *
     5991
     5992|               else if (ltmp LT (long)VALMIN)
     5993|                       ltmp = (long)VALMIN;
     5994
    59955995F10L146:        cmp.l   #VALMIN,LTMP(A6)
    59965996                bge     F10L147
    5997 *
     5997
    59985998                move.l  #VALMIN,LTMP(A6)
    5999 *
    6000 *               tfpval = (short)ltmp;
    6001 *
     5999
     6000|               tfpval = (short)ltmp;
     6001
    60026002F10L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    60036003                bra     F10L149
    6004 *
    6005 *       } else {
    6006 *
    6007 *               tfpval = pt->ipval;
    6008 *
     6004
     6005|       } else {
     6006
     6007|               tfpval = pt->ipval;
     6008
    60096009F10L136:        move.l  PT(A6),A0
    60106010                move    2(A0),TFPVAL(A6)
    6011 *
    6012 *       }
    6013 *
    6014                 .page
    6015 *
    6016 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    6017 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    6018 *
     6011
     6012|       }
     6013
     6014                .page
     6015
     6016|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     6017|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     6018
    60196019F10L149:        move.l  PT(A6),A0
    60206020                move.w  (A0),D0
    60216021                move.w  D0,D2
    6022                 andi.w  #$FFF0,D0
     6022                andi.w  #0xFFF0,D0
    60236023                move.w  _timemlt,D1
    60246024                muls    D1,D0
     
    60266026                asr.l   D1,D0
    60276027                move    D0,R_FPMANT
    6028 *
    6029 *       fpexp = expbit[pt->iptim & 0x000F];
    6030 *
    6031                 and     #$000F,D2
     6028
     6029|       fpexp = expbit[pt->iptim & 0x000F];
     6030
     6031                and     #0x000F,D2
    60326032                move    D2,A0
    60336033                add.l   A0,A0
    60346034                add.l   #_expbit,A0
    60356035                move    (A0),R_FPEXP
    6036 *
    6037                 .page
    6038 *
    6039 *               fp->idfpch = pch;
    6040 *
     6036
     6037                .page
     6038
     6039|               fp->idfpch = pch;
     6040
    60416041F10L163:        move    PCH(A6),(A_FP)
    6042 *
    6043 *               fpval = tfpval;
    6044 *
     6042
     6043|               fpval = tfpval;
     6044
    60456045                move    TFPVAL(A6),R_FPVAL
    6046 *
    6047                 .page
    6048 *
     6046
     6047                .page
     6048
    60496049                move.b  5(A_FP),D0
    60506050                ext.w   D0
    60516051                sub.w   #1,D0
    60526052                movea.l PT(A6),A0
    6053 *
    6054 *       oldi = setipl(FPU_DI);
    6055 *
     6053
     6054|       oldi = setipl(FPU_DI);
     6055
    60566056                move    sr,OLDI(A6)
    60576057                move    #FPU_DI,sr
    6058 *
     6058
    60596059F10L168:        clr.b   10(A0)
    60606060                add.l   #12,a0
    60616061                dbra    D0,F10L168
    6062 *
    6063                 .page
    6064 *
    6065 *       fp->idftmd ^= I_NVBITS;
    6066 *
     6062
     6063                .page
     6064
     6065|       fp->idftmd ^= I_NVBITS;
     6066
    60676067F10L165:        eor.b   #24,7(A_FP)
    6068 *
    6069 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    6070 *
     6068
     6069|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     6070
    60716071                move.b  7(A_FP),R_FPCTL
    60726072                and     #28,R_FPCTL
    60736073                or      #3,R_FPCTL
    6074 *
    6075 *       fp->idfcpt = fp->idfpt1;
    6076 *
     6074
     6075|       fp->idfcpt = fp->idfpt1;
     6076
    60776077                move.b  6(A_FP),8(A_FP)
    6078 *
    6079 *       fp->idftmd |= I_ACTIVE;
    6080 *
     6078
     6079|       fp->idftmd |= I_ACTIVE;
     6080
    60816081                or.b    #2,7(A_FP)
    6082 *
    6083 *       fp->idftrf = trg;
    6084 *
     6082
     6083|       fp->idftrf = trg;
     6084
    60856085                move    TRG(A6),10(A_FP)
    6086 *
    6087 *       *(fpu + (long)FPU_TCV1) = srcval;
    6088 *
    6089                 move    SRCVAL(A6),$8(A_FPU)
    6090 *
    6091 *       ++octype;
    6092 *
     6086
     6087|       |(fpu + (long)FPU_TCV1) = srcval;
     6088
     6089                move    SRCVAL(A6),0x8(A_FPU)
     6090
     6091|       ++octype;
     6092
    60936093                add     #1,OCTYPE(A6)
    6094 *
    6095 *       *(fpu + (long)FPU_TSF1) = mltval;
    6096 *
    6097                 move    MLTVAL(A6),$A(A_FPU)
    6098 *
    6099 *       ++octype;
    6100 *
     6094
     6095|       |(fpu + (long)FPU_TSF1) = mltval;
     6096
     6097                move    MLTVAL(A6),0xA(A_FPU)
     6098
     6099|       ++octype;
     6100
    61016101                add     #1,OCTYPE(A6)
    6102 *
    6103 *       *(fpu + (long)FPU_TMNT) = fpmant;
    6104 *
    6105                 move    R_FPMANT,$14(A_FPU)
    6106 *
    6107 *       ++octype;
    6108 *
     6102
     6103|       |(fpu + (long)FPU_TMNT) = fpmant;
     6104
     6105                move    R_FPMANT,0x14(A_FPU)
     6106
     6107|       ++octype;
     6108
    61096109                add     #1,OCTYPE(A6)
    6110 *
    6111 *       *(fpu + (long)FPU_TEXP) = fpexp;
    6112 *
    6113                 move    R_FPEXP,$16(A_FPU)
    6114 *
    6115 *       ++octype;
    6116 *
     6110
     6111|       |(fpu + (long)FPU_TEXP) = fpexp;
     6112
     6113                move    R_FPEXP,0x16(A_FPU)
     6114
     6115|       ++octype;
     6116
    61176117                add     #1,OCTYPE(A6)
    6118 *
    6119                 .page
    6120 *
    6121 *       if (fp->idftmd & I_VNSUBN)
    6122 *
     6118
     6119                .page
     6120
     6121|       if (fp->idftmd & I_VNSUBN)
     6122
    61236123                btst    #3,7(A_FP)
    61246124                beq     F10L169
    6125 *
    6126 *               *(fpu + (long)FPU_TNV1) = fpval;
    6127 *
    6128                 move    R_FPVAL,$1C(A_FPU)
     6125
     6126|               |(fpu + (long)FPU_TNV1) = fpval;
     6127
     6128                move    R_FPVAL,0x1C(A_FPU)
    61296129                bra     F10L170
    6130 *
    6131 *       else
    6132 *               *(fpu + (long)FPU_TNV0) = fpval;
    6133 *
     6130
     6131|       else
     6132|               |(fpu + (long)FPU_TNV0) = fpval;
     6133
    61346134F10L169:        move    R_FPVAL,2(A_FPU)
    6135 *
    6136 *       ++octype;
    6137 *
     6135
     6136|       ++octype;
     6137
    61386138F10L170:        add     #1,OCTYPE(A6)
    6139 *
    6140 *       *(fpu + (long)FPU_TCTL) = fpctl;
    6141 *
     6139
     6140|       |(fpu + (long)FPU_TCTL) = fpctl;
     6141
    61426142                move    R_FPCTL,(A_FPU)
    6143 *
    6144 *       setipl(oldi);
    6145 *
     6143
     6144|       setipl(oldi);
     6145
    61466146                move    OLDI(A6),sr
    6147 *
    6148                 .page
    6149 * ------------------------------------------------------------------------------
    6150 * Start function 11 -- Ind 6
    6151 * ------------------------------------------------------------------------------
    6152 *
    6153 *    if (ip->idhfnc[11].idftmd & I_TM_KEY) {
    6154 *
     6147
     6148                .page
     6149| ------------------------------------------------------------------------------
     6150| Start function 11 -- Ind 6
     6151| ------------------------------------------------------------------------------
     6152
     6153|    if (ip->idhfnc[11].idftmd & I_TM_KEY) {
     6154
    61556155FN11:           move.l  IP(A6),A0
    61566156                move.b  225(A0),D0
     
    61596159                btst    #0,D0
    61606160                bne     FN11A
    6161 *
     6161
    61626162                jmp     FN12
    6163 *
    6164 *       vp = (vce << 4) + 15;
    6165 *
     6163
     6164|       vp = (vce << 4) + 15;
     6165
    61666166FN11A:          move    VCE(A6),D0
    61676167                asl     #4,D0
    61686168                add.w   #15,D0
    61696169                move    D0,VP(A6)
    6170 *
    6171 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    6172 *
     6170
     6171|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     6172
    61736173                asl     #5,D0
    61746174                ext.l   D0
    61756175                move.l  D0,A_FPU
    6176                 add.l   #_io_fpu+$4000,A_FPU
    6177 *
    6178 *       fp = &ip->idhfnc[11];
    6179 *
     6176                add.l   #_io_fpu+0x4000,A_FPU
     6177
     6178|       fp = &ip->idhfnc[11];
     6179
    61806180                move.l  #132,A_FP
    61816181                add.l   IP(A6),A_FP
    61826182                add.l   #86,A_FP
    6183 *
    6184 *       pt = &ip->idhpnt[fp->idfpt1];
    6185 *
     6183
     6184|       pt = &ip->idhpnt[fp->idfpt1];
     6185
    61866186                clr.l   D0
    61876187                move.b  6(A_FP),D0
     
    61936193                add.l   #242,D0
    61946194                move.l  D0,PT(A6)
    6195 *
    6196                 .page
    6197 *
    6198 *       srcnum = group | fp->idfsrc;
    6199 *
     6195
     6196                .page
     6197
     6198|       srcnum = group | fp->idfsrc;
     6199
    62006200                move.w  GROUP(A6),D0
    62016201                ext.l   D0
     
    62046204                or      D1,D0
    62056205                move    D0,SRCNUM(A6)
    6206 *
    6207 *       vep = &valents[srcnum];
    6208 *
     6206
     6207|       vep = &valents[srcnum];
     6208
    62096209                add.l   D0,D0
    62106210                move.l  D0,D1
     
    62136213                add.l   #_valents,D0
    62146214                move.l  D0,VEP(A6)
    6215 *
    6216 *       smp = vpsms[vp];
    6217 *
     6215
     6216|       smp = vpsms[vp];
     6217
    62186218                move    VP(A6),A0
    62196219                add.l   A0,A0
     
    62216221                add.l   #_vpsms,A0
    62226222                move.l  (A0),A_SMP
    6223 *
    6224 *       if (srcnum NE smp->sm) {
    6225 *
     6223
     6224|       if (srcnum NE smp->sm) {
     6225
    62266226                clr     D0
    62276227                move    10(A_SMP),D0
    62286228                cmp     SRCNUM(A6),D0
    62296229                beq     F11L113
    6230 *
    6231 *               (smp->prv)->nxt = smp->nxt;
    6232 *
     6230
     6231|               (smp->prv)->nxt = smp->nxt;
     6232
    62336233                move.l  4(A_SMP),A0
    62346234                move.l  (A_SMP),(A0)
    6235 *
    6236 *               (smp->nxt)->prv = smp->prv;
    6237 *
     6235
     6236|               (smp->nxt)->prv = smp->prv;
     6237
    62386238                move.l  (A_SMP),A0
    62396239                move.l  4(A_SMP),4(A0)
    6240 *
    6241 *               smp->prv = (struct sment *)vep;
    6242 *
     6240
     6241|               smp->prv = (struct sment |)vep;
     6242
    62436243                move.l  VEP(A6),4(A_SMP)
    6244 *
    6245 *               smp->nxt = vep->nxt;
    6246 *
     6244
     6245|               smp->nxt = vep->nxt;
     6246
    62476247                move.l  VEP(A6),A0
    62486248                move.l  (A0),(A_SMP)
    6249 *
    6250 *               (vep->nxt)->prv = smp;
    6251 *
     6249
     6250|               (vep->nxt)->prv = smp;
     6251
    62526252                move.l  VEP(A6),A0
    62536253                move.l  (A0),A0
    62546254                move.l  A_SMP,4(A0)
    6255 *
    6256 *               vep->nxt = smp;
    6257 *
     6255
     6256|               vep->nxt = smp;
     6257
    62586258                move.l  VEP(A6),A0
    62596259                move.l  A_SMP,(A0)
    6260 *
    6261 *               smp->sm = srcnum;
    6262 *
     6260
     6261|               smp->sm = srcnum;
     6262
    62636263                move    SRCNUM(A6),10(A_SMP)
    6264 *
    6265 *       }
    6266 *
    6267 *       mltval = fp->idfmlt;
    6268 *
     6264
     6265|       }
     6266
     6267|       mltval = fp->idfmlt;
     6268
    62696269F11L113:        move    2(A_FP),MLTVAL(A6)
    6270 *
    6271                 .page
    6272 *
    6273 *       switch (fp->idfsrc) {
    6274 *
     6270
     6271                .page
     6272
     6273|       switch (fp->idfsrc) {
     6274
    62756275                move.b  4(A_FP),D0
    62766276                ext.w   d0
    62776277                cmp     #10,D0
    62786278                bhi     F11L122
    6279 *
     6279
    62806280                asl     #2,D0
    62816281                lea     F11L123,A0
    62826282                movea.l 0(A0,D0.W),A0
    62836283                jmp     (A0)
    6284 *
    6285 *       case SM_NONE:
    6286 *               mltval = 0;
    6287 *
     6284
     6285|       case SM_NONE:
     6286|               mltval = 0;
     6287
    62886288F11L116:        clr     MLTVAL(A6)
    6289 *
    6290 *               tsrcval = 0;
    6291 *
     6289
     6290|               tsrcval = 0;
     6291
    62926292                clr     TSRCVAL(A6)
    6293 *
    6294 *               break;
    6295 *
     6293
     6294|               break;
     6295
    62966296                bra     F11L114
    6297 *
    6298 *       case SM_RAND:
    6299 *               tsrcval = xgetran(mltval);
    6300 *
     6297
     6298|       case SM_RAND:
     6299|               tsrcval = xgetran(mltval);
     6300
    63016301F11L117:        move    MLTVAL(A6),(sp)
    63026302                jsr     _xgetran
    63036303                move    D0,TSRCVAL(A6)
    6304 *
    6305 *               break;
    6306 *
     6304
     6305|               break;
     6306
    63076307                bra     F11L114
    6308 *
    6309 *       case SM_PTCH:
    6310 *               tsrcval = pch;
    6311 *
     6308
     6309|       case SM_PTCH:
     6310|               tsrcval = pch;
     6311
    63126312F11L118:        move    PCH(A6),TSRCVAL(A6)
    6313 *
    6314 *               break;
    6315 *
     6313
     6314|               break;
     6315
    63166316                bra     F11L114
    6317 *
    6318                 .page
    6319 *
    6320 *       case SM_FREQ:
    6321 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    6322 *
     6317
     6318                .page
     6319
     6320|       case SM_FREQ:
     6321|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     6322
    63236323F11L119:        move    PCH(A6),D0
    63246324                asr     #7,D0
     
    63286328                add.l   #_ptoftab,A0
    63296329                move    (A0),TSRCVAL(A6)
    6330 *
    6331 *               break;
    6332 *
     6330
     6331|               break;
     6332
    63336333                bra     F11L114
    6334 *
    6335 *       case SM_KVEL:
    6336 *               tsrcval = veltab[trg];
    6337 *
     6334
     6335|       case SM_KVEL:
     6336|               tsrcval = veltab[trg];
     6337
    63386338F11L120:        move    TRG(A6),A0
    63396339                add.l   A0,A0
    63406340                add.l   #_veltab,A0
    63416341                move    (A0),TSRCVAL(A6)
    6342 *
    6343 *               break;
    6344 *
     6342
     6343|               break;
     6344
    63456345                bra     F11L114
    6346 *
    6347 *       case SM_KPRS:
    6348 *               tsrcval = prstab[trg];
    6349 *
     6346
     6347|       case SM_KPRS:
     6348|               tsrcval = prstab[trg];
     6349
    63506350F11L121:        move    TRG(A6),A0
    63516351                add.l   A0,A0
    63526352                add.l   #_prstab,A0
    63536353                move    (A0),TSRCVAL(A6)
    6354 *
    6355 *               break;
    6356 *
     6354
     6355|               break;
     6356
    63576357                bra     F11L114
    6358 *
    6359 *       default:
    6360 *               tsrcval = vep->val;
    6361 *
     6358
     6359|       default:
     6360|               tsrcval = vep->val;
     6361
    63626362F11L122:        move.l  VEP(A6),A0
    63636363                move    8(A0),TSRCVAL(A6)
    6364 *
    6365 *       }
    6366 *
    6367                 .page
    6368 *
    6369 *               srcval = tsrcval;
    6370 *
     6364
     6365|       }
     6366
     6367                .page
     6368
     6369|               srcval = tsrcval;
     6370
    63716371F11L114:        move    TSRCVAL(A6),SRCVAL(A6)
    6372 *
    6373                 .page
    6374 *
    6375 *       if (pt->ipvsrc) {
    6376 *
     6372
     6373                .page
     6374
     6375|       if (pt->ipvsrc) {
     6376
    63776377F11L124:        move.l  PT(A6),A0
    63786378                tst.b   6(A0)
    63796379                beq     F11L136
    6380 *
    6381 *               switch (pt->ipvsrc) {
    6382 *
     6380
     6381|               switch (pt->ipvsrc) {
     6382
    63836383                move.l  PT(A6),A0
    63846384                move.b  6(A0),D0
     
    63876387                cmp     #9,D0
    63886388                bhi     F11L144
    6389 *
     6389
    63906390                asl     #2,D0
    63916391                lea     F11L145,A0
    63926392                move.l  0(A0,D0.W),A0
    63936393                jmp     (A0)
    6394 *
    6395 *               case SM_RAND:
    6396 *                       ltmp = xgetran(pt_>ipvmlt);
    6397 *
     6394
     6395|               case SM_RAND:
     6396|                       ltmp = xgetran(pt_>ipvmlt);
     6397
    63986398F11L139:        move.l  PT(A6),A0
    63996399                move    4(A0),(sp)
     
    64016401                ext.l   D0
    64026402                move.l  D0,LTMP(A6)
    6403 *
    6404 *                       break;
    6405 *
     6403
     6404|                       break;
     6405
    64066406                bra     F11L137
    6407 *
    6408 *               case SM_PTCH:
    6409 *                       ltmp = pch;
    6410 *
     6407
     6408|               case SM_PTCH:
     6409|                       ltmp = pch;
     6410
    64116411F11L140:        move    PCH(A6),A0
    64126412                move.l  A0,LTMP(A6)
    6413 *
    6414 *                       break;
    6415 *
     6413
     6414|                       break;
     6415
    64166416                bra     F11L137
    6417 *
    6418                 .page
    6419 *
    6420 *               case SM_FREQ:
    6421 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    6422 *
     6417
     6418                .page
     6419
     6420|               case SM_FREQ:
     6421|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     6422
    64236423F11L141:        move    PCH(A6),D0
    64246424                asr     #7,D0
     
    64306430                ext.l   D0
    64316431                move.l  D0,LTMP(A6)
    6432 *
    6433 *                       break;
    6434 *
     6432
     6433|                       break;
     6434
    64356435                bra     F11L137
    6436 *
    6437 *               case SM_KVEL:
    6438 *                       ltmp = veltab[trg];
    6439 *
     6436
     6437|               case SM_KVEL:
     6438|                       ltmp = veltab[trg];
     6439
    64406440F11L142:        move    TRG(A6),A0
    64416441                add.l   A0,A0
     
    64446444                ext.l   D0
    64456445                move.l  D0,LTMP(A6)
    6446 *
    6447 *                       break;
    6448 *
     6446
     6447|                       break;
     6448
    64496449                bra     F11L137
    6450 *
    6451                 .page
    6452 *
    6453 *               case SM_KPRS:
    6454 *                       ltmp = prstab[trg];
    6455 *
     6450
     6451                .page
     6452
     6453|               case SM_KPRS:
     6454|                       ltmp = prstab[trg];
     6455
    64566456F11L143:        move    TRG(A6),A0
    64576457                add.l   A0,A0
     
    64606460                ext.l   D0
    64616461                move.l  D0,LTMP(A6)
    6462 *
    6463 *                       break;
    6464 *
     6462
     6463|                       break;
     6464
    64656465                bra     F11L137
    6466 *
    6467                 .page
    6468 *
    6469 *               default:
    6470 *                       ltmp = valents[group | pt->ipvsrc].val;
    6471 *
     6466
     6467                .page
     6468
     6469|               default:
     6470|                       ltmp = valents[group | pt->ipvsrc].val;
     6471
    64726472F11L144:        move.l  PT(A6),A0
    64736473                clr.l   D0
     
    64836483                move    8(A0,A1.l),D0
    64846484                move.l  D0,LTMP(A6)
    6485 *
    6486 *               }
    6487 *
    6488 *
    6489                 .page
    6490 *
    6491 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    6492 *
     6485
     6486|               }
     6487
     6488
     6489                .page
     6490
     6491|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     6492
    64936493F11L137:        move.l  PT(A6),A0
    64946494                move.w  4(A0),D0
     
    64986498                asr.l   D1,D0
    64996499                move.l  D0,LTMP(A6)
    6500 *
    6501 *               ltmp += (long)pt->ipval;
    6502 *
     6500
     6501|               ltmp += (long)pt->ipval;
     6502
    65036503                move.l  PT(A6),A0
    65046504                move    2(A0),D0
    65056505                ext.l   D0
    65066506                add.l   D0,LTMP(A6)
    6507 *
    6508 *               if (ltmp GT (long)VALMAX)
    6509 *                       ltmp = (long)VALMAX;
    6510 *
     6507
     6508|               if (ltmp GT (long)VALMAX)
     6509|                       ltmp = (long)VALMAX;
     6510
    65116511                cmp.l   #VALMAX,LTMP(A6)
    65126512                ble     F11L146
    6513 *
     6513
    65146514                move.l  #VALMAX,LTMP(A6)
    65156515                bra     F11L147
    6516 *
    6517 *               else if (ltmp LT (long)VALMIN)
    6518 *                       ltmp = (long)VALMIN;
    6519 *
     6516
     6517|               else if (ltmp LT (long)VALMIN)
     6518|                       ltmp = (long)VALMIN;
     6519
    65206520F11L146:        cmp.l   #VALMIN,LTMP(A6)
    65216521                bge     F11L147
    6522 *
     6522
    65236523                move.l  #VALMIN,LTMP(A6)
    6524 *
    6525 *               tfpval = (short)ltmp;
    6526 *
     6524
     6525|               tfpval = (short)ltmp;
     6526
    65276527F11L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    65286528                bra     F11L149
    6529 *
    6530 *       } else {
    6531 *
    6532 *               tfpval = pt->ipval;
    6533 *
     6529
     6530|       } else {
     6531
     6532|               tfpval = pt->ipval;
     6533
    65346534F11L136:        move.l  PT(A6),A0
    65356535                move    2(A0),TFPVAL(A6)
    6536 *
    6537 *       }
    6538 *
    6539                 .page
    6540 *
    6541 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    6542 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    6543 *
     6536
     6537|       }
     6538
     6539                .page
     6540
     6541|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     6542|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     6543
    65446544F11L149:        move.l  PT(A6),A0
    65456545                move.w  (A0),D0
    65466546                move.w  D0,D2
    6547                 andi.w  #$FFF0,D0
     6547                andi.w  #0xFFF0,D0
    65486548                move.w  _timemlt,D1
    65496549                muls    D1,D0
     
    65516551                asr.l   D1,D0
    65526552                move    D0,R_FPMANT
    6553 *
    6554 *       fpexp = expbit[pt->iptim & 0x000F];
    6555 *
    6556                 and     #$000F,D2
     6553
     6554|       fpexp = expbit[pt->iptim & 0x000F];
     6555
     6556                and     #0x000F,D2
    65576557                move    D2,A0
    65586558                add.l   A0,A0
    65596559                add.l   #_expbit,A0
    65606560                move    (A0),R_FPEXP
    6561 *
    6562                 .page
    6563 *
    6564 *               fp->idfpch = pch;
    6565 *
     6561
     6562                .page
     6563
     6564|               fp->idfpch = pch;
     6565
    65666566F11L163:        move    PCH(A6),(A_FP)
    6567 *
    6568 *               fpval = tfpval;
    6569 *
     6567
     6568|               fpval = tfpval;
     6569
    65706570                move    TFPVAL(A6),R_FPVAL
    6571 *
    6572                 .page
    6573 *
     6571
     6572                .page
     6573
    65746574                move.b  5(A_FP),D0
    65756575                ext.w   D0
    65766576                sub.w   #1,D0
    65776577                movea.l PT(A6),A0
    6578 *
    6579 *       oldi = setipl(FPU_DI);
    6580 *
     6578
     6579|       oldi = setipl(FPU_DI);
     6580
    65816581                move    sr,OLDI(A6)
    65826582                move    #FPU_DI,sr
    6583 *
     6583
    65846584F11L168:        clr.b   10(A0)
    65856585                add.l   #12,a0
    65866586                dbra    D0,F11L168
    6587 *
    6588                 .page
    6589 *
    6590 *       fp->idftmd ^= I_NVBITS;
    6591 *
     6587
     6588                .page
     6589
     6590|       fp->idftmd ^= I_NVBITS;
     6591
    65926592F11L165:        eor.b   #24,7(A_FP)
    6593 *
    6594 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    6595 *
     6593
     6594|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     6595
    65966596                move.b  7(A_FP),R_FPCTL
    65976597                and     #28,R_FPCTL
    65986598                or      #3,R_FPCTL
    6599 *
    6600 *       fp->idfcpt = fp->idfpt1;
    6601 *
     6599
     6600|       fp->idfcpt = fp->idfpt1;
     6601
    66026602                move.b  6(A_FP),8(A_FP)
    6603 *
    6604 *       fp->idftmd |= I_ACTIVE;
    6605 *
     6603
     6604|       fp->idftmd |= I_ACTIVE;
     6605
    66066606                or.b    #2,7(A_FP)
    6607 *
    6608 *       fp->idftrf = trg;
    6609 *
     6607
     6608|       fp->idftrf = trg;
     6609
    66106610                move    TRG(A6),10(A_FP)
    6611 *
    6612 *       *(fpu + (long)FPU_TCV1) = srcval;
    6613 *
    6614                 move    SRCVAL(A6),$8(A_FPU)
    6615 *
    6616 *       ++octype;
    6617 *
     6611
     6612|       |(fpu + (long)FPU_TCV1) = srcval;
     6613
     6614                move    SRCVAL(A6),0x8(A_FPU)
     6615
     6616|       ++octype;
     6617
    66186618                add     #1,OCTYPE(A6)
    6619 *
    6620 *       *(fpu + (long)FPU_TSF1) = mltval;
    6621 *
    6622                 move    MLTVAL(A6),$A(A_FPU)
    6623 *
    6624 *       ++octype;
    6625 *
     6619
     6620|       |(fpu + (long)FPU_TSF1) = mltval;
     6621
     6622                move    MLTVAL(A6),0xA(A_FPU)
     6623
     6624|       ++octype;
     6625
    66266626                add     #1,OCTYPE(A6)
    6627 *
    6628 *       *(fpu + (long)FPU_TMNT) = fpmant;
    6629 *
    6630                 move    R_FPMANT,$14(A_FPU)
    6631 *
    6632 *       ++octype;
    6633 *
     6627
     6628|       |(fpu + (long)FPU_TMNT) = fpmant;
     6629
     6630                move    R_FPMANT,0x14(A_FPU)
     6631
     6632|       ++octype;
     6633
    66346634                add     #1,OCTYPE(A6)
    6635 *
    6636 *       *(fpu + (long)FPU_TEXP) = fpexp;
    6637 *
    6638                 move    R_FPEXP,$16(A_FPU)
    6639 *
    6640 *       ++octype;
    6641 *
     6635
     6636|       |(fpu + (long)FPU_TEXP) = fpexp;
     6637
     6638                move    R_FPEXP,0x16(A_FPU)
     6639
     6640|       ++octype;
     6641
    66426642                add     #1,OCTYPE(A6)
    6643 *
    6644                 .page
    6645 *
    6646 *       if (fp->idftmd & I_VNSUBN)
    6647 *
     6643
     6644                .page
     6645
     6646|       if (fp->idftmd & I_VNSUBN)
     6647
    66486648                btst    #3,7(A_FP)
    66496649                beq     F11L169
    6650 *
    6651 *               *(fpu + (long)FPU_TNV1) = fpval;
    6652 *
    6653                 move    R_FPVAL,$1C(A_FPU)
     6650
     6651|               |(fpu + (long)FPU_TNV1) = fpval;
     6652
     6653                move    R_FPVAL,0x1C(A_FPU)
    66546654                bra     F11L170
    6655 *
    6656 *       else
    6657 *               *(fpu + (long)FPU_TNV0) = fpval;
    6658 *
     6655
     6656|       else
     6657|               |(fpu + (long)FPU_TNV0) = fpval;
     6658
    66596659F11L169:        move    R_FPVAL,2(A_FPU)
    6660 *
    6661 *       ++octype;
    6662 *
     6660
     6661|       ++octype;
     6662
    66636663F11L170:        add     #1,OCTYPE(A6)
    6664 *
    6665 *       *(fpu + (long)FPU_TCTL) = fpctl;
    6666 *
     6664
     6665|       |(fpu + (long)FPU_TCTL) = fpctl;
     6666
    66676667                move    R_FPCTL,(A_FPU)
    6668 *
    6669 *       setipl(oldi);
    6670 *
     6668
     6669|       setipl(oldi);
     6670
    66716671                move    OLDI(A6),sr
    6672 *
    6673                 .page
    6674 * ------------------------------------------------------------------------------
    6675 * Start function 12 -- Level
    6676 * ------------------------------------------------------------------------------
    6677 *
    6678 *    if (ip->idhfnc[12].idftmd & I_TM_KEY) {
    6679 *
     6672
     6673                .page
     6674| ------------------------------------------------------------------------------
     6675| Start function 12 -- Level
     6676| ------------------------------------------------------------------------------
     6677
     6678|    if (ip->idhfnc[12].idftmd & I_TM_KEY) {
     6679
    66806680FN12:           move.l  IP(A6),A0
    66816681                move.b  237(A0),D0
     
    66846684                btst    #0,D0
    66856685                bne     FN12A
    6686 *
     6686
    66876687                jmp     FNEXIT
    6688 *
    6689 *       vp = (vce << 4) + 2;
    6690 *
     6688
     6689|       vp = (vce << 4) + 2;
     6690
    66916691FN12A:          move    VCE(A6),D0
    66926692                asl     #4,D0
    66936693                add.w   #2,D0
    66946694                move    D0,VP(A6)
    6695 *
    6696 *       fpu = io_fpu + FPU_OFNC + (vp << 4);
    6697 *
     6695
     6696|       fpu = io_fpu + FPU_OFNC + (vp << 4);
     6697
    66986698                asl     #5,D0
    66996699                ext.l   D0
    67006700                move.l  D0,A_FPU
    6701                 add.l   #_io_fpu+$4000,A_FPU
    6702 *
    6703 *       fp = &ip->idhfnc[12];
    6704 *
     6701                add.l   #_io_fpu+0x4000,A_FPU
     6702
     6703|       fp = &ip->idhfnc[12];
     6704
    67056705                move.l  #144,A_FP
    67066706                add.l   IP(A6),A_FP
    67076707                add.l   #86,A_FP
    6708 *
    6709 *       pt = &ip->idhpnt[fp->idfpt1];
    6710 *
     6708
     6709|       pt = &ip->idhpnt[fp->idfpt1];
     6710
    67116711                clr.l   D0
    67126712                move.b  6(A_FP),D0
     
    67186718                add.l   #242,D0
    67196719                move.l  D0,PT(A6)
    6720 *
    6721                 .page
    6722 *
    6723 *       srcnum = group | fp->idfsrc;
    6724 *
     6720
     6721                .page
     6722
     6723|       srcnum = group | fp->idfsrc;
     6724
    67256725                move.w  GROUP(A6),D0
    67266726                ext.l   D0
     
    67296729                or      D1,D0
    67306730                move    D0,SRCNUM(A6)
    6731 *
    6732 *       vep = &valents[srcnum];
    6733 *
     6731
     6732|       vep = &valents[srcnum];
     6733
    67346734                add.l   D0,D0
    67356735                move.l  D0,D1
     
    67386738                add.l   #_valents,D0
    67396739                move.l  D0,VEP(A6)
    6740 *
    6741 *       smp = vpsms[vp];
    6742 *
     6740
     6741|       smp = vpsms[vp];
     6742
    67436743                move    VP(A6),A0
    67446744                add.l   A0,A0
     
    67466746                add.l   #_vpsms,A0
    67476747                move.l  (A0),A_SMP
    6748 *
    6749 *       if (srcnum NE smp->sm) {
    6750 *
     6748
     6749|       if (srcnum NE smp->sm) {
     6750
    67516751                clr     D0
    67526752                move    10(A_SMP),D0
    67536753                cmp     SRCNUM(A6),D0
    67546754                beq     F12L113
    6755 *
    6756 *               (smp->prv)->nxt = smp->nxt;
    6757 *
     6755
     6756|               (smp->prv)->nxt = smp->nxt;
     6757
    67586758                move.l  4(A_SMP),A0
    67596759                move.l  (A_SMP),(A0)
    6760 *
    6761 *               (smp->nxt)->prv = smp->prv;
    6762 *
     6760
     6761|               (smp->nxt)->prv = smp->prv;
     6762
    67636763                move.l  (A_SMP),A0
    67646764                move.l  4(A_SMP),4(A0)
    6765 *
    6766 *               smp->prv = (struct sment *)vep;
    6767 *
     6765
     6766|               smp->prv = (struct sment |)vep;
     6767
    67686768                move.l  VEP(A6),4(A_SMP)
    6769 *
    6770 *               smp->nxt = vep->nxt;
    6771 *
     6769
     6770|               smp->nxt = vep->nxt;
     6771
    67726772                move.l  VEP(A6),A0
    67736773                move.l  (A0),(A_SMP)
    6774 *
    6775 *               (vep->nxt)->prv = smp;
    6776 *
     6774
     6775|               (vep->nxt)->prv = smp;
     6776
    67776777                move.l  VEP(A6),A0
    67786778                move.l  (A0),A0
    67796779                move.l  A_SMP,4(A0)
    6780 *
    6781 *               vep->nxt = smp;
    6782 *
     6780
     6781|               vep->nxt = smp;
     6782
    67836783                move.l  VEP(A6),A0
    67846784                move.l  A_SMP,(A0)
    6785 *
    6786 *               smp->sm = srcnum;
    6787 *
     6785
     6786|               smp->sm = srcnum;
     6787
    67886788                move    SRCNUM(A6),10(A_SMP)
    6789 *
    6790 *       }
    6791 *
    6792 *       mltval = fp->idfmlt;
    6793 *
     6789
     6790|       }
     6791
     6792|       mltval = fp->idfmlt;
     6793
    67946794F12L113:        move    2(A_FP),MLTVAL(A6)
    6795 *
    6796                 .page
    6797 *
    6798 *       switch (fp->idfsrc) {
    6799 *
     6795
     6796                .page
     6797
     6798|       switch (fp->idfsrc) {
     6799
    68006800                move.b  4(A_FP),D0
    68016801                ext.w   d0
    68026802                cmp     #10,D0
    68036803                bhi     F12L122
    6804 *
     6804
    68056805                asl     #2,D0
    68066806                lea     F12L123,A0
    68076807                movea.l 0(A0,D0.W),A0
    68086808                jmp     (A0)
    6809 *
    6810 *       case SM_NONE:
    6811 *               mltval = 0;
    6812 *
     6809
     6810|       case SM_NONE:
     6811|               mltval = 0;
     6812
    68136813F12L116:        clr     MLTVAL(A6)
    6814 *
    6815 *               tsrcval = 0;
    6816 *
     6814
     6815|               tsrcval = 0;
     6816
    68176817                clr     TSRCVAL(A6)
    6818 *
    6819 *               break;
    6820 *
     6818
     6819|               break;
     6820
    68216821                bra     F12L114
    6822 *
    6823 *       case SM_RAND:
    6824 *               tsrcval = xgetran(mltval);
    6825 *
     6822
     6823|       case SM_RAND:
     6824|               tsrcval = xgetran(mltval);
     6825
    68266826F12L117:        move    MLTVAL(A6),(sp)
    68276827                jsr     _xgetran
    68286828                move    D0,TSRCVAL(A6)
    6829 *
    6830 *               break;
    6831 *
     6829
     6830|               break;
     6831
    68326832                bra     F12L114
    6833 *
    6834 *       case SM_PTCH:
    6835 *               tsrcval = pch;
    6836 *
     6833
     6834|       case SM_PTCH:
     6835|               tsrcval = pch;
     6836
    68376837F12L118:        move    PCH(A6),TSRCVAL(A6)
    6838 *
    6839 *               break;
    6840 *
     6838
     6839|               break;
     6840
    68416841                bra     F12L114
    6842 *
    6843                 .page
    6844 *
    6845 *       case SM_FREQ:
    6846 *               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
    6847 *
     6842
     6843                .page
     6844
     6845|       case SM_FREQ:
     6846|               tsrcval = ptoftab[(pch >> 7) & 0x00FF];
     6847
    68486848F12L119:        move    PCH(A6),D0
    68496849                asr     #7,D0
     
    68536853                add.l   #_ptoftab,A0
    68546854                move    (A0),TSRCVAL(A6)
    6855 *
    6856 *               break;
    6857 *
     6855
     6856|               break;
     6857
    68586858                bra     F12L114
    6859 *
    6860 *       case SM_KVEL:
    6861 *               tsrcval = veltab[trg];
    6862 *
     6859
     6860|       case SM_KVEL:
     6861|               tsrcval = veltab[trg];
     6862
    68636863F12L120:        move    TRG(A6),A0
    68646864                add.l   A0,A0
    68656865                add.l   #_veltab,A0
    68666866                move    (A0),TSRCVAL(A6)
    6867 *
    6868 *               break;
    6869 *
     6867
     6868|               break;
     6869
    68706870                bra     F12L114
    6871 *
    6872 *       case SM_KPRS:
    6873 *               tsrcval = prstab[trg];
    6874 *
     6871
     6872|       case SM_KPRS:
     6873|               tsrcval = prstab[trg];
     6874
    68756875F12L121:        move    TRG(A6),A0
    68766876                add.l   A0,A0
    68776877                add.l   #_prstab,A0
    68786878                move    (A0),TSRCVAL(A6)
    6879 *
    6880 *               break;
    6881 *
     6879
     6880|               break;
     6881
    68826882                bra     F12L114
    6883 *
    6884 *       default:
    6885 *               tsrcval = vep->val;
    6886 *
     6883
     6884|       default:
     6885|               tsrcval = vep->val;
     6886
    68876887F12L122:        move.l  VEP(A6),A0
    68886888                move    8(A0),TSRCVAL(A6)
    6889 *
    6890 *       }
    6891 *
    6892                 .page
    6893 *
    6894 *               srcval = tsrcval;
    6895 *
     6889
     6890|       }
     6891
     6892                .page
     6893
     6894|               srcval = tsrcval;
     6895
    68966896F12L114:        move    TSRCVAL(A6),SRCVAL(A6)
    6897 *
    6898                 .page
    6899 *
    6900 *       if (pt->ipvsrc) {
    6901 *
     6897
     6898                .page
     6899
     6900|       if (pt->ipvsrc) {
     6901
    69026902F12L124:        move.l  PT(A6),A0
    69036903                tst.b   6(A0)
    69046904                beq     F12L136
    6905 *
    6906 *               switch (pt->ipvsrc) {
    6907 *
     6905
     6906|               switch (pt->ipvsrc) {
     6907
    69086908                move.l  PT(A6),A0
    69096909                move.b  6(A0),D0
     
    69126912                cmp     #9,D0
    69136913                bhi     F12L144
    6914 *
     6914
    69156915                asl     #2,D0
    69166916                lea     F12L145,A0
    69176917                move.l  0(A0,D0.W),A0
    69186918                jmp     (A0)
    6919 *
    6920 *               case SM_RAND:
    6921 *                       ltmp = xgetran(pt_>ipvmlt);
    6922 *
     6919
     6920|               case SM_RAND:
     6921|                       ltmp = xgetran(pt_>ipvmlt);
     6922
    69236923F12L139:        move.l  PT(A6),A0
    69246924                move    4(A0),(sp)
     
    69266926                ext.l   D0
    69276927                move.l  D0,LTMP(A6)
    6928 *
    6929 *                       break;
    6930 *
     6928
     6929|                       break;
     6930
    69316931                bra     F12L137
    6932 *
    6933 *               case SM_PTCH:
    6934 *                       ltmp = pch;
    6935 *
     6932
     6933|               case SM_PTCH:
     6934|                       ltmp = pch;
     6935
    69366936F12L140:        move    PCH(A6),A0
    69376937                move.l  A0,LTMP(A6)
    6938 *
    6939 *                       break;
    6940 *
     6938
     6939|                       break;
     6940
    69416941                bra     F12L137
    6942 *
    6943                 .page
    6944 *
    6945 *               case SM_FREQ:
    6946 *                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
    6947 *
     6942
     6943                .page
     6944
     6945|               case SM_FREQ:
     6946|                       ltmp = ptoftab[(pch >> 7) & 0x00FF];
     6947
    69486948F12L141:        move    PCH(A6),D0
    69496949                asr     #7,D0
     
    69556955                ext.l   D0
    69566956                move.l  D0,LTMP(A6)
    6957 *
    6958 *                       break;
    6959 *
     6957
     6958|                       break;
     6959
    69606960                bra     F12L137
    6961 *
    6962 *               case SM_KVEL:
    6963 *                       ltmp = veltab[trg];
    6964 *
     6961
     6962|               case SM_KVEL:
     6963|                       ltmp = veltab[trg];
     6964
    69656965F12L142:        move    TRG(A6),A0
    69666966                add.l   A0,A0
     
    69696969                ext.l   D0
    69706970                move.l  D0,LTMP(A6)
    6971 *
    6972 *                       break;
    6973 *
     6971
     6972|                       break;
     6973
    69746974                bra     F12L137
    6975 *
    6976                 .page
    6977 *
    6978 *               case SM_KPRS:
    6979 *                       ltmp = prstab[trg];
    6980 *
     6975
     6976                .page
     6977
     6978|               case SM_KPRS:
     6979|                       ltmp = prstab[trg];
     6980
    69816981F12L143:        move    TRG(A6),A0
    69826982                add.l   A0,A0
     
    69856985                ext.l   D0
    69866986                move.l  D0,LTMP(A6)
    6987 *
    6988 *                       break;
    6989 *
     6987
     6988|                       break;
     6989
    69906990                bra     F12L137
    6991 *
    6992                 .page
    6993 *
    6994 *               default:
    6995 *                       ltmp = valents[group | pt->ipvsrc].val;
    6996 *
     6991
     6992                .page
     6993
     6994|               default:
     6995|                       ltmp = valents[group | pt->ipvsrc].val;
     6996
    69976997F12L144:        move.l  PT(A6),A0
    69986998                clr.l   D0
     
    70087008                move    8(A0,A1.l),D0
    70097009                move.l  D0,LTMP(A6)
    7010 *
    7011 *               }
    7012 *
    7013 *
    7014                 .page
    7015 *
    7016 *               ltmp = (ltmp * pt->ipvmlt) >> 15;
    7017 *
     7010
     7011|               }
     7012
     7013
     7014                .page
     7015
     7016|               ltmp = (ltmp | pt->ipvmlt) >> 15;
     7017
    70187018F12L137:        move.l  PT(A6),A0
    70197019                move.w  4(A0),D0
     
    70237023                asr.l   D1,D0
    70247024                move.l  D0,LTMP(A6)
    7025 *
    7026 *               ltmp += (long)pt->ipval;
    7027 *
     7025
     7026|               ltmp += (long)pt->ipval;
     7027
    70287028                move.l  PT(A6),A0
    70297029                move    2(A0),D0
    70307030                ext.l   D0
    70317031                add.l   D0,LTMP(A6)
    7032 *
    7033 *               if (ltmp GT (long)VALMAX)
    7034 *                       ltmp = (long)VALMAX;
    7035 *
     7032
     7033|               if (ltmp GT (long)VALMAX)
     7034|                       ltmp = (long)VALMAX;
     7035
    70367036                cmp.l   #VALMAX,LTMP(A6)
    70377037                ble     F12L146
    7038 *
     7038
    70397039                move.l  #VALMAX,LTMP(A6)
    70407040                bra     F12L147
    7041 *
    7042 *               else if (ltmp LT (long)VALMIN)
    7043 *                       ltmp = (long)VALMIN;
    7044 *
     7041
     7042|               else if (ltmp LT (long)VALMIN)
     7043|                       ltmp = (long)VALMIN;
     7044
    70457045F12L146:        cmp.l   #VALMIN,LTMP(A6)
    70467046                bge     F12L147
    7047 *
     7047
    70487048                move.l  #VALMIN,LTMP(A6)
    7049 *
    7050 *               tfpval = (short)ltmp;
    7051 *
     7049
     7050|               tfpval = (short)ltmp;
     7051
    70527052F12L147:        move.w  LTMP+2(A6),TFPVAL(A6)
    70537053                bra     F12L149
    7054 *
    7055 *       } else {
    7056 *
    7057 *               tfpval = pt->ipval;
    7058 *
     7054
     7055|       } else {
     7056
     7057|               tfpval = pt->ipval;
     7058
    70597059F12L136:        move.l  PT(A6),A0
    70607060                move    2(A0),TFPVAL(A6)
    7061 *
    7062 *       }
    7063 *
    7064                 .page
    7065 *
    7066 *       fpmant = (((long)pt->iptom & 0x0000FFF0L)
    7067 *               * ((long)timemlt & 0x0000FFFFL)) >> 15;
    7068 *
     7061
     7062|       }
     7063
     7064                .page
     7065
     7066|       fpmant = (((long)pt->iptom & 0x0000FFF0L)
     7067|               | ((long)timemlt & 0x0000FFFFL)) >> 15;
     7068
    70697069F12L149:        move.l  PT(A6),A0
    70707070                move.w  (A0),D0
    70717071                move.w  D0,D2
    7072                 andi.w  #$FFF0,D0
     7072                andi.w  #0xFFF0,D0
    70737073                move.w  _timemlt,D1
    70747074                muls    D1,D0
     
    70767076                asr.l   D1,D0
    70777077                move    D0,R_FPMANT
    7078 *
    7079 *       fpexp = expbit[pt->iptim & 0x000F];
    7080 *
    7081                 and     #$000F,D2
     7078
     7079|       fpexp = expbit[pt->iptim & 0x000F];
     7080
     7081                and     #0x000F,D2
    70827082                move    D2,A0
    70837083                add.l   A0,A0
    70847084                add.l   #_expbit,A0
    70857085                move    (A0),R_FPEXP
    7086 *
    7087                 .page
    7088 *
    7089 *               fp->idfpch = pch;
    7090 *
     7086
     7087                .page
     7088
     7089|               fp->idfpch = pch;
     7090
    70917091F12L162:        move    PCH(A6),(A_FP)
    7092 *
    7093 *               fpval = ((tfpval >> 5) - 500) << 6;
    7094 *
     7092
     7093|               fpval = ((tfpval >> 5) - 500) << 6;
     7094
    70957095                move    TFPVAL(A6),R_FPVAL
    70967096                asr     #5,R_FPVAL
    70977097                add     #-500,R_FPVAL
    70987098                asl     #6,R_FPVAL
    7099 *
    7100                 .page
    7101 *
     7099
     7100                .page
     7101
    71027102                move.b  5(A_FP),D0
    71037103                ext.w   D0
    71047104                sub.w   #1,D0
    71057105                movea.l PT(A6),A0
    7106 *
    7107 *       oldi = setipl(FPU_DI);
    7108 *
     7106
     7107|       oldi = setipl(FPU_DI);
     7108
    71097109                move    sr,OLDI(A6)
    71107110                move    #FPU_DI,sr
    7111 *
     7111
    71127112F12L168:        clr.b   10(A0)
    71137113                add.l   #12,a0
    71147114                dbra    D0,F12L168
    7115 *
    7116                 .page
    7117 *
    7118 *       fp->idftmd ^= I_NVBITS;
    7119 *
     7115
     7116                .page
     7117
     7118|       fp->idftmd ^= I_NVBITS;
     7119
    71207120F12L165:        eor.b   #24,7(A_FP)
    7121 *
    7122 *       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
    7123 *
     7121
     7122|       fpctl = (fp->idftmd & (I_NRATIO | I_NVBITS)) | 0x0003;
     7123
    71247124                move.b  7(A_FP),R_FPCTL
    71257125                and     #28,R_FPCTL
    71267126                or      #3,R_FPCTL
    7127 *
    7128 *       fp->idfcpt = fp->idfpt1;
    7129 *
     7127
     7128|       fp->idfcpt = fp->idfpt1;
     7129
    71307130                move.b  6(A_FP),8(A_FP)
    7131 *
    7132 *       fp->idftmd |= I_ACTIVE;
    7133 *
     7131
     7132|       fp->idftmd |= I_ACTIVE;
     7133
    71347134                or.b    #2,7(A_FP)
    7135 *
    7136 *       fp->idftrf = trg;
    7137 *
     7135
     7136|       fp->idftrf = trg;
     7137
    71387138                move    TRG(A6),10(A_FP)
    7139 *
    7140 *       *(fpu + (long)FPU_TCV1) = srcval;
    7141 *
    7142                 move    SRCVAL(A6),$8(A_FPU)
    7143 *
    7144 *       ++octype;
    7145 *
     7139
     7140|       |(fpu + (long)FPU_TCV1) = srcval;
     7141
     7142                move    SRCVAL(A6),0x8(A_FPU)
     7143
     7144|       ++octype;
     7145
    71467146                add     #1,OCTYPE(A6)
    7147 *
    7148 *       *(fpu + (long)FPU_TSF1) = mltval;
    7149 *
    7150                 move    MLTVAL(A6),$A(A_FPU)
    7151 *
    7152 *       ++octype;
    7153 *
     7147
     7148|       |(fpu + (long)FPU_TSF1) = mltval;
     7149
     7150                move    MLTVAL(A6),0xA(A_FPU)
     7151
     7152|       ++octype;
     7153
    71547154                add     #1,OCTYPE(A6)
    7155 *
    7156 *       *(fpu + (long)FPU_TMNT) = fpmant;
    7157 *
    7158                 move    R_FPMANT,$14(A_FPU)
    7159 *
    7160 *       ++octype;
    7161 *
     7155
     7156|       |(fpu + (long)FPU_TMNT) = fpmant;
     7157
     7158                move    R_FPMANT,0x14(A_FPU)
     7159
     7160|       ++octype;
     7161
    71627162                add     #1,OCTYPE(A6)
    7163 *
    7164 *       *(fpu + (long)FPU_TEXP) = fpexp;
    7165 *
    7166                 move    R_FPEXP,$16(A_FPU)
    7167 *
    7168 *       ++octype;
    7169 *
     7163
     7164|       |(fpu + (long)FPU_TEXP) = fpexp;
     7165
     7166                move    R_FPEXP,0x16(A_FPU)
     7167
     7168|       ++octype;
     7169
    71707170                add     #1,OCTYPE(A6)
    7171 *
    7172                 .page
    7173 *
    7174 *       if (fp->idftmd & I_VNSUBN)
    7175 *
     7171
     7172                .page
     7173
     7174|       if (fp->idftmd & I_VNSUBN)
     7175
    71767176                btst    #3,7(A_FP)
    71777177                beq     F12L169
    7178 *
    7179 *               *(fpu + (long)FPU_TNV1) = fpval;
    7180 *
    7181                 move    R_FPVAL,$1C(A_FPU)
     7178
     7179|               |(fpu + (long)FPU_TNV1) = fpval;
     7180
     7181                move    R_FPVAL,0x1C(A_FPU)
    71827182                bra     F12L170
    7183 *
    7184 *       else
    7185 *               *(fpu + (long)FPU_TNV0) = fpval;
    7186 *
     7183
     7184|       else
     7185|               |(fpu + (long)FPU_TNV0) = fpval;
     7186
    71877187F12L169:        move    R_FPVAL,2(A_FPU)
    7188 *
    7189 *       ++octype;
    7190 *
     7188
     7189|       ++octype;
     7190
    71917191F12L170:        add     #1,OCTYPE(A6)
    7192 *
    7193 *       *(fpu + (long)FPU_TCTL) = fpctl;
    7194 *
     7192
     7193|       |(fpu + (long)FPU_TCTL) = fpctl;
     7194
    71957195                move    R_FPCTL,(A_FPU)
    7196 *
    7197 *       setipl(oldi);
    7198 *
     7196
     7197|       setipl(oldi);
     7198
    71997199                move    OLDI(A6),sr
    7200 *
    7201 *    }
    7202 *
    7203                 .page
    7204 *
     7200
     7201|    }
     7202
     7203                .page
     7204
    72057205FNEXIT:         tst.l   (sp)+
    72067206                movem.l (sp)+,R_FPVAL-R_FPMANT/A_SMP-A_FP
    72077207                unlk    A6
    72087208                rts
    7209 *
    7210 * }
    7211 *
    7212                 .page
    7213 *
     7209
     7210| }
     7211
     7212                .page
     7213
    72147214                .data
    7215 *
    7216 * Jump tables for switch statements
    7217 * ---------------------------------
    7218 *
     7215
     7216| Jump tables for switch statements
     7217| ---------------------------------
     7218
    72197219F00L123:        .dc.l   F00L116
    72207220                .dc.l   F00L117
     
    72287228                .dc.l   F00L122
    72297229                .dc.l   F00L119
    7230 *
     7230
    72317231F00L145:        .dc.l   F00L139
    72327232                .dc.l   F00L144
     
    72397239                .dc.l   F00L144
    72407240                .dc.l   F00L141
    7241 *
     7241
    72427242F01L123:        .dc.l   F01L116
    72437243                .dc.l   F01L117
     
    72517251                .dc.l   F01L122
    72527252                .dc.l   F01L119
    7253 *
     7253
    72547254F01L145:        .dc.l   F01L139
    72557255                .dc.l   F01L144
     
    72627262                .dc.l   F01L144
    72637263                .dc.l   F01L141
    7264 *
     7264
    72657265F02L123:        .dc.l   F02L116
    72667266                .dc.l   F02L117
     
    72747274                .dc.l   F02L122
    72757275                .dc.l   F02L119
    7276 *
     7276
    72777277F02L145:        .dc.l   F02L139
    72787278                .dc.l   F02L144
     
    72857285                .dc.l   F02L144
    72867286                .dc.l   F02L141
    7287 *
     7287
    72887288F03L123:        .dc.l   F03L116
    72897289                .dc.l   F03L117
     
    72977297                .dc.l   F03L122
    72987298                .dc.l   F03L119
    7299 *
     7299
    73007300F03L145:        .dc.l   F03L139
    73017301                .dc.l   F03L144
     
    73087308                .dc.l   F03L144
    73097309                .dc.l   F03L141
    7310 *
     7310
    73117311F04L123:        .dc.l   F04L116
    73127312                .dc.l   F04L117
     
    73207320                .dc.l   F04L122
    73217321                .dc.l   F04L119
    7322 *
     7322
    73237323F04L145:        .dc.l   F04L139
    73247324                .dc.l   F04L144
     
    73317331                .dc.l   F04L144
    73327332                .dc.l   F04L141
    7333 *
     7333
    73347334F05L123:        .dc.l   F05L116
    73357335                .dc.l   F05L117
     
    73437343                .dc.l   F05L122
    73447344                .dc.l   F05L119
    7345 *
     7345
    73467346F05L145:        .dc.l   F05L139
    73477347                .dc.l   F05L144
     
    73547354                .dc.l   F05L144
    73557355                .dc.l   F05L141
    7356 *
     7356
    73577357F06L123:        .dc.l   F06L116
    73587358                .dc.l   F06L117
     
    73667366                .dc.l   F06L122
    73677367                .dc.l   F06L119
    7368 *
     7368
    73697369F06L145:        .dc.l   F06L139
    73707370                .dc.l   F06L144
     
    73777377                .dc.l   F06L144
    73787378                .dc.l   F06L141
    7379 *
     7379
    73807380F07L123:        .dc.l   F07L116
    73817381                .dc.l   F07L117
     
    73897389                .dc.l   F07L122
    73907390                .dc.l   F07L119
    7391 *
     7391
    73927392F07L145:        .dc.l   F07L139
    73937393                .dc.l   F07L144
     
    74007400                .dc.l   F07L144
    74017401                .dc.l   F07L141
    7402 *
     7402
    74037403F08L123:        .dc.l   F08L116
    74047404                .dc.l   F08L117
     
    74127412                .dc.l   F08L122
    74137413                .dc.l   F08L119
    7414 *
     7414
    74157415F08L145:        .dc.l   F08L139
    74167416                .dc.l   F08L144
     
    74237423                .dc.l   F08L144
    74247424                .dc.l   F08L141
    7425 *
     7425
    74267426F09L123:        .dc.l   F09L116
    74277427                .dc.l   F09L117
     
    74357435                .dc.l   F09L122
    74367436                .dc.l   F09L119
    7437 *
     7437
    74387438F09L145:        .dc.l   F09L139
    74397439                .dc.l   F09L144
     
    74467446                .dc.l   F09L144
    74477447                .dc.l   F09L141
    7448 *
     7448
    74497449F10L123:        .dc.l   F10L116
    74507450                .dc.l   F10L117
     
    74587458                .dc.l   F10L122
    74597459                .dc.l   F10L119
    7460 *
     7460
    74617461F10L145:        .dc.l   F10L139
    74627462                .dc.l   F10L144
     
    74697469                .dc.l   F10L144
    74707470                .dc.l   F10L141
    7471 *
     7471
    74727472F11L123:        .dc.l   F11L116
    74737473                .dc.l   F11L117
     
    74817481                .dc.l   F11L122
    74827482                .dc.l   F11L119
    7483 *
     7483
    74847484F11L145:        .dc.l   F11L139
    74857485                .dc.l   F11L144
     
    74927492                .dc.l   F11L144
    74937493                .dc.l   F11L141
    7494 *
     7494
    74957495F12L123:        .dc.l   F12L116
    74967496                .dc.l   F12L117
     
    75047504                .dc.l   F12L122
    75057505                .dc.l   F12L119
    7506 *
     7506
    75077507F12L145:        .dc.l   F12L139
    75087508                .dc.l   F12L144
     
    75157515                .dc.l   F12L144
    75167516                .dc.l   F12L141
    7517 *
    7518 * vbtab -- vbuf pointer table -- indexed by voice number
    7519 * -----    ---------------------------------------------
     7517
     7518| vbtab -- vbuf pointer table -- indexed by voice number
     7519| -----    ---------------------------------------------
    75207520vbtab:          .dc.l   _vbufs
    75217521                .dc.l   _vbufs+VBLEN
     
    75307530                .dc.l   _vbufs+(10*VBLEN)
    75317531                .dc.l   _vbufs+(11*VBLEN)
    7532 *
     7532
    75337533                .end
  • ram/fpuint.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * fpuint.s -- process FPU interrupts / clear FPU
    3 * Version 63 -- 1988-08-31 -- D.N. Lynx Crowe
    4 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| fpuint.s -- process FPU interrupts / clear FPU
     3| Version 63 -- 1988-08-31 -- D.N. Lynx Crowe
     4| ------------------------------------------------------------------------------
    55                .text
    6 *
    7                 .xdef   _fpuint         * process an FPU interrupt
    8                 .xdef   _fpuclr         * reset the FPU
    9                 .xdef   _clrvce         * quiet a voice
    10 *
    11                 .xdef   _fputrap        * a very good debug trap point
    12 *
    13                 .xdef   _fp_resv        * 'spare' function reset value table
    14                 .xdef   _fpuifnc        * FPU interrupt code  (voice / function)
    15 *
    16                 .xref   _irand          * ranged random number function
    17                 .xref   _scope          * diagnostic scope function
    18                 .xref   _xgetran        * random number function
    19 *
     6
     7                .xdef   _fpuint         | process an FPU interrupt
     8                .xdef   _fpuclr         | reset the FPU
     9                .xdef   _clrvce         | quiet a voice
     10
     11                .xdef   _fputrap        | a very good debug trap point
     12
     13                .xdef   _fp_resv        | 'spare' function reset value table
     14                .xdef   _fpuifnc        | FPU interrupt code  (voice / function)
     15
     16                .xref   _irand          | ranged random number function
     17                .xref   _scope          | diagnostic scope function
     18                .xref   _xgetran        | random number function
     19
    2020                .xref   _expbit
    2121                .xref   _funcndx
     
    3333                .xref   _vce2trg
    3434                .xref   _veltab
    35 *
    36                 .page
    37 * ------------------------------------------------------------------------------
    38 * Register usage
    39 * --------------
    40 *       d0      scratch
    41 *       d1      FPU function index
    42 *       d2      point index from FH_CPT  (idfcpt)
    43 *       d3      scratch
    44 *       d4      jump point number from PT_PAR1  (ippar1)
    45 *       d5      scratch
    46 *
    47 *       a0      scratch
    48 *       a1      function header base
    49 *       a2      point table base
    50 *       a3      FPU base
    51 *
    52 * ------------------------------------------------------------------------------
    53 * FPU definitions
    54 * ---------------
    55 *
    56 UPD_BIT         .equ    $0001                   * update bit  (1 = update)
    57 INT_BIT         .equ    $0002                   * int. bit    (0 = disable)
    58 RAT_BIT         .equ    $0004                   * ratio bit   (0 = ratio)
    59 *
    60 VSUBNBIT        .equ    3                       * new value select bit number
    61 VAL_BITS        .equ    $0018                   * new value select bit mask
    62 *
    63 MSK_RNVB        .equ    $000C                   * new value / ratio bits
    64 MSK_ONVB        .equ    $0010                   * old new value bit
    65 *
    66 FKILL           .equ    $0014                   * kill value for function
    67 FSEND           .equ    $0015                   * send new value to function
    68 *
    69 CLREXP          .equ    $8000                   * clear value for time exponent
    70 CLRMNT          .equ    $8000                   * clear value for time mantissa
    71 *
    72 * ------------------------------------------------------------------------------
    73 * Miscellaneous definitions
    74 * -------------------------
    75 *
    76 PCHMAX          .equ    21920                   * maximum pitch value
    77 VALMAX          .equ    32000                   * maximum value to send to FPU
    78 VALMIN          .equ    -32000                  * minimum value to send to FPU
    79 *
    80 LSPCH           .equ    2                       * left shift for sources to freq
    81 *
    82 VALLEN          .equ    10                      * length of the 'valent' struct
    83 VT_VAL          .equ    8                       * value offset in 'valent'
    84 *
    85                 .page
    86 * ------------------------------------------------------------------------------
    87 * FPU addresses
    88 * -------------
    89 *
    90 FPUBASE         .equ    $180000                 * FPU base address
    91 *
    92 FPUWST          .equ    FPUBASE                 * FPU waveshape base
    93 FPUFUNC         .equ    FPUBASE+$4000           * FPU function base
    94 FPUINT1         .equ    FPUBASE+$4000           * FPU int. input address (R/O)
    95 FPUINT2         .equ    FPUBASE+$6000           * FPU int. reset address (W/O)
    96 FPUCFG          .equ    FPUBASE+$5FE0           * FPU config. data address (W/O)
    97 *
    98 F_CTL           .equ    $00                     * control word
    99 F_VAL10         .equ    $02                     * new value "10"
    100 F_CV1           .equ    $08                     * control voltage 1
    101 F_SF1           .equ    $0A                     * scale factor 1
    102 F_CV2           .equ    $0C                     * control voltage 2
    103 F_SF2           .equ    $0E                     * scale factor 2
    104 F_CV3           .equ    $10                     * control voltage 3
    105 F_SF3           .equ    $12                     * scale factor 3
    106 F_MNT           .equ    $14                     * time mantissa
    107 F_EXP           .equ    $16                     * time exponent
    108 F_VAL01         .equ    $1C                     * new value "01"
    109 *
    110 P_FREQ1         .equ    $0020                   * frequency 1
    111 P_FREQ2         .equ    $0060                   * frequency 2
    112 P_FREQ3         .equ    $00A0                   * frequency 3
    113 P_FREQ4         .equ    $00E0                   * frequency 4
    114 P_FILTER        .equ    $0140                   * filter
    115 P_FILTRQ        .equ    $00C0                   * filter q
    116 *
    117 P_INDEX1        .equ    $0120                   * index 1
    118 P_INDEX2        .equ    $0160                   * index 2
    119 P_INDEX3        .equ    $0180                   * index 3
    120 P_INDEX4        .equ    $01A0                   * index 4
    121 P_INDEX5        .equ    $01C0                   * index 5
    122 P_INDEX6        .equ    $01E0                   * index 6
    123 *
    124 P_LEVEL         .equ    $0040                   * level
    125 *
    126 P_LOCN          .equ    $0080                   * location
    127 P_DYNAM         .equ    $0100                   * dynamics
    128 *
    129                 .page
    130 * ------------------------------------------------------------------------------
    131 * Structure definitions
    132 * ------------------------------------------------------------------------------
    133 * The following MUST match the idfnhdr structure definition in instdsp.h:
    134 *
    135 FH_LEN          .equ    12              * length of the idfnhdr structure
    136 *
    137 FH_PCH          .equ    0               * WORD - pitch offset  (freq1 only)
    138 FH_MLT          .equ    2               * WORD - overall value multiplier
    139 FH_SRC          .equ    4               * BYTE - overall value source
    140 FH_PIF          .equ    5               * BYTE - # of points in the function
    141 FH_PT1          .equ    6               * BYTE - index of first point
    142 FH_TMD          .equ    7               * BYTE - trigger mode / control bits
    143 FH_CPT          .equ    8               * BYTE - current point
    144 FH_PRM          .equ    9               * BYTE - misc. function parameter
    145 FH_TRG          .equ    10              * WORD - trigger
    146 *
    147 I_ACTIVE        .equ    1               * 'Active' bit number        (in FH_TMD)
    148 *
    149 MSK_CTL         .equ    $001C           * mask for FPU hardware bits (in FH_TMD)
    150 *
    151 * ------------------------------------------------------------------------------
    152 * The following MUST match the instpnt structure definition in instdsp.h:
    153 *
    154 PT_LEN          .equ    12              * length of the instpnt structure
    155 *
    156 PT_TIM          .equ    0               * WORD - time (packed)
    157 PT_VAL          .equ    2               * WORD - value
    158 PT_VMLT         .equ    4               * WORD - value multiplier
    159 PT_VSRC         .equ    6               * BYTE - value source
    160 PT_ACT          .equ    7               * BYTE - action
    161 PT_PAR1         .equ    8               * BYTE - parameter 1
    162 PT_PAR2         .equ    9               * BYTE - parameter 2
    163 PT_PAR3         .equ    10              * BYTE - parameter 3
    164 PT_PAD          .equ    11              * BYTE - padding for even boundary
    165 *
    166 MSK_MNT         .equ    $FFF0           * mask for mantissa  (in PT_TIM)
    167 MSK_EXP         .equ    $000F           * mask for exponent  (in PT_TIM)
    168 *
    169 MAX_ACT         .equ    7               * maximum action code value
    170 *
    171                 .page
    172 *
    173 * ------------------------------------------------------------------------------
    174 * pflist definitions -- must match those in instdsp.h
    175 *
    176 PF_NEXT         .equ    0
    177 PF_TRIG         .equ    4
    178 PF_FUNC         .equ    6
    179 PF_D1           .equ    8
    180 PF_D2           .equ    12
    181 PF_D4           .equ    16
    182 PF_A1           .equ    20
    183 PF_A2           .equ    24
    184 PF_A3           .equ    28
    185 * ------------------------------------------------------------------------------
    186 * Source definitions -- must match those in 'smdefs.h'
    187 *
    188 SM_RAND         .equ    1               * random
    189 SM_PTCH         .equ    5               * pitch
    190 SM_KPRS         .equ    6               * key pressure
    191 SM_KVEL         .equ    7               * key velocity
    192 SM_FREQ         .equ    10              * frequency
    193 *
    194                 .page
    195 * ------------------------------------------------------------------------------
    196 * _fpuint() -- process FPU interrupts
    197 *
    198 *       void
    199 *       fpuint();
    200 *
    201 *               Processes FPU interrupts.  Must be the target of vector 26,
    202 *               which is Autovector Interrupt level 2.
    203 *
    204 * ------------------------------------------------------------------------------
    205 *
    206 _fpuint:        movem.l d0-d5/a0-a3,-(a7)       * preserve registers we use
    207                 move.w  FPUINT1,d0      * read FPU interrupt status
    208                 andi.w  #$00FF,d0       * mask out garbage in MS bits
    209                 move.w  d0,_fpuifnc     * save for later use
    210                 move.w  _ndisp,d1       * get display number
    211                 cmpi.w  #11,d1          * see if we display
    212                 bne     nodisp          * jump if not
    213 *
    214                 tst.w   _scopef         * ...
    215                 beq     nodisp          * ...
    216 *
    217                 move.w  d0,-(a7)        * display value
    218                 jsr     _scope          * ...
    219                 tst.w   (a7)+           * ...
    220 *
    221                 move.w  _fpuifnc,d0     * get FPU status
    222 *
    223 nodisp:         move.w  d0,d1           * save in d1  (becomes function offset)
    224 *
    225                 lsl.w   #5,d1           * develop FPU function offset
    226                 lea     FPUFUNC,a3      * setup FPU function base address
    227 *
    228                 lsl.w   #3,d0           * develop funcndx[] index
    229                 lea     _funcndx,a0     * setup funcndx[] base address
    230 *
    231                 tst.l   0(a0,d0.W)      * see if function is defined
    232                 bne     fnok            * jump if so
    233 *
    234                 move.w  d1,d0           * get function offset in d0
    235                 andi.w  #$1E00,d0       * mask for voice number
    236                 cmpi.w  #$1800,d0       * see if it's a real voice  (0..11)
    237                 bge     fpexit          * don't send a kill if not a real voice
    238 *
    239                 move.w  #FKILL,F_CTL(a3,d1.W)   * kill the undefined function
    240 *
    241 fpexit:         clr.w   FPUINT2         * reset the FPU interrupt latch
    242                 movem.l (a7)+,d0-d5/a0-a3       * restore the registers
    243                 rte                     * return to interrupted code
    244 *
    245                 .page
    246 * ------------------------------------------------------------------------------
    247 * set up to process active functions,  stop ones that should be inactive
    248 * ------------------------------------------------------------------------------
    249 fnok:           movea.l 0(a0,d0.W),a1   * get pointer to function header
    250                 movea.l 4(a0,d0.W),a2   * get pointer to point table
    251                 btst    #I_ACTIVE,FH_TMD(a1)    * see if function is active
    252                 bne     doact           * go process action if so
    253 *
    254 * ------------------------------------------------------------------------------
    255 * stop a function
    256 * ------------------------------------------------------------------------------
    257 stopfn:         move.b  FH_TMD(a1),d0   * get function control bits
    258                 andi.w  #MSK_RNVB,d0    * mask for ratio / new new-value bit
    259                 move.w  d0,d3           * isolate new new-value bit
    260                 add.w   d3,d3           * ... from function header
    261                 andi.w  #MSK_ONVB,d3    * ... shift to old new-value bit
    262                 or.w    d3,d0           * ... and put new bit in old bit       
    263                 move.w  d0,F_CTL(a3,d1.W)       * stop the function
    264                 bclr    #I_ACTIVE,FH_TMD(a1)    * reset the active bit
    265                 bra     fpexit          * go restore registers and exit
    266 *
    267                 .page
    268 * ------------------------------------------------------------------------------
    269 * setup for and dispatch to the proper action handler
    270 * ------------------------------------------------------------------------------
    271 doact:          clr.w   d2              * get current point index in d2
    272                 move.b  FH_CPT(a1),d2   * ...
    273                 lsl.w   #2,d2           * multiply it by the length of a point
    274                 move.w  d2,d0           * ...  (fast multiply by PT_LEN = 12
    275                 add.w   d2,d2           * ...   via shift and add)
    276                 add.w   d0,d2           * ...
    277                 clr.w   d4              * get jump point # into d4
    278                 move.b  PT_PAR1(a2,d2.W),d4     * ...
    279                 clr.w   d3              * get action code in d3
    280                 move.b  PT_ACT(a2,d2.W),d3      * ...
    281                 cmpi.b  #MAX_ACT,d3     * check against the limit
    282                 bgt     stopfn          * stop things if it's a bad action code
    283 *
    284                 lsl.w   #2,d3           * develop index to action dispatch table
    285                 lea     actab,a0        * get the address of the action handler
    286                 movea.l 0(a0,d3.W),a0   * ...
    287 *
    288 * ------------------------------------------------------------------------------
    289 * At this point we're ready to do the action associated with the point,
    290 * and the registers are set up,  and will remain,  as follows:
    291 *
    292 *       d1      FPU function index      a1      function header base
    293 *       d2      point table index       a2      point table base
    294 *                                       a3      FPU function base
    295 *       d4      jump point number
    296 *
    297 *       d0, d3, d5, and a0 are used as scratch throughout the code.
    298 *
    299 * ------------------------------------------------------------------------------
    300 *
    301 _fputrap:       jmp     (a0)            * dispatch to action handler
    302 *
    303                 .page
    304 * ------------------------------------------------------------------------------
    305 * act0 -- AC_NULL -- no action
    306 * ----    --------------------
    307 act0:           move.b  FH_PT1(a1),d0   * get first point number
    308                 add.b   FH_PIF(a1),d0   * add number of points in function
    309                 subq.b  #1,d0           * make it last point number
    310                 cmp.b   FH_CPT(a1),d0   * see if we're at the last point
    311                 beq     stopfn          * stop function if so
    312 *
    313                 addq.b  #1,FH_CPT(a1)   * update function header for next point
    314                 addi.w  #PT_LEN,d2      * advance the point index
    315 *
    316 * ------------------------------------------------------------------------------
    317 * outseg -- output a segment
    318 * ------    ----------------
    319 outseg:         move.w  PT_TIM(a2,d2.w),d3      * get packed time
    320                 move.w  d3,d0                   * extract mantissa
    321                 andi.w  #MSK_MNT,d0             * ...
    322                 mulu    _timemlt,d0             * multiply by panel time pot value
    323                 lsr.l   #8,d0                   * ... and scale it
    324                 lsr.l   #7,d0                   * ...
    325                 move.w  d0,F_MNT(a3,d1.W)       * send mantissa to FPU
    326                 andi.w  #MSK_EXP,d3             * extract exponent code
    327                 add.w   d3,d3                   * look up decoded exponent
    328                 lea     _expbit,a0              * ... in expbit
    329                 move.w  0(a0,d3.W),F_EXP(a3,d1.W)       * send exponent to FPU
    330                 move.w  PT_VAL(a2,d2.W),d3      * get the function value
    331 *
    332 * ------------------------------------------------------------------------------
    333 * get the point source, if any
    334 * ------------------------------------------------------------------------------
    335                 tst.w   PT_VMLT(a2,d2.W)        * see if we have a point mlt.
    336                 beq     nosrc                   * don't do anything for zero
    337 *
    338                 clr.w   d0                      * get the source number
    339                 move.b  PT_VSRC(a2,d2.W),d0     * ...
    340                 beq     nosrc                   * don't do anything for zero
    341 *
    342 * ------------------------------------------------------------------------------
    343 * SM_RAND -- random
    344 * ------------------------------------------------------------------------------
    345                 cmpi.w  #SM_RAND,d0             * is this the random source ?
    346                 bne     srctyp0                 * jump if not
    347 *
    348                 movem.l d1-d2/a0-a2,-(a7)       * preserve registers around call
    349                 move.w  PT_VMLT(a2,d2.W),-(a7)  * pass multiplier to xgetran()
    350                 jsr     _xgetran                * call for a random number
    351                 tst.w   (a7)+                   * clean up stack
    352                 movem.l (a7)+,d1-d2/a0-a2       * restore registers
    353                 move.w  d0,d5                   * put random value in the value register
    354                 bra     applym                  * go apply the multiplier
    355 *
    356                 .page
    357 * ------------------------------------------------------------------------------
    358 * SM_FREQ -- frequency
    359 * ------------------------------------------------------------------------------
    360 srctyp0:        cmpi.w  #SM_FREQ,d0     * is this the frequency source ?
    361                 bne     srctyp1         * jump if not
    362 *
    363                 move.w  (a1),d0         * get the pitch
    364                 lsr.w   #6,d0           * shift to a word index
    365                 andi.w  #$01FE,d0       * mask out extraneous bits
    366                 lea     _ptoftab,a0     * get entry from ptoftab[]
    367                 move.w  0(a0,d0.W),d5   * ...
    368                 bra     applym          * go apply the multiplier
    369 *
    370 * ------------------------------------------------------------------------------
    371 * SM_PTCH -- pitch
    372 * ------------------------------------------------------------------------------
    373 srctyp1:        cmpi.w  #SM_PTCH,d0     * is this the pitch source ?
    374                 bne     srctyp2         * jump if not
    375 *
    376                 move.w  (a1),d5         * get the pitch as the value
    377                 bra     applym          * go apply the multiplier
    378 *
    379 * ------------------------------------------------------------------------------
    380 * SM_KVEL -- velocity
    381 * ------------------------------------------------------------------------------
    382 srctyp2:        cmpi.w  #SM_KVEL,d0     * is this the key velocity source ?
    383                 bne     srctyp3         * jump if not
    384 *
    385                 move.w  FH_TRG(a1),d0   * get the trigger number
    386                 add.w   d0,d0           * ... as a word index
    387                 lea     _veltab,a0      * ... into veltab[]
    388                 move.w  0(a0,d0.W),d5   * get the velocity from veltab[trg]
    389                 bra     applym          * go apply the multiplier
    390 *
    391 * ------------------------------------------------------------------------------
    392 * SM_KPRS -- pressure
    393 * ------------------------------------------------------------------------------
    394 srctyp3:        cmpi.w  #SM_KPRS,d0     * is this the key pressure source ?
    395                 bne     srctyp4         * jump if not  (must be an analog input)
    396 *
    397                 move.w  FH_TRG(a1),d0   * get the trigger number
    398                 add.w   d0,d0           * ... as a word index
    399                 lea     _prstab,a0      * ... into prstab[]
    400                 move.w  0(a0,d0.W),d5   * get the pressure from prstab[trg]
    401                 bra     applym          * go apply the multiplier
    402 *
    403                 .page
    404 * ------------------------------------------------------------------------------
    405 * all other sources come out of the valents[] array
    406 * ------------------------------------------------------------------------------
    407 srctyp4:        lea     _vce2grp,a0     * point at vce2grp[]
    408                 move.w  _fpuifnc,d5     * get voice number in d5
    409                 lsr.w   #3,d5           * ...
    410                 andi.w  #$001E,d5       * ... as a word index
    411                 move.w  0(a0,d5.W),d5   * get the group number
    412                 subq.w  #1,d5           * ...
    413                 lsl.w   #4,d5           * shift it left a nybble
    414                 or.w    d5,d0           * OR it into the source number
    415                 add.w   d0,d0           * make source number a valents[] index
    416                 move.w  d0,d5           * ... (fast multiply by VALLEN = 10
    417                 lsl.w   #2,d0           * ...  via shift and add)
    418                 add.w   d5,d0           * ...
    419                 lea     _valents,a0     * get base of valents[]
    420                 move.w  VT_VAL(a0,d0.W),d5      * get value
    421 *
    422 * ------------------------------------------------------------------------------
    423 * apply the multiplier to the source, and add it to the function value
    424 * ------------------------------------------------------------------------------
    425 applym:         muls    PT_VMLT(a2,d2.W),d5     * apply the multiplier
    426                 asr.l   #7,d5           * scale the result
    427                 asr.l   #8,d5           * ...
    428                 ext.l   d3              * add the function value
    429                 add.l   d3,d5           * ...
    430                 cmpi.l  #VALMAX,d5      * check for overflow
    431                 ble     srcmlt1         * jump if no overflow
    432 *
    433                 move.l  #VALMAX,d5      * limit at VALMAX
    434                 bra     srcmlt2         * ...
    435 *
    436 srcmlt1:        cmpi.l  #VALMIN,d5      * check for underflow
    437                 bge     srcmlt2         * jump if no underflow
    438 *
    439                 move.l  #VALMIN,d5      * limit at VALMIN
    440 *
    441 srcmlt2:        move.w  d5,d3           * setup value for output to FPU
    442 *
    443                 .page
    444 * ------------------------------------------------------------------------------
    445 * adjust the value according to the function type
    446 * ------------------------------------------------------------------------------
    447 nosrc:          move.w  d1,d0           * get function type
    448                 andi.w  #$01E0,d0       * ...
    449 *
    450 * ------------------------------------------------------------------------------
    451 * level or location
    452 * ------------------------------------------------------------------------------
    453                 cmpi.w  #P_LEVEL,d0     * see if it's the level
    454                 beq     outsegl         * jump if so
    455 *
    456                 cmpi.w  #P_LOCN,d0      * see if it's the location
    457                 bne     outsegf         * jump if not
    458 *
    459                 tst.w   d3              * check sign of value
    460                 bpl     outsegc         * jump if positive
    461 *
    462                 clr.w   d3              * force negative values to 0
    463 *
    464 outsegc:        asr.w   #5,d3           * shift value to LS bits
    465                 sub.w   #500,d3         * subtract 5.00 from value
    466                 asl.w   #6,d3           * readjust to MS bits
    467                 bra     outseg3         * go output the value
    468 *
    469 outsegl:        tst.w   d3              * check sign of value
    470                 bpl     outsegm         * jump if positive
    471 *
    472                 clr.w   d3              * limit negative values at 0
    473 *
    474 outsegm:        asr.w   #5,d3           * shift value to LS bits
    475                 sub.w   #500,d3         * subtract 5.00 from value
    476                 asl.w   #6,d3           * readjust to MS bits
    477                 bra     outseg3         * go output the value
    478 *
    479                 .page
    480 * ------------------------------------------------------------------------------
    481 * filter
    482 * ------------------------------------------------------------------------------
    483 outsegf:        cmpi.w  #P_FILTER,d0    * see if it's filter
    484                 bne     outsegp         * jump if not
    485 *
    486                 ext.l   d3              * make function value a long
    487                 asr.l   #1,d3           * multiply function value by .75
    488                 move.l  d3,d0           * ...  (fast multiply by .75
    489                 asr.l   #1,d0           * ...   via shift and add)
    490                 add.l   d0,d3           * ...
    491                 move.w  (a1),d0         * add pitch
    492                 ext.l   d0              * ...
    493                 add.l   d0,d3           * ...
    494                 cmpi.l  #VALMAX,d3      * see if it's within limits
    495                 ble     outsega         * ...
    496 *
    497                 move.w  #VALMAX,d3      * limit at VALMAX
    498                 bra     outseg3         * ...
    499 *
    500 outsega:        cmpi.l  #VALMIN,d3      * ...
    501                 bge     outseg3         * ...
    502 *
    503                 move.w  #VALMIN,d3      * limit at VALMIN
    504                 bra     outseg3         * ...
    505 *
    506                 .page
    507 * ------------------------------------------------------------------------------
    508 * freq 1..4
    509 * ------------------------------------------------------------------------------
    510 outsegp:        cmpi.w  #P_FREQ1,d0     * see if it's freq1
    511                 beq     outseg0         * go process freq1
    512 *
    513 outsegq:        cmpi.w  #P_FREQ2,d0     * see if it's freq2
    514                 beq     outseg0         * process it if so
    515 *
    516                 cmpi.w  #P_FREQ3,d0     * see if it's freq3
    517                 beq     outseg0         * process it if so
    518 *
    519                 cmpi.w  #P_FREQ4,d0     * see if it's freq4
    520                 bne     outseg3         * jump if not
    521 *
    522 outseg0:        ext.l   d3              * scale the point value to cents offset
    523                 asr.l   #5,d3           * ...
    524                 sub.l   #500,d3         * ... value - 500
    525                 asl.l   #LSPCH,d3       * mult. by 2 and scale for 1/2 cent lsb
    526                 move.w  (a1),d0         * add pitch from function header
    527                 ext.l   d0              * ...
    528                 add.l   d0,d3           * ...
    529                 cmp.l   #PCHMAX,d3      * see if result is valid
    530                 ble     outseg3         * jump if within pitch limits
    531 *
    532                 move.l  #PCHMAX,d3      * limit at maximum pitch
    533 *
    534 * ------------------------------------------------------------------------------
    535 * send the value to the FPU
    536 * ------------------------------------------------------------------------------
    537 outseg3:        move.b  FH_TMD(a1),d0   * get hardware bits from function header
    538                 eor.w   #VAL_BITS,d0    * toggle new value select bits
    539                 move.b  d0,FH_TMD(a1)   * store updated word
    540                 btst.l  #VSUBNBIT,d0    * check which value address to use
     35
     36                .page
     37| ------------------------------------------------------------------------------
     38| Register usage
     39| --------------
     40|       d0      scratch
     41|       d1      FPU function index
     42|       d2      point index from FH_CPT  (idfcpt)
     43|       d3      scratch
     44|       d4      jump point number from PT_PAR1  (ippar1)
     45|       d5      scratch
     46
     47|       a0      scratch
     48|       a1      function header base
     49|       a2      point table base
     50|       a3      FPU base
     51
     52| ------------------------------------------------------------------------------
     53| FPU definitions
     54| ---------------
     55
     56UPD_BIT         =       0x0001                  | update bit  (1 = update)
     57INT_BIT         =       0x0002                  | int. bit    (0 = disable)
     58RAT_BIT         =       0x0004                  | ratio bit   (0 = ratio)
     59
     60VSUBNBIT        =       3                       | new value select bit number
     61VAL_BITS        =       0x0018                  | new value select bit mask
     62
     63MSK_RNVB        =       0x000C                  | new value / ratio bits
     64MSK_ONVB        =       0x0010                  | old new value bit
     65
     66FKILL           =       0x0014                  | kill value for function
     67FSEND           =       0x0015                  | send new value to function
     68
     69CLREXP          =       0x8000                  | clear value for time exponent
     70CLRMNT          =       0x8000                  | clear value for time mantissa
     71
     72| ------------------------------------------------------------------------------
     73| Miscellaneous definitions
     74| -------------------------
     75
     76PCHMAX          =       21920                   | maximum pitch value
     77VALMAX          =       32000                   | maximum value to send to FPU
     78VALMIN          =       -32000                  | minimum value to send to FPU
     79
     80LSPCH           =       2                       | left shift for sources to freq
     81
     82VALLEN          =       10                      | length of the 'valent' struct
     83VT_VAL          =       8                       | value offset in 'valent'
     84
     85                .page
     86| ------------------------------------------------------------------------------
     87| FPU addresses
     88| -------------
     89
     90FPUBASE         =       0x180000                | FPU base address
     91
     92FPUWST          =       FPUBASE                 | FPU waveshape base
     93FPUFUNC         =       FPUBASE+0x4000          | FPU function base
     94FPUINT1         =       FPUBASE+0x4000          | FPU int. input address (R/O)
     95FPUINT2         =       FPUBASE+0x6000          | FPU int. reset address (W/O)
     96FPUCFG          =       FPUBASE+0x5FE0          | FPU config. data address (W/O)
     97
     98F_CTL           =       0x00                    | control word
     99F_VAL10         =       0x02                    | new value "10"
     100F_CV1           =       0x08                    | control voltage 1
     101F_SF1           =       0x0A                    | scale factor 1
     102F_CV2           =       0x0C                    | control voltage 2
     103F_SF2           =       0x0E                    | scale factor 2
     104F_CV3           =       0x10                    | control voltage 3
     105F_SF3           =       0x12                    | scale factor 3
     106F_MNT           =       0x14                    | time mantissa
     107F_EXP           =       0x16                    | time exponent
     108F_VAL01         =       0x1C                    | new value "01"
     109
     110P_FREQ1         =       0x0020                  | frequency 1
     111P_FREQ2         =       0x0060                  | frequency 2
     112P_FREQ3         =       0x00A0                  | frequency 3
     113P_FREQ4         =       0x00E0                  | frequency 4
     114P_FILTER        =       0x0140                  | filter
     115P_FILTRQ        =       0x00C0                  | filter q
     116
     117P_INDEX1        =       0x0120                  | index 1
     118P_INDEX2        =       0x0160                  | index 2
     119P_INDEX3        =       0x0180                  | index 3
     120P_INDEX4        =       0x01A0                  | index 4
     121P_INDEX5        =       0x01C0                  | index 5
     122P_INDEX6        =       0x01E0                  | index 6
     123
     124P_LEVEL         =       0x0040                  | level
     125
     126P_LOCN          =       0x0080                  | location
     127P_DYNAM         =       0x0100                  | dynamics
     128
     129                .page
     130| ------------------------------------------------------------------------------
     131| Structure definitions
     132| ------------------------------------------------------------------------------
     133| The following MUST match the idfnhdr structure definition in instdsp.h:
     134
     135FH_LEN          =       12              | length of the idfnhdr structure
     136
     137FH_PCH          =       0               | WORD - pitch offset  (freq1 only)
     138FH_MLT          =       2               | WORD - overall value multiplier
     139FH_SRC          =       4               | BYTE - overall value source
     140FH_PIF          =       5               | BYTE - # of points in the function
     141FH_PT1          =       6               | BYTE - index of first point
     142FH_TMD          =       7               | BYTE - trigger mode / control bits
     143FH_CPT          =       8               | BYTE - current point
     144FH_PRM          =       9               | BYTE - misc. function parameter
     145FH_TRG          =       10              | WORD - trigger
     146
     147I_ACTIVE        =       1               | 'Active' bit number        (in FH_TMD)
     148
     149MSK_CTL         =       0x001C          | mask for FPU hardware bits (in FH_TMD)
     150
     151| ------------------------------------------------------------------------------
     152| The following MUST match the instpnt structure definition in instdsp.h:
     153
     154PT_LEN          =       12              | length of the instpnt structure
     155
     156PT_TIM          =       0               | WORD - time (packed)
     157PT_VAL          =       2               | WORD - value
     158PT_VMLT         =       4               | WORD - value multiplier
     159PT_VSRC         =       6               | BYTE - value source
     160PT_ACT          =       7               | BYTE - action
     161PT_PAR1         =       8               | BYTE - parameter 1
     162PT_PAR2         =       9               | BYTE - parameter 2
     163PT_PAR3         =       10              | BYTE - parameter 3
     164PT_PAD          =       11              | BYTE - padding for even boundary
     165
     166MSK_MNT         =       0xFFF0          | mask for mantissa  (in PT_TIM)
     167MSK_EXP         =       0x000F          | mask for exponent  (in PT_TIM)
     168
     169MAX_ACT         =       7               | maximum action code value
     170
     171                .page
     172
     173| ------------------------------------------------------------------------------
     174| pflist definitions -- must match those in instdsp.h
     175
     176PF_NEXT         =       0
     177PF_TRIG         =       4
     178PF_FUNC         =       6
     179PF_D1           =       8
     180PF_D2           =       12
     181PF_D4           =       16
     182PF_A1           =       20
     183PF_A2           =       24
     184PF_A3           =       28
     185| ------------------------------------------------------------------------------
     186| Source definitions -- must match those in 'smdefs.h'
     187
     188SM_RAND         =       1               | random
     189SM_PTCH         =       5               | pitch
     190SM_KPRS         =       6               | key pressure
     191SM_KVEL         =       7               | key velocity
     192SM_FREQ         =       10              | frequency
     193
     194                .page
     195| ------------------------------------------------------------------------------
     196| _fpuint() -- process FPU interrupts
     197
     198|       void
     199|       fpuint();
     200
     201|               Processes FPU interrupts.  Must be the target of vector 26,
     202|               which is Autovector Interrupt level 2.
     203
     204| ------------------------------------------------------------------------------
     205
     206_fpuint:        movem.l d0-d5/a0-a3,-(a7)       | preserve registers we use
     207                move.w  FPUINT1,d0      | read FPU interrupt status
     208                andi.w  #0x00FF,d0      | mask out garbage in MS bits
     209                move.w  d0,_fpuifnc     | save for later use
     210                move.w  _ndisp,d1       | get display number
     211                cmpi.w  #11,d1          | see if we display
     212                bne     nodisp          | jump if not
     213
     214                tst.w   _scopef         | ...
     215                beq     nodisp          | ...
     216
     217                move.w  d0,-(a7)        | display value
     218                jsr     _scope          | ...
     219                tst.w   (a7)+           | ...
     220
     221                move.w  _fpuifnc,d0     | get FPU status
     222
     223nodisp:         move.w  d0,d1           | save in d1  (becomes function offset)
     224
     225                lsl.w   #5,d1           | develop FPU function offset
     226                lea     FPUFUNC,a3      | setup FPU function base address
     227
     228                lsl.w   #3,d0           | develop funcndx[] index
     229                lea     _funcndx,a0     | setup funcndx[] base address
     230
     231                tst.l   0(a0,d0.W)      | see if function is defined
     232                bne     fnok            | jump if so
     233
     234                move.w  d1,d0           | get function offset in d0
     235                andi.w  #0x1E00,d0      | mask for voice number
     236                cmpi.w  #0x1800,d0      | see if it's a real voice  (0..11)
     237                bge     fpexit          | don't send a kill if not a real voice
     238
     239                move.w  #FKILL,F_CTL(a3,d1.W)   | kill the undefined function
     240
     241fpexit:         clr.w   FPUINT2         | reset the FPU interrupt latch
     242                movem.l (a7)+,d0-d5/a0-a3       | restore the registers
     243                rte                     | return to interrupted code
     244
     245                .page
     246| ------------------------------------------------------------------------------
     247| set up to process active functions,  stop ones that should be inactive
     248| ------------------------------------------------------------------------------
     249fnok:           movea.l 0(a0,d0.W),a1   | get pointer to function header
     250                movea.l 4(a0,d0.W),a2   | get pointer to point table
     251                btst    #I_ACTIVE,FH_TMD(a1)    | see if function is active
     252                bne     doact           | go process action if so
     253
     254| ------------------------------------------------------------------------------
     255| stop a function
     256| ------------------------------------------------------------------------------
     257stopfn:         move.b  FH_TMD(a1),d0   | get function control bits
     258                andi.w  #MSK_RNVB,d0    | mask for ratio / new new-value bit
     259                move.w  d0,d3           | isolate new new-value bit
     260                add.w   d3,d3           | ... from function header
     261                andi.w  #MSK_ONVB,d3    | ... shift to old new-value bit
     262                or.w    d3,d0           | ... and put new bit in old bit
     263                move.w  d0,F_CTL(a3,d1.W)       | stop the function
     264                bclr    #I_ACTIVE,FH_TMD(a1)    | reset the active bit
     265                bra     fpexit          | go restore registers and exit
     266
     267                .page
     268| ------------------------------------------------------------------------------
     269| setup for and dispatch to the proper action handler
     270| ------------------------------------------------------------------------------
     271doact:          clr.w   d2              | get current point index in d2
     272                move.b  FH_CPT(a1),d2   | ...
     273                lsl.w   #2,d2           | multiply it by the length of a point
     274                move.w  d2,d0           | ...  (fast multiply by PT_LEN = 12
     275                add.w   d2,d2           | ...   via shift and add)
     276                add.w   d0,d2           | ...
     277                clr.w   d4              | get jump point # into d4
     278                move.b  PT_PAR1(a2,d2.W),d4     | ...
     279                clr.w   d3              | get action code in d3
     280                move.b  PT_ACT(a2,d2.W),d3      | ...
     281                cmpi.b  #MAX_ACT,d3     | check against the limit
     282                bgt     stopfn          | stop things if it's a bad action code
     283
     284                lsl.w   #2,d3           | develop index to action dispatch table
     285                lea     actab,a0        | get the address of the action handler
     286                movea.l 0(a0,d3.W),a0   | ...
     287
     288| ------------------------------------------------------------------------------
     289| At this point we're ready to do the action associated with the point,
     290| and the registers are set up,  and will remain,  as follows:
     291
     292|       d1      FPU function index      a1      function header base
     293|       d2      point table index       a2      point table base
     294|                                       a3      FPU function base
     295|       d4      jump point number
     296
     297|       d0, d3, d5, and a0 are used as scratch throughout the code.
     298
     299| ------------------------------------------------------------------------------
     300
     301_fputrap:       jmp     (a0)            | dispatch to action handler
     302
     303                .page
     304| ------------------------------------------------------------------------------
     305| act0 -- AC_NULL -- no action
     306| ----    --------------------
     307act0:           move.b  FH_PT1(a1),d0   | get first point number
     308                add.b   FH_PIF(a1),d0   | add number of points in function
     309                subq.b  #1,d0           | make it last point number
     310                cmp.b   FH_CPT(a1),d0   | see if we're at the last point
     311                beq     stopfn          | stop function if so
     312
     313                addq.b  #1,FH_CPT(a1)   | update function header for next point
     314                addi.w  #PT_LEN,d2      | advance the point index
     315
     316| ------------------------------------------------------------------------------
     317| outseg -- output a segment
     318| ------    ----------------
     319outseg:         move.w  PT_TIM(a2,d2.w),d3      | get packed time
     320                move.w  d3,d0                   | extract mantissa
     321                andi.w  #MSK_MNT,d0             | ...
     322                mulu    _timemlt,d0             | multiply by panel time pot value
     323                lsr.l   #8,d0                   | ... and scale it
     324                lsr.l   #7,d0                   | ...
     325                move.w  d0,F_MNT(a3,d1.W)       | send mantissa to FPU
     326                andi.w  #MSK_EXP,d3             | extract exponent code
     327                add.w   d3,d3                   | look up decoded exponent
     328                lea     _expbit,a0              | ... in expbit
     329                move.w  0(a0,d3.W),F_EXP(a3,d1.W)       | send exponent to FPU
     330                move.w  PT_VAL(a2,d2.W),d3      | get the function value
     331
     332| ------------------------------------------------------------------------------
     333| get the point source, if any
     334| ------------------------------------------------------------------------------
     335                tst.w   PT_VMLT(a2,d2.W)        | see if we have a point mlt.
     336                beq     nosrc                   | don't do anything for zero
     337
     338                clr.w   d0                      | get the source number
     339                move.b  PT_VSRC(a2,d2.W),d0     | ...
     340                beq     nosrc                   | don't do anything for zero
     341
     342| ------------------------------------------------------------------------------
     343| SM_RAND -- random
     344| ------------------------------------------------------------------------------
     345                cmpi.w  #SM_RAND,d0             | is this the random source ?
     346                bne     srctyp0                 | jump if not
     347
     348                movem.l d1-d2/a0-a2,-(a7)       | preserve registers around call
     349                move.w  PT_VMLT(a2,d2.W),-(a7)  | pass multiplier to xgetran()
     350                jsr     _xgetran                | call for a random number
     351                tst.w   (a7)+                   | clean up stack
     352                movem.l (a7)+,d1-d2/a0-a2       | restore registers
     353                move.w  d0,d5                   | put random value in the value register
     354                bra     applym                  | go apply the multiplier
     355
     356                .page
     357| ------------------------------------------------------------------------------
     358| SM_FREQ -- frequency
     359| ------------------------------------------------------------------------------
     360srctyp0:        cmpi.w  #SM_FREQ,d0     | is this the frequency source ?
     361                bne     srctyp1         | jump if not
     362
     363                move.w  (a1),d0         | get the pitch
     364                lsr.w   #6,d0           | shift to a word index
     365                andi.w  #0x01FE,d0      | mask out extraneous bits
     366                lea     _ptoftab,a0     | get entry from ptoftab[]
     367                move.w  0(a0,d0.W),d5   | ...
     368                bra     applym          | go apply the multiplier
     369
     370| ------------------------------------------------------------------------------
     371| SM_PTCH -- pitch
     372| ------------------------------------------------------------------------------
     373srctyp1:        cmpi.w  #SM_PTCH,d0     | is this the pitch source ?
     374                bne     srctyp2         | jump if not
     375
     376                move.w  (a1),d5         | get the pitch as the value
     377                bra     applym          | go apply the multiplier
     378
     379| ------------------------------------------------------------------------------
     380| SM_KVEL -- velocity
     381| ------------------------------------------------------------------------------
     382srctyp2:        cmpi.w  #SM_KVEL,d0     | is this the key velocity source ?
     383                bne     srctyp3         | jump if not
     384
     385                move.w  FH_TRG(a1),d0   | get the trigger number
     386                add.w   d0,d0           | ... as a word index
     387                lea     _veltab,a0      | ... into veltab[]
     388                move.w  0(a0,d0.W),d5   | get the velocity from veltab[trg]
     389                bra     applym          | go apply the multiplier
     390
     391| ------------------------------------------------------------------------------
     392| SM_KPRS -- pressure
     393| ------------------------------------------------------------------------------
     394srctyp3:        cmpi.w  #SM_KPRS,d0     | is this the key pressure source ?
     395                bne     srctyp4         | jump if not  (must be an analog input)
     396
     397                move.w  FH_TRG(a1),d0   | get the trigger number
     398                add.w   d0,d0           | ... as a word index
     399                lea     _prstab,a0      | ... into prstab[]
     400                move.w  0(a0,d0.W),d5   | get the pressure from prstab[trg]
     401                bra     applym          | go apply the multiplier
     402
     403                .page
     404| ------------------------------------------------------------------------------
     405| all other sources come out of the valents[] array
     406| ------------------------------------------------------------------------------
     407srctyp4:        lea     _vce2grp,a0     | point at vce2grp[]
     408                move.w  _fpuifnc,d5     | get voice number in d5
     409                lsr.w   #3,d5           | ...
     410                andi.w  #0x001E,d5      | ... as a word index
     411                move.w  0(a0,d5.W),d5   | get the group number
     412                subq.w  #1,d5           | ...
     413                lsl.w   #4,d5           | shift it left a nybble
     414                or.w    d5,d0           | OR it into the source number
     415                add.w   d0,d0           | make source number a valents[] index
     416                move.w  d0,d5           | ... (fast multiply by VALLEN = 10
     417                lsl.w   #2,d0           | ...  via shift and add)
     418                add.w   d5,d0           | ...
     419                lea     _valents,a0     | get base of valents[]
     420                move.w  VT_VAL(a0,d0.W),d5      | get value
     421
     422| ------------------------------------------------------------------------------
     423| apply the multiplier to the source, and add it to the function value
     424| ------------------------------------------------------------------------------
     425applym:         muls    PT_VMLT(a2,d2.W),d5     | apply the multiplier
     426                asr.l   #7,d5           | scale the result
     427                asr.l   #8,d5           | ...
     428                ext.l   d3              | add the function value
     429                add.l   d3,d5           | ...
     430                cmpi.l  #VALMAX,d5      | check for overflow
     431                ble     srcmlt1         | jump if no overflow
     432
     433                move.l  #VALMAX,d5      | limit at VALMAX
     434                bra     srcmlt2         | ...
     435
     436srcmlt1:        cmpi.l  #VALMIN,d5      | check for underflow
     437                bge     srcmlt2         | jump if no underflow
     438
     439                move.l  #VALMIN,d5      | limit at VALMIN
     440
     441srcmlt2:        move.w  d5,d3           | setup value for output to FPU
     442
     443                .page
     444| ------------------------------------------------------------------------------
     445| adjust the value according to the function type
     446| ------------------------------------------------------------------------------
     447nosrc:          move.w  d1,d0           | get function type
     448                andi.w  #0x01E0,d0      | ...
     449
     450| ------------------------------------------------------------------------------
     451| level or location
     452| ------------------------------------------------------------------------------
     453                cmpi.w  #P_LEVEL,d0     | see if it's the level
     454                beq     outsegl         | jump if so
     455
     456                cmpi.w  #P_LOCN,d0      | see if it's the location
     457                bne     outsegf         | jump if not
     458
     459                tst.w   d3              | check sign of value
     460                bpl     outsegc         | jump if positive
     461
     462                clr.w   d3              | force negative values to 0
     463
     464outsegc:        asr.w   #5,d3           | shift value to LS bits
     465                sub.w   #500,d3         | subtract 5.00 from value
     466                asl.w   #6,d3           | readjust to MS bits
     467                bra     outseg3         | go output the value
     468
     469outsegl:        tst.w   d3              | check sign of value
     470                bpl     outsegm         | jump if positive
     471
     472                clr.w   d3              | limit negative values at 0
     473
     474outsegm:        asr.w   #5,d3           | shift value to LS bits
     475                sub.w   #500,d3         | subtract 5.00 from value
     476                asl.w   #6,d3           | readjust to MS bits
     477                bra     outseg3         | go output the value
     478
     479                .page
     480| ------------------------------------------------------------------------------
     481| filter
     482| ------------------------------------------------------------------------------
     483outsegf:        cmpi.w  #P_FILTER,d0    | see if it's filter
     484                bne     outsegp         | jump if not
     485
     486                ext.l   d3              | make function value a long
     487                asr.l   #1,d3           | multiply function value by .75
     488                move.l  d3,d0           | ...  (fast multiply by .75
     489                asr.l   #1,d0           | ...   via shift and add)
     490                add.l   d0,d3           | ...
     491                move.w  (a1),d0         | add pitch
     492                ext.l   d0              | ...
     493                add.l   d0,d3           | ...
     494                cmpi.l  #VALMAX,d3      | see if it's within limits
     495                ble     outsega         | ...
     496
     497                move.w  #VALMAX,d3      | limit at VALMAX
     498                bra     outseg3         | ...
     499
     500outsega:        cmpi.l  #VALMIN,d3      | ...
     501                bge     outseg3         | ...
     502
     503                move.w  #VALMIN,d3      | limit at VALMIN
     504                bra     outseg3         | ...
     505
     506                .page
     507| ------------------------------------------------------------------------------
     508| freq 1..4
     509| ------------------------------------------------------------------------------
     510outsegp:        cmpi.w  #P_FREQ1,d0     | see if it's freq1
     511                beq     outseg0         | go process freq1
     512
     513outsegq:        cmpi.w  #P_FREQ2,d0     | see if it's freq2
     514                beq     outseg0         | process it if so
     515
     516                cmpi.w  #P_FREQ3,d0     | see if it's freq3
     517                beq     outseg0         | process it if so
     518
     519                cmpi.w  #P_FREQ4,d0     | see if it's freq4
     520                bne     outseg3         | jump if not
     521
     522outseg0:        ext.l   d3              | scale the point value to cents offset
     523                asr.l   #5,d3           | ...
     524                sub.l   #500,d3         | ... value - 500
     525                asl.l   #LSPCH,d3       | mult. by 2 and scale for 1/2 cent lsb
     526                move.w  (a1),d0         | add pitch from function header
     527                ext.l   d0              | ...
     528                add.l   d0,d3           | ...
     529                cmp.l   #PCHMAX,d3      | see if result is valid
     530                ble     outseg3         | jump if within pitch limits
     531
     532                move.l  #PCHMAX,d3      | limit at maximum pitch
     533
     534| ------------------------------------------------------------------------------
     535| send the value to the FPU
     536| ------------------------------------------------------------------------------
     537outseg3:        move.b  FH_TMD(a1),d0   | get hardware bits from function header
     538                eor.w   #VAL_BITS,d0    | toggle new value select bits
     539                move.b  d0,FH_TMD(a1)   | store updated word
     540                btst.l  #VSUBNBIT,d0    | check which value address to use
    541541                beq     outseg1
    542 *
    543                 move.w  d3,F_VAL01(a3,d1.W)     * send value to FPU
     542
     543                move.w  d3,F_VAL01(a3,d1.W)     | send value to FPU
    544544                bra     outseg2
    545 *
    546 outseg1:        move.w  d3,F_VAL10(a3,d1.W)     * send value to FPU
    547 *
    548 outseg2:        andi.w  #MSK_CTL,d0             * mask off software bits
    549                 ori.w   #UPD_BIT+INT_BIT,d0     * set the update & !lastseg bits
    550                 move.w  d0,F_CTL(a3,d1.W)       * send control word to FPU
    551                 bra     fpexit                  * done -- exit
    552 *
    553                 .page
    554 *
    555 * ------------------------------------------------------------------------------
    556 * act1 -- AC_SUST -- pause if key is down  (sustain)
    557 * ----    ------------------------------------------
    558 act1:           move.w  _fpuifnc,d0     * get voice as a word index
    559                 lsr.w   #3,d0           * ...
    560                 andi.w  #$001E,d0       * ...
    561                 lea     _vce2trg,a0     * point at voice to trigger table
    562                 move.w  0(a0,d0.W),d0   * get trigger table entry into d0
    563                 cmpi.w  #-1,d0          * see if voice is free
    564                 beq     act0            * continue function if so
    565 *
    566                 btst    #15,d0          * see if voice is held by a pedal
    567                 bne     act1a           * sustain if so
    568 *
    569                 btst    #14,d0          * see if voice is sustained by a pedal
    570                 bne     act1a           * sustain if so
    571 *
    572                 lea     _trgtab,a0      * point at trigger table
    573                 tst.b   0(a0,d0.W)      * check trigger status
    574                 beq     act0            * continue function if not active
    575 *
    576 act1a:          move.l  _pfqhdr,d3      * see if any pflist entries remain
    577                 beq     act0            * continue if not  (shouldn't happen!)
    578 *
    579                 move.b  FH_PT1(a1),d0   * get first point number
    580                 add.b   FH_PIF(a1),d0   * add base to first point
    581                 subq.b  #1,d0           * make d0 last point number
    582                 cmp.b   FH_CPT(a1),d0   * check current point number
    583                 beq     stopfn          * done if this is the last point
    584 *
    585                 addq.b  #1,FH_CPT(a1)           * update current point number
    586                 addi.w  #PT_LEN,d2              * advance the point index
    587                 movea.l d3,a0                   * acquire a new pflist entry
    588                 move.l  (a0),_pfqhdr            * ...
    589                 move.l  _pflist,(a0)            * chain it to pflist
    590                 move.l  a0,_pflist              * ...
    591                 move.w  FH_TRG(a1),PF_TRIG(a0)          * set trigger number in entry
    592                 move.w  _fpuifnc,PF_FUNC(a0)            * set v/p word in entry
    593                 movem.l d1-d2/d4/a1-a3,PF_D1(a0)        * set registers in entry
    594                 move.b  FH_TMD(a1),d0           * stop the function
    595                 andi.w  #MSK_RNVB,d0            * ...
    596                 move.w  d0,d3                   * ...
    597                 add.w   d3,d3                   * ...
    598                 andi.w  #MSK_ONVB,d3            * ...
    599                 or.w    d3,d0                   * ...
    600                 move.w  d0,F_CTL(a3,d1.W)       * ...
    601                 bra     fpexit                  * exit
    602 *
    603                 .page
    604 *
    605 * ------------------------------------------------------------------------------
    606 * act2 -- AC_ENBL -- stop if key is up
    607 * ----    ----------------------------
    608 act2:           move.w  _fpuifnc,d0     * get voice as a word index
    609                 lsr.w   #3,d0           * ...
    610                 andi.w  #$001E,d0       * ...
    611                 lea     _vce2trg,a0     * check to see if voice is free
    612                 move.w  0(a0,d0.W),d0   * ...
    613                 cmpi.w  #-1,d0          * ...
    614                 beq     stopfn          * if so, stop the function
    615 *
    616                 btst    #15,d0          * see if voice is held
    617                 bne     act0            * continue if so
    618 *
    619                 btst    #14,d0          * ...
    620                 bne     act0            * ...
    621 *
    622                 lea     _trgtab,a0      * check trigger table entry
    623                 tst.b   0(a0,d0.W)      * ...
    624                 bne     act0            * if trigger is active, continue
    625 *
    626                 bra     stopfn          * if not, stop the function
    627 *
    628 * ------------------------------------------------------------------------------
    629 * act3 -- AC_JUMP -- unconditional jump
    630 * ----    -----------------------------
    631 act3:           cmp.b   FH_PIF(a1),d4   * check jump point against limit
    632                 bcc     stopfn          * stop function if jump point invalid
    633 *
    634                 clr.w   d2              * get index of first point
    635                 move.b  FH_PT1(a1),d2   * ...
    636                 add.b   d4,d2           * add jump point
    637                 move.b  d2,FH_CPT(a1)   * make it the current point
    638                 lsl.w   #2,d2           * develop new point index in d2
    639                 move.w  d2,d0           * ... (fast multiply by PT_LEN = 12
    640                 add.w   d2,d2           * ...  via shift and add)
    641                 add.w   d0,d2           * ...
    642                 bra     outseg          * output the segment
    643 *
    644                 .page
    645 *
    646 * ------------------------------------------------------------------------------
    647 * act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times
    648 * ----    ----------------------------------------------
    649 act4:           tst.b   PT_PAR3(a2,d2.W)        * check counter
    650                 bne     act4a                   * jump if it's running
    651 *
    652                 move.b  PT_PAR2(a2,d2.W),d0     * get parameter
    653                 subi.w  #90,d0                  * put parameter in random range
    654                 bmi     act4b                   * treat as normal if < 90
    655 *
    656                 movem.l d1-d2/a0-a2,-(a7)       * get ranged random number
    657                 move.w  d0,-(a7)                * ...
    658                 jsr     _irand                  * ...
    659                 tst.w   (a7)+                   * ...
    660                 movem.l (a7)+,d1-d2/a0-a2       * ...
    661                 move.b  d0,PT_PAR3(a2,d2.w)     * set counter
    662                 beq     act0                    * next segment if cntr set to 0
    663 *
    664                 bra     act3                    * else jump to the point
    665 *
    666 act4b:          move.b  PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W)       * set counter
    667                 beq     act0                    * next segment if cntr set to 0
    668 *
    669                 bra     act3                    * else jump to the point
    670 *
    671 act4a:          subq.b  #1,PT_PAR3(a2,d2.W)     * decrement counter
    672                 beq     act0                    * next segment if cntr ran out
    673 *
    674                 bra     act3                    * jump if it's still non-zero
    675 *
    676 * ------------------------------------------------------------------------------
    677 * act5 -- AC_KYUP -- jump if key is up
    678 * ----    ----------------------------
    679 act5:           move.w  _fpuifnc,d0     * get voice as a word index
    680                 lsr.w   #3,d0           * ...
    681                 andi.w  #$001E,d0       * ...
    682                 lea     _vce2trg,a0     * check to see if voice is free
    683                 move.w  0(a0,d0.W),d0   * ...
    684                 cmpi.w  #-1,d0          * ...
    685                 beq     act3            * if so (inactive), do the jump
    686 *
    687                 btst    #15,d0          * see if voice is held
    688                 bne     act0            * continue if so
    689 *
    690                 btst    #14,d0          * ...
    691                 bne     act0            * ...
    692 *
    693                 lea     _trgtab,a0      * check trigger table entry
    694                 tst.b   0(a0,d0.W)      * see if the trigger is active
    695                 beq     act3            * if not, do the jump
    696 *
    697                 bra     act0            * if so, do next segment
    698 *
    699                 .page
    700 *
    701 * ------------------------------------------------------------------------------
    702 * act6 -- AC_KYDN -- jump if key is down
    703 * ----    ------------------------------
    704 act6:           move.w  _fpuifnc,d0     * get voice as a word index
    705                 lsr.w   #3,d0           * ...
    706                 andi.w  #$001E,d0       * ...
    707                 lea     _vce2trg,a0     * check to see if voice is free
    708                 move.w  0(a0,d0.W),d0   * ...
    709                 cmpi.w  #-1,d0          * ...
    710                 beq     act0            * if so (inactive), continue
    711 *
    712                 btst    #15,d0          * see if voice is held
    713                 bne     act3            * do jump if so
    714 *
    715                 btst    #14,d0          * ...
    716                 bne     act3            * ...
    717 *
    718                 lea     _trgtab,a0      * check trigger table entry
    719                 tst.b   0(a0,d0.W)      * see if the trigger is active
    720                 bne     act3            * if so, do the jump
    721 *
    722                 bra     act0            * if not, do next segment
    723 *
    724 * ------------------------------------------------------------------------------
    725 * Test stub
    726 * ---------
    727 act7:           bra     act0            * AC_HERE: treat act7 as AC_NULL
    728 *
    729                 .page
    730 * ------------------------------------------------------------------------------
    731 *
    732 * _fpuclr -- clear the FPU
    733 * -------    -------------
    734 *
    735 *       void
    736 *       fpuclr()
    737 *
    738 *               Resets the FPU functions to their nominal values.
    739 *
    740 * ------------------------------------------------------------------------------
    741 *
    742 _fpuclr:        link    a6,#0                   * link stack frames
    743                 move.w  sr,-(a7)                * save the interrupt level
    744                 ori.w   #$0700,sr               * turn off interrupts
    745 *
    746                 lea     FPUFUNC,a0              * point at the first function
    747                 lea     _fp_resv,a2             * point at reset value table
    748                 move.w  #11,d1                  * set the outer loop count
    749 *
    750                 .page
    751 * ------------------------------------------------------------------------------
    752 * reset the 'spare' function for the voice
    753 * ------------------------------------------------------------------------------
    754 clr0:           move.w  #CLREXP,F_EXP(a0)       * set time exponent
    755                 tst.l   actab                   * delay
    756                 tst.l   actab                   * ...
    757                 move.w  #CLRMNT,F_MNT(a0)       * set time mantissa
    758                 tst.l   actab                   * delay
    759                 tst.l   actab                   * ...
    760 *
    761                 move.w  #0,F_SF3(a0)            * set scale factor 3
    762                 tst.l   actab                   * delay
    763                 tst.l   actab                   * ...
    764                 move.w  #0,F_CV3(a0)            * set voltage 3
    765                 tst.l   actab                   * delay
    766                 tst.l   actab                   * ...
    767 *
    768                 move.w  #0,F_SF2(a0)            * set scale factor 2
    769                 tst.l   actab                   * delay
    770                 tst.l   actab                   * ...
    771                 move.w  #0,F_CV2(a0)            * set voltage 2
    772                 tst.l   actab                   * delay
    773                 tst.l   actab                   * ...
    774 *
    775                 move.w  #0,F_SF1(a0)            * set scale factor 1
    776                 tst.l   actab                   * delay
    777                 tst.l   actab                   * ...
    778                 move.w  #0,F_CV1(a0)            * set voltage 1
    779                 tst.l   actab                   * delay
    780                 tst.l   actab                   * ...
    781 *
    782                 move.w  (a2),F_VAL10(a0)        * set value from variable table
    783                 tst.l   actab                   * delay
    784                 tst.l   actab                   * ...
    785                 move.w  (a2)+,F_VAL01(a0)       * ...
    786                 tst.l   actab                   * delay
    787                 tst.l   actab                   * ...
    788                 move.w  #FSEND,F_CTL(a0)        * set control word
    789                 tst.l   actab                   * delay
    790                 tst.l   actab                   * ...
    791 *
    792                 .page
    793                 adda.w  #$0020,a0               * point at 2nd function
    794                 lea     fprescon,a1             * set reset constant pointer
    795                 move.w  #14,d0                  * set inner loop count
    796 *
    797 * ------------------------------------------------------------------------------
    798 * reset the other functions for the voice
    799 * ------------------------------------------------------------------------------
    800 clr1:           move.w  #CLREXP,F_EXP(a0)       * set time exponent
    801                 tst.l   actab                   * delay
    802                 tst.l   actab                   * ...
    803                 move.w  #CLRMNT,F_MNT(a0)       * set time mantissa
    804                 tst.l   actab                   * delay
    805                 tst.l   actab                   * ...
    806 *
    807                 move.w  #0,F_SF3(a0)            * set scale factor 3
    808                 tst.l   actab                   * delay
    809                 tst.l   actab                   * ...
    810                 move.w  #0,F_CV3(a0)            * set voltage 3
    811                 tst.l   actab                   * delay
    812                 tst.l   actab                   * ...
    813 *
    814                 move.w  #0,F_SF2(a0)            * set scale factor 2
    815                 tst.l   actab                   * delay
    816                 tst.l   actab                   * ...
    817                 move.w  #0,F_CV2(a0)            * set voltage 2
    818                 tst.l   actab                   * delay
    819                 tst.l   actab                   * ...
    820 *
    821                 move.w  #0,F_SF1(a0)            * set scale factor 1
    822                 tst.l   actab                   * delay
    823                 tst.l   actab                   * ...
    824                 move.w  #0,F_CV1(a0)            * set voltage 1
    825                 tst.l   actab                   * delay
    826                 tst.l   actab                   * ...
    827 *
    828                 move.w  (a1),F_VAL10(a0)        * set value from constant table
    829                 tst.l   actab                   * delay
    830                 tst.l   actab                   * ...
    831                 move.w  (a1)+,F_VAL01(a0)       * ...
    832                 tst.l   actab                   * delay
    833                 tst.l   actab                   * ...
    834                 move.w  #FSEND,F_CTL(a0)        * set control word
    835                 tst.l   actab                   * delay
    836                 tst.l   actab                   * ...
    837 *
    838                 .page
    839 * ------------------------------------------------------------------------------
    840 * loop through reset for all of the voices and functions
    841 * ------------------------------------------------------------------------------
    842                 adda.w  #$0020,a0               * point at next function
    843                 dbra    d0,clr1                 * loop until all funcs. cleared
    844 *
    845                 dbra    d1,clr0                 * loop until all voices cleared
    846 * ------------------------------------------------------------------------------
    847 * clear the FPU interrupt, and return
    848 * ------------------------------------------------------------------------------
    849                 move.w  #0,FPUINT2              * clear FPU interrupt
    850                 move.w  (a7)+,sr                * restore interrupts
    851                 unlk    a6                      * unlink stack frames
    852                 rts                             * return to caller
    853 *
    854                 .page
    855 *
    856 * _clrvce -- quiet a voice
    857 * -------    -------------
    858 *
    859 *       void
    860 *       clrvce(vce)
    861 *       short vce;
    862 *
    863 *               Quiet the voice by resetting the FPU functions it uses.
    864 *
    865 _clrvce:        link    a6,#0                   * link stack frames
    866                 move.w  sr,-(a7)                * save the interrupt level
    867                 ori.w   #$0700,sr               * turn off interrupts
    868 *
    869                 lea     FPUFUNC+$20,a0          * point at the 2nd function
    870                 move.w  8(a6),d0                * get voice number
    871                 ext.l   d0                      * ...
    872                 lsl.l   #8,d0                   * shift into position
    873                 add.l   d0,d0                   * ...
    874                 adda.l  d0,a0                   * add to function base
    875                 lea     fprescon,a1             * set reset constant pointer
    876                 move.w  #14,d0                  * set inner loop count
    877 *
    878 vclr1:          move.l  a0,d1                   * see if we reset this function
    879                 and.w   #$01F0,d1               * ...
    880 *
    881                 cmpi.w  #$0100,d1               * dynamics ?
    882                 beq     vclr2                   * skip it if so
    883 *
    884                 move.w  #CLREXP,F_EXP(a0)       * set time exponent
    885                 tst.l   actab                   * delay
    886                 tst.l   actab                   * ...
    887                 move.w  #CLRMNT,F_MNT(a0)       * set time mantissa
    888                 tst.l   actab                   * delay
    889                 tst.l   actab                   * ...
    890 *
    891                 cmpi.w  #$0020,d1               * freq 1 ?
    892                 beq     vclr3                   * don't reset CV3 (fine tune)
    893 *
    894                 move.w  #0,F_SF3(a0)            * set scale factor 3
    895                 tst.l   actab                   * delay
    896                 tst.l   actab                   * ...
    897                 move.w  #0,F_CV3(a0)            * set voltage 3
    898                 tst.l   actab                   * delay
    899                 tst.l   actab                   * ...
    900 *
    901 vclr3:          move.w  #0,F_SF1(a0)            * set scale factor 1
    902                 tst.l   actab                   * delay
    903                 tst.l   actab                   * ...
    904                 move.w  #0,F_CV1(a0)            * set voltage 1
    905                 tst.l   actab                   * delay
    906                 tst.l   actab                   * ...
    907 *
    908                 .page
    909 *
    910                 move.w  (a1),F_VAL10(a0)        * set value from constant table
    911                 tst.l   actab                   * delay
    912                 tst.l   actab                   * ...
    913                 move.w  (a1),F_VAL01(a0)        * ...
    914                 tst.l   actab                   * delay
    915                 tst.l   actab                   * ...
    916                 move.w  #FSEND,F_CTL(a0)        * set control word
    917                 tst.l   actab                   * delay
    918                 tst.l   actab                   * ...
    919 *
    920 vclr2:          adda.w  #2,a1                   * point at next function
    921                 adda.w  #$0020,a0               *
    922                 dbra    d0,vclr1                * loop until all funcs. cleared
    923 *
    924                 move.w  (a7)+,sr                * restore interrupts
    925                 unlk    a6                      * unlink stack frames
    926                 rts                             * return to caller
    927 *
    928                 .page
    929 * ------------------------------------------------------------------------------
     545
     546outseg1:        move.w  d3,F_VAL10(a3,d1.W)     | send value to FPU
     547
     548outseg2:        andi.w  #MSK_CTL,d0             | mask off software bits
     549                ori.w   #UPD_BIT+INT_BIT,d0     | set the update & !lastseg bits
     550                move.w  d0,F_CTL(a3,d1.W)       | send control word to FPU
     551                bra     fpexit                  | done -- exit
     552
     553                .page
     554
     555| ------------------------------------------------------------------------------
     556| act1 -- AC_SUST -- pause if key is down  (sustain)
     557| ----    ------------------------------------------
     558act1:           move.w  _fpuifnc,d0     | get voice as a word index
     559                lsr.w   #3,d0           | ...
     560                andi.w  #0x001E,d0      | ...
     561                lea     _vce2trg,a0     | point at voice to trigger table
     562                move.w  0(a0,d0.W),d0   | get trigger table entry into d0
     563                cmpi.w  #-1,d0          | see if voice is free
     564                beq     act0            | continue function if so
     565
     566                btst    #15,d0          | see if voice is held by a pedal
     567                bne     act1a           | sustain if so
     568
     569                btst    #14,d0          | see if voice is sustained by a pedal
     570                bne     act1a           | sustain if so
     571
     572                lea     _trgtab,a0      | point at trigger table
     573                tst.b   0(a0,d0.W)      | check trigger status
     574                beq     act0            | continue function if not active
     575
     576act1a:          move.l  _pfqhdr,d3      | see if any pflist entries remain
     577                beq     act0            | continue if not  (shouldn't happen!)
     578
     579                move.b  FH_PT1(a1),d0   | get first point number
     580                add.b   FH_PIF(a1),d0   | add base to first point
     581                subq.b  #1,d0           | make d0 last point number
     582                cmp.b   FH_CPT(a1),d0   | check current point number
     583                beq     stopfn          | done if this is the last point
     584
     585                addq.b  #1,FH_CPT(a1)           | update current point number
     586                addi.w  #PT_LEN,d2              | advance the point index
     587                movea.l d3,a0                   | acquire a new pflist entry
     588                move.l  (a0),_pfqhdr            | ...
     589                move.l  _pflist,(a0)            | chain it to pflist
     590                move.l  a0,_pflist              | ...
     591                move.w  FH_TRG(a1),PF_TRIG(a0)          | set trigger number in entry
     592                move.w  _fpuifnc,PF_FUNC(a0)            | set v/p word in entry
     593                movem.l d1-d2/d4/a1-a3,PF_D1(a0)        | set registers in entry
     594                move.b  FH_TMD(a1),d0           | stop the function
     595                andi.w  #MSK_RNVB,d0            | ...
     596                move.w  d0,d3                   | ...
     597                add.w   d3,d3                   | ...
     598                andi.w  #MSK_ONVB,d3            | ...
     599                or.w    d3,d0                   | ...
     600                move.w  d0,F_CTL(a3,d1.W)       | ...
     601                bra     fpexit                  | exit
     602
     603                .page
     604
     605| ------------------------------------------------------------------------------
     606| act2 -- AC_ENBL -- stop if key is up
     607| ----    ----------------------------
     608act2:           move.w  _fpuifnc,d0     | get voice as a word index
     609                lsr.w   #3,d0           | ...
     610                andi.w  #0x001E,d0      | ...
     611                lea     _vce2trg,a0     | check to see if voice is free
     612                move.w  0(a0,d0.W),d0   | ...
     613                cmpi.w  #-1,d0          | ...
     614                beq     stopfn          | if so, stop the function
     615
     616                btst    #15,d0          | see if voice is held
     617                bne     act0            | continue if so
     618
     619                btst    #14,d0          | ...
     620                bne     act0            | ...
     621
     622                lea     _trgtab,a0      | check trigger table entry
     623                tst.b   0(a0,d0.W)      | ...
     624                bne     act0            | if trigger is active, continue
     625
     626                bra     stopfn          | if not, stop the function
     627
     628| ------------------------------------------------------------------------------
     629| act3 -- AC_JUMP -- unconditional jump
     630| ----    -----------------------------
     631act3:           cmp.b   FH_PIF(a1),d4   | check jump point against limit
     632                bcc     stopfn          | stop function if jump point invalid
     633
     634                clr.w   d2              | get index of first point
     635                move.b  FH_PT1(a1),d2   | ...
     636                add.b   d4,d2           | add jump point
     637                move.b  d2,FH_CPT(a1)   | make it the current point
     638                lsl.w   #2,d2           | develop new point index in d2
     639                move.w  d2,d0           | ... (fast multiply by PT_LEN = 12
     640                add.w   d2,d2           | ...  via shift and add)
     641                add.w   d0,d2           | ...
     642                bra     outseg          | output the segment
     643
     644                .page
     645
     646| ------------------------------------------------------------------------------
     647| act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times
     648| ----    ----------------------------------------------
     649act4:           tst.b   PT_PAR3(a2,d2.W)        | check counter
     650                bne     act4a                   | jump if it's running
     651
     652                move.b  PT_PAR2(a2,d2.W),d0     | get parameter
     653                subi.w  #90,d0                  | put parameter in random range
     654                bmi     act4b                   | treat as normal if < 90
     655
     656                movem.l d1-d2/a0-a2,-(a7)       | get ranged random number
     657                move.w  d0,-(a7)                | ...
     658                jsr     _irand                  | ...
     659                tst.w   (a7)+                   | ...
     660                movem.l (a7)+,d1-d2/a0-a2       | ...
     661                move.b  d0,PT_PAR3(a2,d2.w)     | set counter
     662                beq     act0                    | next segment if cntr set to 0
     663
     664                bra     act3                    | else jump to the point
     665
     666act4b:          move.b  PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W)       | set counter
     667                beq     act0                    | next segment if cntr set to 0
     668
     669                bra     act3                    | else jump to the point
     670
     671act4a:          subq.b  #1,PT_PAR3(a2,d2.W)     | decrement counter
     672                beq     act0                    | next segment if cntr ran out
     673
     674                bra     act3                    | jump if it's still non-zero
     675
     676| ------------------------------------------------------------------------------
     677| act5 -- AC_KYUP -- jump if key is up
     678| ----    ----------------------------
     679act5:           move.w  _fpuifnc,d0     | get voice as a word index
     680                lsr.w   #3,d0           | ...
     681                andi.w  #0x001E,d0      | ...
     682                lea     _vce2trg,a0     | check to see if voice is free
     683                move.w  0(a0,d0.W),d0   | ...
     684                cmpi.w  #-1,d0          | ...
     685                beq     act3            | if so (inactive), do the jump
     686
     687                btst    #15,d0          | see if voice is held
     688                bne     act0            | continue if so
     689
     690                btst    #14,d0          | ...
     691                bne     act0            | ...
     692
     693                lea     _trgtab,a0      | check trigger table entry
     694                tst.b   0(a0,d0.W)      | see if the trigger is active
     695                beq     act3            | if not, do the jump
     696
     697                bra     act0            | if so, do next segment
     698
     699                .page
     700
     701| ------------------------------------------------------------------------------
     702| act6 -- AC_KYDN -- jump if key is down
     703| ----    ------------------------------
     704act6:           move.w  _fpuifnc,d0     | get voice as a word index
     705                lsr.w   #3,d0           | ...
     706                andi.w  #0x001E,d0      | ...
     707                lea     _vce2trg,a0     | check to see if voice is free
     708                move.w  0(a0,d0.W),d0   | ...
     709                cmpi.w  #-1,d0          | ...
     710                beq     act0            | if so (inactive), continue
     711
     712                btst    #15,d0          | see if voice is held
     713                bne     act3            | do jump if so
     714
     715                btst    #14,d0          | ...
     716                bne     act3            | ...
     717
     718                lea     _trgtab,a0      | check trigger table entry
     719                tst.b   0(a0,d0.W)      | see if the trigger is active
     720                bne     act3            | if so, do the jump
     721
     722                bra     act0            | if not, do next segment
     723
     724| ------------------------------------------------------------------------------
     725| Test stub
     726| ---------
     727act7:           bra     act0            | AC_HERE: treat act7 as AC_NULL
     728
     729                .page
     730| ------------------------------------------------------------------------------
     731
     732| _fpuclr -- clear the FPU
     733| -------    -------------
     734
     735|       void
     736|       fpuclr()
     737
     738|               Resets the FPU functions to their nominal values.
     739
     740| ------------------------------------------------------------------------------
     741
     742_fpuclr:        link    a6,#0                   | link stack frames
     743                move.w  sr,-(a7)                | save the interrupt level
     744                ori.w   #0x0700,sr              | turn off interrupts
     745
     746                lea     FPUFUNC,a0              | point at the first function
     747                lea     _fp_resv,a2             | point at reset value table
     748                move.w  #11,d1                  | set the outer loop count
     749
     750                .page
     751| ------------------------------------------------------------------------------
     752| reset the 'spare' function for the voice
     753| ------------------------------------------------------------------------------
     754clr0:           move.w  #CLREXP,F_EXP(a0)       | set time exponent
     755                tst.l   actab                   | delay
     756                tst.l   actab                   | ...
     757                move.w  #CLRMNT,F_MNT(a0)       | set time mantissa
     758                tst.l   actab                   | delay
     759                tst.l   actab                   | ...
     760
     761                move.w  #0,F_SF3(a0)            | set scale factor 3
     762                tst.l   actab                   | delay
     763                tst.l   actab                   | ...
     764                move.w  #0,F_CV3(a0)            | set voltage 3
     765                tst.l   actab                   | delay
     766                tst.l   actab                   | ...
     767
     768                move.w  #0,F_SF2(a0)            | set scale factor 2
     769                tst.l   actab                   | delay
     770                tst.l   actab                   | ...
     771                move.w  #0,F_CV2(a0)            | set voltage 2
     772                tst.l   actab                   | delay
     773                tst.l   actab                   | ...
     774
     775                move.w  #0,F_SF1(a0)            | set scale factor 1
     776                tst.l   actab                   | delay
     777                tst.l   actab                   | ...
     778                move.w  #0,F_CV1(a0)            | set voltage 1
     779                tst.l   actab                   | delay
     780                tst.l   actab                   | ...
     781
     782                move.w  (a2),F_VAL10(a0)        | set value from variable table
     783                tst.l   actab                   | delay
     784                tst.l   actab                   | ...
     785                move.w  (a2)+,F_VAL01(a0)       | ...
     786                tst.l   actab                   | delay
     787                tst.l   actab                   | ...
     788                move.w  #FSEND,F_CTL(a0)        | set control word
     789                tst.l   actab                   | delay
     790                tst.l   actab                   | ...
     791
     792                .page
     793                adda.w  #0x0020,a0              | point at 2nd function
     794                lea     fprescon,a1             | set reset constant pointer
     795                move.w  #14,d0                  | set inner loop count
     796
     797| ------------------------------------------------------------------------------
     798| reset the other functions for the voice
     799| ------------------------------------------------------------------------------
     800clr1:           move.w  #CLREXP,F_EXP(a0)       | set time exponent
     801                tst.l   actab                   | delay
     802                tst.l   actab                   | ...
     803                move.w  #CLRMNT,F_MNT(a0)       | set time mantissa
     804                tst.l   actab                   | delay
     805                tst.l   actab                   | ...
     806
     807                move.w  #0,F_SF3(a0)            | set scale factor 3
     808                tst.l   actab                   | delay
     809                tst.l   actab                   | ...
     810                move.w  #0,F_CV3(a0)            | set voltage 3
     811                tst.l   actab                   | delay
     812                tst.l   actab                   | ...
     813
     814                move.w  #0,F_SF2(a0)            | set scale factor 2
     815                tst.l   actab                   | delay
     816                tst.l   actab                   | ...
     817                move.w  #0,F_CV2(a0)            | set voltage 2
     818                tst.l   actab                   | delay
     819                tst.l   actab                   | ...
     820
     821                move.w  #0,F_SF1(a0)            | set scale factor 1
     822                tst.l   actab                   | delay
     823                tst.l   actab                   | ...
     824                move.w  #0,F_CV1(a0)            | set voltage 1
     825                tst.l   actab                   | delay
     826                tst.l   actab                   | ...
     827
     828                move.w  (a1),F_VAL10(a0)        | set value from constant table
     829                tst.l   actab                   | delay
     830                tst.l   actab                   | ...
     831                move.w  (a1)+,F_VAL01(a0)       | ...
     832                tst.l   actab                   | delay
     833                tst.l   actab                   | ...
     834                move.w  #FSEND,F_CTL(a0)        | set control word
     835                tst.l   actab                   | delay
     836                tst.l   actab                   | ...
     837
     838                .page
     839| ------------------------------------------------------------------------------
     840| loop through reset for all of the voices and functions
     841| ------------------------------------------------------------------------------
     842                adda.w  #0x0020,a0              | point at next function
     843                dbra    d0,clr1                 | loop until all funcs. cleared
     844
     845                dbra    d1,clr0                 | loop until all voices cleared
     846| ------------------------------------------------------------------------------
     847| clear the FPU interrupt, and return
     848| ------------------------------------------------------------------------------
     849                move.w  #0,FPUINT2              | clear FPU interrupt
     850                move.w  (a7)+,sr                | restore interrupts
     851                unlk    a6                      | unlink stack frames
     852                rts                             | return to caller
     853
     854                .page
     855
     856| _clrvce -- quiet a voice
     857| -------    -------------
     858
     859|       void
     860|       clrvce(vce)
     861|       short vce;
     862
     863|               Quiet the voice by resetting the FPU functions it uses.
     864
     865_clrvce:        link    a6,#0                   | link stack frames
     866                move.w  sr,-(a7)                | save the interrupt level
     867                ori.w   #0x0700,sr              | turn off interrupts
     868
     869                lea     FPUFUNC+0x20,a0         | point at the 2nd function
     870                move.w  8(a6),d0                | get voice number
     871                ext.l   d0                      | ...
     872                lsl.l   #8,d0                   | shift into position
     873                add.l   d0,d0                   | ...
     874                adda.l  d0,a0                   | add to function base
     875                lea     fprescon,a1             | set reset constant pointer
     876                move.w  #14,d0                  | set inner loop count
     877
     878vclr1:          move.l  a0,d1                   | see if we reset this function
     879                and.w   #0x01F0,d1              | ...
     880
     881                cmpi.w  #0x0100,d1              | dynamics ?
     882                beq     vclr2                   | skip it if so
     883
     884                move.w  #CLREXP,F_EXP(a0)       | set time exponent
     885                tst.l   actab                   | delay
     886                tst.l   actab                   | ...
     887                move.w  #CLRMNT,F_MNT(a0)       | set time mantissa
     888                tst.l   actab                   | delay
     889                tst.l   actab                   | ...
     890
     891                cmpi.w  #0x0020,d1              | freq 1 ?
     892                beq     vclr3                   | don't reset CV3 (fine tune)
     893
     894                move.w  #0,F_SF3(a0)            | set scale factor 3
     895                tst.l   actab                   | delay
     896                tst.l   actab                   | ...
     897                move.w  #0,F_CV3(a0)            | set voltage 3
     898                tst.l   actab                   | delay
     899                tst.l   actab                   | ...
     900
     901vclr3:          move.w  #0,F_SF1(a0)            | set scale factor 1
     902                tst.l   actab                   | delay
     903                tst.l   actab                   | ...
     904                move.w  #0,F_CV1(a0)            | set voltage 1
     905                tst.l   actab                   | delay
     906                tst.l   actab                   | ...
     907
     908                .page
     909
     910                move.w  (a1),F_VAL10(a0)        | set value from constant table
     911                tst.l   actab                   | delay
     912                tst.l   actab                   | ...
     913                move.w  (a1),F_VAL01(a0)        | ...
     914                tst.l   actab                   | delay
     915                tst.l   actab                   | ...
     916                move.w  #FSEND,F_CTL(a0)        | set control word
     917                tst.l   actab                   | delay
     918                tst.l   actab                   | ...
     919
     920vclr2:          adda.w  #2,a1                   | point at next function
     921                adda.w  #0x0020,a0              |
     922                dbra    d0,vclr1                | loop until all funcs. cleared
     923
     924                move.w  (a7)+,sr                | restore interrupts
     925                unlk    a6                      | unlink stack frames
     926                rts                             | return to caller
     927
     928                .page
     929| ------------------------------------------------------------------------------
    930930                .data
    931 * ------------------------------------------------------------------------------
    932 *
    933 * actab -- action code dispatch table
    934 * -----    --------------------------
    935 actab:          dc.l    act0    * 0 - AC_NULL:  no action
    936                 dc.l    act1    * 1 - AC_SUST:  sustain
    937                 dc.l    act2    * 2 - AC_ENBL:  enable
    938                 dc.l    act3    * 3 - AC_JUMP:  unconditional jump
    939                 dc.l    act4    * 4 - AC_LOOP:  jump n times      (loop)
    940                 dc.l    act5    * 5 - AC_KYUP:  jump if key up    (enable jump)
    941                 dc.l    act6    * 6 - AC_KYDN:  jump if key down  (sustain jump)
    942                 dc.l    act7    * 7 - AC_HERE:  here on key up
    943 *
    944 * fprescon -- FPU reset constant table
    945 * --------    ------------------------
    946 fprescon:       dc.w    $0000   * frq 1           0.00
    947                 dc.w    $8300   * level         -10.00
    948                 dc.w    $0000   * frq 2           0.00
    949                 dc.w    $0000   * locn            0.00
    950                 dc.w    $0000   * frq 3           0.00
    951                 dc.w    $0000   * reson           0.00
    952                 dc.w    $0000   * frq 4           0.00
    953                 dc.w    $7D00   * dyn           +10.00
    954                 dc.w    $0000   * ind 1           0.00
    955                 dc.w    $3E80   * filt           +5.00
    956                 dc.w    $0000   * ind 2           0.00
    957                 dc.w    $0000   * ind 3           0.00
    958                 dc.w    $0000   * ind 4           0.00
    959                 dc.w    $0000   * ind 5           0.00
    960                 dc.w    $0000   * ind 6           0.00
    961 *
    962 * ------------------------------------------------------------------------------
     931| ------------------------------------------------------------------------------
     932
     933| actab -- action code dispatch table
     934| -----    --------------------------
     935actab:          dc.l    act0    | 0 - AC_NULL:  no action
     936                dc.l    act1    | 1 - AC_SUST:  sustain
     937                dc.l    act2    | 2 - AC_ENBL:  enable
     938                dc.l    act3    | 3 - AC_JUMP:  unconditional jump
     939                dc.l    act4    | 4 - AC_LOOP:  jump n times      (loop)
     940                dc.l    act5    | 5 - AC_KYUP:  jump if key up    (enable jump)
     941                dc.l    act6    | 6 - AC_KYDN:  jump if key down  (sustain jump)
     942                dc.l    act7    | 7 - AC_HERE:  here on key up
     943
     944| fprescon -- FPU reset constant table
     945| --------    ------------------------
     946fprescon:       dc.w    0x0000  | frq 1           0.00
     947                dc.w    0x8300  | level         -10.00
     948                dc.w    0x0000  | frq 2           0.00
     949                dc.w    0x0000  | locn            0.00
     950                dc.w    0x0000  | frq 3           0.00
     951                dc.w    0x0000  | reson           0.00
     952                dc.w    0x0000  | frq 4           0.00
     953                dc.w    0x7D00  | dyn           +10.00
     954                dc.w    0x0000  | ind 1           0.00
     955                dc.w    0x3E80  | filt           +5.00
     956                dc.w    0x0000  | ind 2           0.00
     957                dc.w    0x0000  | ind 3           0.00
     958                dc.w    0x0000  | ind 4           0.00
     959                dc.w    0x0000  | ind 5           0.00
     960                dc.w    0x0000  | ind 6           0.00
     961
     962| ------------------------------------------------------------------------------
    963963                .bss
    964 * ------------------------------------------------------------------------------
    965 *
    966 _fp_resv:       ds.w    12              * fpu spare function reset values
    967 _fpuifnc:       ds.w    1               * interrupting function number from FPU
    968 *
     964| ------------------------------------------------------------------------------
     965
     966_fp_resv:       ds.w    12              | fpu spare function reset values
     967_fpuifnc:       ds.w    1               | interrupting function number from FPU
     968
    969969                .end
  • ram/procpfl.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * procpfl.s -- process pendant functions  (sustain release processing)
    3 * Version 8 -- 1988-08-31 -- D.N. Lynx Crowe
    4 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| procpfl.s -- process pendant functions  (sustain release processing)
     3| Version 8 -- 1988-08-31 -- D.N. Lynx Crowe
     4| ------------------------------------------------------------------------------
    55                .text
    6 *
     6
    77                .xdef   _procpfl
    8 *
    9                 .xdef   _curpf_f        * current function (v/p)
    10                 .xdef   _curpf_l        * current pflist entry
    11                 .xdef   _curpf_t        * current trigger
    12 *
     8
     9                .xdef   _curpf_f        | current function (v/p)
     10                .xdef   _curpf_l        | current pflist entry
     11                .xdef   _curpf_t        | current trigger
     12
    1313                .xref   _irand
    1414                .xref   _xgetran
    15 *
     15
    1616                .xref   _expbit
    1717                .xref   _funcndx
     
    2626                .xref   _vce2trg
    2727                .xref   _veltab
    28 *
    29                 .page
    30 * ------------------------------------------------------------------------------
    31 * Register usage
    32 * --------------
    33 *       d0      scratch
    34 *       d1      FPU function index
    35 *       d2      point index from FH_CPT  (idfcpt)
    36 *       d3      scratch
    37 *       d4      jump point number from PT_PAR1  (ippar1)
    38 *       d5      scratch
    39 *
    40 *       a0      scratch
    41 *       a1      function header base
    42 *       a2      point table base
    43 *       a3      FPU base
    44 *
    45 * ------------------------------------------------------------------------------
    46 * FPU definitions
    47 * ---------------
    48 *
    49 UPD_BIT         .equ    $0001                   * update bit  (1 = update)
    50 INT_BIT         .equ    $0002                   * int. bit    (0 = disable)
    51 RAT_BIT         .equ    $0004                   * ratio bit   (0 = ratio)
    52 *
    53 VSUBNBIT        .equ    3                       * new value select bit number
    54 VAL_BITS        .equ    $0018                   * new value select bit mask
    55 *
    56 MSK_RNVB        .equ    $000C                   * new value / ratio bits
    57 MSK_ONVB        .equ    $0010                   * old new value bit
    58 *
    59 FKILL           .equ    $0014                   * kill value for function
    60 FSEND           .equ    $0015                   * send new value to function
    61 *
    62 CLREXP          .equ    $8000                   * clear value for time exponent
    63 CLRMNT          .equ    $8000                   * clear value for time mantissa
    64 *
    65 * ------------------------------------------------------------------------------
    66 * Miscellaneous definitions
    67 * -------------------------
    68 *
    69 PCHMAX          .equ    21920                   * maximum pitch value
    70 VALMAX          .equ    32000                   * maximum value to send to FPU
    71 VALMIN          .equ    -32000                  * minimum value to send to FPU
    72 *
    73 LSPCH           .equ    2                       * left shift for sources to freq
    74 *
    75 VALLEN          .equ    10                      * length of the 'valent' struct
    76 VT_VAL          .equ    8                       * value offset in 'valent'
    77 *
    78                 .page
    79 * ------------------------------------------------------------------------------
    80 * FPU addresses
    81 * -------------
    82 *
    83 FPUBASE         .equ    $180000                 * FPU base address
    84 *
    85 FPUWST          .equ    FPUBASE                 * FPU waveshape base
    86 FPUFUNC         .equ    FPUBASE+$4000           * FPU function base
    87 FPUINT1         .equ    FPUBASE+$4000           * FPU int. input address (R/O)
    88 FPUINT2         .equ    FPUBASE+$6000           * FPU int. reset address (W/O)
    89 FPUCFG          .equ    FPUBASE+$5FE0           * FPU config. data address (W/O)
    90 *
    91 F_CTL           .equ    $00                     * control word
    92 F_VAL10         .equ    $02                     * new value "10"
    93 F_CV1           .equ    $08                     * control voltage 1
    94 F_SF1           .equ    $0A                     * scale factor 1
    95 F_CV2           .equ    $0C                     * control voltage 2
    96 F_SF2           .equ    $0E                     * scale factor 2
    97 F_CV3           .equ    $10                     * control voltage 3
    98 F_SF3           .equ    $12                     * scale factor 3
    99 F_MNT           .equ    $14                     * time mantissa
    100 F_EXP           .equ    $16                     * time exponent
    101 F_VAL01         .equ    $1C                     * new value "01"
    102 *
    103 P_FREQ1         .equ    $0020                   * frequency 1
    104 P_FREQ2         .equ    $0060                   * frequency 2
    105 P_FREQ3         .equ    $00A0                   * frequency 3
    106 P_FREQ4         .equ    $00E0                   * frequency 4
    107 P_FILTER        .equ    $0140                   * filter
    108 P_FILTRQ        .equ    $00C0                   * filter q
    109 *
    110 P_INDEX1        .equ    $0120                   * index 1
    111 P_INDEX2        .equ    $0160                   * index 2
    112 P_INDEX3        .equ    $0180                   * index 3
    113 P_INDEX4        .equ    $01A0                   * index 4
    114 P_INDEX5        .equ    $01C0                   * index 5
    115 P_INDEX6        .equ    $01E0                   * index 6
    116 *
    117 P_LEVEL         .equ    $0040                   * level
    118 *
    119 P_LOCN          .equ    $0080                   * location
    120 P_DYNAM         .equ    $0100                   * dynamics
    121 *
    122                 .page
    123 * ------------------------------------------------------------------------------
    124 * Structure definitions
    125 * ------------------------------------------------------------------------------
    126 * The following MUST match the idfnhdr structure definition in instdsp.h:
    127 *
    128 FH_LEN          .equ    12              * length of the idfnhdr structure
    129 *
    130 FH_PCH          .equ    0               * WORD - pitch offset
    131 FH_MLT          .equ    2               * WORD - overall value multiplier
    132 FH_SRC          .equ    4               * BYTE - overall value source
    133 FH_PIF          .equ    5               * BYTE - # of points in the function
    134 FH_PT1          .equ    6               * BYTE - index of first point
    135 FH_TMD          .equ    7               * BYTE - trigger mode / control bits
    136 FH_CPT          .equ    8               * BYTE - current point
    137 FH_PRM          .equ    9               * BYTE - misc. function parameter
    138 FH_TRG          .equ    10              * WORD - trigger
    139 *
    140 I_ACTIVE        .equ    1               * 'Active' bit number        (in FH_TMD)
    141 *
    142 MSK_CTL         .equ    $001C           * mask for FPU hardware bits (in FH_TMD)
    143 *
    144 * ------------------------------------------------------------------------------
    145 * The following MUST match the instpnt structure definition in instdsp.h:
    146 *
    147 PT_LEN          .equ    12              * length of the instpnt structure
    148 *
    149 PT_TIM          .equ    0               * WORD - time (packed)
    150 PT_VAL          .equ    2               * WORD - value
    151 PT_VMLT         .equ    4               * WORD - value multiplier
    152 PT_VSRC         .equ    6               * BYTE - value source
    153 PT_ACT          .equ    7               * BYTE - action
    154 PT_PAR1         .equ    8               * BYTE - parameter 1
    155 PT_PAR2         .equ    9               * BYTE - parameter 2
    156 PT_PAR3         .equ    10              * BYTE - parameter 3
    157 PT_PAD          .equ    11              * BYTE - padding for even boundary
    158 *
    159 MSK_MNT         .equ    $FFF0           * mask for mantissa  (in PT_TIM)
    160 MSK_EXP         .equ    $000F           * mask for exponent  (in PT_TIM)
    161 *
    162 MAX_ACT         .equ    7               * maximum action code value
    163 *
    164 * ------------------------------------------------------------------------------
    165 * Source definitions -- must match those in 'smdefs.h'
    166 *
    167 SM_RAND         .equ    1               * random
    168 SM_PTCH         .equ    5               * pitch
    169 SM_KPRS         .equ    6               * key pressure
    170 SM_KVEL         .equ    7               * key velocity
    171 SM_FREQ         .equ    10              * frequency
    172 *
    173                 .page
    174 *
    175 * Layout of pflist entries      32 bytes each
    176 * ------------------------
    177 PF_NEXT         .equ    0               * LONG - next entry pointer
    178 PF_TRIG         .equ    4               * WORD - trigger number
    179 PF_FUNC         .equ    6               * WORD - fpuifnc value
    180 PF_D1           .equ    8               * LONG - d1
    181 PF_D2           .equ    12              * LONG - d2
    182 PF_D4           .equ    16              * LONG - d4
    183 PF_A1           .equ    20              * LONG - a1
    184 PF_A2           .equ    24              * LONG - a2
    185 PF_A3           .equ    28              * LONG - a3
    186 *
    187 * Parameter offset
    188 * ----------------
    189 TRIG            .equ    8               * WORD - trigger number
    190 *
    191 * Register equates
    192 * ----------------
    193 RCUR            .equ    a4              * current pflist entry pointer
    194 RPRV            .equ    a5              * previous pflist entry pointer
    195 *
    196                 .page
    197 * ------------------------------------------------------------------------------
    198 * _procpfl() -- process pendant functions
    199 *
    200 *       void
    201 *       procpfl(trig);
    202 *       unsigned trig;
    203 *
    204 *               Processes pendant (sustained) functions by restarting them
    205 *       when the trigger (trig) that's sustaining them is released.
    206 *       Invoked by key release processing in msm() and localkb().
    207 *
    208 * ------------------------------------------------------------------------------
    209 *
    210 _procpfl:       nop                             * FOR DEBUGGING PATCH
    211 *
    212                 link    a6,#0                   * allocate stack frame
    213                 movem.l d3-d7/a3-a5,-(a7)       * preserve registers we use
    214 *
    215                 move.w  sr,d7                   * save interrupt state
    216                 move.w  #$2200,sr               * turn off FPU interrupts
    217 *
    218                 move.w  TRIG(a6),d6             * get trigger we're processing
    219                 move.w  d6,_curpf_t             * ...
    220                 movea.l #_pflist,RPRV           * point at 'previous' pflist entry
    221                 bra     pfscan                  * go scan the chain
    222 *
    223 pfpass:         movea.l RCUR,RPRV               * point at previous entry
    224 *
    225 pfscan:         move.l  (RPRV),d5               * get next pflist entry pointer
    226                 beq     pfexit                  * done if no more
    227 *
    228                 movea.l d5,RCUR                 * point at  current entry
    229                 move.l  d5,_curpf_l             * ...
    230 *
    231                 cmp.w   PF_TRIG(RCUR),d6        * see if this entry is wanted
    232                 bne     pfpass                  * jump if not
    233 *
    234                 movem.l PF_D1(RCUR),d1-d2/d4/a1-a3      * restore processing state
    235                 move.w  PF_FUNC(RCUR),_curpf_f          * ...
    236 *
    237                 btst    #I_ACTIVE,FH_TMD(a1)    * see if function is active
    238                 bne     doact                   * continue function if so
    239 *
    240                 bra     stopfn                  * stop function if not
    241 *
    242 pfnext:         move.l  (RCUR),(RPRV)           * remove entry from pflist
    243                 move.l  _pfqhdr,(RCUR)          * chain entry to free list
    244                 move.l  RCUR,_pfqhdr            * ...
    245                 bra     pfscan                  * go look at next entry
    246 *
    247 pfexit:         move.w  d7,sr                   * restore interrupt level
    248                 movem.l (a7)+,d3-d7/a3-a5       * restore the registers we used
    249                 unlk    a6                      * deallocate stack frame
    250                 rts                             * return to caller
    251 *
    252                 .page
    253 *
    254 * ------------------------------------------------------------------------------
    255 * stop a function
    256 * ------------------------------------------------------------------------------
    257 stopfn:         move.b  FH_TMD(a1),d0   * get function control bits
    258                 andi.w  #MSK_RNVB,d0    * mask for ratio / new new-value bit
    259                 move.w  d0,d3           * isolate new new-value bit
    260                 add.w   d3,d3           * ... from function header
    261                 andi.w  #MSK_ONVB,d3    * ... shift to old new-value bit
    262                 or.w    d3,d0           * ... and put new bit in old bit       
    263                 move.w  d0,F_CTL(a3,d1.W)       * stop the function
    264                 bclr    #I_ACTIVE,FH_TMD(a1)    * reset the active bit
    265                 bra     pfnext          * go restore registers and exit
    266 *
    267 * ------------------------------------------------------------------------------
    268 * setup for and dispatch to the proper action handler
    269 * ------------------------------------------------------------------------------
    270 doact:          clr.w   d2              * get current point index in d2
    271                 move.b  FH_CPT(a1),d2   * ...
    272                 lsl.w   #2,d2           * multiply it by the length of a point
    273                 move.w  d2,d0           * ...  (fast multiply by PT_LEN = 12
    274                 add.w   d2,d2           * ...   via shift and add)
    275                 add.w   d0,d2           * ...
    276                 clr.w   d4              * get jump point # into d4
    277                 move.b  PT_PAR1(a2,d2.W),d4     * ...
    278                 clr.w   d3              * get action code in d3
    279                 move.b  PT_ACT(a2,d2.W),d3      * ...
    280                 cmpi.b  #MAX_ACT,d3     * check against the limit
    281                 bgt     stopfn          * stop things if it's a bad action code
    282 *
    283                 lsl.w   #2,d3           * develop index to action dispatch table
    284                 lea     actab,a0        * get the address of the action handler
    285                 movea.l 0(a0,d3.W),a0   * ...
    286 *
    287 * ------------------------------------------------------------------------------
    288 * At this point we're ready to do the action associated with the point,
    289 * and the registers are set up,  and will remain,  as follows:
    290 *
    291 *       d1      FPU function index      a1      function header base
    292 *       d2      point table index       a2      point table base
    293 *                                       a3      FPU function base
    294 *       d4      jump point number
    295 *
    296 *       d0, d3, d5, and a0 are used as scratch throughout the code.
    297 *
    298 * ------------------------------------------------------------------------------
    299 *
    300                 jmp     (a0)            * dispatch to action handler
    301 *
    302                 .page
    303 * ------------------------------------------------------------------------------
    304 * act0 -- AC_NULL -- no action
    305 * ----    --------------------
    306 act0:           move.b  FH_PT1(a1),d0   * get first point number
    307                 add.b   FH_PIF(a1),d0   * add number of points in function
    308                 subq.b  #1,d0           * make it last point number
    309                 cmp.b   FH_CPT(a1),d0   * see if we're at the last point
    310                 beq     stopfn          * stop function if so
    311 *
    312                 addq.b  #1,FH_CPT(a1)   * update function header for next point
    313                 addi.w  #PT_LEN,d2      * advance the point index
    314 *
    315 * ------------------------------------------------------------------------------
    316 * outseg -- output a segment
    317 * ------    ----------------
    318 outseg:         move.w  PT_TIM(a2,d2.w),d3      * get packed time
    319                 move.w  d3,d0                   * extract mantissa
    320                 andi.w  #MSK_MNT,d0             * ...
    321                 mulu    _timemlt,d0             * multiply by panel time pot value
    322                 lsr.l   #8,d0                   * ... and scale it
    323                 lsr.l   #7,d0                   * ...
    324                 move.w  d0,F_MNT(a3,d1.W)       * send mantissa to FPU
    325                 andi.w  #MSK_EXP,d3             * extract exponent code
    326                 add.w   d3,d3                   * look up decoded exponent
    327                 lea     _expbit,a0              * ... in expbit
    328                 move.w  0(a0,d3.W),F_EXP(a3,d1.W)       * send exponent to FPU
    329                 move.w  PT_VAL(a2,d2.W),d3      * get the function value
    330 *
    331                 .page
    332 * ------------------------------------------------------------------------------
    333 * get the point source, if any
    334 * ------------------------------------------------------------------------------
    335                 tst.w   PT_VMLT(a2,d2.W)        * see if we have a point mlt.
    336                 beq     nosrc                   * don't do anything for zero
    337 *
    338                 clr.w   d0                      * get the source number
    339                 move.b  PT_VSRC(a2,d2.W),d0     * ...
    340                 beq     nosrc                   * don't do anything for zero
    341 *
    342 * ------------------------------------------------------------------------------
    343 * SM_RAND -- random
    344 * ------------------------------------------------------------------------------
    345                 cmpi.w  #SM_RAND,d0             * is this the random source ?
    346                 bne     srctyp0                 * jump if not
    347 *
    348                 movem.l d1-d2/a0-a2,-(a7)       * preserve registers around call
    349                 move.w  PT_VMLT(a2,d2.W),-(a7)  * pass multiplier to xgetran()
    350                 jsr     _xgetran                * call for a random number
    351                 tst.w   (a7)+                   * clean up stack
    352                 movem.l (a7)+,d1-d2/a0-a2       * restore registers
    353                 move.w  d0,d5                   * put random value in the value register
    354                 bra     applym                  * go apply the multiplier
    355 *
    356                 .page
    357 * ------------------------------------------------------------------------------
    358 * SM_FREQ -- frequency
    359 * ------------------------------------------------------------------------------
    360 srctyp0:        cmpi.w  #SM_FREQ,d0     * is this the frequency source ?
    361                 bne     srctyp1         * jump if not
    362 *
    363                 move.w  (a1),d0         * get the pitch
    364                 lsr.w   #6,d0           * shift to a word index
    365                 andi.w  #$01FE,d0       * mask out extraneous bits
    366                 lea     _ptoftab,a0     * get entry from ptoftab[]
    367                 move.w  0(a0,d0.W),d5   * ...
    368                 bra     applym          * go apply the multiplier
    369 *
    370 * ------------------------------------------------------------------------------
    371 * SM_PTCH -- pitch
    372 * ------------------------------------------------------------------------------
    373 srctyp1:        cmpi.w  #SM_PTCH,d0     * is this the pitch source ?
    374                 bne     srctyp2         * jump if not
    375 *
    376                 move.w  (a1),d5         * get the pitch as the value
    377                 bra     applym          * go apply the multiplier
    378 *
    379 * ------------------------------------------------------------------------------
    380 * SM_KVEL -- velocity
    381 * ------------------------------------------------------------------------------
    382 srctyp2:        cmpi.w  #SM_KVEL,d0     * is this the key velocity source ?
    383                 bne     srctyp3         * jump if not
    384 *
    385                 move.w  FH_TRG(a1),d0   * get the trigger number
    386                 add.w   d0,d0           * ... as a word index
    387                 lea     _veltab,a0      * ... into veltab[]
    388                 move.w  0(a0,d0.W),d5   * get the velocity from veltab[trg]
    389                 bra     applym          * go apply the multiplier
    390 *
    391 * ------------------------------------------------------------------------------
    392 * SM_KPRS -- pressure
    393 * ------------------------------------------------------------------------------
    394 srctyp3:        cmpi.w  #SM_KPRS,d0     * is this the key pressure source ?
    395                 bne     srctyp4         * jump if not  (must be an analog input)
    396 *
    397                 move.w  FH_TRG(a1),d0   * get the trigger number
    398                 add.w   d0,d0           * ... as a word index
    399                 lea     _prstab,a0      * ... into prstab[]
    400                 move.w  0(a0,d0.W),d5   * get the pressure from prstab[trg]
    401                 bra     applym          * go apply the multiplier
    402 *
    403                 .page
    404 * ------------------------------------------------------------------------------
    405 * all other sources come out of the valents[] array
    406 * ------------------------------------------------------------------------------
    407 srctyp4:        lea     _vce2grp,a0     * point at vce2grp[]
    408                 move.w  _curpf_f,d5     * get voice number in d5
    409                 lsr.w   #3,d5           * ...
    410                 andi.w  #$001E,d5       * ... as a word index
    411                 move.w  0(a0,d5.W),d5   * get the group number
    412                 subq.w  #1,d5           * ...
    413                 lsl.w   #4,d5           * shift it left a nybble
    414                 or.w    d5,d0           * OR it into the source number
    415                 add.w   d0,d0           * make source number a valents[] index
    416                 move.w  d0,d5           * ... (fast multiply by VALLEN = 10
    417                 lsl.w   #2,d0           * ...  via shift and add)
    418                 add.w   d5,d0           * ...
    419                 lea     _valents,a0     * get base of valents[]
    420                 move.w  VT_VAL(a0,d0.W),d5      * get value
    421 *
    422 * ------------------------------------------------------------------------------
    423 * apply the multiplier to the source, and add it to the function value
    424 * ------------------------------------------------------------------------------
    425 applym:         muls    PT_VMLT(a2,d2.W),d5     * apply the multiplier
    426                 asr.l   #7,d5           * scale the result
    427                 asr.l   #8,d5           * ...
    428                 ext.l   d3              * add the function value
    429                 add.l   d3,d5           * ...
    430                 cmpi.l  #VALMAX,d5      * check for overflow
    431                 ble     srcmlt1         * jump if no overflow
    432 *
    433                 move.l  #VALMAX,d5      * limit at VALMAX
    434                 bra     srcmlt2         * ...
    435 *
    436 srcmlt1:        cmpi.l  #VALMIN,d5      * check for underflow
    437                 bge     srcmlt2         * jump if no underflow
    438 *
    439                 move.l  #VALMIN,d5      * limit at VALMIN
    440 *
    441 srcmlt2:        move.w  d5,d3           * setup value for output to FPU
    442 *
    443                 .page
    444 * ------------------------------------------------------------------------------
    445 * adjust the value according to the function type
    446 * ------------------------------------------------------------------------------
    447 nosrc:          move.w  d1,d0           * get function type
    448                 andi.w  #$01E0,d0       * ...
    449 *
    450 * ------------------------------------------------------------------------------
    451 * level or location
    452 * ------------------------------------------------------------------------------
    453                 cmpi.w  #P_LEVEL,d0     * see if it's the level
    454                 beq     outsegl         * jump if so
    455 *
    456                 cmpi.w  #P_LOCN,d0      * see if it's the location
    457                 bne     outsegf         * jump if not
    458 *
    459                 tst.w   d3              * check sign of value
    460                 bpl     outsegc         * jump if positive
    461 *
    462                 clr.w   d3              * force negative values to 0
    463 *
    464 outsegc:        asr.w   #5,d3           * shift value to LS bits
    465                 sub.w   #500,d3         * subtract 5.00 from value
    466                 asl.w   #6,d3           * readjust to MS bits
    467                 bra     outseg3         * go output the value
    468 *
    469 outsegl:        tst.w   d3              * check sign of value
    470                 bpl     outsegm         * jump if positive
    471 *
    472                 clr.w   d3              * limit negative values at 0
    473 *
    474 outsegm:        asr.w   #5,d3           * shift value to LS bits
    475                 sub.w   #500,d3         * subtract 5.00 from value
    476                 asl.w   #6,d3           * readjust to MS bits
    477                 bra     outseg3         * go output the value
    478 *
    479                 .page
    480 * ------------------------------------------------------------------------------
    481 * filter
    482 * ------------------------------------------------------------------------------
    483 outsegf:        cmpi.w  #P_FILTER,d0    * see if it's the filter
    484                 bne     outsegp         * jump if not
    485 *
    486                 ext.l   d3              * make function value a long
    487                 asr.l   #1,d3           * multiply function value by .75
    488                 move.l  d3,d0           * ...  (fast multiply by .75
    489                 asr.l   #1,d0           * ...   via shift and add)
    490                 add.l   d0,d3           * ...
    491                 move.w  (a1),d0         * add pitch
    492                 ext.l   d0              * ...
    493                 add.l   d0,d3           * ...
    494                 cmpi.l  #VALMAX,d3      * see if it's within limits
    495                 ble     outsega         * ...
    496 *
    497                 move.w  #VALMAX,d3      * limit at VALMAX
    498                 bra     outseg3         * ...
    499 *
    500 outsega:        cmpi.l  #VALMIN,d3      * ...
    501                 bge     outseg3         * ...
    502 *
    503                 move.w  #VALMIN,d3      * limit at VALMIN
    504                 bra     outseg3         * ...
    505 *
    506                 .page
    507 * ------------------------------------------------------------------------------
    508 * freq 1..4
    509 * ------------------------------------------------------------------------------
    510 outsegp:        cmpi.w  #P_FREQ1,d0     * see if it's freq1
    511                 beq     outseg0         * go process freq1
    512 *
    513 outsegq:        cmpi.w  #P_FREQ2,d0     * see if it's freq2
    514                 beq     outseg0         * process it if so
    515 *
    516                 cmpi.w  #P_FREQ3,d0     * see if it's freq3
    517                 beq     outseg0         * process it if so
    518 *
    519                 cmpi.w  #P_FREQ4,d0     * see if it's freq4
    520                 bne     outseg3         * jump if not
    521 *
    522 outseg0:        ext.l   d3              * scale the point value to cents offset
    523                 asr.l   #5,d3           * ...
    524                 sub.l   #500,d3         * ... value - 500
    525                 asl.l   #LSPCH,d3       * mult. by 2 and scale for 1/2 cent lsb
    526                 move.w  (a1),d0         * add pitch from function header
    527                 ext.l   d0              * ...
    528                 add.l   d0,d3           * ...
    529                 cmp.l   #PCHMAX,d3      * see if result is valid
    530                 ble     outseg3         * jump if within pitch limits
    531 *
    532                 move.l  #PCHMAX,d3      * limit at maximum pitch
    533 *
    534 * ------------------------------------------------------------------------------
    535 * send the value to the FPU
    536 * ------------------------------------------------------------------------------
    537 outseg3:        move.b  FH_TMD(a1),d0   * get hardware bits from function header
    538                 eor.w   #VAL_BITS,d0    * toggle new value select bits
    539                 move.b  d0,FH_TMD(a1)   * store updated word
    540                 btst.l  #VSUBNBIT,d0    * check which value address to use
     28
     29                .page
     30| ------------------------------------------------------------------------------
     31| Register usage
     32| --------------
     33|       d0      scratch
     34|       d1      FPU function index
     35|       d2      point index from FH_CPT  (idfcpt)
     36|       d3      scratch
     37|       d4      jump point number from PT_PAR1  (ippar1)
     38|       d5      scratch
     39
     40|       a0      scratch
     41|       a1      function header base
     42|       a2      point table base
     43|       a3      FPU base
     44
     45| ------------------------------------------------------------------------------
     46| FPU definitions
     47| ---------------
     48
     49UPD_BIT         =       0x0001                  | update bit  (1 = update)
     50INT_BIT         =       0x0002                  | int. bit    (0 = disable)
     51RAT_BIT         =       0x0004                  | ratio bit   (0 = ratio)
     52
     53VSUBNBIT        =       3                       | new value select bit number
     54VAL_BITS        =       0x0018                  | new value select bit mask
     55
     56MSK_RNVB        =       0x000C                  | new value / ratio bits
     57MSK_ONVB        =       0x0010                  | old new value bit
     58
     59FKILL           =       0x0014                  | kill value for function
     60FSEND           =       0x0015                  | send new value to function
     61
     62CLREXP          =       0x8000                  | clear value for time exponent
     63CLRMNT          =       0x8000                  | clear value for time mantissa
     64
     65| ------------------------------------------------------------------------------
     66| Miscellaneous definitions
     67| -------------------------
     68
     69PCHMAX          =       21920                   | maximum pitch value
     70VALMAX          =       32000                   | maximum value to send to FPU
     71VALMIN          =       -32000                  | minimum value to send to FPU
     72
     73LSPCH           =       2                       | left shift for sources to freq
     74
     75VALLEN          =       10                      | length of the 'valent' struct
     76VT_VAL          =       8                       | value offset in 'valent'
     77
     78                .page
     79| ------------------------------------------------------------------------------
     80| FPU addresses
     81| -------------
     82
     83FPUBASE         =       0x180000                | FPU base address
     84
     85FPUWST          =       FPUBASE                 | FPU waveshape base
     86FPUFUNC         =       FPUBASE+0x4000          | FPU function base
     87FPUINT1         =       FPUBASE+0x4000          | FPU int. input address (R/O)
     88FPUINT2         =       FPUBASE+0x6000          | FPU int. reset address (W/O)
     89FPUCFG          =       FPUBASE+0x5FE0          | FPU config. data address (W/O)
     90
     91F_CTL           =       0x00                    | control word
     92F_VAL10         =       0x02                    | new value "10"
     93F_CV1           =       0x08                    | control voltage 1
     94F_SF1           =       0x0A                    | scale factor 1
     95F_CV2           =       0x0C                    | control voltage 2
     96F_SF2           =       0x0E                    | scale factor 2
     97F_CV3           =       0x10                    | control voltage 3
     98F_SF3           =       0x12                    | scale factor 3
     99F_MNT           =       0x14                    | time mantissa
     100F_EXP           =       0x16                    | time exponent
     101F_VAL01         =       0x1C                    | new value "01"
     102
     103P_FREQ1         =       0x0020                  | frequency 1
     104P_FREQ2         =       0x0060                  | frequency 2
     105P_FREQ3         =       0x00A0                  | frequency 3
     106P_FREQ4         =       0x00E0                  | frequency 4
     107P_FILTER        =       0x0140                  | filter
     108P_FILTRQ        =       0x00C0                  | filter q
     109
     110P_INDEX1        =       0x0120                  | index 1
     111P_INDEX2        =       0x0160                  | index 2
     112P_INDEX3        =       0x0180                  | index 3
     113P_INDEX4        =       0x01A0                  | index 4
     114P_INDEX5        =       0x01C0                  | index 5
     115P_INDEX6        =       0x01E0                  | index 6
     116
     117P_LEVEL         =       0x0040                  | level
     118
     119P_LOCN          =       0x0080                  | location
     120P_DYNAM         =       0x0100                  | dynamics
     121
     122                .page
     123| ------------------------------------------------------------------------------
     124| Structure definitions
     125| ------------------------------------------------------------------------------
     126| The following MUST match the idfnhdr structure definition in instdsp.h:
     127
     128FH_LEN          =       12              | length of the idfnhdr structure
     129
     130FH_PCH          =       0               | WORD - pitch offset
     131FH_MLT          =       2               | WORD - overall value multiplier
     132FH_SRC          =       4               | BYTE - overall value source
     133FH_PIF          =       5               | BYTE - # of points in the function
     134FH_PT1          =       6               | BYTE - index of first point
     135FH_TMD          =       7               | BYTE - trigger mode / control bits
     136FH_CPT          =       8               | BYTE - current point
     137FH_PRM          =       9               | BYTE - misc. function parameter
     138FH_TRG          =       10              | WORD - trigger
     139
     140I_ACTIVE        =       1               | 'Active' bit number        (in FH_TMD)
     141
     142MSK_CTL         =       0x001C          | mask for FPU hardware bits (in FH_TMD)
     143
     144| ------------------------------------------------------------------------------
     145| The following MUST match the instpnt structure definition in instdsp.h:
     146
     147PT_LEN          =       12              | length of the instpnt structure
     148
     149PT_TIM          =       0               | WORD - time (packed)
     150PT_VAL          =       2               | WORD - value
     151PT_VMLT         =       4               | WORD - value multiplier
     152PT_VSRC         =       6               | BYTE - value source
     153PT_ACT          =       7               | BYTE - action
     154PT_PAR1         =       8               | BYTE - parameter 1
     155PT_PAR2         =       9               | BYTE - parameter 2
     156PT_PAR3         =       10              | BYTE - parameter 3
     157PT_PAD          =       11              | BYTE - padding for even boundary
     158
     159MSK_MNT         =       0xFFF0          | mask for mantissa  (in PT_TIM)
     160MSK_EXP         =       0x000F          | mask for exponent  (in PT_TIM)
     161
     162MAX_ACT         =       7               | maximum action code value
     163
     164| ------------------------------------------------------------------------------
     165| Source definitions -- must match those in 'smdefs.h'
     166
     167SM_RAND         =       1               | random
     168SM_PTCH         =       5               | pitch
     169SM_KPRS         =       6               | key pressure
     170SM_KVEL         =       7               | key velocity
     171SM_FREQ         =       10              | frequency
     172
     173                .page
     174
     175| Layout of pflist entries      32 bytes each
     176| ------------------------
     177PF_NEXT         =       0               | LONG - next entry pointer
     178PF_TRIG         =       4               | WORD - trigger number
     179PF_FUNC         =       6               | WORD - fpuifnc value
     180PF_D1           =       8               | LONG - d1
     181PF_D2           =       12              | LONG - d2
     182PF_D4           =       16              | LONG - d4
     183PF_A1           =       20              | LONG - a1
     184PF_A2           =       24              | LONG - a2
     185PF_A3           =       28              | LONG - a3
     186
     187| Parameter offset
     188| ----------------
     189TRIG            =       8               | WORD - trigger number
     190
     191| Register equates
     192| ----------------
     193RCUR            =       a4              | current pflist entry pointer
     194RPRV            =       a5              | previous pflist entry pointer
     195
     196                .page
     197| ------------------------------------------------------------------------------
     198| _procpfl() -- process pendant functions
     199
     200|       void
     201|       procpfl(trig);
     202|       unsigned trig;
     203
     204|               Processes pendant (sustained) functions by restarting them
     205|       when the trigger (trig) that's sustaining them is released.
     206|       Invoked by key release processing in msm() and localkb().
     207
     208| ------------------------------------------------------------------------------
     209
     210_procpfl:       nop                             | FOR DEBUGGING PATCH
     211
     212                link    a6,#0                   | allocate stack frame
     213                movem.l d3-d7/a3-a5,-(a7)       | preserve registers we use
     214
     215                move.w  sr,d7                   | save interrupt state
     216                move.w  #0x2200,sr              | turn off FPU interrupts
     217
     218                move.w  TRIG(a6),d6             | get trigger we're processing
     219                move.w  d6,_curpf_t             | ...
     220                movea.l #_pflist,RPRV           | point at 'previous' pflist entry
     221                bra     pfscan                  | go scan the chain
     222
     223pfpass:         movea.l RCUR,RPRV               | point at previous entry
     224
     225pfscan:         move.l  (RPRV),d5               | get next pflist entry pointer
     226                beq     pfexit                  | done if no more
     227
     228                movea.l d5,RCUR                 | point at  current entry
     229                move.l  d5,_curpf_l             | ...
     230
     231                cmp.w   PF_TRIG(RCUR),d6        | see if this entry is wanted
     232                bne     pfpass                  | jump if not
     233
     234                movem.l PF_D1(RCUR),d1-d2/d4/a1-a3      | restore processing state
     235                move.w  PF_FUNC(RCUR),_curpf_f          | ...
     236
     237                btst    #I_ACTIVE,FH_TMD(a1)    | see if function is active
     238                bne     doact                   | continue function if so
     239
     240                bra     stopfn                  | stop function if not
     241
     242pfnext:         move.l  (RCUR),(RPRV)           | remove entry from pflist
     243                move.l  _pfqhdr,(RCUR)          | chain entry to free list
     244                move.l  RCUR,_pfqhdr            | ...
     245                bra     pfscan                  | go look at next entry
     246
     247pfexit:         move.w  d7,sr                   | restore interrupt level
     248                movem.l (a7)+,d3-d7/a3-a5       | restore the registers we used
     249                unlk    a6                      | deallocate stack frame
     250                rts                             | return to caller
     251
     252                .page
     253
     254| ------------------------------------------------------------------------------
     255| stop a function
     256| ------------------------------------------------------------------------------
     257stopfn:         move.b  FH_TMD(a1),d0   | get function control bits
     258                andi.w  #MSK_RNVB,d0    | mask for ratio / new new-value bit
     259                move.w  d0,d3           | isolate new new-value bit
     260                add.w   d3,d3           | ... from function header
     261                andi.w  #MSK_ONVB,d3    | ... shift to old new-value bit
     262                or.w    d3,d0           | ... and put new bit in old bit
     263                move.w  d0,F_CTL(a3,d1.W)       | stop the function
     264                bclr    #I_ACTIVE,FH_TMD(a1)    | reset the active bit
     265                bra     pfnext          | go restore registers and exit
     266
     267| ------------------------------------------------------------------------------
     268| setup for and dispatch to the proper action handler
     269| ------------------------------------------------------------------------------
     270doact:          clr.w   d2              | get current point index in d2
     271                move.b  FH_CPT(a1),d2   | ...
     272                lsl.w   #2,d2           | multiply it by the length of a point
     273                move.w  d2,d0           | ...  (fast multiply by PT_LEN = 12
     274                add.w   d2,d2           | ...   via shift and add)
     275                add.w   d0,d2           | ...
     276                clr.w   d4              | get jump point # into d4
     277                move.b  PT_PAR1(a2,d2.W),d4     | ...
     278                clr.w   d3              | get action code in d3
     279                move.b  PT_ACT(a2,d2.W),d3      | ...
     280                cmpi.b  #MAX_ACT,d3     | check against the limit
     281                bgt     stopfn          | stop things if it's a bad action code
     282
     283                lsl.w   #2,d3           | develop index to action dispatch table
     284                lea     actab,a0        | get the address of the action handler
     285                movea.l 0(a0,d3.W),a0   | ...
     286
     287| ------------------------------------------------------------------------------
     288| At this point we're ready to do the action associated with the point,
     289| and the registers are set up,  and will remain,  as follows:
     290
     291|       d1      FPU function index      a1      function header base
     292|       d2      point table index       a2      point table base
     293|                                       a3      FPU function base
     294|       d4      jump point number
     295
     296|       d0, d3, d5, and a0 are used as scratch throughout the code.
     297
     298| ------------------------------------------------------------------------------
     299
     300                jmp     (a0)            | dispatch to action handler
     301
     302                .page
     303| ------------------------------------------------------------------------------
     304| act0 -- AC_NULL -- no action
     305| ----    --------------------
     306act0:           move.b  FH_PT1(a1),d0   | get first point number
     307                add.b   FH_PIF(a1),d0   | add number of points in function
     308                subq.b  #1,d0           | make it last point number
     309                cmp.b   FH_CPT(a1),d0   | see if we're at the last point
     310                beq     stopfn          | stop function if so
     311
     312                addq.b  #1,FH_CPT(a1)   | update function header for next point
     313                addi.w  #PT_LEN,d2      | advance the point index
     314
     315| ------------------------------------------------------------------------------
     316| outseg -- output a segment
     317| ------    ----------------
     318outseg:         move.w  PT_TIM(a2,d2.w),d3      | get packed time
     319                move.w  d3,d0                   | extract mantissa
     320                andi.w  #MSK_MNT,d0             | ...
     321                mulu    _timemlt,d0             | multiply by panel time pot value
     322                lsr.l   #8,d0                   | ... and scale it
     323                lsr.l   #7,d0                   | ...
     324                move.w  d0,F_MNT(a3,d1.W)       | send mantissa to FPU
     325                andi.w  #MSK_EXP,d3             | extract exponent code
     326                add.w   d3,d3                   | look up decoded exponent
     327                lea     _expbit,a0              | ... in expbit
     328                move.w  0(a0,d3.W),F_EXP(a3,d1.W)       | send exponent to FPU
     329                move.w  PT_VAL(a2,d2.W),d3      | get the function value
     330
     331                .page
     332| ------------------------------------------------------------------------------
     333| get the point source, if any
     334| ------------------------------------------------------------------------------
     335                tst.w   PT_VMLT(a2,d2.W)        | see if we have a point mlt.
     336                beq     nosrc                   | don't do anything for zero
     337
     338                clr.w   d0                      | get the source number
     339                move.b  PT_VSRC(a2,d2.W),d0     | ...
     340                beq     nosrc                   | don't do anything for zero
     341
     342| ------------------------------------------------------------------------------
     343| SM_RAND -- random
     344| ------------------------------------------------------------------------------
     345                cmpi.w  #SM_RAND,d0             | is this the random source ?
     346                bne     srctyp0                 | jump if not
     347
     348                movem.l d1-d2/a0-a2,-(a7)       | preserve registers around call
     349                move.w  PT_VMLT(a2,d2.W),-(a7)  | pass multiplier to xgetran()
     350                jsr     _xgetran                | call for a random number
     351                tst.w   (a7)+                   | clean up stack
     352                movem.l (a7)+,d1-d2/a0-a2       | restore registers
     353                move.w  d0,d5                   | put random value in the value register
     354                bra     applym                  | go apply the multiplier
     355
     356                .page
     357| ------------------------------------------------------------------------------
     358| SM_FREQ -- frequency
     359| ------------------------------------------------------------------------------
     360srctyp0:        cmpi.w  #SM_FREQ,d0     | is this the frequency source ?
     361                bne     srctyp1         | jump if not
     362
     363                move.w  (a1),d0         | get the pitch
     364                lsr.w   #6,d0           | shift to a word index
     365                andi.w  #0x01FE,d0      | mask out extraneous bits
     366                lea     _ptoftab,a0     | get entry from ptoftab[]
     367                move.w  0(a0,d0.W),d5   | ...
     368                bra     applym          | go apply the multiplier
     369
     370| ------------------------------------------------------------------------------
     371| SM_PTCH -- pitch
     372| ------------------------------------------------------------------------------
     373srctyp1:        cmpi.w  #SM_PTCH,d0     | is this the pitch source ?
     374                bne     srctyp2         | jump if not
     375
     376                move.w  (a1),d5         | get the pitch as the value
     377                bra     applym          | go apply the multiplier
     378
     379| ------------------------------------------------------------------------------
     380| SM_KVEL -- velocity
     381| ------------------------------------------------------------------------------
     382srctyp2:        cmpi.w  #SM_KVEL,d0     | is this the key velocity source ?
     383                bne     srctyp3         | jump if not
     384
     385                move.w  FH_TRG(a1),d0   | get the trigger number
     386                add.w   d0,d0           | ... as a word index
     387                lea     _veltab,a0      | ... into veltab[]
     388                move.w  0(a0,d0.W),d5   | get the velocity from veltab[trg]
     389                bra     applym          | go apply the multiplier
     390
     391| ------------------------------------------------------------------------------
     392| SM_KPRS -- pressure
     393| ------------------------------------------------------------------------------
     394srctyp3:        cmpi.w  #SM_KPRS,d0     | is this the key pressure source ?
     395                bne     srctyp4         | jump if not  (must be an analog input)
     396
     397                move.w  FH_TRG(a1),d0   | get the trigger number
     398                add.w   d0,d0           | ... as a word index
     399                lea     _prstab,a0      | ... into prstab[]
     400                move.w  0(a0,d0.W),d5   | get the pressure from prstab[trg]
     401                bra     applym          | go apply the multiplier
     402
     403                .page
     404| ------------------------------------------------------------------------------
     405| all other sources come out of the valents[] array
     406| ------------------------------------------------------------------------------
     407srctyp4:        lea     _vce2grp,a0     | point at vce2grp[]
     408                move.w  _curpf_f,d5     | get voice number in d5
     409                lsr.w   #3,d5           | ...
     410                andi.w  #0x001E,d5      | ... as a word index
     411                move.w  0(a0,d5.W),d5   | get the group number
     412                subq.w  #1,d5           | ...
     413                lsl.w   #4,d5           | shift it left a nybble
     414                or.w    d5,d0           | OR it into the source number
     415                add.w   d0,d0           | make source number a valents[] index
     416                move.w  d0,d5           | ... (fast multiply by VALLEN = 10
     417                lsl.w   #2,d0           | ...  via shift and add)
     418                add.w   d5,d0           | ...
     419                lea     _valents,a0     | get base of valents[]
     420                move.w  VT_VAL(a0,d0.W),d5      | get value
     421
     422| ------------------------------------------------------------------------------
     423| apply the multiplier to the source, and add it to the function value
     424| ------------------------------------------------------------------------------
     425applym:         muls    PT_VMLT(a2,d2.W),d5     | apply the multiplier
     426                asr.l   #7,d5           | scale the result
     427                asr.l   #8,d5           | ...
     428                ext.l   d3              | add the function value
     429                add.l   d3,d5           | ...
     430                cmpi.l  #VALMAX,d5      | check for overflow
     431                ble     srcmlt1         | jump if no overflow
     432
     433                move.l  #VALMAX,d5      | limit at VALMAX
     434                bra     srcmlt2         | ...
     435
     436srcmlt1:        cmpi.l  #VALMIN,d5      | check for underflow
     437                bge     srcmlt2         | jump if no underflow
     438
     439                move.l  #VALMIN,d5      | limit at VALMIN
     440
     441srcmlt2:        move.w  d5,d3           | setup value for output to FPU
     442
     443                .page
     444| ------------------------------------------------------------------------------
     445| adjust the value according to the function type
     446| ------------------------------------------------------------------------------
     447nosrc:          move.w  d1,d0           | get function type
     448                andi.w  #0x01E0,d0      | ...
     449
     450| ------------------------------------------------------------------------------
     451| level or location
     452| ------------------------------------------------------------------------------
     453                cmpi.w  #P_LEVEL,d0     | see if it's the level
     454                beq     outsegl         | jump if so
     455
     456                cmpi.w  #P_LOCN,d0      | see if it's the location
     457                bne     outsegf         | jump if not
     458
     459                tst.w   d3              | check sign of value
     460                bpl     outsegc         | jump if positive
     461
     462                clr.w   d3              | force negative values to 0
     463
     464outsegc:        asr.w   #5,d3           | shift value to LS bits
     465                sub.w   #500,d3         | subtract 5.00 from value
     466                asl.w   #6,d3           | readjust to MS bits
     467                bra     outseg3         | go output the value
     468
     469outsegl:        tst.w   d3              | check sign of value
     470                bpl     outsegm         | jump if positive
     471
     472                clr.w   d3              | limit negative values at 0
     473
     474outsegm:        asr.w   #5,d3           | shift value to LS bits
     475                sub.w   #500,d3         | subtract 5.00 from value
     476                asl.w   #6,d3           | readjust to MS bits
     477                bra     outseg3         | go output the value
     478
     479                .page
     480| ------------------------------------------------------------------------------
     481| filter
     482| ------------------------------------------------------------------------------
     483outsegf:        cmpi.w  #P_FILTER,d0    | see if it's the filter
     484                bne     outsegp         | jump if not
     485
     486                ext.l   d3              | make function value a long
     487                asr.l   #1,d3           | multiply function value by .75
     488                move.l  d3,d0           | ...  (fast multiply by .75
     489                asr.l   #1,d0           | ...   via shift and add)
     490                add.l   d0,d3           | ...
     491                move.w  (a1),d0         | add pitch
     492                ext.l   d0              | ...
     493                add.l   d0,d3           | ...
     494                cmpi.l  #VALMAX,d3      | see if it's within limits
     495                ble     outsega         | ...
     496
     497                move.w  #VALMAX,d3      | limit at VALMAX
     498                bra     outseg3         | ...
     499
     500outsega:        cmpi.l  #VALMIN,d3      | ...
     501                bge     outseg3         | ...
     502
     503                move.w  #VALMIN,d3      | limit at VALMIN
     504                bra     outseg3         | ...
     505
     506                .page
     507| ------------------------------------------------------------------------------
     508| freq 1..4
     509| ------------------------------------------------------------------------------
     510outsegp:        cmpi.w  #P_FREQ1,d0     | see if it's freq1
     511                beq     outseg0         | go process freq1
     512
     513outsegq:        cmpi.w  #P_FREQ2,d0     | see if it's freq2
     514                beq     outseg0         | process it if so
     515
     516                cmpi.w  #P_FREQ3,d0     | see if it's freq3
     517                beq     outseg0         | process it if so
     518
     519                cmpi.w  #P_FREQ4,d0     | see if it's freq4
     520                bne     outseg3         | jump if not
     521
     522outseg0:        ext.l   d3              | scale the point value to cents offset
     523                asr.l   #5,d3           | ...
     524                sub.l   #500,d3         | ... value - 500
     525                asl.l   #LSPCH,d3       | mult. by 2 and scale for 1/2 cent lsb
     526                move.w  (a1),d0         | add pitch from function header
     527                ext.l   d0              | ...
     528                add.l   d0,d3           | ...
     529                cmp.l   #PCHMAX,d3      | see if result is valid
     530                ble     outseg3         | jump if within pitch limits
     531
     532                move.l  #PCHMAX,d3      | limit at maximum pitch
     533
     534| ------------------------------------------------------------------------------
     535| send the value to the FPU
     536| ------------------------------------------------------------------------------
     537outseg3:        move.b  FH_TMD(a1),d0   | get hardware bits from function header
     538                eor.w   #VAL_BITS,d0    | toggle new value select bits
     539                move.b  d0,FH_TMD(a1)   | store updated word
     540                btst.l  #VSUBNBIT,d0    | check which value address to use
    541541                beq     outseg1
    542 *
    543                 move.w  d3,F_VAL01(a3,d1.W)     * send value to FPU
     542
     543                move.w  d3,F_VAL01(a3,d1.W)     | send value to FPU
    544544                bra     outseg2
    545 *
    546 outseg1:        move.w  d3,F_VAL10(a3,d1.W)     * send value to FPU
    547 *
    548 outseg2:        andi.w  #MSK_CTL,d0             * mask off software bits
    549                 ori.w   #UPD_BIT+INT_BIT,d0     * set the update & !lastseg bits
    550                 move.w  d0,F_CTL(a3,d1.W)       * send control word to FPU
    551                 bra     pfnext                  * done -- exit
    552 *
    553                 .page
    554 *
    555 * ------------------------------------------------------------------------------
    556 * act2 -- AC_ENBL -- stop if key is up
    557 * ----    ----------------------------
    558 act2:           move.w  _curpf_f,d0     * get voice as a word index
    559                 lsr.w   #3,d0           * ...
    560                 andi.w  #$001E,d0       * ...
    561                 lea     _vce2trg,a0     * check to see if voice is free
    562                 move.w  0(a0,d0.W),d0   * ...
    563                 cmpi.w  #-1,d0          * ...
    564                 beq     stopfn          * if so, stop the function
    565 *
    566                 btst    #15,d0          * see if voice is held
    567                 bne     act0            * continue if so
    568 *
    569                 btst    #14,d0          * ...
    570                 bne     act0            * ...
    571 *
    572                 lea     _trgtab,a0      * check trigger table entry
    573                 tst.b   0(a0,d0.W)      * ...
    574                 bne     act0            * if trigger is active, continue
    575 *
    576                 bra     stopfn          * if not, stop the function
    577 *
    578 * ------------------------------------------------------------------------------
    579 * act3 -- AC_JUMP -- unconditional jump
    580 * ----    -----------------------------
    581 act3:           cmp.b   FH_PIF(a1),d4   * check jump point against limit
    582                 bcc     stopfn          * stop function if jump point invalid
    583 *
    584                 clr.w   d2              * get index of first point
    585                 move.b  FH_PT1(a1),d2   * ...
    586                 add.b   d4,d2           * add jump point
    587                 move.b  d2,FH_CPT(a1)   * make it the current point
    588                 lsl.w   #2,d2           * develop new point index in d2
    589                 move.w  d2,d0           * ... (fast multiply by PT_LEN = 12
    590                 add.w   d2,d2           * ...  via shift and add)
    591                 add.w   d0,d2           * ...
    592                 bra     outseg          * output the segment
    593 *
    594                 .page
    595 *
    596 * ------------------------------------------------------------------------------
    597 * act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times
    598 * ----    ----------------------------------------------
    599 act4:           tst.b   PT_PAR3(a2,d2.W)        * check counter
    600                 bne     act4a                   * jump if it's running
    601 *
    602                 move.b  PT_PAR2(a2,d2.W),d0     * get parameter
    603                 subi.w  #90,d0                  * put parameter in random range
    604                 bmi     act4b                   * treat as normal if < 90
    605 *
    606                 movem.l d1-d2/a0-a2,-(a7)       * get ranged random number
    607                 move.w  d0,-(a7)                * ...
    608                 jsr     _irand                  * ...
    609                 tst.w   (a7)+                   * ...
    610                 movem.l (a7)+,d1-d2/a0-a2       * ...
    611                 move.b  d0,PT_PAR3(a2,d2.w)     * set counter
    612                 beq     act0                    * next segment if cntr set to 0
    613 *
    614                 bra     act3                    * else jump to the point
    615 *
    616 act4b:          move.b  PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W)       * set counter
    617                 beq     act0                    * next segment if cntr set to 0
    618 *
    619                 bra     act3                    * else jump to the point
    620 *
    621 act4a:          subq.b  #1,PT_PAR3(a2,d2.W)     * decrement counter
    622                 beq     act0                    * next segment if cntr ran out
    623 *
    624                 bra     act3                    * jump if it's still non-zero
    625 *
    626 * ------------------------------------------------------------------------------
    627 * act5 -- AC_KYUP -- jump if key is up
    628 * ----    ----------------------------
    629 act5:           move.w  _curpf_f,d0     * get voice as a word index
    630                 lsr.w   #3,d0           * ...
    631                 andi.w  #$001E,d0       * ...
    632                 lea     _vce2trg,a0     * check to see if voice is free
    633                 move.w  0(a0,d0.W),d0   * ...
    634                 cmpi.w  #-1,d0          * ...
    635                 beq     act3            * if so (inactive), do the jump
    636 *
    637                 btst    #15,d0          * see if voice is held
    638                 bne     act0            * continue if so
    639 *
    640                 btst    #14,d0          * ...
    641                 bne     act0            * ...
    642 *
    643                 lea     _trgtab,a0      * check trigger table entry
    644                 tst.b   0(a0,d0.W)      * see if the trigger is active
    645                 beq     act3            * if not, do the jump
    646 *
    647                 bra     act0            * if so, do next segment
    648 *
    649                 .page
    650 *
    651 * ------------------------------------------------------------------------------
    652 * act6 -- AC_KYDN -- jump if key is down
    653 * ----    ------------------------------
    654 act6:           move.w  _curpf_f,d0     * get voice as a word index
    655                 lsr.w   #3,d0           * ...
    656                 andi.w  #$001E,d0       * ...
    657                 lea     _vce2trg,a0     * check to see if voice is free
    658                 move.w  0(a0,d0.W),d0   * ...
    659                 cmpi.w  #-1,d0          * ...
    660                 beq     act0            * if so (inactive), continue
    661 *
    662                 btst    #15,d0          * see if voice is held
    663                 bne     act3            * do jump if so
    664 *
    665                 btst    #14,d0          * ...
    666                 bne     act3            * ...
    667 *
    668                 lea     _trgtab,a0      * check trigger table entry
    669                 tst.b   0(a0,d0.W)      * see if the trigger is active
    670                 bne     act3            * if so, do the jump
    671 *
    672                 bra     act0            * if not, do next segment
    673 *
    674 * ------------------------------------------------------------------------------
    675 act7:           bra     act0            * AC_HERE: treat act7 as AC_NULL
    676 *
    677                 .page
    678 *
    679 * act1 -- AC_SUST -- pause if key is down (sustain)
    680 * ----    -----------------------------------------
    681 act1:           move.w  _curpf_f,d0     * get voice as a word index
    682                 lsr.w   #3,d0           * ...
    683                 andi.w  #$001E,d0       * ...
    684                 lea     _vce2trg,a0     * point at voice to trigger table
    685                 move.w  0(a0,d0.W),d0   * get trigger table entry
    686                 cmpi.w  #-1,d0          * see if voice is free
    687                 beq     act0            * treat as no-op if so
    688 *
    689                 btst    #15,d0          * see if voice is held by a pedal
    690                 bne     act1a           * sustain if so
    691 *
    692                 btst    #14,d0          * see if voice is sustained by a pedal
    693                 bne     act1a           * sustain if so
    694 *
    695                 lea     _trgtab,a0      * point at trigger table
    696                 tst.b   0(a0,d0.W)      * check trigger status
    697                 beq     act0            * continue if not active
    698 *
    699 act1a:          move.l  _pfqhdr,d3      * see if any pflist entries remain
    700                 beq     act0            * no-op if not  (shouldn't happen ...)
    701 *
    702                 move.b  FH_PT1(a1),d0   * get first point number
    703                 add.b   FH_PIF(a1),d0   * add base to first point
    704                 subq.b  #1,d0           * make d0 last point number
    705                 cmp.b   FH_CPT(a1),d0   * check current point number
    706                 beq     stopfn          * done if this is the last point
    707 *
    708                 addq.b  #1,FH_CPT(a1)           * update current point number
    709                 addi.w  #PT_LEN,d2              * update point index
    710                 movea.l d3,a0                   * acquire a new pflist entry
    711                 move.l  (a0),_pfqhdr            * ...
    712                 move.l  _pflist,(a0)            * ...
    713                 move.l  a0,_pflist              * ...
    714                 move.w  FH_TRG(a1),PF_TRIG(a0)  * set trigger number in entry
    715                 move.w  _curpf_f,PF_FUNC(a0)    * set v/p word in entry
    716                 movem.l d1-d2/d4/a1-a3,PF_D1(a0)        * set registers in entry
    717                 move.b  FH_TMD(a1),d0           * stop the function
    718                 andi.w  #MSK_RNVB,d0            * ...
    719                 move.w  d0,d3                   * ...
    720                 add.w   d3,d3                   * ...
    721                 andi.w  #MSK_ONVB,d3            * ...
    722                 or.w    d3,d0                   * ...
    723                 move.w  d0,F_CTL(a3,d1.W)       * ...
    724                 bra     pfnext                  * go do next list entry
    725 *
    726                 .page
    727 * ------------------------------------------------------------------------------
     545
     546outseg1:        move.w  d3,F_VAL10(a3,d1.W)     | send value to FPU
     547
     548outseg2:        andi.w  #MSK_CTL,d0             | mask off software bits
     549                ori.w   #UPD_BIT+INT_BIT,d0     | set the update & !lastseg bits
     550                move.w  d0,F_CTL(a3,d1.W)       | send control word to FPU
     551                bra     pfnext                  | done -- exit
     552
     553                .page
     554
     555| ------------------------------------------------------------------------------
     556| act2 -- AC_ENBL -- stop if key is up
     557| ----    ----------------------------
     558act2:           move.w  _curpf_f,d0     | get voice as a word index
     559                lsr.w   #3,d0           | ...
     560                andi.w  #0x001E,d0      | ...
     561                lea     _vce2trg,a0     | check to see if voice is free
     562                move.w  0(a0,d0.W),d0   | ...
     563                cmpi.w  #-1,d0          | ...
     564                beq     stopfn          | if so, stop the function
     565
     566                btst    #15,d0          | see if voice is held
     567                bne     act0            | continue if so
     568
     569                btst    #14,d0          | ...
     570                bne     act0            | ...
     571
     572                lea     _trgtab,a0      | check trigger table entry
     573                tst.b   0(a0,d0.W)      | ...
     574                bne     act0            | if trigger is active, continue
     575
     576                bra     stopfn          | if not, stop the function
     577
     578| ------------------------------------------------------------------------------
     579| act3 -- AC_JUMP -- unconditional jump
     580| ----    -----------------------------
     581act3:           cmp.b   FH_PIF(a1),d4   | check jump point against limit
     582                bcc     stopfn          | stop function if jump point invalid
     583
     584                clr.w   d2              | get index of first point
     585                move.b  FH_PT1(a1),d2   | ...
     586                add.b   d4,d2           | add jump point
     587                move.b  d2,FH_CPT(a1)   | make it the current point
     588                lsl.w   #2,d2           | develop new point index in d2
     589                move.w  d2,d0           | ... (fast multiply by PT_LEN = 12
     590                add.w   d2,d2           | ...  via shift and add)
     591                add.w   d0,d2           | ...
     592                bra     outseg          | output the segment
     593
     594                .page
     595
     596| ------------------------------------------------------------------------------
     597| act4 -- AC_LOOP -- jump to point PT_PAR1 PT_PAR2 times
     598| ----    ----------------------------------------------
     599act4:           tst.b   PT_PAR3(a2,d2.W)        | check counter
     600                bne     act4a                   | jump if it's running
     601
     602                move.b  PT_PAR2(a2,d2.W),d0     | get parameter
     603                subi.w  #90,d0                  | put parameter in random range
     604                bmi     act4b                   | treat as normal if < 90
     605
     606                movem.l d1-d2/a0-a2,-(a7)       | get ranged random number
     607                move.w  d0,-(a7)                | ...
     608                jsr     _irand                  | ...
     609                tst.w   (a7)+                   | ...
     610                movem.l (a7)+,d1-d2/a0-a2       | ...
     611                move.b  d0,PT_PAR3(a2,d2.w)     | set counter
     612                beq     act0                    | next segment if cntr set to 0
     613
     614                bra     act3                    | else jump to the point
     615
     616act4b:          move.b  PT_PAR2(a2,d2.W),PT_PAR3(a2,d2.W)       | set counter
     617                beq     act0                    | next segment if cntr set to 0
     618
     619                bra     act3                    | else jump to the point
     620
     621act4a:          subq.b  #1,PT_PAR3(a2,d2.W)     | decrement counter
     622                beq     act0                    | next segment if cntr ran out
     623
     624                bra     act3                    | jump if it's still non-zero
     625
     626| ------------------------------------------------------------------------------
     627| act5 -- AC_KYUP -- jump if key is up
     628| ----    ----------------------------
     629act5:           move.w  _curpf_f,d0     | get voice as a word index
     630                lsr.w   #3,d0           | ...
     631                andi.w  #0x001E,d0      | ...
     632                lea     _vce2trg,a0     | check to see if voice is free
     633                move.w  0(a0,d0.W),d0   | ...
     634                cmpi.w  #-1,d0          | ...
     635                beq     act3            | if so (inactive), do the jump
     636
     637                btst    #15,d0          | see if voice is held
     638                bne     act0            | continue if so
     639
     640                btst    #14,d0          | ...
     641                bne     act0            | ...
     642
     643                lea     _trgtab,a0      | check trigger table entry
     644                tst.b   0(a0,d0.W)      | see if the trigger is active
     645                beq     act3            | if not, do the jump
     646
     647                bra     act0            | if so, do next segment
     648
     649                .page
     650
     651| ------------------------------------------------------------------------------
     652| act6 -- AC_KYDN -- jump if key is down
     653| ----    ------------------------------
     654act6:           move.w  _curpf_f,d0     | get voice as a word index
     655                lsr.w   #3,d0           | ...
     656                andi.w  #0x001E,d0      | ...
     657                lea     _vce2trg,a0     | check to see if voice is free
     658                move.w  0(a0,d0.W),d0   | ...
     659                cmpi.w  #-1,d0          | ...
     660                beq     act0            | if so (inactive), continue
     661
     662                btst    #15,d0          | see if voice is held
     663                bne     act3            | do jump if so
     664
     665                btst    #14,d0          | ...
     666                bne     act3            | ...
     667
     668                lea     _trgtab,a0      | check trigger table entry
     669                tst.b   0(a0,d0.W)      | see if the trigger is active
     670                bne     act3            | if so, do the jump
     671
     672                bra     act0            | if not, do next segment
     673
     674| ------------------------------------------------------------------------------
     675act7:           bra     act0            | AC_HERE: treat act7 as AC_NULL
     676
     677                .page
     678
     679| act1 -- AC_SUST -- pause if key is down (sustain)
     680| ----    -----------------------------------------
     681act1:           move.w  _curpf_f,d0     | get voice as a word index
     682                lsr.w   #3,d0           | ...
     683                andi.w  #0x001E,d0      | ...
     684                lea     _vce2trg,a0     | point at voice to trigger table
     685                move.w  0(a0,d0.W),d0   | get trigger table entry
     686                cmpi.w  #-1,d0          | see if voice is free
     687                beq     act0            | treat as no-op if so
     688
     689                btst    #15,d0          | see if voice is held by a pedal
     690                bne     act1a           | sustain if so
     691
     692                btst    #14,d0          | see if voice is sustained by a pedal
     693                bne     act1a           | sustain if so
     694
     695                lea     _trgtab,a0      | point at trigger table
     696                tst.b   0(a0,d0.W)      | check trigger status
     697                beq     act0            | continue if not active
     698
     699act1a:          move.l  _pfqhdr,d3      | see if any pflist entries remain
     700                beq     act0            | no-op if not  (shouldn't happen ...)
     701
     702                move.b  FH_PT1(a1),d0   | get first point number
     703                add.b   FH_PIF(a1),d0   | add base to first point
     704                subq.b  #1,d0           | make d0 last point number
     705                cmp.b   FH_CPT(a1),d0   | check current point number
     706                beq     stopfn          | done if this is the last point
     707
     708                addq.b  #1,FH_CPT(a1)           | update current point number
     709                addi.w  #PT_LEN,d2              | update point index
     710                movea.l d3,a0                   | acquire a new pflist entry
     711                move.l  (a0),_pfqhdr            | ...
     712                move.l  _pflist,(a0)            | ...
     713                move.l  a0,_pflist              | ...
     714                move.w  FH_TRG(a1),PF_TRIG(a0)  | set trigger number in entry
     715                move.w  _curpf_f,PF_FUNC(a0)    | set v/p word in entry
     716                movem.l d1-d2/d4/a1-a3,PF_D1(a0)        | set registers in entry
     717                move.b  FH_TMD(a1),d0           | stop the function
     718                andi.w  #MSK_RNVB,d0            | ...
     719                move.w  d0,d3                   | ...
     720                add.w   d3,d3                   | ...
     721                andi.w  #MSK_ONVB,d3            | ...
     722                or.w    d3,d0                   | ...
     723                move.w  d0,F_CTL(a3,d1.W)       | ...
     724                bra     pfnext                  | go do next list entry
     725
     726                .page
     727| ------------------------------------------------------------------------------
    728728                .data
    729 * ------------------------------------------------------------------------------
    730 *
    731 * actab -- action code dispatch table
    732 * -----    --------------------------
    733 actab:          dc.l    act0    * 0 - AC_NULL:  no action
    734                 dc.l    act1    * 1 - AC_SUST:  sustain
    735                 dc.l    act2    * 2 - AC_ENBL:  enable
    736                 dc.l    act3    * 3 - AC_JUMP:  unconditional jump
    737                 dc.l    act4    * 4 - AC_LOOP:  jump n times      (loop)
    738                 dc.l    act5    * 5 - AC_KYUP:  jump if key up    (enable jump)
    739                 dc.l    act6    * 6 - AC_KYDN:  jump if key down  (sustain jump)
    740                 dc.l    act7    * 7 - AC_HERE:  here on key up
    741 *
    742 * ------------------------------------------------------------------------------
     729| ------------------------------------------------------------------------------
     730
     731| actab -- action code dispatch table
     732| -----    --------------------------
     733actab:          dc.l    act0    | 0 - AC_NULL:  no action
     734                dc.l    act1    | 1 - AC_SUST:  sustain
     735                dc.l    act2    | 2 - AC_ENBL:  enable
     736                dc.l    act3    | 3 - AC_JUMP:  unconditional jump
     737                dc.l    act4    | 4 - AC_LOOP:  jump n times      (loop)
     738                dc.l    act5    | 5 - AC_KYUP:  jump if key up    (enable jump)
     739                dc.l    act6    | 6 - AC_KYDN:  jump if key down  (sustain jump)
     740                dc.l    act7    | 7 - AC_HERE:  here on key up
     741
     742| ------------------------------------------------------------------------------
    743743                .bss
    744 * ------------------------------------------------------------------------------
    745 *
    746 * ----------------- local variables --------------------------------------------
    747 *
    748 _curpf_f:       ds.w    1       * interrupting voice & parameter from FPU
    749 *
    750 * ----------------- debug variables --------------------------------------------
    751 *
    752 _curpf_t:       ds.w    1       * current trigger
    753 *
    754 _curpf_l:       ds.l    1       * current pflist entry
    755 *
    756 * ------------------------------------------------------------------------------
    757 *
     744| ------------------------------------------------------------------------------
     745
     746| ----------------- local variables --------------------------------------------
     747
     748_curpf_f:       ds.w    1       | interrupting voice & parameter from FPU
     749
     750| ----------------- debug variables --------------------------------------------
     751
     752_curpf_t:       ds.w    1       | current trigger
     753
     754_curpf_l:       ds.l    1       | current pflist entry
     755
     756| ------------------------------------------------------------------------------
     757
    758758                .end
  • ram/sedisp.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * sedisp.s -- score event display driver
    3 * Version 43 -- 1988-09-26 -- D.N. Lynx Crowe
    4 *
    5 *       se_disp(ep, sd, gdstb, cf)
    6 *       struct s_entry *ep;
    7 *       short sd;
    8 *       struct gdsel *gdstb[];
    9 *       short cf;
    10 *
    11 *               Displays the event at 'ep', scrolling in direction 'sd', by
    12 *               updating 'gdstb'.  Uses the accidental code in 'ac_code', and
    13 *               the note type table 'nsvtab'.  Checks 'cf' to determine if
    14 *               we're displaying in the center of the screen.
    15 *               Allocates gdsel events as needed for new events.
    16 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| sedisp.s -- score event display driver
     3| Version 43 -- 1988-09-26 -- D.N. Lynx Crowe
     4
     5|       se_disp(ep, sd, gdstb, cf)
     6|       struct s_entry |ep;
     7|       short sd;
     8|       struct gdsel |gdstb[];
     9|       short cf;
     10
     11|               Displays the event at 'ep', scrolling in direction 'sd', by
     12|               updating 'gdstb'.  Uses the accidental code in 'ac_code', and
     13|               the note type table 'nsvtab'.  Checks 'cf' to determine if
     14|               we're displaying in the center of the screen.
     15|               Allocates gdsel events as needed for new events.
     16| ------------------------------------------------------------------------------
    1717                .text
    18 *
     18
    1919                .xdef   _se_disp
    20 *
     20
    2121                .xdef   _ac_code
    2222                .xdef   numstr
    23 *
     23
    2424                .xref   _dclkmd
    2525                .xref   _dsgmodz
     
    2929                .xref   _vputc
    3030                .xref   _vputs
    31 *
     31
    3232                .xref   _angroup
    3333                .xref   _ctrsw
     
    4949                .xref   _vrbw15
    5050                .xref   _vrcw
    51 *
    52                 .page
    53 *
    54 * parameter offsets
    55 * -----------------
    56 * for se_disp:
    57 * ------------
    58 P_EP            .equ    8               * LONG - event pointer
    59 P_SD            .equ    12              * WORD - scroll direction
    60 P_SL            .equ    14              * LONG - slice control table pointer
    61 P_CF            .equ    18              * WORD - center slice flag
    62 *
    63 * for vputa:
    64 * ----------
    65 ROW             .equ    4               * WORD - 'row' parameter offset
    66 COL             .equ    6               * WORD - 'col' parameter offset
    67 ATR             .equ    8               * WORD - 'atr' parameter offset
    68 *
    69 * Character field attributes for highlighting
    70 * -------------------------------------------
    71 AT01            .equ    $0054
    72 AT04            .equ    $0053
    73 AT05            .equ    $0054
    74 AT06            .equ    $0053
    75 AT07            .equ    $0054
    76 AT08            .equ    $0053
    77 AT09            .equ    $0054
    78 AT10            .equ    $0053
    79 AT11            .equ    $0052
    80 AT12            .equ    $0052
    81 *
    82 * Special character equates
    83 * -------------------------
    84 SP_M1           .equ    $A1                     * -1
    85 SP_P1           .equ    $A0                     * +1
    86 *
    87                 .page
    88 *
    89 * event structure offsets
    90 * -----------------------
    91 *                     offset             length
    92 *                     ------             ------
    93 E_TIME          .equ    0               * LONG
    94 E_SIZE          .equ    4               * BYTE
    95 E_TYPE          .equ    5               * BYTE
    96 E_DATA1         .equ    6               * BYTE
    97 E_NOTE          .equ    6               * BYTE
    98 E_DATA2         .equ    7               * BYTE
    99 E_GROUP         .equ    7               * BYTE
    100 E_BAK           .equ    8               * LONG
    101 E_FWD           .equ    12              * LONG
    102 E_DN            .equ    16              * LONG
    103 E_VEL           .equ    16              * WORD
    104 E_DATA4         .equ    18              * WORD
    105 E_UP            .equ    20              * LONG
    106 E_LFT           .equ    24              * LONG
    107 E_RGT           .equ    28              * LONG
    108 *
    109 N_ETYPES        .equ    25              * number of event types
    110 *
    111 * gdsel structure definitions
    112 * ---------------------------
    113 G_NEXT          .equ    0               * long - 'next' field   (struct gdsel *)
    114 G_NOTE          .equ    4               * word - 'note' field   (short)
    115 G_CODE          .equ    6               * word - 'code' field   (short)
    116 *
    117 NATCH_B         .equ    3               * uslice note code:  'begin natural'
    118 NOTE_E          .equ    6               * uslice note code:  'end note'
    119 *
    120 NGDSEL          .equ    17              * number of event slots in gdstb
    121 *
    122 BARFLAG         .equ    4*(NGDSEL-1)    * offset to the bar marker flag
    123 *
    124                 .page
    125 *
    126 * A few words about se_disp:
    127 * --------------------------
    128 * se_disp has to be very fast, so it's written in assembly language,
    129 * rather than C, which is usually pretty good, but not quite good enough
    130 * for this application.  The faster this routine runs, the higher the
    131 * tempo we can keep up with.  If this code is fast enough, we end up
    132 * hardware limited by the maximum rate of the timer, and the VSDD update rate.
    133 *
    134 _se_disp:       link    a6,#0                   * allocate and link stack frame
    135                 movea.l P_EP(a6),a0             * get event pointer 'ep' into a0
    136                 move.b  E_TYPE(a0),d1           * get event type into d1.W
    137                 andi.w  #$007F,d1               * mask off new-note flag
    138                 cmp.b   #N_ETYPES,d1            * see if it's valid
    139                 blt     seds1                   * jump if it is
    140 *
    141 dsexit:         unlk    a6                      * done -- unlink stack frames
    142                 rts                             * return to caller
    143 *
    144 seds1:          lea     sddtab,a1               * get base of dispatch table
    145                 lsl.w   #2,d1                   * multiplty event by 4 for index
    146                 movea.l 0(a1,d1.W),a2           * get address of event routine
    147                 jmp     (a2)                    * jump to event display routine
    148 *
    149 * On entry, the individual display routines only depend on a0 pointing at the
    150 * event they were dispatched for.  Registers a6 and a7 have their usual meaning,
    151 * a6 = frame pointer, a7 = stack pointer.
    152 *
    153 * d0..d2 are used for scratch, as are a0..a2, and are not saved by this code.
    154 *
    155                 .page
    156 *
    157 * dsnbx -- dispatch to begin / end based on sd
    158 * -----    -----------------------------------
    159 dsnbx:          tst.w   P_SD(a7)                * check direction
    160                 bne     dsne                    * treat as end if going backward
    161 *
    162 * dsnb -- display note begin
    163 * ----    ------------------
    164 dsnb:           move.b  E_TYPE(a0),d1           * get event type
    165                 move.w  d1,d2                   * save in d2
    166                 andi.w  #$007F,d1               * clear new-note flag
    167                 move.b  d1,E_TYPE(a0)           * store type back in event
    168                 clr.w   d0                      * get group number
    169                 move.b  E_GROUP(a0),d0          * ... in d0
    170                 move.w  d0,d1                   * save group in d1
    171                 add.w   d0,d0                   * make d0 a word offset
    172                 lea     _grpstat,a1             * check grpstat[grp]
    173                 tst.w   0(a1,d0.W)              * ...
    174                 beq     dsexit                  * done if not enabled
    175 *
    176                 tst.w   P_CF(a6)                * check center slice flag
    177                 beq     dsnb0                   * jump if not center slice
    178 *
    179                 tst.w   _velflag                * see if we display velocity
    180                 beq     dsnvx                   * jump if not
    181 *
    182                 move.w  d2,-(a7)                * save new-note flag on stack
    183                 move.w  d1,-(a7)                * save group number on stack
    184                 move.w  E_VEL(a0),d0            * get velocity
    185                 move.w  d1,d2                   * point into lastvel[]
    186                 add.w   d2,d2                   * ...
    187                 lea     _lastvel,a1             * ...
    188                 move.w  d0,0(a1,d2.W)           * update lastvel[group]
    189                 ext.l   d0                      * scale
    190                 divu    #252,d0                 * ...
    191                 cmpi.w  #100,d0                 * convert MS digit
    192                 bcs     dsnv0                   * ...
    193 *
    194                 move.b  #'1',numstr             * ...
    195                 subi.w  #100,d0                 * ...
    196                 bra     dsnv1                   * ...
    197 *
    198 dsnv0:          move.b  #'0',numstr             * ...
    199 *
    200 dsnv1:          ext.l   d0                      * convert middle & LS digits
    201                 divu    #10,d0                  * ...
    202                 addi.l  #$00300030,d0           * ...
    203                 move.b  d0,numstr+1             * ...
    204                 swap    d0                      * ...
    205                 move.b  d0,numstr+2             * ...
    206                 clr.b   numstr+3                * terminate string
    207                 move.w  d1,d0                   * col = group
    208                 asl.w   #2,d0                   * ... * 5
    209                 add.w   d1,d0                   * ...
    210                 add.w   #6,d0                   * ... + 6
    211                 move.l  a0,-(a7)                * save event pointer on stack
    212                 move.w  #AT11,-(a7)             * put attribute on stack
    213                 move.l  #numstr,-(a7)           * put string address on stack
    214                 move.w  d0,-(a7)                * put column on stack
    215                 move.w  #5,-(a7)                * put row on stack
    216                 move.l  _obj8,-(a7)             * put VSDD address on stack
    217                 jsr     _vputs                  * update the screen
    218                 add.l   #14,a7                  * clean up stack
    219                 movea.l (a7)+,a0                * restore event pointer
    220 *
    221                 .page
    222 *
    223                 move.w  (a7)+,d0                * get group from stack
    224                 cmpi.w  #12,d0                  * see which byte it's in
    225                 bcc     dsnv2                   * jump if in MS byte
    226 *
    227                 bset    d0,_vrbw12+1            * set group bit in LS byte
    228                 bra     dsnv3                   * ...
    229 *
    230 dsnv2:          bset    d0,_vrbw12              * set group bit in MS byte
    231 *
    232 dsnv3:          bset    #4,_vrcw                * set video reset type bit
    233                 move.w  (a7)+,d2                * get new-note flag from stack
    234 *
    235 dsnvx:          btst.l  #7,d2                   * check new-note flag
    236                 beq     dsexit                  * done if not set
    237 *
    238 dsnb0:          clr.w   d1                      * get note number nn (0..127)
    239                 move.b  E_NOTE(a0),d1           * ... in d1
    240                 sub.w   #21,d1                  * subtract base of piano scale
    241                 bmi     dsexit                  * done if not displayable
    242 *
    243                 cmp.w   #87,d1                  * see if it's too high
    244                 bgt     dsexit                  * done if not displayable
    245 *
    246                 move.l  _gdfsep,d0              * quit if no elements left
    247                 beq     dsexit                  * ...
    248 *
    249                 movea.l d0,a1                   * a1 = gdsp
    250                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    251                 clr.w   d2                      * d2 = ep->group
    252                 move.b  E_GROUP(a0),d2          * ...
    253                 lsl.w   #2,d2                   * ... * 4
    254                 movea.l P_SL(a6),a2             * a2 points at gdstb
    255                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[ep->group]
    256                 move.l  a1,0(a2,d2.W)           * gdstb[ep->group] = gdsp
    257                 move.w  d1,G_NOTE(a1)           * gdsp->note = nn
    258                 lea     _nsvtab,a2              * a2 points at nsvtab
    259                 tst.b   0(a2,d1.W)              * check nsvtab[nn]
    260                 beq     dsnb1                   * jump if natural note
    261 *
    262                 move.b  _ac_code,d1             * setup for an accidental note
    263                 bra     dsnb2                   * ...
    264 *
    265 dsnb1:          move.b  #NATCH_B,d1             * setup for a natural note
    266 *
    267 dsnb2:          move.w  d1,G_CODE(a1)           * gdsp->code = note type
    268                 bra     dsexit                  * done
    269 *
    270                 .page
    271 *
    272 * dsnex -- dispatch to end/begin based on sd
    273 * -----    ---------------------------------
    274 dsnex:          tst.w   P_SD(a7)                * check direction
    275                 bne     dsnb                    * treat as begin if going backward
    276 *
    277 * dsne -- display note end
    278 * ----    ----------------
    279 dsne:           move.b  E_TYPE(a0),d1           * get event type
    280                 move.w  d1,d2                   * save in d2
    281                 andi.w  #$007F,d1               * clear new-note flag
    282                 move.b  d1,E_TYPE(a0)           * store type back in event
    283                 clr.w   d0                      * get group number
    284                 move.b  E_GROUP(a0),d0          * ... in d0
    285                 add.w   d0,d0                   * ... as a word offset
    286                 lea     _grpstat,a1             * check grpstat[grp]
    287                 tst.w   0(a1,d0.W)              * ...
    288                 beq     dsexit                  * done if not enabled
    289 *
    290                 tst.w   P_CF(a6)                * check center slice flag
    291                 beq     dsne3                   * jump if not center slice
    292 *
    293                 btst.l  #7,d2                   * check new-note flag
    294                 beq     dsexit                  * done if not set
    295 *
    296 dsne3:          move.b  E_NOTE(a0),d1           * d1 = note number nn (0..127)
    297                 sub.w   #21,d1                  * subtract base of piano scale
    298                 bmi     dsexit                  * done if not displayable
    299 *
    300                 cmp.w   #87,d1                  * see if it's too high
    301                 bgt     dsexit                  * done if not displayable
    302 *
    303                 movea.l P_SL(a6),a2             * a2 points at gdstb
    304                 clr.w   d2                      * get group in d2
    305                 move.b  E_GROUP(a0),d2          * ...
    306                 lsl.w   #2,d2                   * ... * 4
    307                 move.l  0(a2,d2.W),d0           * check gdstb[ep->group]
     51
     52                .page
     53
     54| parameter offsets
     55| -----------------
     56| for se_disp:
     57| ------------
     58P_EP            =       8               | LONG - event pointer
     59P_SD            =       12              | WORD - scroll direction
     60P_SL            =       14              | LONG - slice control table pointer
     61P_CF            =       18              | WORD - center slice flag
     62
     63| for vputa:
     64| ----------
     65ROW             =       4               | WORD - 'row' parameter offset
     66COL             =       6               | WORD - 'col' parameter offset
     67ATR             =       8               | WORD - 'atr' parameter offset
     68
     69| Character field attributes for highlighting
     70| -------------------------------------------
     71AT01            =       0x0054
     72AT04            =       0x0053
     73AT05            =       0x0054
     74AT06            =       0x0053
     75AT07            =       0x0054
     76AT08            =       0x0053
     77AT09            =       0x0054
     78AT10            =       0x0053
     79AT11            =       0x0052
     80AT12            =       0x0052
     81
     82| Special character equates
     83| -------------------------
     84SP_M1           =       0xA1                    | -1
     85SP_P1           =       0xA0                    | +1
     86
     87                .page
     88
     89| event structure offsets
     90| -----------------------
     91|                     offset             length
     92|                     ------             ------
     93E_TIME          =       0               | LONG
     94E_SIZE          =       4               | BYTE
     95E_TYPE          =       5               | BYTE
     96E_DATA1         =       6               | BYTE
     97E_NOTE          =       6               | BYTE
     98E_DATA2         =       7               | BYTE
     99E_GROUP         =       7               | BYTE
     100E_BAK           =       8               | LONG
     101E_FWD           =       12              | LONG
     102E_DN            =       16              | LONG
     103E_VEL           =       16              | WORD
     104E_DATA4         =       18              | WORD
     105E_UP            =       20              | LONG
     106E_LFT           =       24              | LONG
     107E_RGT           =       28              | LONG
     108
     109N_ETYPES        =       25              | number of event types
     110
     111| gdsel structure definitions
     112| ---------------------------
     113G_NEXT          =       0               | long - 'next' field   (struct gdsel |)
     114G_NOTE          =       4               | word - 'note' field   (short)
     115G_CODE          =       6               | word - 'code' field   (short)
     116
     117NATCH_B         =       3               | uslice note code:  'begin natural'
     118NOTE_E          =       6               | uslice note code:  'end note'
     119
     120NGDSEL          =       17              | number of event slots in gdstb
     121
     122BARFLAG         =       4|(NGDSEL-1)    | offset to the bar marker flag
     123
     124                .page
     125
     126| A few words about se_disp:
     127| --------------------------
     128| se_disp has to be very fast, so it's written in assembly language,
     129| rather than C, which is usually pretty good, but not quite good enough
     130| for this application.  The faster this routine runs, the higher the
     131| tempo we can keep up with.  If this code is fast enough, we end up
     132| hardware limited by the maximum rate of the timer, and the VSDD update rate.
     133
     134_se_disp:       link    a6,#0                   | allocate and link stack frame
     135                movea.l P_EP(a6),a0             | get event pointer 'ep' into a0
     136                move.b  E_TYPE(a0),d1           | get event type into d1.W
     137                andi.w  #0x007F,d1              | mask off new-note flag
     138                cmp.b   #N_ETYPES,d1            | see if it's valid
     139                blt     seds1                   | jump if it is
     140
     141dsexit:         unlk    a6                      | done -- unlink stack frames
     142                rts                             | return to caller
     143
     144seds1:          lea     sddtab,a1               | get base of dispatch table
     145                lsl.w   #2,d1                   | multiplty event by 4 for index
     146                movea.l 0(a1,d1.W),a2           | get address of event routine
     147                jmp     (a2)                    | jump to event display routine
     148
     149| On entry, the individual display routines only depend on a0 pointing at the
     150| event they were dispatched for.  Registers a6 and a7 have their usual meaning,
     151| a6 = frame pointer, a7 = stack pointer.
     152
     153| d0..d2 are used for scratch, as are a0..a2, and are not saved by this code.
     154
     155                .page
     156
     157| dsnbx -- dispatch to begin / end based on sd
     158| -----    -----------------------------------
     159dsnbx:          tst.w   P_SD(a7)                | check direction
     160                bne     dsne                    | treat as end if going backward
     161
     162| dsnb -- display note begin
     163| ----    ------------------
     164dsnb:           move.b  E_TYPE(a0),d1           | get event type
     165                move.w  d1,d2                   | save in d2
     166                andi.w  #0x007F,d1              | clear new-note flag
     167                move.b  d1,E_TYPE(a0)           | store type back in event
     168                clr.w   d0                      | get group number
     169                move.b  E_GROUP(a0),d0          | ... in d0
     170                move.w  d0,d1                   | save group in d1
     171                add.w   d0,d0                   | make d0 a word offset
     172                lea     _grpstat,a1             | check grpstat[grp]
     173                tst.w   0(a1,d0.W)              | ...
     174                beq     dsexit                  | done if not enabled
     175
     176                tst.w   P_CF(a6)                | check center slice flag
     177                beq     dsnb0                   | jump if not center slice
     178
     179                tst.w   _velflag                | see if we display velocity
     180                beq     dsnvx                   | jump if not
     181
     182                move.w  d2,-(a7)                | save new-note flag on stack
     183                move.w  d1,-(a7)                | save group number on stack
     184                move.w  E_VEL(a0),d0            | get velocity
     185                move.w  d1,d2                   | point into lastvel[]
     186                add.w   d2,d2                   | ...
     187                lea     _lastvel,a1             | ...
     188                move.w  d0,0(a1,d2.W)           | update lastvel[group]
     189                ext.l   d0                      | scale
     190                divu    #252,d0                 | ...
     191                cmpi.w  #100,d0                 | convert MS digit
     192                bcs     dsnv0                   | ...
     193
     194                move.b  #'1',numstr             | ...
     195                subi.w  #100,d0                 | ...
     196                bra     dsnv1                   | ...
     197
     198dsnv0:          move.b  #'0',numstr             | ...
     199
     200dsnv1:          ext.l   d0                      | convert middle & LS digits
     201                divu    #10,d0                  | ...
     202                addi.l  #0x00300030,d0          | ...
     203                move.b  d0,numstr+1             | ...
     204                swap    d0                      | ...
     205                move.b  d0,numstr+2             | ...
     206                clr.b   numstr+3                | terminate string
     207                move.w  d1,d0                   | col = group
     208                asl.w   #2,d0                   | ... | 5
     209                add.w   d1,d0                   | ...
     210                add.w   #6,d0                   | ... + 6
     211                move.l  a0,-(a7)                | save event pointer on stack
     212                move.w  #AT11,-(a7)             | put attribute on stack
     213                move.l  #numstr,-(a7)           | put string address on stack
     214                move.w  d0,-(a7)                | put column on stack
     215                move.w  #5,-(a7)                | put row on stack
     216                move.l  _obj8,-(a7)             | put VSDD address on stack
     217                jsr     _vputs                  | update the screen
     218                add.l   #14,a7                  | clean up stack
     219                movea.l (a7)+,a0                | restore event pointer
     220
     221                .page
     222
     223                move.w  (a7)+,d0                | get group from stack
     224                cmpi.w  #12,d0                  | see which byte it's in
     225                bcc     dsnv2                   | jump if in MS byte
     226
     227                bset    d0,_vrbw12+1            | set group bit in LS byte
     228                bra     dsnv3                   | ...
     229
     230dsnv2:          bset    d0,_vrbw12              | set group bit in MS byte
     231
     232dsnv3:          bset    #4,_vrcw                | set video reset type bit
     233                move.w  (a7)+,d2                | get new-note flag from stack
     234
     235dsnvx:          btst.l  #7,d2                   | check new-note flag
     236                beq     dsexit                  | done if not set
     237
     238dsnb0:          clr.w   d1                      | get note number nn (0..127)
     239                move.b  E_NOTE(a0),d1           | ... in d1
     240                sub.w   #21,d1                  | subtract base of piano scale
     241                bmi     dsexit                  | done if not displayable
     242
     243                cmp.w   #87,d1                  | see if it's too high
     244                bgt     dsexit                  | done if not displayable
     245
     246                move.l  _gdfsep,d0              | quit if no elements left
     247                beq     dsexit                  | ...
     248
     249                movea.l d0,a1                   | a1 = gdsp
     250                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     251                clr.w   d2                      | d2 = ep->group
     252                move.b  E_GROUP(a0),d2          | ...
     253                lsl.w   #2,d2                   | ... | 4
     254                movea.l P_SL(a6),a2             | a2 points at gdstb
     255                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[ep->group]
     256                move.l  a1,0(a2,d2.W)           | gdstb[ep->group] = gdsp
     257                move.w  d1,G_NOTE(a1)           | gdsp->note = nn
     258                lea     _nsvtab,a2              | a2 points at nsvtab
     259                tst.b   0(a2,d1.W)              | check nsvtab[nn]
     260                beq     dsnb1                   | jump if natural note
     261
     262                move.b  _ac_code,d1             | setup for an accidental note
     263                bra     dsnb2                   | ...
     264
     265dsnb1:          move.b  #NATCH_B,d1             | setup for a natural note
     266
     267dsnb2:          move.w  d1,G_CODE(a1)           | gdsp->code = note type
     268                bra     dsexit                  | done
     269
     270                .page
     271
     272| dsnex -- dispatch to end/begin based on sd
     273| -----    ---------------------------------
     274dsnex:          tst.w   P_SD(a7)                | check direction
     275                bne     dsnb                    | treat as begin if going backward
     276
     277| dsne -- display note end
     278| ----    ----------------
     279dsne:           move.b  E_TYPE(a0),d1           | get event type
     280                move.w  d1,d2                   | save in d2
     281                andi.w  #0x007F,d1              | clear new-note flag
     282                move.b  d1,E_TYPE(a0)           | store type back in event
     283                clr.w   d0                      | get group number
     284                move.b  E_GROUP(a0),d0          | ... in d0
     285                add.w   d0,d0                   | ... as a word offset
     286                lea     _grpstat,a1             | check grpstat[grp]
     287                tst.w   0(a1,d0.W)              | ...
     288                beq     dsexit                  | done if not enabled
     289
     290                tst.w   P_CF(a6)                | check center slice flag
     291                beq     dsne3                   | jump if not center slice
     292
     293                btst.l  #7,d2                   | check new-note flag
     294                beq     dsexit                  | done if not set
     295
     296dsne3:          move.b  E_NOTE(a0),d1           | d1 = note number nn (0..127)
     297                sub.w   #21,d1                  | subtract base of piano scale
     298                bmi     dsexit                  | done if not displayable
     299
     300                cmp.w   #87,d1                  | see if it's too high
     301                bgt     dsexit                  | done if not displayable
     302
     303                movea.l P_SL(a6),a2             | a2 points at gdstb
     304                clr.w   d2                      | get group in d2
     305                move.b  E_GROUP(a0),d2          | ...
     306                lsl.w   #2,d2                   | ... | 4
     307                move.l  0(a2,d2.W),d0           | check gdstb[ep->group]
    308308                beq     dsexit
    309 *
    310 dsne0:          movea.l d0,a1                   * a1 = gdsp
    311 *
    312 dsne1:          cmp.w   G_NOTE(a1),d1           * compare nn to gdsp->note
    313                 bne     dsne2                   * jump if not the one we want
    314 *
    315                 move.w  #NOTE_E,G_CODE(a1)      * gdsp->code = NOTE_E  (end note)
    316 *
    317 dsne2:          move.l  G_NEXT(a1),d0           * get gdsp->next
    318                 beq     dsexit                  * done if next = NULL
    319 *
    320                 bra     dsne0                   * loop for next one
    321 *
    322                 .page
    323 *
    324 * dssbgn -- display section begin
    325 * ------    ---------------------
    326 dssbgn:         tst.w   P_CF(a6)                * center update ?
    327                 beq     dsbgn0                  * jump if not
    328 *
    329                 clr.w   d1                      * get section number
    330                 move.b  E_DATA1(a0),d1          * ... from the event
    331                 addq.w  #1,d1                   * ... adjusted for display
    332                 ext.l   d1                      * ... as a long in d1
    333                 divu    #10,d1                  * divide by 10 for conversion
    334                 add.l   #$00300030,d1           * add '0' for ASCII conversion
    335                 move.b  d1,numstr               * put MS byte in work area
    336                 swap    d1                      * swap register halves
    337                 move.b  d1,numstr+1             * put LS byte in work area
    338                 clr.b   numstr+2                * terminate string
    339                 move.w  #AT01,-(a7)             * put attribute on stack
    340                 move.l  #numstr,-(a7)           * put buffer address on stack
    341                 move.w  #6,-(a7)                * put column on stack
    342                 move.w  #0,-(a7)                * put row on stack
    343                 move.l  _obj8,-(a7)             * put sbase on stack
    344                 jsr     _vputs                  * update the screen
    345                 add.l   #14,a7                  * clean up stack
    346                 bset    #4,_vrcw+1              * set video reset type bit
    347                 tst.w   _ctrsw                  * update center for scupd ?
    348                 beq     dsexit                  * done if not
    349 *
    350 dsbgn0:         move.l  _gdfsep,d0              * quit if no elements left
    351                 beq     dsexit                  * ...
    352 *
    353                 movea.l d0,a1                   * a1 = gdsp
    354                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    355                 move.w  #48,d2                  * d2 = event PRIORITY * 4
    356                 movea.l P_SL(a6),a2             * a2 points at gdstb
    357                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    358                 move.w  #$1111,G_NOTE(a1)       * gdsp->note = COLOR
    359                 move.w  #0,G_CODE(a1)           * gdsp->code = PATTERN
    360                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    361                 bra     dsexit                  * done
    362 *
    363                 .page
    364 *
    365 * dssend -- display section end
    366 * ------    -------------------
    367 dssend:         tst.w   P_CF(a6)                * center update ?
    368                 beq     dssend0                 * jump if not
    369 *
    370                 tst.w   _ctrsw                  * update center for scupd ?
    371                 beq     dsexit                  * done if not
    372 *
    373 dssend0:        move.l  _gdfsep,d0              * quit if no elements left
    374                 beq     dsexit                  * ...
    375 *
    376                 movea.l d0,a1                   * a1 = gdsp
    377                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    378                 move.w  #48,d2                  * d2 = event PRIORITY * 4
    379                 movea.l P_SL(a6),a2             * a2 points at gdstb
    380                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    381                 move.w  #$1111,G_NOTE(a1)       * gdsp->note = COLOR
    382                 move.w  #2,G_CODE(a1)           * gdsp->code = PATTERN
    383                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    384                 bra     dsexit                  * done
    385 *
    386 * dsbeat -- display beat
    387 * ------    ------------
    388 dsbeat:         tst.w   P_CF(a6)                * center update ?
    389                 bne     dsexit                  * done if so
    390 *
    391                 move.l  _gdfsep,d0              * quit if no elements left
    392                 beq     dsexit                  * ...
    393 *
    394                 movea.l d0,a1                   * a1 = gdsp
    395                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    396                 move.w  #48,d2                  * d2 = event PRIORITY * 4
    397                 movea.l P_SL(a6),a2             * a2 points at gdstb
    398                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    399                 move.w  #$1111,G_NOTE(a1)       * gdsp->note = COLOR
    400                 move.w  #1,G_CODE(a1)           * gdsp->code = PATTERN
    401                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    402                 bra     dsexit                  * done
    403 *
    404                 .page
    405 *
    406 * dstune -- display tuning
    407 * ------    --------------
    408 dstune:         tst.w   P_CF(a6)                * center update ?
    409                 beq     dstune0                 * jump if not
    410 *
    411                 clr.w   d1                      * get current tuning
    412                 move.b  E_DATA1(a0),d1          * ...
    413                 add.w   #$0030,d1               * add '0' for ASCII conversion
    414                 move.w  #AT05,-(a7)             * put attribute on stack
    415                 move.w  d1,-(a7)                * put character on stack
    416                 move.w  #19,-(a7)               * put column on stack
    417                 move.w  #1,-(a7)                * put row on stack
    418                 move.l  _obj8,-(a7)             * put sbase on stack
    419                 jsr     _vputc                  * display character
    420                 add.l   #12,a7                  * clean up stack
    421                 bset    #1,_vrcw+1              * set video reset type bit
    422                 tst.w   _ctrsw                  * update center for scupd ?
    423                 beq     dsexit                  * done if not
    424 *
    425 dstune0:        move.l  _gdfsep,d0              * quit if no elements left
    426                 beq     dsexit                  * ...
    427 *
    428                 movea.l d0,a1                   * a1 = gdsp
    429                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    430                 move.w  #52,d2                  * d2 = event PRIORITY * 4
    431                 movea.l P_SL(a6),a2             * a2 points at gdstb
    432                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    433                 move.w  #$CCCC,G_NOTE(a1)       * gdsp->note = COLOR
    434                 move.w  #3,G_CODE(a1)           * gdsp->code = PATTERN
    435                 move.l  a1,0(a2,d2.W)           * gdstb[priority] = gdsp
    436                 bra     dsexit                  * done
    437 *
    438                 .page
    439 *
    440 * dstrns -- display transposition
    441 * ------    ---------------------
    442 dstrns:         clr.w   d0                      * get group number
    443                 move.b  E_DATA1(a0),d0          * ... in d0
    444                 add.w   d0,d0                   * ... as a word offset
    445                 lea     _grpstat,a1             * check grpstat[grp]
    446                 tst.w   0(a1,d0.W)              * ...
    447                 beq     dsexit                  * done if not enabled
    448 *
    449                 tst.w   P_CF(a6)                * center update
    450                 beq     dstrns0                 * jump if not
    451 *
    452                 move.w  E_LFT(a0),d1            * get transposition value
    453                 bpl     dstrns1                 * jump if positive
    454 *
    455                 move.b  #'-',numstr             * note negative sign
    456                 neg.w   d1                      * make number positive
    457                 bra     dstrns2                 * ...
    458 *
    459 dstrns1:        move.b  #'+',numstr             * note positive sign
    460 *
    461 dstrns2:        cmpi.w  #1000,d1                * is number GE 1000 ?
    462                 bcs     dstrns3                 * jump if not
    463 *
    464                 subi.w  #1000,d1                * adjust number
    465                 cmpi.b  #'-',numstr             * was number negative
    466                 bne     dstrns4                 * jump if not
    467 *
    468                 move.b  #SP_M1,numstr           * set -1 in numstr
    469                 bra     dstrns3                 * ...
    470 *
    471 dstrns4:        move.b  #SP_P1,numstr           * set +1 in numstr
    472 *
    473 dstrns3:        ext.l   d1                      * make d1 a long
    474                 divu    #100,d1                 * convert 1st digit
    475                 addi.w  #$0030,d1               * ... to ASCII
    476                 move.b  d1,numstr+1             * ... in numstr
    477                 swap    d1                      * convert 2nd digit
    478                 ext.l   d1                      * ...
    479                 divu    #10,d1                  * ...
    480                 addi.w  #$0030,d1               * ... to ASCII
    481                 move.b  d1,numstr+2             * ... in numstr
    482                 swap    d1                      * convert 3rd digit
    483                 addi.w  #$0030,d1               * ... to ASCII
    484                 move.b  d1,numstr+3             * ... in numstr
    485                 clr.b   numstr+4                * terminate numstr
    486 *
    487                 .page
    488 *
    489                 move.w  d0,d1                   * get group number
    490                 asr.w   #1,d1                   * ... in d1
    491                 move.w  d1,-(a7)                * save group number on stack
    492                 add.w   d0,d0                   * calculate column
    493                 add.w   d0,d1                   * ... = 5 * group
    494                 addi.w  #5,d1                   * ... + 5
    495                 move.w  #AT11,-(a7)             * vputs(obj8, 3, col, numstr, atr11)
    496                 move.l  #numstr,-(a7)           * ...
    497                 move.w  d1,-(a7)                * ...
    498                 move.w  #3,-(a7)                * ...
    499                 move.l  _obj8,-(a7)             * ...
    500                 jsr     _vputs                  * ...
    501                 add.l   #14,a7                  * ...
    502                 move.w  (a7)+,d0                * get group number
    503                 cmpi.w  #8,d0                   * see which byte it's in
    504                 bcc     dstrns5                 * jump if in MS byte
    505 *
    506                 bset    d0,_vrbw09+1            * set group bit in LS byte
    507                 bra     dstrns6                 * ...
    508 *
    509 dstrns5:        sub.w   #8,d0                   * adjust for byte
    510                 bset    d0,_vrbw09              * set group bit in MS byte
    511 *
    512 dstrns6:        bset    #1,_vrcw                * set video reset type bit
    513                 tst.w   _ctrsw                  * update center for scupd ?
    514                 beq     dsexit                  * done if not
    515 *
    516 dstrns0:        move.l  _gdfsep,d0              * quit if no elements left
    517                 beq     dsexit                  * ...
    518 *
    519                 movea.l d0,a1                   * a1 = gdsp
    520                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    521                 move.w  #52,d2                  * d2 = event PRIORITY * 4
    522                 movea.l P_SL(a6),a2             * a2 points at gdstb
    523                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    524                 move.w  #$9999,G_NOTE(a1)       * gdsp->note = COLOR
    525                 move.w  #4,G_CODE(a1)           * gdsp->code = PATTERN
    526                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    527                 bra     dsexit                  * done
    528 *
    529                 .page
    530 *
    531 * dsdyn -- display dynamics
    532 * -----    ----------------
    533 dsdyn:          clr.w   d0                      * get group number
    534                 move.b  E_DATA1(a0),d0          * ... in d0
    535                 add.w   d0,d0                   * ... as a word offset
    536                 lea     _grpstat,a1             * check grpstat[grp]
    537                 tst.w   0(a1,d0.W)              * ...
    538                 beq     dsexit                  * done if not enabled
    539 *
    540                 tst.w   P_CF(a6)                * center update ?
    541                 beq     dsdyn00                 * jump if not
    542 *
    543                 clr.w   d0                      * get dynamics
    544                 move.b  E_DATA2(a0),d0          * ... in d0
    545                 move.w  d0,-(a7)                * save dyanmics
    546                 clr.w   d1                      * get group number
    547                 move.b  E_DATA1(a0),d1          * ... in d1
    548                 move.w  d1,-(a7)                * save group number
    549                 move.w  (a7),d0                 * col = group number
    550                 add.w   d0,d0                   * ... * 5
    551                 add.w   d0,d0                   * ...
    552                 move.w  (a7)+,d2                * ...  (d2 = group number)
    553                 add.w   d2,d0                   * ...
    554                 add.w   #6,d0                   * ... + 6
    555                 move.w  (a7)+,d1                * get dynamics
    556                 add.w   #$0030,d1               * add '0' for ASCII conversion
    557                 move.w  d2,-(a7)                * save group number
    558                 move.w  #AT11,-(a7)             * put attribute on stack
    559                 move.w  d1,-(a7)                * put digit on stack
    560                 move.w  d0,-(a7)                * put column on stack
    561                 move.w  #4,-(a7)                * put row on stack
    562                 move.l  _obj8,-(a7)             * put object address on stack
    563                 jsr     _vputc                  * update the screen
    564                 add.l   #12,a7                  * clean up stack
    565                 move.w  (a7)+,d0                * get group number
    566                 cmp.w   #8,d0                   * see which word it's in
    567                 bcc     dsdyn1                  * jump if in MS word
    568 *
    569                 bset    d0,_vrbw10+1            * set group bit in LS byte
    570                 bra     dsdyn2                  * ...
    571 *
    572 dsdyn1:         sub.w   #8,d0                   * adjust for for byte
    573                 bset    d0,_vrbw10              * set group bit in MS byte
    574 *
    575 dsdyn2:         bset    #2,_vrcw                * set video reset type bit
    576                 tst.w   _ctrsw                  * update center for scupd ?
    577                 beq     dsexit                  * done if not
    578 *
    579                 .page
    580 dsdyn00:        move.l  _gdfsep,d0              * quit if no elements left
    581                 beq     dsexit                  * ...
    582 *
    583                 movea.l d0,a1                   * a1 = gdsp
    584                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    585                 move.w  #52,d2                  * d2 = event PRIORITY * 4
    586                 movea.l P_SL(a6),a2             * a2 points at gdstb
    587                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    588                 move.w  #$9999,G_NOTE(a1)       * gdsp->note = COLOR
    589                 move.w  #5,G_CODE(a1)           * gdsp->code = PATTERN
    590                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    591                 bra     dsexit                  * done
    592 *
    593                 .page
    594 *
    595 * dslocn -- display location
    596 * ------    ----------------
    597 dslocn:         clr.w   d0                      * get group number
    598                 move.b  E_DATA1(a0),d0          * ... in d0
    599                 add.w   d0,d0                   * ... as a word offset
    600                 lea     _grpstat,a1             * check grpstat[grp]
    601                 tst.w   0(a1,d0.W)              * ...
    602                 beq     dsexit                  * done if not enabled
    603 *
    604                 tst.w   P_CF(a6)                * center update ?
    605                 beq     dsloc00                 * jump if not
    606 *
    607                 clr.w   d0                      * get location
    608                 move.b  E_DATA2(a0),d0          * ... in d0
    609                 move.w  d0,-(a7)                * save location
    610                 clr.w   d1                      * get group number
    611                 move.b  E_DATA1(a0),d1          * ... in d1
    612                 move.w  d1,-(a7)                * save group number
    613                 move.w  (a7),d0                 * col = group number
    614                 add.w   d0,d0                   * ... * 5
    615                 add.w   d0,d0                   * ...
    616                 move.w  (a7)+,d2                * ...  (d2 = group number)
    617                 add.w   d2,d0                   * ...
    618                 add.w   #8,d0                   * ... + 8
    619                 move.w  (a7)+,d1                * get location
    620                 add.w   #$0031,d1               * add '0' for ASCII conversion
    621                 move.w  d2,-(a7)                * save group number
    622                 move.w  #AT11,-(a7)             * put attribute on stack
    623                 move.w  d1,-(a7)                * put character on stack
    624                 move.w  d0,-(a7)                * put column on stack
    625                 move.w  #4,-(a7)                * put row on stack
    626                 move.l  _obj8,-(a7)             * put object address on stack
    627                 jsr     _vputc                  * update the screen
    628                 add.l   #12,a7                  * clean up stack
    629                 move.w  (a7)+,d0                * get group number
    630                 cmp.w   #8,d0                   * see which word it's in
    631                 bcc     dslocn1                 * jump if in MS word
    632 *
    633                 bset    d0,_vrbw11+1            * set group bit in LS byte
    634                 bra     dslocn2                 * ...
    635 *
    636 dslocn1:        sub.w   #8,d0                   * adjust for for byte
    637                 bset    d0,_vrbw11              * set group bit in MS byte
    638 *
    639 dslocn2:        bset    #3,_vrcw                * set video reset type bit
    640                 tst.w   _ctrsw                  * update center for scupd ?
    641                 beq     dsexit                  * done if not
    642 *
    643                 .page
    644 dsloc00:        move.l  _gdfsep,d0              * quit if no elements left
    645                 beq     dsexit                  * ...
    646 *
    647                 movea.l d0,a1                   * a1 = gdsp
    648                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    649                 move.w  #52,d2                  * d2 = event PRIORITY * 4
    650                 movea.l P_SL(a6),a2             * a2 points at gdstb
    651                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    652                 move.w  #$9999,G_NOTE(a1)       * gdsp->note = COLOR
    653                 move.w  #5,G_CODE(a1)           * gdsp->code = PATTERN
    654                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    655                 bra     dsexit                  * done
    656 *
    657                 .page
    658 *
    659 * dsanrs -- display analog resolution
    660 * ------    -------------------------
    661 dsanrs:         move.b  E_DATA1(a0),d1          * get var / group
    662                 move.w  d1,d0                   * extract group number
    663                 andi.w  #$000F,d0               * ... in d0
    664                 add.w   d0,d0                   * ... as a word offset
    665                 lea     _grpstat,a1             * check grpstat[grp]
    666                 tst.w   0(a1,d0.W)              * ...
    667                 beq     dsexit                  * done if not enabled
    668 *
    669                 tst.w   P_CF(a6)                * center update ?
    670                 beq     dsanrs0                 * jump if not
    671 *
    672                 move.w  _angroup,d2             * see if we display
    673                 bmi     dsexit                  * jump if not
    674 *
    675                 subq.w  #1,d2                   * adust selected group number
    676                 move.w  d1,d0                   * extract group from event
    677                 andi.w  #$000F,d0               * ...
    678                 cmp.w   d0,d2                   * see if we display
    679                 bne     dsexit                  * jump if not
    680 *
    681                 lsr.w   #4,d1                   * extract variable number
    682                 andi.w  #$000F,d1               * ...
    683                 move.w  d1,-(a7)                * save variable number
    684                 move.w  d1,d0                   * calculate display offset
    685                 lsl.w   #3,d0                   * ... (var * 9) + 6
    686                 add.w   d0,d1                   * ... in d1
    687                 addq.w  #6,d1                   * ...
    688                 move.b  E_DATA2(a0),d0          * get resolution
    689                 addi.w  #$0030,d0               * convert for display
    690                 move.w  #AT12,-(a7)             * put attribute on stack
    691                 move.w  d0,-(a7)                * put character on stack
    692                 move.w  d1,-(a7)                * put column on stack
    693                 move.w  #7,-(a7)                * put row on stack
    694                 move.l  _obj8,-(a7)             * put sbase on stack
    695                 jsr     _vputc                  * update the screen
    696                 add.l   #12,a7                  * clean up stack
    697                 move.w  (a7)+,d0                * get variable number
    698                 bset    d0,_vrbw13+1            * set variable bit
    699                 bset    #5,_vrcw                * set video reset type bit
    700                 tst.w   _ctrsw                  * update center for scupd ?
    701                 beq     dsexit                  * done if not
    702 *
    703                 .page
    704 dsanrs0:        move.l  _gdfsep,d0              * quit if no elements left
    705                 beq     dsexit                  * ...
    706 *
    707                 movea.l d0,a1                   * a1 = gdsp
    708                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    709                 move.w  #52,d2                  * d2 = event PRIORITY * 4
    710                 movea.l P_SL(a6),a2             * a2 points at gdstb
    711                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    712                 move.w  #$9999,G_NOTE(a1)       * gdsp->note = COLOR
    713                 move.w  #6,G_CODE(a1)           * gdsp->code = PATTERN
    714                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    715                 bra     dsexit                  * done
    716 *
    717                 .page
    718 *
    719 * dsanvl -- display analog value
    720 * ------    --------------------
    721 dsanvl:         move.w  _angroup,d2             * see if we display
    722                 bmi     dsexit                  * jump if not
    723 *
    724                 move.b  E_DATA1(a0),d1          * get var / group
    725                 move.w  d1,d0                   * extract group number
    726                 andi.w  #$000F,d0               * ... in d0
    727                 add.w   d0,d0                   * ... as a word offset
    728                 lea     _grpstat,a1             * check grpstat[grp]
    729                 tst.w   0(a1,d0.W)              * ...
    730                 beq     dsexit                  * done if not enabled
    731 *
    732                 tst.w   P_CF(a6)                * center update ?
    733                 beq     dsanvl0                 * jump if not
    734 *
    735                 subq.w  #1,d2                   * adust group number
    736                 move.w  d1,d0                   * extract group
    737                 andi.w  #$000F,d0               * ...
    738                 cmp.w   d0,d2                   * see if we display
    739                 bne     dsexit                  * jump if not
    740 *
    741                 lsr.w   #4,d1                   * extract variable number
    742                 andi.w  #$000F,d1               * ...
    743                 move.w  d1,-(a7)                * save variable number
    744                 move.w  d1,d0                   * calculate display offset
    745                 lsl.w   #3,d0                   * ... (var * 9) + 8
    746                 add.w   d0,d1                   * ... in d1
    747                 addi.w  #8,d1                   * ...
    748                 move.w  E_DN(a0),d0             * get value
    749                 asr.w   #5,d0                   * adjust to low 11 bits
    750                 bpl     dsanvl1                 * jump if positive
    751 *
    752                 move.b  #'-',numstr             * set sign = '-'
    753                 neg.w   d0                      * make value positive
     309
     310dsne0:          movea.l d0,a1                   | a1 = gdsp
     311
     312dsne1:          cmp.w   G_NOTE(a1),d1           | compare nn to gdsp->note
     313                bne     dsne2                   | jump if not the one we want
     314
     315                move.w  #NOTE_E,G_CODE(a1)      | gdsp->code = NOTE_E  (end note)
     316
     317dsne2:          move.l  G_NEXT(a1),d0           | get gdsp->next
     318                beq     dsexit                  | done if next = NULL
     319
     320                bra     dsne0                   | loop for next one
     321
     322                .page
     323
     324| dssbgn -- display section begin
     325| ------    ---------------------
     326dssbgn:         tst.w   P_CF(a6)                | center update ?
     327                beq     dsbgn0                  | jump if not
     328
     329                clr.w   d1                      | get section number
     330                move.b  E_DATA1(a0),d1          | ... from the event
     331                addq.w  #1,d1                   | ... adjusted for display
     332                ext.l   d1                      | ... as a long in d1
     333                divu    #10,d1                  | divide by 10 for conversion
     334                add.l   #0x00300030,d1          | add '0' for ASCII conversion
     335                move.b  d1,numstr               | put MS byte in work area
     336                swap    d1                      | swap register halves
     337                move.b  d1,numstr+1             | put LS byte in work area
     338                clr.b   numstr+2                | terminate string
     339                move.w  #AT01,-(a7)             | put attribute on stack
     340                move.l  #numstr,-(a7)           | put buffer address on stack
     341                move.w  #6,-(a7)                | put column on stack
     342                move.w  #0,-(a7)                | put row on stack
     343                move.l  _obj8,-(a7)             | put sbase on stack
     344                jsr     _vputs                  | update the screen
     345                add.l   #14,a7                  | clean up stack
     346                bset    #4,_vrcw+1              | set video reset type bit
     347                tst.w   _ctrsw                  | update center for scupd ?
     348                beq     dsexit                  | done if not
     349
     350dsbgn0:         move.l  _gdfsep,d0              | quit if no elements left
     351                beq     dsexit                  | ...
     352
     353                movea.l d0,a1                   | a1 = gdsp
     354                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     355                move.w  #48,d2                  | d2 = event PRIORITY | 4
     356                movea.l P_SL(a6),a2             | a2 points at gdstb
     357                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     358                move.w  #0x1111,G_NOTE(a1)      | gdsp->note = COLOR
     359                move.w  #0,G_CODE(a1)           | gdsp->code = PATTERN
     360                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     361                bra     dsexit                  | done
     362
     363                .page
     364
     365| dssend -- display section end
     366| ------    -------------------
     367dssend:         tst.w   P_CF(a6)                | center update ?
     368                beq     dssend0                 | jump if not
     369
     370                tst.w   _ctrsw                  | update center for scupd ?
     371                beq     dsexit                  | done if not
     372
     373dssend0:        move.l  _gdfsep,d0              | quit if no elements left
     374                beq     dsexit                  | ...
     375
     376                movea.l d0,a1                   | a1 = gdsp
     377                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     378                move.w  #48,d2                  | d2 = event PRIORITY | 4
     379                movea.l P_SL(a6),a2             | a2 points at gdstb
     380                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     381                move.w  #0x1111,G_NOTE(a1)      | gdsp->note = COLOR
     382                move.w  #2,G_CODE(a1)           | gdsp->code = PATTERN
     383                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     384                bra     dsexit                  | done
     385
     386| dsbeat -- display beat
     387| ------    ------------
     388dsbeat:         tst.w   P_CF(a6)                | center update ?
     389                bne     dsexit                  | done if so
     390
     391                move.l  _gdfsep,d0              | quit if no elements left
     392                beq     dsexit                  | ...
     393
     394                movea.l d0,a1                   | a1 = gdsp
     395                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     396                move.w  #48,d2                  | d2 = event PRIORITY | 4
     397                movea.l P_SL(a6),a2             | a2 points at gdstb
     398                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     399                move.w  #0x1111,G_NOTE(a1)      | gdsp->note = COLOR
     400                move.w  #1,G_CODE(a1)           | gdsp->code = PATTERN
     401                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     402                bra     dsexit                  | done
     403
     404                .page
     405
     406| dstune -- display tuning
     407| ------    --------------
     408dstune:         tst.w   P_CF(a6)                | center update ?
     409                beq     dstune0                 | jump if not
     410
     411                clr.w   d1                      | get current tuning
     412                move.b  E_DATA1(a0),d1          | ...
     413                add.w   #0x0030,d1              | add '0' for ASCII conversion
     414                move.w  #AT05,-(a7)             | put attribute on stack
     415                move.w  d1,-(a7)                | put character on stack
     416                move.w  #19,-(a7)               | put column on stack
     417                move.w  #1,-(a7)                | put row on stack
     418                move.l  _obj8,-(a7)             | put sbase on stack
     419                jsr     _vputc                  | display character
     420                add.l   #12,a7                  | clean up stack
     421                bset    #1,_vrcw+1              | set video reset type bit
     422                tst.w   _ctrsw                  | update center for scupd ?
     423                beq     dsexit                  | done if not
     424
     425dstune0:        move.l  _gdfsep,d0              | quit if no elements left
     426                beq     dsexit                  | ...
     427
     428                movea.l d0,a1                   | a1 = gdsp
     429                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     430                move.w  #52,d2                  | d2 = event PRIORITY | 4
     431                movea.l P_SL(a6),a2             | a2 points at gdstb
     432                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     433                move.w  #0xCCCC,G_NOTE(a1)      | gdsp->note = COLOR
     434                move.w  #3,G_CODE(a1)           | gdsp->code = PATTERN
     435                move.l  a1,0(a2,d2.W)           | gdstb[priority] = gdsp
     436                bra     dsexit                  | done
     437
     438                .page
     439
     440| dstrns -- display transposition
     441| ------    ---------------------
     442dstrns:         clr.w   d0                      | get group number
     443                move.b  E_DATA1(a0),d0          | ... in d0
     444                add.w   d0,d0                   | ... as a word offset
     445                lea     _grpstat,a1             | check grpstat[grp]
     446                tst.w   0(a1,d0.W)              | ...
     447                beq     dsexit                  | done if not enabled
     448
     449                tst.w   P_CF(a6)                | center update
     450                beq     dstrns0                 | jump if not
     451
     452                move.w  E_LFT(a0),d1            | get transposition value
     453                bpl     dstrns1                 | jump if positive
     454
     455                move.b  #'-',numstr             | note negative sign
     456                neg.w   d1                      | make number positive
     457                bra     dstrns2                 | ...
     458
     459dstrns1:        move.b  #'+',numstr             | note positive sign
     460
     461dstrns2:        cmpi.w  #1000,d1                | is number GE 1000 ?
     462                bcs     dstrns3                 | jump if not
     463
     464                subi.w  #1000,d1                | adjust number
     465                cmpi.b  #'-',numstr             | was number negative
     466                bne     dstrns4                 | jump if not
     467
     468                move.b  #SP_M1,numstr           | set -1 in numstr
     469                bra     dstrns3                 | ...
     470
     471dstrns4:        move.b  #SP_P1,numstr           | set +1 in numstr
     472
     473dstrns3:        ext.l   d1                      | make d1 a long
     474                divu    #100,d1                 | convert 1st digit
     475                addi.w  #0x0030,d1              | ... to ASCII
     476                move.b  d1,numstr+1             | ... in numstr
     477                swap    d1                      | convert 2nd digit
     478                ext.l   d1                      | ...
     479                divu    #10,d1                  | ...
     480                addi.w  #0x0030,d1              | ... to ASCII
     481                move.b  d1,numstr+2             | ... in numstr
     482                swap    d1                      | convert 3rd digit
     483                addi.w  #0x0030,d1              | ... to ASCII
     484                move.b  d1,numstr+3             | ... in numstr
     485                clr.b   numstr+4                | terminate numstr
     486
     487                .page
     488
     489                move.w  d0,d1                   | get group number
     490                asr.w   #1,d1                   | ... in d1
     491                move.w  d1,-(a7)                | save group number on stack
     492                add.w   d0,d0                   | calculate column
     493                add.w   d0,d1                   | ... = 5 | group
     494                addi.w  #5,d1                   | ... + 5
     495                move.w  #AT11,-(a7)             | vputs(obj8, 3, col, numstr, atr11)
     496                move.l  #numstr,-(a7)           | ...
     497                move.w  d1,-(a7)                | ...
     498                move.w  #3,-(a7)                | ...
     499                move.l  _obj8,-(a7)             | ...
     500                jsr     _vputs                  | ...
     501                add.l   #14,a7                  | ...
     502                move.w  (a7)+,d0                | get group number
     503                cmpi.w  #8,d0                   | see which byte it's in
     504                bcc     dstrns5                 | jump if in MS byte
     505
     506                bset    d0,_vrbw09+1            | set group bit in LS byte
     507                bra     dstrns6                 | ...
     508
     509dstrns5:        sub.w   #8,d0                   | adjust for byte
     510                bset    d0,_vrbw09              | set group bit in MS byte
     511
     512dstrns6:        bset    #1,_vrcw                | set video reset type bit
     513                tst.w   _ctrsw                  | update center for scupd ?
     514                beq     dsexit                  | done if not
     515
     516dstrns0:        move.l  _gdfsep,d0              | quit if no elements left
     517                beq     dsexit                  | ...
     518
     519                movea.l d0,a1                   | a1 = gdsp
     520                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     521                move.w  #52,d2                  | d2 = event PRIORITY | 4
     522                movea.l P_SL(a6),a2             | a2 points at gdstb
     523                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     524                move.w  #0x9999,G_NOTE(a1)      | gdsp->note = COLOR
     525                move.w  #4,G_CODE(a1)           | gdsp->code = PATTERN
     526                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     527                bra     dsexit                  | done
     528
     529                .page
     530
     531| dsdyn -- display dynamics
     532| -----    ----------------
     533dsdyn:          clr.w   d0                      | get group number
     534                move.b  E_DATA1(a0),d0          | ... in d0
     535                add.w   d0,d0                   | ... as a word offset
     536                lea     _grpstat,a1             | check grpstat[grp]
     537                tst.w   0(a1,d0.W)              | ...
     538                beq     dsexit                  | done if not enabled
     539
     540                tst.w   P_CF(a6)                | center update ?
     541                beq     dsdyn00                 | jump if not
     542
     543                clr.w   d0                      | get dynamics
     544                move.b  E_DATA2(a0),d0          | ... in d0
     545                move.w  d0,-(a7)                | save dyanmics
     546                clr.w   d1                      | get group number
     547                move.b  E_DATA1(a0),d1          | ... in d1
     548                move.w  d1,-(a7)                | save group number
     549                move.w  (a7),d0                 | col = group number
     550                add.w   d0,d0                   | ... | 5
     551                add.w   d0,d0                   | ...
     552                move.w  (a7)+,d2                | ...  (d2 = group number)
     553                add.w   d2,d0                   | ...
     554                add.w   #6,d0                   | ... + 6
     555                move.w  (a7)+,d1                | get dynamics
     556                add.w   #0x0030,d1              | add '0' for ASCII conversion
     557                move.w  d2,-(a7)                | save group number
     558                move.w  #AT11,-(a7)             | put attribute on stack
     559                move.w  d1,-(a7)                | put digit on stack
     560                move.w  d0,-(a7)                | put column on stack
     561                move.w  #4,-(a7)                | put row on stack
     562                move.l  _obj8,-(a7)             | put object address on stack
     563                jsr     _vputc                  | update the screen
     564                add.l   #12,a7                  | clean up stack
     565                move.w  (a7)+,d0                | get group number
     566                cmp.w   #8,d0                   | see which word it's in
     567                bcc     dsdyn1                  | jump if in MS word
     568
     569                bset    d0,_vrbw10+1            | set group bit in LS byte
     570                bra     dsdyn2                  | ...
     571
     572dsdyn1:         sub.w   #8,d0                   | adjust for for byte
     573                bset    d0,_vrbw10              | set group bit in MS byte
     574
     575dsdyn2:         bset    #2,_vrcw                | set video reset type bit
     576                tst.w   _ctrsw                  | update center for scupd ?
     577                beq     dsexit                  | done if not
     578
     579                .page
     580dsdyn00:        move.l  _gdfsep,d0              | quit if no elements left
     581                beq     dsexit                  | ...
     582
     583                movea.l d0,a1                   | a1 = gdsp
     584                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     585                move.w  #52,d2                  | d2 = event PRIORITY | 4
     586                movea.l P_SL(a6),a2             | a2 points at gdstb
     587                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     588                move.w  #0x9999,G_NOTE(a1)      | gdsp->note = COLOR
     589                move.w  #5,G_CODE(a1)           | gdsp->code = PATTERN
     590                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     591                bra     dsexit                  | done
     592
     593                .page
     594
     595| dslocn -- display location
     596| ------    ----------------
     597dslocn:         clr.w   d0                      | get group number
     598                move.b  E_DATA1(a0),d0          | ... in d0
     599                add.w   d0,d0                   | ... as a word offset
     600                lea     _grpstat,a1             | check grpstat[grp]
     601                tst.w   0(a1,d0.W)              | ...
     602                beq     dsexit                  | done if not enabled
     603
     604                tst.w   P_CF(a6)                | center update ?
     605                beq     dsloc00                 | jump if not
     606
     607                clr.w   d0                      | get location
     608                move.b  E_DATA2(a0),d0          | ... in d0
     609                move.w  d0,-(a7)                | save location
     610                clr.w   d1                      | get group number
     611                move.b  E_DATA1(a0),d1          | ... in d1
     612                move.w  d1,-(a7)                | save group number
     613                move.w  (a7),d0                 | col = group number
     614                add.w   d0,d0                   | ... | 5
     615                add.w   d0,d0                   | ...
     616                move.w  (a7)+,d2                | ...  (d2 = group number)
     617                add.w   d2,d0                   | ...
     618                add.w   #8,d0                   | ... + 8
     619                move.w  (a7)+,d1                | get location
     620                add.w   #0x0031,d1              | add '0' for ASCII conversion
     621                move.w  d2,-(a7)                | save group number
     622                move.w  #AT11,-(a7)             | put attribute on stack
     623                move.w  d1,-(a7)                | put character on stack
     624                move.w  d0,-(a7)                | put column on stack
     625                move.w  #4,-(a7)                | put row on stack
     626                move.l  _obj8,-(a7)             | put object address on stack
     627                jsr     _vputc                  | update the screen
     628                add.l   #12,a7                  | clean up stack
     629                move.w  (a7)+,d0                | get group number
     630                cmp.w   #8,d0                   | see which word it's in
     631                bcc     dslocn1                 | jump if in MS word
     632
     633                bset    d0,_vrbw11+1            | set group bit in LS byte
     634                bra     dslocn2                 | ...
     635
     636dslocn1:        sub.w   #8,d0                   | adjust for for byte
     637                bset    d0,_vrbw11              | set group bit in MS byte
     638
     639dslocn2:        bset    #3,_vrcw                | set video reset type bit
     640                tst.w   _ctrsw                  | update center for scupd ?
     641                beq     dsexit                  | done if not
     642
     643                .page
     644dsloc00:        move.l  _gdfsep,d0              | quit if no elements left
     645                beq     dsexit                  | ...
     646
     647                movea.l d0,a1                   | a1 = gdsp
     648                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     649                move.w  #52,d2                  | d2 = event PRIORITY | 4
     650                movea.l P_SL(a6),a2             | a2 points at gdstb
     651                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     652                move.w  #0x9999,G_NOTE(a1)      | gdsp->note = COLOR
     653                move.w  #5,G_CODE(a1)           | gdsp->code = PATTERN
     654                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     655                bra     dsexit                  | done
     656
     657                .page
     658
     659| dsanrs -- display analog resolution
     660| ------    -------------------------
     661dsanrs:         move.b  E_DATA1(a0),d1          | get var / group
     662                move.w  d1,d0                   | extract group number
     663                andi.w  #0x000F,d0              | ... in d0
     664                add.w   d0,d0                   | ... as a word offset
     665                lea     _grpstat,a1             | check grpstat[grp]
     666                tst.w   0(a1,d0.W)              | ...
     667                beq     dsexit                  | done if not enabled
     668
     669                tst.w   P_CF(a6)                | center update ?
     670                beq     dsanrs0                 | jump if not
     671
     672                move.w  _angroup,d2             | see if we display
     673                bmi     dsexit                  | jump if not
     674
     675                subq.w  #1,d2                   | adust selected group number
     676                move.w  d1,d0                   | extract group from event
     677                andi.w  #0x000F,d0              | ...
     678                cmp.w   d0,d2                   | see if we display
     679                bne     dsexit                  | jump if not
     680
     681                lsr.w   #4,d1                   | extract variable number
     682                andi.w  #0x000F,d1              | ...
     683                move.w  d1,-(a7)                | save variable number
     684                move.w  d1,d0                   | calculate display offset
     685                lsl.w   #3,d0                   | ... (var | 9) + 6
     686                add.w   d0,d1                   | ... in d1
     687                addq.w  #6,d1                   | ...
     688                move.b  E_DATA2(a0),d0          | get resolution
     689                addi.w  #0x0030,d0              | convert for display
     690                move.w  #AT12,-(a7)             | put attribute on stack
     691                move.w  d0,-(a7)                | put character on stack
     692                move.w  d1,-(a7)                | put column on stack
     693                move.w  #7,-(a7)                | put row on stack
     694                move.l  _obj8,-(a7)             | put sbase on stack
     695                jsr     _vputc                  | update the screen
     696                add.l   #12,a7                  | clean up stack
     697                move.w  (a7)+,d0                | get variable number
     698                bset    d0,_vrbw13+1            | set variable bit
     699                bset    #5,_vrcw                | set video reset type bit
     700                tst.w   _ctrsw                  | update center for scupd ?
     701                beq     dsexit                  | done if not
     702
     703                .page
     704dsanrs0:        move.l  _gdfsep,d0              | quit if no elements left
     705                beq     dsexit                  | ...
     706
     707                movea.l d0,a1                   | a1 = gdsp
     708                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     709                move.w  #52,d2                  | d2 = event PRIORITY | 4
     710                movea.l P_SL(a6),a2             | a2 points at gdstb
     711                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     712                move.w  #0x9999,G_NOTE(a1)      | gdsp->note = COLOR
     713                move.w  #6,G_CODE(a1)           | gdsp->code = PATTERN
     714                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     715                bra     dsexit                  | done
     716
     717                .page
     718
     719| dsanvl -- display analog value
     720| ------    --------------------
     721dsanvl:         move.w  _angroup,d2             | see if we display
     722                bmi     dsexit                  | jump if not
     723
     724                move.b  E_DATA1(a0),d1          | get var / group
     725                move.w  d1,d0                   | extract group number
     726                andi.w  #0x000F,d0              | ... in d0
     727                add.w   d0,d0                   | ... as a word offset
     728                lea     _grpstat,a1             | check grpstat[grp]
     729                tst.w   0(a1,d0.W)              | ...
     730                beq     dsexit                  | done if not enabled
     731
     732                tst.w   P_CF(a6)                | center update ?
     733                beq     dsanvl0                 | jump if not
     734
     735                subq.w  #1,d2                   | adust group number
     736                move.w  d1,d0                   | extract group
     737                andi.w  #0x000F,d0              | ...
     738                cmp.w   d0,d2                   | see if we display
     739                bne     dsexit                  | jump if not
     740
     741                lsr.w   #4,d1                   | extract variable number
     742                andi.w  #0x000F,d1              | ...
     743                move.w  d1,-(a7)                | save variable number
     744                move.w  d1,d0                   | calculate display offset
     745                lsl.w   #3,d0                   | ... (var | 9) + 8
     746                add.w   d0,d1                   | ... in d1
     747                addi.w  #8,d1                   | ...
     748                move.w  E_DN(a0),d0             | get value
     749                asr.w   #5,d0                   | adjust to low 11 bits
     750                bpl     dsanvl1                 | jump if positive
     751
     752                move.b  #'-',numstr             | set sign = '-'
     753                neg.w   d0                      | make value positive
    754754                bra     dsanvl2
    755 *
    756 dsanvl1:        move.b  #'+',numstr             * set sign = '+'
    757 *
    758                 .page
    759 dsanvl2:        ext.l   d0                      * convert MS digit
    760                 divu    #1000,d0                * ...
    761                 add.w   #$0030,d0               * ...
    762                 move.b  d0,numstr+1             * ...
    763                 swap    d0                      * convert middle digit
    764                 ext.l   d0                      * ...
    765                 divu    #100,d0                 * ...
    766                 add.w   #$0030,d0               * ...
    767                 move.b  d0,numstr+2             * ...
    768                 move.b  #'.',numstr+3           * insert decimal point
    769                 swap    d0                      * convert LS digit
    770                 ext.l   d0                      * ...
    771                 divu    #10,d0                  * ...
    772                 add.w   #$0030,d0               * ...
    773                 move.b  d0,numstr+4             * ...
    774                 clr.b   numstr+5                * terminate string
    775                 move.w  #AT12,-(a7)             * put attribute on stack
    776                 move.l  #numstr,-(a7)           * put buffer address on stack
    777                 move.w  d1,-(a7)                * put column on stack
    778                 move.w  #7,-(a7)                * put row on stack
    779                 move.l  _obj8,-(a7)             * put sbase on stack
    780                 jsr     _vputs                  * update the screen
    781                 add.l   #14,a7                  * clean up stack
    782                 move.w  (a7)+,d0                * get variable number
    783                 bset    d0,_vrbw14+1            * set variable bit
    784                 bset    #6,_vrcw                * set video reset type bit
    785                 tst.w   _ctrsw                  * update center for scupd ?
    786                 beq     dsexit                  * done if not
    787 *
    788 dsanvl0:        move.l  _gdfsep,d0              * quit if no elements left
    789                 beq     dsexit                  * ...
    790 *
    791                 movea.l d0,a1                   * a1 = gdsp
    792                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    793                 move.w  #52,d2                  * d2 = event PRIORITY * 4
    794                 movea.l P_SL(a6),a2             * a2 points at gdstb
    795                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    796                 move.w  #$9999,G_NOTE(a1)       * gdsp->note = COLOR
    797                 move.w  #6,G_CODE(a1)           * gdsp->code = PATTERN
    798                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    799                 bra     dsexit                  * done
    800 *
    801                 .page
    802 *
    803 * dsasgn -- display assignment
    804 * ------    ------------------
    805 dsasgn:         tst.w   P_CF(a6)                * center update ?
    806                 beq     dsasgn0                 * jump if not
    807 *
    808                 move.l  a0,-(a7)                * stash a0
    809                 jsr     _mpcupd                 * update changed stuff
    810                 movea.l (a7)+,a0                * restore a0
    811                 clr.w   d1                      * get assignment
    812                 move.b  E_DATA1(a0),d1          * ... from the event
    813                 ext.l   d1                      * ... as a long in d1
    814                 divu    #10,d1                  * divide by 10 for conversion
    815                 add.l   #$00300030,d1           * add '0' for ASCII conversion
    816                 move.b  d1,numstr               * put MS byte in work area
    817                 swap    d1                      * swap register halves
    818                 move.b  d1,numstr+1             * put LS byte in work area
    819                 clr.b   numstr+2                * terminate string
    820                 move.w  #AT04,-(a7)             * put attribute on stack
    821                 move.l  #numstr,-(a7)           * put buffer address on stack
    822                 move.w  #11,-(a7)               * put column on stack
    823                 move.w  #1,-(a7)                * put row on stack
    824                 move.l  _obj8,-(a7)             * put sbase on stack
    825                 jsr     _vputs                  * update the screen
    826                 add.l   #14,a7                  * clean up stack
    827                 bset    #0,_vrcw+1              * set video reset type bit
    828                 tst.w   _ctrsw                  * update center for scupd ?
    829                 beq     dsexit                  * done if not
    830 *
    831 dsasgn0:        move.l  _gdfsep,d0              * quit if no elements left
    832                 beq     dsexit                  * ...
    833 *
    834                 movea.l d0,a1                   * a1 = gdsp
    835                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    836                 move.w  #56,d2                  * d2 = event PRIORITY * 4
    837                 movea.l P_SL(a6),a2             * a2 points at gdstb
    838                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    839                 move.w  #$3333,G_NOTE(a1)       * gdsp->note = COLOR
    840                 move.w  #3,G_CODE(a1)           * gdsp->code = PATTERN
    841                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    842                 bra     dsexit                  * done
    843 *
    844                 .page
    845 *
    846 * dstmpo -- display tempo
    847 * ------    -------------
    848 dstmpo:         tst.w   P_CF(a6)                * center update ?
    849                 beq     dstmpo0                 * jump if not
    850 *
    851                 clr.w   d1                      * get tempo
    852                 move.b  E_DATA1(a0),d1          * ... from event
    853                 ext.l   d1                      * ... as a long in d1
    854                 divu    #10,d1                  * divide by 10 for conversion
    855                 swap    d1                      * swap register halves
    856                 add.w   #$0030,d1               * add '0' for ASCII conversion
    857                 move.b  d1,numstr+2             * put LS byte in work area
    858                 swap    d1                      * swap register halves
    859                 ext.l   d1                      * divide again
    860                 divu    #10,d1                  * ...
    861                 add.l   #$00300030,d1           * add '0' for ASCII conversion
    862                 move.b  d1,numstr               * put MS byte in work area
    863                 swap    d1                      * swap register halves
    864                 move.b  d1,numstr+1             * put middle byte in work area
    865                 clr.b   numstr+3                * terminate string
    866                 move.w  #AT06,-(a7)             * put attribute on stack
    867                 move.l  #numstr,-(a7)           * put buffer address on stack
    868                 move.w  #27,-(a7)               * put column on stack
    869                 move.w  #1,-(a7)                * put row on stack
    870                 move.l  _obj8,-(a7)             * put sbase on stack
    871                 jsr     _vputs                  * display tempo
    872                 add.l   #14,a7                  * clean up stack
    873                 bset    #2,_vrcw+1              * set video reset type bit
    874                 tst.w   _ctrsw                  * update center for scupd ?
    875                 beq     dsexit                  * done if not
    876 *
    877 dstmpo0:        move.l  _gdfsep,d0              * quit if no elements left
    878                 beq     dsexit                  * ...
    879 *
    880                 movea.l d0,a1                   * a1 = gdsp
    881                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    882                 move.w  #56,d2                  * d2 = event PRIORITY * 4
    883                 movea.l P_SL(a6),a2             * a2 points at gdstb
    884                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    885                 move.w  #$3333,G_NOTE(a1)       * gdsp->note = COLOR
    886                 move.w  #4,G_CODE(a1)           * gdsp->code = PATTERN
    887                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    888                 bra     dsexit                  * done
    889 *
    890                 .page
    891 *
    892 * dsstop -- display stop
    893 * ------    ------------
    894 dsstop:         tst.w   P_CF(a6)                * center update ?
    895                 beq     dsstop0                 * jump if not
    896 *
    897                 jsr     _dclkmd                 * show that clock is stopped
    898                 move.w  #AT08,-(a7)             * put attribute on stack
    899                 move.w  #40,-(a7)               * put 1st column on stack
    900                 move.w  #1,-(a7)                * put row on stack
    901                 move.l  _obj8,-(a7)             * put sbase on stack
    902                 jsr     _vputa                  * hilite first column
    903                 move.w  #41,COL(a7)             * put 2nd column on stack
    904                 jsr     _vputa                  * hilite second column
    905                 move.w  #42,COL(a7)             * put 3rd column on stack
    906                 jsr     _vputa                  * hilite third column
    907                 move.w  #43,COL(a7)             * put 4th column on stack
    908                 jsr     _vputa                  * hilite fourth column
    909                 add.l   #10,a7                  * clean up stack
    910                 bset    #7,_vrcw                * set video reset type bits
    911                 bset    #0,_vrbw15              * ...
    912                 tst.w   _ctrsw                  * update center for scupd ?
    913                 beq     dsexit                  * done if not
    914 *
    915 dsstop0:        move.l  _gdfsep,d0              * quit if no elements left
    916                 beq     dsexit                  * ...
    917 *
    918                 movea.l d0,a1                   * a1 = gdsp
    919                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    920                 move.w  #56,d2                  * d2 = event PRIORITY * 4
    921                 movea.l P_SL(a6),a2             * a2 points at gdstb
    922                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    923                 move.w  #$3333,G_NOTE(a1)       * gdsp->note = COLOR
    924                 move.w  #5,G_CODE(a1)           * gdsp->code = PATTERN
    925                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    926                 bra     dsexit                  * done
    927 *
    928                 .page
    929 *
    930 * dsnext -- display next
    931 * ------    ------------
    932 dsnext:         tst.w   P_CF(a6)                * center update ?
    933                 beq     dsnext0                 * jump if not
    934 *
    935                 move.w  #AT08,-(a7)             * put attribute on stack
    936                 move.w  #45,-(a7)               * put 1st column on stack
    937                 move.w  #1,-(a7)                * put row on stack
    938                 move.l  _obj8,-(a7)             * put sbase on stack
    939                 jsr     _vputa                  * hilite first column
    940                 move.w  #46,COL(a7)             * put 2nd column on stack
    941                 jsr     _vputa                  * hilite second column
    942                 move.w  #47,COL(a7)             * put 3rd column on stack
    943                 jsr     _vputa                  * hilite third column
    944                 move.w  #48,COL(a7)             * put 4th column on stack
    945                 jsr     _vputa                  * hilite fourth column
    946                 add.l   #10,a7                  * clean up stack
    947                 bset    #7,_vrcw                * set video reset type bits
    948                 bset    #1,_vrbw15              * ...
    949                 tst.w   _ctrsw                  * update center for scupd ?
    950                 beq     dsexit                  * done if not
    951 *
    952 dsnext0:        move.l  _gdfsep,d0              * quit if no elements left
    953                 beq     dsexit                  * ...
    954 *
    955                 movea.l d0,a1                   * a1 = gdsp
    956                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    957                 move.w  #56,d2                  * d2 = event PRIORITY * 4
    958                 movea.l P_SL(a6),a2             * a2 points at gdstb
    959                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    960                 move.w  #$3333,G_NOTE(a1)       * gdsp->note = COLOR
    961                 move.w  #5,G_CODE(a1)           * gdsp->code = PATTERN
    962                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    963                 bra     dsexit                  * done
    964 *
    965                 .page
    966 *
    967 * dsgrp -- display group status
    968 * -----    --------------------
    969 dsgrp:          tst.w   P_CF(a6)                * center update ?
    970                 beq     dsgrp0                  * jump if not
    971 *
    972                 tst.w   _ctrsw                  * update center for scupd ?
    973                 beq     dsexit                  * done if not
    974 *
    975 dsgrp0:         move.l  _gdfsep,d0              * quit if no elements left
    976                 beq     dsexit                  * ...
    977 *
    978                 movea.l d0,a1                   * a1 = gdsp
    979                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    980                 move.w  #60,d2                  * d2 = event PRIORITY * 4
    981                 movea.l P_SL(a6),a2             * a2 points at gdstb
    982                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    983                 move.w  #$9999,G_NOTE(a1)       * gdsp->note = COLOR
    984                 move.w  #3,G_CODE(a1)           * gdsp->code = PATTERN
    985                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    986                 bra     dsexit                  * done
    987 *
    988                 .page
    989 *
    990 * dsinst -- display instrument
    991 * ------    ------------------
    992 dsinst:         clr.w   d0                      * get group number
    993                 move.b  E_DATA1(a0),d0          * ... in d0
    994                 add.w   d0,d0                   * ... as a word offset
    995                 lea     _grpstat,a1             * check grpstat[grp]
    996                 tst.w   0(a1,d0.W)              * ...
    997                 beq     dsexit                  * done if not enabled
    998 *
    999                 tst.w   P_CF(a6)                * center update ?
    1000                 beq     dsins00                 * jump if not
    1001 *
    1002                 lea     _ins2grp,a1             * point at ins2grp[]
    1003                 clr.w   d0                      * get instrument number
    1004                 move.b  E_DATA2(a0),d0          * ... in d0
    1005                 move.w  d0,-(a7)                * save instrument number
    1006                 clr.w   d1                      * get group number
    1007                 move.b  E_DATA1(a0),d1          * ... in d1
    1008                 move.w  d1,-(a7)                * save group number
    1009                 move.w  (a7),d0                 * col = group number
    1010                 add.w   d0,d0                   * ... * 5
    1011                 add.w   d0,d0                   * ...
    1012                 move.w  (a7)+,d2                * ...  (d2 = group number)
    1013                 add.w   d2,d0                   * ...
    1014                 add.w   #7,d0                   * ... + 7
    1015                 clr.l   d1                      * get instrument number
    1016                 move.w  (a7)+,d1                * ... as a long in d1
    1017                 divu    #10,d1                  * divide by 10 for conversion
    1018                 add.l   #$00300030,d1           * add '0' for ASCII conversion
    1019                 move.b  d1,numstr               * put MS byte in work area
    1020                 swap    d1                      * swap register halves
    1021                 move.b  d1,numstr+1             * put LS byte in work area
    1022                 clr.b   numstr+2                * terminate string
    1023                 move.w  d2,-(a7)                * save group number
    1024                 move.w  #AT11,-(a7)             * put attribute on stack
    1025                 move.l  #numstr,-(a7)           * put buffer address on stack
    1026                 move.w  d0,-(a7)                * put column on stack
    1027                 move.w  #2,-(a7)                * put row on stack
    1028                 move.l  _obj8,-(a7)             * put object address on stack
    1029                 jsr     _vputs                  * update the screen
    1030                 add.l   #14,a7                  * clean up stack
    1031 *
    1032                 .page
    1033                 move.w  (a7)+,d0                * get group number
    1034                 cmp.w   #8,d0                   * see which word it's in
    1035                 bcc     dsinst1                 * jump if in MS word
    1036 *
    1037                 bset    d0,_vrbw08+1            * set group bit in LS byte
    1038                 bra     dsinst2                 * ...
    1039 *
    1040 dsinst1:        sub.w   #8,d0                   * adjust for for byte
    1041                 bset    d0,_vrbw08              * set group bit in MS byte
    1042 *
    1043 dsinst2:        bset    #0,_vrcw                * set video reset type bit
    1044                 tst.w   _ctrsw                  * update center for scupd ?
    1045                 beq     dsexit                  * done if not
    1046 *
    1047 dsins00:        move.l  _gdfsep,d0              * quit if no elements left
    1048                 beq     dsexit                  * ...
    1049 *
    1050                 movea.l d0,a1                   * a1 = gdsp
    1051                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    1052                 move.w  #60,d2                  * d2 = event PRIORITY * 4
    1053                 movea.l P_SL(a6),a2             * a2 points at gdstb
    1054                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    1055                 move.w  #$9999,G_NOTE(a1)       * gdsp->note = COLOR
    1056                 move.w  #3,G_CODE(a1)           * gdsp->code = PATTERN
    1057                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    1058                 bra     dsexit                  * done
    1059 *
    1060                 .page
    1061 *
    1062 * dsintp -- display interpolation
    1063 * ------    ---------------------
    1064 dsintp:         tst.w   P_CF(a6)                * center update ?
    1065                 beq     dsintp0                 * jump if not
    1066 *
    1067                 move.w  E_DATA1(a0),-(a7)       * get interpolate value
    1068                 jsr     _fromfpu                * convert to milliseconds
    1069                 tst.w   (a7)+                   * ...
    1070                 andi.l  #$0000FFFF,d0           * clear high bits
    1071                 divu    #10000,d0               * convert 1st digit
    1072                 addi.w  #$0030,d0               * ... to ASCII
    1073                 move.b  d0,numstr               * ... in numstr
    1074                 swap    d0                      * convert 2nd digit
    1075                 ext.l   d0                      * ...
    1076                 divu    #1000,d0                * ...
    1077                 addi.w  #$0030,d0               * ... to ASCII
    1078                 move.b  d0,numstr+1             * ... in numstr
    1079                 move.b  #'.',numstr+2           * insert decimal point
    1080                 swap    d0                      * convert 3rd digit
    1081                 ext.l   d0                      * ...
    1082                 divu    #100,d0                 * ...
    1083                 addi.w  #$0030,d0               * ... to ASCII
    1084                 move.b  d0,numstr+3             * ... in numstr
    1085                 clr.b   numstr+4                * terminate numstr
    1086                 move.w  #AT07,-(a7)             * vputs(obj8, 1, 35, numstr, AT07)
    1087                 move.l  #numstr,-(a7)           * ...
    1088                 move.w  #35,-(a7)               * ...
    1089                 move.w  #1,-(a7)                * ...
    1090                 move.l  _obj8,-(a7)             * ...
    1091                 jsr     _vputs                  * ...
    1092                 add.l   #14,a7                  * ...
    1093                 bset    #3,_vrcw+1              * set video reset bit
    1094                 tst.w   _ctrsw                  * update center for scupd ?
    1095                 beq     dsexit                  * done if not
    1096 *
    1097 dsintp0:        move.l  _gdfsep,d0              * quit if no elements left
    1098                 beq     dsexit                  * ...
    1099 *
    1100                 movea.l d0,a1                   * a1 = gdsp
    1101                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    1102                 move.w  #60,d2                  * d2 = event PRIORITY * 4
    1103                 movea.l P_SL(a6),a2             * a2 points at gdstb
    1104                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    1105                 move.w  #$CCCC,G_NOTE(a1)       * gdsp->note = COLOR
    1106                 move.w  #4,G_CODE(a1)           * gdsp->code = PATTERN
    1107                 move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    1108                 bra     dsexit                  * done
    1109 *
    1110                 .page
    1111 *
    1112 * dspnch -- display punch in/out
    1113 * ------    --------------------
    1114 dspnch:         tst.w   P_CF(a6)                * center update ?
    1115                 beq     dspnch0                 * jump if not
    1116 *
    1117                 tst.w   E_DATA1(a0)             * punch in ?
    1118                 beq     dspnch1                 * jump if not
    1119 *
    1120                 move.w  #AT09,-(a7)             * put attribute on stack
    1121                 move.w  #50,-(a7)               * put 1st col on stack
    1122                 move.w  #1,-(a7)                * put row on stack
    1123                 move.l  _obj8,-(a7)             * put object address on stack
    1124                 jsr     _vputa                  * highlight 1st column
    1125                 move.w  #51,COL(a7)             * put 2nd col on stack
    1126                 jsr     _vputa                  * highlight 2nd col
    1127                 add.l   #10,a7                  * clean up stack
    1128                 bset    #5,_vrcw+1              * set video reset bit
    1129                 bra     dspnch2                 * go do maker update
    1130 *
    1131 dspnch1:        move.w  #AT09,-(a7)             * put attribute on stack
    1132                 move.w  #53,-(a7)               * put 1st col on stack
    1133                 move.w  #1,-(a7)                * put row on stack
    1134                 move.l  _obj8,-(a7)             * put object address on stack
    1135                 jsr     _vputa                  * highlight 1st column
    1136                 move.w  #54,COL(a7)             * put 2nd col on stack
    1137                 jsr     _vputa                  * highlight 2nd column
    1138                 move.w  #55,COL(a7)             * put 3rd col on stack
    1139                 jsr     _vputa                  * highlight 3rd column
    1140                 add.l   #10,a7                  * clean up stack
    1141                 bset    #6,_vrcw+1              * set video reset bit
    1142 *
    1143 dspnch2:        jsr     _dsgmodz                * display updated modes
    1144                 tst.w   _ctrsw                  * update center for scupd ?
    1145                 beq     dsexit                  * done if not
    1146 *
    1147 dspnch0:        move.l  _gdfsep,d0              * quit if no elements left
    1148                 beq     dsexit                  * ...
    1149 *
    1150                 movea.l d0,a1                   * a1 = gdsp
    1151                 move.l  G_NEXT(a1),_gdfsep      * gdfsep = gdsp->next
    1152                 move.w  #60,d2                  * d2 = event PRIORITY * 4
    1153                 movea.l P_SL(a6),a2             * a2 points at gdstb
    1154                 move.l  0(a2,d2.W),G_NEXT(a1)   * gdsp->next = gdstb[pri]
    1155                 move.w  #$CCCC,G_NOTE(a1)       * gdsp->note = COLOR
    1156                 tst.w   E_DATA1(a0)             * see which kind we have
    1157                 bne     dspnchi                 * jump if 'punch in'
    1158 *
    1159                 move.w  #6,G_CODE(a1)           * gdsp->code = 'out' PATTERN
     755
     756dsanvl1:        move.b  #'+',numstr             | set sign = '+'
     757
     758                .page
     759dsanvl2:        ext.l   d0                      | convert MS digit
     760                divu    #1000,d0                | ...
     761                add.w   #0x0030,d0              | ...
     762                move.b  d0,numstr+1             | ...
     763                swap    d0                      | convert middle digit
     764                ext.l   d0                      | ...
     765                divu    #100,d0                 | ...
     766                add.w   #0x0030,d0              | ...
     767                move.b  d0,numstr+2             | ...
     768                move.b  #'.',numstr+3           | insert decimal point
     769                swap    d0                      | convert LS digit
     770                ext.l   d0                      | ...
     771                divu    #10,d0                  | ...
     772                add.w   #0x0030,d0              | ...
     773                move.b  d0,numstr+4             | ...
     774                clr.b   numstr+5                | terminate string
     775                move.w  #AT12,-(a7)             | put attribute on stack
     776                move.l  #numstr,-(a7)           | put buffer address on stack
     777                move.w  d1,-(a7)                | put column on stack
     778                move.w  #7,-(a7)                | put row on stack
     779                move.l  _obj8,-(a7)             | put sbase on stack
     780                jsr     _vputs                  | update the screen
     781                add.l   #14,a7                  | clean up stack
     782                move.w  (a7)+,d0                | get variable number
     783                bset    d0,_vrbw14+1            | set variable bit
     784                bset    #6,_vrcw                | set video reset type bit
     785                tst.w   _ctrsw                  | update center for scupd ?
     786                beq     dsexit                  | done if not
     787
     788dsanvl0:        move.l  _gdfsep,d0              | quit if no elements left
     789                beq     dsexit                  | ...
     790
     791                movea.l d0,a1                   | a1 = gdsp
     792                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     793                move.w  #52,d2                  | d2 = event PRIORITY | 4
     794                movea.l P_SL(a6),a2             | a2 points at gdstb
     795                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     796                move.w  #0x9999,G_NOTE(a1)      | gdsp->note = COLOR
     797                move.w  #6,G_CODE(a1)           | gdsp->code = PATTERN
     798                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     799                bra     dsexit                  | done
     800
     801                .page
     802
     803| dsasgn -- display assignment
     804| ------    ------------------
     805dsasgn:         tst.w   P_CF(a6)                | center update ?
     806                beq     dsasgn0                 | jump if not
     807
     808                move.l  a0,-(a7)                | stash a0
     809                jsr     _mpcupd                 | update changed stuff
     810                movea.l (a7)+,a0                | restore a0
     811                clr.w   d1                      | get assignment
     812                move.b  E_DATA1(a0),d1          | ... from the event
     813                ext.l   d1                      | ... as a long in d1
     814                divu    #10,d1                  | divide by 10 for conversion
     815                add.l   #0x00300030,d1          | add '0' for ASCII conversion
     816                move.b  d1,numstr               | put MS byte in work area
     817                swap    d1                      | swap register halves
     818                move.b  d1,numstr+1             | put LS byte in work area
     819                clr.b   numstr+2                | terminate string
     820                move.w  #AT04,-(a7)             | put attribute on stack
     821                move.l  #numstr,-(a7)           | put buffer address on stack
     822                move.w  #11,-(a7)               | put column on stack
     823                move.w  #1,-(a7)                | put row on stack
     824                move.l  _obj8,-(a7)             | put sbase on stack
     825                jsr     _vputs                  | update the screen
     826                add.l   #14,a7                  | clean up stack
     827                bset    #0,_vrcw+1              | set video reset type bit
     828                tst.w   _ctrsw                  | update center for scupd ?
     829                beq     dsexit                  | done if not
     830
     831dsasgn0:        move.l  _gdfsep,d0              | quit if no elements left
     832                beq     dsexit                  | ...
     833
     834                movea.l d0,a1                   | a1 = gdsp
     835                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     836                move.w  #56,d2                  | d2 = event PRIORITY | 4
     837                movea.l P_SL(a6),a2             | a2 points at gdstb
     838                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     839                move.w  #0x3333,G_NOTE(a1)      | gdsp->note = COLOR
     840                move.w  #3,G_CODE(a1)           | gdsp->code = PATTERN
     841                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     842                bra     dsexit                  | done
     843
     844                .page
     845
     846| dstmpo -- display tempo
     847| ------    -------------
     848dstmpo:         tst.w   P_CF(a6)                | center update ?
     849                beq     dstmpo0                 | jump if not
     850
     851                clr.w   d1                      | get tempo
     852                move.b  E_DATA1(a0),d1          | ... from event
     853                ext.l   d1                      | ... as a long in d1
     854                divu    #10,d1                  | divide by 10 for conversion
     855                swap    d1                      | swap register halves
     856                add.w   #0x0030,d1              | add '0' for ASCII conversion
     857                move.b  d1,numstr+2             | put LS byte in work area
     858                swap    d1                      | swap register halves
     859                ext.l   d1                      | divide again
     860                divu    #10,d1                  | ...
     861                add.l   #0x00300030,d1          | add '0' for ASCII conversion
     862                move.b  d1,numstr               | put MS byte in work area
     863                swap    d1                      | swap register halves
     864                move.b  d1,numstr+1             | put middle byte in work area
     865                clr.b   numstr+3                | terminate string
     866                move.w  #AT06,-(a7)             | put attribute on stack
     867                move.l  #numstr,-(a7)           | put buffer address on stack
     868                move.w  #27,-(a7)               | put column on stack
     869                move.w  #1,-(a7)                | put row on stack
     870                move.l  _obj8,-(a7)             | put sbase on stack
     871                jsr     _vputs                  | display tempo
     872                add.l   #14,a7                  | clean up stack
     873                bset    #2,_vrcw+1              | set video reset type bit
     874                tst.w   _ctrsw                  | update center for scupd ?
     875                beq     dsexit                  | done if not
     876
     877dstmpo0:        move.l  _gdfsep,d0              | quit if no elements left
     878                beq     dsexit                  | ...
     879
     880                movea.l d0,a1                   | a1 = gdsp
     881                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     882                move.w  #56,d2                  | d2 = event PRIORITY | 4
     883                movea.l P_SL(a6),a2             | a2 points at gdstb
     884                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     885                move.w  #0x3333,G_NOTE(a1)      | gdsp->note = COLOR
     886                move.w  #4,G_CODE(a1)           | gdsp->code = PATTERN
     887                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     888                bra     dsexit                  | done
     889
     890                .page
     891
     892| dsstop -- display stop
     893| ------    ------------
     894dsstop:         tst.w   P_CF(a6)                | center update ?
     895                beq     dsstop0                 | jump if not
     896
     897                jsr     _dclkmd                 | show that clock is stopped
     898                move.w  #AT08,-(a7)             | put attribute on stack
     899                move.w  #40,-(a7)               | put 1st column on stack
     900                move.w  #1,-(a7)                | put row on stack
     901                move.l  _obj8,-(a7)             | put sbase on stack
     902                jsr     _vputa                  | hilite first column
     903                move.w  #41,COL(a7)             | put 2nd column on stack
     904                jsr     _vputa                  | hilite second column
     905                move.w  #42,COL(a7)             | put 3rd column on stack
     906                jsr     _vputa                  | hilite third column
     907                move.w  #43,COL(a7)             | put 4th column on stack
     908                jsr     _vputa                  | hilite fourth column
     909                add.l   #10,a7                  | clean up stack
     910                bset    #7,_vrcw                | set video reset type bits
     911                bset    #0,_vrbw15              | ...
     912                tst.w   _ctrsw                  | update center for scupd ?
     913                beq     dsexit                  | done if not
     914
     915dsstop0:        move.l  _gdfsep,d0              | quit if no elements left
     916                beq     dsexit                  | ...
     917
     918                movea.l d0,a1                   | a1 = gdsp
     919                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     920                move.w  #56,d2                  | d2 = event PRIORITY | 4
     921                movea.l P_SL(a6),a2             | a2 points at gdstb
     922                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     923                move.w  #0x3333,G_NOTE(a1)      | gdsp->note = COLOR
     924                move.w  #5,G_CODE(a1)           | gdsp->code = PATTERN
     925                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     926                bra     dsexit                  | done
     927
     928                .page
     929
     930| dsnext -- display next
     931| ------    ------------
     932dsnext:         tst.w   P_CF(a6)                | center update ?
     933                beq     dsnext0                 | jump if not
     934
     935                move.w  #AT08,-(a7)             | put attribute on stack
     936                move.w  #45,-(a7)               | put 1st column on stack
     937                move.w  #1,-(a7)                | put row on stack
     938                move.l  _obj8,-(a7)             | put sbase on stack
     939                jsr     _vputa                  | hilite first column
     940                move.w  #46,COL(a7)             | put 2nd column on stack
     941                jsr     _vputa                  | hilite second column
     942                move.w  #47,COL(a7)             | put 3rd column on stack
     943                jsr     _vputa                  | hilite third column
     944                move.w  #48,COL(a7)             | put 4th column on stack
     945                jsr     _vputa                  | hilite fourth column
     946                add.l   #10,a7                  | clean up stack
     947                bset    #7,_vrcw                | set video reset type bits
     948                bset    #1,_vrbw15              | ...
     949                tst.w   _ctrsw                  | update center for scupd ?
     950                beq     dsexit                  | done if not
     951
     952dsnext0:        move.l  _gdfsep,d0              | quit if no elements left
     953                beq     dsexit                  | ...
     954
     955                movea.l d0,a1                   | a1 = gdsp
     956                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     957                move.w  #56,d2                  | d2 = event PRIORITY | 4
     958                movea.l P_SL(a6),a2             | a2 points at gdstb
     959                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     960                move.w  #0x3333,G_NOTE(a1)      | gdsp->note = COLOR
     961                move.w  #5,G_CODE(a1)           | gdsp->code = PATTERN
     962                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     963                bra     dsexit                  | done
     964
     965                .page
     966
     967| dsgrp -- display group status
     968| -----    --------------------
     969dsgrp:          tst.w   P_CF(a6)                | center update ?
     970                beq     dsgrp0                  | jump if not
     971
     972                tst.w   _ctrsw                  | update center for scupd ?
     973                beq     dsexit                  | done if not
     974
     975dsgrp0:         move.l  _gdfsep,d0              | quit if no elements left
     976                beq     dsexit                  | ...
     977
     978                movea.l d0,a1                   | a1 = gdsp
     979                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     980                move.w  #60,d2                  | d2 = event PRIORITY | 4
     981                movea.l P_SL(a6),a2             | a2 points at gdstb
     982                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     983                move.w  #0x9999,G_NOTE(a1)      | gdsp->note = COLOR
     984                move.w  #3,G_CODE(a1)           | gdsp->code = PATTERN
     985                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     986                bra     dsexit                  | done
     987
     988                .page
     989
     990| dsinst -- display instrument
     991| ------    ------------------
     992dsinst:         clr.w   d0                      | get group number
     993                move.b  E_DATA1(a0),d0          | ... in d0
     994                add.w   d0,d0                   | ... as a word offset
     995                lea     _grpstat,a1             | check grpstat[grp]
     996                tst.w   0(a1,d0.W)              | ...
     997                beq     dsexit                  | done if not enabled
     998
     999                tst.w   P_CF(a6)                | center update ?
     1000                beq     dsins00                 | jump if not
     1001
     1002                lea     _ins2grp,a1             | point at ins2grp[]
     1003                clr.w   d0                      | get instrument number
     1004                move.b  E_DATA2(a0),d0          | ... in d0
     1005                move.w  d0,-(a7)                | save instrument number
     1006                clr.w   d1                      | get group number
     1007                move.b  E_DATA1(a0),d1          | ... in d1
     1008                move.w  d1,-(a7)                | save group number
     1009                move.w  (a7),d0                 | col = group number
     1010                add.w   d0,d0                   | ... | 5
     1011                add.w   d0,d0                   | ...
     1012                move.w  (a7)+,d2                | ...  (d2 = group number)
     1013                add.w   d2,d0                   | ...
     1014                add.w   #7,d0                   | ... + 7
     1015                clr.l   d1                      | get instrument number
     1016                move.w  (a7)+,d1                | ... as a long in d1
     1017                divu    #10,d1                  | divide by 10 for conversion
     1018                add.l   #0x00300030,d1          | add '0' for ASCII conversion
     1019                move.b  d1,numstr               | put MS byte in work area
     1020                swap    d1                      | swap register halves
     1021                move.b  d1,numstr+1             | put LS byte in work area
     1022                clr.b   numstr+2                | terminate string
     1023                move.w  d2,-(a7)                | save group number
     1024                move.w  #AT11,-(a7)             | put attribute on stack
     1025                move.l  #numstr,-(a7)           | put buffer address on stack
     1026                move.w  d0,-(a7)                | put column on stack
     1027                move.w  #2,-(a7)                | put row on stack
     1028                move.l  _obj8,-(a7)             | put object address on stack
     1029                jsr     _vputs                  | update the screen
     1030                add.l   #14,a7                  | clean up stack
     1031
     1032                .page
     1033                move.w  (a7)+,d0                | get group number
     1034                cmp.w   #8,d0                   | see which word it's in
     1035                bcc     dsinst1                 | jump if in MS word
     1036
     1037                bset    d0,_vrbw08+1            | set group bit in LS byte
     1038                bra     dsinst2                 | ...
     1039
     1040dsinst1:        sub.w   #8,d0                   | adjust for for byte
     1041                bset    d0,_vrbw08              | set group bit in MS byte
     1042
     1043dsinst2:        bset    #0,_vrcw                | set video reset type bit
     1044                tst.w   _ctrsw                  | update center for scupd ?
     1045                beq     dsexit                  | done if not
     1046
     1047dsins00:        move.l  _gdfsep,d0              | quit if no elements left
     1048                beq     dsexit                  | ...
     1049
     1050                movea.l d0,a1                   | a1 = gdsp
     1051                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     1052                move.w  #60,d2                  | d2 = event PRIORITY | 4
     1053                movea.l P_SL(a6),a2             | a2 points at gdstb
     1054                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     1055                move.w  #0x9999,G_NOTE(a1)      | gdsp->note = COLOR
     1056                move.w  #3,G_CODE(a1)           | gdsp->code = PATTERN
     1057                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     1058                bra     dsexit                  | done
     1059
     1060                .page
     1061
     1062| dsintp -- display interpolation
     1063| ------    ---------------------
     1064dsintp:         tst.w   P_CF(a6)                | center update ?
     1065                beq     dsintp0                 | jump if not
     1066
     1067                move.w  E_DATA1(a0),-(a7)       | get interpolate value
     1068                jsr     _fromfpu                | convert to milliseconds
     1069                tst.w   (a7)+                   | ...
     1070                andi.l  #0x0000FFFF,d0          | clear high bits
     1071                divu    #10000,d0               | convert 1st digit
     1072                addi.w  #0x0030,d0              | ... to ASCII
     1073                move.b  d0,numstr               | ... in numstr
     1074                swap    d0                      | convert 2nd digit
     1075                ext.l   d0                      | ...
     1076                divu    #1000,d0                | ...
     1077                addi.w  #0x0030,d0              | ... to ASCII
     1078                move.b  d0,numstr+1             | ... in numstr
     1079                move.b  #'.',numstr+2           | insert decimal point
     1080                swap    d0                      | convert 3rd digit
     1081                ext.l   d0                      | ...
     1082                divu    #100,d0                 | ...
     1083                addi.w  #0x0030,d0              | ... to ASCII
     1084                move.b  d0,numstr+3             | ... in numstr
     1085                clr.b   numstr+4                | terminate numstr
     1086                move.w  #AT07,-(a7)             | vputs(obj8, 1, 35, numstr, AT07)
     1087                move.l  #numstr,-(a7)           | ...
     1088                move.w  #35,-(a7)               | ...
     1089                move.w  #1,-(a7)                | ...
     1090                move.l  _obj8,-(a7)             | ...
     1091                jsr     _vputs                  | ...
     1092                add.l   #14,a7                  | ...
     1093                bset    #3,_vrcw+1              | set video reset bit
     1094                tst.w   _ctrsw                  | update center for scupd ?
     1095                beq     dsexit                  | done if not
     1096
     1097dsintp0:        move.l  _gdfsep,d0              | quit if no elements left
     1098                beq     dsexit                  | ...
     1099
     1100                movea.l d0,a1                   | a1 = gdsp
     1101                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     1102                move.w  #60,d2                  | d2 = event PRIORITY | 4
     1103                movea.l P_SL(a6),a2             | a2 points at gdstb
     1104                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     1105                move.w  #0xCCCC,G_NOTE(a1)      | gdsp->note = COLOR
     1106                move.w  #4,G_CODE(a1)           | gdsp->code = PATTERN
     1107                move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     1108                bra     dsexit                  | done
     1109
     1110                .page
     1111
     1112| dspnch -- display punch in/out
     1113| ------    --------------------
     1114dspnch:         tst.w   P_CF(a6)                | center update ?
     1115                beq     dspnch0                 | jump if not
     1116
     1117                tst.w   E_DATA1(a0)             | punch in ?
     1118                beq     dspnch1                 | jump if not
     1119
     1120                move.w  #AT09,-(a7)             | put attribute on stack
     1121                move.w  #50,-(a7)               | put 1st col on stack
     1122                move.w  #1,-(a7)                | put row on stack
     1123                move.l  _obj8,-(a7)             | put object address on stack
     1124                jsr     _vputa                  | highlight 1st column
     1125                move.w  #51,COL(a7)             | put 2nd col on stack
     1126                jsr     _vputa                  | highlight 2nd col
     1127                add.l   #10,a7                  | clean up stack
     1128                bset    #5,_vrcw+1              | set video reset bit
     1129                bra     dspnch2                 | go do maker update
     1130
     1131dspnch1:        move.w  #AT09,-(a7)             | put attribute on stack
     1132                move.w  #53,-(a7)               | put 1st col on stack
     1133                move.w  #1,-(a7)                | put row on stack
     1134                move.l  _obj8,-(a7)             | put object address on stack
     1135                jsr     _vputa                  | highlight 1st column
     1136                move.w  #54,COL(a7)             | put 2nd col on stack
     1137                jsr     _vputa                  | highlight 2nd column
     1138                move.w  #55,COL(a7)             | put 3rd col on stack
     1139                jsr     _vputa                  | highlight 3rd column
     1140                add.l   #10,a7                  | clean up stack
     1141                bset    #6,_vrcw+1              | set video reset bit
     1142
     1143dspnch2:        jsr     _dsgmodz                | display updated modes
     1144                tst.w   _ctrsw                  | update center for scupd ?
     1145                beq     dsexit                  | done if not
     1146
     1147dspnch0:        move.l  _gdfsep,d0              | quit if no elements left
     1148                beq     dsexit                  | ...
     1149
     1150                movea.l d0,a1                   | a1 = gdsp
     1151                move.l  G_NEXT(a1),_gdfsep      | gdfsep = gdsp->next
     1152                move.w  #60,d2                  | d2 = event PRIORITY | 4
     1153                movea.l P_SL(a6),a2             | a2 points at gdstb
     1154                move.l  0(a2,d2.W),G_NEXT(a1)   | gdsp->next = gdstb[pri]
     1155                move.w  #0xCCCC,G_NOTE(a1)      | gdsp->note = COLOR
     1156                tst.w   E_DATA1(a0)             | see which kind we have
     1157                bne     dspnchi                 | jump if 'punch in'
     1158
     1159                move.w  #6,G_CODE(a1)           | gdsp->code = 'out' PATTERN
    11601160                bra     dspnchx
    1161 *
    1162 dspnchi:        move.w  #5,G_CODE(a1)           * gdsp->code = 'in' PATTERN
    1163 *
    1164 dspnchx:        move.l  a1,0(a2,d2.W)           * gdstb[pri] = gdsp
    1165                 bra     dsexit                  * done
    1166 *
    1167                 .page
    1168 *
    1169 * dsbar -- display a bar marker
    1170 * -----    --------------------
    1171 dsbar:          tst.w   P_CF(a6)                * center update ?
    1172                 beq     dsbar0                  * jump if not
    1173 *
    1174                 tst.w   _ctrsw                  * update center for scupd ?
    1175                 beq     dsexit                  * done if not
    1176 *
    1177 dsbar0:         movea.l P_SL(a6),a2             * a2 points at gdstb
    1178                 move.l  #-1,BARFLAG(a2)         * set the bar marker flag
    1179                 bra     dsexit                  * done
    1180 *
    1181                 .page
    1182 *
    1183 * ==============================================================================
     1161
     1162dspnchi:        move.w  #5,G_CODE(a1)           | gdsp->code = 'in' PATTERN
     1163
     1164dspnchx:        move.l  a1,0(a2,d2.W)           | gdstb[pri] = gdsp
     1165                bra     dsexit                  | done
     1166
     1167                .page
     1168
     1169| dsbar -- display a bar marker
     1170| -----    --------------------
     1171dsbar:          tst.w   P_CF(a6)                | center update ?
     1172                beq     dsbar0                  | jump if not
     1173
     1174                tst.w   _ctrsw                  | update center for scupd ?
     1175                beq     dsexit                  | done if not
     1176
     1177dsbar0:         movea.l P_SL(a6),a2             | a2 points at gdstb
     1178                move.l  #-1,BARFLAG(a2)         | set the bar marker flag
     1179                bra     dsexit                  | done
     1180
     1181                .page
     1182
     1183| ==============================================================================
    11841184                .data
    1185 * ==============================================================================
    1186 *
    1187 * sddtab -- score display dispatch table -- MUST match score.h definitions
    1188 * ------    ----------------------------    ------------------------------
    1189 sddtab:         dc.l    dsexit          * 0     null
    1190                 dc.l    dsexit          * 1     score begin
    1191                 dc.l    dssbgn          * 2     section begin
    1192                 dc.l    dssend          * 3     section end
    1193                 dc.l    dsinst          * 4     instrument change
    1194                 dc.l    dsnbx           * 5     note begin
    1195                 dc.l    dsnex           * 6     note end
    1196                 dc.l    dsstop          * 7     stop
    1197                 dc.l    dsintp          * 8     interpolate
    1198                 dc.l    dstmpo          * 9     tempo
    1199                 dc.l    dstune          * 10    tuning
    1200                 dc.l    dsgrp           * 11    group status
    1201                 dc.l    dslocn          * 12    location
    1202                 dc.l    dsdyn           * 13    dynamics
    1203                 dc.l    dsanvl          * 14    analog value
    1204                 dc.l    dsanrs          * 15    analog resolution
    1205                 dc.l    dsasgn          * 16    I/O assign
    1206                 dc.l    dstrns          * 17    transposition
    1207                 dc.l    dsexit          * 18    repeat
    1208                 dc.l    dspnch          * 19    punch in/out
    1209                 dc.l    dsexit          * 20    polyphonic pressure
    1210                 dc.l    dsexit          * 21    score end
    1211                 dc.l    dsexit          * 22    channel pressure
    1212                 dc.l    dsbar           * 23    bar marker
    1213                 dc.l    dsnext          * 24    next score
    1214 *
    1215 * ==============================================================================
     1185| ==============================================================================
     1186
     1187| sddtab -- score display dispatch table -- MUST match score.h definitions
     1188| ------    ----------------------------    ------------------------------
     1189sddtab:         dc.l    dsexit          | 0     null
     1190                dc.l    dsexit          | 1     score begin
     1191                dc.l    dssbgn          | 2     section begin
     1192                dc.l    dssend          | 3     section end
     1193                dc.l    dsinst          | 4     instrument change
     1194                dc.l    dsnbx           | 5     note begin
     1195                dc.l    dsnex           | 6     note end
     1196                dc.l    dsstop          | 7     stop
     1197                dc.l    dsintp          | 8     interpolate
     1198                dc.l    dstmpo          | 9     tempo
     1199                dc.l    dstune          | 10    tuning
     1200                dc.l    dsgrp           | 11    group status
     1201                dc.l    dslocn          | 12    location
     1202                dc.l    dsdyn           | 13    dynamics
     1203                dc.l    dsanvl          | 14    analog value
     1204                dc.l    dsanrs          | 15    analog resolution
     1205                dc.l    dsasgn          | 16    I/O assign
     1206                dc.l    dstrns          | 17    transposition
     1207                dc.l    dsexit          | 18    repeat
     1208                dc.l    dspnch          | 19    punch in/out
     1209                dc.l    dsexit          | 20    polyphonic pressure
     1210                dc.l    dsexit          | 21    score end
     1211                dc.l    dsexit          | 22    channel pressure
     1212                dc.l    dsbar           | 23    bar marker
     1213                dc.l    dsnext          | 24    next score
     1214
     1215| ==============================================================================
    12161216                .bss
    1217 * ==============================================================================
    1218 *
    1219 * globals:
    1220 * --------
    1221 _ac_code:       ds.b    1               * accidental code
    1222 *
    1223 * locals:
    1224 * -------
    1225 numstr:         ds.b    65              * video display update work area
    1226 *
    1227 * ------------------------------------------------------------------------------
    1228 *
     1217| ==============================================================================
     1218
     1219| globals:
     1220| --------
     1221_ac_code:       ds.b    1               | accidental code
     1222
     1223| locals:
     1224| -------
     1225numstr:         ds.b    65              | video display update work area
     1226
     1227| ------------------------------------------------------------------------------
     1228
    12291229                .end
  • ram/seexec.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * seexec.s -- score event execution driver
    3 * Version 40 -- 1988-10-06 -- D.N. Lynx Crowe
    4 *
    5 *       struct s_entry *
    6 *       se_exec(ep, sd)
    7 *       struct s_entry *ep;
    8 *       short sd;
    9 *
    10 *               Executes the event at 'ep', scrolling in direction 'sd'.
    11 *
    12 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| seexec.s -- score event execution driver
     3| Version 40 -- 1988-10-06 -- D.N. Lynx Crowe
     4
     5|       struct s_entry |
     6|       se_exec(ep, sd)
     7|       struct s_entry |ep;
     8|       short sd;
     9
     10|               Executes the event at 'ep', scrolling in direction 'sd'.
     11
     12| ------------------------------------------------------------------------------
    1313                .text
    14 *
     14
    1515                .xdef   _se_exec
    16 *
     16
    1717                .xdef   BadEvnt
    18 *
     18
    1919                .xdef   _xevent
    20 *
     20
    2121                .xref   _asgvce
    2222                .xref   _clkset
     
    3131                .xref   _settune
    3232                .xref   _setv2gi
    33 *
     33
    3434                .xref   _anrs
    3535                .xref   _var2src
     
    4848                .xref   _vce2trg
    4949                .xref   _veltab
    50 *
    51                 .page
    52 *
    53 * parameter offsets
    54 * -----------------
    55 P_EP            .equ    8               * WORD - 'ep' parameter offset
    56 P_SD            .equ    12              * WORD - 'sd' parameter offset
    57 *
    58 * event structure offsets -- MUST match score.h definitions
    59 * -----------------------    ------------------------------
    60 *                     offset             length
    61 *                     ------             ------
    62 E_TIME          .equ    0               * LONG
    63 E_SIZE          .equ    4               * BYTE
    64 E_TYPE          .equ    5               * BYTE
    65 E_DATA1         .equ    6               * BYTE
    66 E_NOTE          .equ    6               * BYTE
    67 E_DATA2         .equ    7               * BYTE
    68 E_GROUP         .equ    7               * BYTE
    69 E_BAK           .equ    8               * LONG
    70 E_FWD           .equ    12              * LONG
    71 E_DN            .equ    16              * LONG
    72 E_VEL           .equ    16              * WORD
    73 E_DATA4         .equ    18              * WORD
    74 E_UP            .equ    20              * LONG
    75 E_LFT           .equ    24              * LONG
    76 E_RGT           .equ    28              * LONG
    77 *
    78 * Miscellaneous constants
    79 * -----------------------
    80 N_ETYPES        .equ    25              * number of event types
    81 *
    82 M_KSTATE        .equ    $01             * keys status bit
    83 N_KSTATE        .equ    $FE             * keys status bit complement
    84 *
    85 D_BAK           .equ    1               * code for backward scrolling
    86 *
    87 LCL_PRT         .equ    2               * 0-origin local port number
    88 LCL_PCH         .equ    $1080           * port and channel for trigger
    89 *
    90                 .page
    91 *
    92 * A few words about se_exec:
    93 *
    94 * se_exec has to be very fast, so it's written in assembly language,
    95 * rather than C, which is usually pretty good, but not quite good enough
    96 * for this application.  The faster this routine runs, the higher the
    97 * tempo we can keep up with.  If this code is fast enough, we end up
    98 * hardware limited by the timer.
    99 *
    100 _se_exec:       link    a6,#0                   * link stack frames
    101                 movea.l P_EP(a6),a0             * get event pointer 'ep' into a0
    102                 move.l  a0,_xevent              * save in xevent
    103                 move.b  E_TYPE(a0),d1           * get event type into d1.W
    104                 andi.w  #$007F,d1               * ... and mask off new-data flag
    105                 cmp.b   #N_ETYPES,d1            * see if it's valid
    106                 blt     sexc1                   * jump if it is
    107 *
    108 BadEvnt:        move.l  a0,d0                   * setup to return pointer we got
    109                 bra     done                    * exit
    110 *
    111 exexit:         movea.l _xevent,a0              * point at next event
    112                 move.l  E_FWD(a0),d0            * ...
    113 *
    114 done:           unlk    a6                      * done -- unlink stack frames
    115                 rts                             * return to caller
    116 *
    117 sexc1:          lea     sextab,a1               * get base of dispatch table
    118                 lsl.w   #2,d1                   * multiplty event by 4 for index
    119                 movea.l 0(a1,d1.W),a2           * get address of event routine
    120                 jmp     (a2)                    * jump to event execution routine
    121 *
    122 * On entry, the individual execution routines only depend on a0 pointing at the
    123 * event they were dispatched for.
    124 *
    125 * The usual C function register usage conventions apply:
    126 *
    127 * d0..d2 and a0..a2 are used for scratch, and are not preserved.
    128 *
    129 * d3..d6 and a3..a5 are register variables, and are preserved.
    130 * a6 = frame pointer, a7 = stack pointer, and are preserved.
    131 *
    132                 .page
    133 *
    134 * exnbeg -- execute note begin
    135 * ------    ------------------
    136 * If things need to be sped up, we could incorporate the functions of
    137 * asgvce() here, rather than calling it.  asgvce() could also be re-written in
    138 * assembly language to make it a shade faster.
    139 *
    140 exnbeg:         cmpi.w  #D_BAK,P_SD(a6)         * check direction
    141                 beq     nendex                  * if backward, treat as note end
    142 *
    143 nbegex:         clr.w   d1                      * clear d1
    144                 move.b  E_GROUP(a0),d1          * get group number
    145                 add.w   d1,d1                   * ... * 2
    146                 lea     _grpstat,a1             * point at grpstat
    147                 tst.w   0(a1,d1.W)              * see if group is enabled
    148                 beq     exexit                  * done if not
    149 *
    150                 move.b  E_NOTE(a0),d1           * d1 = note number nn (0..127)
    151                 move.w  #LCL_PCH,d2             * put port and channel in d2
    152                 add.w   d1,d2                   * d2 = trg
    153                 lea     _trgtab,a1              * point at trgtab[trg]
    154                 move.b  0(a1,d2.W),d0           * ...
    155                 or.b    #M_KSTATE,d0            * set trigger table entry on
    156                 move.b  d0,0(a1,d2.W)           * ...
    157                 lea     _veltab,a1              * point at veltab
    158                 add.w   d2,d2                   * ...
    159                 move.w  E_VEL(a0),0(a1,d2.W)    * put velocity in veltab
    160                 move.w  E_VEL(a0),-(a7)         * put velocity on the stack
    161                 move.w  d1,-(a7)                * put note number on the stack
    162                 move.w  #1,-(a7)                * put channel on the stack
    163                 move.w  #LCL_PRT,-(a7)          * put port on the stack
    164                 move.b  E_GROUP(a0),d1          * d1 = group number  (0..11)
    165                 move.w  d1,-(a7)                * put group number on the stack
    166                 jsr     _asgvce                 * start the note
    167                 add.l   #10,a7                  * clean up the stack           
    168                 bra     exexit                  * done
    169 *
    170                 .page
    171 *
    172 * exnend -- execute note end
    173 * ------    ----------------
    174 * If things need to be sped up, we could incorporate the functions of
    175 * procpfl() here, rather than calling it.  procpfl() could also be re-written in
    176 * assembly language to make it a shade faster.
    177 *
    178 exnend:         cmpi.w  #D_BAK,P_SD(a6)         * check direction
    179                 beq     nbegex                  * if backward, treat as beginning
    180 *
    181 nendex:         clr.w   d1                      * clear d1
    182                 move.b  E_GROUP(a0),d1          * get group number
    183                 add.w   d1,d1                   * ... * 2
    184                 lea     _grpstat,a1             * point at grpstat
    185                 tst.w   0(a1,d1.W)              * check group status
    186                 beq     exexit                  * done if disabled
    187 *
    188                 move.b  E_NOTE(a0),d1           * d1 = note number nn (0..127)
    189                 move.w  #LCL_PCH,d2             * put port and channel in d2
    190                 add.w   d1,d2                   * d2 = trg * 2
    191                 add.w   d2,d2                   * ...
    192                 lea     _trgtab,a1              * set trigger table entry off
    193                 move.b  0(a1,d2.W),d0           * ...
    194                 and.b   #N_KSTATE,d0            * ...
    195                 move.b  d0,0(a1,d2.W)           * ...
    196                 bne     exexit                  * done if note still active
    197 *
    198                 .page
    199 *
    200                 lsr.w   #1,d2                   * adjust d2
    201                 clr.w   d1                      * set loop index
    202                 lea     _vce2trg,a2             * point at vce2trg table
    203 *
    204 exnend1:        cmp.w   (a2),d2                 * see if this voice uses trg
    205                 bne     exnend2                 * jump if not
    206 *
    207                 move.w  #-1,(a2)                * set entry to -1
    208                 move.l  a2,-(a7)                * save a2 on stack
    209                 move.w  d1,-(a7)                * save d1 on stack
    210                 move.w  d2,-(a7)                * save d2 on stack
    211                 lea     _vce2grp,a1             * put group on stack
    212                 move.w  d1,d0                   * ...
    213                 add.w   d0,d0                   * ...
    214                 move.w  0(a1,d0.W),-(a7)        * ...
    215                 move.w  d2,-(a7)                * put trg on stack
    216                 jsr     _procpfl                * process sustained voices
    217                 addq.l  #4,a7                   * clean up stack
    218                 move.w  (a7)+,d2                * restore d2
    219                 move.w  (a7)+,d1                * restore d1
    220                 movea.l (a7)+,a2                * restore a2
    221 *
    222 exnend2:        addq.l  #2,a2                   * point at next vce2trg entry
    223                 addq.w  #1,d1                   * loop until all are checked
    224                 cmp.w   #12,d1                  * ...
    225                 bne     exnend1                 * ...
    226 *
    227                 bra     exexit                  * done
    228 *
    229                 .page
    230 *
    231 * exsbgn -- execute section begin
    232 * ------    ---------------------
    233 exsbgn:         clr.w   d0                      * get section number
    234                 move.b  E_DATA1(a0),d0          * ...
    235                 move.w  d0,_cursect             * set section number
    236                 bra     exexit                  * done
    237 *
    238 * exasgn -- execute assignment event
    239 * ------    ------------------------
    240 exasgn:         clr.w   d0                      * get assignment
    241                 move.b  E_DATA1(a0),d0          * ...
    242                 move.w  d0,-(a7)                * getasg(curasg = asgn)
    243                 move.w  d0,_curasg              * ...
    244                 jsr     _getasg                 * ...
    245                 tst.w   (a7)+                   * ...
    246                 bra     exexit                  * done
    247 *
    248 * extune -- execute tuning event
    249 * ------    --------------------
    250 extune:         clr.w   d0                      * get tuning
    251                 move.b  E_DATA1(a0),d0          * ...
    252                 move.w  d0,-(a7)                * gettun(tuning)
    253                 jsr     _gettun                 * ...
    254                 tst.w   (a7)+                   * ...
    255                 bra     exexit                  * done
    256 *
    257 * extrns -- execute transposition event
    258 * ------    ---------------------------
    259 extrns:         clr.w   d0                      * get group number
    260                 move.b  E_DATA1(a0),d0          * ...
    261                 add.w   d0,d0                   * ... as an index in d0
    262                 lea     _grpstat,a1             * check grpstat[grp]
    263                 tst.w   0(a1,d0.W)              * ...
    264                 beq     exexit                  * done if disabled
    265 *
    266                 lea     _s_trns,a1              * set group transposition
    267                 move.w  E_LFT(a0),0(a1,d0.W)    * ...
    268                 jsr     _settune                * ...
    269                 bra     exexit                  * done
    270 *
    271                 .page
    272 *
    273 * extmpo -- execute tempo event
    274 * ------    -------------------
    275 extmpo:         clr.w   d0                      * get tempo
    276                 move.b  E_DATA1(a0),d0          * ...
    277                 move.w  d0,-(a7)                * settmpo(tempo)
    278                 jsr     _settmpo                * ...
    279                 tst.w   (a7)+                   * ...
    280                 bra     exexit                  * done
    281 *
    282 * exstop -- execute stop event
    283 * ------    ------------------
    284 exstop:         clr.w   -(a7)                   * stop the clock
    285                 jsr     _clkset                 * ...
    286                 tst.w   (a7)+                   * ...
    287                 bra     exexit                  * that's all, folks
    288 *
    289 * exintp -- execute interpolate event
    290 * ------    -------------------------
    291 exintp:         move.w  E_DATA1(a0),_curintp    * set interpolate value
    292                 bra     exexit                  * done
    293 *
    294                 .page
    295 *
    296 * exinst -- execute instrument change event
    297 * ------    -------------------------------
    298 exinst:         clr.w   d0                      * get group number
    299                 move.b  E_DATA1(a0),d0          * ... in d0
    300                 add.w   d0,d0                   * ... as a word offset
    301                 lea     _grpstat,a1             * check grpstat[grp]
    302                 tst.w   0(a1,d0.W)              * ...
    303                 beq     exexit                  * done if not enabled
    304 *
    305                 lea     _ins2grp,a1             * point at ins2grp[]
    306                 clr.w   d0                      * get instrument number
    307                 move.b  E_DATA2(a0),d0          * ... in d0
    308                 clr.w   d1                      * get group number
    309                 move.b  E_DATA1(a0),d1          * ... in d1
    310                 move.w  d1,-(a7)                * put group number on stack
    311                 add.w   d1,d1                   * make d1 a word pointer
    312                 move.w  0(a1,d1.W),d2           * get ins2grp[group]
    313                 and.w   #$FF00,d2               * mask off GTAG1..GTAG8
    314                 or.w    d0,d2                   * OR in new instrument number
    315                 move.w  d2,0(a1,d1.W)           * set ins2grp[group]
    316                 jsr     _setv2gi                * setv2gi(group)
    317                 tst.w   (a7)+                   * clean up stack
    318                 bra     exexit                  * done
    319 *
    320                 .page
    321 *
    322 * exdyn -- execute dynamics event
    323 * -----    ----------------------
    324 exdyn:          clr.w   d0                      * get group number
    325                 move.b  E_DATA1(a0),d0          * ... in d0
    326                 add.w   d0,d0                   * ... as a word offset
    327                 lea     _grpstat,a1             * check grpstat[grp]
    328                 tst.w   0(a1,d0.W)              * ...
    329                 beq     exexit                  * done if not enabled
    330 *
    331                 clr.w   d0                      * get dynamics
    332                 move.b  E_DATA2(a0),d0          * ... in d0
    333                 clr.w   d1                      * get group number
    334                 move.b  E_DATA1(a0),d1          * ... in d1
    335                 move.w  d0,-(a7)                * setdyn(group, dyn)
    336                 move.w  d1,-(a7)                * ...
    337                 jsr     _setdyn                 * ...
    338                 adda.l  #4,a7                   * clean up stack
    339                 bra     exexit                  * done
    340 *
    341 * exlocn -- execute location event
    342 * ------    ----------------------
    343 exlocn:         clr.w   d0                      * get group number
    344                 move.b  E_DATA1(a0),d0          * ... in d0
    345                 add.w   d0,d0                   * ... as a word offset
    346                 lea     _grpstat,a1             * check grpstat[grp]
    347                 tst.w   0(a1,d0.W)              * ...
    348                 beq     exexit                  * done if not enabled
    349 *
    350                 clr.w   d0                      * get location
    351                 move.b  E_DATA2(a0),d0          * ... in d0
    352                 clr.w   d1                      * get group number
    353                 move.b  E_DATA1(a0),d1          * ... in d1
    354                 move.w  d0,-(a7)                * setloc(group, loc)
    355                 move.w  d1,-(a7)                * ...
    356                 jsr     _setloc                 * ...
    357                 adda.l  #4,a7                   * clean up stack
    358                 bra     exexit                  * done
    359 *
    360                 .page
    361 *
    362 * exanrs -- execute analog resolution event
    363 * ------    -------------------------------
    364 exanrs:         move.b  E_DATA1(a0),d0          * get group number
    365                 andi.w  #$000F,d0               * ... in d0
    366                 add.w   d0,d0                   * ... as a word offset
    367                 lea     _grpstat,a1             * check grpstat[grp]
    368                 tst.w   0(a1,d0.W)              * ...
    369                 beq     exexit                  * done if not enabled
    370 *
    371                 clr.w   d1                      * get variable / group numbers
    372                 move.b  E_DATA1(a0),d1          * ...
    373                 add.w   d1,d1                   * convert to word index
    374                 clr.w   d0                      * get resolution
    375                 move.b  E_DATA2(a0),d0          * ... in d0
    376                 lea     _anrs,a1                * point at resolution table base
    377                 move.w  d0,0(a1,d1.W)           * save resolution in table
    378                 bra     exexit                  * done
    379 *
    380 * exanvl -- execute analog value event
    381 * ------    --------------------------
    382 exanvl:         move.b  E_DATA1(a0),d0          * get group number
    383                 andi.w  #$000F,d0               * ... in d0
    384                 add.w   d0,d0                   * ... as a word offset
    385                 lea     _grpstat,a1             * check grpstat[grp]
    386                 tst.w   0(a1,d0.W)              * ...
    387                 beq     exexit                  * done if not enabled
    388 *
    389                 move.w  E_DN(a0),-(a7)          * put value on stack
    390                 clr.w   d2                      * get variable / group numbers
    391                 move.b  E_DATA1(a0),d2          * ... into d2
    392                 move.w  d2,d1                   * extract group number
    393                 andi.w  #$000F,d1               * ... into d1
    394                 lsr.w   #3,d2                   * extract variable number
    395                 andi.w  #$001E,d2               * ... as a word index in d2
    396                 lea     _var2src,a1             * point at variable map
    397                 move.w  0(a1,d2.W),-(a7)        * put source number on stack
    398                 move.w  d1,-(a7)                * put group number on stack
    399                 jsr     _setsv                  * setsv(group, src, val)
    400                 adda.l  #6,a7                   * clean up stack
    401                 bra     exexit                  * done
    402 *
    403 * exnext -- next score
    404 * ------    ----------
    405 exnext:         move.w  #1,_nxtflag             * set next score flag
    406                 bra     exexit                  * done
    407 *
    408                 .page
    409 *
    410 * expnch -- execute punch in/out
    411 * ------    --------------------
    412 expnch:         tst.w   _recsw                  * recording ?
    413                 beq     exexit                  * ignore if not
    414 *
    415                 tst.w   E_DATA1(a0)             * punch in ?
    416                 bne     expnch5                 * jump if so
    417 *
    418 * punch out
    419 *
    420                 lea     _grpmode,a1             * setup for group modes
    421                 move.w  #11,d0                  * ...
    422 *
    423 expnch0:        cmpi.w  #2,(a1)                 * in record mode ?
    424                 bne     expnch1                 * jump if not
    425 *
    426                 clr.w   (a1)                    * set to play mode
    427 *
    428 expnch1:        addq.l  #2,a1                   * point at next entry
    429                 dbra    d0,expnch0              * loop through all groups
    430 *
    431                 lea     _varmode,a1             * setup for variable modes
    432                 move.w  #5,d1                   * set variable count
    433 *
    434 expnch4:        clr.w   d0                      * clear offset
    435 *
    436 expnch2:        cmpi.w  #2,0(a1,d0.W)           * in record mode ?
    437                 bne     expnch3                 * jump if not
    438 *
    439                 clr.w   0(a1,d0.W)              * set to play mode
    440 *
    441 expnch3:        addq.w  #2,d0                   * update offset
    442                 cmpi.w  #24,d0                  * check for final group
    443                 bne     expnch2                 * loop through all groups
    444 *
    445                 add.l   #32,a1                  * point at next variable
    446                 dbra    d1,expnch4              * loop through all variables
    447 *
     50
     51                .page
     52
     53| parameter offsets
     54| -----------------
     55P_EP            =       8               | WORD - 'ep' parameter offset
     56P_SD            =       12              | WORD - 'sd' parameter offset
     57
     58| event structure offsets -- MUST match score.h definitions
     59| -----------------------    ------------------------------
     60|                     offset             length
     61|                     ------             ------
     62E_TIME          =       0               | LONG
     63E_SIZE          =       4               | BYTE
     64E_TYPE          =       5               | BYTE
     65E_DATA1         =       6               | BYTE
     66E_NOTE          =       6               | BYTE
     67E_DATA2         =       7               | BYTE
     68E_GROUP         =       7               | BYTE
     69E_BAK           =       8               | LONG
     70E_FWD           =       12              | LONG
     71E_DN            =       16              | LONG
     72E_VEL           =       16              | WORD
     73E_DATA4         =       18              | WORD
     74E_UP            =       20              | LONG
     75E_LFT           =       24              | LONG
     76E_RGT           =       28              | LONG
     77
     78| Miscellaneous constants
     79| -----------------------
     80N_ETYPES        =       25              | number of event types
     81
     82M_KSTATE        =       0x01            | keys status bit
     83N_KSTATE        =       0xFE            | keys status bit complement
     84
     85D_BAK           =       1               | code for backward scrolling
     86
     87LCL_PRT         =       2               | 0-origin local port number
     88LCL_PCH         =       0x1080          | port and channel for trigger
     89
     90                .page
     91
     92| A few words about se_exec:
     93
     94| se_exec has to be very fast, so it's written in assembly language,
     95| rather than C, which is usually pretty good, but not quite good enough
     96| for this application.  The faster this routine runs, the higher the
     97| tempo we can keep up with.  If this code is fast enough, we end up
     98| hardware limited by the timer.
     99
     100_se_exec:       link    a6,#0                   | link stack frames
     101                movea.l P_EP(a6),a0             | get event pointer 'ep' into a0
     102                move.l  a0,_xevent              | save in xevent
     103                move.b  E_TYPE(a0),d1           | get event type into d1.W
     104                andi.w  #0x007F,d1              | ... and mask off new-data flag
     105                cmp.b   #N_ETYPES,d1            | see if it's valid
     106                blt     sexc1                   | jump if it is
     107
     108BadEvnt:        move.l  a0,d0                   | setup to return pointer we got
     109                bra     done                    | exit
     110
     111exexit:         movea.l _xevent,a0              | point at next event
     112                move.l  E_FWD(a0),d0            | ...
     113
     114done:           unlk    a6                      | done -- unlink stack frames
     115                rts                             | return to caller
     116
     117sexc1:          lea     sextab,a1               | get base of dispatch table
     118                lsl.w   #2,d1                   | multiplty event by 4 for index
     119                movea.l 0(a1,d1.W),a2           | get address of event routine
     120                jmp     (a2)                    | jump to event execution routine
     121
     122| On entry, the individual execution routines only depend on a0 pointing at the
     123| event they were dispatched for.
     124
     125| The usual C function register usage conventions apply:
     126
     127| d0..d2 and a0..a2 are used for scratch, and are not preserved.
     128
     129| d3..d6 and a3..a5 are register variables, and are preserved.
     130| a6 = frame pointer, a7 = stack pointer, and are preserved.
     131
     132                .page
     133
     134| exnbeg -- execute note begin
     135| ------    ------------------
     136| If things need to be sped up, we could incorporate the functions of
     137| asgvce() here, rather than calling it.  asgvce() could also be re-written in
     138| assembly language to make it a shade faster.
     139
     140exnbeg:         cmpi.w  #D_BAK,P_SD(a6)         | check direction
     141                beq     nendex                  | if backward, treat as note end
     142
     143nbegex:         clr.w   d1                      | clear d1
     144                move.b  E_GROUP(a0),d1          | get group number
     145                add.w   d1,d1                   | ... | 2
     146                lea     _grpstat,a1             | point at grpstat
     147                tst.w   0(a1,d1.W)              | see if group is enabled
     148                beq     exexit                  | done if not
     149
     150                move.b  E_NOTE(a0),d1           | d1 = note number nn (0..127)
     151                move.w  #LCL_PCH,d2             | put port and channel in d2
     152                add.w   d1,d2                   | d2 = trg
     153                lea     _trgtab,a1              | point at trgtab[trg]
     154                move.b  0(a1,d2.W),d0           | ...
     155                or.b    #M_KSTATE,d0            | set trigger table entry on
     156                move.b  d0,0(a1,d2.W)           | ...
     157                lea     _veltab,a1              | point at veltab
     158                add.w   d2,d2                   | ...
     159                move.w  E_VEL(a0),0(a1,d2.W)    | put velocity in veltab
     160                move.w  E_VEL(a0),-(a7)         | put velocity on the stack
     161                move.w  d1,-(a7)                | put note number on the stack
     162                move.w  #1,-(a7)                | put channel on the stack
     163                move.w  #LCL_PRT,-(a7)          | put port on the stack
     164                move.b  E_GROUP(a0),d1          | d1 = group number  (0..11)
     165                move.w  d1,-(a7)                | put group number on the stack
     166                jsr     _asgvce                 | start the note
     167                add.l   #10,a7                  | clean up the stack
     168                bra     exexit                  | done
     169
     170                .page
     171
     172| exnend -- execute note end
     173| ------    ----------------
     174| If things need to be sped up, we could incorporate the functions of
     175| procpfl() here, rather than calling it.  procpfl() could also be re-written in
     176| assembly language to make it a shade faster.
     177
     178exnend:         cmpi.w  #D_BAK,P_SD(a6)         | check direction
     179                beq     nbegex                  | if backward, treat as beginning
     180
     181nendex:         clr.w   d1                      | clear d1
     182                move.b  E_GROUP(a0),d1          | get group number
     183                add.w   d1,d1                   | ... | 2
     184                lea     _grpstat,a1             | point at grpstat
     185                tst.w   0(a1,d1.W)              | check group status
     186                beq     exexit                  | done if disabled
     187
     188                move.b  E_NOTE(a0),d1           | d1 = note number nn (0..127)
     189                move.w  #LCL_PCH,d2             | put port and channel in d2
     190                add.w   d1,d2                   | d2 = trg | 2
     191                add.w   d2,d2                   | ...
     192                lea     _trgtab,a1              | set trigger table entry off
     193                move.b  0(a1,d2.W),d0           | ...
     194                and.b   #N_KSTATE,d0            | ...
     195                move.b  d0,0(a1,d2.W)           | ...
     196                bne     exexit                  | done if note still active
     197
     198                .page
     199
     200                lsr.w   #1,d2                   | adjust d2
     201                clr.w   d1                      | set loop index
     202                lea     _vce2trg,a2             | point at vce2trg table
     203
     204exnend1:        cmp.w   (a2),d2                 | see if this voice uses trg
     205                bne     exnend2                 | jump if not
     206
     207                move.w  #-1,(a2)                | set entry to -1
     208                move.l  a2,-(a7)                | save a2 on stack
     209                move.w  d1,-(a7)                | save d1 on stack
     210                move.w  d2,-(a7)                | save d2 on stack
     211                lea     _vce2grp,a1             | put group on stack
     212                move.w  d1,d0                   | ...
     213                add.w   d0,d0                   | ...
     214                move.w  0(a1,d0.W),-(a7)        | ...
     215                move.w  d2,-(a7)                | put trg on stack
     216                jsr     _procpfl                | process sustained voices
     217                addq.l  #4,a7                   | clean up stack
     218                move.w  (a7)+,d2                | restore d2
     219                move.w  (a7)+,d1                | restore d1
     220                movea.l (a7)+,a2                | restore a2
     221
     222exnend2:        addq.l  #2,a2                   | point at next vce2trg entry
     223                addq.w  #1,d1                   | loop until all are checked
     224                cmp.w   #12,d1                  | ...
     225                bne     exnend1                 | ...
     226
     227                bra     exexit                  | done
     228
     229                .page
     230
     231| exsbgn -- execute section begin
     232| ------    ---------------------
     233exsbgn:         clr.w   d0                      | get section number
     234                move.b  E_DATA1(a0),d0          | ...
     235                move.w  d0,_cursect             | set section number
     236                bra     exexit                  | done
     237
     238| exasgn -- execute assignment event
     239| ------    ------------------------
     240exasgn:         clr.w   d0                      | get assignment
     241                move.b  E_DATA1(a0),d0          | ...
     242                move.w  d0,-(a7)                | getasg(curasg = asgn)
     243                move.w  d0,_curasg              | ...
     244                jsr     _getasg                 | ...
     245                tst.w   (a7)+                   | ...
     246                bra     exexit                  | done
     247
     248| extune -- execute tuning event
     249| ------    --------------------
     250extune:         clr.w   d0                      | get tuning
     251                move.b  E_DATA1(a0),d0          | ...
     252                move.w  d0,-(a7)                | gettun(tuning)
     253                jsr     _gettun                 | ...
     254                tst.w   (a7)+                   | ...
     255                bra     exexit                  | done
     256
     257| extrns -- execute transposition event
     258| ------    ---------------------------
     259extrns:         clr.w   d0                      | get group number
     260                move.b  E_DATA1(a0),d0          | ...
     261                add.w   d0,d0                   | ... as an index in d0
     262                lea     _grpstat,a1             | check grpstat[grp]
     263                tst.w   0(a1,d0.W)              | ...
     264                beq     exexit                  | done if disabled
     265
     266                lea     _s_trns,a1              | set group transposition
     267                move.w  E_LFT(a0),0(a1,d0.W)    | ...
     268                jsr     _settune                | ...
     269                bra     exexit                  | done
     270
     271                .page
     272
     273| extmpo -- execute tempo event
     274| ------    -------------------
     275extmpo:         clr.w   d0                      | get tempo
     276                move.b  E_DATA1(a0),d0          | ...
     277                move.w  d0,-(a7)                | settmpo(tempo)
     278                jsr     _settmpo                | ...
     279                tst.w   (a7)+                   | ...
     280                bra     exexit                  | done
     281
     282| exstop -- execute stop event
     283| ------    ------------------
     284exstop:         clr.w   -(a7)                   | stop the clock
     285                jsr     _clkset                 | ...
     286                tst.w   (a7)+                   | ...
     287                bra     exexit                  | that's all, folks
     288
     289| exintp -- execute interpolate event
     290| ------    -------------------------
     291exintp:         move.w  E_DATA1(a0),_curintp    | set interpolate value
     292                bra     exexit                  | done
     293
     294                .page
     295
     296| exinst -- execute instrument change event
     297| ------    -------------------------------
     298exinst:         clr.w   d0                      | get group number
     299                move.b  E_DATA1(a0),d0          | ... in d0
     300                add.w   d0,d0                   | ... as a word offset
     301                lea     _grpstat,a1             | check grpstat[grp]
     302                tst.w   0(a1,d0.W)              | ...
     303                beq     exexit                  | done if not enabled
     304
     305                lea     _ins2grp,a1             | point at ins2grp[]
     306                clr.w   d0                      | get instrument number
     307                move.b  E_DATA2(a0),d0          | ... in d0
     308                clr.w   d1                      | get group number
     309                move.b  E_DATA1(a0),d1          | ... in d1
     310                move.w  d1,-(a7)                | put group number on stack
     311                add.w   d1,d1                   | make d1 a word pointer
     312                move.w  0(a1,d1.W),d2           | get ins2grp[group]
     313                and.w   #0xFF00,d2              | mask off GTAG1..GTAG8
     314                or.w    d0,d2                   | OR in new instrument number
     315                move.w  d2,0(a1,d1.W)           | set ins2grp[group]
     316                jsr     _setv2gi                | setv2gi(group)
     317                tst.w   (a7)+                   | clean up stack
     318                bra     exexit                  | done
     319
     320                .page
     321
     322| exdyn -- execute dynamics event
     323| -----    ----------------------
     324exdyn:          clr.w   d0                      | get group number
     325                move.b  E_DATA1(a0),d0          | ... in d0
     326                add.w   d0,d0                   | ... as a word offset
     327                lea     _grpstat,a1             | check grpstat[grp]
     328                tst.w   0(a1,d0.W)              | ...
     329                beq     exexit                  | done if not enabled
     330
     331                clr.w   d0                      | get dynamics
     332                move.b  E_DATA2(a0),d0          | ... in d0
     333                clr.w   d1                      | get group number
     334                move.b  E_DATA1(a0),d1          | ... in d1
     335                move.w  d0,-(a7)                | setdyn(group, dyn)
     336                move.w  d1,-(a7)                | ...
     337                jsr     _setdyn                 | ...
     338                adda.l  #4,a7                   | clean up stack
     339                bra     exexit                  | done
     340
     341| exlocn -- execute location event
     342| ------    ----------------------
     343exlocn:         clr.w   d0                      | get group number
     344                move.b  E_DATA1(a0),d0          | ... in d0
     345                add.w   d0,d0                   | ... as a word offset
     346                lea     _grpstat,a1             | check grpstat[grp]
     347                tst.w   0(a1,d0.W)              | ...
     348                beq     exexit                  | done if not enabled
     349
     350                clr.w   d0                      | get location
     351                move.b  E_DATA2(a0),d0          | ... in d0
     352                clr.w   d1                      | get group number
     353                move.b  E_DATA1(a0),d1          | ... in d1
     354                move.w  d0,-(a7)                | setloc(group, loc)
     355                move.w  d1,-(a7)                | ...
     356                jsr     _setloc                 | ...
     357                adda.l  #4,a7                   | clean up stack
     358                bra     exexit                  | done
     359
     360                .page
     361
     362| exanrs -- execute analog resolution event
     363| ------    -------------------------------
     364exanrs:         move.b  E_DATA1(a0),d0          | get group number
     365                andi.w  #0x000F,d0              | ... in d0
     366                add.w   d0,d0                   | ... as a word offset
     367                lea     _grpstat,a1             | check grpstat[grp]
     368                tst.w   0(a1,d0.W)              | ...
     369                beq     exexit                  | done if not enabled
     370
     371                clr.w   d1                      | get variable / group numbers
     372                move.b  E_DATA1(a0),d1          | ...
     373                add.w   d1,d1                   | convert to word index
     374                clr.w   d0                      | get resolution
     375                move.b  E_DATA2(a0),d0          | ... in d0
     376                lea     _anrs,a1                | point at resolution table base
     377                move.w  d0,0(a1,d1.W)           | save resolution in table
     378                bra     exexit                  | done
     379
     380| exanvl -- execute analog value event
     381| ------    --------------------------
     382exanvl:         move.b  E_DATA1(a0),d0          | get group number
     383                andi.w  #0x000F,d0              | ... in d0
     384                add.w   d0,d0                   | ... as a word offset
     385                lea     _grpstat,a1             | check grpstat[grp]
     386                tst.w   0(a1,d0.W)              | ...
     387                beq     exexit                  | done if not enabled
     388
     389                move.w  E_DN(a0),-(a7)          | put value on stack
     390                clr.w   d2                      | get variable / group numbers
     391                move.b  E_DATA1(a0),d2          | ... into d2
     392                move.w  d2,d1                   | extract group number
     393                andi.w  #0x000F,d1              | ... into d1
     394                lsr.w   #3,d2                   | extract variable number
     395                andi.w  #0x001E,d2              | ... as a word index in d2
     396                lea     _var2src,a1             | point at variable map
     397                move.w  0(a1,d2.W),-(a7)        | put source number on stack
     398                move.w  d1,-(a7)                | put group number on stack
     399                jsr     _setsv                  | setsv(group, src, val)
     400                adda.l  #6,a7                   | clean up stack
     401                bra     exexit                  | done
     402
     403| exnext -- next score
     404| ------    ----------
     405exnext:         move.w  #1,_nxtflag             | set next score flag
     406                bra     exexit                  | done
     407
     408                .page
     409
     410| expnch -- execute punch in/out
     411| ------    --------------------
     412expnch:         tst.w   _recsw                  | recording ?
     413                beq     exexit                  | ignore if not
     414
     415                tst.w   E_DATA1(a0)             | punch in ?
     416                bne     expnch5                 | jump if so
     417
     418| punch out
     419
     420                lea     _grpmode,a1             | setup for group modes
     421                move.w  #11,d0                  | ...
     422
     423expnch0:        cmpi.w  #2,(a1)                 | in record mode ?
     424                bne     expnch1                 | jump if not
     425
     426                clr.w   (a1)                    | set to play mode
     427
     428expnch1:        addq.l  #2,a1                   | point at next entry
     429                dbra    d0,expnch0              | loop through all groups
     430
     431                lea     _varmode,a1             | setup for variable modes
     432                move.w  #5,d1                   | set variable count
     433
     434expnch4:        clr.w   d0                      | clear offset
     435
     436expnch2:        cmpi.w  #2,0(a1,d0.W)           | in record mode ?
     437                bne     expnch3                 | jump if not
     438
     439                clr.w   0(a1,d0.W)              | set to play mode
     440
     441expnch3:        addq.w  #2,d0                   | update offset
     442                cmpi.w  #24,d0                  | check for final group
     443                bne     expnch2                 | loop through all groups
     444
     445                add.l   #32,a1                  | point at next variable
     446                dbra    d1,expnch4              | loop through all variables
     447
    448448                bra     exexit
    449 *
    450                 .page
    451 *
    452 * punch in
    453 *
    454 expnch5:        lea     _grpmode,a1             * setup for group modes
    455                 move.w  #11,d0                  * ...
    456 *
    457 expnch6:        cmpi.w  #1,(a1)                 * in standby mode ?
    458                 bne     expnch7                 * jump if not
    459 *
    460                 move.w  #2,(a1)                 * set to record mode
    461 *
    462 expnch7:        addq.l  #2,a1                   * point at next entry
    463                 dbra    d0,expnch6              * loop through all groups
    464 *
    465                 lea     _varmode,a1             * setup for variable modes
    466                 move.w  #5,d1                   * set variable count
    467 *
    468 expnch10:       clr.w   d0                      * clear offset
    469 *
    470 expnch8:        cmpi.w  #1,0(a1,d0.W)           * in standby mode ?
    471                 bne     expnch9                 * jump if not
    472 *
    473                 move.w  #2,0(a1,d0.W)           * set to record mode
    474 *
    475 expnch9:        addq.w  #2,d0                   * update offset
    476                 cmpi.w  #24,d0                  * check for final group
    477                 bne     expnch8                 * loop through all groups
    478 *
    479                 adda.l  #32,a1                  * point at next variable
    480                 dbra    d1,expnch10             * loop through all variables
    481 *
     449
     450                .page
     451
     452| punch in
     453
     454expnch5:        lea     _grpmode,a1             | setup for group modes
     455                move.w  #11,d0                  | ...
     456
     457expnch6:        cmpi.w  #1,(a1)                 | in standby mode ?
     458                bne     expnch7                 | jump if not
     459
     460                move.w  #2,(a1)                 | set to record mode
     461
     462expnch7:        addq.l  #2,a1                   | point at next entry
     463                dbra    d0,expnch6              | loop through all groups
     464
     465                lea     _varmode,a1             | setup for variable modes
     466                move.w  #5,d1                   | set variable count
     467
     468expnch10:       clr.w   d0                      | clear offset
     469
     470expnch8:        cmpi.w  #1,0(a1,d0.W)           | in standby mode ?
     471                bne     expnch9                 | jump if not
     472
     473                move.w  #2,0(a1,d0.W)           | set to record mode
     474
     475expnch9:        addq.w  #2,d0                   | update offset
     476                cmpi.w  #24,d0                  | check for final group
     477                bne     expnch8                 | loop through all groups
     478
     479                adda.l  #32,a1                  | point at next variable
     480                dbra    d1,expnch10             | loop through all variables
     481
    482482                bra     exexit
    483 *
    484                 .page
    485 *
    486 * sextab -- score execution dispatch table -- MUST match score.h definitions
    487 * ------    ----------------------------------------------------------------
    488 sextab:         dc.l    exexit          * 0     null
    489                 dc.l    exexit          * 1     score begin
    490                 dc.l    exsbgn          * 2     section begin
    491                 dc.l    exexit          * 3     section end
    492                 dc.l    exinst          * 4     instrument change
    493                 dc.l    exnbeg          * 5     note begin
    494                 dc.l    exnend          * 6     note end
    495                 dc.l    exstop          * 7     stop
    496                 dc.l    exintp          * 8     interpolate
    497                 dc.l    extmpo          * 9     tempo
    498                 dc.l    extune          * 10    tuning
    499                 dc.l    exexit          * 11    group status
    500                 dc.l    exlocn          * 12    location
    501                 dc.l    exdyn           * 13    dynamics
    502                 dc.l    exanvl          * 14    analog value
    503                 dc.l    exanrs          * 15    analog resolution
    504                 dc.l    exasgn          * 16    I/O assign
    505                 dc.l    extrns          * 17    transposition
    506                 dc.l    exexit          * 18    repeat
    507                 dc.l    expnch          * 19    punch in/out
    508                 dc.l    exexit          * 20    -unused- (polyphonic pressure)
    509                 dc.l    exexit          * 21    score end
    510                 dc.l    exexit          * 22    -unused- (channel pressure)
    511                 dc.l    exexit          * 23    bar marker
    512                 dc.l    exnext          * 24    next score
    513 *
     483
     484                .page
     485
     486| sextab -- score execution dispatch table -- MUST match score.h definitions
     487| ------    ----------------------------------------------------------------
     488sextab:         dc.l    exexit          | 0     null
     489                dc.l    exexit          | 1     score begin
     490                dc.l    exsbgn          | 2     section begin
     491                dc.l    exexit          | 3     section end
     492                dc.l    exinst          | 4     instrument change
     493                dc.l    exnbeg          | 5     note begin
     494                dc.l    exnend          | 6     note end
     495                dc.l    exstop          | 7     stop
     496                dc.l    exintp          | 8     interpolate
     497                dc.l    extmpo          | 9     tempo
     498                dc.l    extune          | 10    tuning
     499                dc.l    exexit          | 11    group status
     500                dc.l    exlocn          | 12    location
     501                dc.l    exdyn           | 13    dynamics
     502                dc.l    exanvl          | 14    analog value
     503                dc.l    exanrs          | 15    analog resolution
     504                dc.l    exasgn          | 16    I/O assign
     505                dc.l    extrns          | 17    transposition
     506                dc.l    exexit          | 18    repeat
     507                dc.l    expnch          | 19    punch in/out
     508                dc.l    exexit          | 20    -unused- (polyphonic pressure)
     509                dc.l    exexit          | 21    score end
     510                dc.l    exexit          | 22    -unused- (channel pressure)
     511                dc.l    exexit          | 23    bar marker
     512                dc.l    exnext          | 24    next score
     513
    514514                .bss
    515 *
    516 * Variable storage areas
    517 * ----------------------
    518 * globals:
    519 * --------
    520 _xevent:        ds.l    1               * next event pointer
    521 *
     515
     516| Variable storage areas
     517| ----------------------
     518| globals:
     519| --------
     520_xevent:        ds.l    1               | next event pointer
     521
    522522                .end
  • ram/serintr.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * serintr.s -- MIDAS-VII serial I/O subroutines
    3 * Version 4 -- 1988-12-13 -- D.N. Lynx Crowe
    4 *
    5 * These subroutines replace those in bios.s in order to add support for
    6 * MIDAS-VII foot pedal and pulse inputs, and pulse outputs.
    7 *
    8 * WARNING:  The code below uses addresses in the bios RAM area.  These addresses
    9 * correspond to those in PROMS dated 1988-06-20 et seq.  If the bios is changed,
    10 * the addresses marked with <== may have to be changed.
    11 * ------------------------------------------------------------------------------
    12 *
     1| ------------------------------------------------------------------------------
     2| serintr.s -- MIDAS-VII serial I/O subroutines
     3| Version 4 -- 1988-12-13 -- D.N. Lynx Crowe
     4
     5| These subroutines replace those in bios.s in order to add support for
     6| MIDAS-VII foot pedal and pulse inputs, and pulse outputs.
     7
     8| WARNING:  The code below uses addresses in the bios RAM area.  These addresses
     9| correspond to those in PROMS dated 1988-06-20 et seq.  If the bios is changed,
     10| the addresses marked with <== may have to be changed.
     11| ------------------------------------------------------------------------------
     12
    1313                .text
    14 *
     14
    1515                .xdef   _setsio
    16 *
     16
    1717                .xdef   _foot1
    1818                .xdef   _foot2
    1919                .xdef   _pulse1
    2020                .xdef   _pulse2
    21 *
     21
    2222                .xdef   serintr
    23 *
     23
    2424                .xdef   serint
    2525                .xdef   midint
    26 *
     26
    2727                .xdef   wrapin
    2828                .xdef   wrapout
    29 *
     29
    3030                .xdef   serput
    3131                .xdef   midput
    32 *
     32
    3333                .xdef   rtschk
    34 *
     34
    3535                .xdef   rtson
    3636                .xdef   rtsoff
    37 *
    38 * ==============================================================================
    39 *
    40 * The following addresses, marked by <==, are bios version dependent:
    41 *
    42 RAM             .equ    $00000400       * Beginning of system RAM area  <==
    43 *
    44 SR1IOREC        .equ    RAM+$0AB0       * Serial-1 iorec structure      <==
    45 SR2IOREC        .equ    RAM+$0AD8       * Serial-2 iorec structure      <==
    46 MC1IOREC        .equ    RAM+$0B00       * MIDI-1 iorec structure        <==
    47 MC2IOREC        .equ    RAM+$0B28       * MIDI-2 iorec structure        <==
    48 *
    49 * End of bios version dependent addresses.
    50 *
    51 * ==============================================================================
    52 *
    53                 .page
    54 *
    55 SERVECT         .equ    $000074         * Level 5 interrupt autovector address
    56 *
    57 IPL7            .equ    $0700           * IPL 7 value for sr
    58 *
    59 * ACIA I/O Addresses:
    60 * -------------------
    61 SR1ACIA         .equ    $3A8001         * Serial-1 ACIA base address
    62 SR2ACIA         .equ    $3A8009         * Serial-2 ACIA base address
    63 MC1ACIA         .equ    $3AC001         * MIDI-1 ACIA base address
    64 MC2ACIA         .equ    $3AC009         * MIDI-2 ACIA base address
    65 *
    66 * ACIA Register offsets:
    67 * ----------------------
    68 ACIA_IER        .equ    0               * ACIA IER offset
    69 ACIA_ISR        .equ    0               * ACIA ISR offset
    70 ACIA_CSR        .equ    2               * ACIA CSR offset
    71 ACIA_CFR        .equ    2               * ACIA CFR offset
    72 ACIA_TBR        .equ    4               * ACIA TBR offset
    73 ACIA_TDR        .equ    6               * ACIA TDR offset
    74 ACIA_RDR        .equ    6               * ACIA RDR offset
    75 *
    76 * iorec structure definitions:
    77 * ----------------------------
    78 IORECLN         .equ    40              * Length of an iorec structure
    79 *
    80 ibuf            .equ    0               * Input buffer base address
    81 ibufsize        .equ    4               * Input buffer size  (bytes)
    82 ibufhd          .equ    6               * Input buffer head index
    83 ibuftl          .equ    8               * Input buffer tail index
    84 ibuflow         .equ    10              * Input buffer low water mark
    85 ibufhi          .equ    12              * Input buffer high water mark
    86 obuf            .equ    14              * Output buffer base address
    87 obufsize        .equ    18              * Output buffer size  (bytes)
    88 obufhd          .equ    20              * Output buffer head index
    89 obuftl          .equ    22              * Output buffer tail index
    90 obuflow         .equ    24              * Output buffer low water mark
    91 obufhi          .equ    26              * Output buffer high water mark
    92 cfr0            .equ    28              * ACIA CFR, MS bit = 0
    93 cfr1            .equ    29              * ACIA CFR, MS bit = 1
    94 flagxon         .equ    30              * XON flag  (non-zero = XOFF sent)
    95 flagxoff        .equ    31              * XOFF flag  (non-zero = active)
    96 linedisc        .equ    32              * Line discipline flags
    97 erbyte          .equ    33              * Last error byte
    98 isr             .equ    34              * ACIA ISR on interrupt
    99 csr             .equ    35              * ACIA CSR on interrupt
    100 errct           .equ    36              * Error count  (FRM/OVR/BRK)
    101 ibfct           .equ    38              * Input buffer full count
    102 *
    103                 .page
    104 *
    105 * serintr -- Serial (Serial-1, Serial-2, MIDI-1, MIDI-2) interrupt handler
    106 * -------    -------------------------------------------------------------
    107 serintr:        movem.l d0-d3/a0-a2,-(a7)       * Save registers
    108                 lea     SR1IOREC,a0             * Point at Serial-1 iorec
    109                 lea     SR1ACIA,a1              * Point at Serial-1 ACIA
    110                 movea.l _foot1,a2               * Point at foot sw. 1 processor
    111                 bsr     serint                  * Go process (possible) int.
    112 *
    113                 lea     SR2IOREC,a0             * Point at Serial-2 iorec
    114                 lea     SR2ACIA,a1              * Point at Serial-2 ACIA
    115                 movea.l _foot2,a2               * Point at foot sw. 2 processor
    116                 bsr     serint                  * Go process (possible) int.
    117 *
    118                 lea     MC1IOREC,a0             * Point at MIDI-1 iorec
    119                 lea     MC1ACIA,a1              * Point at MIDI-1 ACIA
    120                 movea.l _pulse1,a2              * Point at pulse 1 processor
    121                 bsr     midint                  * Go process (possible) int.
    122 *
    123                 lea     MC2IOREC,a0             * Point at MIDI-2 iorec
    124                 lea     MC2ACIA,a1              * Point at MIDI-2 ACIA
    125                 movea.l _pulse2,a2              * Point at pulse 2 processor
    126                 bsr     midint                  * Go process (possible) int.
    127 *
    128                 movem.l (a7)+,d0-d3/a0-a2       * Restore registers
    129                 rte                             * Return from exception
    130 *
    131                 .page
    132 *
    133 * serint -- Process an interrupt from Serial-1 or Serial-2
    134 * ------    ----------------------------------------------
    135 serint:         move.b  ACIA_ISR(a1),isr(a0)    * Get and save ISR
    136                 move.b  ACIA_CSR(a1),csr(a0)    * Get and save CSR
    137 *
    138                 btst.b  #7,isr(a0)              * Was int for this device ?
    139                 beq     serintx                 * Jump if not
    140 *
    141 serchk:         btst.b  #1,isr(a0)              * FRM/OVR/BRK error ?
    142                 bne     sererr                  * Jump if so
    143 *
    144                 btst.b  #0,isr(a0)              * Receiver interrupt ?
    145                 bne     serrx                   * Jump if so
    146 *
    147 sertxq:         btst.b  #6,isr(a0)              * Transmitter interrupt ?
    148                 bne     sertx                   * Jump if so
    149 *
    150 serctq:         btst.b  #5,isr(a0)              * CTS interrupt ?
    151                 bne     sercts                  * Jump if so
    152 *
    153 serintx:        btst.b  #4,isr(a0)              * DCD interrupt ?
    154                 bne     calldcd                 * Jump if so
    155 *
    156 serdone:        rts                             * Return to caller
    157 *
    158 calldcd:        move.b  csr(a0),d0              * Get CSR interrupt status
    159                 btst.l  #4,d0                   * Check DCD input  (0 = active)
    160                 bne     calldcd0                * Jump if line was inactive
    161 *
    162                 moveq.l #1,d0                   * Set footswitch status to TRUE
    163                 bra     calldcd1                * ...
    164 *
    165 calldcd0:       moveq.l #0,d0                   * Set footswitch status to FALSE
    166 *
    167 calldcd1:       move.w  d0,-(a7)                * Call the footswitch processor
    168                 jsr     (a2)                    * ... (*footX)(status)
    169                 tst.w   (a7)+                   * ...
    170                 rts                             * Return to caller
    171 *
    172                 .page
    173 *
    174 * Handle serial I/O port error
    175 *
    176 sererr:         addq.w  #1,errct(a0)            * Update error count
    177                 move.b  ACIA_RDR(a1),erbyte(a0) * Get error byte
    178                 rts                             * Return to caller
    179 *
    180 *
    181 * Handle CTS interupt
    182 *
    183 sercts:         btst.b  #1,linedisc(a0)         * RTS/CTS mode ?
    184                 beq     serintx                 * Ignore if not
    185 *
    186                 btst.b  #5,csr(a0)              * CTS set ?
    187                 beq     serintx                 * Ignore if not
    188 *
    189 sercts1:        btst.b  #6,isr(a0)              * TDRE set ?
    190                 beq     sercts1                 * Loop until it is  (!)
    191 *
    192                 move.w  obufhd(a0),d2           * Head index to d2
    193                 cmp.w   obuftl(a0),d2           * Compare to tail index
    194                 beq     serintx                 * Done if buffer empty
    195 *
    196                 bsr     wrapout                 * Adjust pointer for wraparound
    197                 move.l  obuf(a0),a2             * Get buffer base in a2
    198                 move.b  0(a2,d2),ACIA_TDR(a1)   * Send byte on its way
    199                 move.w  d2,obufhd(a0)           * Save updated head index
    200                 bra     serintx                 * Done
    201 *
    202                 .page
    203 *
    204 * Handle receiver interrupt
    205 *
    206 serrx:          btst.b  #1,linedisc(a0)         * RTS/CTS mode set ?
    207                 beq     serrx1                  * Jump if not
    208 *
    209                 bsr     rtsoff                  * Turn off RTS
    210 *
    211 serrx1:         move.b  ACIA_RDR(a1),d0         * Read data from ACIA
    212                 btst.b  #1,linedisc(a0)         * RTS/CTS mode set ?
    213                 bne     serrx3                  * Jump if so
    214 *
    215                 btst.b  #0,linedisc(a0)         * XON/XOFF mode set ?
    216                 beq     serrx3                  * Jump if not
    217 *
    218                 cmpi.b  #$11,d0                 * Is this an XON ?
    219                 bne     serrx2                  * Jump if not
    220 *
    221                 move.b  #$00,flagxoff(a0)       * Clear flagxoff
    222                 bra     sertxq                  * Done
    223 *
    224 serrx2:         cmpi.b  #$13,d0                 * Is this an XOFF ?
    225                 bne     serrx3                  * Jump if not
    226 *
    227                 move.b  #$FF,flagxoff(a0)       * Set flagxoff
    228                 bra     sertxq                  * Done
    229 *
    230 serrx3:         move.w  ibuftl(a0),d1           * Get tail index in d1
    231                 bsr     wrapin                  * Adjust for wraparound
    232                 cmp.w   ibufhd(a0),d1           * Head = tail ?
    233                 beq     seribf                  * If so, we drop the character
    234 *
    235                 .page
    236                 move.l  ibuf(a0),a2             * Get buffer address
    237                 move.b  d0,0(a2,d1)             * Stash byte in buffer
    238                 move.w  d1,ibuftl(a0)           * Save updated tail index
    239                 move.w  ibuftl(a0),d2           * Tail index to d2
    240                 move.w  ibufhd(a0),d3           * Head index to d3
    241                 cmp.w   d3,d2                   * Head > Tail ?
    242                 bhi     rsi_1                   * Jump if not
    243 *
    244                 add.w   ibufsize(a0),d2         * Add buffer size to tail index
    245 *
    246 rsi_1:          sub.w   d3,d2                   * Length = (adjusted)Tail - Head
    247                 cmp.w   ibufhi(a0),d2           * Hit high water mark ?
    248                 bne     serrx4                  * Jump if not
    249 *
    250                 btst.b  #1,linedisc(a0)         * RTS/CTS mode set ?
    251                 bne     sertxq                  * Done if so
    252 *
    253                 btst.b  #0,linedisc(a0)         * XON/XOFF mode set ?
    254                 beq     serrx4                  * Jump if not
    255 *
    256                 tst.b   flagxon(a0)             * XOFF already sent ?
    257                 bne     serrx4                  * Jump if so
    258 *
    259                 move.b  #$FF,flagxon(a0)        * Set the flag
    260                 move.b  #$13,d1                 * Send an XOFF
    261                 bsr     serput                  * ...
    262 *
    263 serrx4:         btst    #1,linedisc(a0)         * RTS/CTS mode set ?
    264                 beq     sertxq                  * Done if not
    265 *
    266                 bsr     rtson                   * Turn on RTS
    267                 bra     sertxq                  * Done
    268 *
    269                 .page
    270 *
    271 * Handle transmitter interrupt
    272 *
    273 sertx:          btst.b  #1,linedisc(a0)         * RTS/CTS mode set ?
    274                 bne     sertx2                  * If so, go check CTS
    275 *
    276                 btst.b  #0,linedisc(a0)         * XON/XOFF mode set ?
    277                 beq     sertx1                  * Jump if not
    278 *
    279                 tst.b   flagxoff(a0)            * Check flagxoff
    280                 bne     serctq                  * Done if set
    281 *
    282 sertx1:         move.w  obufhd(a0),d2           * Head index to d2
    283                 cmp.w   obuftl(a0),d2           * Compare to tail index
    284                 beq     serctq                  * Done if buffer empty
    285 *
    286                 bsr     wrapout                 * Adjust pointer for wraparound
    287                 move.l  obuf(a0),a2             * Get buffer base address
    288                 move.b  0(a2,d2),ACIA_TDR(a1)   * Send byte on its way
    289                 move.w  d2,obufhd(a0)           * Save updated head index
    290                 bra     serctq                  * Done
    291 *
    292 sertx2:         btst.b  #5,csr(a0)              * CTS set in csr ?
    293                 beq     serctq                  * If not, go check for CTS int
    294 *
    295                 bra     sertx1                  * CTS was set, go transmit
    296 *
    297 seribf:         move.b  d0,erbyte(a0)           * Log dropped character
    298                 addq.w  #1,ibfct(a0)            * ...
    299                 bra     sertxq                  * Go check Tx interrupt
    300 *
    301                 .page
    302 *
    303 * midint -- Process an interrupt from MIDI-1 or MIDI-2
    304 * ------    ------------------------------------------
    305 midint:         move.b  ACIA_ISR(a1),isr(a0)    * Get and save ISR
    306                 move.b  ACIA_CSR(a1),csr(a0)    * Get and save CSR
    307 *
    308                 btst.b  #7,isr(a0)              * Was int for this device ?
    309                 beq     midintx                 * Jump if not
    310 *
    311 midchk:         btst.b  #1,isr(a0)              * FRM/OVR/BRK error ?
    312                 bne     miderr                  * Jump if so
    313 *
    314                 btst.b  #0,isr(a0)              * Receiver interrupt ?
    315                 bne     midrx                   * Jump if so
    316 *
    317 midtxq:         btst.b  #6,isr(a0)              * Transmitter interrupt ?
    318                 bne     midtx                   * Jump if so
    319 *
    320 midintx:        btst    #4,isr(a0)              * DCD interrupt ?
    321                 bne     mididcd                 * Jump if so
    322 *
    323 mididone:       rts                             * Return to caller
    324 *
    325 mididcd:        jmp     (a2)                    * Exit through the DCD processor
    326 *
    327 miderr:         addq.w  #1,errct(a0)            * Update error count
    328                 move.b  ACIA_RDR(a1),erbyte(a0) * Get error byte
     37
     38| ==============================================================================
     39
     40| The following addresses, marked by <==, are bios version dependent:
     41
     42RAM             =       0x00000400      | Beginning of system RAM area  <==
     43
     44SR1IOREC        =       RAM+0x0AB0      | Serial-1 iorec structure      <==
     45SR2IOREC        =       RAM+0x0AD8      | Serial-2 iorec structure      <==
     46MC1IOREC        =       RAM+0x0B00      | MIDI-1 iorec structure        <==
     47MC2IOREC        =       RAM+0x0B28      | MIDI-2 iorec structure        <==
     48
     49| End of bios version dependent addresses.
     50
     51| ==============================================================================
     52
     53                .page
     54
     55SERVECT         =       0x000074        | Level 5 interrupt autovector address
     56
     57IPL7            =       0x0700          | IPL 7 value for sr
     58
     59| ACIA I/O Addresses:
     60| -------------------
     61SR1ACIA         =       0x3A8001        | Serial-1 ACIA base address
     62SR2ACIA         =       0x3A8009        | Serial-2 ACIA base address
     63MC1ACIA         =       0x3AC001        | MIDI-1 ACIA base address
     64MC2ACIA         =       0x3AC009        | MIDI-2 ACIA base address
     65
     66| ACIA Register offsets:
     67| ----------------------
     68ACIA_IER        =       0               | ACIA IER offset
     69ACIA_ISR        =       0               | ACIA ISR offset
     70ACIA_CSR        =       2               | ACIA CSR offset
     71ACIA_CFR        =       2               | ACIA CFR offset
     72ACIA_TBR        =       4               | ACIA TBR offset
     73ACIA_TDR        =       6               | ACIA TDR offset
     74ACIA_RDR        =       6               | ACIA RDR offset
     75
     76| iorec structure definitions:
     77| ----------------------------
     78IORECLN         =       40              | Length of an iorec structure
     79
     80ibuf            =       0               | Input buffer base address
     81ibufsize        =       4               | Input buffer size  (bytes)
     82ibufhd          =       6               | Input buffer head index
     83ibuftl          =       8               | Input buffer tail index
     84ibuflow         =       10              | Input buffer low water mark
     85ibufhi          =       12              | Input buffer high water mark
     86obuf            =       14              | Output buffer base address
     87obufsize        =       18              | Output buffer size  (bytes)
     88obufhd          =       20              | Output buffer head index
     89obuftl          =       22              | Output buffer tail index
     90obuflow         =       24              | Output buffer low water mark
     91obufhi          =       26              | Output buffer high water mark
     92cfr0            =       28              | ACIA CFR, MS bit = 0
     93cfr1            =       29              | ACIA CFR, MS bit = 1
     94flagxon         =       30              | XON flag  (non-zero = XOFF sent)
     95flagxoff        =       31              | XOFF flag  (non-zero = active)
     96linedisc        =       32              | Line discipline flags
     97erbyte          =       33              | Last error byte
     98isr             =       34              | ACIA ISR on interrupt
     99csr             =       35              | ACIA CSR on interrupt
     100errct           =       36              | Error count  (FRM/OVR/BRK)
     101ibfct           =       38              | Input buffer full count
     102
     103                .page
     104
     105| serintr -- Serial (Serial-1, Serial-2, MIDI-1, MIDI-2) interrupt handler
     106| -------    -------------------------------------------------------------
     107serintr:        movem.l d0-d3/a0-a2,-(a7)       | Save registers
     108                lea     SR1IOREC,a0             | Point at Serial-1 iorec
     109                lea     SR1ACIA,a1              | Point at Serial-1 ACIA
     110                movea.l _foot1,a2               | Point at foot sw. 1 processor
     111                bsr     serint                  | Go process (possible) int.
     112
     113                lea     SR2IOREC,a0             | Point at Serial-2 iorec
     114                lea     SR2ACIA,a1              | Point at Serial-2 ACIA
     115                movea.l _foot2,a2               | Point at foot sw. 2 processor
     116                bsr     serint                  | Go process (possible) int.
     117
     118                lea     MC1IOREC,a0             | Point at MIDI-1 iorec
     119                lea     MC1ACIA,a1              | Point at MIDI-1 ACIA
     120                movea.l _pulse1,a2              | Point at pulse 1 processor
     121                bsr     midint                  | Go process (possible) int.
     122
     123                lea     MC2IOREC,a0             | Point at MIDI-2 iorec
     124                lea     MC2ACIA,a1              | Point at MIDI-2 ACIA
     125                movea.l _pulse2,a2              | Point at pulse 2 processor
     126                bsr     midint                  | Go process (possible) int.
     127
     128                movem.l (a7)+,d0-d3/a0-a2       | Restore registers
     129                rte                             | Return from exception
     130
     131                .page
     132
     133| serint -- Process an interrupt from Serial-1 or Serial-2
     134| ------    ----------------------------------------------
     135serint:         move.b  ACIA_ISR(a1),isr(a0)    | Get and save ISR
     136                move.b  ACIA_CSR(a1),csr(a0)    | Get and save CSR
     137
     138                btst.b  #7,isr(a0)              | Was int for this device ?
     139                beq     serintx                 | Jump if not
     140
     141serchk:         btst.b  #1,isr(a0)              | FRM/OVR/BRK error ?
     142                bne     sererr                  | Jump if so
     143
     144                btst.b  #0,isr(a0)              | Receiver interrupt ?
     145                bne     serrx                   | Jump if so
     146
     147sertxq:         btst.b  #6,isr(a0)              | Transmitter interrupt ?
     148                bne     sertx                   | Jump if so
     149
     150serctq:         btst.b  #5,isr(a0)              | CTS interrupt ?
     151                bne     sercts                  | Jump if so
     152
     153serintx:        btst.b  #4,isr(a0)              | DCD interrupt ?
     154                bne     calldcd                 | Jump if so
     155
     156serdone:        rts                             | Return to caller
     157
     158calldcd:        move.b  csr(a0),d0              | Get CSR interrupt status
     159                btst.l  #4,d0                   | Check DCD input  (0 = active)
     160                bne     calldcd0                | Jump if line was inactive
     161
     162                moveq.l #1,d0                   | Set footswitch status to TRUE
     163                bra     calldcd1                | ...
     164
     165calldcd0:       moveq.l #0,d0                   | Set footswitch status to FALSE
     166
     167calldcd1:       move.w  d0,-(a7)                | Call the footswitch processor
     168                jsr     (a2)                    | ... (|footX)(status)
     169                tst.w   (a7)+                   | ...
     170                rts                             | Return to caller
     171
     172                .page
     173
     174| Handle serial I/O port error
     175
     176sererr:         addq.w  #1,errct(a0)            | Update error count
     177                move.b  ACIA_RDR(a1),erbyte(a0) | Get error byte
     178                rts                             | Return to caller
     179
     180
     181| Handle CTS interupt
     182
     183sercts:         btst.b  #1,linedisc(a0)         | RTS/CTS mode ?
     184                beq     serintx                 | Ignore if not
     185
     186                btst.b  #5,csr(a0)              | CTS set ?
     187                beq     serintx                 | Ignore if not
     188
     189sercts1:        btst.b  #6,isr(a0)              | TDRE set ?
     190                beq     sercts1                 | Loop until it is  (!)
     191
     192                move.w  obufhd(a0),d2           | Head index to d2
     193                cmp.w   obuftl(a0),d2           | Compare to tail index
     194                beq     serintx                 | Done if buffer empty
     195
     196                bsr     wrapout                 | Adjust pointer for wraparound
     197                move.l  obuf(a0),a2             | Get buffer base in a2
     198                move.b  0(a2,d2),ACIA_TDR(a1)   | Send byte on its way
     199                move.w  d2,obufhd(a0)           | Save updated head index
     200                bra     serintx                 | Done
     201
     202                .page
     203
     204| Handle receiver interrupt
     205
     206serrx:          btst.b  #1,linedisc(a0)         | RTS/CTS mode set ?
     207                beq     serrx1                  | Jump if not
     208
     209                bsr     rtsoff                  | Turn off RTS
     210
     211serrx1:         move.b  ACIA_RDR(a1),d0         | Read data from ACIA
     212                btst.b  #1,linedisc(a0)         | RTS/CTS mode set ?
     213                bne     serrx3                  | Jump if so
     214
     215                btst.b  #0,linedisc(a0)         | XON/XOFF mode set ?
     216                beq     serrx3                  | Jump if not
     217
     218                cmpi.b  #0x11,d0                | Is this an XON ?
     219                bne     serrx2                  | Jump if not
     220
     221                move.b  #0x00,flagxoff(a0)      | Clear flagxoff
     222                bra     sertxq                  | Done
     223
     224serrx2:         cmpi.b  #0x13,d0                | Is this an XOFF ?
     225                bne     serrx3                  | Jump if not
     226
     227                move.b  #0xFF,flagxoff(a0)      | Set flagxoff
     228                bra     sertxq                  | Done
     229
     230serrx3:         move.w  ibuftl(a0),d1           | Get tail index in d1
     231                bsr     wrapin                  | Adjust for wraparound
     232                cmp.w   ibufhd(a0),d1           | Head = tail ?
     233                beq     seribf                  | If so, we drop the character
     234
     235                .page
     236                move.l  ibuf(a0),a2             | Get buffer address
     237                move.b  d0,0(a2,d1)             | Stash byte in buffer
     238                move.w  d1,ibuftl(a0)           | Save updated tail index
     239                move.w  ibuftl(a0),d2           | Tail index to d2
     240                move.w  ibufhd(a0),d3           | Head index to d3
     241                cmp.w   d3,d2                   | Head > Tail ?
     242                bhi     rsi_1                   | Jump if not
     243
     244                add.w   ibufsize(a0),d2         | Add buffer size to tail index
     245
     246rsi_1:          sub.w   d3,d2                   | Length = (adjusted)Tail - Head
     247                cmp.w   ibufhi(a0),d2           | Hit high water mark ?
     248                bne     serrx4                  | Jump if not
     249
     250                btst.b  #1,linedisc(a0)         | RTS/CTS mode set ?
     251                bne     sertxq                  | Done if so
     252
     253                btst.b  #0,linedisc(a0)         | XON/XOFF mode set ?
     254                beq     serrx4                  | Jump if not
     255
     256                tst.b   flagxon(a0)             | XOFF already sent ?
     257                bne     serrx4                  | Jump if so
     258
     259                move.b  #0xFF,flagxon(a0)       | Set the flag
     260                move.b  #0x13,d1                | Send an XOFF
     261                bsr     serput                  | ...
     262
     263serrx4:         btst    #1,linedisc(a0)         | RTS/CTS mode set ?
     264                beq     sertxq                  | Done if not
     265
     266                bsr     rtson                   | Turn on RTS
     267                bra     sertxq                  | Done
     268
     269                .page
     270
     271| Handle transmitter interrupt
     272
     273sertx:          btst.b  #1,linedisc(a0)         | RTS/CTS mode set ?
     274                bne     sertx2                  | If so, go check CTS
     275
     276                btst.b  #0,linedisc(a0)         | XON/XOFF mode set ?
     277                beq     sertx1                  | Jump if not
     278
     279                tst.b   flagxoff(a0)            | Check flagxoff
     280                bne     serctq                  | Done if set
     281
     282sertx1:         move.w  obufhd(a0),d2           | Head index to d2
     283                cmp.w   obuftl(a0),d2           | Compare to tail index
     284                beq     serctq                  | Done if buffer empty
     285
     286                bsr     wrapout                 | Adjust pointer for wraparound
     287                move.l  obuf(a0),a2             | Get buffer base address
     288                move.b  0(a2,d2),ACIA_TDR(a1)   | Send byte on its way
     289                move.w  d2,obufhd(a0)           | Save updated head index
     290                bra     serctq                  | Done
     291
     292sertx2:         btst.b  #5,csr(a0)              | CTS set in csr ?
     293                beq     serctq                  | If not, go check for CTS int
     294
     295                bra     sertx1                  | CTS was set, go transmit
     296
     297seribf:         move.b  d0,erbyte(a0)           | Log dropped character
     298                addq.w  #1,ibfct(a0)            | ...
     299                bra     sertxq                  | Go check Tx interrupt
     300
     301                .page
     302
     303| midint -- Process an interrupt from MIDI-1 or MIDI-2
     304| ------    ------------------------------------------
     305midint:         move.b  ACIA_ISR(a1),isr(a0)    | Get and save ISR
     306                move.b  ACIA_CSR(a1),csr(a0)    | Get and save CSR
     307
     308                btst.b  #7,isr(a0)              | Was int for this device ?
     309                beq     midintx                 | Jump if not
     310
     311midchk:         btst.b  #1,isr(a0)              | FRM/OVR/BRK error ?
     312                bne     miderr                  | Jump if so
     313
     314                btst.b  #0,isr(a0)              | Receiver interrupt ?
     315                bne     midrx                   | Jump if so
     316
     317midtxq:         btst.b  #6,isr(a0)              | Transmitter interrupt ?
     318                bne     midtx                   | Jump if so
     319
     320midintx:        btst    #4,isr(a0)              | DCD interrupt ?
     321                bne     mididcd                 | Jump if so
     322
     323mididone:       rts                             | Return to caller
     324
     325mididcd:        jmp     (a2)                    | Exit through the DCD processor
     326
     327miderr:         addq.w  #1,errct(a0)            | Update error count
     328                move.b  ACIA_RDR(a1),erbyte(a0) | Get error byte
    329329                rts
    330 *
    331 * Handle receiver interrupt
    332 *
    333 midrx:          move.b  ACIA_RDR(a1),d0         * Read data from ACIA
    334                 move.w  ibuftl(a0),d1           * Get tail index in d1
    335                 bsr     wrapin                  * Adjust for wraparound
    336                 cmp.w   ibufhd(a0),d1           * Head = tail ?
    337                 beq     midibf                  * If so, we drop the character
    338 *
    339                 move.l  ibuf(a0),a2             * Get buffer address
    340                 move.b  d0,0(a2,d1)             * Stash byte in buffer
    341                 move.w  d1,ibuftl(a0)           * Save updated tail index
    342                 bra     midtxq                  * Done  (go check tx int)
    343 *
    344                 .page
    345 *
    346 * Handle transmitter interrupt
    347 *
    348 midtx:          move.w  obufhd(a0),d2           * Head index to d2
    349                 cmp.w   obuftl(a0),d2           * Compare to tail index
    350                 beq     midintx                 * Done if buffer empty
    351 *
    352                 bsr     wrapout                 * Adjust pointer for wraparound
    353                 move.l  obuf(a0),a2             * Get buffer base address
    354                 move.b  0(a2,d2),ACIA_TDR(a1)   * Send byte on its way
    355                 move.w  d2,obufhd(a0)           * Save updated head index
    356                 bra     midintx                 * Done
    357 *
    358 midibf:         move.b  d0,erbyte(a0)           * Log dropped character
    359                 addq.w  #1,ibfct(a0)            * ...
    360                 bra     midtxq                  * Go check Tx interrupt
    361 *
    362                 .page
    363 *
    364 * serput -- Output a character to a serial port
    365 * ------    -----------------------------------
    366 serput:         move.w  sr,-(a7)                * Save status register
    367                 ori.w   #IPL7,sr                * DISABLE INTERRUPTS
    368                 move.b  ACIA_ISR(a1),isr(a0)    * Get ACIA isr
    369                 move.b  ACIA_CSR(a1),csr(a0)    * Get ACIA csr
    370                 btst    #0,linedisc(a0)         * XON/XOFF mode ?
    371                 beq     serpt_1                 * Jump if not
    372 *
    373                 tst.b   flagxoff(a0)            * XON active ?
    374                 bne     serpt_2                 * Jump if so
    375 *
    376 serpt_1:        btst.b  #6,isr(a0)              * Is ACIA still sending ?
    377                 beq     serpt_2                 * Jump if so
    378 *
    379                 move.w  obufhd(a0),d2           * Head index to d2
    380                 cmp.w   obuftl(a0),d2           * Compare to tail index
    381                 bne     serpt_2                 * Jump if buffer not empty
    382 *
    383                 move.b  d1,ACIA_TDR(a1)         * Give byte to ACIA to send
    384                 bra     serpt_3                 * Go deal with RTS/CTS if needed
    385 *
    386 serpt_2:        move.w  obuftl(a0),d2           * Tail index to d2
    387                 bsr     wrapout                 * Adjust for wraparound
    388                 cmp.w   obufhd(a0),d2           * Compare to head index
    389                 beq     serpt_4                 * Jump if buffer full
    390 *
    391                 move.l  obuf(a0),a2             * Get buffer base address in a2
    392                 move.b  d1,0(a2,d2)             * Put character in buffer
    393                 move.w  d2,obuftl(a0)           * Update buffer tail index
    394 *
    395 serpt_3:        bsr     serchk                  * Check status on our way out
    396                 bsr     rtschk                  * Handle RTS protocol
    397                 move.w  (a7)+,sr                * RESTORE INTERRUPTS
    398                 andi    #$FFFE,sr               * Clear carry flag = OK
    399                 rts                             * Return to caller
    400 *
    401 serpt_4:        bsr     serchk                  * Check status on our way out
    402                 bsr     rtschk                  * Handle RTS protocol
    403                 move.w  (a7)+,sr                * RESTORE INTERRUPTS
    404                 ori     #$0001,sr               * Set carry flag = buffer full
    405                 rts                             * Return to caller
    406 *
    407                 .page
    408 *
    409 * midput -- Output to MIDI
    410 * ------    --------------
    411 midput:         move.w  sr,-(a7)                * Save status register
    412                 ori.w   #IPL7,sr                * DISABLE INTERRUPTS
    413                 move.b  ACIA_ISR(a1),isr(a0)    * Get ACIA isr
    414                 move.b  ACIA_CSR(a1),csr(a0)    * Get ACIA csr
    415                 btst.b  #6,isr(a0)              * Is ACIA still sending ?
    416                 beq     midpt_2                 * Jump if so
    417 *
    418                 move.w  obufhd(a0),d2           * Head index to d2
    419                 cmp.w   obuftl(a0),d2           * Compare to tail index
    420                 bne     midpt_2                 * Jump if buffer not empty
    421 *
    422                 move.b  d1,ACIA_TDR(a1)         * Give byte to ACIA to send
    423                 bra     midpt_3                 * Go set final status and exit
    424 *
    425 midpt_2:        move.w  obuftl(a0),d2           * Tail index to d2
    426                 bsr     wrapout                 * Adjust for wraparound
    427                 cmp.w   obufhd(a0),d2           * Compare to head index
    428                 beq     midpt_4                 * Jump if buffer full
    429 *
    430                 move.l  obuf(a0),a2             * Get buffer base address in a2
    431                 move.b  d1,0(a2,d2)             * Put character in buffer
    432                 move.w  d2,obuftl(a0)           * Update buffer tail index
    433 *
    434 midpt_3:        bsr     midchk                  * Check status on our way out
    435                 move.w  (a7)+,sr                * RESTORE INTERRUPTS
    436                 andi    #$FFFE,sr               * Clear carry flag = OK
    437                 rts                             * Return to caller
    438 *
    439 midpt_4:        bsr     midchk                  * Check status on our way out
    440                 move.w  (a7)+,sr                * RESTORE INTERRUPTS
    441                 ori     #$0001,sr               * Set carry flag = buffer full
    442                 rts                             * Return to caller
    443 *
    444                 .page
    445 *
    446 * rtschk -- Check RTS mode and turn on RTS if it's enabled
    447 * ------    ----------------------------------------------
    448 rtschk:         btst    #1,linedisc(a0)         * RTS/CTS mode set ?
    449                 beq     rtsexit                 * Jump to exit if not
    450 *
    451 * rtson -- Turn on RTS line
    452 * -----    ----------------
    453 rtson:          move.b  cfr1(a0),d0             * Pick up CFR1 image
    454                 bclr    #0,d0                   * Turn on RTS line  (0 = on)
    455                 bra     rtscmn                  * Join common RTS code below
    456 *
    457 * rtsoff -- Turn off RTS line
    458 * ------    -----------------
    459 rtsoff:         move.b  cfr1(a0),d0             * Pick up CFR1 image
    460                 bset    #0,d0                   * Turn off RTS line  (1 = off)
    461 
    462 rtscmn:         bset    #7,d0                   * Make sure MS bit is set
    463                 move.b  d0,cfr1(a0)             * Update CFR1 image
    464                 move.b  d0,ACIA_CFR(a1)         * Send CFR to hardware
    465 *
    466 rtsexit:        rts                             * Return to caller
    467 *
    468                 .page
    469 *
    470 * wrapin -- Check input pointer for wraparound
    471 * ------    ----------------------------------
    472 wrapin:         add.w   #1,d1                   * Head index +1
    473                 cmp.w   ibufsize(a0),d1         * = buffer size ?
    474                 bcs     wrapin1                 * Jump if not
    475 *
    476                 moveq.l #0,d1                   * Wraparound
    477 *
    478 wrapin1:        rts                             * Return to caller
    479 *
    480 * wrapout -- Check output pointer for wraparound
    481 * -------    -----------------------------------
    482 wrapout:        addq.w  #1,d2                   * Tail index +1
    483                 cmp.w   obufsize(a0),d2         * = buffer size ?
    484                 bcs     wrapout1                * Jump if not
    485 *
    486                 moveq.l #0,d2                   * Wrap around if so
    487 *
    488 wrapout1:       rts                             * Return to caller
    489 *
    490                 .page
    491 *
    492 * _setsio -- setsio() -- initialize serial I/O vectors and DCD interrupts
    493 * -------    ------------------------------------------------------------
    494 _setsio:        move.w  sr,-(a7)                * Preserve status register
    495                 ori.w   #$IPL7,sr               * DISABLE INTERRUPTS
    496 *
    497                 lea     nulsiox,a0              * Get null return address
    498                 move.l  a0,_foot1               * Initialize foot1 vector
    499                 move.l  a0,_foot2               * Initialize foot2 vector
    500                 move.l  a0,_pulse1              * Initialize pulse1 vector
    501                 move.l  a0,_pulse2              * Initialize pulse2 vector
    502 *
    503                 lea     SR1ACIA,a1              * Point at Serial-1 ACIA
    504                 move.b  #$90,ACIA_IER(a1)       * Enable DCD interrupts
    505 *
    506                 lea     SR2ACIA,a1              * Point at Serial-2 ACIA
    507                 move.b  #$90,ACIA_IER(a1)       * Enable DCD interrupts
    508 *
    509                 lea     MC1ACIA,a1              * Point at MIDI-1 ACIA
    510                 move.b  #$90,ACIA_IER(a1)       * Enable DCD interrupts
    511 *
    512                 lea     MC2ACIA,a1              * Point at MIDI-2 ACIA
    513                 move.b  #$90,ACIA_IER(a1)       * Enable DCD interrupts
    514 *
    515                 lea     serintr,a0              * Initialize interrupt vector
    516                 move.l  a0,SERVECT              * ... in processor RAM
    517 *
    518                 move.w  (a7)+,sr                * RESTORE INTERRUPTS
    519 *
    520 nulsiox:        rts                             * Return to caller
    521 *
     330
     331| Handle receiver interrupt
     332
     333midrx:          move.b  ACIA_RDR(a1),d0         | Read data from ACIA
     334                move.w  ibuftl(a0),d1           | Get tail index in d1
     335                bsr     wrapin                  | Adjust for wraparound
     336                cmp.w   ibufhd(a0),d1           | Head = tail ?
     337                beq     midibf                  | If so, we drop the character
     338
     339                move.l  ibuf(a0),a2             | Get buffer address
     340                move.b  d0,0(a2,d1)             | Stash byte in buffer
     341                move.w  d1,ibuftl(a0)           | Save updated tail index
     342                bra     midtxq                  | Done  (go check tx int)
     343
     344                .page
     345
     346| Handle transmitter interrupt
     347
     348midtx:          move.w  obufhd(a0),d2           | Head index to d2
     349                cmp.w   obuftl(a0),d2           | Compare to tail index
     350                beq     midintx                 | Done if buffer empty
     351
     352                bsr     wrapout                 | Adjust pointer for wraparound
     353                move.l  obuf(a0),a2             | Get buffer base address
     354                move.b  0(a2,d2),ACIA_TDR(a1)   | Send byte on its way
     355                move.w  d2,obufhd(a0)           | Save updated head index
     356                bra     midintx                 | Done
     357
     358midibf:         move.b  d0,erbyte(a0)           | Log dropped character
     359                addq.w  #1,ibfct(a0)            | ...
     360                bra     midtxq                  | Go check Tx interrupt
     361
     362                .page
     363
     364| serput -- Output a character to a serial port
     365| ------    -----------------------------------
     366serput:         move.w  sr,-(a7)                | Save status register
     367                ori.w   #IPL7,sr                | DISABLE INTERRUPTS
     368                move.b  ACIA_ISR(a1),isr(a0)    | Get ACIA isr
     369                move.b  ACIA_CSR(a1),csr(a0)    | Get ACIA csr
     370                btst    #0,linedisc(a0)         | XON/XOFF mode ?
     371                beq     serpt_1                 | Jump if not
     372
     373                tst.b   flagxoff(a0)            | XON active ?
     374                bne     serpt_2                 | Jump if so
     375
     376serpt_1:        btst.b  #6,isr(a0)              | Is ACIA still sending ?
     377                beq     serpt_2                 | Jump if so
     378
     379                move.w  obufhd(a0),d2           | Head index to d2
     380                cmp.w   obuftl(a0),d2           | Compare to tail index
     381                bne     serpt_2                 | Jump if buffer not empty
     382
     383                move.b  d1,ACIA_TDR(a1)         | Give byte to ACIA to send
     384                bra     serpt_3                 | Go deal with RTS/CTS if needed
     385
     386serpt_2:        move.w  obuftl(a0),d2           | Tail index to d2
     387                bsr     wrapout                 | Adjust for wraparound
     388                cmp.w   obufhd(a0),d2           | Compare to head index
     389                beq     serpt_4                 | Jump if buffer full
     390
     391                move.l  obuf(a0),a2             | Get buffer base address in a2
     392                move.b  d1,0(a2,d2)             | Put character in buffer
     393                move.w  d2,obuftl(a0)           | Update buffer tail index
     394
     395serpt_3:        bsr     serchk                  | Check status on our way out
     396                bsr     rtschk                  | Handle RTS protocol
     397                move.w  (a7)+,sr                | RESTORE INTERRUPTS
     398                andi    #0xFFFE,sr              | Clear carry flag = OK
     399                rts                             | Return to caller
     400
     401serpt_4:        bsr     serchk                  | Check status on our way out
     402                bsr     rtschk                  | Handle RTS protocol
     403                move.w  (a7)+,sr                | RESTORE INTERRUPTS
     404                ori     #0x0001,sr              | Set carry flag = buffer full
     405                rts                             | Return to caller
     406
     407                .page
     408
     409| midput -- Output to MIDI
     410| ------    --------------
     411midput:         move.w  sr,-(a7)                | Save status register
     412                ori.w   #IPL7,sr                | DISABLE INTERRUPTS
     413                move.b  ACIA_ISR(a1),isr(a0)    | Get ACIA isr
     414                move.b  ACIA_CSR(a1),csr(a0)    | Get ACIA csr
     415                btst.b  #6,isr(a0)              | Is ACIA still sending ?
     416                beq     midpt_2                 | Jump if so
     417
     418                move.w  obufhd(a0),d2           | Head index to d2
     419                cmp.w   obuftl(a0),d2           | Compare to tail index
     420                bne     midpt_2                 | Jump if buffer not empty
     421
     422                move.b  d1,ACIA_TDR(a1)         | Give byte to ACIA to send
     423                bra     midpt_3                 | Go set final status and exit
     424
     425midpt_2:        move.w  obuftl(a0),d2           | Tail index to d2
     426                bsr     wrapout                 | Adjust for wraparound
     427                cmp.w   obufhd(a0),d2           | Compare to head index
     428                beq     midpt_4                 | Jump if buffer full
     429
     430                move.l  obuf(a0),a2             | Get buffer base address in a2
     431                move.b  d1,0(a2,d2)             | Put character in buffer
     432                move.w  d2,obuftl(a0)           | Update buffer tail index
     433
     434midpt_3:        bsr     midchk                  | Check status on our way out
     435                move.w  (a7)+,sr                | RESTORE INTERRUPTS
     436                andi    #0xFFFE,sr              | Clear carry flag = OK
     437                rts                             | Return to caller
     438
     439midpt_4:        bsr     midchk                  | Check status on our way out
     440                move.w  (a7)+,sr                | RESTORE INTERRUPTS
     441                ori     #0x0001,sr              | Set carry flag = buffer full
     442                rts                             | Return to caller
     443
     444                .page
     445
     446| rtschk -- Check RTS mode and turn on RTS if it's enabled
     447| ------    ----------------------------------------------
     448rtschk:         btst    #1,linedisc(a0)         | RTS/CTS mode set ?
     449                beq     rtsexit                 | Jump to exit if not
     450
     451| rtson -- Turn on RTS line
     452| -----    ----------------
     453rtson:          move.b  cfr1(a0),d0             | Pick up CFR1 image
     454                bclr    #0,d0                   | Turn on RTS line  (0 = on)
     455                bra     rtscmn                  | Join common RTS code below
     456
     457| rtsoff -- Turn off RTS line
     458| ------    -----------------
     459rtsoff:         move.b  cfr1(a0),d0             | Pick up CFR1 image
     460                bset    #0,d0                   | Turn off RTS line  (1 = off)
     461
     462rtscmn:         bset    #7,d0                   | Make sure MS bit is set
     463                move.b  d0,cfr1(a0)             | Update CFR1 image
     464                move.b  d0,ACIA_CFR(a1)         | Send CFR to hardware
     465
     466rtsexit:        rts                             | Return to caller
     467
     468                .page
     469
     470| wrapin -- Check input pointer for wraparound
     471| ------    ----------------------------------
     472wrapin:         add.w   #1,d1                   | Head index +1
     473                cmp.w   ibufsize(a0),d1         | = buffer size ?
     474                bcs     wrapin1                 | Jump if not
     475
     476                moveq.l #0,d1                   | Wraparound
     477
     478wrapin1:        rts                             | Return to caller
     479
     480| wrapout -- Check output pointer for wraparound
     481| -------    -----------------------------------
     482wrapout:        addq.w  #1,d2                   | Tail index +1
     483                cmp.w   obufsize(a0),d2         | = buffer size ?
     484                bcs     wrapout1                | Jump if not
     485
     486                moveq.l #0,d2                   | Wrap around if so
     487
     488wrapout1:       rts                             | Return to caller
     489
     490                .page
     491
     492| _setsio -- setsio() -- initialize serial I/O vectors and DCD interrupts
     493| -------    ------------------------------------------------------------
     494_setsio:        move.w  sr,-(a7)                | Preserve status register
     495                ori.w   #IPL7,sr                | DISABLE INTERRUPTS
     496
     497                lea     nulsiox,a0              | Get null return address
     498                move.l  a0,_foot1               | Initialize foot1 vector
     499                move.l  a0,_foot2               | Initialize foot2 vector
     500                move.l  a0,_pulse1              | Initialize pulse1 vector
     501                move.l  a0,_pulse2              | Initialize pulse2 vector
     502
     503                lea     SR1ACIA,a1              | Point at Serial-1 ACIA
     504                move.b  #0x90,ACIA_IER(a1)      | Enable DCD interrupts
     505
     506                lea     SR2ACIA,a1              | Point at Serial-2 ACIA
     507                move.b  #0x90,ACIA_IER(a1)      | Enable DCD interrupts
     508
     509                lea     MC1ACIA,a1              | Point at MIDI-1 ACIA
     510                move.b  #0x90,ACIA_IER(a1)      | Enable DCD interrupts
     511
     512                lea     MC2ACIA,a1              | Point at MIDI-2 ACIA
     513                move.b  #0x90,ACIA_IER(a1)      | Enable DCD interrupts
     514
     515                lea     serintr,a0              | Initialize interrupt vector
     516                move.l  a0,SERVECT              | ... in processor RAM
     517
     518                move.w  (a7)+,sr                | RESTORE INTERRUPTS
     519
     520nulsiox:        rts                             | Return to caller
     521
    522522                .bss
    523 *
    524 * DCD interrupt processor vectors
    525 * -------------------------------
    526 _foot1:         .ds.l   1                       * short (*foot1)();
    527 _foot2:         .ds.l   1                       * short (*foot2)();
    528 _pulse1:        .ds.l   1                       * short (*pulse1)();
    529 _pulse2:        .ds.l   1                       * short (*pulse2)();
    530 *
     523
     524| DCD interrupt processor vectors
     525| -------------------------------
     526_foot1:         .ds.l   1                       | short (|foot1)();
     527_foot2:         .ds.l   1                       | short (|foot2)();
     528_pulse1:        .ds.l   1                       | short (|pulse1)();
     529_pulse2:        .ds.l   1                       | short (|pulse2)();
     530
    531531                .end
  • ram/sreset.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * sreset.s -- reset score highlighting
    3 * Version 14 -- 1988-07-28 -- D.N. Lynx Crowe
    4 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| sreset.s -- reset score highlighting
     3| Version 14 -- 1988-07-28 -- D.N. Lynx Crowe
     4| ------------------------------------------------------------------------------
    55                .text
    6 *
    7                 .xdef   _sreset         * sreset()
    8 *
    9                 .xref   _vputa          * vputa(sbase, row, col, attrib)
    10 *
    11                 .xref   _ndisp          * WORD - display number
    12                 .xref   _obj8           * LONG - object base address
    13                 .xref   _vrbw08         * WORD - detail word for bit 8
    14                 .xref   _vrbw09         * WORD - detail word for bit 9
    15                 .xref   _vrbw10         * WORD - detail word for bit 10
    16                 .xref   _vrbw11         * WORD - detail word for bit 11
    17                 .xref   _vrbw12         * WORD - detail word for bit 12
    18                 .xref   _vrbw13         * WORD - detail word for bit 13
    19                 .xref   _vrbw14         * WORD - detail word for bit 14
    20                 .xref   _vrbw15         * WORD - detail word for bit 15
    21                 .xref   _vrcw           * WORD - video reset control word
    22 *
    23 ROW             .equ    4
    24 COL             .equ    6
    25 ATR             .equ    8
    26 *
    27 AT01            .equ    $0014
    28 AT04            .equ    $0013
    29 AT05            .equ    $0014
    30 AT06            .equ    $0013
    31 AT07            .equ    $0014
    32 AT08            .equ    $0013
    33 AT09            .equ    $0014
    34 AT10            .equ    $0013
    35 AT11            .equ    $0012
    36 AT12            .equ    $0012
    37 *
    38                 .page
    39 *
    40 * sreset() -- reset highlighting
    41 * --------    ------------------
    42 _sreset:        link    a6,#0           * link stack frame
    43                 cmp.w   #2,_ndisp       * see if we should update display
    44                 bne     srsexit         * jump if not
    45 *
    46                 move.w  _vrcw,d0        * get and check vrcw
    47                 bne     srs0            * jump if something to do
    48 *
    49 srsexit:        unlk    a6              * unlink stack frame
    50                 rts                     * return to caller
    51 *
    52 srs0:           move.w  sr,d1           * <<<<< disable interrupts >>>>>
    53                 ori.w   #$0700,sr       * ...
    54 *
    55                 move.w  _vrcw,vrcw      * make local copies of control variables
    56                 clr.w   _vrcw           * ... and clear them for the next pass
    57                 move.w  _vrbw08,vrbw08  * ...
    58                 clr.w   _vrbw08         * ...
    59                 move.w  _vrbw09,vrbw09  * ...
    60                 clr.w   _vrbw09         * ...
    61                 move.w  _vrbw10,vrbw10  * ...
    62                 clr.w   _vrbw10         * ...
    63                 move.w  _vrbw11,vrbw11  * ...
    64                 clr.w   _vrbw11         * ...
    65                 move.w  _vrbw12,vrbw12  * ...
    66                 clr.w   _vrbw12         * ...
    67                 move.w  _vrbw13,vrbw13  * ...
    68                 clr.w   _vrbw13         * ...
    69                 move.w  _vrbw14,vrbw14  * ...
    70                 clr.w   _vrbw14         * ...
    71                 move.w  _vrbw15,vrbw15  * ...
    72                 clr.w   _vrbw15         * ...
    73 *
    74                 move.w  d1,sr           * <<<<< restore interrupts >>>>>
    75 *
    76 * Setup STACK for subsequent calls to vputa(sbase, row, col, atr):
    77 *
    78 *       0(a7)   sbase
    79 *
    80 *       4(a7)   row     ROW
    81 *       6(a7)   col     COL
    82 *       8(a7)   atr     ATR
    83 *
    84                 clr.w   -(a7)           * put dummy attribute on stack
    85                 clr.w   -(a7)           * put dummy column on stack
    86                 clr.w   -(a7)           * put dummy row on stack
    87                 move.l  _obj8,-(a7)     * put sbase on stack
    88 *
    89                 .page
    90 *
    91 * assignment
    92 * ----------
    93                 btst    #0,d0           * assignment ?
    94                 beq     srs1            * jump if not
    95 *
    96                 move.w  #AT04,ATR(a7)   * put attribute on stack
    97                 move.w  #1,ROW(a7)      * put row on stack
    98                 move.w  #11,COL(a7)     * put 1st column on stack
    99                 jsr     _vputa          * reset first column
    100                 move.w  #12,COL(a7)     * put 2nd column on stack
    101                 jsr     _vputa          * reset second column
    102                 move.w  vrcw,d0         * restore vrcw to d0
    103 *
    104 * tuning
    105 * ------
    106 srs1:           btst    #1,d0           * tuning ?
    107                 beq     srs2            * jump if not
    108 *
    109                 move.w  #AT05,ATR(a7)   * put attribute on stack
    110                 move.w  #1,ROW(a7)      * put row on stack
    111                 move.w  #19,COL(a7)     * put column on stack
    112                 jsr     _vputa          * reset column
    113                 move.w  vrcw,d0         * restore vrcw to d0
    114 *
    115 * tempo
    116 * -----
    117 srs2:           btst    #2,d0           * tempo ?
    118                 beq     srs3            * jump if not
    119 *
    120                 move.w  #AT06,ATR(a7)   * put attribute on stack
    121                 move.w  #1,ROW(a7)      * put row on stack
    122                 move.w  #27,COL(a7)     * put 1st column on stack
    123                 jsr     _vputa          * reset first column
    124                 move.w  #28,COL(a7)     * put 2nd column on stack
    125                 jsr     _vputa          * reset second column
    126                 move.w  #29,COL(a7)     * put 3rd column on stack
    127                 jsr     _vputa          * reset third column
    128                 move.w  vrcw,d0         * restore vrcw to d0
    129 *
    130                 .page
    131 *
    132 * interpolate
    133 * -----------
    134 srs3:           btst    #3,d0           * interpolate ?
    135                 beq     srs4            * jump if not
    136 *
    137                 move.w  #AT07,ATR(a7)   * put attribute on stack
    138                 move.w  #1,ROW(a7)      * put row on stack
    139                 move.w  #35,COL(a7)     * put 1st column on stack
    140                 jsr     _vputa          * reset first column
    141                 move.w  #36,COL(a7)     * put 2nd column on stack
    142                 jsr     _vputa          * reset second column
    143                 move.w  #37,COL(a7)     * put 3rd column on stack
    144                 jsr     _vputa          * reset third column
    145                 move.w  #38,COL(a7)     * put 4th column on stack
    146                 jsr     _vputa          * reset fourth column
    147                 move.w  vrcw,d0         * restore vrcw to d0
    148 *
    149 * section begin
    150 * -------------
    151 srs4:           btst    #4,d0           * section begin ?
    152                 beq     srs5            * jump if not
    153 *
    154                 move.w  #AT01,ATR(a7)   * put attribute on stack
    155                 move.w  #0,ROW(a7)      * put row on stack
    156                 move.w  #6,COL(a7)      * put 1st column on stack
    157                 jsr     _vputa          * reset first column
    158                 move.w  #7,COL(a7)      * put 2nd column on stack
    159                 jsr     _vputa          * reset second column
    160 *
    161                 .page
    162 *
    163 * punch in
    164 * --------
    165 srs5:           btst    #5,d0           * punch in ?
    166                 beq     srs6            * jump if not
    167 *
    168                 move.w  #AT09,ATR(a7)   * put attribute on stack
    169                 move.w  #1,ROW(a7)      * put row on stack
    170                 move.w  #50,COL(a7)     * put 1st column on stack
    171                 jsr     _vputa          * reset first column
    172                 move.w  #51,COL(a7)     * put 2nd column on stack
    173                 jsr     _vputa          * reset second column
    174                 move.w  vrcw,d0         * restore vrcw to d0
    175 *
    176 * punch out
    177 * ---------
    178 srs6:           btst    #6,d0           * punch out ?
    179                 beq     srs7            * jump if not
    180 *
    181                 move.w  #AT09,ATR(a7)   * put attribute on stack
    182                 move.w  #1,ROW(a7)      * put row on stack
    183                 move.w  #53,COL(a7)     * put 1st column on stack
    184                 jsr     _vputa          * reset first column
    185                 move.w  #54,COL(a7)     * put 2nd column on stack
    186                 jsr     _vputa          * reset second column
    187                 move.w  #55,COL(a7)     * put 3rd column on stack
    188                 jsr     _vputa          * reset third column
    189                 move.w  vrcw,d0         * restore vrcw to d0
    190 *
    191 * Output
    192 * ------
    193 srs7:           btst    #7,d0           * output ?
    194                 beq     srs8            * jump if not
    195 *
    196                 move.w  #AT10,ATR(a7)   * put attribute on stack
    197                 move.w  #1,ROW(a7)      * put row on stack
    198                 move.w  #57,COL(a7)     * put 1st column on stack
    199                 jsr     _vputa          * reset first column
    200                 move.w  #58,COL(a7)     * put 2nd column on stack
    201                 jsr     _vputa          * reset second column
    202                 move.w  #59,COL(a7)     * put 3rd column on stack
    203                 jsr     _vputa          * reset third column
    204                 move.w  #60,COL(a7)     * put 4th column on stack
    205                 jsr     _vputa          * reset fourth column
    206                 move.w  #61,COL(a7)     * put 5th column on stack
    207                 jsr     _vputa          * reset fifth column
    208                 move.w  #62,COL(a7)     * put 6th column on stack
    209                 jsr     _vputa          * reset sixth column
    210                 move.w  vrcw,d0         * restore vrcw to d0
    211 *
    212                 .page
    213 *
    214 * instrument
    215 * ----------
    216 srs8:           btst    #8,d0           * instrument ?
    217                 beq     srs9            * jump if not
    218 *
    219                 move.w  #2,ROW(a7)      * put row on stack
    220                 move.w  #AT11,ATR(a7)   * put attribute on stack
    221                 btst    #0,vrbw08+1     * group 1 ?
    222                 beq     srs8a           * jump if not
    223 *
    224                 move.w  #7,COL(a7)      * put 1st column on stack
    225                 jsr     _vputa          * reset first column
    226                 move.w  #8,COL(a7)      * put 2nd column on stack
    227                 jsr     _vputa          * reset second column
    228 *
    229 srs8a:          btst    #1,vrbw08+1     * group 2 ?
    230                 beq     srs8b           * jump if not
    231 *
    232                 move.w  #12,COL(a7)     * put 1st column on stack
    233                 jsr     _vputa          * reset first character
    234                 move.w  #13,COL(a7)     * put 2nd column on stack
    235                 jsr     _vputa          * reset second character
    236 *
    237 srs8b:          btst    #2,vrbw08+1     * group 3 ?
    238                 beq     srs8c           * jump if not
    239 *
    240                 move.w  #17,COL(a7)     * put 1st column on stack
    241                 jsr     _vputa          * reset first character
    242                 move.w  #18,COL(a7)     * put 2nd column on stack
    243                 jsr     _vputa          * reset second character
    244 *
    245 srs8c:          btst    #3,vrbw08+1     * group 4 ?
    246                 beq     srs8d           * jump if not
    247 *
    248                 move.w  #22,COL(a7)     * put 1st column on stack
    249                 jsr     _vputa          * reset first character
    250                 move.w  #23,COL(a7)     * put 2nd column on stack
    251                 jsr     _vputa          * reset second character
    252 *
    253                 .page
    254 *
    255 srs8d:          btst    #4,vrbw08+1     * group 5 ?
    256                 beq     srs8e           * jump if not
    257 *
    258                 move.w  #27,COL(a7)     * put 1st column on stack
    259                 jsr     _vputa          * reset first character
    260                 move.w  #28,COL(a7)     * put 2nd column on stack
    261                 jsr     _vputa          * reset second character
    262 *
    263 srs8e:          btst    #5,vrbw08+1     * group 6 ?
    264                 beq     srs8f           * jump if not
    265 *
    266                 move.w  #32,COL(a7)     * put 1st column on stack
    267                 jsr     _vputa          * reset first character
    268                 move.w  #33,COL(a7)     * put 2nd column on stack
    269                 jsr     _vputa          * reset second character
    270 *
    271 srs8f:          btst    #6,vrbw08+1     * group 7 ?
    272                 beq     srs8g           * jump if not
    273 *
    274                 move.w  #37,COL(a7)     * put 1st column on stack
    275                 jsr     _vputa          * reset first character
    276                 move.w  #38,COL(a7)     * put 2nd column on stack
    277                 jsr     _vputa          * reset second character
    278 *
    279 srs8g:          btst    #7,vrbw08+1     * group 8 ?
    280                 beq     srs8h           * jump if not
    281 *
    282                 move.w  #42,COL(a7)     * put 1st column on stack
    283                 jsr     _vputa          * reset first character
    284                 move.w  #43,COL(a7)     * put 2nd column on stack
    285                 jsr     _vputa          * reset second character
    286 *
    287                 .page
    288 *
    289 srs8h:          btst    #0,vrbw08       * group 9
    290                 beq     srs8j           * jump if not
    291 *
    292                 move.w  #47,COL(a7)     * put 1st column on stack
    293                 jsr     _vputa          * reset first character
    294                 move.w  #48,COL(a7)     * put 2nd column on stack
    295                 jsr     _vputa          * reset second character
    296 *
    297 srs8j:          btst    #1,vrbw08       * group 10
    298                 beq     srs8k           * jump if not
    299 *
    300                 move.w  #52,COL(a7)     * put 1st column on stack
    301                 jsr     _vputa          * reset first character
    302                 move.w  #53,COL(a7)     * put 2nd column on stack
    303                 jsr     _vputa          * reset second character
    304 *
    305 srs8k:          btst    #2,vrbw08       * group 11
    306                 beq     srs8m           * jump if not
    307 *
    308                 move.w  #57,COL(a7)     * put 1st column on stack
    309                 jsr     _vputa          * reset first character
    310                 move.w  #58,COL(a7)     * put 2nd column on stack
    311                 jsr     _vputa          * reset second character
    312 *
    313 srs8m:          btst    #3,vrbw08       * group 12
    314                 beq     srs8x           * jump if not
    315 *
    316                 move.w  #62,COL(a7)     * put 1st column on stack
    317                 jsr     _vputa          * reset first character
    318                 move.w  #63,COL(a7)     * put 2nd column on stack
    319                 jsr     _vputa          * reset second character
    320 *
    321 srs8x:          move.w  vrcw,d0         * restore vrcw to d0
    322 *
    323                 .page
    324 *
    325 * transpose
    326 * ---------
    327 srs9:           btst    #9,d0           * transpose ?
    328                 beq     srs10           * jump if not
    329 *
    330                 move.w  #AT11,ATR(a7)   * put attribute on stack
    331                 move.w  #3,ROW(a7)      * put row on stack
    332                 btst    #0,vrbw09+1     * group 1 ?
    333                 beq     srs9a           * jump if not
    334 *
    335                 move.w  #5,COL(a7)      * put 1st column on stack
    336                 jsr     _vputa          * reset first column
    337                 move.w  #6,COL(a7)      * put 2nd column on stack
    338                 jsr     _vputa          * reset second column
    339                 move.w  #7,COL(a7)      * put 3rd column on stack
    340                 jsr     _vputa          * reset third column
    341                 move.w  #8,COL(a7)      * put 4th column on stack
    342                 jsr     _vputa          * reset fourth column
    343 *
    344 srs9a:          btst    #1,vrbw09+1     * group 2 ?
    345                 beq     srs9b           * jump if not
    346 *
    347                 move.w  #10,COL(a7)     * put 1st column on stack
    348                 jsr     _vputa          * reset first column
    349                 move.w  #11,COL(a7)     * put 2nd column on stack
    350                 jsr     _vputa          * reset second column
    351                 move.w  #12,COL(a7)     * put 3rd column on stack
    352                 jsr     _vputa          * reset third column
    353                 move.w  #13,COL(a7)     * put 4th column on stack
    354                 jsr     _vputa          * reset fourth column
    355 *
    356 srs9b:          btst    #2,vrbw09+1     * group 3 ?
    357                 beq     srs9c           * jump if not
    358 *
    359                 move.w  #15,COL(a7)     * put 1st column on stack
    360                 jsr     _vputa          * reset first column
    361                 move.w  #16,COL(a7)     * put 2nd column on stack
    362                 jsr     _vputa          * reset second column
    363                 move.w  #17,COL(a7)     * put 3rd column on stack
    364                 jsr     _vputa          * reset third column
    365                 move.w  #18,COL(a7)     * put 4th column on stack
    366                 jsr     _vputa          * reset fourth column
    367 *
    368                 .page
    369 *
    370 srs9c:          btst    #3,vrbw09+1     * group 4 ?
    371                 beq     srs9d           * jump if not
    372 *
    373                 move.w  #20,COL(a7)     * put 1st column on stack
    374                 jsr     _vputa          * reset first column
    375                 move.w  #21,COL(a7)     * put 2nd column on stack
    376                 jsr     _vputa          * reset second column
    377                 move.w  #22,COL(a7)     * put 3rd column on stack
    378                 jsr     _vputa          * reset third column
    379                 move.w  #23,COL(a7)     * put 4th column on stack
    380                 jsr     _vputa          * reset fourth column
    381 *
    382 srs9d:          btst    #4,vrbw09+1     * group 5 ?
    383                 beq     srs9e           * jump if not
    384 *
    385                 move.w  #25,COL(a7)     * put 1st column on stack
    386                 jsr     _vputa          * reset first column
    387                 move.w  #26,COL(a7)     * put 2nd column on stack
    388                 jsr     _vputa          * reset second column
    389                 move.w  #27,COL(a7)     * put 3rd column on stack
    390                 jsr     _vputa          * reset third column
    391                 move.w  #28,COL(a7)     * put 4th column on stack
    392                 jsr     _vputa          * reset fourth column
    393 *
    394 srs9e:          btst    #5,vrbw09+1     * group 6 ?
    395                 beq     srs9f           * jump if not
    396 *
    397                 move.w  #30,COL(a7)     * put 1st column on stack
    398                 jsr     _vputa          * reset first column
    399                 move.w  #31,COL(a7)     * put 2nd column on stack
    400                 jsr     _vputa          * reset second column
    401                 move.w  #32,COL(a7)     * put 3rd column on stack
    402                 jsr     _vputa          * reset third column
    403                 move.w  #33,COL(a7)     * put 4th column on stack
    404                 jsr     _vputa          * reset fourth column
    405 *
    406                 .page
    407 *
    408 srs9f:          btst    #6,vrbw09+1     * group 7 ?
    409                 beq     srs9g           * jump if not
    410 *
    411                 move.w  #35,COL(a7)     * put 1st column on stack
    412                 jsr     _vputa          * reset first column
    413                 move.w  #36,COL(a7)     * put 2nd column on stack
    414                 jsr     _vputa          * reset second column
    415                 move.w  #37,COL(a7)     * put 3rd column on stack
    416                 jsr     _vputa          * reset third column
    417                 move.w  #38,COL(a7)     * put 4th column on stack
    418                 jsr     _vputa          * reset fourth column
    419 *
    420 srs9g:          btst    #7,vrbw09+1     * group 8 ?
    421                 beq     srs9h           * jump if not
    422 *
    423                 move.w  #40,COL(a7)     * put 1st column on stack
    424                 jsr     _vputa          * reset first column
    425                 move.w  #41,COL(a7)     * put 2nd column on stack
    426                 jsr     _vputa          * reset second column
    427                 move.w  #42,COL(a7)     * put 3rd column on stack
    428                 jsr     _vputa          * reset third column
    429                 move.w  #43,COL(a7)     * put 4th column on stack
    430                 jsr     _vputa          * reset fourth column
    431 *
    432 srs9h:          btst    #0,vrbw09       * group 9
    433                 beq     srs9j           * jump if not
    434 *
    435                 move.w  #45,COL(a7)     * put 1st column on stack
    436                 jsr     _vputa          * reset first column
    437                 move.w  #46,COL(a7)     * put 2nd column on stack
    438                 jsr     _vputa          * reset second column
    439                 move.w  #47,COL(a7)     * put 3rd column on stack
    440                 jsr     _vputa          * reset third column
    441                 move.w  #48,COL(a7)     * put 4th column on stack
    442                 jsr     _vputa          * reset fourth column
    443 *
    444                 .page
    445 *
    446 srs9j:          btst    #1,vrbw09       * group 10
    447                 beq     srs9k           * jump if not
    448 *
    449                 move.w  #50,COL(a7)     * put 1st column on stack
    450                 jsr     _vputa          * reset first column
    451                 move.w  #51,COL(a7)     * put 2nd column on stack
    452                 jsr     _vputa          * reset second column
    453                 move.w  #52,COL(a7)     * put 3rd column on stack
    454                 jsr     _vputa          * reset third column
    455                 move.w  #53,COL(a7)     * put 4th column on stack
    456                 jsr     _vputa          * reset fourth column
    457 *
    458 srs9k:          btst    #2,vrbw09       * group 11
    459                 beq     srs9m           * jump if not
    460 *
    461                 move.w  #55,COL(a7)     * put 1st column on stack
    462                 jsr     _vputa          * reset first column
    463                 move.w  #56,COL(a7)     * put 2nd column on stack
    464                 jsr     _vputa          * reset second column
    465                 move.w  #57,COL(a7)     * put 3rd column on stack
    466                 jsr     _vputa          * reset third column
    467                 move.w  #58,COL(a7)     * put 4th column on stack
    468                 jsr     _vputa          * reset fourth column
    469 *
    470 srs9m:          btst    #3,vrbw09       * group 12
    471                 beq     srs9x           * jump if not
    472 *
    473                 move.w  #60,COL(a7)     * put 1st column on stack
    474                 jsr     _vputa          * reset first column
    475                 move.w  #61,COL(a7)     * put 2nd column on stack
    476                 jsr     _vputa          * reset second column
    477                 move.w  #62,COL(a7)     * put 3rd column on stack
    478                 jsr     _vputa          * reset third column
    479                 move.w  #63,COL(a7)     * put 4th column on stack
    480                 jsr     _vputa          * reset fourth column
    481 *
    482 srs9x:          move.w  vrcw,d0         * restore vrcw to d0
    483 *
    484                 .page
    485 *
    486 * dynamics
    487 * --------
    488 srs10:          btst    #10,d0          * dynamics ?
    489                 beq     srs11           * jump if not
    490 *
    491                 move.w  #AT11,ATR(a7)   * put attribute on stack
    492                 move.w  #4,ROW(a7)      * put row on stack
    493                 btst    #0,vrbw10+1     * group 1 ?
    494                 beq     srs10a          * jump if not
    495 *
    496                 move.w  #6,COL(a7)      * put column on stack
    497                 jsr     _vputa          * reset column
    498 *
    499 srs10a:         btst    #1,vrbw10+1     * group 2 ?
    500                 beq     srs10b          * jump if not
    501 *
    502                 move.w  #11,COL(a7)     * put column on stack
    503                 jsr     _vputa          * reset column
    504 *
    505 srs10b:         btst    #2,vrbw10+1     * group 3 ?
    506                 beq     srs10c          * jump if not
    507 *
    508                 move.w  #16,COL(a7)     * put column on stack
    509                 jsr     _vputa          * reset column
    510 *
    511 srs10c:         btst    #3,vrbw10+1     * group 4 ?
    512                 beq     srs10d          * jump if not
    513 *
    514                 move.w  #21,COL(a7)     * put column on stack
    515                 jsr     _vputa          * reset column
    516 *
    517                 .page
    518 *
    519 srs10d:         btst    #4,vrbw10+1     * group 5 ?
    520                 beq     srs10e          * jump if not
    521 *
    522                 move.w  #26,COL(a7)     * put column on stack
    523                 jsr     _vputa          * reset column
    524 *
    525 srs10e:         btst    #5,vrbw10+1     * group 6 ?
    526                 beq     srs10f          * jump if not
    527 *
    528                 move.w  #31,COL(a7)     * put column on stack
    529                 jsr     _vputa          * reset column
    530 *
    531 srs10f:         btst    #6,vrbw10+1     * group 7 ?
    532                 beq     srs10g          * jump if not
    533 *
    534                 move.w  #36,COL(a7)     * put column on stack
    535                 jsr     _vputa          * reset column
    536 *
    537 srs10g:         btst    #7,vrbw10+1     * group 8 ?
    538                 beq     srs10h          * jump if not
    539 *
    540                 move.w  #41,COL(a7)     * put column on stack
    541                 jsr     _vputa          * reset column
    542 *
    543                 .page
    544 *
    545 srs10h:         btst    #0,vrbw10       * group 9
    546                 beq     srs10j          * jump if not
    547 *
    548                 move.w  #46,COL(a7)     * put column on stack
    549                 jsr     _vputa          * reset column
    550 *
    551 srs10j:         btst    #1,vrbw10       * group 10
    552                 beq     srs10k          * jump if not
    553 *
    554                 move.w  #51,COL(a7)     * put column on stack
    555                 jsr     _vputa          * reset column
    556 *
    557 srs10k:         btst    #2,vrbw10       * group 11
    558                 beq     srs10m          * jump if not
    559 *
    560                 move.w  #56,COL(a7)     * put column on stack
    561                 jsr     _vputa          * reset column
    562 *
    563 srs10m:         btst    #3,vrbw10       * group 12
    564                 beq     srs10x          * jump if not
    565 *
    566                 move.w  #61,COL(a7)     * put column on stack
    567                 jsr     _vputa          * reset column
    568 *
    569 srs10x:         move.w  vrcw,d0         * restore vrcw to d0
    570 *
    571                 .page
    572 *
    573 * location
    574 * --------
    575 srs11:          btst    #11,d0          * location ?
    576                 beq     srs12           * jump if not
    577 *
    578                 move.w  #AT11,ATR(a7)   * put attribute on stack
    579                 move.w  #4,ROW(a7)      * put row on stack
    580                 btst    #0,vrbw11+1     * group 1 ?
    581                 beq     srs11a          * jump if not
    582 *
    583                 move.w  #8,COL(a7)      * put column on stack
    584                 jsr     _vputa          * reset column
    585 *
    586 srs11a:         btst    #1,vrbw11+1     * group 2 ?
    587                 beq     srs11b          * jump if not
    588 *
    589                 move.w  #13,COL(a7)     * put column on stack
    590                 jsr     _vputa          * reset column
    591 *
    592 srs11b:         btst    #2,vrbw11+1     * group 3 ?
    593                 beq     srs11c          * jump if not
    594 *
    595                 move.w  #18,COL(a7)     * put column on stack
    596                 jsr     _vputa          * reset column
    597 *
    598 srs11c:         btst    #3,vrbw11+1     * group 4 ?
    599                 beq     srs11d          * jump if not
    600 *
    601                 move.w  #23,COL(a7)     * put column on stack
    602                 jsr     _vputa          * reset column
    603 *
    604                 .page
    605 *
    606 srs11d:         btst    #4,vrbw11+1     * group 5 ?
    607                 beq     srs11e          * jump if not
    608 *
    609                 move.w  #28,COL(a7)     * put column on stack
    610                 jsr     _vputa          * reset column
    611 *
    612 srs11e:         btst    #5,vrbw11+1     * group 6 ?
    613                 beq     srs11f          * jump if not
    614 *
    615                 move.w  #33,COL(a7)     * put column on stack
    616                 jsr     _vputa          * reset column
    617 *
    618 srs11f:         btst    #6,vrbw11+1     * group 7 ?
    619                 beq     srs11g          * jump if not
    620 *
    621                 move.w  #38,COL(a7)     * put column on stack
    622                 jsr     _vputa          * reset column
    623 *
    624 srs11g:         btst    #7,vrbw11+1     * group 8 ?
    625                 beq     srs11h          * jump if not
    626 *
    627                 move.w  #43,COL(a7)     * put column on stack
    628                 jsr     _vputa          * reset column
    629 *
    630                 .page
    631 *
    632 srs11h:         btst    #0,vrbw11       * group 9
    633                 beq     srs11j          * jump if not
    634 *
    635                 move.w  #48,COL(a7)     * put column on stack
    636                 jsr     _vputa          * reset column
    637 *
    638 srs11j:         btst    #1,vrbw11       * group 10
    639                 beq     srs11k          * jump if not
    640 *
    641                 move.w  #53,COL(a7)     * put column on stack
    642                 jsr     _vputa          * reset column
    643 *
    644 srs11k:         btst    #2,vrbw11       * group 11
    645                 beq     srs11m          * jump if not
    646 *
    647                 move.w  #58,COL(a7)     * put column on stack
    648                 jsr     _vputa          * reset column
    649 *
    650 srs11m:         btst    #3,vrbw11       * group 12
    651                 beq     srs11x          * jump if not
    652 *
    653                 move.w  #63,COL(a7)     * put column on stack
    654                 jsr     _vputa          * reset column
    655 *
    656 srs11x:         move.w  vrcw,d0         * restore vrcw to d0
    657 *
    658                 .page
    659 *
    660 * velocity
    661 * --------
    662 srs12:          btst    #12,d0          * velocity ?
    663                 beq     srs13           * jump if not
    664 *
    665                 move.w  #AT11,ATR(a7)   * put attribute on stack
    666                 move.w  #5,ROW(a7)      * put row on stack
    667                 btst    #0,vrbw12+1     * group 1 ?
    668                 beq     srs12a          * jump if not
    669 *
    670                 move.w  #6,COL(a7)      * put 1st column on stack
    671                 jsr     _vputa          * reset first column
    672                 move.w  #7,COL(a7)      * put 2nd column on stack
    673                 jsr     _vputa          * reset second column
    674                 move.w  #8,COL(a7)      * put 3rd column on stack
    675                 jsr     _vputa          * reset third column
    676 *
    677 srs12a:         btst    #1,vrbw12+1     * group 2 ?
    678                 beq     srs12b          * jump if not
    679 *
    680                 move.w  #11,COL(a7)     * put 1st column on stack
    681                 jsr     _vputa          * reset first column
    682                 move.w  #12,COL(a7)     * put 2nd column on stack
    683                 jsr     _vputa          * reset second column
    684                 move.w  #13,COL(a7)     * put 3rd column on stack
    685                 jsr     _vputa          * reset third column
    686 *
    687 srs12b:         btst    #2,vrbw12+1     * group 3 ?
    688                 beq     srs12c          * jump if not
    689 *
    690                 move.w  #16,COL(a7)     * put 1st column on stack
    691                 jsr     _vputa          * reset first column
    692                 move.w  #17,COL(a7)     * put 2nd column on stack
    693                 jsr     _vputa          * reset second column
    694                 move.w  #18,COL(a7)     * put 3rd column on stack
    695                 jsr     _vputa          * reset third column
    696 *
    697                 .page
    698 *
    699 srs12c:         btst    #3,vrbw12+1     * group 4 ?
    700                 beq     srs12d          * jump if not
    701 *
    702                 move.w  #21,COL(a7)     * put 1st column on stack
    703                 jsr     _vputa          * reset first column
    704                 move.w  #22,COL(a7)     * put 2nd column on stack
    705                 jsr     _vputa          * reset second column
    706                 move.w  #23,COL(a7)     * put 3rd column on stack
    707                 jsr     _vputa          * reset third column
    708 *
    709 srs12d:         btst    #4,vrbw12+1     * group 5 ?
    710                 beq     srs12e          * jump if not
    711 *
    712                 move.w  #26,COL(a7)     * put 1st column on stack
    713                 jsr     _vputa          * reset first column
    714                 move.w  #27,COL(a7)     * put 2nd column on stack
    715                 jsr     _vputa          * reset second column
    716                 move.w  #28,COL(a7)     * put 3rd column on stack
    717                 jsr     _vputa          * reset third column
    718 *
    719 srs12e:         btst    #5,vrbw12+1     * group 6 ?
    720                 beq     srs12f          * jump if not
    721 *
    722                 move.w  #31,COL(a7)     * put 1st column on stack
    723                 jsr     _vputa          * reset first column
    724                 move.w  #32,COL(a7)     * put 2nd column on stack
    725                 jsr     _vputa          * reset second column
    726                 move.w  #33,COL(a7)     * put 3rd column on stack
    727                 jsr     _vputa          * reset third column
    728 *
    729                 .page
    730 *
    731 srs12f:         btst    #6,vrbw12+1     * group 7 ?
    732                 beq     srs12g          * jump if not
    733 *
    734                 move.w  #36,COL(a7)     * put 1st column on stack
    735                 jsr     _vputa          * reset first column
    736                 move.w  #37,COL(a7)     * put 2nd column on stack
    737                 jsr     _vputa          * reset second column
    738                 move.w  #38,COL(a7)     * put 3rd column on stack
    739                 jsr     _vputa          * reset third column
    740 *
    741 srs12g:         btst    #7,vrbw12+1     * group 8 ?
    742                 beq     srs12h          * jump if not
    743 *
    744                 move.w  #41,COL(a7)     * put 1st column on stack
    745                 jsr     _vputa          * reset first column
    746                 move.w  #42,COL(a7)     * put 2nd column on stack
    747                 jsr     _vputa          * reset second column
    748                 move.w  #43,COL(a7)     * put 3rd column on stack
    749                 jsr     _vputa          * reset third column
    750 *
    751 srs12h:         btst    #0,vrbw12       * group 9
    752                 beq     srs12j          * jump if not
    753 *
    754                 move.w  #46,COL(a7)     * put 1st column on stack
    755                 jsr     _vputa          * reset first column
    756                 move.w  #47,COL(a7)     * put 2nd column on stack
    757                 jsr     _vputa          * reset second column
    758                 move.w  #48,COL(a7)     * put 3rd column on stack
    759                 jsr     _vputa          * reset third column
    760 *
    761                 .page
    762 *
    763 srs12j:         btst    #1,vrbw12       * group 10
    764                 beq     srs12k          * jump if not
    765 *
    766                 move.w  #51,COL(a7)     * put 1st column on stack
    767                 jsr     _vputa          * reset first column
    768                 move.w  #52,COL(a7)     * put 2nd column on stack
    769                 jsr     _vputa          * reset second column
    770                 move.w  #53,COL(a7)     * put 3rd column on stack
    771                 jsr     _vputa          * reset third column
    772 *
    773 srs12k:         btst    #2,vrbw12       * group 11
    774                 beq     srs12m          * jump if not
    775 *
    776                 move.w  #56,COL(a7)     * put 1st column on stack
    777                 jsr     _vputa          * reset first column
    778                 move.w  #57,COL(a7)     * put 2nd column on stack
    779                 jsr     _vputa          * reset second column
    780                 move.w  #58,COL(a7)     * put 3rd column on stack
    781                 jsr     _vputa          * reset third column
    782 *
    783 srs12m:         btst    #3,vrbw12       * group 12
    784                 beq     srs12x          * jump if not
    785 *
    786                 move.w  #61,COL(a7)     * put 1st column on stack
    787                 jsr     _vputa          * reset first column
    788                 move.w  #62,COL(a7)     * put 2nd column on stack
    789                 jsr     _vputa          * reset second column
    790                 move.w  #63,COL(a7)     * put 3rd column on stack
    791                 jsr     _vputa          * reset third column
    792 *
    793 srs12x:         move.w  vrcw,d0         * restore vrcw to d0
    794 *
    795                 .page
    796 *
    797 * resolution
    798 * ----------
    799 srs13:          btst    #13,d0          * resolution ?
    800                 beq     srs14           * jump if not
    801 *
    802                 move.w  #AT12,ATR(a7)   * put attribute on stack
    803                 move.w  #7,ROW(a7)      * put row on stack
    804                 btst    #0,vrbw13+1     * variable 1 ?
    805                 beq     srs13a          * jump if not
    806 *
    807                 move.w  #6,COL(a7)      * put column on stack
    808                 jsr     _vputa          * reset column
    809 *
    810 srs13a:         btst    #1,vrbw13+1     * variable 2 ?
    811                 beq     srs13b          * jump if not
    812 *
    813                 move.w  #15,COL(a7)     * put column on stack
    814                 jsr     _vputa          * reset column
    815 *
    816 srs13b:         btst    #2,vrbw13+1     * variable 3 ?
    817                 beq     srs13c          * jump if not
    818 *
    819                 move.w  #24,COL(a7)     * put column on stack
    820                 jsr     _vputa          * reset column
    821 *
    822 srs13c:         btst    #3,vrbw13+1     * variable 4 ?
    823                 beq     srs13d          * jump if not
    824 *
    825                 move.w  #33,COL(a7)     * put column on stack
    826                 jsr     _vputa          * reset column
    827 *
    828 srs13d:         btst    #4,vrbw13+1     * variable 5 ?
    829                 beq     srs13e          * jump if not
    830 *
    831                 move.w  #42,COL(a7)     * put column on stack
    832                 jsr     _vputa          * reset column
    833 *
    834 srs13e:         btst    #5,vrbw13+1     * variable 6 ?
    835                 beq     srs13x          * jump if not
    836 *
    837                 move.w  #51,COL(a7)     * put column on stack
    838                 jsr     _vputa          * reset column
    839 *
    840 srs13x:         move.w  vrcw,d0         * restore vrcw to d0
    841 *
    842                 .page
    843 *
    844 * analog value
    845 * ------------
    846 srs14:          btst    #14,d0          * analog value ?
    847                 beq     srs15           * jump if not
    848 *
    849                 move.w  #AT12,ATR(a7)   * put attribute on stack
    850                 move.w  #7,ROW(a7)      * put row on stack
    851                 btst    #0,vrbw14+1     * variable 1 ?
    852                 beq     srs14a          * jump if not
    853 *
    854                 move.w  #8,COL(a7)      * put 1st column on stack
    855                 jsr     _vputa          * reset first column
    856                 move.w  #9,COL(a7)      * put 2nd column on stack
    857                 jsr     _vputa          * reset second column
    858                 move.w  #10,COL(a7)     * put 3rd column on stack
    859                 jsr     _vputa          * reset third column
    860                 move.w  #11,COL(a7)     * put 4th column on stack
    861                 jsr     _vputa          * reset fourth column
    862                 move.w  #12,COL(a7)     * put 5th column on stack
    863                 jsr     _vputa          * reset fifth column
    864 *
    865 srs14a:         btst    #1,vrbw14+1     * variable 2 ?
    866                 beq     srs14b          * jump if not
    867 *
    868                 move.w  #17,COL(a7)     * put 1st column on stack
    869                 jsr     _vputa          * reset first column
    870                 move.w  #18,COL(a7)     * put 2nd column on stack
    871                 jsr     _vputa          * reset second column
    872                 move.w  #19,COL(a7)     * put 3rd column on stack
    873                 jsr     _vputa          * reset third column
    874                 move.w  #20,COL(a7)     * put 4th column on stack
    875                 jsr     _vputa          * reset fourth column
    876                 move.w  #21,COL(a7)     * put 5th column on stack
    877                 jsr     _vputa          * reset fifth column
    878 *
    879                 .page
    880 *
    881 srs14b:         btst    #2,vrbw14+1     * variable 3 ?
    882                 beq     srs14c          * jump if not
    883 *
    884                 move.w  #26,COL(a7)     * put 1st column on stack
    885                 jsr     _vputa          * reset first column
    886                 move.w  #27,COL(a7)     * put 2nd column on stack
    887                 jsr     _vputa          * reset second column
    888                 move.w  #28,COL(a7)     * put 3rd column on stack
    889                 jsr     _vputa          * reset third column
    890                 move.w  #29,COL(a7)     * put 4th column on stack
    891                 jsr     _vputa          * reset fourth column
    892                 move.w  #30,COL(a7)     * put 5th column on stack
    893                 jsr     _vputa          * reset fifth column
    894 *
    895 srs14c:         btst    #3,vrbw14+1     * variable 4 ?
    896                 beq     srs14d          * jump if not
    897 *
    898                 move.w  #35,COL(a7)     * put 1st column on stack
    899                 jsr     _vputa          * reset first column
    900                 move.w  #36,COL(a7)     * put 2nd column on stack
    901                 jsr     _vputa          * reset second column
    902                 move.w  #37,COL(a7)     * put 3rd column on stack
    903                 jsr     _vputa          * reset third column
    904                 move.w  #38,COL(a7)     * put 4th column on stack
    905                 jsr     _vputa          * reset fourth column
    906                 move.w  #39,COL(a7)     * put 5th column on stack
    907                 jsr     _vputa          * reset fifth column
    908 *
    909                 .page
    910 *
    911 srs14d:         btst    #4,vrbw14+1     * variable 5 ?
    912                 beq     srs14e          * jump if not
    913 *
    914                 move.w  #44,COL(a7)     * put 1st column on stack
    915                 jsr     _vputa          * reset first column
    916                 move.w  #45,COL(a7)     * put 2nd column on stack
    917                 jsr     _vputa          * reset second column
    918                 move.w  #46,COL(a7)     * put 3rd column on stack
    919                 jsr     _vputa          * reset third column
    920                 move.w  #47,COL(a7)     * put 4th column on stack
    921                 jsr     _vputa          * reset fourth column
    922                 move.w  #48,COL(a7)     * put 5th column on stack
    923                 jsr     _vputa          * reset fifth column
    924 *
    925 srs14e:         btst    #5,vrbw14+1     * variable 6 ?
    926                 beq     srs14x          * jump if not
    927 *
    928                 move.w  #53,COL(a7)     * put 1st column on stack
    929                 jsr     _vputa          * reset first column
    930                 move.w  #54,COL(a7)     * put 2nd column on stack
    931                 jsr     _vputa          * reset second column
    932                 move.w  #55,COL(a7)     * put 3rd column on stack
    933                 jsr     _vputa          * reset third column
    934                 move.w  #56,COL(a7)     * put 4th column on stack
    935                 jsr     _vputa          * reset fourth column
    936                 move.w  #57,COL(a7)     * put 5th column on stack
    937                 jsr     _vputa          * reset fifth column
    938 *
    939 srs14x:         move.w  vrcw,d0         * restore vrcw to d0
    940 *
    941                 .page
    942 *
    943 * stop/next
    944 * ---------
    945 srs15:          btst    #15,d0          * stop/next ?
    946                 beq     srs16           * jump if not
    947 *
    948                 btst    #0,vrbw15       * stop ?
    949                 beq     srs15a          * jump if not
    950 *
    951                 move.w  #AT08,ATR(a7)   * put attribute on stack
    952                 move.w  #1,ROW(a7)      * put row on stack
    953                 move.w  #40,COL(a7)     * put 1st column on stack
    954                 jsr     _vputa          * reset first column
    955                 move.w  #41,COL(a7)     * put 2nd column on stack
    956                 jsr     _vputa          * reset second column
    957                 move.w  #42,COL(a7)     * put 3rd column on stack
    958                 jsr     _vputa          * reset third column
    959                 move.w  #43,COL(a7)     * put 4th column on stack
    960                 jsr     _vputa          * reset fourth column
    961 *
    962 srs15a:         btst    #1,vrbw15       * next ?
    963                 beq     srs16           * jump if not
    964 *
    965                 move.w  #AT08,ATR(a7)   * put attribute on stack
    966                 move.w  #1,ROW(a7)      * put row on stack
    967                 move.w  #45,COL(a7)     * put 1st column on stack
    968                 jsr     _vputa          * reset first column
    969                 move.w  #46,COL(a7)     * put 2nd column on stack
    970                 jsr     _vputa          * reset second column
    971                 move.w  #47,COL(a7)     * put 3rd column on stack
    972                 jsr     _vputa          * reset third column
    973                 move.w  #48,COL(a7)     * put 4th column on stack
    974                 jsr     _vputa          * reset fourth column
    975 *
    976 srs16:          add.l   #10,a7          * clean up stack
    977                 bra     srsexit         * done
    978 *
    979                 .page
    980 *
     6
     7                .xdef   _sreset         | sreset()
     8
     9                .xref   _vputa          | vputa(sbase, row, col, attrib)
     10
     11                .xref   _ndisp          | WORD - display number
     12                .xref   _obj8           | LONG - object base address
     13                .xref   _vrbw08         | WORD - detail word for bit 8
     14                .xref   _vrbw09         | WORD - detail word for bit 9
     15                .xref   _vrbw10         | WORD - detail word for bit 10
     16                .xref   _vrbw11         | WORD - detail word for bit 11
     17                .xref   _vrbw12         | WORD - detail word for bit 12
     18                .xref   _vrbw13         | WORD - detail word for bit 13
     19                .xref   _vrbw14         | WORD - detail word for bit 14
     20                .xref   _vrbw15         | WORD - detail word for bit 15
     21                .xref   _vrcw           | WORD - video reset control word
     22
     23ROW             =       4
     24COL             =       6
     25ATR             =       8
     26
     27AT01            =       0x0014
     28AT04            =       0x0013
     29AT05            =       0x0014
     30AT06            =       0x0013
     31AT07            =       0x0014
     32AT08            =       0x0013
     33AT09            =       0x0014
     34AT10            =       0x0013
     35AT11            =       0x0012
     36AT12            =       0x0012
     37
     38                .page
     39
     40| sreset() -- reset highlighting
     41| --------    ------------------
     42_sreset:        link    a6,#0           | link stack frame
     43                cmp.w   #2,_ndisp       | see if we should update display
     44                bne     srsexit         | jump if not
     45
     46                move.w  _vrcw,d0        | get and check vrcw
     47                bne     srs0            | jump if something to do
     48
     49srsexit:        unlk    a6              | unlink stack frame
     50                rts                     | return to caller
     51
     52srs0:           move.w  sr,d1           | <<<<< disable interrupts >>>>>
     53                ori.w   #0x0700,sr      | ...
     54
     55                move.w  _vrcw,vrcw      | make local copies of control variables
     56                clr.w   _vrcw           | ... and clear them for the next pass
     57                move.w  _vrbw08,vrbw08  | ...
     58                clr.w   _vrbw08         | ...
     59                move.w  _vrbw09,vrbw09  | ...
     60                clr.w   _vrbw09         | ...
     61                move.w  _vrbw10,vrbw10  | ...
     62                clr.w   _vrbw10         | ...
     63                move.w  _vrbw11,vrbw11  | ...
     64                clr.w   _vrbw11         | ...
     65                move.w  _vrbw12,vrbw12  | ...
     66                clr.w   _vrbw12         | ...
     67                move.w  _vrbw13,vrbw13  | ...
     68                clr.w   _vrbw13         | ...
     69                move.w  _vrbw14,vrbw14  | ...
     70                clr.w   _vrbw14         | ...
     71                move.w  _vrbw15,vrbw15  | ...
     72                clr.w   _vrbw15         | ...
     73
     74                move.w  d1,sr           | <<<<< restore interrupts >>>>>
     75
     76| Setup STACK for subsequent calls to vputa(sbase, row, col, atr):
     77
     78|       0(a7)   sbase
     79
     80|       4(a7)   row     ROW
     81|       6(a7)   col     COL
     82|       8(a7)   atr     ATR
     83
     84                clr.w   -(a7)           | put dummy attribute on stack
     85                clr.w   -(a7)           | put dummy column on stack
     86                clr.w   -(a7)           | put dummy row on stack
     87                move.l  _obj8,-(a7)     | put sbase on stack
     88
     89                .page
     90
     91| assignment
     92| ----------
     93                btst    #0,d0           | assignment ?
     94                beq     srs1            | jump if not
     95
     96                move.w  #AT04,ATR(a7)   | put attribute on stack
     97                move.w  #1,ROW(a7)      | put row on stack
     98                move.w  #11,COL(a7)     | put 1st column on stack
     99                jsr     _vputa          | reset first column
     100                move.w  #12,COL(a7)     | put 2nd column on stack
     101                jsr     _vputa          | reset second column
     102                move.w  vrcw,d0         | restore vrcw to d0
     103
     104| tuning
     105| ------
     106srs1:           btst    #1,d0           | tuning ?
     107                beq     srs2            | jump if not
     108
     109                move.w  #AT05,ATR(a7)   | put attribute on stack
     110                move.w  #1,ROW(a7)      | put row on stack
     111                move.w  #19,COL(a7)     | put column on stack
     112                jsr     _vputa          | reset column
     113                move.w  vrcw,d0         | restore vrcw to d0
     114
     115| tempo
     116| -----
     117srs2:           btst    #2,d0           | tempo ?
     118                beq     srs3            | jump if not
     119
     120                move.w  #AT06,ATR(a7)   | put attribute on stack
     121                move.w  #1,ROW(a7)      | put row on stack
     122                move.w  #27,COL(a7)     | put 1st column on stack
     123                jsr     _vputa          | reset first column
     124                move.w  #28,COL(a7)     | put 2nd column on stack
     125                jsr     _vputa          | reset second column
     126                move.w  #29,COL(a7)     | put 3rd column on stack
     127                jsr     _vputa          | reset third column
     128                move.w  vrcw,d0         | restore vrcw to d0
     129
     130                .page
     131
     132| interpolate
     133| -----------
     134srs3:           btst    #3,d0           | interpolate ?
     135                beq     srs4            | jump if not
     136
     137                move.w  #AT07,ATR(a7)   | put attribute on stack
     138                move.w  #1,ROW(a7)      | put row on stack
     139                move.w  #35,COL(a7)     | put 1st column on stack
     140                jsr     _vputa          | reset first column
     141                move.w  #36,COL(a7)     | put 2nd column on stack
     142                jsr     _vputa          | reset second column
     143                move.w  #37,COL(a7)     | put 3rd column on stack
     144                jsr     _vputa          | reset third column
     145                move.w  #38,COL(a7)     | put 4th column on stack
     146                jsr     _vputa          | reset fourth column
     147                move.w  vrcw,d0         | restore vrcw to d0
     148
     149| section begin
     150| -------------
     151srs4:           btst    #4,d0           | section begin ?
     152                beq     srs5            | jump if not
     153
     154                move.w  #AT01,ATR(a7)   | put attribute on stack
     155                move.w  #0,ROW(a7)      | put row on stack
     156                move.w  #6,COL(a7)      | put 1st column on stack
     157                jsr     _vputa          | reset first column
     158                move.w  #7,COL(a7)      | put 2nd column on stack
     159                jsr     _vputa          | reset second column
     160
     161                .page
     162
     163| punch in
     164| --------
     165srs5:           btst    #5,d0           | punch in ?
     166                beq     srs6            | jump if not
     167
     168                move.w  #AT09,ATR(a7)   | put attribute on stack
     169                move.w  #1,ROW(a7)      | put row on stack
     170                move.w  #50,COL(a7)     | put 1st column on stack
     171                jsr     _vputa          | reset first column
     172                move.w  #51,COL(a7)     | put 2nd column on stack
     173                jsr     _vputa          | reset second column
     174                move.w  vrcw,d0         | restore vrcw to d0
     175
     176| punch out
     177| ---------
     178srs6:           btst    #6,d0           | punch out ?
     179                beq     srs7            | jump if not
     180
     181                move.w  #AT09,ATR(a7)   | put attribute on stack
     182                move.w  #1,ROW(a7)      | put row on stack
     183                move.w  #53,COL(a7)     | put 1st column on stack
     184                jsr     _vputa          | reset first column
     185                move.w  #54,COL(a7)     | put 2nd column on stack
     186                jsr     _vputa          | reset second column
     187                move.w  #55,COL(a7)     | put 3rd column on stack
     188                jsr     _vputa          | reset third column
     189                move.w  vrcw,d0         | restore vrcw to d0
     190
     191| Output
     192| ------
     193srs7:           btst    #7,d0           | output ?
     194                beq     srs8            | jump if not
     195
     196                move.w  #AT10,ATR(a7)   | put attribute on stack
     197                move.w  #1,ROW(a7)      | put row on stack
     198                move.w  #57,COL(a7)     | put 1st column on stack
     199                jsr     _vputa          | reset first column
     200                move.w  #58,COL(a7)     | put 2nd column on stack
     201                jsr     _vputa          | reset second column
     202                move.w  #59,COL(a7)     | put 3rd column on stack
     203                jsr     _vputa          | reset third column
     204                move.w  #60,COL(a7)     | put 4th column on stack
     205                jsr     _vputa          | reset fourth column
     206                move.w  #61,COL(a7)     | put 5th column on stack
     207                jsr     _vputa          | reset fifth column
     208                move.w  #62,COL(a7)     | put 6th column on stack
     209                jsr     _vputa          | reset sixth column
     210                move.w  vrcw,d0         | restore vrcw to d0
     211
     212                .page
     213
     214| instrument
     215| ----------
     216srs8:           btst    #8,d0           | instrument ?
     217                beq     srs9            | jump if not
     218
     219                move.w  #2,ROW(a7)      | put row on stack
     220                move.w  #AT11,ATR(a7)   | put attribute on stack
     221                btst    #0,vrbw08+1     | group 1 ?
     222                beq     srs8a           | jump if not
     223
     224                move.w  #7,COL(a7)      | put 1st column on stack
     225                jsr     _vputa          | reset first column
     226                move.w  #8,COL(a7)      | put 2nd column on stack
     227                jsr     _vputa          | reset second column
     228
     229srs8a:          btst    #1,vrbw08+1     | group 2 ?
     230                beq     srs8b           | jump if not
     231
     232                move.w  #12,COL(a7)     | put 1st column on stack
     233                jsr     _vputa          | reset first character
     234                move.w  #13,COL(a7)     | put 2nd column on stack
     235                jsr     _vputa          | reset second character
     236
     237srs8b:          btst    #2,vrbw08+1     | group 3 ?
     238                beq     srs8c           | jump if not
     239
     240                move.w  #17,COL(a7)     | put 1st column on stack
     241                jsr     _vputa          | reset first character
     242                move.w  #18,COL(a7)     | put 2nd column on stack
     243                jsr     _vputa          | reset second character
     244
     245srs8c:          btst    #3,vrbw08+1     | group 4 ?
     246                beq     srs8d           | jump if not
     247
     248                move.w  #22,COL(a7)     | put 1st column on stack
     249                jsr     _vputa          | reset first character
     250                move.w  #23,COL(a7)     | put 2nd column on stack
     251                jsr     _vputa          | reset second character
     252
     253                .page
     254
     255srs8d:          btst    #4,vrbw08+1     | group 5 ?
     256                beq     srs8e           | jump if not
     257
     258                move.w  #27,COL(a7)     | put 1st column on stack
     259                jsr     _vputa          | reset first character
     260                move.w  #28,COL(a7)     | put 2nd column on stack
     261                jsr     _vputa          | reset second character
     262
     263srs8e:          btst    #5,vrbw08+1     | group 6 ?
     264                beq     srs8f           | jump if not
     265
     266                move.w  #32,COL(a7)     | put 1st column on stack
     267                jsr     _vputa          | reset first character
     268                move.w  #33,COL(a7)     | put 2nd column on stack
     269                jsr     _vputa          | reset second character
     270
     271srs8f:          btst    #6,vrbw08+1     | group 7 ?
     272                beq     srs8g           | jump if not
     273
     274                move.w  #37,COL(a7)     | put 1st column on stack
     275                jsr     _vputa          | reset first character
     276                move.w  #38,COL(a7)     | put 2nd column on stack
     277                jsr     _vputa          | reset second character
     278
     279srs8g:          btst    #7,vrbw08+1     | group 8 ?
     280                beq     srs8h           | jump if not
     281
     282                move.w  #42,COL(a7)     | put 1st column on stack
     283                jsr     _vputa          | reset first character
     284                move.w  #43,COL(a7)     | put 2nd column on stack
     285                jsr     _vputa          | reset second character
     286
     287                .page
     288
     289srs8h:          btst    #0,vrbw08       | group 9
     290                beq     srs8j           | jump if not
     291
     292                move.w  #47,COL(a7)     | put 1st column on stack
     293                jsr     _vputa          | reset first character
     294                move.w  #48,COL(a7)     | put 2nd column on stack
     295                jsr     _vputa          | reset second character
     296
     297srs8j:          btst    #1,vrbw08       | group 10
     298                beq     srs8k           | jump if not
     299
     300                move.w  #52,COL(a7)     | put 1st column on stack
     301                jsr     _vputa          | reset first character
     302                move.w  #53,COL(a7)     | put 2nd column on stack
     303                jsr     _vputa          | reset second character
     304
     305srs8k:          btst    #2,vrbw08       | group 11
     306                beq     srs8m           | jump if not
     307
     308                move.w  #57,COL(a7)     | put 1st column on stack
     309                jsr     _vputa          | reset first character
     310                move.w  #58,COL(a7)     | put 2nd column on stack
     311                jsr     _vputa          | reset second character
     312
     313srs8m:          btst    #3,vrbw08       | group 12
     314                beq     srs8x           | jump if not
     315
     316                move.w  #62,COL(a7)     | put 1st column on stack
     317                jsr     _vputa          | reset first character
     318                move.w  #63,COL(a7)     | put 2nd column on stack
     319                jsr     _vputa          | reset second character
     320
     321srs8x:          move.w  vrcw,d0         | restore vrcw to d0
     322
     323                .page
     324
     325| transpose
     326| ---------
     327srs9:           btst    #9,d0           | transpose ?
     328                beq     srs10           | jump if not
     329
     330                move.w  #AT11,ATR(a7)   | put attribute on stack
     331                move.w  #3,ROW(a7)      | put row on stack
     332                btst    #0,vrbw09+1     | group 1 ?
     333                beq     srs9a           | jump if not
     334
     335                move.w  #5,COL(a7)      | put 1st column on stack
     336                jsr     _vputa          | reset first column
     337                move.w  #6,COL(a7)      | put 2nd column on stack
     338                jsr     _vputa          | reset second column
     339                move.w  #7,COL(a7)      | put 3rd column on stack
     340                jsr     _vputa          | reset third column
     341                move.w  #8,COL(a7)      | put 4th column on stack
     342                jsr     _vputa          | reset fourth column
     343
     344srs9a:          btst    #1,vrbw09+1     | group 2 ?
     345                beq     srs9b           | jump if not
     346
     347                move.w  #10,COL(a7)     | put 1st column on stack
     348                jsr     _vputa          | reset first column
     349                move.w  #11,COL(a7)     | put 2nd column on stack
     350                jsr     _vputa          | reset second column
     351                move.w  #12,COL(a7)     | put 3rd column on stack
     352                jsr     _vputa          | reset third column
     353                move.w  #13,COL(a7)     | put 4th column on stack
     354                jsr     _vputa          | reset fourth column
     355
     356srs9b:          btst    #2,vrbw09+1     | group 3 ?
     357                beq     srs9c           | jump if not
     358
     359                move.w  #15,COL(a7)     | put 1st column on stack
     360                jsr     _vputa          | reset first column
     361                move.w  #16,COL(a7)     | put 2nd column on stack
     362                jsr     _vputa          | reset second column
     363                move.w  #17,COL(a7)     | put 3rd column on stack
     364                jsr     _vputa          | reset third column
     365                move.w  #18,COL(a7)     | put 4th column on stack
     366                jsr     _vputa          | reset fourth column
     367
     368                .page
     369
     370srs9c:          btst    #3,vrbw09+1     | group 4 ?
     371                beq     srs9d           | jump if not
     372
     373                move.w  #20,COL(a7)     | put 1st column on stack
     374                jsr     _vputa          | reset first column
     375                move.w  #21,COL(a7)     | put 2nd column on stack
     376                jsr     _vputa          | reset second column
     377                move.w  #22,COL(a7)     | put 3rd column on stack
     378                jsr     _vputa          | reset third column
     379                move.w  #23,COL(a7)     | put 4th column on stack
     380                jsr     _vputa          | reset fourth column
     381
     382srs9d:          btst    #4,vrbw09+1     | group 5 ?
     383                beq     srs9e           | jump if not
     384
     385                move.w  #25,COL(a7)     | put 1st column on stack
     386                jsr     _vputa          | reset first column
     387                move.w  #26,COL(a7)     | put 2nd column on stack
     388                jsr     _vputa          | reset second column
     389                move.w  #27,COL(a7)     | put 3rd column on stack
     390                jsr     _vputa          | reset third column
     391                move.w  #28,COL(a7)     | put 4th column on stack
     392                jsr     _vputa          | reset fourth column
     393
     394srs9e:          btst    #5,vrbw09+1     | group 6 ?
     395                beq     srs9f           | jump if not
     396
     397                move.w  #30,COL(a7)     | put 1st column on stack
     398                jsr     _vputa          | reset first column
     399                move.w  #31,COL(a7)     | put 2nd column on stack
     400                jsr     _vputa          | reset second column
     401                move.w  #32,COL(a7)     | put 3rd column on stack
     402                jsr     _vputa          | reset third column
     403                move.w  #33,COL(a7)     | put 4th column on stack
     404                jsr     _vputa          | reset fourth column
     405
     406                .page
     407
     408srs9f:          btst    #6,vrbw09+1     | group 7 ?
     409                beq     srs9g           | jump if not
     410
     411                move.w  #35,COL(a7)     | put 1st column on stack
     412                jsr     _vputa          | reset first column
     413                move.w  #36,COL(a7)     | put 2nd column on stack
     414                jsr     _vputa          | reset second column
     415                move.w  #37,COL(a7)     | put 3rd column on stack
     416                jsr     _vputa          | reset third column
     417                move.w  #38,COL(a7)     | put 4th column on stack
     418                jsr     _vputa          | reset fourth column
     419
     420srs9g:          btst    #7,vrbw09+1     | group 8 ?
     421                beq     srs9h           | jump if not
     422
     423                move.w  #40,COL(a7)     | put 1st column on stack
     424                jsr     _vputa          | reset first column
     425                move.w  #41,COL(a7)     | put 2nd column on stack
     426                jsr     _vputa          | reset second column
     427                move.w  #42,COL(a7)     | put 3rd column on stack
     428                jsr     _vputa          | reset third column
     429                move.w  #43,COL(a7)     | put 4th column on stack
     430                jsr     _vputa          | reset fourth column
     431
     432srs9h:          btst    #0,vrbw09       | group 9
     433                beq     srs9j           | jump if not
     434
     435                move.w  #45,COL(a7)     | put 1st column on stack
     436                jsr     _vputa          | reset first column
     437                move.w  #46,COL(a7)     | put 2nd column on stack
     438                jsr     _vputa          | reset second column
     439                move.w  #47,COL(a7)     | put 3rd column on stack
     440                jsr     _vputa          | reset third column
     441                move.w  #48,COL(a7)     | put 4th column on stack
     442                jsr     _vputa          | reset fourth column
     443
     444                .page
     445
     446srs9j:          btst    #1,vrbw09       | group 10
     447                beq     srs9k           | jump if not
     448
     449                move.w  #50,COL(a7)     | put 1st column on stack
     450                jsr     _vputa          | reset first column
     451                move.w  #51,COL(a7)     | put 2nd column on stack
     452                jsr     _vputa          | reset second column
     453                move.w  #52,COL(a7)     | put 3rd column on stack
     454                jsr     _vputa          | reset third column
     455                move.w  #53,COL(a7)     | put 4th column on stack
     456                jsr     _vputa          | reset fourth column
     457
     458srs9k:          btst    #2,vrbw09       | group 11
     459                beq     srs9m           | jump if not
     460
     461                move.w  #55,COL(a7)     | put 1st column on stack
     462                jsr     _vputa          | reset first column
     463                move.w  #56,COL(a7)     | put 2nd column on stack
     464                jsr     _vputa          | reset second column
     465                move.w  #57,COL(a7)     | put 3rd column on stack
     466                jsr     _vputa          | reset third column
     467                move.w  #58,COL(a7)     | put 4th column on stack
     468                jsr     _vputa          | reset fourth column
     469
     470srs9m:          btst    #3,vrbw09       | group 12
     471                beq     srs9x           | jump if not
     472
     473                move.w  #60,COL(a7)     | put 1st column on stack
     474                jsr     _vputa          | reset first column
     475                move.w  #61,COL(a7)     | put 2nd column on stack
     476                jsr     _vputa          | reset second column
     477                move.w  #62,COL(a7)     | put 3rd column on stack
     478                jsr     _vputa          | reset third column
     479                move.w  #63,COL(a7)     | put 4th column on stack
     480                jsr     _vputa          | reset fourth column
     481
     482srs9x:          move.w  vrcw,d0         | restore vrcw to d0
     483
     484                .page
     485
     486| dynamics
     487| --------
     488srs10:          btst    #10,d0          | dynamics ?
     489                beq     srs11           | jump if not
     490
     491                move.w  #AT11,ATR(a7)   | put attribute on stack
     492                move.w  #4,ROW(a7)      | put row on stack
     493                btst    #0,vrbw10+1     | group 1 ?
     494                beq     srs10a          | jump if not
     495
     496                move.w  #6,COL(a7)      | put column on stack
     497                jsr     _vputa          | reset column
     498
     499srs10a:         btst    #1,vrbw10+1     | group 2 ?
     500                beq     srs10b          | jump if not
     501
     502                move.w  #11,COL(a7)     | put column on stack
     503                jsr     _vputa          | reset column
     504
     505srs10b:         btst    #2,vrbw10+1     | group 3 ?
     506                beq     srs10c          | jump if not
     507
     508                move.w  #16,COL(a7)     | put column on stack
     509                jsr     _vputa          | reset column
     510
     511srs10c:         btst    #3,vrbw10+1     | group 4 ?
     512                beq     srs10d          | jump if not
     513
     514                move.w  #21,COL(a7)     | put column on stack
     515                jsr     _vputa          | reset column
     516
     517                .page
     518
     519srs10d:         btst    #4,vrbw10+1     | group 5 ?
     520                beq     srs10e          | jump if not
     521
     522                move.w  #26,COL(a7)     | put column on stack
     523                jsr     _vputa          | reset column
     524
     525srs10e:         btst    #5,vrbw10+1     | group 6 ?
     526                beq     srs10f          | jump if not
     527
     528                move.w  #31,COL(a7)     | put column on stack
     529                jsr     _vputa          | reset column
     530
     531srs10f:         btst    #6,vrbw10+1     | group 7 ?
     532                beq     srs10g          | jump if not
     533
     534                move.w  #36,COL(a7)     | put column on stack
     535                jsr     _vputa          | reset column
     536
     537srs10g:         btst    #7,vrbw10+1     | group 8 ?
     538                beq     srs10h          | jump if not
     539
     540                move.w  #41,COL(a7)     | put column on stack
     541                jsr     _vputa          | reset column
     542
     543                .page
     544
     545srs10h:         btst    #0,vrbw10       | group 9
     546                beq     srs10j          | jump if not
     547
     548                move.w  #46,COL(a7)     | put column on stack
     549                jsr     _vputa          | reset column
     550
     551srs10j:         btst    #1,vrbw10       | group 10
     552                beq     srs10k          | jump if not
     553
     554                move.w  #51,COL(a7)     | put column on stack
     555                jsr     _vputa          | reset column
     556
     557srs10k:         btst    #2,vrbw10       | group 11
     558                beq     srs10m          | jump if not
     559
     560                move.w  #56,COL(a7)     | put column on stack
     561                jsr     _vputa          | reset column
     562
     563srs10m:         btst    #3,vrbw10       | group 12
     564                beq     srs10x          | jump if not
     565
     566                move.w  #61,COL(a7)     | put column on stack
     567                jsr     _vputa          | reset column
     568
     569srs10x:         move.w  vrcw,d0         | restore vrcw to d0
     570
     571                .page
     572
     573| location
     574| --------
     575srs11:          btst    #11,d0          | location ?
     576                beq     srs12           | jump if not
     577
     578                move.w  #AT11,ATR(a7)   | put attribute on stack
     579                move.w  #4,ROW(a7)      | put row on stack
     580                btst    #0,vrbw11+1     | group 1 ?
     581                beq     srs11a          | jump if not
     582
     583                move.w  #8,COL(a7)      | put column on stack
     584                jsr     _vputa          | reset column
     585
     586srs11a:         btst    #1,vrbw11+1     | group 2 ?
     587                beq     srs11b          | jump if not
     588
     589                move.w  #13,COL(a7)     | put column on stack
     590                jsr     _vputa          | reset column
     591
     592srs11b:         btst    #2,vrbw11+1     | group 3 ?
     593                beq     srs11c          | jump if not
     594
     595                move.w  #18,COL(a7)     | put column on stack
     596                jsr     _vputa          | reset column
     597
     598srs11c:         btst    #3,vrbw11+1     | group 4 ?
     599                beq     srs11d          | jump if not
     600
     601                move.w  #23,COL(a7)     | put column on stack
     602                jsr     _vputa          | reset column
     603
     604                .page
     605
     606srs11d:         btst    #4,vrbw11+1     | group 5 ?
     607                beq     srs11e          | jump if not
     608
     609                move.w  #28,COL(a7)     | put column on stack
     610                jsr     _vputa          | reset column
     611
     612srs11e:         btst    #5,vrbw11+1     | group 6 ?
     613                beq     srs11f          | jump if not
     614
     615                move.w  #33,COL(a7)     | put column on stack
     616                jsr     _vputa          | reset column
     617
     618srs11f:         btst    #6,vrbw11+1     | group 7 ?
     619                beq     srs11g          | jump if not
     620
     621                move.w  #38,COL(a7)     | put column on stack
     622                jsr     _vputa          | reset column
     623
     624srs11g:         btst    #7,vrbw11+1     | group 8 ?
     625                beq     srs11h          | jump if not
     626
     627                move.w  #43,COL(a7)     | put column on stack
     628                jsr     _vputa          | reset column
     629
     630                .page
     631
     632srs11h:         btst    #0,vrbw11       | group 9
     633                beq     srs11j          | jump if not
     634
     635                move.w  #48,COL(a7)     | put column on stack
     636                jsr     _vputa          | reset column
     637
     638srs11j:         btst    #1,vrbw11       | group 10
     639                beq     srs11k          | jump if not
     640
     641                move.w  #53,COL(a7)     | put column on stack
     642                jsr     _vputa          | reset column
     643
     644srs11k:         btst    #2,vrbw11       | group 11
     645                beq     srs11m          | jump if not
     646
     647                move.w  #58,COL(a7)     | put column on stack
     648                jsr     _vputa          | reset column
     649
     650srs11m:         btst    #3,vrbw11       | group 12
     651                beq     srs11x          | jump if not
     652
     653                move.w  #63,COL(a7)     | put column on stack
     654                jsr     _vputa          | reset column
     655
     656srs11x:         move.w  vrcw,d0         | restore vrcw to d0
     657
     658                .page
     659
     660| velocity
     661| --------
     662srs12:          btst    #12,d0          | velocity ?
     663                beq     srs13           | jump if not
     664
     665                move.w  #AT11,ATR(a7)   | put attribute on stack
     666                move.w  #5,ROW(a7)      | put row on stack
     667                btst    #0,vrbw12+1     | group 1 ?
     668                beq     srs12a          | jump if not
     669
     670                move.w  #6,COL(a7)      | put 1st column on stack
     671                jsr     _vputa          | reset first column
     672                move.w  #7,COL(a7)      | put 2nd column on stack
     673                jsr     _vputa          | reset second column
     674                move.w  #8,COL(a7)      | put 3rd column on stack
     675                jsr     _vputa          | reset third column
     676
     677srs12a:         btst    #1,vrbw12+1     | group 2 ?
     678                beq     srs12b          | jump if not
     679
     680                move.w  #11,COL(a7)     | put 1st column on stack
     681                jsr     _vputa          | reset first column
     682                move.w  #12,COL(a7)     | put 2nd column on stack
     683                jsr     _vputa          | reset second column
     684                move.w  #13,COL(a7)     | put 3rd column on stack
     685                jsr     _vputa          | reset third column
     686
     687srs12b:         btst    #2,vrbw12+1     | group 3 ?
     688                beq     srs12c          | jump if not
     689
     690                move.w  #16,COL(a7)     | put 1st column on stack
     691                jsr     _vputa          | reset first column
     692                move.w  #17,COL(a7)     | put 2nd column on stack
     693                jsr     _vputa          | reset second column
     694                move.w  #18,COL(a7)     | put 3rd column on stack
     695                jsr     _vputa          | reset third column
     696
     697                .page
     698
     699srs12c:         btst    #3,vrbw12+1     | group 4 ?
     700                beq     srs12d          | jump if not
     701
     702                move.w  #21,COL(a7)     | put 1st column on stack
     703                jsr     _vputa          | reset first column
     704                move.w  #22,COL(a7)     | put 2nd column on stack
     705                jsr     _vputa          | reset second column
     706                move.w  #23,COL(a7)     | put 3rd column on stack
     707                jsr     _vputa          | reset third column
     708
     709srs12d:         btst    #4,vrbw12+1     | group 5 ?
     710                beq     srs12e          | jump if not
     711
     712                move.w  #26,COL(a7)     | put 1st column on stack
     713                jsr     _vputa          | reset first column
     714                move.w  #27,COL(a7)     | put 2nd column on stack
     715                jsr     _vputa          | reset second column
     716                move.w  #28,COL(a7)     | put 3rd column on stack
     717                jsr     _vputa          | reset third column
     718
     719srs12e:         btst    #5,vrbw12+1     | group 6 ?
     720                beq     srs12f          | jump if not
     721
     722                move.w  #31,COL(a7)     | put 1st column on stack
     723                jsr     _vputa          | reset first column
     724                move.w  #32,COL(a7)     | put 2nd column on stack
     725                jsr     _vputa          | reset second column
     726                move.w  #33,COL(a7)     | put 3rd column on stack
     727                jsr     _vputa          | reset third column
     728
     729                .page
     730
     731srs12f:         btst    #6,vrbw12+1     | group 7 ?
     732                beq     srs12g          | jump if not
     733
     734                move.w  #36,COL(a7)     | put 1st column on stack
     735                jsr     _vputa          | reset first column
     736                move.w  #37,COL(a7)     | put 2nd column on stack
     737                jsr     _vputa          | reset second column
     738                move.w  #38,COL(a7)     | put 3rd column on stack
     739                jsr     _vputa          | reset third column
     740
     741srs12g:         btst    #7,vrbw12+1     | group 8 ?
     742                beq     srs12h          | jump if not
     743
     744                move.w  #41,COL(a7)     | put 1st column on stack
     745                jsr     _vputa          | reset first column
     746                move.w  #42,COL(a7)     | put 2nd column on stack
     747                jsr     _vputa          | reset second column
     748                move.w  #43,COL(a7)     | put 3rd column on stack
     749                jsr     _vputa          | reset third column
     750
     751srs12h:         btst    #0,vrbw12       | group 9
     752                beq     srs12j          | jump if not
     753
     754                move.w  #46,COL(a7)     | put 1st column on stack
     755                jsr     _vputa          | reset first column
     756                move.w  #47,COL(a7)     | put 2nd column on stack
     757                jsr     _vputa          | reset second column
     758                move.w  #48,COL(a7)     | put 3rd column on stack
     759                jsr     _vputa          | reset third column
     760
     761                .page
     762
     763srs12j:         btst    #1,vrbw12       | group 10
     764                beq     srs12k          | jump if not
     765
     766                move.w  #51,COL(a7)     | put 1st column on stack
     767                jsr     _vputa          | reset first column
     768                move.w  #52,COL(a7)     | put 2nd column on stack
     769                jsr     _vputa          | reset second column
     770                move.w  #53,COL(a7)     | put 3rd column on stack
     771                jsr     _vputa          | reset third column
     772
     773srs12k:         btst    #2,vrbw12       | group 11
     774                beq     srs12m          | jump if not
     775
     776                move.w  #56,COL(a7)     | put 1st column on stack
     777                jsr     _vputa          | reset first column
     778                move.w  #57,COL(a7)     | put 2nd column on stack
     779                jsr     _vputa          | reset second column
     780                move.w  #58,COL(a7)     | put 3rd column on stack
     781                jsr     _vputa          | reset third column
     782
     783srs12m:         btst    #3,vrbw12       | group 12
     784                beq     srs12x          | jump if not
     785
     786                move.w  #61,COL(a7)     | put 1st column on stack
     787                jsr     _vputa          | reset first column
     788                move.w  #62,COL(a7)     | put 2nd column on stack
     789                jsr     _vputa          | reset second column
     790                move.w  #63,COL(a7)     | put 3rd column on stack
     791                jsr     _vputa          | reset third column
     792
     793srs12x:         move.w  vrcw,d0         | restore vrcw to d0
     794
     795                .page
     796
     797| resolution
     798| ----------
     799srs13:          btst    #13,d0          | resolution ?
     800                beq     srs14           | jump if not
     801
     802                move.w  #AT12,ATR(a7)   | put attribute on stack
     803                move.w  #7,ROW(a7)      | put row on stack
     804                btst    #0,vrbw13+1     | variable 1 ?
     805                beq     srs13a          | jump if not
     806
     807                move.w  #6,COL(a7)      | put column on stack
     808                jsr     _vputa          | reset column
     809
     810srs13a:         btst    #1,vrbw13+1     | variable 2 ?
     811                beq     srs13b          | jump if not
     812
     813                move.w  #15,COL(a7)     | put column on stack
     814                jsr     _vputa          | reset column
     815
     816srs13b:         btst    #2,vrbw13+1     | variable 3 ?
     817                beq     srs13c          | jump if not
     818
     819                move.w  #24,COL(a7)     | put column on stack
     820                jsr     _vputa          | reset column
     821
     822srs13c:         btst    #3,vrbw13+1     | variable 4 ?
     823                beq     srs13d          | jump if not
     824
     825                move.w  #33,COL(a7)     | put column on stack
     826                jsr     _vputa          | reset column
     827
     828srs13d:         btst    #4,vrbw13+1     | variable 5 ?
     829                beq     srs13e          | jump if not
     830
     831                move.w  #42,COL(a7)     | put column on stack
     832                jsr     _vputa          | reset column
     833
     834srs13e:         btst    #5,vrbw13+1     | variable 6 ?
     835                beq     srs13x          | jump if not
     836
     837                move.w  #51,COL(a7)     | put column on stack
     838                jsr     _vputa          | reset column
     839
     840srs13x:         move.w  vrcw,d0         | restore vrcw to d0
     841
     842                .page
     843
     844| analog value
     845| ------------
     846srs14:          btst    #14,d0          | analog value ?
     847                beq     srs15           | jump if not
     848
     849                move.w  #AT12,ATR(a7)   | put attribute on stack
     850                move.w  #7,ROW(a7)      | put row on stack
     851                btst    #0,vrbw14+1     | variable 1 ?
     852                beq     srs14a          | jump if not
     853
     854                move.w  #8,COL(a7)      | put 1st column on stack
     855                jsr     _vputa          | reset first column
     856                move.w  #9,COL(a7)      | put 2nd column on stack
     857                jsr     _vputa          | reset second column
     858                move.w  #10,COL(a7)     | put 3rd column on stack
     859                jsr     _vputa          | reset third column
     860                move.w  #11,COL(a7)     | put 4th column on stack
     861                jsr     _vputa          | reset fourth column
     862                move.w  #12,COL(a7)     | put 5th column on stack
     863                jsr     _vputa          | reset fifth column
     864
     865srs14a:         btst    #1,vrbw14+1     | variable 2 ?
     866                beq     srs14b          | jump if not
     867
     868                move.w  #17,COL(a7)     | put 1st column on stack
     869                jsr     _vputa          | reset first column
     870                move.w  #18,COL(a7)     | put 2nd column on stack
     871                jsr     _vputa          | reset second column
     872                move.w  #19,COL(a7)     | put 3rd column on stack
     873                jsr     _vputa          | reset third column
     874                move.w  #20,COL(a7)     | put 4th column on stack
     875                jsr     _vputa          | reset fourth column
     876                move.w  #21,COL(a7)     | put 5th column on stack
     877                jsr     _vputa          | reset fifth column
     878
     879                .page
     880
     881srs14b:         btst    #2,vrbw14+1     | variable 3 ?
     882                beq     srs14c          | jump if not
     883
     884                move.w  #26,COL(a7)     | put 1st column on stack
     885                jsr     _vputa          | reset first column
     886                move.w  #27,COL(a7)     | put 2nd column on stack
     887                jsr     _vputa          | reset second column
     888                move.w  #28,COL(a7)     | put 3rd column on stack
     889                jsr     _vputa          | reset third column
     890                move.w  #29,COL(a7)     | put 4th column on stack
     891                jsr     _vputa          | reset fourth column
     892                move.w  #30,COL(a7)     | put 5th column on stack
     893                jsr     _vputa          | reset fifth column
     894
     895srs14c:         btst    #3,vrbw14+1     | variable 4 ?
     896                beq     srs14d          | jump if not
     897
     898                move.w  #35,COL(a7)     | put 1st column on stack
     899                jsr     _vputa          | reset first column
     900                move.w  #36,COL(a7)     | put 2nd column on stack
     901                jsr     _vputa          | reset second column
     902                move.w  #37,COL(a7)     | put 3rd column on stack
     903                jsr     _vputa          | reset third column
     904                move.w  #38,COL(a7)     | put 4th column on stack
     905                jsr     _vputa          | reset fourth column
     906                move.w  #39,COL(a7)     | put 5th column on stack
     907                jsr     _vputa          | reset fifth column
     908
     909                .page
     910
     911srs14d:         btst    #4,vrbw14+1     | variable 5 ?
     912                beq     srs14e          | jump if not
     913
     914                move.w  #44,COL(a7)     | put 1st column on stack
     915                jsr     _vputa          | reset first column
     916                move.w  #45,COL(a7)     | put 2nd column on stack
     917                jsr     _vputa          | reset second column
     918                move.w  #46,COL(a7)     | put 3rd column on stack
     919                jsr     _vputa          | reset third column
     920                move.w  #47,COL(a7)     | put 4th column on stack
     921                jsr     _vputa          | reset fourth column
     922                move.w  #48,COL(a7)     | put 5th column on stack
     923                jsr     _vputa          | reset fifth column
     924
     925srs14e:         btst    #5,vrbw14+1     | variable 6 ?
     926                beq     srs14x          | jump if not
     927
     928                move.w  #53,COL(a7)     | put 1st column on stack
     929                jsr     _vputa          | reset first column
     930                move.w  #54,COL(a7)     | put 2nd column on stack
     931                jsr     _vputa          | reset second column
     932                move.w  #55,COL(a7)     | put 3rd column on stack
     933                jsr     _vputa          | reset third column
     934                move.w  #56,COL(a7)     | put 4th column on stack
     935                jsr     _vputa          | reset fourth column
     936                move.w  #57,COL(a7)     | put 5th column on stack
     937                jsr     _vputa          | reset fifth column
     938
     939srs14x:         move.w  vrcw,d0         | restore vrcw to d0
     940
     941                .page
     942
     943| stop/next
     944| ---------
     945srs15:          btst    #15,d0          | stop/next ?
     946                beq     srs16           | jump if not
     947
     948                btst    #0,vrbw15       | stop ?
     949                beq     srs15a          | jump if not
     950
     951                move.w  #AT08,ATR(a7)   | put attribute on stack
     952                move.w  #1,ROW(a7)      | put row on stack
     953                move.w  #40,COL(a7)     | put 1st column on stack
     954                jsr     _vputa          | reset first column
     955                move.w  #41,COL(a7)     | put 2nd column on stack
     956                jsr     _vputa          | reset second column
     957                move.w  #42,COL(a7)     | put 3rd column on stack
     958                jsr     _vputa          | reset third column
     959                move.w  #43,COL(a7)     | put 4th column on stack
     960                jsr     _vputa          | reset fourth column
     961
     962srs15a:         btst    #1,vrbw15       | next ?
     963                beq     srs16           | jump if not
     964
     965                move.w  #AT08,ATR(a7)   | put attribute on stack
     966                move.w  #1,ROW(a7)      | put row on stack
     967                move.w  #45,COL(a7)     | put 1st column on stack
     968                jsr     _vputa          | reset first column
     969                move.w  #46,COL(a7)     | put 2nd column on stack
     970                jsr     _vputa          | reset second column
     971                move.w  #47,COL(a7)     | put 3rd column on stack
     972                jsr     _vputa          | reset third column
     973                move.w  #48,COL(a7)     | put 4th column on stack
     974                jsr     _vputa          | reset fourth column
     975
     976srs16:          add.l   #10,a7          | clean up stack
     977                bra     srsexit         | done
     978
     979                .page
     980
    981981                .bss
    982 *
    983 * local copies of _vrcw, _vrbw08.._vrbw15
    984 *
     982
     983| local copies of _vrcw, _vrbw08.._vrbw15
     984
    985985vrcw:           .ds.w   1
    986986vrbw08:         .ds.w   1
     
    992992vrbw14:         .ds.w   1
    993993vrbw15:         .ds.w   1
    994 *
     994
    995995                .end
  • ram/timeint.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * timeint.s -- MIDAS-VII timer interrupt handler
    3 * Version 15 -- 1989-07-20 -- D.N. Lynx Crowe
    4 * ------------------------------------------------------------------------------
    5 *
    6 * This code replaces the interrupt handler in bios.s, which is known to
    7 * have a bug in it, and adds support for the VSDD and an array of programable
    8 * timers with 1 Ms resolution.
    9 *
    10 * WARNING:  There are equates to addresses in the bios EPROM which may change
    11 * when the bios is reassembled.  If the bios is reassembled be sure to update
    12 * the equates flagged by "<<<=====".
    13 *
    14 * The addresses currently in the equates are for EPROMs dated 1988-04-18 or
    15 * 1988-06-20 ONLY.
    16 *
    17 * ------------------------------------------------------------------------------
    18 * Hardware timer usage:
    19 * ---------------------
    20 *       Timer 1         PLL divider for score clock -- fixed at 64
    21 *       Timer 2         PLL divider for score clock -- nominally 3200
    22 *       Timer 3         1 Ms Real Time Clock
    23 *
    24 * ------------------------------------------------------------------------------
    25 *
     1| ------------------------------------------------------------------------------
     2| timeint.s -- MIDAS-VII timer interrupt handler
     3| Version 15 -- 1989-07-20 -- D.N. Lynx Crowe
     4| ------------------------------------------------------------------------------
     5
     6| This code replaces the interrupt handler in bios.s, which is known to
     7| have a bug in it, and adds support for the VSDD and an array of programable
     8| timers with 1 Ms resolution.
     9
     10| WARNING:  There are equates to addresses in the bios EPROM which may change
     11| when the bios is reassembled.  If the bios is reassembled be sure to update
     12| the equates flagged by "<<<=====".
     13
     14| The addresses currently in the equates are for EPROMs dated 1988-04-18 or
     15| 1988-06-20 ONLY.
     16
     17| ------------------------------------------------------------------------------
     18| Hardware timer usage:
     19| ---------------------
     20|       Timer 1         PLL divider for score clock -- fixed at 64
     21|       Timer 2         PLL divider for score clock -- nominally 3200
     22|       Timer 3         1 Ms Real Time Clock
     23
     24| ------------------------------------------------------------------------------
     25
    2626                .text
    27 *
    28                 .xdef   _tsetup         * tsetup() -- timer setup function
    29                 .xdef   timeint         * timer interrupt handler
    30 *
    31                 .xdef   _M1IoRec        * MIDI channel 1 IoRec         
    32                 .xdef   _M2IoRec        * MIDI channel 2 IoRec         
    33                 .xdef   _S1IoRec        * RS232 channel 1 IoRec         
    34                 .xdef   _S2IoRec        * RS232 channel 2 IoRec         
    35                 .xdef   _timers         * timer array -- short timers[NTIMERS]
    36                 .xdef   _vi_clk         * VSDD scroll delay timer
    37                 .xdef   _vi_tag         * VSDD VI tag
    38 *
    39                 .xref   lclsadr         * score object base address
    40                 .xref   lclscrl         * score object scroll offset
    41                 .xref   _v_odtab        * VSDD object descriptor table
    42 *
    43                 .page
    44 * ==============================================================================
    45 *
    46 FRAMES          .equ    0               * set non-zero to enable frame pulses
    47 *
    48 * Equates to variables in bios.s:
    49 * -------------------------------
    50 * These variables are permanently assigned.
    51 *
    52 TIMEVEC         .equ    $00000400       * LONG - System timer trap vector
    53 *
    54 FC_SW           .equ    $00000420       * WORD - Frame clock switch
    55 FC_VAL          .equ    $00000422       * LONG - Frame clock value
    56 *
    57 HZ_1K           .equ    $0000049A       * LONG - 1000 Hz clock
    58 HZ_200          .equ    $0000049E       * LONG - 200 Hz clock
    59 FRCLOCK         .equ    $000004A2       * LONG - 50 Hz clock
    60 *
    61 T3COUNT         .equ    $000004AA       * WORD - Timer 3 count
    62 *
    63 * ------------------------------------------------------------------------------
    64 *
    65 * WARNING:  The address of "FLOCK" depends on the version of the bios EPROM.
    66 * The address below is for EPROMs dated 1988-04-18 or 1988-06-20 ONLY.
    67 *
    68 FLOCK           .equ    $00000E0C       * WORD - Floppy semaphore       <<<=====
    69 *
    70 * ==============================================================================
    71 *
    72 * Equates to routines in bios.s:
    73 * ------------------------------
    74 *
    75 * WARNING:  The address of "FLOPVBL" depends on the version of the bios EPROM.
    76 * The address below is for EPROMs dated 1988-04-18 or 1988-06-20 ONLY.
    77 *
    78 FLOPVBL         .equ    $001015EE       * floppy VI handler address     <<<=====
    79 *
    80 * ==============================================================================
    81 *
    82                 .page
    83 *
    84 * Hardware address equates:
    85 * -------------------------
    86 TI_VEC          .equ    $00000070       * Timer interrupt autovector
    87 *
    88 TIMER           .equ    $003A0001       * Timer base address
    89 M1_ACIA         .equ    $003AC001       * MIDI ACIA channel 1 base address
    90 *
    91 * ------------------------------------------------------------------------------
    92 *
    93 * Timer register equates:
    94 * -----------------------
    95 TIME_CRX        .equ    TIMER           * Control register 1 or 3
    96 TIME_CR2        .equ    TIMER+2         * Control register 2
    97 TIME_T1H        .equ    TIMER+4         * Timer 1 high byte
    98 TIME_T1L        .equ    TIMER+6         * Timer 1 low byte
    99 TIME_T2H        .equ    TIMER+8         * Timer 2 high byte
    100 TIME_T2L        .equ    TIMER+10        * Timer 2 low byte
    101 TIME_T3H        .equ    TIMER+12        * Timer 3 high byte
    102 TIME_T3L        .equ    TIMER+14        * Timer 3 low byte
    103 *
    104 * Serial I/O equates:
    105 * -------------------
    106 ACIA_CFR        .equ    2               * CFR offset from ACIA base
    107 DTR_BIT         .equ    1               * DTR bit in ACIA CFR1
    108 *
    109 IO_CFR1         .equ    29              * cfr1 offset in M1IoRec
    110 *
    111 * ==============================================================================
    112 *
    113 * Miscellaneous equates:
    114 * ----------------------
    115 IPL7            .equ    $0700           * IPL mask for interrupt disable
    116 *
    117 FCMAX           .equ    $00FFFFFF       * Maximum frame counter value
    118 FCMIN           .equ    $00000000       * Minimum frame counter value
    119 *
    120 NTIMERS         .equ    8               * Number of timers in the timer array
    121 *
    122 XBIOS           .equ    14              * XBIOS TRAP number
    123 X_PIOREC        .equ    0               * X_PIOREC code
    124 SR1_DEV         .equ    0               * RS232 ACIA channel 1
    125 SR2_DEV         .equ    1               * RS232 ACIA channel 2
    126 MC1_DEV         .equ    3               * MIDI ACIA channel 1
    127 MC2_DEV         .equ    4               * MIDI ACIA channel 2
    128 * ==============================================================================
    129 *
    130                 .page
    131 * ==============================================================================
    132 * _tsetup -- tsetup() -- timer setup function
    133 * ==============================================================================
    134 *
    135 _tsetup:        move.w  sr,-(a7)                * Save old interrupt mask
    136                 ori.w   #IPL7,sr                * Disable interrupts
    137 *
    138                 move.w  #SR1_DEV,-(a7)          * Establish S1IoRec
    139                 move.w  #X_PIOREC,-(a7)         * ...
    140                 trap    #XBIOS                  * ...
    141                 add.l   #4,a7                   * ...
    142                 move.l  d0,_S1IoRec             * ...
    143 *
    144                 move.w  #SR2_DEV,-(a7)          * Establish S2IoRec
    145                 move.w  #X_PIOREC,-(a7)         * ...
    146                 trap    #XBIOS                  * ...
    147                 add.l   #4,a7                   * ...
    148                 move.l  d0,_S2IoRec             * ...
    149 *
    150                 move.w  #MC1_DEV,-(a7)          * Establish M1IoRec
    151                 move.w  #X_PIOREC,-(a7)         * ...
    152                 trap    #XBIOS                  * ...
    153                 add.l   #4,a7                   * ...
    154                 move.l  d0,_M1IoRec             * ...
    155 *
    156                 move.w  #MC2_DEV,-(a7)          * Establish M2IoRec
    157                 move.w  #X_PIOREC,-(a7)         * ...
    158                 trap    #XBIOS                  * ...
    159                 add.l   #4,a7                   * ...
    160                 move.l  d0,_M2IoRec             * ...
    161 *
    162                 .page
    163 *
    164                 clr.w   FC_SW                   * Stop the frame clock
    165                 clr.l   FC_VAL                  * ... and reset it
    166                 clr.w   _vi_tag                 * Clear VSDD VI tag
    167                 clr.w   _vi_clk                 * Clear VSDD delay timer
    168                 clr.w   lclsadr                 * Clear score scroll address
    169                 clr.w   lclscrl                 * Clear score scroll offset
    170 *
    171                 lea     _timers,a0              * Point at timer array
    172                 move.w  #NTIMERS-1,d0           * Setup to clear timer array
    173 *
    174 tclr:           clr.w   (a0)+                   * Clear a timer array entry
    175                 dbra    d0,tclr                 * Loop until done
    176 *
    177                 move.l  #nullrts,TIMEVEC        * Set timer interrupt vector
    178                 move.l  #timeint,TI_VEC         * Set timer trap vector
    179 *
    180                 move.b  #$00,TIME_T1H           * Setup timer 1  (PLL)
    181                 move.b  #$1F,TIME_T1L           * ... for divide by 64
    182                 move.b  #$0C,TIME_T2H           * Setup timer 2  (FC)
    183                 move.b  #$7F,TIME_T2L           * ... for divide by 3200
    184                 move.b  #$03,TIME_T3H           * Setup timer 3  (RTC)
    185                 move.b  #$20,TIME_T3L           * ... for 1Ms interval
    186                 move.b  #$42,TIME_CRX           * Setup CR3
    187                 move.b  #$41,TIME_CR2           * Setup CR2
    188                 move.b  #$81,TIME_CRX           * Setup CR1
    189                 move.b  #$80,TIME_CRX           * Start the timers
    190 *
    191                 move.w  (a7)+,sr                * Restore interrupts
    192 *
    193 nullrts:        rts                             * Return to caller
    194 *
    195                 .page
    196 * ==============================================================================
    197 * timeint -- timer interrupt handler
    198 * ==============================================================================
    199 *
    200 timeint:        movem.l d0-d7/a0-a6,-(a7)       * Save registers
    201                 move.b  TIME_CR2,d0             * Get timer interrupt status
    202 * ------------------------------------------------------------------------------
    203 * process 1 MS timer
    204 * ------------------------------------------------------------------------------
    205                 btst.l  #2,d0                   * Check timer 3 status
    206                 beq     tmi02                   * Jump if not active
    207 *
    208                 move.b  TIME_T3H,d1             * Read timer 3 count
    209                 lsl.w   #8,d1                   * ...
    210                 move.b  TIME_T3L,d1             * ...
    211                 move.w  d1,T3COUNT              * ... and save it
    212 *
    213                 addq.l  #1,HZ_1K                * Update 1ms clock  (1 KHz)
    214 *
    215                 move.l  d0,-(a7)                * Preserve D0
    216 * ------------------------------------------------------------------------------
    217 * process VSDD timer
    218 * ------------------------------------------------------------------------------
    219                 tst.w   _vi_tag                 * Does the VSDD need service ?
    220                 beq     updtime                 * Jump if not
    221 *
    222                 move.w  _vi_clk,d0              * Get VSDD scroll delay timer
    223                 subq.w  #1,d0                   * Decrement timer
    224                 move.w  d0,_vi_clk              * Update timer
    225                 bne     updtime                 * Jump if it's not zero yet
    226 *
    227                 move.w  lclsadr,_v_odtab+12     * Update scroll address
    228                 move.w  lclscrl,_v_odtab+10     * Update scroll offset
    229                 clr.w   _vi_tag                 * Reset the tag
    230 *
    231                 .page
    232 *
    233 * ------------------------------------------------------------------------------
    234 * process programable timers
    235 * ------------------------------------------------------------------------------
    236 *
    237 updtime:        move.w  #NTIMERS-1,d0           * Setup timer array counter
    238                 lea     _timers,a0              * Point at timer array
    239 *
    240 tdcr:           move.w  (a0),d1                 * Get timer array entry
    241                 beq     tdcr1                   * Jump if already 0
    242 *
    243                 subq.w  #1,d1                   * Decrement timer
    244 *
    245 tdcr1:          move.w  d1,(a0)+                * Store updated timer value
    246                 dbra    d0,tdcr                 * Loop until done
    247 *
    248 * ------------------------------------------------------------------------------
    249 * process timer hook vector
    250 * ------------------------------------------------------------------------------
    251                 movea.l TIMEVEC,a0              * Get RTC vector
    252                 move.w  #1,-(a7)                * Pass 1 msec on stack
    253                 jsr     (a0)                    * Process RTC vector
    254                 addq.l  #2,a7                   * Clean up stack
    255 *
    256                 move.l  (a7)+,d0                * Restore D0
    257 *
    258                 .page
    259 * ------------------------------------------------------------------------------
    260 * process 5 Ms clock
    261 * ------------------------------------------------------------------------------
    262                 move.w  tdiv1,d1                * Update divider
    263                 addq.w  #1,d1                   * ...
    264                 move.w  d1,tdiv1                * ...
    265 *
    266                 cmpi.w  #5,d1                   * Do we need to update HZ_200 ?
    267                 blt     tmi02                   * Jump if not
    268 *
    269                 addq.l  #1,HZ_200               * Update 5ms clock   (200 Hz)
    270 * ------------------------------------------------------------------------------
    271 * process 20 Ms floppy clock
    272 * ------------------------------------------------------------------------------
    273                 move.w  tdiv2,d1                * Update divider
    274                 addq.w  #1,d1                   * ...
    275                 move.w  d1,tdiv2                * ...
    276 *
    277                 cmpi.w  #4,d1                   * Do we need to update FRCLOCK ?
    278                 blt     tmi01                   * Jump if not
    279 *
    280                 addq.l  #1,FRCLOCK              * Update 20 Ms clock  (50 Hz)
    281                 tst.w   FLOCK                   * See if floppy is active
    282                 bne     tmi00                   * Don't call FLOPVBL if so
    283 *
    284                 jsr     FLOPVBL                 * Check on the floppy
    285 *
    286 tmi00:          move.w  #0,tdiv2                * Reset tdiv2
    287 *
    288 tmi01:          move.w  #0,tdiv1                * Reset tdiv1
    289 *
    290                 .page
    291 * ------------------------------------------------------------------------------
    292 * process PLL timers
    293 * ------------------------------------------------------------------------------
    294 *
    295 tmi02:          btst.l  #0,d0                   * Check timer 1 int
    296                 beq     tmi03                   * Jump if not set
    297 *
    298                 move.b  TIME_T1H,d1             * Read timer 1 to clear int.
    299                 move.b  TIME_T1L,d1             * ...
    300 *
    301 tmi03:          btst.l  #1,d0                   * Check for timer 2 int.
    302                 beq     tmi04                   * Jump if not set
    303 *
    304                 move.b  TIME_T2H,d1             * Read timer 2 to clear int.
    305                 move.b  TIME_T2L,d1             * ...
    306 *
    307                 .page
    308 * ------------------------------------------------------------------------------
    309 * update score frame counter
    310 * ------------------------------------------------------------------------------
    311                 tst.w   FC_SW                   * Should we update the frame ?
    312                 beq     tmi04                   * Jump if not
    313 *
    314                 bmi     tmi05                   * Jump if we count down
    315 *
    316                 move.l  FC_VAL,d0               * Get the frame count
    317                 cmp.l   #FCMAX,d0               * See it we've topped out
    318                 bge     tmi06                   * Jump if limit was hit
    319 *
    320                 addq.l  #1,d0                   * Count up 1 frame
    321                 move.l  d0,FC_VAL               * Store updated frame count
    322 *
     27
     28                .xdef   _tsetup         | tsetup() -- timer setup function
     29                .xdef   timeint         | timer interrupt handler
     30
     31                .xdef   _M1IoRec        | MIDI channel 1 IoRec
     32                .xdef   _M2IoRec        | MIDI channel 2 IoRec
     33                .xdef   _S1IoRec        | RS232 channel 1 IoRec
     34                .xdef   _S2IoRec        | RS232 channel 2 IoRec
     35                .xdef   _timers         | timer array -- short timers[NTIMERS]
     36                .xdef   _vi_clk         | VSDD scroll delay timer
     37                .xdef   _vi_tag         | VSDD VI tag
     38
     39                .xref   lclsadr         | score object base address
     40                .xref   lclscrl         | score object scroll offset
     41                .xref   _v_odtab        | VSDD object descriptor table
     42
     43                .page
     44| ==============================================================================
     45
     46FRAMES          =       0               | set non-zero to enable frame pulses
     47
     48| Equates to variables in bios.s:
     49| -------------------------------
     50| These variables are permanently assigned.
     51
     52TIMEVEC         =       0x00000400      | LONG - System timer trap vector
     53
     54FC_SW           =       0x00000420      | WORD - Frame clock switch
     55FC_VAL          =       0x00000422      | LONG - Frame clock value
     56
     57HZ_1K           =       0x0000049A      | LONG - 1000 Hz clock
     58HZ_200          =       0x0000049E      | LONG - 200 Hz clock
     59FRCLOCK         =       0x000004A2      | LONG - 50 Hz clock
     60
     61T3COUNT         =       0x000004AA      | WORD - Timer 3 count
     62
     63| ------------------------------------------------------------------------------
     64
     65| WARNING:  The address of "FLOCK" depends on the version of the bios EPROM.
     66| The address below is for EPROMs dated 1988-04-18 or 1988-06-20 ONLY.
     67
     68FLOCK           =       0x00000E0C      | WORD - Floppy semaphore       <<<=====
     69
     70| ==============================================================================
     71
     72| Equates to routines in bios.s:
     73| ------------------------------
     74
     75| WARNING:  The address of "FLOPVBL" depends on the version of the bios EPROM.
     76| The address below is for EPROMs dated 1988-04-18 or 1988-06-20 ONLY.
     77
     78FLOPVBL         =       0x001015EE      | floppy VI handler address     <<<=====
     79
     80| ==============================================================================
     81
     82                .page
     83
     84| Hardware address equates:
     85| -------------------------
     86TI_VEC          =       0x00000070      | Timer interrupt autovector
     87
     88TIMER           =       0x003A0001      | Timer base address
     89M1_ACIA         =       0x003AC001      | MIDI ACIA channel 1 base address
     90
     91| ------------------------------------------------------------------------------
     92
     93| Timer register equates:
     94| -----------------------
     95TIME_CRX        =       TIMER           | Control register 1 or 3
     96TIME_CR2        =       TIMER+2         | Control register 2
     97TIME_T1H        =       TIMER+4         | Timer 1 high byte
     98TIME_T1L        =       TIMER+6         | Timer 1 low byte
     99TIME_T2H        =       TIMER+8         | Timer 2 high byte
     100TIME_T2L        =       TIMER+10        | Timer 2 low byte
     101TIME_T3H        =       TIMER+12        | Timer 3 high byte
     102TIME_T3L        =       TIMER+14        | Timer 3 low byte
     103
     104| Serial I/O equates:
     105| -------------------
     106ACIA_CFR        =       2               | CFR offset from ACIA base
     107DTR_BIT         =       1               | DTR bit in ACIA CFR1
     108
     109IO_CFR1         =       29              | cfr1 offset in M1IoRec
     110
     111| ==============================================================================
     112
     113| Miscellaneous equates:
     114| ----------------------
     115IPL7            =       0x0700          | IPL mask for interrupt disable
     116
     117FCMAX           =       0x00FFFFFF      | Maximum frame counter value
     118FCMIN           =       0x00000000      | Minimum frame counter value
     119
     120NTIMERS         =       8               | Number of timers in the timer array
     121
     122XBIOS           =       14              | XBIOS TRAP number
     123X_PIOREC        =       0               | X_PIOREC code
     124SR1_DEV         =       0               | RS232 ACIA channel 1
     125SR2_DEV         =       1               | RS232 ACIA channel 2
     126MC1_DEV         =       3               | MIDI ACIA channel 1
     127MC2_DEV         =       4               | MIDI ACIA channel 2
     128| ==============================================================================
     129
     130                .page
     131| ==============================================================================
     132| _tsetup -- tsetup() -- timer setup function
     133| ==============================================================================
     134
     135_tsetup:        move.w  sr,-(a7)                | Save old interrupt mask
     136                ori.w   #IPL7,sr                | Disable interrupts
     137
     138                move.w  #SR1_DEV,-(a7)          | Establish S1IoRec
     139                move.w  #X_PIOREC,-(a7)         | ...
     140                trap    #XBIOS                  | ...
     141                add.l   #4,a7                   | ...
     142                move.l  d0,_S1IoRec             | ...
     143
     144                move.w  #SR2_DEV,-(a7)          | Establish S2IoRec
     145                move.w  #X_PIOREC,-(a7)         | ...
     146                trap    #XBIOS                  | ...
     147                add.l   #4,a7                   | ...
     148                move.l  d0,_S2IoRec             | ...
     149
     150                move.w  #MC1_DEV,-(a7)          | Establish M1IoRec
     151                move.w  #X_PIOREC,-(a7)         | ...
     152                trap    #XBIOS                  | ...
     153                add.l   #4,a7                   | ...
     154                move.l  d0,_M1IoRec             | ...
     155
     156                move.w  #MC2_DEV,-(a7)          | Establish M2IoRec
     157                move.w  #X_PIOREC,-(a7)         | ...
     158                trap    #XBIOS                  | ...
     159                add.l   #4,a7                   | ...
     160                move.l  d0,_M2IoRec             | ...
     161
     162                .page
     163
     164                clr.w   FC_SW                   | Stop the frame clock
     165                clr.l   FC_VAL                  | ... and reset it
     166                clr.w   _vi_tag                 | Clear VSDD VI tag
     167                clr.w   _vi_clk                 | Clear VSDD delay timer
     168                clr.w   lclsadr                 | Clear score scroll address
     169                clr.w   lclscrl                 | Clear score scroll offset
     170
     171                lea     _timers,a0              | Point at timer array
     172                move.w  #NTIMERS-1,d0           | Setup to clear timer array
     173
     174tclr:           clr.w   (a0)+                   | Clear a timer array entry
     175                dbra    d0,tclr                 | Loop until done
     176
     177                move.l  #nullrts,TIMEVEC        | Set timer interrupt vector
     178                move.l  #timeint,TI_VEC         | Set timer trap vector
     179
     180                move.b  #0x00,TIME_T1H          | Setup timer 1  (PLL)
     181                move.b  #0x1F,TIME_T1L          | ... for divide by 64
     182                move.b  #0x0C,TIME_T2H          | Setup timer 2  (FC)
     183                move.b  #0x7F,TIME_T2L          | ... for divide by 3200
     184                move.b  #0x03,TIME_T3H          | Setup timer 3  (RTC)
     185                move.b  #0x20,TIME_T3L          | ... for 1Ms interval
     186                move.b  #0x42,TIME_CRX          | Setup CR3
     187                move.b  #0x41,TIME_CR2          | Setup CR2
     188                move.b  #0x81,TIME_CRX          | Setup CR1
     189                move.b  #0x80,TIME_CRX          | Start the timers
     190
     191                move.w  (a7)+,sr                | Restore interrupts
     192
     193nullrts:        rts                             | Return to caller
     194
     195                .page
     196| ==============================================================================
     197| timeint -- timer interrupt handler
     198| ==============================================================================
     199
     200timeint:        movem.l d0-d7/a0-a6,-(a7)       | Save registers
     201                move.b  TIME_CR2,d0             | Get timer interrupt status
     202| ------------------------------------------------------------------------------
     203| process 1 MS timer
     204| ------------------------------------------------------------------------------
     205                btst.l  #2,d0                   | Check timer 3 status
     206                beq     tmi02                   | Jump if not active
     207
     208                move.b  TIME_T3H,d1             | Read timer 3 count
     209                lsl.w   #8,d1                   | ...
     210                move.b  TIME_T3L,d1             | ...
     211                move.w  d1,T3COUNT              | ... and save it
     212
     213                addq.l  #1,HZ_1K                | Update 1ms clock  (1 KHz)
     214
     215                move.l  d0,-(a7)                | Preserve D0
     216| ------------------------------------------------------------------------------
     217| process VSDD timer
     218| ------------------------------------------------------------------------------
     219                tst.w   _vi_tag                 | Does the VSDD need service ?
     220                beq     updtime                 | Jump if not
     221
     222                move.w  _vi_clk,d0              | Get VSDD scroll delay timer
     223                subq.w  #1,d0                   | Decrement timer
     224                move.w  d0,_vi_clk              | Update timer
     225                bne     updtime                 | Jump if it's not zero yet
     226
     227                move.w  lclsadr,_v_odtab+12     | Update scroll address
     228                move.w  lclscrl,_v_odtab+10     | Update scroll offset
     229                clr.w   _vi_tag                 | Reset the tag
     230
     231                .page
     232
     233| ------------------------------------------------------------------------------
     234| process programable timers
     235| ------------------------------------------------------------------------------
     236
     237updtime:        move.w  #NTIMERS-1,d0           | Setup timer array counter
     238                lea     _timers,a0              | Point at timer array
     239
     240tdcr:           move.w  (a0),d1                 | Get timer array entry
     241                beq     tdcr1                   | Jump if already 0
     242
     243                subq.w  #1,d1                   | Decrement timer
     244
     245tdcr1:          move.w  d1,(a0)+                | Store updated timer value
     246                dbra    d0,tdcr                 | Loop until done
     247
     248| ------------------------------------------------------------------------------
     249| process timer hook vector
     250| ------------------------------------------------------------------------------
     251                movea.l TIMEVEC,a0              | Get RTC vector
     252                move.w  #1,-(a7)                | Pass 1 msec on stack
     253                jsr     (a0)                    | Process RTC vector
     254                addq.l  #2,a7                   | Clean up stack
     255
     256                move.l  (a7)+,d0                | Restore D0
     257
     258                .page
     259| ------------------------------------------------------------------------------
     260| process 5 Ms clock
     261| ------------------------------------------------------------------------------
     262                move.w  tdiv1,d1                | Update divider
     263                addq.w  #1,d1                   | ...
     264                move.w  d1,tdiv1                | ...
     265
     266                cmpi.w  #5,d1                   | Do we need to update HZ_200 ?
     267                blt     tmi02                   | Jump if not
     268
     269                addq.l  #1,HZ_200               | Update 5ms clock   (200 Hz)
     270| ------------------------------------------------------------------------------
     271| process 20 Ms floppy clock
     272| ------------------------------------------------------------------------------
     273                move.w  tdiv2,d1                | Update divider
     274                addq.w  #1,d1                   | ...
     275                move.w  d1,tdiv2                | ...
     276
     277                cmpi.w  #4,d1                   | Do we need to update FRCLOCK ?
     278                blt     tmi01                   | Jump if not
     279
     280                addq.l  #1,FRCLOCK              | Update 20 Ms clock  (50 Hz)
     281                tst.w   FLOCK                   | See if floppy is active
     282                bne     tmi00                   | Don't call FLOPVBL if so
     283
     284                jsr     FLOPVBL                 | Check on the floppy
     285
     286tmi00:          move.w  #0,tdiv2                | Reset tdiv2
     287
     288tmi01:          move.w  #0,tdiv1                | Reset tdiv1
     289
     290                .page
     291| ------------------------------------------------------------------------------
     292| process PLL timers
     293| ------------------------------------------------------------------------------
     294
     295tmi02:          btst.l  #0,d0                   | Check timer 1 int
     296                beq     tmi03                   | Jump if not set
     297
     298                move.b  TIME_T1H,d1             | Read timer 1 to clear int.
     299                move.b  TIME_T1L,d1             | ...
     300
     301tmi03:          btst.l  #1,d0                   | Check for timer 2 int.
     302                beq     tmi04                   | Jump if not set
     303
     304                move.b  TIME_T2H,d1             | Read timer 2 to clear int.
     305                move.b  TIME_T2L,d1             | ...
     306
     307                .page
     308| ------------------------------------------------------------------------------
     309| update score frame counter
     310| ------------------------------------------------------------------------------
     311                tst.w   FC_SW                   | Should we update the frame ?
     312                beq     tmi04                   | Jump if not
     313
     314                bmi     tmi05                   | Jump if we count down
     315
     316                move.l  FC_VAL,d0               | Get the frame count
     317                cmp.l   #FCMAX,d0               | See it we've topped out
     318                bge     tmi06                   | Jump if limit was hit
     319
     320                addq.l  #1,d0                   | Count up 1 frame
     321                move.l  d0,FC_VAL               | Store updated frame count
     322
    323323                .ifne   FRAMES
    324                 move.w  sr,d1                   * Preserve interrupt status
    325                 ori.w   #$0700,sr               * Disable interrupts
    326 *
    327                 movea.l _M1IoRec,a0             * Point at M1IoRec
    328                 move.b  IO_CFR1(a0),d0          * Get MIDI-1 CFR1 value
    329                 or.b    #$80,d0                 * Force MSB = 1 for CFR1 output
    330                 movea.l #M1_ACIA,a0             * Point at MIDI-1 ACIA channel
    331                 bchg.l  #DTR_BIT,d0             * Toggle DTR for output
    332                 move.b  d0,ACIA_CFR(a0)         * Output toggled DTR
    333                 bchg.l  #DTR_BIT,d0             * Toggle DTR for output
    334                 move.b  d0,ACIA_CFR(a0)         * Output toggled DTR
    335                 move.w  d1,sr                   * Restore interrupts
     324                move.w  sr,d1                   | Preserve interrupt status
     325                ori.w   #0x0700,sr              | Disable interrupts
     326
     327                movea.l _M1IoRec,a0             | Point at M1IoRec
     328                move.b  IO_CFR1(a0),d0          | Get MIDI-1 CFR1 value
     329                or.b    #0x80,d0                | Force MSB = 1 for CFR1 output
     330                movea.l #M1_ACIA,a0             | Point at MIDI-1 ACIA channel
     331                bchg.l  #DTR_BIT,d0             | Toggle DTR for output
     332                move.b  d0,ACIA_CFR(a0)         | Output toggled DTR
     333                bchg.l  #DTR_BIT,d0             | Toggle DTR for output
     334                move.b  d0,ACIA_CFR(a0)         | Output toggled DTR
     335                move.w  d1,sr                   | Restore interrupts
    336336                .endc
    337 *
    338                 bra     tmi04                   * Done
    339 *
    340 tmi07:          move.l  #FCMIN,FC_VAL           * Force hard limit, just in case
    341                 bra     tmi04                   * Done
    342 *
    343 tmi06:          move.l  #FCMAX,FC_VAL           * Force hard limit, just in case
    344                 bra     tmi04                   * Done
    345 *
    346 tmi05:          move.l  FC_VAL,d0               * Get the frame count
    347                 ble     tmi07                   * Done if already counted down
    348 *
    349                 subq.l  #1,d0                   * Count down 1 frame
    350                 move.l  d0,FC_VAL               * Store udpated frame count
    351                 bra     tmi04                   * Done
    352 *
    353                 nop                             * Filler to force equal paths
    354 *
    355 tmi04:          movem.l (a7)+,d0-d7/a0-a6       * Restore registers
    356                 rte                             * Return to interrupted code
    357 *
    358                 .page
    359 * ==============================================================================
     337
     338                bra     tmi04                   | Done
     339
     340tmi07:          move.l  #FCMIN,FC_VAL           | Force hard limit, just in case
     341                bra     tmi04                   | Done
     342
     343tmi06:          move.l  #FCMAX,FC_VAL           | Force hard limit, just in case
     344                bra     tmi04                   | Done
     345
     346tmi05:          move.l  FC_VAL,d0               | Get the frame count
     347                ble     tmi07                   | Done if already counted down
     348
     349                subq.l  #1,d0                   | Count down 1 frame
     350                move.l  d0,FC_VAL               | Store udpated frame count
     351                bra     tmi04                   | Done
     352
     353                nop                             | Filler to force equal paths
     354
     355tmi04:          movem.l (a7)+,d0-d7/a0-a6       | Restore registers
     356                rte                             | Return to interrupted code
     357
     358                .page
     359| ==============================================================================
    360360                .bss
    361 * ==============================================================================
    362 *
    363 * A note on tdiv1 and tdiv2:
    364 * --------------------------
    365 *
    366 * tdiv1 and tdiv2 are actually defined in the bios,  but since they could move
    367 * we define them here and ignore the ones in the bios.
    368 *
    369 tdiv1:          ds.w    1               * Timer divider 1  (divides HZ_1K)
    370 tdiv2:          ds.w    1               * Timer divider 2  (divides HZ_200)
    371 *
    372 * ------------------------------------------------------------------------------
    373 *
    374 _timers:        ds.w    NTIMERS         * Timer array -- short timers[NTIMERS];
    375 *
    376 _vi_clk:        ds.w    1               * VSDD scroll delay timer
    377 _vi_tag:        ds.w    1               * VSDD VI 'needs service' tag
    378 *
    379 _S1IoRec:       ds.l    1               * address of RS232 channel 1 IoRec
    380 _S2IoRec:       ds.l    1               * address of RS232 channel 2 IoRec
    381 _M1IoRec:       ds.l    1               * address of MIDI channel 1 IoRec
    382 _M2IoRec:       ds.l    1               * address of MIDI channel 2 IoRec
    383 * ==============================================================================
    384 *
     361| ==============================================================================
     362
     363| A note on tdiv1 and tdiv2:
     364| --------------------------
     365
     366| tdiv1 and tdiv2 are actually defined in the bios,  but since they could move
     367| we define them here and ignore the ones in the bios.
     368
     369tdiv1:          ds.w    1               | Timer divider 1  (divides HZ_1K)
     370tdiv2:          ds.w    1               | Timer divider 2  (divides HZ_200)
     371
     372| ------------------------------------------------------------------------------
     373
     374_timers:        ds.w    NTIMERS         | Timer array -- short timers[NTIMERS];
     375
     376_vi_clk:        ds.w    1               | VSDD scroll delay timer
     377_vi_tag:        ds.w    1               | VSDD VI 'needs service' tag
     378
     379_S1IoRec:       ds.l    1               | address of RS232 channel 1 IoRec
     380_S2IoRec:       ds.l    1               | address of RS232 channel 2 IoRec
     381_M1IoRec:       ds.l    1               | address of MIDI channel 1 IoRec
     382_M2IoRec:       ds.l    1               | address of MIDI channel 2 IoRec
     383| ==============================================================================
     384
    385385                .end
  • ram/tofpu.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * tofpu.s -- convert between millisecond time interval and FPU increment formats
    3 * Version 9 -- 1987-12-21 -- D.N. Lynx Crowe
    4 *
    5 *       unsigned short
    6 *       tofpu(time)
    7 *       unsigned short time;
    8 *
    9 *               Converts 'time' in milliseconds to FPU format.
    10 *
    11 *       unsigned short
    12 *       fromfpu(fputime)
    13 *       unsigned short fputime;
    14 *
    15 *               Converts 'fputime' from FPU format to milliseconds.
    16 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| tofpu.s -- convert between millisecond time interval and FPU increment formats
     3| Version 9 -- 1987-12-21 -- D.N. Lynx Crowe
     4
     5|       unsigned short
     6|       tofpu(time)
     7|       unsigned short time;
     8
     9|               Converts 'time' in milliseconds to FPU format.
     10
     11|       unsigned short
     12|       fromfpu(fputime)
     13|       unsigned short fputime;
     14
     15|               Converts 'fputime' from FPU format to milliseconds.
     16| ------------------------------------------------------------------------------
    1717                .text
    18 *
     18
    1919                .xdef   _tofpu
    2020                .xdef   _fromfpu
    21 *
    22 TIME            .equ    8               * WORD - time argument  (either format)
    23 *
    24 TCYCL           .equ    $3B000000       * LONG - scaled FPU cycle time  (.4608)
    25 *
     21
     22TIME            =       8               | WORD - time argument  (either format)
     23
     24TCYCL           =       0x3B000000      | LONG - scaled FPU cycle time  (.4608)
     25
    2626                .page
    27 _tofpu:         link    a6,#0           * link stack frames
    28                 move.w  TIME(a6),d1     * get time interval
    29                 beq     notime          * jump if zero time
    30 *
    31                 clr.w   d2              * clear shift count
    32 *
    33 sloop:          btst    #15,d1          * see if MSB is set yet
    34                 bne     gotexp          * jump if so
    35 *
    36                 lsl.w   d1              * shift time left a bit
    37                 addq.w  #1,d2           * increment the shift count
    38                 cmpi.w  #15,d2          * see if we've hit the maximum
    39                 bne     sloop           * try again if not
    40 *
    41 gotexp:         move.l  #TCYCL,d0       * divide FPU cycle time by shifted value
    42                 divu    d1,d0           * ...
    43                 andi.w  #$FFF0,d0       * mask result
    44                 or.w    d2,d0           * set the exponent
    45 *
    46 finis:          unlk    a6              * unlink stack frames
    47                 rts                     * return to caller
    48 *
    49 notime:         clr.w   d0              * zero time is zero ...
    50                 bra     finis           * return value for zero time
    51 *
     27_tofpu:         link    a6,#0           | link stack frames
     28                move.w  TIME(a6),d1     | get time interval
     29                beq     notime          | jump if zero time
     30
     31                clr.w   d2              | clear shift count
     32
     33sloop:          btst    #15,d1          | see if MSB is set yet
     34                bne     gotexp          | jump if so
     35
     36                lsl.w   #1,d1           | shift time left a bit
     37                addq.w  #1,d2           | increment the shift count
     38                cmpi.w  #15,d2          | see if we've hit the maximum
     39                bne     sloop           | try again if not
     40
     41gotexp:         move.l  #TCYCL,d0       | divide FPU cycle time by shifted value
     42                divu    d1,d0           | ...
     43                andi.w  #0xFFF0,d0      | mask result
     44                or.w    d2,d0           | set the exponent
     45
     46finis:          unlk    a6              | unlink stack frames
     47                rts                     | return to caller
     48
     49notime:         clr.w   d0              | zero time is zero ...
     50                bra     finis           | return value for zero time
     51
    5252                .page
    53 _fromfpu:       link    a6,#0           * link stack frames
    54                 move.w  TIME(a6),d1     * get FPU formatted time
    55                 beq     zerotime        * done if it's zero
    56 *
    57                 move.w  d1,d2           * extract shift count
    58                 andi.w  #$000F,d2       * ...
    59                 andi.w  #$FFF0,d1       * extract mantissa
    60                 beq     zerotime        * ... just in case it's zero  (an error)
    61 *
    62                 move.l  #TCYCL,d0       * get FPU cycle time
    63                 divu    d1,d0           * divide by mantissa
    64                 bvc     divok           * jump if divide ok
    65 *
    66                 move.w  #$FFFF,d0       * jam maximum value for overflow
    67 *
    68 divok:          lsr.w   d2,d0           * shift result into position
    69 *
    70 byebye:         unlk    a6              * unlink stack frames
    71                 rts                     * return to caller
    72 *
    73 zerotime:       clr.l   d0              * return a zero result
    74                 bra     byebye          * ...
    75 *
     53_fromfpu:       link    a6,#0           | link stack frames
     54                move.w  TIME(a6),d1     | get FPU formatted time
     55                beq     zerotime        | done if it's zero
     56
     57                move.w  d1,d2           | extract shift count
     58                andi.w  #0x000F,d2      | ...
     59                andi.w  #0xFFF0,d1      | extract mantissa
     60                beq     zerotime        | ... just in case it's zero  (an error)
     61
     62                move.l  #TCYCL,d0       | get FPU cycle time
     63                divu    d1,d0           | divide by mantissa
     64                bvc     divok           | jump if divide ok
     65
     66                move.w  #0xFFFF,d0      | jam maximum value for overflow
     67
     68divok:          lsr.w   d2,d0           | shift result into position
     69
     70byebye:         unlk    a6              | unlink stack frames
     71                rts                     | return to caller
     72
     73zerotime:       clr.l   d0              | return a zero result
     74                bra     byebye          | ...
     75
    7676                .end
  • rom/bios.s

    rf40a309 r4f508e6  
    1 ********************************************************************************
    2 *                                                                              *
    3 * bios.s -- BIOS for the Buchla 700 and NASA 3D Helmet Display                 *
    4 * ------    --------------------------------------------------                 *
    5 *                                                                              *
    6 * See VM1,VM2 and VDATE for version and date                                   *
    7 * Written by D.N. Lynx Crowe                                                   *
    8 *                                                                              *
    9 * Very loosely based on ideas from:                                            *
    10 *                                                                              *
    11 *       "Atari ST Internals", by Abacus Software,                              *
    12 *       "A Hitchhiker's Guide to the BIOS", by Atari,                          *
    13 *       "DOS Technical Reference", by IBM,                                     *
    14 *       "DOS/360", by IBM,
    15 *       "CP/M" , by Digital Research, and, of course,                          *
    16 *       "Unix (tm)", by AT&T, et al.                                           *
    17 *                                                                              *
    18 * After all,  Why re-invent the wheel?                                         *
    19 *                                                                              *
    20 * Some of the functions are the same as Ataris, but quite a few are different, *
    21 * and our I/O configuration is much different, so BEWARE!  Make no             *
    22 * assumptions, and read the documentation and comments very carefully.         *
    23 *                                                                              *
    24 * Especially watch out for the extended BIOS functions.  Most of them          *
    25 * are nothing at all like the Atari / GEMDOS extended bios functions,          *
    26 * and even the ones that are similar have different numbers.                   *
    27 ********************************************************************************
    28 *
     1||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     2|                                                                              |
     3| bios.s -- BIOS for the Buchla 700 and NASA 3D Helmet Display                 |
     4| ------    --------------------------------------------------                 |
     5|                                                                              |
     6| See VM1,VM2 and VDATE for version and date                                   |
     7| Written by D.N. Lynx Crowe                                                   |
     8|                                                                              |
     9| Very loosely based on ideas from:                                            |
     10|                                                                              |
     11|       "Atari ST Internals", by Abacus Software,                              |
     12|       "A Hitchhiker's Guide to the BIOS", by Atari,                          |
     13|       "DOS Technical Reference", by IBM,                                     |
     14|       "DOS/360", by IBM,
     15|       "CP/M" , by Digital Research, and, of course,                          |
     16|       "Unix (tm)", by AT&T, et al.                                           |
     17|                                                                              |
     18| After all,  Why re-invent the wheel?                                         |
     19|                                                                              |
     20| Some of the functions are the same as Ataris, but quite a few are different, |
     21| and our I/O configuration is much different, so BEWARE!  Make no             |
     22| assumptions, and read the documentation and comments very carefully.         |
     23|                                                                              |
     24| Especially watch out for the extended BIOS functions.  Most of them          |
     25| are nothing at all like the Atari / GEMDOS extended bios functions,          |
     26| and even the ones that are similar have different numbers.                   |
     27||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     28
    2929                .text
    30 *
    31 * Version and date
    32 * ----------------
    33 VM1             .equ    18              * First part of version number
    34 VM2             .equ    0               * Second part of version number
    35 VDATE           .equ    $19880620       * Version date
    36 *
    37 BUCHLA          .equ    1               * Non-Zero for Buchla 700, 0 for NASA
    38 NASASIO         .equ    0               * Non-zero for NASA, 0 for Buchla addr.
    39 *
    40 FL_SKR          .equ    $00             * Seek rate  (WD1772, 6Ms/step)
    41 *************************************************************************
    42 *
    43                 .page
    44 *
    45                 .xref   start_          * Where ROMP starts
    46                 .xref   _errno          * Start of ROMP bss space
    47 *
    48                 .xdef   basepage        * Pseudo base page for romp
    49                 .xdef   _rsflag         * Register save area overflow flag
    50 *
     30
     31| Version and date
     32| ----------------
     33VM1             =       18              | First part of version number
     34VM2             =       0               | Second part of version number
     35VDATE           =       0x19880620      | Version date
     36
     37BUCHLA          =       1               | Non-Zero for Buchla 700, 0 for NASA
     38NASASIO         =       0               | Non-zero for NASA, 0 for Buchla addr.
     39
     40FL_SKR          =       0x00            | Seek rate  (WD1772, 6Ms/step)
     41|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     42
     43                .page
     44
     45                .xref   start_          | Where ROMP starts
     46                .xref   _errno          | Start of ROMP bss space
     47
     48                .xdef   basepage        | Pseudo base page for romp
     49                .xdef   _rsflag         | Register save area overflow flag
     50
    5151                .ifne   BUCHLA
    52 *
    53                 .xdef   _hdvini         * Disk init
    54 *
    55                 .endc
    56 *
    57                 .xdef   _wzcrsh         * ROMP crash flag
    58                 .xdef   _crshvc         * Crash vector
    59                 .xdef   _crshsr         * Crash SR
    60                 .xdef   _crshpc         * Crash PC
    61                 .xdef   _crshsp         * Crash SP
    62                 .xdef   _crshus         * Crash USP
    63                 .xdef   _crshrg         * Crash SP registers
    64                 .xdef   _crshst         * Crash top of stack
    65 *
    66                 .page
    67 *
     52
     53                .xdef   _hdvini         | Disk init
     54
     55                .endc
     56
     57                .xdef   _wzcrsh         | ROMP crash flag
     58                .xdef   _crshvc         | Crash vector
     59                .xdef   _crshsr         | Crash SR
     60                .xdef   _crshpc         | Crash PC
     61                .xdef   _crshsp         | Crash SP
     62                .xdef   _crshus         | Crash USP
     63                .xdef   _crshrg         | Crash SP registers
     64                .xdef   _crshst         | Crash top of stack
     65
     66                .page
     67
    6868                .ifne   BUCHLA
    69 *
     69
    7070                .xdef   _hz_1k
    7171                .xdef   _hz_200
     
    7474                .xdef   t2count
    7575                .xdef   t3count
    76 *
     76
    7777                .xdef   nflops
    7878                .xdef   disknum
     
    8181                .xdef   flock
    8282                .xdef   fverify
    83 *
     83
    8484                .xdef   retrycnt
    8585                .xdef   wpstatus
    8686                .xdef   wplatch
    8787                .xdef   bootdev
    88 *
     88
    8989                .xdef   cdev
    9090                .xdef   ctrack
     
    9292                .xdef   cside
    9393                .xdef   ccount
    94 *
     94
    9595                .xdef   cdma
    9696                .xdef   edma
    9797                .xdef   tmpdma
    9898                .xdef   rseed
    99 *
     99
    100100                .xdef   savptr
    101 *
     101
    102102                .xdef   flpsrsv
    103103                .xdef   flpregs
    104 *
     104
    105105                .xdef   dsb0
    106106                .xdef   dsb1
    107 *
     107
    108108                .xdef   dskmode
    109109                .xdef   dskerrs
    110110                .xdef   drvbpbs
    111 *
    112                 .endc
    113 *
     111
     112                .endc
     113
    114114                .xdef   biostop
    115 *
    116                 .page
    117 *
    118 * Some critical equates:
    119 * ----------------------
    120 * Interrupt masks
    121 * ---------------
    122 IPL3            .equ    $0300           * IPL 3 value for sr
    123 IPL4            .equ    $0400           * IPL 4 value for sr
    124 IPL7            .equ    $0700           * IPL 7 value for sr    (4 for debug)
    125 *
     115
     116                .page
     117
     118| Some critical equates:
     119| ----------------------
     120| Interrupt masks
     121| ---------------
     122IPL3            =       0x0300          | IPL 3 value for sr
     123IPL4            =       0x0400          | IPL 4 value for sr
     124IPL7            =       0x0700          | IPL 7 value for sr    (4 for debug)
     125
    126126                .ifne   BUCHLA
    127 *
    128 INITIPL         .equ    IPL3+$2000      * Initial Internal Priority Level
    129 *
    130                 .endc
    131 *
     127
     128INITIPL         =       IPL3+0x2000     | Initial Internal Priority Level
     129
     130                .endc
     131
    132132                .ifeq   BUCHLA
    133 *
    134 INITIPL         .equ    IPL4+$2000      * Initial Internal Priority Level
    135 *
    136                 .endc
    137 *
    138 * Memory allocation
    139 * -----------------
     133
     134INITIPL         =       IPL4+0x2000     | Initial Internal Priority Level
     135
     136                .endc
     137
     138| Memory allocation
     139| -----------------
    140140                .ifeq   BUCHLA
    141 *
    142 TPA             .equ    $008000         * Put TPA 32K up from the bottom
    143 *
    144                 .endc
    145 *
     141
     142TPA             =       0x008000        | Put TPA 32K up from the bottom
     143
     144                .endc
     145
    146146                .ifne   BUCHLA
    147 *
    148 TPA             .equ    $010000         * Put TPA 64K up from the bottom
    149 *
    150                 .endc
    151 *
    152 SSTACK          .equ    TPA             * Put system stack just below TPA
    153 *
    154 p_bbase         .equ    $0018           * Basepage offset to bss base
    155 p_blen          .equ    $001C           * Basepage offset to bss length
    156 *
    157 * It's magic ...
    158 * --------------
    159 FMAGIC          .equ    $87654321       * Magic for formatting
    160 RETRYIT         .equ    $10000          * Magic for re-try from criter
    161 RSMAGIC         .equ    $78563412       * Magic for register save area OK
    162 *
    163 * Miscellaneous constants
    164 * -----------------------
    165 FCMAX           .equ    $00FFFFFF       * Maximum frame counter value (24 bits)
    166 *
    167                 .page
    168 *
    169 * CFR0 Baud Rates:
    170 * ----------------
    171 BR_300          .equ    $04
    172 BR_600          .equ    $05
    173 BR_1200         .equ    $06
    174 BR_1800         .equ    $07
    175 BR_2400         .equ    $08
    176 BR_3600         .equ    $09
    177 BR_4800         .equ    $0A
    178 BR_7200         .equ    $0B
    179 BR_9600         .equ    $0C
    180 BR_19K2         .equ    $0D
    181 BR_EXT          .equ    $0F
    182 *
    183 * CFR0 Stop bits (includes TBR select bit):
    184 * -----------------------------------------
    185 NSB_1           .equ    $40
    186 NSB_2           .equ    $60
    187 *
    188 * CFR1 Number of Data Bits (includes MSB):
    189 * ----------------------------------------
    190 NDB_5           .equ    $80
    191 NDB_6           .equ    $A0
    192 NDB_7           .equ    $C0
    193 NDB_8           .equ    $E0
    194 *
    195 * CFR1 Parity Selection:
    196 * ----------------------
    197 P_ODD           .equ    $04
    198 P_EVEN          .equ    $0C
    199 P_MARK          .equ    $14
    200 P_SPACE         .equ    $1C
    201 *
    202 P_NONE          .equ    $00
    203 *
    204 * Line Discipline:
    205 * ----------------
    206 L_NUL           .equ    $00             * No protocol
    207 L_XON           .equ    $01             * XON/XOFF
    208 L_RTS           .equ    $02             * RTS/CTS
    209 *
    210                 .page
    211 *
    212 * I/O Buffer Sizes:
    213 * -----------------
    214 SR1IBS          .equ    256
    215 SR1OBS          .equ    256
    216 SR2IBS          .equ    256
    217 SR2OBS          .equ    256
    218 *
     147
     148TPA             =       0x010000        | Put TPA 64K up from the bottom
     149
     150                .endc
     151
     152SSTACK          =       TPA             | Put system stack just below TPA
     153
     154p_bbase         =       0x0018          | Basepage offset to bss base
     155p_blen          =       0x001C          | Basepage offset to bss length
     156
     157| It's magic ...
     158| --------------
     159FMAGIC          =       0x87654321      | Magic for formatting
     160RETRYIT         =       0x10000         | Magic for re-try from criter
     161RSMAGIC         =       0x78563412      | Magic for register save area OK
     162
     163| Miscellaneous constants
     164| -----------------------
     165FCMAX           =       0x00FFFFFF      | Maximum frame counter value (24 bits)
     166
     167                .page
     168
     169| CFR0 Baud Rates:
     170| ----------------
     171BR_300          =       0x04
     172BR_600          =       0x05
     173BR_1200         =       0x06
     174BR_1800         =       0x07
     175BR_2400         =       0x08
     176BR_3600         =       0x09
     177BR_4800         =       0x0A
     178BR_7200         =       0x0B
     179BR_9600         =       0x0C
     180BR_19K2         =       0x0D
     181BR_EXT          =       0x0F
     182
     183| CFR0 Stop bits (includes TBR select bit):
     184| -----------------------------------------
     185NSB_1           =       0x40
     186NSB_2           =       0x60
     187
     188| CFR1 Number of Data Bits (includes MSB):
     189| ----------------------------------------
     190NDB_5           =       0x80
     191NDB_6           =       0xA0
     192NDB_7           =       0xC0
     193NDB_8           =       0xE0
     194
     195| CFR1 Parity Selection:
     196| ----------------------
     197P_ODD           =       0x04
     198P_EVEN          =       0x0C
     199P_MARK          =       0x14
     200P_SPACE         =       0x1C
     201
     202P_NONE          =       0x00
     203
     204| Line Discipline:
     205| ----------------
     206L_NUL           =       0x00            | No protocol
     207L_XON           =       0x01            | XON/XOFF
     208L_RTS           =       0x02            | RTS/CTS
     209
     210                .page
     211
     212| I/O Buffer Sizes:
     213| -----------------
     214SR1IBS          =       256
     215SR1OBS          =       256
     216SR2IBS          =       256
     217SR2OBS          =       256
     218
    219219                .ifne   BUCHLA
    220 *
    221 MC1IBS          .equ    512
    222 MC1OBS          .equ    256
    223 MC2IBS          .equ    512
    224 MC2OBS          .equ    256
    225 *
    226                 .endc
    227 *
    228 * Line Disciplines:
    229 * -----------------
    230 SR1DISC         .equ    L_XON
    231 SR2DISC         .equ    L_XON
    232 *
     220
     221MC1IBS          =       512
     222MC1OBS          =       256
     223MC2IBS          =       512
     224MC2OBS          =       256
     225
     226                .endc
     227
     228| Line Disciplines:
     229| -----------------
     230SR1DISC         =       L_XON
     231SR2DISC         =       L_XON
     232
    233233                .ifne   BUCHLA
    234 *
    235 MC1DISC         .equ    L_NUL
    236 MC2DISC         .equ    L_NUL
    237 *
    238                 .endc
    239 *
    240 * CFR Setings:
    241 * ------------
    242 SR1CFR0         .equ    BR_9600+NSB_1
    243 SR1CFR1         .equ    NDB_8+P_NONE
    244 SR2CFR0         .equ    BR_9600+NSB_1
    245 SR2CFR1         .equ    NDB_8+P_NONE
    246 *
     234
     235MC1DISC         =       L_NUL
     236MC2DISC         =       L_NUL
     237
     238                .endc
     239
     240| CFR Setings:
     241| ------------
     242SR1CFR0         =       BR_9600+NSB_1
     243SR1CFR1         =       NDB_8+P_NONE
     244SR2CFR0         =       BR_9600+NSB_1
     245SR2CFR1         =       NDB_8+P_NONE
     246
    247247                .ifne   BUCHLA
    248 *
    249 MC1CFR0         .equ    BR_EXT+NSB_1
    250 MC1CFR1         .equ    NDB_8+P_NONE
    251 MC2CFR0         .equ    BR_EXT+NSB_1
    252 MC2CFR1         .equ    NDB_8+P_NONE
    253 *
    254                 .endc
    255 *
    256                 .page
    257 *
    258 * I/O Addresses:
    259 * --------------
    260 VSDDINIT        .equ    $200400         * VSDD initial register base address
    261 VSDDDATA        .equ    $200000         * VSDD data segment base address
    262 *
     248
     249MC1CFR0         =       BR_EXT+NSB_1
     250MC1CFR1         =       NDB_8+P_NONE
     251MC2CFR0         =       BR_EXT+NSB_1
     252MC2CFR1         =       NDB_8+P_NONE
     253
     254                .endc
     255
     256                .page
     257
     258| I/O Addresses:
     259| --------------
     260VSDDINIT        =       0x200400        | VSDD initial register base address
     261VSDDDATA        =       0x200000        | VSDD data segment base address
     262
    263263                .ifeq   BUCHLA
    264 *
     264
    265265                .ifeq   NASASIO
    266 *
    267 SR1ACIA         .equ    $3A8001         * Serial-1 ACIA base address    (BUCHLA)
    268 SR2ACIA         .equ    $3A8009         * Serial-2 ACIA base address
    269 *
    270                 .endc
    271 *
     266
     267SR1ACIA         =       0x3A8001        | Serial-1 ACIA base address    (BUCHLA)
     268SR2ACIA         =       0x3A8009        | Serial-2 ACIA base address
     269
     270                .endc
     271
    272272                .ifne   NASASIO
    273 *
    274 SR1ACIA         .equ    $398001         * Serial-1 ACIA base address    (NASA)
    275 SR2ACIA         .equ    $398009         * Serial-2 ACIA base address
    276 *
    277                 .endc
    278 *
    279                 .endc
    280 *
     273
     274SR1ACIA         =       0x398001        | Serial-1 ACIA base address    (NASA)
     275SR2ACIA         =       0x398009        | Serial-2 ACIA base address
     276
     277                .endc
     278
     279                .endc
     280
    281281                .ifne   BUCHLA
    282 *
    283 FPUBASE         .equ    $180000         * FPU base address
    284 TIMER           .equ    $3A0001         * Timer base address
    285 LCD             .equ    $3A4001         * LCD driver base address
    286 SR1ACIA         .equ    $3A8001         * Serial-1 ACIA base address    (BUCHLA)
    287 SR2ACIA         .equ    $3A8009         * Serial-2 ACIA base address
    288 MC1ACIA         .equ    $3AC001         * MIDI-1 ACIA base address
    289 MC2ACIA         .equ    $3AC009         * MIDI-2 ACIA base address
    290 FLOPPY          .equ    $3B0001         * Floppy controller base address
    291 PSG             .equ    $3B4001         * Sound chip base address
    292 LEDS            .equ    $3B8001         * LED driver base address
    293 ANALOG          .equ    $3BC001         * Analog processor base address
    294 *
    295 * FPU address offsets and misc. values
    296 *
    297 FPU_CTL         .equ    $4000           * FPU control
    298 *
    299 FPU_IN          .equ    $4000           * FPU input address
    300 FPU_CLR         .equ    $6000           * FPU interrupt reset address
    301 *
    302 FPU_RST         .equ    $0015           * FPU reset value
    303 *
    304 * PSG address offsets
    305 *
    306 PSG_RD          .equ    PSG             * Read PSG data
    307 PSG_WL          .equ    PSG             * Write PSG address latch
    308 PSG_WD          .equ    PSG+2           * Write PSG data
    309 *
    310                 .endc
    311 *
    312 * VSDD data structure offsets
    313 *
    314 VSDD_REG        .equ    VSDDDATA        * Registers
    315 VSDD_AT         .equ    VSDDDATA+$0100  * Access Table
    316 *
     282
     283FPUBASE         =       0x180000        | FPU base address
     284TIMER           =       0x3A0001        | Timer base address
     285LCD             =       0x3A4001        | LCD driver base address
     286SR1ACIA         =       0x3A8001        | Serial-1 ACIA base address    (BUCHLA)
     287SR2ACIA         =       0x3A8009        | Serial-2 ACIA base address
     288MC1ACIA         =       0x3AC001        | MIDI-1 ACIA base address
     289MC2ACIA         =       0x3AC009        | MIDI-2 ACIA base address
     290FLOPPY          =       0x3B0001        | Floppy controller base address
     291PSG             =       0x3B4001        | Sound chip base address
     292LEDS            =       0x3B8001        | LED driver base address
     293ANALOG          =       0x3BC001        | Analog processor base address
     294
     295| FPU address offsets and misc. values
     296
     297FPU_CTL         =       0x4000          | FPU control
     298
     299FPU_IN          =       0x4000          | FPU input address
     300FPU_CLR         =       0x6000          | FPU interrupt reset address
     301
     302FPU_RST         =       0x0015          | FPU reset value
     303
     304| PSG address offsets
     305
     306PSG_RD          =       PSG             | Read PSG data
     307PSG_WL          =       PSG             | Write PSG address latch
     308PSG_WD          =       PSG+2           | Write PSG data
     309
     310                .endc
     311
     312| VSDD data structure offsets
     313
     314VSDD_REG        =       VSDDDATA        | Registers
     315VSDD_AT         =       VSDDDATA+0x0100 | Access Table
     316
    317317                .ifne   BUCHLA
    318 *
    319 * Timer registers
    320 *
    321 TIME_CRX        .equ    TIMER           * Control register 1 or 3
    322 TIME_CR2        .equ    TIMER+2         * Control register 2
    323 TIME_T1H        .equ    TIMER+4         * Timer 1 high byte
    324 TIME_T1L        .equ    TIMER+6         * Timer 1 low byte
    325 TIME_T2H        .equ    TIMER+8         * Tiemr 2 high byte
    326 TIME_T2L        .equ    TIMER+10        * Timer 2 low byte
    327 TIME_T3H        .equ    TIMER+12        * Timer 3 high byte
    328 TIME_T3L        .equ    TIMER+14        * Timer 3 low byte
    329 *
    330                 .endc
    331 *
    332 * ACIA Register offsets:
    333 * ----------------------
    334 ACIA_IER        .equ    0               * ACIA IER offset
    335 ACIA_ISR        .equ    0               * ACIA ISR offset
    336 ACIA_CSR        .equ    2               * ACIA CSR offset
    337 ACIA_CFR        .equ    2               * ACIA CFR offset
    338 ACIA_TBR        .equ    4               * ACIA TBR offset
    339 ACIA_TDR        .equ    6               * ACIA TDR offset
    340 ACIA_RDR        .equ    6               * ACIA RDR offset
    341 *
    342                 .page
    343 *
     318
     319| Timer registers
     320
     321TIME_CRX        =       TIMER           | Control register 1 or 3
     322TIME_CR2        =       TIMER+2         | Control register 2
     323TIME_T1H        =       TIMER+4         | Timer 1 high byte
     324TIME_T1L        =       TIMER+6         | Timer 1 low byte
     325TIME_T2H        =       TIMER+8         | Tiemr 2 high byte
     326TIME_T2L        =       TIMER+10        | Timer 2 low byte
     327TIME_T3H        =       TIMER+12        | Timer 3 high byte
     328TIME_T3L        =       TIMER+14        | Timer 3 low byte
     329
     330                .endc
     331
     332| ACIA Register offsets:
     333| ----------------------
     334ACIA_IER        =       0               | ACIA IER offset
     335ACIA_ISR        =       0               | ACIA ISR offset
     336ACIA_CSR        =       2               | ACIA CSR offset
     337ACIA_CFR        =       2               | ACIA CFR offset
     338ACIA_TBR        =       4               | ACIA TBR offset
     339ACIA_TDR        =       6               | ACIA TDR offset
     340ACIA_RDR        =       6               | ACIA RDR offset
     341
     342                .page
     343
    344344                .ifne   BUCHLA
    345 *
    346 * Floppy register offsets:
    347 * ------------------------
    348 DSKCMD          .equ    0               * Command / status
    349 DSKTRK          .equ    2               * Track
    350 DSKSEC          .equ    4               * Sector
    351 DSKDAT          .equ    6               * Data
    352 *
    353 * Miscellaneous equates:
    354 * ----------------------
    355 FL_NC           .equ    $02             * Non-compensated R/W/F bit
    356 *
    357 APISIZE         .equ    256             * Analog processor buffer size
    358 *
    359 * Floppy commands:
    360 * ----------------
    361 FL_RS           .equ    $80             * Read sector
    362 FL_RM           .equ    $90             * Read multiple
    363 FL_WS           .equ    $A0             * Write sector
    364 FL_WT           .equ    $F0             * Write track  (format)
    365 FL_FR           .equ    $D0             * Force reset
    366 FL_SK           .equ    $10             * Seek
    367 FL_SV           .equ    $14             * Seek w/verify
    368 *
    369                 .endc
    370 *
    371                 .page
    372 *
    373 * iorec structure definitions:
    374 * ----------------------------
    375 IORECLN         .equ    40              * Length of an iorec structure
    376 *
    377 ibuf            .equ    0               * Input buffer base address
    378 ibufsize        .equ    4               * Input buffer size  (bytes)
    379 ibufhd          .equ    6               * Input buffer head index
    380 ibuftl          .equ    8               * Input buffer tail index
    381 ibuflow         .equ    10              * Input buffer low water mark
    382 ibufhi          .equ    12              * Input buffer high water mark
    383 obuf            .equ    14              * Output buffer base address
    384 obufsize        .equ    18              * Output buffer size  (bytes)
    385 obufhd          .equ    20              * Output buffer head index
    386 obuftl          .equ    22              * Output buffer tail index
    387 obuflow         .equ    24              * Output buffer low water mark
    388 obufhi          .equ    26              * Output buffer high water mark
    389 cfr0            .equ    28              * ACIA CFR, MS bit = 0
    390 cfr1            .equ    29              * ACIA CFR, MS bit = 1
    391 flagxon         .equ    30              * XON flag  (non-zero = XOFF sent)
    392 flagxoff        .equ    31              * XOFF flag  (non-zero = active)
    393 linedisc        .equ    32              * Line discipline flags
    394 erbyte          .equ    33              * Last error byte
    395 isr             .equ    34              * ACIA ISR on interrupt
    396 csr             .equ    35              * ACIA CSR on interrupt
    397 errct           .equ    36              * Error count  (FRM/OVR/BRK)
    398 ibfct           .equ    38              * Input buffer full count
    399 *
    400                 .page
    401 *
    402 * Error codes:
    403 * ------------
    404 ERR01           .equ    -1              * All purpose error
    405 ERR02           .equ    -2              * Drive not ready
    406 ERR03           .equ    -3              * Unknown command
    407 ERR04           .equ    -4              * CRC Error
    408 ERR05           .equ    -5              * Invalid request
    409 ERR06           .equ    -6              * Seek error
    410 ERR07           .equ    -7              * Unknown media
    411 ERR08           .equ    -8              * Sector not found
    412 ERR09           .equ    -9              * End of media  (out of paper)
    413 ERR10           .equ    -10             * Write fault
    414 ERR11           .equ    -11             * Read fault
    415 ERR12           .equ    -12             * General mishap
    416 ERR13           .equ    -13             * Write protected
    417 ERR14           .equ    -14             * Media changed
    418 ERR15           .equ    -15             * Unknown device
    419 ERR16           .equ    -16             * Bad sectors
    420 ERR17           .equ    -17             * Insert disk
    421 *
    422                 .page
    423 *
    424 * In the Beginning...
    425 * -------------------
    426 *
    427 * Low PROM -- Contains the initial sp (unused), and the initial pc,
    428 * as well as some version and creation date stuff and a copyright message,
    429 * just to be thorough about it.
    430 *
    431 begin:          bra.s   biosinit                * Jump to bios init
    432 *
    433 vermsg:         dc.b    VM1,VM2                 * Version number
    434 *
    435                 dc.l    biosinit                * Reset address (bios init)
    436 *
    437 created:        dc.l    VDATE                   * Creation date
    438 *
    439 copyrite:       dc.b    '{Copyright 1988 by '   * Copyright message
    440                 dc.b    'D.N. Lynx Crowe}',0
    441 *
    442                 dc.l    0                       * Some padding
    443 *
     345
     346| Floppy register offsets:
     347| ------------------------
     348DSKCMD          =       0               | Command / status
     349DSKTRK          =       2               | Track
     350DSKSEC          =       4               | Sector
     351DSKDAT          =       6               | Data
     352
     353| Miscellaneous equates:
     354| ----------------------
     355FL_NC           =       0x02            | Non-compensated R/W/F bit
     356
     357APISIZE         =       256             | Analog processor buffer size
     358
     359| Floppy commands:
     360| ----------------
     361FL_RS           =       0x80            | Read sector
     362FL_RM           =       0x90            | Read multiple
     363FL_WS           =       0xA0            | Write sector
     364FL_WT           =       0xF0            | Write track  (format)
     365FL_FR           =       0xD0            | Force reset
     366FL_SK           =       0x10            | Seek
     367FL_SV           =       0x14            | Seek w/verify
     368
     369                .endc
     370
     371                .page
     372
     373| iorec structure definitions:
     374| ----------------------------
     375IORECLN         =       40              | Length of an iorec structure
     376
     377ibuf            =       0               | Input buffer base address
     378ibufsize        =       4               | Input buffer size  (bytes)
     379ibufhd          =       6               | Input buffer head index
     380ibuftl          =       8               | Input buffer tail index
     381ibuflow         =       10              | Input buffer low water mark
     382ibufhi          =       12              | Input buffer high water mark
     383obuf            =       14              | Output buffer base address
     384obufsize        =       18              | Output buffer size  (bytes)
     385obufhd          =       20              | Output buffer head index
     386obuftl          =       22              | Output buffer tail index
     387obuflow         =       24              | Output buffer low water mark
     388obufhi          =       26              | Output buffer high water mark
     389cfr0            =       28              | ACIA CFR, MS bit = 0
     390cfr1            =       29              | ACIA CFR, MS bit = 1
     391flagxon         =       30              | XON flag  (non-zero = XOFF sent)
     392flagxoff        =       31              | XOFF flag  (non-zero = active)
     393linedisc        =       32              | Line discipline flags
     394erbyte          =       33              | Last error byte
     395isr             =       34              | ACIA ISR on interrupt
     396csr             =       35              | ACIA CSR on interrupt
     397errct           =       36              | Error count  (FRM/OVR/BRK)
     398ibfct           =       38              | Input buffer full count
     399
     400                .page
     401
     402| Error codes:
     403| ------------
     404ERR01           =       -1              | All purpose error
     405ERR02           =       -2              | Drive not ready
     406ERR03           =       -3              | Unknown command
     407ERR04           =       -4              | CRC Error
     408ERR05           =       -5              | Invalid request
     409ERR06           =       -6              | Seek error
     410ERR07           =       -7              | Unknown media
     411ERR08           =       -8              | Sector not found
     412ERR09           =       -9              | End of media  (out of paper)
     413ERR10           =       -10             | Write fault
     414ERR11           =       -11             | Read fault
     415ERR12           =       -12             | General mishap
     416ERR13           =       -13             | Write protected
     417ERR14           =       -14             | Media changed
     418ERR15           =       -15             | Unknown device
     419ERR16           =       -16             | Bad sectors
     420ERR17           =       -17             | Insert disk
     421
     422                .page
     423
     424| In the Beginning...
     425| -------------------
     426
     427| Low PROM -- Contains the initial sp (unused), and the initial pc,
     428| as well as some version and creation date stuff and a copyright message,
     429| just to be thorough about it.
     430
     431begin:          bra.s   biosinit                | Jump to bios init
     432
     433vermsg:         dc.b    VM1,VM2                 | Version number
     434
     435                dc.l    biosinit                | Reset address (bios init)
     436
     437created:        dc.l    VDATE                   | Creation date
     438
     439copyrite:       dc.b    "{Copyright 1988 by "   | Copyright message
     440                dc.b    "D.N. Lynx Crowe}",0
     441
     442                dc.l    0                       | Some padding
     443
    444444                .page
    445445                .even
    446 *
    447 * biosinit -- Setup the defaults for the BIOS
    448 * --------    -------------------------------
    449 biosinit:       move.w  #$2700,sr               * Set sup mode, no interrupts
    450                 move.l  #SSTACK,a7              * Setup supervisor stack pointer
    451 *
    452                 lea     badtrap,a1              * Set default trap vector
    453                 adda.l  #$02000000,a1           * ... with trap # in 31..24
    454                 lea     8,a0                    * ... for traps 2..255
     446
     447| biosinit -- Setup the defaults for the BIOS
     448| --------    -------------------------------
     449biosinit:       move.w  #0x2700,sr              | Set sup mode, no interrupts
     450                move.l  #SSTACK,a7              | Setup supervisor stack pointer
     451
     452                lea     badtrap,a1              | Set default trap vector
     453                adda.l  #0x02000000,a1          | ... with trap # in 31..24
     454                lea     8,a0                    | ... for traps 2..255
    455455                move.l  #253,d1
    456 *
    457 binit1:         move.l  a1,(a0)+                * Store trap vector
    458                 adda.l  #$01000000,a1           * Increment trap #
    459                 dbf     d1,binit1               * Loop until done
    460 *
    461                 lea     biosram,a0              * Clear BIOS ram ...
    462                 lea     SSTACK-2,a1             * ... from biosram to SSTACK-1
    463 *
    464 binit2:         move.w  #0,(a0)+                * Zero a word
    465                 cmpa.l  a0,a1                   * Last one ?
    466                 bne     binit2                  * Loop if not
    467 *
    468                 move.l  #rsarea,savptr          * Setup pointer to register area
    469                 move.l  #RSMAGIC,_rsflag        * Set magic in _rsflag
    470 *
    471                 move.l  #nullrts,timevec        * Set timer interrupt vector
    472                 move.l  #nullrts,critvec        * Set critical error vector
    473                 move.l  #nullrts,termvec        * Set process terminate vector
    474                 move.l  #nullrts,resvec3        * Set software vector 3
    475                 move.l  #nullrts,resvec4        * Set software vector 4
    476                 move.l  #nullrts,resvec5        * Set software vector 5
    477                 move.l  #nullrts,resvec6        * Set software vector 6
    478                 move.l  #nullrts,resvec7        * Set software vector 7
    479 *
    480                 move.l  #hardhlt,$0008          * Set bus error vector
    481                 move.l  #nullrte,$0014          * Set divide error vector
    482                 move.l  #nullrte,$0018          * Set CHK vector
    483                 move.l  #nullrte,$001C          * Set TRAPV vector
    484                 move.l  #nullrte,$0024          * Set trace vector
    485 *
    486                 move.l  #nullrte,$0030          * Set reserved vector 12
    487                 move.l  #nullrte,$0034          * Set reserved vector 13
    488                 move.l  #nullrte,$0038          * Set reserved vector 14
    489 *
    490                 move.l  #nullrte,$003C          * Set uninitialized int. vector
    491 *
    492                 move.l  #nullrte,$0040          * Set reserved vector 16
    493                 move.l  #nullrte,$0044          * Set reserved vector 17
    494                 move.l  #nullrte,$0048          * Set reserved vector 18
    495                 move.l  #nullrte,$004C          * Set reserved vector 19
    496                 move.l  #nullrte,$0050          * Set reserved vector 20
    497                 move.l  #nullrte,$0054          * Set reserved vector 21
    498                 move.l  #nullrte,$0058          * Set reserved vector 22
    499                 move.l  #nullrte,$005C          * Set reserved vector 23
    500 *
    501                 move.l  #nullrte,$0060          * Set spurious int. vector
    502 *
    503                 move.l  #serintr,$0074          * Set ACIA interrupt vector
    504                 move.l  #nullrte,$0078          * Set level 6 vector
    505                 move.l  #nullrte,$007C          * Set level 7 vector
    506 *
    507                 move.l  #trap13,$00B4           * Set trap13 vector
    508                 move.l  #trap14,$00B8           * Set trap14 vector
    509 *
    510                 .page
    511 *
     456
     457binit1:         move.l  a1,(a0)+                | Store trap vector
     458                adda.l  #0x01000000,a1          | Increment trap #
     459                dbf     d1,binit1               | Loop until done
     460
     461                lea     biosram,a0              | Clear BIOS ram ...
     462                lea     SSTACK-2,a1             | ... from biosram to SSTACK-1
     463
     464binit2:         move.w  #0,(a0)+                | Zero a word
     465                cmpa.l  a0,a1                   | Last one ?
     466                bne     binit2                  | Loop if not
     467
     468                move.l  #rsarea,savptr          | Setup pointer to register area
     469                move.l  #RSMAGIC,_rsflag        | Set magic in _rsflag
     470
     471                move.l  #nullrts,timevec        | Set timer interrupt vector
     472                move.l  #nullrts,critvec        | Set critical error vector
     473                move.l  #nullrts,termvec        | Set process terminate vector
     474                move.l  #nullrts,resvec3        | Set software vector 3
     475                move.l  #nullrts,resvec4        | Set software vector 4
     476                move.l  #nullrts,resvec5        | Set software vector 5
     477                move.l  #nullrts,resvec6        | Set software vector 6
     478                move.l  #nullrts,resvec7        | Set software vector 7
     479
     480                move.l  #hardhlt,0x0008         | Set bus error vector
     481                move.l  #nullrte,0x0014         | Set divide error vector
     482                move.l  #nullrte,0x0018         | Set CHK vector
     483                move.l  #nullrte,0x001C         | Set TRAPV vector
     484                move.l  #nullrte,0x0024         | Set trace vector
     485
     486                move.l  #nullrte,0x0030         | Set reserved vector 12
     487                move.l  #nullrte,0x0034         | Set reserved vector 13
     488                move.l  #nullrte,0x0038         | Set reserved vector 14
     489
     490                move.l  #nullrte,0x003C         | Set uninitialized int. vector
     491
     492                move.l  #nullrte,0x0040         | Set reserved vector 16
     493                move.l  #nullrte,0x0044         | Set reserved vector 17
     494                move.l  #nullrte,0x0048         | Set reserved vector 18
     495                move.l  #nullrte,0x004C         | Set reserved vector 19
     496                move.l  #nullrte,0x0050         | Set reserved vector 20
     497                move.l  #nullrte,0x0054         | Set reserved vector 21
     498                move.l  #nullrte,0x0058         | Set reserved vector 22
     499                move.l  #nullrte,0x005C         | Set reserved vector 23
     500
     501                move.l  #nullrte,0x0060         | Set spurious int. vector
     502
     503                move.l  #serintr,0x0074         | Set ACIA interrupt vector
     504                move.l  #nullrte,0x0078         | Set level 6 vector
     505                move.l  #nullrte,0x007C         | Set level 7 vector
     506
     507                move.l  #trap13,0x00B4          | Set trap13 vector
     508                move.l  #trap14,0x00B8          | Set trap14 vector
     509
     510                .page
     511
    512512                .ifne   BUCHLA
    513 *
    514                 move.l  #nullfpu,$0068          * Set FPU interrupt vector
    515                 move.l  #api_int,$006C          * Set analog trap vector
    516                 move.l  #timeint,$0070          * Set timer trap vector
    517 *
    518                 move.l  #_hdvini,hdv_init       * Set disk init vector
    519                 move.l  #getbpb,hdv_bpb         * Set get BPB vector
    520                 move.l  #rwabs,hdv_rw           * Set disk I/O vector
    521                 move.l  #bootload,hdv_boot      * Setup boot load vector
    522                 move.l  #mediach,hdv_mchg       * Setup media change vector
    523 *
    524                 move.w  #$FFFF,fverify          * Set read after write flag
    525                 move.w  #FL_SKR,seekrate        * Set default seek rate
    526                 move.w  #$FFFF,booted           * Say we're not booted yet
    527                 move.l  #buffer,dskbufp         * Setup default disk buffer
    528 *
    529                 .page
    530 *
    531                 move.b  #7,PSG_WL               * Select PSG R7
    532                 move.b  #$80,PSG_WD             * Write $80  (port B = output)
    533                 move.b  #15,PSG_WL              * Select PSG R15
    534                 move.b  #$00,PSG_WD             * Write $00  (sync enable)
    535 *
    536                 move.b  #$00,TIME_T1H           * Setup timer 1  (PLL)
    537                 move.b  #$1F,TIME_T1L           * ... for divide by 64
    538                 move.b  #$0C,TIME_T2H           * Setup timer 2  (FC)
    539                 move.b  #$7F,TIME_T2L           * ... for divide by 3200
    540                 move.b  #$03,TIME_T3H           * Setup timer 3  (RTC)
    541                 move.b  #$20,TIME_T3L           * ... for 1Ms interval
    542                 move.b  #$42,TIME_CRX           * Setup CR3
    543                 move.b  #$41,TIME_CR2           * Setup CR2
    544                 move.b  #$81,TIME_CRX           * Setup CR1
    545                 move.b  #$80,TIME_CRX           * Start the timers
    546 *
    547                 .endc
    548 *
    549                 lea     sr1iorec,a0             * Serial-1 iorec address to a0
    550                 lea     SR1ACIA,a1              * Serial-1 ACIA address to a1
    551                 lea     sr1dflt,a2              * Serial-1 dflt table addr to a2
    552                 bsr.w   aciainit                * Go initialize the port
    553 *
    554                 lea     sr2iorec,a0             * Serial-2 iorec address to a0
    555                 lea     SR2ACIA,a1              * Serial-2 ACIA address to a1
    556                 lea     sr2dflt,a2              * Serial-2 dflt table addr to a2
    557                 bsr.w   aciainit                * Go initialize the port
    558 *
     513
     514                move.l  #nullfpu,0x0068         | Set FPU interrupt vector
     515                move.l  #api_int,0x006C         | Set analog trap vector
     516                move.l  #timeint,0x0070         | Set timer trap vector
     517
     518                move.l  #_hdvini,hdv_init       | Set disk init vector
     519                move.l  #getbpb,hdv_bpb         | Set get BPB vector
     520                move.l  #rwabs,hdv_rw           | Set disk I/O vector
     521                move.l  #bootload,hdv_boot      | Setup boot load vector
     522                move.l  #mediach,hdv_mchg       | Setup media change vector
     523
     524                move.w  #0xFFFF,fverify         | Set read after write flag
     525                move.w  #FL_SKR,seekrate        | Set default seek rate
     526                move.w  #0xFFFF,booted          | Say we're not booted yet
     527                move.l  #buffer,dskbufp         | Setup default disk buffer
     528
     529                .page
     530
     531                move.b  #7,PSG_WL               | Select PSG R7
     532                move.b  #0x80,PSG_WD            | Write 0x80  (port B = output)
     533                move.b  #15,PSG_WL              | Select PSG R15
     534                move.b  #0x00,PSG_WD            | Write 0x00  (sync enable)
     535
     536                move.b  #0x00,TIME_T1H          | Setup timer 1  (PLL)
     537                move.b  #0x1F,TIME_T1L          | ... for divide by 64
     538                move.b  #0x0C,TIME_T2H          | Setup timer 2  (FC)
     539                move.b  #0x7F,TIME_T2L          | ... for divide by 3200
     540                move.b  #0x03,TIME_T3H          | Setup timer 3  (RTC)
     541                move.b  #0x20,TIME_T3L          | ... for 1Ms interval
     542                move.b  #0x42,TIME_CRX          | Setup CR3
     543                move.b  #0x41,TIME_CR2          | Setup CR2
     544                move.b  #0x81,TIME_CRX          | Setup CR1
     545                move.b  #0x80,TIME_CRX          | Start the timers
     546
     547                .endc
     548
     549                lea     sr1iorec,a0             | Serial-1 iorec address to a0
     550                lea     SR1ACIA,a1              | Serial-1 ACIA address to a1
     551                lea     sr1dflt,a2              | Serial-1 dflt table addr to a2
     552                bsr.w   aciainit                | Go initialize the port
     553
     554                lea     sr2iorec,a0             | Serial-2 iorec address to a0
     555                lea     SR2ACIA,a1              | Serial-2 ACIA address to a1
     556                lea     sr2dflt,a2              | Serial-2 dflt table addr to a2
     557                bsr.w   aciainit                | Go initialize the port
     558
    559559                .ifne   BUCHLA
    560 *
    561                 lea     mc1iorec,a0             * MIDI-1 iorec address to a0
    562                 lea     MC1ACIA,a1              * MIDI-1 ACIA address to a1
    563                 lea     mc1dflt,a2              * MIDI-1 dflt table addr to a2
    564                 bsr.w   aciainit                * Go initialize the port
    565 *
    566                 lea     mc2iorec,a0             * MIDI-2 iorec address to a0
    567                 lea     MC2ACIA,a1              * MIDI-2 ACIA address to a1
    568                 lea     mc2dflt,a2              * MIDI-2 dflt table addr to a2
    569                 bsr.w   aciainit                * Go initialize the port
    570 *
    571                 .page
    572 *
    573                 lea     VSDDINIT,a1             * Setup to load VSDD regs
    574                 lea     vsddtab,a0              * ... from vsddtab
    575                 move.w  #15,d0                  * ... all 16 registers
    576 *
    577 vsddinit:       move.w  (a0)+,(a1)+             * Load the VSDD registers
     560
     561                lea     mc1iorec,a0             | MIDI-1 iorec address to a0
     562                lea     MC1ACIA,a1              | MIDI-1 ACIA address to a1
     563                lea     mc1dflt,a2              | MIDI-1 dflt table addr to a2
     564                bsr.w   aciainit                | Go initialize the port
     565
     566                lea     mc2iorec,a0             | MIDI-2 iorec address to a0
     567                lea     MC2ACIA,a1              | MIDI-2 ACIA address to a1
     568                lea     mc2dflt,a2              | MIDI-2 dflt table addr to a2
     569                bsr.w   aciainit                | Go initialize the port
     570
     571                .page
     572
     573                lea     VSDDINIT,a1             | Setup to load VSDD regs
     574                lea     vsddtab,a0              | ... from vsddtab
     575                move.w  #15,d0                  | ... all 16 registers
     576
     577vsddinit:       move.w  (a0)+,(a1)+             | Load the VSDD registers
    578578                btst.l  #0,d0
    579579                btst.l  #0,d0
    580580                btst.l  #0,d0
    581581                dbf     d0,vsddinit
    582 *
    583                 move.w  vsddit02,VSDDINIT       * Enable the video
    584 *
    585                 move.l  #api_fum,api_fi         * Clear analog processor fifo
    586                 move.l  #api_fum,api_fo         * ...
    587 *
    588                 move.w  #23,d0                  * Setup to clear key LEDs
    589                 move.b  #$80,d1                 * ...
    590 *
    591 ledclear:       move.b  d1,LEDS                 * Clear a LED
    592                 addq.b  #1,d1                   * Increment LED number
    593                 dbra    d0,ledclear             * Loop until all are done
    594 *
    595                 move.w  #7,d0                   * Setup to clear pot LEDs
    596                 move.b  #$18,d1                 * ...
    597 *
    598 ledclr2:        move.b  d1,LEDS                 * Clear a LED
    599                 addq.b  #1,d1                   * Increment LED number
    600                 dbra    d0,ledclr2              * Loop until all are done
    601 *
    602                 clr.w   fc_sw                   * Stop the frame clock
    603                 clr.l   fc_val                  * ... and reset it
    604 *
    605                 .page
    606 *
    607                 lea     FPUBASE+FPU_CTL,a0      * Point at FPU master level
    608                 move.w  #$0000,$08(a0)          * Set CV1 to 0
    609                 addq.w  #1,d0                   * Delay
    610                 addq.w  #1,d0                   * ...
    611                 move.w  #$0000,$0A(a0)          * Set SF1 to 0
    612                 addq.w  #1,d0                   * Delay
    613                 addq.w  #1,d0                   * ...
    614                 move.w  #$0000,$0C(a0)          * Set CV2 to 0
    615                 addq.w  #1,d0                   * Delay
    616                 addq.w  #1,d0                   * ...
    617                 move.w  #$0000,$0E(a0)          * Set SF2 to 0
    618                 addq.w  #1,d0                   * Delay
    619                 addq.w  #1,d0                   * ...
    620                 move.w  #$0000,$10(a0)          * Set CV3 to 0
    621                 addq.w  #1,d0                   * Delay
    622                 addq.w  #1,d0                   * ...
    623                 move.w  #$0000,$12(a0)          * Set SF3 to 0
    624                 addq.w  #1,d0                   * Delay
    625                 addq.w  #1,d0                   * ...
    626                 move.w  #$8300,$02(a0)          * Set new value '10' to -10.00
    627                 addq.w  #1,d0                   * Delay
    628                 addq.w  #1,d0                   * ...
    629                 move.w  #$8300,$1C(a0)          * Set new value '01' to -10.00
    630                 addq.w  #1,d0                   * Delay
    631                 addq.w  #1,d0                   * ...
    632                 move.w  #$0001,$16(a0)          * Set exponent for shortest time
    633                 addq.w  #1,d0                   * Delay
    634                 addq.w  #1,d0                   * ...
    635                 move.w  #$FFF0,$14(a0)          * Set mantissa for shortest time
    636                 addq.w  #1,d0                   * Delay
    637                 addq.w  #1,d0                   * ...
    638                 move.w  #$0005,$00(a0)          * Send control word to FPU
    639 *
    640                 .endc
    641 *
    642                 .page
    643 *
    644                 move.w  #INITIPL,sr             * Enable interrupts
    645                 lea     basepage,a1             * Pass start_ a pseudo base page
    646                 move.l  #_errno,p_bbase(a1)     * ...
    647                 clr.l   p_blen(a1)              * ...
    648                 move.l  a1,-(a7)                * ...
    649                 jsr     start_                  * Go start ROMP  (we assume ...)
    650 *
    651                 jmp     biosinit                * Just in case we return ...
    652 *
    653                 .page
    654 *
     582
     583                move.w  vsddit02,VSDDINIT       | Enable the video
     584
     585                move.l  #api_fum,api_fi         | Clear analog processor fifo
     586                move.l  #api_fum,api_fo         | ...
     587
     588                move.w  #23,d0                  | Setup to clear key LEDs
     589                move.b  #0x80,d1                | ...
     590
     591ledclear:       move.b  d1,LEDS                 | Clear a LED
     592                addq.b  #1,d1                   | Increment LED number
     593                dbra    d0,ledclear             | Loop until all are done
     594
     595                move.w  #7,d0                   | Setup to clear pot LEDs
     596                move.b  #0x18,d1                | ...
     597
     598ledclr2:        move.b  d1,LEDS                 | Clear a LED
     599                addq.b  #1,d1                   | Increment LED number
     600                dbra    d0,ledclr2              | Loop until all are done
     601
     602                clr.w   fc_sw                   | Stop the frame clock
     603                clr.l   fc_val                  | ... and reset it
     604
     605                .page
     606
     607                lea     FPUBASE+FPU_CTL,a0      | Point at FPU master level
     608                move.w  #0x0000,0x08(a0)        | Set CV1 to 0
     609                addq.w  #1,d0                   | Delay
     610                addq.w  #1,d0                   | ...
     611                move.w  #0x0000,0x0A(a0)        | Set SF1 to 0
     612                addq.w  #1,d0                   | Delay
     613                addq.w  #1,d0                   | ...
     614                move.w  #0x0000,0x0C(a0)        | Set CV2 to 0
     615                addq.w  #1,d0                   | Delay
     616                addq.w  #1,d0                   | ...
     617                move.w  #0x0000,0x0E(a0)        | Set SF2 to 0
     618                addq.w  #1,d0                   | Delay
     619                addq.w  #1,d0                   | ...
     620                move.w  #0x0000,0x10(a0)        | Set CV3 to 0
     621                addq.w  #1,d0                   | Delay
     622                addq.w  #1,d0                   | ...
     623                move.w  #0x0000,0x12(a0)        | Set SF3 to 0
     624                addq.w  #1,d0                   | Delay
     625                addq.w  #1,d0                   | ...
     626                move.w  #0x8300,0x02(a0)        | Set new value '10' to -10.00
     627                addq.w  #1,d0                   | Delay
     628                addq.w  #1,d0                   | ...
     629                move.w  #0x8300,0x1C(a0)        | Set new value '01' to -10.00
     630                addq.w  #1,d0                   | Delay
     631                addq.w  #1,d0                   | ...
     632                move.w  #0x0001,0x16(a0)        | Set exponent for shortest time
     633                addq.w  #1,d0                   | Delay
     634                addq.w  #1,d0                   | ...
     635                move.w  #0xFFF0,0x14(a0)        | Set mantissa for shortest time
     636                addq.w  #1,d0                   | Delay
     637                addq.w  #1,d0                   | ...
     638                move.w  #0x0005,0x00(a0)        | Send control word to FPU
     639
     640                .endc
     641
     642                .page
     643
     644                move.w  #INITIPL,sr             | Enable interrupts
     645                lea     basepage,a1             | Pass start_ a pseudo base page
     646                move.l  #_errno,p_bbase(a1)     | ...
     647                clr.l   p_blen(a1)              | ...
     648                move.l  a1,-(a7)                | ...
     649                jsr     start_                  | Go start ROMP  (we assume ...)
     650
     651                jmp     biosinit                | Just in case we return ...
     652
     653                .page
     654
    655655                .ifne   BUCHLA
    656 *
    657 * nullfpu -- Null FPU trap handler
    658 * -------    ---------------------
    659 nullfpu:        movem.l d0-d0/a0-a0,-(a7)       * Save registers
    660                 movea.l #FPUBASE,a0             * Setup FPU base address in a0
    661                 move.w  FPU_IN(a0),d0           * Read FPU interrupt port
    662                 andi.l  #$000000FF,d0           * Mask for voice & parameter
    663                 lsl.l   #5,d0                   * Shift for word offset
    664                 addi.l  #FPU_CTL,d0             * Add FPU control offset
    665                 move.w  #FPU_RST,0(a0,d0.L)     * Reset the function
    666                 clr.w   FPU_CLR(a0)             * Clear the interrupt
    667                 movem.l (a7)+,d0-d0/a0-a0       * Restore registers
    668                 rte                             * Return to interrupted code
    669 *
    670                 .endc
    671 *
    672                 .page
    673 *
    674 * hardhlt -- Bus error trap handler
    675 * -------    ----------------------
    676 hardhlt:        stop    #$2700                  * stop dead -- system is AFU
    677                 bra     hardhlt                 * ...
    678 *
    679 * badtrap -- Bad trap handler
    680 * -------    ----------------
    681 badtrap:        move.w  (a7)+,_crshsr           * Get crash SR
    682                 move.l  (a7)+,_crshpc           * Get crash PC
    683                 move.l  a7,_crshsp              * Get crash SP
    684                 bsr     badtr1                  * Get TRAP PC with vector number
     656
     657| nullfpu -- Null FPU trap handler
     658| -------    ---------------------
     659nullfpu:        movem.l d0-d0/a0-a0,-(a7)       | Save registers
     660                movea.l #FPUBASE,a0             | Setup FPU base address in a0
     661                move.w  FPU_IN(a0),d0           | Read FPU interrupt port
     662                andi.l  #0x000000FF,d0          | Mask for voice & parameter
     663                lsl.l   #5,d0                   | Shift for word offset
     664                addi.l  #FPU_CTL,d0             | Add FPU control offset
     665                move.w  #FPU_RST,0(a0,d0.L)     | Reset the function
     666                clr.w   FPU_CLR(a0)             | Clear the interrupt
     667                movem.l (a7)+,d0-d0/a0-a0       | Restore registers
     668                rte                             | Return to interrupted code
     669
     670                .endc
     671
     672                .page
     673
     674| hardhlt -- Bus error trap handler
     675| -------    ----------------------
     676hardhlt:        stop    #0x2700                 | stop dead -- system is AFU
     677                bra     hardhlt                 | ...
     678
     679| badtrap -- Bad trap handler
     680| -------    ----------------
     681badtrap:        move.w  (a7)+,_crshsr           | Get crash SR
     682                move.l  (a7)+,_crshpc           | Get crash PC
     683                move.l  a7,_crshsp              | Get crash SP
     684                bsr     badtr1                  | Get TRAP PC with vector number
    685685                nop
    686 *
    687 badtr1:         move.l  (a7)+,_crshvc           * Save for analysis of vector #
    688                 movem.l d0-d7/a0-a7,_crshrg     * Save crash registers
    689                 move.l  usp,a0                  * Preserve crash USP
    690                 move.l  a0,_crshus              * ...
    691                 move.l  a7,d0                   * Get SP
    692                 andi.l  #$FFFFFFFE,d0           * ... make sure it's even
    693                 movea.l d0,a1                   * ...
    694                 move.w  #15,d0                  * Save top 16 words
    695                 lea     _crshst,a0              * ... of crash stack in _crshst
    696 *
    697 badtr2:         move.w  (a1)+,(a0)+             * Save a stack value
    698                 dbf     d0,badtr2               * Loop until all are saved
    699 *
    700                 clr.l   d0                      * Get TRAP number
    701                 move.b  _crshvc,d0              * ... as LS byte of d0
    702                 move.l  _crshpc,a0              * Save crash PC in a0
    703                 move.w  #$FFFF,_wzcrsh          * Indicate we crashed
    704                 move.l  #rsarea,savptr          * Restore system save pointer
    705                 move.l  #SSTACK,a7              * Reset the stack pointer
    706                 move.l  #RSMAGIC,_rsflag        * ... and the stack sentinel
    707                 trap    #15                     * TRAP to ROMP
    708 *
    709                 jmp     biosinit                * Recover with a cold start
    710 *
    711                 .page
    712 *
     686
     687badtr1:         move.l  (a7)+,_crshvc           | Save for analysis of vector #
     688                movem.l d0-d7/a0-a7,_crshrg     | Save crash registers
     689                move.l  usp,a0                  | Preserve crash USP
     690                move.l  a0,_crshus              | ...
     691                move.l  a7,d0                   | Get SP
     692                andi.l  #0xFFFFFFFE,d0          | ... make sure it's even
     693                movea.l d0,a1                   | ...
     694                move.w  #15,d0                  | Save top 16 words
     695                lea     _crshst,a0              | ... of crash stack in _crshst
     696
     697badtr2:         move.w  (a1)+,(a0)+             | Save a stack value
     698                dbf     d0,badtr2               | Loop until all are saved
     699
     700                clr.l   d0                      | Get TRAP number
     701                move.b  _crshvc,d0              | ... as LS byte of d0
     702                move.l  _crshpc,a0              | Save crash PC in a0
     703                move.w  #0xFFFF,_wzcrsh         | Indicate we crashed
     704                move.l  #rsarea,savptr          | Restore system save pointer
     705                move.l  #SSTACK,a7              | Reset the stack pointer
     706                move.l  #RSMAGIC,_rsflag        | ... and the stack sentinel
     707                trap    #15                     | TRAP to ROMP
     708
     709                jmp     biosinit                | Recover with a cold start
     710
     711                .page
     712
    713713                .ifne   BUCHLA
    714 *
    715 * timeint -- Timer interrupt handler
    716 * -------    -----------------------
    717 timeint:        movem.l d0-d7/a0-a6,-(a7)       * Save registers
    718                 move.b  TIME_CR2,d0             * Get timer interrupt status
    719                 btst.l  #2,d0                   * Check timer 3 status
    720                 beq     tmi02                   * Jump if not active
    721 *
    722                 move.b  TIME_T3H,d1             * Read timer 1 count
    723                 lsl.l   #8,d1                   * ...
    724                 move.b  TIME_T3L,d1             * ...
    725                 move.w  d1,t3count              * ... and save it
    726 *
    727                 addq.l  #1,_hz_1k               * Update 1ms clock  (1 KHz)
    728 *
    729                 move.w  tdiv1,d1                * Update divider
    730                 addq.w  #1,d1                   * ...
    731                 move.w  d1,tdiv1                * ...
    732 *
    733                 cmpi.w  #5,d1                   * Do we need to update _hz_200 ?
    734                 blt     tmi02                   * Jump if not
    735 *
    736                 addq.l  #1,_hz_200              * Update 5ms clock   (200 Hz)
    737 *
    738                 move.w  tdiv2,d1                * Update divider
    739                 addq.w  #1,d1                   * ...
    740                 move.w  d1,tdiv2                * ...
    741 *
    742                 cmpi.w  #4,d1                   * Do we need to update frclock ?
    743                 blt     tmi01                   * Jump if not
    744 *
    745                 addq.l  #1,frclock              * Update 20 Ms clock  (50 Hz)
    746                 tst.w   flock                   * See if floppy is active
    747                 bne     tmi00                   * Don't call flopvbl if so
    748 *
    749                 bsr     flopvbl                 * Check on the floppy
    750 *
    751 tmi00:          move.w  #0,tdiv2                * Reset tdiv2
    752 *
    753 tmi01:          move.w  #0,tdiv1                * Reset tdiv1
    754 *
    755                 .page
    756 *
    757 tmi02:          btst.l  #0,d0                   * Check timer 1 int
    758                 beq     tmi03                   * Jump if not set
    759 *
    760                 move.b  TIME_T1H,d1             * Read timer 1 to clear int.
    761                 lsl.l   #8,d1                   * ...
    762                 move.b  TIME_T1L,d1             * ...
    763                 move.w  d1,t1count              * ... and save the count
    764 *
    765 tmi03:          btst.l  #1,d0                   * Check for timer 2 int.
    766                 beq     tmi04                   * Jump if not set
    767 *
    768                 move.b  TIME_T2H,d1             * Read timer 2 to clear int.
    769                 lsl.l   #8,d1                   * ...
    770                 move.b  TIME_T2L,d1             * ...
    771                 move.w  d1,t2count              * ... and save the count
    772 *
    773                 tst.w   fc_sw                   * Should we update the frame ?
    774                 beq     tmi04                   * Jump if not
    775 *
    776                 bmi     tmi05                   * Jump if we count down
    777 *
    778                 move.l  fc_val,d0               * Get the frame count
    779                 cmp.l   #FCMAX,d0               * See it we've topped out
    780                 bge     tmi06                   * Jump if limit was hit
    781 *
    782                 addq.l  #1,d0                   * Count up 1 frame
    783                 move.l  d0,fc_val               * Store updated frame count
    784                 bra     tmi04                   * Done
    785 *
    786 tmi06:          move.l  #FCMAX,fc_val           * Force hard limit, just in case
    787                 bra     tmi04                   * Done
    788 *
    789 tmi05:          move.l  fc_val,d0               * Get the frame count
    790                 beq     tmi04                   * Done if already zero
    791 *
    792                 subq.l  #1,d0                   * Count down 1 frame
    793                 move.l  d0,fc_val               * Store udpated frame count
    794 *
    795                 movea.l timevec,a0              * Do RTC vector
    796                 move.w  #1,-(a7)                * ... pass 1 msec on stack
    797                 jsr     (a0)                    * ...
    798                 addq.l  #4,a7                   * ...
    799 *
    800 tmi04:          movem.l (a7)+,d0-d7/a0-a6               * Restore registers
    801                 rte                             * Return to interrupted code
    802 *
    803                 .endc
    804 *
    805                 .page
    806 *
    807 * trap14 -- Extended BIOS entry point
    808 * ------    -------------------------
    809 trap14:         lea     t14tab,a0               * Setup trap 14 table address
    810                 bra     trapent                 * Go process trap
    811 *
    812 * trap13 -- Main BIOS entry point
    813 * ------    ---------------------
    814 trap13:         lea     t13tab,a0               * Setup trap 13 table address
    815 *
    816 trapent:        move.l  savptr,a1               * Get save area pointer
    817                 move.w  (a7)+,d0                * Status register to D0
    818                 move.w  d0,-(a1)                * Save in save area
    819                 move.l  (a7)+,-(a1)             * Stash PC in save area
    820                 movem.l d3-d7/a3-a7,-(a1)       * Save parameter register
    821                 move.l  a1,savptr               * Update save pointer
    822                 btst    #13,d0                  * Were we in sup. mode ?
    823                 bne     trwzsup                 * Jump if so
    824 *
    825                 move.l  usp,a7                  * Move user sp to stack ptr.
    826 *
    827 trwzsup:        move.w  (a7)+,d0                * Get function number from stack
    828                 cmp.w   (a0)+,d0                * Check against limit
    829                 bge     trpexit                 * Jump if it's invalid
    830 *
    831                 lsl.w   #2,d0                   * Multiply by 4 for use as index
    832                 move.l  0(a0,d0),d0             * Get routine address
    833                 move.l  d0,a0                   * ... into a0
    834                 bpl     trpnind                 * Jump if it's indirect
    835 *
    836                 move.l  (a0),a0                 * Use indirect value
    837 *
    838 trpnind:        sub.l   a5,a5                   * Clear a5
    839                 jsr     (a0)                    * Execute the routine
    840 *
    841 trpexit:        move.l  savptr,a1               * Get SAVPTR into a1
    842                 movem.l (a1)+,d3-d7/a3-a7       * Restore registers
    843                 move.l  (a1)+,-(a7)             * Push return onto stack
    844                 move.w  (a1)+,-(a7)             * Push status onto stack
    845                 move.l  a1,savptr               * Update SAVPTR
    846 *
    847 * nullrte -- null rte
    848 * -------    --------
    849 nullrte:        rte                             * Return to interrupted code
    850 *
    851 * nullrts -- null return
    852 * -------    -----------
    853 nullrts:        rts                             * Just return to the caller
    854 *
    855                 .page
    856 *
    857 * bconstat -- Get character device input status
    858 * --------    ---------------------------------
    859 bconstat:       lea     cdt01,a0                * Point at status table
    860                 bra     condisp                 * Jump to dispatcher
    861 *
    862 * bconin -- Get input from character device
    863 * ------    -------------------------------
    864 bconin:         lea     cdt02,a0                * Point at input table
    865                 bra     condisp                 * Jump to dispatcher
    866 *
    867 * bconout -- Output to character device
    868 * -------    --------------------------
    869 bconout:        lea     cdt03,a0                * Point at output table
    870                 bra     condisp                 * Jump to dispatcher
    871 *
    872 * bcostat -- Get character device output status
    873 * -------    ----------------------------------
    874 bcostat:        lea     cdt04,a0                * Point at status table
    875 *
    876 * condisp -- Character device function dispatcher
    877 * -------    ------------------------------------
    878 condisp:        move.w  4(a7),d0                * Get device number
    879                 lsl.w   #2,d0                   * ... times 4 for pointer
    880                 move.l  0(a0,d0),a0             * Get routine address
    881                 jmp     (a0)                    * Jump to it
    882 *
    883                 .page
    884 *
    885 * sr1ist -- Check CON (Serial-1) input buffer status
    886 * ------    ----------------------------------------
    887 sr1ist:         lea     sr1iorec,a0             * Address of iorec to a0
    888                 lea     SR1ACIA,a1              * Address of ACIA to a1
    889                 bra     chkist                  * Go check buffer status
    890 *
    891 * sr2ist -- Check AUX (Serial-2) input buffer status
    892 * ------    ----------------------------------------
    893 sr2ist:         lea     sr2iorec,a0             * Address of iorec to a0
    894                 lea     SR2ACIA,a1              * Address of ACIA to a1
    895 *
     714
     715| timeint -- Timer interrupt handler
     716| -------    -----------------------
     717timeint:        movem.l d0-d7/a0-a6,-(a7)       | Save registers
     718                move.b  TIME_CR2,d0             | Get timer interrupt status
     719                btst.l  #2,d0                   | Check timer 3 status
     720                beq     tmi02                   | Jump if not active
     721
     722                move.b  TIME_T3H,d1             | Read timer 1 count
     723                lsl.l   #8,d1                   | ...
     724                move.b  TIME_T3L,d1             | ...
     725                move.w  d1,t3count              | ... and save it
     726
     727                addq.l  #1,_hz_1k               | Update 1ms clock  (1 KHz)
     728
     729                move.w  tdiv1,d1                | Update divider
     730                addq.w  #1,d1                   | ...
     731                move.w  d1,tdiv1                | ...
     732
     733                cmpi.w  #5,d1                   | Do we need to update _hz_200 ?
     734                blt     tmi02                   | Jump if not
     735
     736                addq.l  #1,_hz_200              | Update 5ms clock   (200 Hz)
     737
     738                move.w  tdiv2,d1                | Update divider
     739                addq.w  #1,d1                   | ...
     740                move.w  d1,tdiv2                | ...
     741
     742                cmpi.w  #4,d1                   | Do we need to update frclock ?
     743                blt     tmi01                   | Jump if not
     744
     745                addq.l  #1,frclock              | Update 20 Ms clock  (50 Hz)
     746                tst.w   flock                   | See if floppy is active
     747                bne     tmi00                   | Don't call flopvbl if so
     748
     749                bsr     flopvbl                 | Check on the floppy
     750
     751tmi00:          move.w  #0,tdiv2                | Reset tdiv2
     752
     753tmi01:          move.w  #0,tdiv1                | Reset tdiv1
     754
     755                .page
     756
     757tmi02:          btst.l  #0,d0                   | Check timer 1 int
     758                beq     tmi03                   | Jump if not set
     759
     760                move.b  TIME_T1H,d1             | Read timer 1 to clear int.
     761                lsl.l   #8,d1                   | ...
     762                move.b  TIME_T1L,d1             | ...
     763                move.w  d1,t1count              | ... and save the count
     764
     765tmi03:          btst.l  #1,d0                   | Check for timer 2 int.
     766                beq     tmi04                   | Jump if not set
     767
     768                move.b  TIME_T2H,d1             | Read timer 2 to clear int.
     769                lsl.l   #8,d1                   | ...
     770                move.b  TIME_T2L,d1             | ...
     771                move.w  d1,t2count              | ... and save the count
     772
     773                tst.w   fc_sw                   | Should we update the frame ?
     774                beq     tmi04                   | Jump if not
     775
     776                bmi     tmi05                   | Jump if we count down
     777
     778                move.l  fc_val,d0               | Get the frame count
     779                cmp.l   #FCMAX,d0               | See it we've topped out
     780                bge     tmi06                   | Jump if limit was hit
     781
     782                addq.l  #1,d0                   | Count up 1 frame
     783                move.l  d0,fc_val               | Store updated frame count
     784                bra     tmi04                   | Done
     785
     786tmi06:          move.l  #FCMAX,fc_val           | Force hard limit, just in case
     787                bra     tmi04                   | Done
     788
     789tmi05:          move.l  fc_val,d0               | Get the frame count
     790                beq     tmi04                   | Done if already zero
     791
     792                subq.l  #1,d0                   | Count down 1 frame
     793                move.l  d0,fc_val               | Store udpated frame count
     794
     795                movea.l timevec,a0              | Do RTC vector
     796                move.w  #1,-(a7)                | ... pass 1 msec on stack
     797                jsr     (a0)                    | ...
     798                addq.l  #4,a7                   | ...
     799
     800tmi04:          movem.l (a7)+,d0-d7/a0-a6               | Restore registers
     801                rte                             | Return to interrupted code
     802
     803                .endc
     804
     805                .page
     806
     807| trap14 -- Extended BIOS entry point
     808| ------    -------------------------
     809trap14:         lea     t14tab,a0               | Setup trap 14 table address
     810                bra     trapent                 | Go process trap
     811
     812| trap13 -- Main BIOS entry point
     813| ------    ---------------------
     814trap13:         lea     t13tab,a0               | Setup trap 13 table address
     815
     816trapent:        move.l  savptr,a1               | Get save area pointer
     817                move.w  (a7)+,d0                | Status register to D0
     818                move.w  d0,-(a1)                | Save in save area
     819                move.l  (a7)+,-(a1)             | Stash PC in save area
     820                movem.l d3-d7/a3-a7,-(a1)       | Save parameter register
     821                move.l  a1,savptr               | Update save pointer
     822                btst    #13,d0                  | Were we in sup. mode ?
     823                bne     trwzsup                 | Jump if so
     824
     825                move.l  usp,a7                  | Move user sp to stack ptr.
     826
     827trwzsup:        move.w  (a7)+,d0                | Get function number from stack
     828                cmp.w   (a0)+,d0                | Check against limit
     829                bge     trpexit                 | Jump if it's invalid
     830
     831                lsl.w   #2,d0                   | Multiply by 4 for use as index
     832                move.l  0(a0,d0),d0             | Get routine address
     833                move.l  d0,a0                   | ... into a0
     834                bpl     trpnind                 | Jump if it's indirect
     835
     836                move.l  (a0),a0                 | Use indirect value
     837
     838trpnind:        sub.l   a5,a5                   | Clear a5
     839                jsr     (a0)                    | Execute the routine
     840
     841trpexit:        move.l  savptr,a1               | Get SAVPTR into a1
     842                movem.l (a1)+,d3-d7/a3-a7       | Restore registers
     843                move.l  (a1)+,-(a7)             | Push return onto stack
     844                move.w  (a1)+,-(a7)             | Push status onto stack
     845                move.l  a1,savptr               | Update SAVPTR
     846
     847| nullrte -- null rte
     848| -------    --------
     849nullrte:        rte                             | Return to interrupted code
     850
     851| nullrts -- null return
     852| -------    -----------
     853nullrts:        rts                             | Just return to the caller
     854
     855                .page
     856
     857| bconstat -- Get character device input status
     858| --------    ---------------------------------
     859bconstat:       lea     cdt01,a0                | Point at status table
     860                bra     condisp                 | Jump to dispatcher
     861
     862| bconin -- Get input from character device
     863| ------    -------------------------------
     864bconin:         lea     cdt02,a0                | Point at input table
     865                bra     condisp                 | Jump to dispatcher
     866
     867| bconout -- Output to character device
     868| -------    --------------------------
     869bconout:        lea     cdt03,a0                | Point at output table
     870                bra     condisp                 | Jump to dispatcher
     871
     872| bcostat -- Get character device output status
     873| -------    ----------------------------------
     874bcostat:        lea     cdt04,a0                | Point at status table
     875
     876| condisp -- Character device function dispatcher
     877| -------    ------------------------------------
     878condisp:        move.w  4(a7),d0                | Get device number
     879                lsl.w   #2,d0                   | ... times 4 for pointer
     880                move.l  0(a0,d0),a0             | Get routine address
     881                jmp     (a0)                    | Jump to it
     882
     883                .page
     884
     885| sr1ist -- Check CON (Serial-1) input buffer status
     886| ------    ----------------------------------------
     887sr1ist:         lea     sr1iorec,a0             | Address of iorec to a0
     888                lea     SR1ACIA,a1              | Address of ACIA to a1
     889                bra     chkist                  | Go check buffer status
     890
     891| sr2ist -- Check AUX (Serial-2) input buffer status
     892| ------    ----------------------------------------
     893sr2ist:         lea     sr2iorec,a0             | Address of iorec to a0
     894                lea     SR2ACIA,a1              | Address of ACIA to a1
     895
    896896                .ifne   BUCHLA
    897 *
    898                 bra     chkist                  * Go check buffer status
    899 *
    900 * mc1ist -- Check MC1 (MIDI-1) input buffer status
    901 * ------    --------------------------------------
    902 mc1ist:         lea     mc1iorec,a0             * Address of iorec to a0
    903                 lea     MC1ACIA,a1              * Address of ACIA to a1
    904                 bra     chkist                  * Go check buffer status
    905 *
    906 * mc2ist -- Check MC2 (MIDI-2) input buffer status
    907 * ------    --------------------------------------
    908 mc2ist:         lea     mc2iorec,a0             * Address of iorec to a0
    909                 lea     MC2ACIA,a1              * Address of ACIA to a1
    910 *
    911                 .endc
    912 *
    913 * chkist -- Check input buffer status
    914 * ------    -------------------------
    915 chkist:         moveq.l #-1,d0                  * Default to "Input available"
    916                 lea     ibufhd(a0),a2           * Head index to a2
    917                 lea     ibuftl(a0),a3           * Tail index to a3
    918                 cmpm.w  (a3)+,(a2)+             * Buffer clear ?
    919                 bne     chkist1                 * Jump if not
    920 *
    921                 moveq.l #0,d0                   * Set to "Buffer empty"
    922 *
    923 chkist1:        rts                             * Return to caller
    924 *
    925                 .page
    926 *
    927 * sr1ost -- Check CON (Serial-1) output buffer status
    928 * ------    -----------------------------------------
    929 sr1ost:         lea     sr1iorec,a0             * Address of iorec to a0
    930                 bra     chkost                  * Go check buffer status
    931 *
    932 * sr2ost -- Check AUX (Serial-2) output buffer status
    933 * ------    -----------------------------------------
    934 sr2ost:         lea     sr2iorec,a0             * Address of iorec to a0
    935 *
     897
     898                bra     chkist                  | Go check buffer status
     899
     900| mc1ist -- Check MC1 (MIDI-1) input buffer status
     901| ------    --------------------------------------
     902mc1ist:         lea     mc1iorec,a0             | Address of iorec to a0
     903                lea     MC1ACIA,a1              | Address of ACIA to a1
     904                bra     chkist                  | Go check buffer status
     905
     906| mc2ist -- Check MC2 (MIDI-2) input buffer status
     907| ------    --------------------------------------
     908mc2ist:         lea     mc2iorec,a0             | Address of iorec to a0
     909                lea     MC2ACIA,a1              | Address of ACIA to a1
     910
     911                .endc
     912
     913| chkist -- Check input buffer status
     914| ------    -------------------------
     915chkist:         moveq.l #-1,d0                  | Default to "Input available"
     916                lea     ibufhd(a0),a2           | Head index to a2
     917                lea     ibuftl(a0),a3           | Tail index to a3
     918                cmpm.w  (a3)+,(a2)+             | Buffer clear ?
     919                bne     chkist1                 | Jump if not
     920
     921                moveq.l #0,d0                   | Set to "Buffer empty"
     922
     923chkist1:        rts                             | Return to caller
     924
     925                .page
     926
     927| sr1ost -- Check CON (Serial-1) output buffer status
     928| ------    -----------------------------------------
     929sr1ost:         lea     sr1iorec,a0             | Address of iorec to a0
     930                bra     chkost                  | Go check buffer status
     931
     932| sr2ost -- Check AUX (Serial-2) output buffer status
     933| ------    -----------------------------------------
     934sr2ost:         lea     sr2iorec,a0             | Address of iorec to a0
     935
    936936                .ifne   BUCHLA
    937 *
    938                 bra     chkost                  * Go check buffer status
    939 *
    940 * mc1ost -- Check MC1 (MIDI-1) output buffer status
    941 * ------    ---------------------------------------
    942 mc1ost:         lea     mc1iorec,a0             * Address of iorec to a0
    943                 bra     chkost                  * Go check buffer status
    944 *
    945 * mc2ost -- Check MC2 (MIDI-2) output buffer status
    946 * ------    ---------------------------------------
    947 mc2ost:         lea     mc2iorec,a0             * Address of iorec to a0
    948 *
    949                 .endc
    950 *
    951 * chkost -- Check output buffer status
    952 * ------    --------------------------
    953 chkost:         moveq.l #-1,d0                  * Default to "Output OK"
    954                 move.w  obuftl(a0),d2           * Tail index to d2
    955                 bsr     wrapout                 * Test for pointer wraparound
    956                 cmp.w   obufhd(a0),d2           * Compare with head index
    957                 bne     chkost1                 * Jump if not equal
    958 *
    959                 moveq.l #0,d0                   * Set to "Buffer full"
    960 *
    961 chkost1:        rts                             * Return to caller
    962 *
    963                 .page
    964 *
    965 * wrapin -- Check input pointer for wraparound
    966 * ------    ----------------------------------
    967 wrapin:         add.w   #1,d1                   * Head index +1
    968                 cmp.w   ibufsize(a0),d1         * = buffer size ?
    969                 bcs     wrapin1                 * Jump if not
    970 *
    971                 moveq.l #0,d1                   * Wraparound
    972 *
    973 wrapin1:        rts                             * Return to caller
    974 *
    975 * wrapout -- Check output pointer for wraparound
    976 * -------    -----------------------------------
    977 wrapout:        addq.w  #1,d2                   * Tail index +1
    978                 cmp.w   obufsize(a0),d2         * = buffer size ?
    979                 bcs     wrapout1                * Jump if not
    980 *
    981                 moveq.l #0,d2                   * Wrap around if so
    982 *
    983 wrapout1:       rts                             * Return to caller
    984 *
    985                 .page
    986 *
    987 * sr1inp -- Get input from Serial-1  (wait on busy)
    988 * ------    ---------------------------------------
    989 sr1inp:         lea     sr1iorec,a0             * Serial-1 iorec address
    990                 lea     SR1ACIA,a1              * Serial-1 ACIA base
    991                 bra     serinp                  * Go get a byte
    992 *
    993 * sr2inp -- Get input from Serial-2  (wait on busy)
    994 * ------    ---------------------------------------
    995 sr2inp:         lea     sr2iorec,a0             * Serial-2 iorec address
    996                 lea     SR2ACIA,a1              * Serial-2 ACIA base
    997 *
    998 * serinp -- Get a byte from a serial port  (with handshaking)
    999 * ------    -------------------------------------------------
    1000 serinp:         bsr     chkist                  * Check input status
    1001                 tst.w   d0                      * Character ready ?
    1002                 beq     serinp                  * Loop until one is ...
    1003 *
    1004                 bsr     getser                  * Get a byte from the buffer
    1005                 and.w   #$FFFF,d0               * Isolate LS bits 7..0
    1006                 rts                             * Return to caller
    1007 *
    1008                 .page
    1009 *
     937
     938                bra     chkost                  | Go check buffer status
     939
     940| mc1ost -- Check MC1 (MIDI-1) output buffer status
     941| ------    ---------------------------------------
     942mc1ost:         lea     mc1iorec,a0             | Address of iorec to a0
     943                bra     chkost                  | Go check buffer status
     944
     945| mc2ost -- Check MC2 (MIDI-2) output buffer status
     946| ------    ---------------------------------------
     947mc2ost:         lea     mc2iorec,a0             | Address of iorec to a0
     948
     949                .endc
     950
     951| chkost -- Check output buffer status
     952| ------    --------------------------
     953chkost:         moveq.l #-1,d0                  | Default to "Output OK"
     954                move.w  obuftl(a0),d2           | Tail index to d2
     955                bsr     wrapout                 | Test for pointer wraparound
     956                cmp.w   obufhd(a0),d2           | Compare with head index
     957                bne     chkost1                 | Jump if not equal
     958
     959                moveq.l #0,d0                   | Set to "Buffer full"
     960
     961chkost1:        rts                             | Return to caller
     962
     963                .page
     964
     965| wrapin -- Check input pointer for wraparound
     966| ------    ----------------------------------
     967wrapin:         add.w   #1,d1                   | Head index +1
     968                cmp.w   ibufsize(a0),d1         | = buffer size ?
     969                bcs     wrapin1                 | Jump if not
     970
     971                moveq.l #0,d1                   | Wraparound
     972
     973wrapin1:        rts                             | Return to caller
     974
     975| wrapout -- Check output pointer for wraparound
     976| -------    -----------------------------------
     977wrapout:        addq.w  #1,d2                   | Tail index +1
     978                cmp.w   obufsize(a0),d2         | = buffer size ?
     979                bcs     wrapout1                | Jump if not
     980
     981                moveq.l #0,d2                   | Wrap around if so
     982
     983wrapout1:       rts                             | Return to caller
     984
     985                .page
     986
     987| sr1inp -- Get input from Serial-1  (wait on busy)
     988| ------    ---------------------------------------
     989sr1inp:         lea     sr1iorec,a0             | Serial-1 iorec address
     990                lea     SR1ACIA,a1              | Serial-1 ACIA base
     991                bra     serinp                  | Go get a byte
     992
     993| sr2inp -- Get input from Serial-2  (wait on busy)
     994| ------    ---------------------------------------
     995sr2inp:         lea     sr2iorec,a0             | Serial-2 iorec address
     996                lea     SR2ACIA,a1              | Serial-2 ACIA base
     997
     998| serinp -- Get a byte from a serial port  (with handshaking)
     999| ------    -------------------------------------------------
     1000serinp:         bsr     chkist                  | Check input status
     1001                tst.w   d0                      | Character ready ?
     1002                beq     serinp                  | Loop until one is ...
     1003
     1004                bsr     getser                  | Get a byte from the buffer
     1005                and.w   #0xFFFF,d0              | Isolate LS bits 7..0
     1006                rts                             | Return to caller
     1007
     1008                .page
     1009
    10101010                .ifne   BUCHLA
    1011 *
    1012 * mc1inp -- Get input from MIDI-1  (wait on busy)
    1013 * ------    -------------------------------------
    1014 mc1inp:         lea     mc1iorec,a0             * MIDI-1 iorec address
    1015                 lea     MC1ACIA,a1              * MIDI-1 ACIA base
    1016                 bra     midinp                  * Go get a byte
    1017 *
    1018 * mc2inp -- Get input from MIDI-2  (wait on busy)
    1019 * ------    -------------------------------------
    1020 mc2inp:         lea     mc2iorec,a0             * MIDI-2 iorec address
    1021                 lea     MC2ACIA,a1              * MIDI-2 ACIA base
    1022 *
    1023 * midinp -- Get input from a MIDI port  (no handshaking)
    1024 * ------    --------------------------------------------
    1025 midinp:         bsr     chkist                  * Check input status
    1026                 tst.w   d0                      * Character ready ?
    1027                 beq     midinp                  * Loop until one is ...
    1028 *
    1029                 move.w  sr,-(a7)                * Save status register
    1030                 ori.w   #IPL7,sr                * Set IPL = 7  (disable ints)
    1031                 move.w  ibufhd(a0),d1           * Head index to d1
    1032                 cmp.w   ibuftl(a0),d1           * Compare to tail index
    1033                 beq     midin_1                 * Jump if (somehow) empty
    1034 *
    1035                 addq.w  #1,d1                   * Increment head index
    1036                 cmp.w   ibufsize(a0),d1         * Did pointer wrap around ?
    1037                 bcs     midin_2                 * Jump if not
    1038 *
    1039                 moveq.l #0,d1                   * Wraparound
    1040 *
    1041 midin_2:        move.l  ibuf(a0),a2             * Get buffer base address in a2
    1042                 moveq.l #0,d0                   * Clear MS bits of d0
    1043                 move.b  0(a2,d1),d0             * Get character from buffer
    1044                 move.w  d1,ibufhd(a0)           * Update buffer head index
    1045 *
    1046 midin_1:        move.w  (a7)+,sr                * Restore status
    1047                 rts                             * Return to caller
    1048 *
    1049                 .endc
    1050 *
    1051                 .page
    1052 *
    1053 * getser -- Get a byte from a serial port buffer  (with handshaking)
    1054 * ------    --------------------------------------------------------
    1055 getser:         move.w  sr,-(a7)                * Save status register
    1056                 ori.w   #IPL7,sr                * Set IPL = 7  (disable ints)
    1057                 move.w  ibufhd(a0),d1           * Get input buffer head index
    1058                 cmp.w   ibuftl(a0),d1           * Compare tail index
    1059                 beq     rs_mt                   * Jump if buffer empty
    1060 *
    1061                 bsr     wrapin                  * Adjust pointer for wraparound
    1062                 move.l  ibuf(a0),a2             * Get buffer address
    1063                 moveq.l #0,d0                   * Clear out MS bits of d0
    1064                 move.b  0(a2,d1),d0             * Get character from buffer
    1065                 move.w  d1,ibufhd(a0)           * Update head index
    1066                 move.w  (a7)+,sr                * Restore status
    1067                 andi    #$FFFE,sr               * Clear carry = OK
    1068                 bra     rs_xnf                  * Go do XON/XOFF check
    1069 *
    1070 rs_mt:          move.w  (a7)+,sr                * Restore status
    1071                 ori     #$0001,sr               * Set carry = no character there
    1072 *
    1073 rs_xnf:         btst    #0,linedisc(a0)         * Check for XON/XOFF mode
    1074                 beq     rs_exit                 * Jump if not enabled
    1075 *
    1076                 tst.b   flagxon(a0)             * XON active ?
    1077                 beq     rs_exit                 * Jump if not
    1078 *
    1079                 bsr     rsilen                  * Get length of buffer used
    1080                 cmp.w   ibuflow(a0),d2          * At low water mark ?
    1081                 bne     rs_exit                 * Jump if not
    1082 *
    1083                 move.b  #$11,d1                 * Send an XON
    1084                 bsr     serput                  * ...
    1085                 clr.b   flagxon(a0)             * Clear XON flag
    1086 *
    1087 rs_exit:        rts                             * Return to caller
    1088 *
    1089                 .page
    1090 *
    1091 * sr1out -- Output to serial-1
    1092 * ------    ------------------
    1093 sr1out:         lea     sr1iorec,a0             * Serial-1 iorec address to a0
    1094                 lea     SR1ACIA,a1              * Serial-1 ACIA address to a1
    1095                 move.w  6(a7),d1                * Get data byte from stack
    1096                 bsr     serput                  * Attempt to output
    1097                 bcs     sr1out                  * Try until it works ...
    1098 *
    1099                 rts                             * Return to caller
    1100 *
    1101 * sr2out -- Output to Serial-2
    1102 * ------    ------------------
    1103 sr2out:         lea     sr2iorec,a0             * Serial-2 iorec address to a0
    1104                 lea     SR2ACIA,a1              * Serial-2 ACIA address to a1
    1105                 move.w  6(a7),d1                * Get data byte from stack
    1106                 bsr     serput                  * Attempt to output
    1107                 bcs     sr2out                  * Try until it works ...
    1108 *
    1109                 rts                             * Return to caller
    1110 *
     1011
     1012| mc1inp -- Get input from MIDI-1  (wait on busy)
     1013| ------    -------------------------------------
     1014mc1inp:         lea     mc1iorec,a0             | MIDI-1 iorec address
     1015                lea     MC1ACIA,a1              | MIDI-1 ACIA base
     1016                bra     midinp                  | Go get a byte
     1017
     1018| mc2inp -- Get input from MIDI-2  (wait on busy)
     1019| ------    -------------------------------------
     1020mc2inp:         lea     mc2iorec,a0             | MIDI-2 iorec address
     1021                lea     MC2ACIA,a1              | MIDI-2 ACIA base
     1022
     1023| midinp -- Get input from a MIDI port  (no handshaking)
     1024| ------    --------------------------------------------
     1025midinp:         bsr     chkist                  | Check input status
     1026                tst.w   d0                      | Character ready ?
     1027                beq     midinp                  | Loop until one is ...
     1028
     1029                move.w  sr,-(a7)                | Save status register
     1030                ori.w   #IPL7,sr                | Set IPL = 7  (disable ints)
     1031                move.w  ibufhd(a0),d1           | Head index to d1
     1032                cmp.w   ibuftl(a0),d1           | Compare to tail index
     1033                beq     midin_1                 | Jump if (somehow) empty
     1034
     1035                addq.w  #1,d1                   | Increment head index
     1036                cmp.w   ibufsize(a0),d1         | Did pointer wrap around ?
     1037                bcs     midin_2                 | Jump if not
     1038
     1039                moveq.l #0,d1                   | Wraparound
     1040
     1041midin_2:        move.l  ibuf(a0),a2             | Get buffer base address in a2
     1042                moveq.l #0,d0                   | Clear MS bits of d0
     1043                move.b  0(a2,d1),d0             | Get character from buffer
     1044                move.w  d1,ibufhd(a0)           | Update buffer head index
     1045
     1046midin_1:        move.w  (a7)+,sr                | Restore status
     1047                rts                             | Return to caller
     1048
     1049                .endc
     1050
     1051                .page
     1052
     1053| getser -- Get a byte from a serial port buffer  (with handshaking)
     1054| ------    --------------------------------------------------------
     1055getser:         move.w  sr,-(a7)                | Save status register
     1056                ori.w   #IPL7,sr                | Set IPL = 7  (disable ints)
     1057                move.w  ibufhd(a0),d1           | Get input buffer head index
     1058                cmp.w   ibuftl(a0),d1           | Compare tail index
     1059                beq     rs_mt                   | Jump if buffer empty
     1060
     1061                bsr     wrapin                  | Adjust pointer for wraparound
     1062                move.l  ibuf(a0),a2             | Get buffer address
     1063                moveq.l #0,d0                   | Clear out MS bits of d0
     1064                move.b  0(a2,d1),d0             | Get character from buffer
     1065                move.w  d1,ibufhd(a0)           | Update head index
     1066                move.w  (a7)+,sr                | Restore status
     1067                andi    #0xFFFE,sr              | Clear carry = OK
     1068                bra     rs_xnf                  | Go do XON/XOFF check
     1069
     1070rs_mt:          move.w  (a7)+,sr                | Restore status
     1071                ori     #0x0001,sr              | Set carry = no character there
     1072
     1073rs_xnf:         btst    #0,linedisc(a0)         | Check for XON/XOFF mode
     1074                beq     rs_exit                 | Jump if not enabled
     1075
     1076                tst.b   flagxon(a0)             | XON active ?
     1077                beq     rs_exit                 | Jump if not
     1078
     1079                bsr     rsilen                  | Get length of buffer used
     1080                cmp.w   ibuflow(a0),d2          | At low water mark ?
     1081                bne     rs_exit                 | Jump if not
     1082
     1083                move.b  #0x11,d1                | Send an XON
     1084                bsr     serput                  | ...
     1085                clr.b   flagxon(a0)             | Clear XON flag
     1086
     1087rs_exit:        rts                             | Return to caller
     1088
     1089                .page
     1090
     1091| sr1out -- Output to serial-1
     1092| ------    ------------------
     1093sr1out:         lea     sr1iorec,a0             | Serial-1 iorec address to a0
     1094                lea     SR1ACIA,a1              | Serial-1 ACIA address to a1
     1095                move.w  6(a7),d1                | Get data byte from stack
     1096                bsr     serput                  | Attempt to output
     1097                bcs     sr1out                  | Try until it works ...
     1098
     1099                rts                             | Return to caller
     1100
     1101| sr2out -- Output to Serial-2
     1102| ------    ------------------
     1103sr2out:         lea     sr2iorec,a0             | Serial-2 iorec address to a0
     1104                lea     SR2ACIA,a1              | Serial-2 ACIA address to a1
     1105                move.w  6(a7),d1                | Get data byte from stack
     1106                bsr     serput                  | Attempt to output
     1107                bcs     sr2out                  | Try until it works ...
     1108
     1109                rts                             | Return to caller
     1110
    11111111                .ifne   BUCHLA
    1112 *
    1113 * mc1out -- Output to MIDI-1
    1114 * ------    ----------------
    1115 mc1out:         lea     mc1iorec,a0             * MIDI-1 iorec address to a0
    1116                 lea     MC1ACIA,a1              * MIDI-1 ACIA address to a1
    1117                 move.w  6(a7),d1                * Get data byte from stack
    1118                 bsr     midput                  * Attempt to output
    1119                 bcs     mc1out                  * Try until it works ...
    1120 *
    1121                 rts                             * Return to caller
    1122 *
    1123 * mc2out -- Output to MIDI-2
    1124 * ------    ----------------
    1125 mc2out:         lea     mc2iorec,a0             * MIDI-2 iorec address to a0
    1126                 lea     MC2ACIA,a1              * MIDI-2 ACIA address to a1
    1127                 move.w  6(a7),d1                * Get data byte from stack
    1128                 bsr     midput                  * Attempt to output
    1129                 bcs     mc2out                  * Try until it works ...
    1130 *
    1131                 rts                             * Return to caller
    1132 *
    1133                 .endc
    1134 *
    1135                 .page
    1136 *
    1137 * serput -- Output a character to a serial port
    1138 * ------    -----------------------------------
    1139 serput:         move.w  sr,-(a7)                * Save status register
    1140                 ori.w   #IPL7,sr                * Set IPL = 7  (disable ints)
    1141                 move.b  ACIA_ISR(a1),isr(a0)    * Get ACIA isr
    1142                 move.b  ACIA_CSR(a1),csr(a0)    * Get ACIA csr
    1143                 btst    #0,linedisc(a0)         * XON/XOFF mode ?
    1144                 beq     serpt_1                 * Jump if not
    1145 *
    1146                 tst.b   flagxoff(a0)            * XON active ?
    1147                 bne     serpt_2                 * Jump if so
    1148 *
    1149 serpt_1:        btst.b  #6,isr(a0)              * Is ACIA still sending ?
    1150                 beq     serpt_2                 * Jump if so
    1151 *
    1152                 move.w  obufhd(a0),d2           * Head index to d2
    1153                 cmp.w   obuftl(a0),d2           * Compare to tail index
    1154                 bne     serpt_2                 * Jump if buffer not empty
    1155 *
    1156                 move.b  d1,ACIA_TDR(a1)         * Give byte to ACIA to send
    1157                 bra     serpt_3                 * Go deal with RTS/CTS if needed
    1158 *
    1159 serpt_2:        move.w  obuftl(a0),d2           * Tail index to d2
    1160                 bsr     wrapout                 * Adjust for wraparound
    1161                 cmp.w   obufhd(a0),d2           * Compare to head index
    1162                 beq     serpt_4                 * Jump if buffer full
    1163 *
    1164                 move.l  obuf(a0),a2             * Get buffer base address in a2
    1165                 move.b  d1,0(a2,d2)             * Put character in buffer
    1166                 move.w  d2,obuftl(a0)           * Update buffer tail index
    1167 *
    1168 serpt_3:        bsr     serchk                  * Check status on our way out
    1169                 bsr     rtschk                  * Handle RTS protocol
    1170                 move.w  (a7)+,sr                * Restore status register
    1171                 andi    #$FFFE,sr               * Clear carry flag = OK
    1172                 rts                             * Return to caller
    1173 *
    1174 serpt_4:        bsr     serchk                  * Check status on our way out
    1175                 bsr     rtschk                  * Handle RTS protocol
    1176                 move.w  (a7)+,sr                * Restore status register
    1177                 ori     #$0001,sr               * Set carry flag = buffer full
    1178                 rts                             * Return to caller
    1179 *
    1180                 .page
    1181 *
     1112
     1113| mc1out -- Output to MIDI-1
     1114| ------    ----------------
     1115mc1out:         lea     mc1iorec,a0             | MIDI-1 iorec address to a0
     1116                lea     MC1ACIA,a1              | MIDI-1 ACIA address to a1
     1117                move.w  6(a7),d1                | Get data byte from stack
     1118                bsr     midput                  | Attempt to output
     1119                bcs     mc1out                  | Try until it works ...
     1120
     1121                rts                             | Return to caller
     1122
     1123| mc2out -- Output to MIDI-2
     1124| ------    ----------------
     1125mc2out:         lea     mc2iorec,a0             | MIDI-2 iorec address to a0
     1126                lea     MC2ACIA,a1              | MIDI-2 ACIA address to a1
     1127                move.w  6(a7),d1                | Get data byte from stack
     1128                bsr     midput                  | Attempt to output
     1129                bcs     mc2out                  | Try until it works ...
     1130
     1131                rts                             | Return to caller
     1132
     1133                .endc
     1134
     1135                .page
     1136
     1137| serput -- Output a character to a serial port
     1138| ------    -----------------------------------
     1139serput:         move.w  sr,-(a7)                | Save status register
     1140                ori.w   #IPL7,sr                | Set IPL = 7  (disable ints)
     1141                move.b  ACIA_ISR(a1),isr(a0)    | Get ACIA isr
     1142                move.b  ACIA_CSR(a1),csr(a0)    | Get ACIA csr
     1143                btst    #0,linedisc(a0)         | XON/XOFF mode ?
     1144                beq     serpt_1                 | Jump if not
     1145
     1146                tst.b   flagxoff(a0)            | XON active ?
     1147                bne     serpt_2                 | Jump if so
     1148
     1149serpt_1:        btst.b  #6,isr(a0)              | Is ACIA still sending ?
     1150                beq     serpt_2                 | Jump if so
     1151
     1152                move.w  obufhd(a0),d2           | Head index to d2
     1153                cmp.w   obuftl(a0),d2           | Compare to tail index
     1154                bne     serpt_2                 | Jump if buffer not empty
     1155
     1156                move.b  d1,ACIA_TDR(a1)         | Give byte to ACIA to send
     1157                bra     serpt_3                 | Go deal with RTS/CTS if needed
     1158
     1159serpt_2:        move.w  obuftl(a0),d2           | Tail index to d2
     1160                bsr     wrapout                 | Adjust for wraparound
     1161                cmp.w   obufhd(a0),d2           | Compare to head index
     1162                beq     serpt_4                 | Jump if buffer full
     1163
     1164                move.l  obuf(a0),a2             | Get buffer base address in a2
     1165                move.b  d1,0(a2,d2)             | Put character in buffer
     1166                move.w  d2,obuftl(a0)           | Update buffer tail index
     1167
     1168serpt_3:        bsr     serchk                  | Check status on our way out
     1169                bsr     rtschk                  | Handle RTS protocol
     1170                move.w  (a7)+,sr                | Restore status register
     1171                andi    #0xFFFE,sr              | Clear carry flag = OK
     1172                rts                             | Return to caller
     1173
     1174serpt_4:        bsr     serchk                  | Check status on our way out
     1175                bsr     rtschk                  | Handle RTS protocol
     1176                move.w  (a7)+,sr                | Restore status register
     1177                ori     #0x0001,sr              | Set carry flag = buffer full
     1178                rts                             | Return to caller
     1179
     1180                .page
     1181
    11821182                .ifne   BUCHLA
    1183 *
    1184 * midput -- Output to MIDI
    1185 * ------    --------------
    1186 midput:         move.w  sr,-(a7)                * Save status register
    1187                 ori.w   #IPL7,sr                * Set IPL = 7  (diable ints)
    1188                 move.b  ACIA_ISR(a1),isr(a0)    * Get ACIA isr
    1189                 move.b  ACIA_CSR(a1),csr(a0)    * Get ACIA csr
    1190                 btst.b  #6,isr(a0)              * Is ACIA still sending ?
    1191                 beq     midpt_2                 * Jump if so
    1192 *
    1193                 move.w  obufhd(a0),d2           * Head index to d2
    1194                 cmp.w   obuftl(a0),d2           * Compare to tail index
    1195                 bne     midpt_2                 * Jump if buffer not empty
    1196 *
    1197                 move.b  d1,ACIA_TDR(a1)         * Give byte to ACIA to send
    1198                 bra     midpt_3                 * Go set final status and exit
    1199 *
    1200 midpt_2:        move.w  obuftl(a0),d2           * Tail index to d2
    1201                 bsr     wrapout                 * Adjust for wraparound
    1202                 cmp.w   obufhd(a0),d2           * Compare to head index
    1203                 beq     midpt_4                 * Jump if buffer full
    1204 *
    1205                 move.l  obuf(a0),a2             * Get buffer base address in a2
    1206                 move.b  d1,0(a2,d2)             * Put character in buffer
    1207                 move.w  d2,obuftl(a0)           * Update buffer tail index
    1208 *
    1209 midpt_3:        bsr     midchk                  * Check status on our way out
    1210                 move.w  (a7)+,sr                * Restore status register
    1211                 andi    #$FFFE,sr               * Clear carry flag = OK
    1212                 rts                             * Return to caller
    1213 *
    1214 midpt_4:        bsr     midchk                  * Check status on our way out
    1215                 move.w  (a7)+,sr                * Restore status register
    1216                 ori     #$0001,sr               * Set carry flag = buffer full
    1217                 rts                             * Return to caller
    1218 *
    1219                 .endc
    1220 *
    1221                 .page
    1222 *
    1223 * rtschk -- Check RTS mode and turn on RTS if it's enabled
    1224 * ------    ----------------------------------------------
    1225 rtschk:         btst    #1,linedisc(a0)         * RTS/CTS mode set ?
    1226                 beq     rts_1                   * Jump if not
    1227 *
    1228                 bsr     rtson                   * Turn on RTS
    1229 *
    1230 rts_1:          rts                             * Return to caller
    1231 *
    1232 * rsilen -- Get length of portion of input buffer that's been used so far
    1233 * ------    -------------------------------------------------------------
    1234 rsilen:         move.w  ibuftl(a0),d2           * Tail index to d2
    1235                 move.w  ibufhd(a0),d3           * Head index to d3
    1236                 cmp.w   d3,d2                   * Head > Tail ?
    1237                 bhi     rsi_1                   * Jump if not
    1238 *
    1239                 add.w   ibufsize(a0),d2         * Add buffer size to tail index
    1240 *
    1241 rsi_1:          sub.w   d3,d2                   * Length = (adjusted)Tail - Head
    1242                 rts                             * Return to caller
    1243 *
    1244 * rtson -- Turn on RTS line
    1245 * -----    ----------------
    1246 rtson:          move.b  cfr1(a0),d0             * Pick up CFR1 image
    1247                 bclr    #0,d0                   * Turn on RTS line  (active low)
    1248                 bset    #7,d0                   * Make sure MS bit is set
    1249                 move.b  d0,cfr1(a0)             * Update CFR1 image
    1250                 move.b  d0,ACIA_CFR(a1)         * Send CFR to hardware
    1251                 rts                             * Return to caller
    1252 *
    1253 * rtsoff -- Turn off RTS line
    1254 * ------    -----------------
    1255 rtsoff:         move.b  cfr1(a0),d0             * Pick up CFR1 image
    1256                 bset    #0,d0                   * Turn off RTS line  (active low)
    1257                 bset    #7,d0                   * Make sure MS bit is set
    1258                 move.b  d0,cfr1(a0)             * Update CFR1 image
    1259                 move.b  d0,ACIA_CFR(a1)         * Send CFR to hardware
     1183
     1184| midput -- Output to MIDI
     1185| ------    --------------
     1186midput:         move.w  sr,-(a7)                | Save status register
     1187                ori.w   #IPL7,sr                | Set IPL = 7  (diable ints)
     1188                move.b  ACIA_ISR(a1),isr(a0)    | Get ACIA isr
     1189                move.b  ACIA_CSR(a1),csr(a0)    | Get ACIA csr
     1190                btst.b  #6,isr(a0)              | Is ACIA still sending ?
     1191                beq     midpt_2                 | Jump if so
     1192
     1193                move.w  obufhd(a0),d2           | Head index to d2
     1194                cmp.w   obuftl(a0),d2           | Compare to tail index
     1195                bne     midpt_2                 | Jump if buffer not empty
     1196
     1197                move.b  d1,ACIA_TDR(a1)         | Give byte to ACIA to send
     1198                bra     midpt_3                 | Go set final status and exit
     1199
     1200midpt_2:        move.w  obuftl(a0),d2           | Tail index to d2
     1201                bsr     wrapout                 | Adjust for wraparound
     1202                cmp.w   obufhd(a0),d2           | Compare to head index
     1203                beq     midpt_4                 | Jump if buffer full
     1204
     1205                move.l  obuf(a0),a2             | Get buffer base address in a2
     1206                move.b  d1,0(a2,d2)             | Put character in buffer
     1207                move.w  d2,obuftl(a0)           | Update buffer tail index
     1208
     1209midpt_3:        bsr     midchk                  | Check status on our way out
     1210                move.w  (a7)+,sr                | Restore status register
     1211                andi    #0xFFFE,sr              | Clear carry flag = OK
     1212                rts                             | Return to caller
     1213
     1214midpt_4:        bsr     midchk                  | Check status on our way out
     1215                move.w  (a7)+,sr                | Restore status register
     1216                ori     #0x0001,sr              | Set carry flag = buffer full
     1217                rts                             | Return to caller
     1218
     1219                .endc
     1220
     1221                .page
     1222
     1223| rtschk -- Check RTS mode and turn on RTS if it's enabled
     1224| ------    ----------------------------------------------
     1225rtschk:         btst    #1,linedisc(a0)         | RTS/CTS mode set ?
     1226                beq     rts_1                   | Jump if not
     1227
     1228                bsr     rtson                   | Turn on RTS
     1229
     1230rts_1:          rts                             | Return to caller
     1231
     1232| rsilen -- Get length of portion of input buffer that's been used so far
     1233| ------    -------------------------------------------------------------
     1234rsilen:         move.w  ibuftl(a0),d2           | Tail index to d2
     1235                move.w  ibufhd(a0),d3           | Head index to d3
     1236                cmp.w   d3,d2                   | Head > Tail ?
     1237                bhi     rsi_1                   | Jump if not
     1238
     1239                add.w   ibufsize(a0),d2         | Add buffer size to tail index
     1240
     1241rsi_1:          sub.w   d3,d2                   | Length = (adjusted)Tail - Head
     1242                rts                             | Return to caller
     1243
     1244| rtson -- Turn on RTS line
     1245| -----    ----------------
     1246rtson:          move.b  cfr1(a0),d0             | Pick up CFR1 image
     1247                bclr    #0,d0                   | Turn on RTS line  (active low)
     1248                bset    #7,d0                   | Make sure MS bit is set
     1249                move.b  d0,cfr1(a0)             | Update CFR1 image
     1250                move.b  d0,ACIA_CFR(a1)         | Send CFR to hardware
     1251                rts                             | Return to caller
     1252
     1253| rtsoff -- Turn off RTS line
     1254| ------    -----------------
     1255rtsoff:         move.b  cfr1(a0),d0             | Pick up CFR1 image
     1256                bset    #0,d0                   | Turn off RTS line  (active low)
     1257                bset    #7,d0                   | Make sure MS bit is set
     1258                move.b  d0,cfr1(a0)             | Update CFR1 image
     1259                move.b  d0,ACIA_CFR(a1)         | Send CFR to hardware
    12601260                rts
    1261 *
    1262                 .page
    1263 *
    1264 * serintr -- Serial (Serial-1, Serial-2, MIDI-1, MIDI-2) interrupt handler
    1265 * -------    -------------------------------------------------------------
    1266 serintr:        movem.l d0-d3/a0-a2,-(a7)       * Save registers
    1267                 lea     sr1iorec,a0             * Point at Serial-1 iorec
    1268                 lea     SR1ACIA,a1              * Point at Serial-1 ACIA
    1269                 bsr     serint                  * Go process (possible) int.
    1270 *
    1271                 lea     sr2iorec,a0             * Point at Serial-2 iorec
    1272                 lea     SR2ACIA,a1              * Point at Serial-2 ACIA
    1273                 bsr     serint                  * Go process (possible) int.
    1274 *
     1261
     1262                .page
     1263
     1264| serintr -- Serial (Serial-1, Serial-2, MIDI-1, MIDI-2) interrupt handler
     1265| -------    -------------------------------------------------------------
     1266serintr:        movem.l d0-d3/a0-a2,-(a7)       | Save registers
     1267                lea     sr1iorec,a0             | Point at Serial-1 iorec
     1268                lea     SR1ACIA,a1              | Point at Serial-1 ACIA
     1269                bsr     serint                  | Go process (possible) int.
     1270
     1271                lea     sr2iorec,a0             | Point at Serial-2 iorec
     1272                lea     SR2ACIA,a1              | Point at Serial-2 ACIA
     1273                bsr     serint                  | Go process (possible) int.
     1274
    12751275                .ifne   BUCHLA
    1276 *
    1277                 lea     mc1iorec,a0             * Point at MIDI-1 iorec
    1278                 lea     MC1ACIA,a1              * Point at MIDI-1 ACIA
    1279                 bsr     midint                  * Go process (possible) int.
    1280 *
    1281                 lea     mc2iorec,a0             * Point at MIDI-2 iorec
    1282                 lea     MC2ACIA,a1              * Point at MIDI-2 ACIA
    1283                 bsr     midint                  * Go process (possible) int.
    1284 *
    1285                 .endc
    1286 *
    1287                 movem.l (a7)+,d0-d3/a0-a2       * Restore registers
    1288                 rte                             * Return from exception
    1289 *
    1290                 .page
    1291 *
    1292 * serint -- Process an interrupt from Serial-1 or Serial-2
    1293 * ------    ----------------------------------------------
    1294 serint:         move.b  ACIA_ISR(a1),isr(a0)    * Get and save ISR
    1295                 move.b  ACIA_CSR(a1),csr(a0)    * Get and save CSR
    1296 *
    1297                 btst.b  #7,isr(a0)              * Was int for this device ?
    1298                 beq     serintx                 * Jump if not
    1299 *
    1300 serchk:         btst.b  #1,isr(a0)              * FRM/OVR/BRK error ?
    1301                 bne     sererr                  * Jump if so
    1302 *
    1303                 btst.b  #0,isr(a0)              * Receiver interrupt ?
    1304                 bne     serrx                   * Jump if so
    1305 *
    1306 sertxq:         btst.b  #6,isr(a0)              * Transmitter interrupt ?
    1307                 bne     sertx                   * Jump if so
    1308 *
    1309 serctq:         btst.b  #5,isr(a0)              * CTS interrupt ?
    1310                 bne     sercts                  * Jump if so
    1311 *
    1312 serintx:        rts                             * Return to caller
    1313 *
    1314 sererr:         addq.w  #1,errct(a0)            * Update error count
    1315                 move.b  ACIA_RDR(a1),erbyte(a0) * Get error byte
     1276
     1277                lea     mc1iorec,a0             | Point at MIDI-1 iorec
     1278                lea     MC1ACIA,a1              | Point at MIDI-1 ACIA
     1279                bsr     midint                  | Go process (possible) int.
     1280
     1281                lea     mc2iorec,a0             | Point at MIDI-2 iorec
     1282                lea     MC2ACIA,a1              | Point at MIDI-2 ACIA
     1283                bsr     midint                  | Go process (possible) int.
     1284
     1285                .endc
     1286
     1287                movem.l (a7)+,d0-d3/a0-a2       | Restore registers
     1288                rte                             | Return from exception
     1289
     1290                .page
     1291
     1292| serint -- Process an interrupt from Serial-1 or Serial-2
     1293| ------    ----------------------------------------------
     1294serint:         move.b  ACIA_ISR(a1),isr(a0)    | Get and save ISR
     1295                move.b  ACIA_CSR(a1),csr(a0)    | Get and save CSR
     1296
     1297                btst.b  #7,isr(a0)              | Was int for this device ?
     1298                beq     serintx                 | Jump if not
     1299
     1300serchk:         btst.b  #1,isr(a0)              | FRM/OVR/BRK error ?
     1301                bne     sererr                  | Jump if so
     1302
     1303                btst.b  #0,isr(a0)              | Receiver interrupt ?
     1304                bne     serrx                   | Jump if so
     1305
     1306sertxq:         btst.b  #6,isr(a0)              | Transmitter interrupt ?
     1307                bne     sertx                   | Jump if so
     1308
     1309serctq:         btst.b  #5,isr(a0)              | CTS interrupt ?
     1310                bne     sercts                  | Jump if so
     1311
     1312serintx:        rts                             | Return to caller
     1313
     1314sererr:         addq.w  #1,errct(a0)            | Update error count
     1315                move.b  ACIA_RDR(a1),erbyte(a0) | Get error byte
    13161316                rts
    1317 *
    1318 * Handle CTS interupt
    1319 *
    1320 sercts:         btst.b  #1,linedisc(a0)         * RTS/CTS mode ?
    1321                 beq     serintx                 * Ignore if not
    1322 *
    1323                 btst.b  #5,csr(a0)              * CTS set ?
    1324                 beq     serintx                 * Ignore if not
    1325 *
    1326 sercts1:        btst.b  #6,isr(a0)              * TDRE set ?
    1327                 beq     sercts1                 * Loop until it is  (!)
    1328 *
    1329                 move.w  obufhd(a0),d2           * Head index to d2
    1330                 cmp.w   obuftl(a0),d2           * Compare to tail index
    1331                 beq     serintx                 * Done if buffer empty
    1332 *
    1333                 bsr.w   wrapout                 * Adjust pointer for wraparound
    1334                 move.l  obuf(a0),a2             * Get buffer base in a2
    1335                 move.b  0(a2,d2),ACIA_TDR(a1)   * Send byte on its way
    1336                 move.w  d2,obufhd(a0)           * Save updated head index
     1317
     1318| Handle CTS interupt
     1319
     1320sercts:         btst.b  #1,linedisc(a0)         | RTS/CTS mode ?
     1321                beq     serintx                 | Ignore if not
     1322
     1323                btst.b  #5,csr(a0)              | CTS set ?
     1324                beq     serintx                 | Ignore if not
     1325
     1326sercts1:        btst.b  #6,isr(a0)              | TDRE set ?
     1327                beq     sercts1                 | Loop until it is  (!)
     1328
     1329                move.w  obufhd(a0),d2           | Head index to d2
     1330                cmp.w   obuftl(a0),d2           | Compare to tail index
     1331                beq     serintx                 | Done if buffer empty
     1332
     1333                bsr.w   wrapout                 | Adjust pointer for wraparound
     1334                move.l  obuf(a0),a2             | Get buffer base in a2
     1335                move.b  0(a2,d2),ACIA_TDR(a1)   | Send byte on its way
     1336                move.w  d2,obufhd(a0)           | Save updated head index
    13371337                rts
    1338 *
    1339                 .page
    1340 *
    1341 * Handle receiver interrupt
    1342 *
    1343 serrx:          btst.b  #1,linedisc(a0)         * RTS/CTS mode set ?
    1344                 beq     serrx1                  * Jump if not
    1345 *
    1346                 bsr.w   rtsoff                  * Turn off RTS
    1347 *
    1348 serrx1:         move.b  ACIA_RDR(a1),d0         * Read data from ACIA
    1349                 btst.b  #1,linedisc(a0)         * RTS/CTS mode set ?
    1350                 bne     serrx3                  * Jump if so
    1351 *
    1352                 btst.b  #0,linedisc(a0)         * XON/XOFF mode set ?
    1353                 beq     serrx3                  * Jump if not
    1354 *
    1355                 cmpi.b  #$11,d0                 * Is this an XON ?
    1356                 bne     serrx2                  * Jump if not
    1357 *
    1358                 move.b  #$00,flagxoff(a0)       * Clear flagxoff
    1359                 bra     sertxq                  * Done
    1360 *
    1361 serrx2:         cmpi.b  #$13,d0                 * Is this an XOFF ?
    1362                 bne     serrx3                  * Jump if not
    1363 *
    1364                 move.b  #$FF,flagxoff(a0)       * Set flagxoff
    1365                 bra     sertxq                  * Done
    1366 *
    1367 serrx3:         move.w  ibuftl(a0),d1           * Get tail index in d1
    1368                 bsr.w   wrapin                  * Adjust for wraparound
    1369                 cmp.w   ibufhd(a0),d1           * Head = tail ?
    1370                 beq     seribf                  * If so, we drop the character
    1371 *
    1372                 move.l  ibuf(a0),a2             * Get buffer address
    1373                 move.b  d0,0(a2,d1)             * Stash byte in buffer
    1374                 move.w  d1,ibuftl(a0)           * Save updated tail index
    1375                 bsr     rsilen                  * Get length of buffer used
    1376                 cmp.w   ibufhi(a0),d2           * Hit high water mark ?
    1377                 bne     serrx4                  * Jump if not
    1378 *
    1379                 btst.b  #1,linedisc(a0)         * RTS/CTS mode set ?
    1380                 bne     sertxq                  * Done if so
    1381 *
    1382                 btst.b  #0,linedisc(a0)         * XON/XOFF mode set ?
    1383                 beq     serrx4                  * Jump if not
    1384 *
    1385                 tst.b   flagxon(a0)             * XOFF already sent ?
    1386                 bne     serrx4                  * Jump if so
    1387 *
    1388                 move.b  #$FF,flagxon(a0)        * Set the flag
    1389                 move.b  #$13,d1                 * Send an XOFF
    1390                 bsr.w   serput                  * ...
    1391 *
    1392                 .page
    1393 *
    1394 serrx4:         btst    #1,linedisc(a0)         * RTS/CTS mode set ?
    1395                 beq     sertxq                  * Done if not
    1396 *
    1397                 bsr     rtson                   * Turn on RTS
     1338
     1339                .page
     1340
     1341| Handle receiver interrupt
     1342
     1343serrx:          btst.b  #1,linedisc(a0)         | RTS/CTS mode set ?
     1344                beq     serrx1                  | Jump if not
     1345
     1346                bsr.w   rtsoff                  | Turn off RTS
     1347
     1348serrx1:         move.b  ACIA_RDR(a1),d0         | Read data from ACIA
     1349                btst.b  #1,linedisc(a0)         | RTS/CTS mode set ?
     1350                bne     serrx3                  | Jump if so
     1351
     1352                btst.b  #0,linedisc(a0)         | XON/XOFF mode set ?
     1353                beq     serrx3                  | Jump if not
     1354
     1355                cmpi.b  #0x11,d0                | Is this an XON ?
     1356                bne     serrx2                  | Jump if not
     1357
     1358                move.b  #0x00,flagxoff(a0)      | Clear flagxoff
     1359                bra     sertxq                  | Done
     1360
     1361serrx2:         cmpi.b  #0x13,d0                | Is this an XOFF ?
     1362                bne     serrx3                  | Jump if not
     1363
     1364                move.b  #0xFF,flagxoff(a0)      | Set flagxoff
     1365                bra     sertxq                  | Done
     1366
     1367serrx3:         move.w  ibuftl(a0),d1           | Get tail index in d1
     1368                bsr.w   wrapin                  | Adjust for wraparound
     1369                cmp.w   ibufhd(a0),d1           | Head = tail ?
     1370                beq     seribf                  | If so, we drop the character
     1371
     1372                move.l  ibuf(a0),a2             | Get buffer address
     1373                move.b  d0,0(a2,d1)             | Stash byte in buffer
     1374                move.w  d1,ibuftl(a0)           | Save updated tail index
     1375                bsr     rsilen                  | Get length of buffer used
     1376                cmp.w   ibufhi(a0),d2           | Hit high water mark ?
     1377                bne     serrx4                  | Jump if not
     1378
     1379                btst.b  #1,linedisc(a0)         | RTS/CTS mode set ?
     1380                bne     sertxq                  | Done if so
     1381
     1382                btst.b  #0,linedisc(a0)         | XON/XOFF mode set ?
     1383                beq     serrx4                  | Jump if not
     1384
     1385                tst.b   flagxon(a0)             | XOFF already sent ?
     1386                bne     serrx4                  | Jump if so
     1387
     1388                move.b  #0xFF,flagxon(a0)       | Set the flag
     1389                move.b  #0x13,d1                | Send an XOFF
     1390                bsr.w   serput                  | ...
     1391
     1392                .page
     1393
     1394serrx4:         btst    #1,linedisc(a0)         | RTS/CTS mode set ?
     1395                beq     sertxq                  | Done if not
     1396
     1397                bsr     rtson                   | Turn on RTS
    13981398                bra     sertxq
    1399 *
    1400 * Handle transmitter interrupt
    1401 *
    1402 sertx:          btst.b  #1,linedisc(a0)         * RTS/CTS mode set ?
    1403                 bne     sertx2                  * If so, go check CTS
    1404 *
    1405                 btst.b  #0,linedisc(a0)         * XON/XOFF mode set ?
    1406                 beq     sertx1                  * Jump if not
    1407 *
    1408                 tst.b   flagxoff(a0)            * Check flagxoff
    1409                 bne     serctq                  * Done if set
    1410 *
    1411 sertx1:         move.w  obufhd(a0),d2           * Head index to d2
    1412                 cmp.w   obuftl(a0),d2           * Compare to tail index
    1413                 beq     serctq                  * Done if buffer empty
    1414 *
    1415                 bsr     wrapout                 * Adjust pointer for wraparound
    1416                 move.l  obuf(a0),a2             * Get buffer base address
    1417                 move.b  0(a2,d2),ACIA_TDR(a1)   * Send byte on its way
    1418                 move.w  d2,obufhd(a0)           * Save updated head index
    1419                 bra     serctq                  * Done
    1420 *
    1421 sertx2:         btst.b  #5,csr(a0)              * CTS set in csr ?
    1422                 beq     serctq                  * If not, go check for CTS int
    1423 *
    1424                 bra     sertx1                  * CTS was set, go transmit
    1425 *
    1426 seribf:         move.b  d0,erbyte(a0)           * Log dropped character
    1427                 addq.w  #1,ibfct(a0)            * ...
    1428                 bra     sertxq                  * Go check Tx interrupt
    1429 *
    1430                 .page
    1431 *
     1399
     1400| Handle transmitter interrupt
     1401
     1402sertx:          btst.b  #1,linedisc(a0)         | RTS/CTS mode set ?
     1403                bne     sertx2                  | If so, go check CTS
     1404
     1405                btst.b  #0,linedisc(a0)         | XON/XOFF mode set ?
     1406                beq     sertx1                  | Jump if not
     1407
     1408                tst.b   flagxoff(a0)            | Check flagxoff
     1409                bne     serctq                  | Done if set
     1410
     1411sertx1:         move.w  obufhd(a0),d2           | Head index to d2
     1412                cmp.w   obuftl(a0),d2           | Compare to tail index
     1413                beq     serctq                  | Done if buffer empty
     1414
     1415                bsr     wrapout                 | Adjust pointer for wraparound
     1416                move.l  obuf(a0),a2             | Get buffer base address
     1417                move.b  0(a2,d2),ACIA_TDR(a1)   | Send byte on its way
     1418                move.w  d2,obufhd(a0)           | Save updated head index
     1419                bra     serctq                  | Done
     1420
     1421sertx2:         btst.b  #5,csr(a0)              | CTS set in csr ?
     1422                beq     serctq                  | If not, go check for CTS int
     1423
     1424                bra     sertx1                  | CTS was set, go transmit
     1425
     1426seribf:         move.b  d0,erbyte(a0)           | Log dropped character
     1427                addq.w  #1,ibfct(a0)            | ...
     1428                bra     sertxq                  | Go check Tx interrupt
     1429
     1430                .page
     1431
    14321432                .ifne   BUCHLA
    1433 *
    1434 * midint -- Process an interrupt from MIDI-1 or MIDI-2
    1435 * ------    ------------------------------------------
    1436 midint:         move.b  ACIA_ISR(a1),isr(a0)    * Get and save ISR
    1437                 move.b  ACIA_CSR(a1),csr(a0)    * Get and save CSR
    1438 *
    1439                 btst.b  #7,isr(a0)              * Was int for this device ?
    1440                 beq     midintx                 * Jump if not
    1441 *
    1442 midchk:         btst.b  #1,isr(a0)              * FRM/OVR/BRK error ?
    1443                 bne     miderr                  * Jump if so
    1444 *
    1445                 btst.b  #0,isr(a0)              * Receiver interrupt ?
    1446                 bne     midrx                   * Jump if so
    1447 *
    1448 midtxq:         btst.b  #6,isr(a0)              * Transmitter interrupt ?
    1449                 bne     midtx                   * Jump if so
    1450 *
    1451 midintx:        rts                             * Return to caller
    1452 *
    1453 miderr:         addq.w  #1,errct(a0)            * Update error count
    1454                 move.b  ACIA_RDR(a1),erbyte(a0) * Get error byte
     1433
     1434| midint -- Process an interrupt from MIDI-1 or MIDI-2
     1435| ------    ------------------------------------------
     1436midint:         move.b  ACIA_ISR(a1),isr(a0)    | Get and save ISR
     1437                move.b  ACIA_CSR(a1),csr(a0)    | Get and save CSR
     1438
     1439                btst.b  #7,isr(a0)              | Was int for this device ?
     1440                beq     midintx                 | Jump if not
     1441
     1442midchk:         btst.b  #1,isr(a0)              | FRM/OVR/BRK error ?
     1443                bne     miderr                  | Jump if so
     1444
     1445                btst.b  #0,isr(a0)              | Receiver interrupt ?
     1446                bne     midrx                   | Jump if so
     1447
     1448midtxq:         btst.b  #6,isr(a0)              | Transmitter interrupt ?
     1449                bne     midtx                   | Jump if so
     1450
     1451midintx:        rts                             | Return to caller
     1452
     1453miderr:         addq.w  #1,errct(a0)            | Update error count
     1454                move.b  ACIA_RDR(a1),erbyte(a0) | Get error byte
    14551455                rts
    1456 *
    1457 * Handle receiver interrupt
    1458 *
    1459 midrx:          move.b  ACIA_RDR(a1),d0         * Read data from ACIA
    1460                 move.w  ibuftl(a0),d1           * Get tail index in d1
    1461                 bsr.w   wrapin                  * Adjust for wraparound
    1462                 cmp.w   ibufhd(a0),d1           * Head = tail ?
    1463                 beq     midibf                  * If so, we drop the character
    1464 *
    1465                 move.l  ibuf(a0),a2             * Get buffer address
    1466                 move.b  d0,0(a2,d1)             * Stash byte in buffer
    1467                 move.w  d1,ibuftl(a0)           * Save updated tail index
    1468                 bra     midtxq                  * Done  (go check tx int)
    1469 *
    1470                 .page
    1471 *
    1472 * Handle transmitter interrupt
    1473 *
    1474 midtx:          move.w  obufhd(a0),d2           * Head index to d2
    1475                 cmp.w   obuftl(a0),d2           * Compare to tail index
    1476                 beq     midintx                 * Done if buffer empty
    1477 *
    1478                 bsr     wrapout                 * Adjust pointer for wraparound
    1479                 move.l  obuf(a0),a2             * Get buffer base address
    1480                 move.b  0(a2,d2),ACIA_TDR(a1)   * Send byte on its way
    1481                 move.w  d2,obufhd(a0)           * Save updated head index
    1482                 bra     midintx                 * Done
    1483 *
    1484 midibf:         move.b  d0,erbyte(a0)           * Log dropped character
    1485                 addq.w  #1,ibfct(a0)            * ...
    1486                 bra     midtxq                  * Go check Tx interrupt
    1487 *
    1488                 .endc
    1489 *
    1490                 .page
    1491 *
    1492 * setexec -- Set an exception vector
    1493 * -------    -----------------------
    1494 setexec:        move.w  4(a7),d0                * Get vector number
    1495                 lsl.w   #2,d0                   * .. times 4
    1496                 sub.l   a0,a0                   * Clear a0
    1497                 lea     0(a0,d0),a0             * Get address of old vector
    1498                 move.l  (a0),d0                 * Move old vector to d0
    1499                 move.l  6(a7),d1                * Pick up new vector
    1500                 bmi     setexec1                * Don't set if = -1
    1501 *
    1502                 move.l  d1,(a0)                 * Set new vector
    1503 *
    1504 setexec1:       rts                             * Return to caller
    1505 *
    1506 * piorec -- Get pointer to iorec structure
    1507 * ------    ------------------------------
    1508 piorec:         moveq.l #0,d1                   * Clear out d1
    1509                 move.w  4(a7),d1                * Get device number
    1510                 move.w  sr,-(a7)                * Save status register
    1511                 ori.w   #IPL7,sr                * Set IPL = 7  (no ints)
    1512                 lea     iortab,a2               * Get base address of table
    1513                 asl.l   #2,d1                   * Device # times 4 for index
    1514                 move.l  0(a2,d1),d0             * Get iorec address from table
    1515                 move.w  (a7)+,sr                * Restore status register
    1516                 rts                             * Return to caller
    1517 *
    1518                 .page
    1519 *
    1520 * setport -- Set ACIA parameters  (unit, mode, baud, CFR0, CFR1)
    1521 * -------    ---------------------------------------------------
    1522 setport:        moveq.l #0,d1                   * Clear out d1
    1523                 move.w  4(a7),d1                * Get device number
    1524                 asl.l   #3,d1                   * Times 8 for index
    1525                 ori.w   #IPL7,sr                * Set IPL = 7  (no ints)
    1526                 lea     aciatab,a2              * Get base of table
    1527                 move.l  0(a2,d1),d0             * Get iorec address
    1528                 move.l  4(a2,d1),d2             * Get ACIA address
    1529                 movea.l d0,a0                   * Setup a0 = iorec address
    1530                 movea.l d2,a1                   * Setup a1 = ACIA address
    1531                 tst.w   6(a7)                   * Change mode ?
    1532                 bmi     setpt1                  * Jump if not
    1533 *
    1534                 move.b  7(a7),linedisc(a0)      * Set line discipline  (mode)
    1535 *
    1536 setpt1:         tst.w   8(a7)                   * Change baud rate ?
    1537                 bmi     setpt2                  * Jump if not
    1538 *
    1539                 moveq.l #0,d1                   * Clear out d1
    1540                 move.w  8(a7),d1                * Get baud rate index
    1541                 lea     brtable,a2              * Get base of baud rate table
    1542                 move.b  0(a2,d1),d2             * Get baud rate code from table
    1543                 move.b  cfr0(a0),d0             * Get current CFR0
    1544                 andi.w  #$0070,d0               * Mask off old baud rate code
    1545                 or.w    d2,d0                   * OR in new baud rate code
    1546                 move.b  d0,cfr0(a0)             * Update CFR0 in table
    1547                 move.b  d0,ACIA_CFR(a1)         * Update hardware
    1548 *
    1549 setpt2:         tst.w   10(a7)                  * Change CFR0 ?
    1550                 bmi     setpt3                  * Jump if not
    1551 *
    1552                 move.b  11(a7),cfr0(a0)         * Update CFR0 in table
    1553                 move.b  cfr0(a0),ACIA_CFR(a1)   * Update CFR0 in hardware
    1554 *
    1555 setpt3:         tst.w   12(a7)                  * Change CFR1 ?
    1556                 bmi     setpt4                  * Jump if not
    1557 *
    1558                 bset.b  #7,13(a7)               * Force D7 = 1 in argument
    1559                 move.b  13(a7),cfr1(a0)         * Update CFR1 in table
    1560                 move.b  cfr1(a0),ACIA_CFR(a1)   * Update CFR1 in hardware
    1561 *
    1562 setpt4:         rts                             * Return to caller
    1563 *
    1564                 .page
    1565 *
    1566 * aciainit -- Initialize an ACIA port
    1567 * --------    -----------------------
    1568 aciainit:       move.w  #IORECLN,d0             * Setup byte count for move
    1569                 move.l  a0,-(a7)                * Save iorec base
    1570 *
    1571 aciai_1:        move.b  (a2)+,(a0)+             * Move the default to the iorec
    1572                 dbf     d0,aciai_1              * ...
    1573 *
    1574                 move.l  (a7)+,a0                * Restore iorec base
    1575                 move.b  cfr0(a0),ACIA_CFR(a1)   * Setup CFR0
    1576                 move.b  cfr1(a0),ACIA_CFR(a1)   * Setup CFR1
    1577                 move.b  ACIA_RDR(a1),d0         * Clear RDR
    1578                 move.b  #$7F,ACIA_IER(a1)       * Disable all interrupts
    1579                 btst.b  #1,linedisc(a0)         * Are we in RTS/CTS mode ?
    1580                 bne     aciai_2                 * Jump if so
    1581 *
    1582                 move.b  #$C3,ACIA_IER(a1)       * Enable TDRE, RDRF
    1583                 bra     aciai_3                 * Go return
    1584 *
    1585 aciai_2:        move.b  #$E3,ACIA_IER(a1)       * Enable interrupts we want
    1586 *
    1587 aciai_3:        rts                             * Return to caller
    1588 *
    1589                 .page
    1590 *
     1456
     1457| Handle receiver interrupt
     1458
     1459midrx:          move.b  ACIA_RDR(a1),d0         | Read data from ACIA
     1460                move.w  ibuftl(a0),d1           | Get tail index in d1
     1461                bsr.w   wrapin                  | Adjust for wraparound
     1462                cmp.w   ibufhd(a0),d1           | Head = tail ?
     1463                beq     midibf                  | If so, we drop the character
     1464
     1465                move.l  ibuf(a0),a2             | Get buffer address
     1466                move.b  d0,0(a2,d1)             | Stash byte in buffer
     1467                move.w  d1,ibuftl(a0)           | Save updated tail index
     1468                bra     midtxq                  | Done  (go check tx int)
     1469
     1470                .page
     1471
     1472| Handle transmitter interrupt
     1473
     1474midtx:          move.w  obufhd(a0),d2           | Head index to d2
     1475                cmp.w   obuftl(a0),d2           | Compare to tail index
     1476                beq     midintx                 | Done if buffer empty
     1477
     1478                bsr     wrapout                 | Adjust pointer for wraparound
     1479                move.l  obuf(a0),a2             | Get buffer base address
     1480                move.b  0(a2,d2),ACIA_TDR(a1)   | Send byte on its way
     1481                move.w  d2,obufhd(a0)           | Save updated head index
     1482                bra     midintx                 | Done
     1483
     1484midibf:         move.b  d0,erbyte(a0)           | Log dropped character
     1485                addq.w  #1,ibfct(a0)            | ...
     1486                bra     midtxq                  | Go check Tx interrupt
     1487
     1488                .endc
     1489
     1490                .page
     1491
     1492| setexec -- Set an exception vector
     1493| -------    -----------------------
     1494setexec:        move.w  4(a7),d0                | Get vector number
     1495                lsl.w   #2,d0                   | .. times 4
     1496                sub.l   a0,a0                   | Clear a0
     1497                lea     0(a0,d0),a0             | Get address of old vector
     1498                move.l  (a0),d0                 | Move old vector to d0
     1499                move.l  6(a7),d1                | Pick up new vector
     1500                bmi     setexec1                | Don't set if = -1
     1501
     1502                move.l  d1,(a0)                 | Set new vector
     1503
     1504setexec1:       rts                             | Return to caller
     1505
     1506| piorec -- Get pointer to iorec structure
     1507| ------    ------------------------------
     1508piorec:         moveq.l #0,d1                   | Clear out d1
     1509                move.w  4(a7),d1                | Get device number
     1510                move.w  sr,-(a7)                | Save status register
     1511                ori.w   #IPL7,sr                | Set IPL = 7  (no ints)
     1512                lea     iortab,a2               | Get base address of table
     1513                asl.l   #2,d1                   | Device # times 4 for index
     1514                move.l  0(a2,d1),d0             | Get iorec address from table
     1515                move.w  (a7)+,sr                | Restore status register
     1516                rts                             | Return to caller
     1517
     1518                .page
     1519
     1520| setport -- Set ACIA parameters  (unit, mode, baud, CFR0, CFR1)
     1521| -------    ---------------------------------------------------
     1522setport:        moveq.l #0,d1                   | Clear out d1
     1523                move.w  4(a7),d1                | Get device number
     1524                asl.l   #3,d1                   | Times 8 for index
     1525                ori.w   #IPL7,sr                | Set IPL = 7  (no ints)
     1526                lea     aciatab,a2              | Get base of table
     1527                move.l  0(a2,d1),d0             | Get iorec address
     1528                move.l  4(a2,d1),d2             | Get ACIA address
     1529                movea.l d0,a0                   | Setup a0 = iorec address
     1530                movea.l d2,a1                   | Setup a1 = ACIA address
     1531                tst.w   6(a7)                   | Change mode ?
     1532                bmi     setpt1                  | Jump if not
     1533
     1534                move.b  7(a7),linedisc(a0)      | Set line discipline  (mode)
     1535
     1536setpt1:         tst.w   8(a7)                   | Change baud rate ?
     1537                bmi     setpt2                  | Jump if not
     1538
     1539                moveq.l #0,d1                   | Clear out d1
     1540                move.w  8(a7),d1                | Get baud rate index
     1541                lea     brtable,a2              | Get base of baud rate table
     1542                move.b  0(a2,d1),d2             | Get baud rate code from table
     1543                move.b  cfr0(a0),d0             | Get current CFR0
     1544                andi.w  #0x0070,d0              | Mask off old baud rate code
     1545                or.w    d2,d0                   | OR in new baud rate code
     1546                move.b  d0,cfr0(a0)             | Update CFR0 in table
     1547                move.b  d0,ACIA_CFR(a1)         | Update hardware
     1548
     1549setpt2:         tst.w   10(a7)                  | Change CFR0 ?
     1550                bmi     setpt3                  | Jump if not
     1551
     1552                move.b  11(a7),cfr0(a0)         | Update CFR0 in table
     1553                move.b  cfr0(a0),ACIA_CFR(a1)   | Update CFR0 in hardware
     1554
     1555setpt3:         tst.w   12(a7)                  | Change CFR1 ?
     1556                bmi     setpt4                  | Jump if not
     1557
     1558                bset.b  #7,13(a7)               | Force D7 = 1 in argument
     1559                move.b  13(a7),cfr1(a0)         | Update CFR1 in table
     1560                move.b  cfr1(a0),ACIA_CFR(a1)   | Update CFR1 in hardware
     1561
     1562setpt4:         rts                             | Return to caller
     1563
     1564                .page
     1565
     1566| aciainit -- Initialize an ACIA port
     1567| --------    -----------------------
     1568aciainit:       move.w  #IORECLN,d0             | Setup byte count for move
     1569                move.l  a0,-(a7)                | Save iorec base
     1570
     1571aciai_1:        move.b  (a2)+,(a0)+             | Move the default to the iorec
     1572                dbf     d0,aciai_1              | ...
     1573
     1574                move.l  (a7)+,a0                | Restore iorec base
     1575                move.b  cfr0(a0),ACIA_CFR(a1)   | Setup CFR0
     1576                move.b  cfr1(a0),ACIA_CFR(a1)   | Setup CFR1
     1577                move.b  ACIA_RDR(a1),d0         | Clear RDR
     1578                move.b  #0x7F,ACIA_IER(a1)      | Disable all interrupts
     1579                btst.b  #1,linedisc(a0)         | Are we in RTS/CTS mode ?
     1580                bne     aciai_2                 | Jump if so
     1581
     1582                move.b  #0xC3,ACIA_IER(a1)      | Enable TDRE, RDRF
     1583                bra     aciai_3                 | Go return
     1584
     1585aciai_2:        move.b  #0xE3,ACIA_IER(a1)      | Enable interrupts we want
     1586
     1587aciai_3:        rts                             | Return to caller
     1588
     1589                .page
     1590
    15911591                .ifne   BUCHLA
    1592 *
    1593 * fastcopy -- Copy disk sector quickly
    1594 * --------    ------------------------
    1595 fastcopy:       move.l  4(a7),a0                * Get source pointer
    1596                 move.l  8(a7),a1                * Get destination pointer
    1597                 move.w  $3F,d0                  * 512 bytes  (63+1)*8
    1598 *
    1599 fastcpy1:       move.b  (a0)+,(a1)+             * Move 8 bytes
    1600                 move.b  (a0)+,(a1)+             * ...
    1601                 move.b  (a0)+,(a1)+             * ...
    1602                 move.b  (a0)+,(a1)+             * ...
    1603                 move.b  (a0)+,(a1)+             * ...
    1604                 move.b  (a0)+,(a1)+             * ...
    1605                 move.b  (a0)+,(a1)+             * ...
    1606                 move.b  (a0)+,(a1)+             * ...
    1607                 dbra    d0,fastcpy1             * Loop until all bytes are moved
    1608 *
    1609                 rts                             * Return to caller
    1610 *
    1611                 .page
    1612 *
    1613 * _hdvini -- Drive initialization
    1614 * -------    --------------------
    1615 _hdvini:        link    a6,#-18                 * Reserve space on stack
    1616                 movem.l d3-d7/a3-a5,-(a7)       * Preserve registers
    1617                 move.l  #300,maxactim           * maxactim = 300 * 20ms
    1618                 clr.w   d0                      * Put zeros in ...
    1619                 move.w  d0,nflops               * ... nflops
    1620                 move.w  d0,dskmode              * ... dskmode
    1621                 move.w  d0,-2(a6)               * Start with drive A
    1622                 bra     hdvilp                  * ...
    1623 *
    1624 hdvilp1:        movea.l #dskmode,a0             * Get dskmode address in a0
    1625                 movea.w -2(a6),a1               * Drive number in a1
    1626                 adda.l  a1,a0                   * Point at dskmode for drive
    1627                 clr.b   (a0)                    * Clear flag in dskmode
    1628                 clr.w   -(a7)                   * Push arguments onto stack
    1629                 clr.w   -(a7)                   * ...
    1630                 clr.w   -(a7)                   * ...
    1631                 move.w  -2(a6),-(a7)            * Push drive number onto stack
    1632                 clr.l   -(a7)                   * ... filler
    1633                 clr.l   -(a7)                   * ... filler
    1634                 jsr     flopini                 * Initialize drive
    1635                 adda.l  #16,a7                  * Cleanup stack
    1636                 move.w  d0,-(a7)                * Save error code on stack
    1637                 movea.w -2(a6),a0               * Get drive number
    1638                 adda.l  a0,a0                   * ... times 2
    1639                 adda.l  #dskerrs,a0             * Add base of dskerrs
    1640                 move.w  (a7)+,(a0)              * Move error code off of stack
    1641                 bne     hdvind                  * Jump if drive not present
    1642 *
    1643                 addq.w  #1,nflops               * Update number of drives
    1644                 or.l    #3,drvbits              * Setup drive bits
    1645 *
    1646 hdvind:         addq.w  #1,-2(a6)               * Increment drive number
    1647 *
    1648 hdvilp:         cmp.w   #2,-2(a6)               * See if it's 2 yet
    1649                 blt     hdvilp1                 * Loop until it is
    1650 *
    1651                 movem.l (a7)+,d3-d7/a3-a5       * Restore registers
    1652                 unlk    a6                      * Release temporary stack space
    1653                 rts                             * Return to caller
    1654 *
    1655 * drvmap -- get drive map
    1656 * ------    -------------
    1657 drvmap:         move.l  drvbits,d0              * Get drive bits
    1658                 rts                             * Return to caller
    1659 *
    1660                 .page
    1661 *
    1662 * getbpb -- get BIOS parameter block
    1663 * ------    ------------------------
    1664 getbpb:         link    a6,#-12                 * Reserve space for temporaries
    1665                 movem.l d5-d7/a4-a5,-(a7)       * Save registers on stack
    1666                 cmp.w   #2,8(a6)                * Check drive number
    1667                 blt     gbpb1                   * Jump if OK
    1668 *
    1669                 clr.l   d0                      * Set drive number to 0
    1670                 bra     gbpber                  * Go flag error
    1671 *
    1672 gbpb1:          move.w  8(a6),d0                * Get drive number
    1673                 asl.w   #5,d0                   * ... times 32
    1674                 ext.l   d0                      * ... extend sign
    1675                 move.l  d0,a5                   * Move to a5
    1676                 add.l   #drvbpbs,a5             * Add base of drive bpb are
    1677                 move.l  a5,a4                   * Save in a4
    1678 *
    1679 gbpbrds:        move.w  #1,(a7)                 * floprd count = 1,
    1680                 clr.w   -(a7)                   * ... side = 0,
    1681                 clr.w   -(a7)                   * ... track = 0,
    1682                 move.w  #1,-(a7)                * ... sector = 1,
    1683                 move.w  8(a6),-(a7)             * ... drive #,
    1684                 clr.l   -(a7)                   * ... filler
    1685                 move.l  #buffer,-(a7)           * ... buffer address,
    1686                 jsr     floprd                  * Go read the sector
    1687                 add.l   #16,a7                  * Cleanup stack
    1688                 move.l  d0,-12(a6)              * Save error code
    1689                 tst.l   -12(a6)                 * ... and test it
    1690                 bge     gbpb2                   * Jump if OK
    1691 *
    1692                 move.w  8(a6),(a7)              * Put drive number on stack
    1693                 move.l  -12(a6),d0              * Get error code
    1694                 move.w  d0,-(a7)                * ... and put it on the stack
    1695                 jsr     criter                  * Go do critical error routine
    1696                 addq.l  #2,a7                   * Cleanup stack
    1697                 move.l  d0,-12(a6)              * Save error code
    1698 *
    1699 gbpb2:          move.l  -12(a6),d0              * Get error code
    1700                 cmp.l   #RETRYIT,d0             * Magic number for retry ?
    1701                 beq     gbpbrds                 * Re-read if so
    1702 *
    1703                 tst.l   -12(a6)                 * Test error code
    1704                 bge     gbpb3                   * Jump if OK
    1705 *
    1706                 clr.l   d0                      * Set code in d0
    1707                 bra     gbpber                  * Go set error code
    1708 *
    1709                 .page
    1710 *
    1711 gbpb3:          move.l  #buffer+11,(a7)         * Bytes per sector
    1712                 bsr     itom                    * Convert 8086 to 68K format
    1713                 move.w  d0,d7                   * Save bytes per sector
    1714                 beq     gbpb4                   * Jump if zero
    1715 *
    1716                 move.b  buffer+13,d6            * Sectors per cluster
    1717                 ext.w   d6                      * ... sign extended
    1718                 and.w   #$FF,d6                 * ... and trimmed
    1719                 bne     gbpb5                   * Jump if non-zero
    1720 *
    1721 gbpb4:          clr.l   d0                      * Set error code
    1722                 bra     gbpber                  * ...
    1723 *
    1724 gbpb5:          move.w  d7,(a4)                 * Set recsize
    1725                 move.w  d6,2(a4)                * Set clsiz
    1726                 move.l  #buffer+22,(a7)         * Convert sectors per fat
    1727                 bsr     itom                    * ...
    1728                 move.w  d0,8(a4)                * Set fsiz
    1729                 move.w  8(a4),d0                * Get fsiz
    1730                 addq.w  #1,d0                   * ... plus 1
    1731                 move.w  d0,10(a4)               * Set fatrec
    1732                 move.w  (a4),d0                 * Get recsize
    1733                 muls.w  2(a4),d0                * ... times clsiz
    1734                 move.w  d0,4(a4)                * Set clsizb
    1735                 move.l  #buffer+17,(a7)         * Convert number of dir ents
    1736                 bsr     itom                    * ...
    1737                 asl.w   #5,d0                   * ... times 32
    1738                 ext.l   d0                      * ... sign extended
    1739                 divs.w  (a4),d0                 * ... / recsize
    1740                 move.w  d0,6(a4)                * Set rdlen
    1741                 move.w  10(a4),d0               * Get fatrec
    1742                 add.w   6(a4),d0                * ... + rdlen
    1743                 add.w   8(a4),d0                * ... + fsiz
    1744                 move.w  d0,12(a4)               * Set datrec
    1745                 move.l  #buffer+19,(a7)         * Get number of sectors
    1746                 bsr     itom                    * ... convert
    1747                 sub.w   12(a4),d0               * ... - datrec
    1748                 ext.l   d0                      * ... sign extended
    1749                 divs.w  2(a4),d0                * ... / clsiz
    1750                 move.w  d0,14(a4)               * Set numcl
    1751 *
    1752                 .page
    1753 *
    1754                 move.l  #buffer+26,(a7)         * Convert number of heads
    1755                 bsr     itom                    * ...
    1756                 move.w  d0,20(a5)               * Set dnsides
    1757                 move.l  #buffer+24,(a7)         * Convert sectors per track
    1758                 bsr     itom                    * ...
    1759                 move.w  d0,24(a5)               * Set dspt
    1760                 move.w  20(a5),d0               * Get dnsides
    1761                 muls.w  24(a5),d0               * ... * dspt
    1762                 move.w  d0,22(a5)               * Set dspc
    1763                 move.l  #buffer+28,(a7)         * Convert number of hidden sects
    1764                 bsr     itom                    * ...
    1765                 move.w  d0,26(a5)               * Set dhidden
    1766                 move.l  #buffer+19,(a7)         * Convert sectors on disk
    1767                 bsr     itom                    * ...
    1768                 ext.l   d0                      * ... sign extended
    1769                 divs.w  22(a5),d0               * ... / dspc
    1770                 move.w  d0,18(a5)               * Set dntracks
    1771                 clr.w   d7                      * Counter = 0
    1772                 bra     gbpblpt                 * Jump to end of loop
    1773 *
    1774 gbpb6:          move.l  a5,a0                   * Get buffer pointer
    1775                 move.w  d7,a1                   * Loop count to a1
    1776                 add.l   a1,a0                   * ... + bpb address
    1777                 move.w  d7,a1                   * Loop count to a1
    1778                 add.l   #buffer,a1              * ... + buffer address
    1779                 move.b  8(a1),28(a0)            * Copy a s/n byte
    1780                 addq.w  #1,d7                   * Update loop count
    1781 *
    1782 gbpblpt:        cmp.w   #3,d7                   * Moved 3 bytes ?
    1783                 blt     gbpb6                   * Loop if not
    1784 *
    1785                 .page
    1786 *
    1787                 move.l  #cdev,a0                * Address of cdev table
    1788                 move.w  8(a6),a1                * ... plus drive number
    1789                 add.l   a1,a0                   * ... to a0
    1790                 move.l  #wpstatus,a1            * Address of wpstatus table
    1791                 move.w  8(a6),a2                * ... plus drive number
    1792                 add.l   a2,a1                   * ... to a1
    1793                 move.b  (a1),(a0)               * Move wpstatus to cdev
     1592
     1593| fastcopy -- Copy disk sector quickly
     1594| --------    ------------------------
     1595fastcopy:       move.l  4(a7),a0                | Get source pointer
     1596                move.l  8(a7),a1                | Get destination pointer
     1597                move.w  0x3F,d0                 | 512 bytes  (63+1)|8
     1598
     1599fastcpy1:       move.b  (a0)+,(a1)+             | Move 8 bytes
     1600                move.b  (a0)+,(a1)+             | ...
     1601                move.b  (a0)+,(a1)+             | ...
     1602                move.b  (a0)+,(a1)+             | ...
     1603                move.b  (a0)+,(a1)+             | ...
     1604                move.b  (a0)+,(a1)+             | ...
     1605                move.b  (a0)+,(a1)+             | ...
     1606                move.b  (a0)+,(a1)+             | ...
     1607                dbra    d0,fastcpy1             | Loop until all bytes are moved
     1608
     1609                rts                             | Return to caller
     1610
     1611                .page
     1612
     1613| _hdvini -- Drive initialization
     1614| -------    --------------------
     1615_hdvini:        link    a6,#-18                 | Reserve space on stack
     1616                movem.l d3-d7/a3-a5,-(a7)       | Preserve registers
     1617                move.l  #300,maxactim           | maxactim = 300 | 20ms
     1618                clr.w   d0                      | Put zeros in ...
     1619                move.w  d0,nflops               | ... nflops
     1620                move.w  d0,dskmode              | ... dskmode
     1621                move.w  d0,-2(a6)               | Start with drive A
     1622                bra     hdvilp                  | ...
     1623
     1624hdvilp1:        movea.l #dskmode,a0             | Get dskmode address in a0
     1625                movea.w -2(a6),a1               | Drive number in a1
     1626                adda.l  a1,a0                   | Point at dskmode for drive
     1627                clr.b   (a0)                    | Clear flag in dskmode
     1628                clr.w   -(a7)                   | Push arguments onto stack
     1629                clr.w   -(a7)                   | ...
     1630                clr.w   -(a7)                   | ...
     1631                move.w  -2(a6),-(a7)            | Push drive number onto stack
     1632                clr.l   -(a7)                   | ... filler
     1633                clr.l   -(a7)                   | ... filler
     1634                jsr     flopini                 | Initialize drive
     1635                adda.l  #16,a7                  | Cleanup stack
     1636                move.w  d0,-(a7)                | Save error code on stack
     1637                movea.w -2(a6),a0               | Get drive number
     1638                adda.l  a0,a0                   | ... times 2
     1639                adda.l  #dskerrs,a0             | Add base of dskerrs
     1640                move.w  (a7)+,(a0)              | Move error code off of stack
     1641                bne     hdvind                  | Jump if drive not present
     1642
     1643                addq.w  #1,nflops               | Update number of drives
     1644                or.l    #3,drvbits              | Setup drive bits
     1645
     1646hdvind:         addq.w  #1,-2(a6)               | Increment drive number
     1647
     1648hdvilp:         cmp.w   #2,-2(a6)               | See if it's 2 yet
     1649                blt     hdvilp1                 | Loop until it is
     1650
     1651                movem.l (a7)+,d3-d7/a3-a5       | Restore registers
     1652                unlk    a6                      | Release temporary stack space
     1653                rts                             | Return to caller
     1654
     1655| drvmap -- get drive map
     1656| ------    -------------
     1657drvmap:         move.l  drvbits,d0              | Get drive bits
     1658                rts                             | Return to caller
     1659
     1660                .page
     1661
     1662| getbpb -- get BIOS parameter block
     1663| ------    ------------------------
     1664getbpb:         link    a6,#-12                 | Reserve space for temporaries
     1665                movem.l d5-d7/a4-a5,-(a7)       | Save registers on stack
     1666                cmp.w   #2,8(a6)                | Check drive number
     1667                blt     gbpb1                   | Jump if OK
     1668
     1669                clr.l   d0                      | Set drive number to 0
     1670                bra     gbpber                  | Go flag error
     1671
     1672gbpb1:          move.w  8(a6),d0                | Get drive number
     1673                asl.w   #5,d0                   | ... times 32
     1674                ext.l   d0                      | ... extend sign
     1675                move.l  d0,a5                   | Move to a5
     1676                add.l   #drvbpbs,a5             | Add base of drive bpb are
     1677                move.l  a5,a4                   | Save in a4
     1678
     1679gbpbrds:        move.w  #1,(a7)                 | floprd count = 1,
     1680                clr.w   -(a7)                   | ... side = 0,
     1681                clr.w   -(a7)                   | ... track = 0,
     1682                move.w  #1,-(a7)                | ... sector = 1,
     1683                move.w  8(a6),-(a7)             | ... drive #,
     1684                clr.l   -(a7)                   | ... filler
     1685                move.l  #buffer,-(a7)           | ... buffer address,
     1686                jsr     floprd                  | Go read the sector
     1687                add.l   #16,a7                  | Cleanup stack
     1688                move.l  d0,-12(a6)              | Save error code
     1689                tst.l   -12(a6)                 | ... and test it
     1690                bge     gbpb2                   | Jump if OK
     1691
     1692                move.w  8(a6),(a7)              | Put drive number on stack
     1693                move.l  -12(a6),d0              | Get error code
     1694                move.w  d0,-(a7)                | ... and put it on the stack
     1695                jsr     criter                  | Go do critical error routine
     1696                addq.l  #2,a7                   | Cleanup stack
     1697                move.l  d0,-12(a6)              | Save error code
     1698
     1699gbpb2:          move.l  -12(a6),d0              | Get error code
     1700                cmp.l   #RETRYIT,d0             | Magic number for retry ?
     1701                beq     gbpbrds                 | Re-read if so
     1702
     1703                tst.l   -12(a6)                 | Test error code
     1704                bge     gbpb3                   | Jump if OK
     1705
     1706                clr.l   d0                      | Set code in d0
     1707                bra     gbpber                  | Go set error code
     1708
     1709                .page
     1710
     1711gbpb3:          move.l  #buffer+11,(a7)         | Bytes per sector
     1712                bsr     itom                    | Convert 8086 to 68K format
     1713                move.w  d0,d7                   | Save bytes per sector
     1714                beq     gbpb4                   | Jump if zero
     1715
     1716                move.b  buffer+13,d6            | Sectors per cluster
     1717                ext.w   d6                      | ... sign extended
     1718                and.w   #0xFF,d6                | ... and trimmed
     1719                bne     gbpb5                   | Jump if non-zero
     1720
     1721gbpb4:          clr.l   d0                      | Set error code
     1722                bra     gbpber                  | ...
     1723
     1724gbpb5:          move.w  d7,(a4)                 | Set recsize
     1725                move.w  d6,2(a4)                | Set clsiz
     1726                move.l  #buffer+22,(a7)         | Convert sectors per fat
     1727                bsr     itom                    | ...
     1728                move.w  d0,8(a4)                | Set fsiz
     1729                move.w  8(a4),d0                | Get fsiz
     1730                addq.w  #1,d0                   | ... plus 1
     1731                move.w  d0,10(a4)               | Set fatrec
     1732                move.w  (a4),d0                 | Get recsize
     1733                muls.w  2(a4),d0                | ... times clsiz
     1734                move.w  d0,4(a4)                | Set clsizb
     1735                move.l  #buffer+17,(a7)         | Convert number of dir ents
     1736                bsr     itom                    | ...
     1737                asl.w   #5,d0                   | ... times 32
     1738                ext.l   d0                      | ... sign extended
     1739                divs.w  (a4),d0                 | ... / recsize
     1740                move.w  d0,6(a4)                | Set rdlen
     1741                move.w  10(a4),d0               | Get fatrec
     1742                add.w   6(a4),d0                | ... + rdlen
     1743                add.w   8(a4),d0                | ... + fsiz
     1744                move.w  d0,12(a4)               | Set datrec
     1745                move.l  #buffer+19,(a7)         | Get number of sectors
     1746                bsr     itom                    | ... convert
     1747                sub.w   12(a4),d0               | ... - datrec
     1748                ext.l   d0                      | ... sign extended
     1749                divs.w  2(a4),d0                | ... / clsiz
     1750                move.w  d0,14(a4)               | Set numcl
     1751
     1752                .page
     1753
     1754                move.l  #buffer+26,(a7)         | Convert number of heads
     1755                bsr     itom                    | ...
     1756                move.w  d0,20(a5)               | Set dnsides
     1757                move.l  #buffer+24,(a7)         | Convert sectors per track
     1758                bsr     itom                    | ...
     1759                move.w  d0,24(a5)               | Set dspt
     1760                move.w  20(a5),d0               | Get dnsides
     1761                muls.w  24(a5),d0               | ... | dspt
     1762                move.w  d0,22(a5)               | Set dspc
     1763                move.l  #buffer+28,(a7)         | Convert number of hidden sects
     1764                bsr     itom                    | ...
     1765                move.w  d0,26(a5)               | Set dhidden
     1766                move.l  #buffer+19,(a7)         | Convert sectors on disk
     1767                bsr     itom                    | ...
     1768                ext.l   d0                      | ... sign extended
     1769                divs.w  22(a5),d0               | ... / dspc
     1770                move.w  d0,18(a5)               | Set dntracks
     1771                clr.w   d7                      | Counter = 0
     1772                bra     gbpblpt                 | Jump to end of loop
     1773
     1774gbpb6:          move.l  a5,a0                   | Get buffer pointer
     1775                move.w  d7,a1                   | Loop count to a1
     1776                add.l   a1,a0                   | ... + bpb address
     1777                move.w  d7,a1                   | Loop count to a1
     1778                add.l   #buffer,a1              | ... + buffer address
     1779                move.b  8(a1),28(a0)            | Copy a s/n byte
     1780                addq.w  #1,d7                   | Update loop count
     1781
     1782gbpblpt:        cmp.w   #3,d7                   | Moved 3 bytes ?
     1783                blt     gbpb6                   | Loop if not
     1784
     1785                .page
     1786
     1787                move.l  #cdev,a0                | Address of cdev table
     1788                move.w  8(a6),a1                | ... plus drive number
     1789                add.l   a1,a0                   | ... to a0
     1790                move.l  #wpstatus,a1            | Address of wpstatus table
     1791                move.w  8(a6),a2                | ... plus drive number
     1792                add.l   a2,a1                   | ... to a1
     1793                move.b  (a1),(a0)               | Move wpstatus to cdev
    17941794                beq     gbpb7
    1795 *
    1796                 moveq.l #1,d0                   * Set status = "Uncertain"
     1795
     1796                moveq.l #1,d0                   | Set status = "Uncertain"
    17971797                bra     gbpb8
    1798 *
    1799 gbpb7:          clr.w   d0                      * Set status = "Unchanged"
    1800 *
    1801 gbpb8:          move.l  #dskmode,a1             * Update dskmode table
    1802                 move.w  8(a6),a2                * ...
    1803                 add.l   a2,a1                   * ...
    1804                 move.b  d0,(a1)                 * ...
    1805                 move.l  a5,d0                   * Setup to return bpb pointer
    1806 *
    1807 gbpber:         tst.l   (a7)+                   * Pop garbage off top of stack
    1808                 movem.l (a7)+,d6-d7/a4-a5       * Restore registers
     1798
     1799gbpb7:          clr.w   d0                      | Set status = "Unchanged"
     1800
     1801gbpb8:          move.l  #dskmode,a1             | Update dskmode table
     1802                move.w  8(a6),a2                | ...
     1803                add.l   a2,a1                   | ...
     1804                move.b  d0,(a1)                 | ...
     1805                move.l  a5,d0                   | Setup to return bpb pointer
     1806
     1807gbpber:         tst.l   (a7)+                   | Pop garbage off top of stack
     1808                movem.l (a7)+,d6-d7/a4-a5       | Restore registers
    18091809                unlk    a6
    18101810                rts
    1811 *
    1812                 .page
    1813 *
    1814 * mediach -- check for media change
    1815 * -------    ----------------------
    1816 mediach:        link    a6,#0                   * Create scratch on stack
    1817                 movem.l d6-d7/a5,-(a7)          * Save registers on stack
    1818                 cmp.w   #2,8(a6)                * Check drive number
    1819                 blt     media1                  * Jump if OK
    1820 *
    1821                 moveq.l #ERR15,d0               * Error -- "unknown device"
    1822                 bra     media2                  * ...
    1823 *
    1824 media1:         move.w  8(a6),d7                * Get drive number in d7
    1825                 movea.w d7,a5                   * Point into dskmode table
    1826                 add.l   #dskmode,a5             * ...
    1827                 cmp.b   #2,(a5)                 * Definitely changed ?
    1828                 bne     media3                  * Jump if not
    1829 *
    1830                 moveq.l #2,d0                   * Setup to return "Changed"
    1831                 bra     media2                  * Done -- go return to caller
    1832 *
    1833 media3:         move.l  #wplatch,a0             * Check wplatch for drive
    1834                 tst.b   0(a0,d7)                * ...
    1835                 beq     media4                  * Jump if not set
    1836 *
    1837                 move.b  #1,(a5)                 * Set dskmode to "Uncertain"
    1838 *
    1839 media4:         move.l  _hz_200,d0              * Get time in d0
    1840                 movea.w d7,a1                   * Calculate acctim table address
    1841                 add.l   a1,a1                   * ... = drive # * 4
    1842                 add.l   a1,a1                   * ...
    1843                 add.l   #acctim,a1              * ... + acctim base address
    1844                 move.l  (a1),d1                 * Get acctim for drive
    1845                 sub.l   d1,d0                   * Subtract from current time
    1846                 cmp.l   maxactim,d0             * Timed out ?
    1847                 bge     media5                  * Jump if so
    1848 *
    1849                 clr.w   d0                      * Setup to return "Unchanged"
     1811
     1812                .page
     1813
     1814| mediach -- check for media change
     1815| -------    ----------------------
     1816mediach:        link    a6,#0                   | Create scratch on stack
     1817                movem.l d6-d7/a5,-(a7)          | Save registers on stack
     1818                cmp.w   #2,8(a6)                | Check drive number
     1819                blt     media1                  | Jump if OK
     1820
     1821                moveq.l #ERR15,d0               | Error -- "unknown device"
     1822                bra     media2                  | ...
     1823
     1824media1:         move.w  8(a6),d7                | Get drive number in d7
     1825                movea.w d7,a5                   | Point into dskmode table
     1826                add.l   #dskmode,a5             | ...
     1827                cmp.b   #2,(a5)                 | Definitely changed ?
     1828                bne     media3                  | Jump if not
     1829
     1830                moveq.l #2,d0                   | Setup to return "Changed"
     1831                bra     media2                  | Done -- go return to caller
     1832
     1833media3:         move.l  #wplatch,a0             | Check wplatch for drive
     1834                tst.b   0(a0,d7)                | ...
     1835                beq     media4                  | Jump if not set
     1836
     1837                move.b  #1,(a5)                 | Set dskmode to "Uncertain"
     1838
     1839media4:         move.l  _hz_200,d0              | Get time in d0
     1840                movea.w d7,a1                   | Calculate acctim table address
     1841                add.l   a1,a1                   | ... = drive # | 4
     1842                add.l   a1,a1                   | ...
     1843                add.l   #acctim,a1              | ... + acctim base address
     1844                move.l  (a1),d1                 | Get acctim for drive
     1845                sub.l   d1,d0                   | Subtract from current time
     1846                cmp.l   maxactim,d0             | Timed out ?
     1847                bge     media5                  | Jump if so
     1848
     1849                clr.w   d0                      | Setup to return "Unchanged"
    18501850                bra     media2
    1851 *
    1852 media5:         move.b  (a5),d0                 * Return status from dskmode
     1851
     1852media5:         move.b  (a5),d0                 | Return status from dskmode
    18531853                ext.w   d0
    1854 *
    1855 media2:         tst.l   (a7)+                   * Pop extra stack word
    1856                 movem.l (a7)+,d7/a5             * Restore registers
     1854
     1855media2:         tst.l   (a7)+                   | Pop extra stack word
     1856                movem.l (a7)+,d7/a5             | Restore registers
    18571857                unlk    a6
    1858                 rts                             * Return to caller
    1859 *
    1860                 .page
    1861 *
    1862 * rwabs -- read / write sector(s)
    1863 * -----    ----------------------
    1864 rwabs:          link    a6,#-4                  * Reserve stack for temps
    1865                 movem.l d4-d7/a5,-(a7)          * Save registers on stack
    1866                 cmp.w   #2,18(a6)               * Drive number
     1858                rts                             | Return to caller
     1859
     1860                .page
     1861
     1862| rwabs -- read / write sector(s)
     1863| -----    ----------------------
     1864rwabs:          link    a6,#-4                  | Reserve stack for temps
     1865                movem.l d4-d7/a5,-(a7)          | Save registers on stack
     1866                cmp.w   #2,18(a6)               | Drive number
    18671867                blt     rwabs1
    1868 *
    1869                 moveq.l #ERR15,d0               * ERROR -- "unknown device"
     1868
     1869                moveq.l #ERR15,d0               | ERROR -- "unknown device"
    18701870                bra     rwabser
    1871 *
    1872 rwabs1:         move.w  18(a6),d6               * Save drive number
    1873                 cmp.w   #2,8(a6)                * Check rwflag
     1871
     1872rwabs1:         move.w  18(a6),d6               | Save drive number
     1873                cmp.w   #2,8(a6)                | Check rwflag
    18741874                bge     rwabs7
    1875 *
     1875
    18761876                move.w  d6,d0
    18771877                asl.w   #5,d0
     
    18801880                add.l   #drvbpbs,a5
    18811881                move.w  d6,(a7)
    1882                 bsr     mediach                 * Test for media change
    1883                 move.w  d0,d7                   * Save status
    1884                 cmp.w   #2,d7                   * Disk changed ?
    1885                 bne     rwabs2                  * Jump if not
    1886 *
    1887                 moveq.l #ERR14,d0               * ERROR -- "media changed"
    1888                 bra     rwabser                 * ...
    1889 *
    1890 rwabs2:         cmp.w   #1,d7                   * Disk possibly changed ?
     1882                bsr     mediach                 | Test for media change
     1883                move.w  d0,d7                   | Save status
     1884                cmp.w   #2,d7                   | Disk changed ?
     1885                bne     rwabs2                  | Jump if not
     1886
     1887                moveq.l #ERR14,d0               | ERROR -- "media changed"
     1888                bra     rwabser                 | ...
     1889
     1890rwabs2:         cmp.w   #1,d7                   | Disk possibly changed ?
    18911891                bne     rwabs7
    1892 *
    1893 rwabs3:         move.w  #1,(a7)                 * floprd count = 1,
    1894                 clr.w   -(a7)                   * ... side = 0,
    1895                 clr.w   -(a7)                   * ... track = 0,
    1896                 move.w  #1,-(a7)                * ... sector = 1,
    1897                 move.w  d6,-(a7)                * ... drive number,
    1898                 clr.l   -(a7)                   * ... filler,
    1899                 move.l  #buffer,-(a7)           * ... buffer address,
    1900                 jsr     floprd                  * Read boot sector
    1901                 add.l   #16,a7                  * Cleanup stack
    1902                 move.l  d0,-4(a6)               * Save error number
    1903                 tst.l   -4(a6)                  * ... and test it
    1904                 bge     rwabs11                 * Jump if OK
    1905 *
    1906                 .page
    1907 *
     1892
     1893rwabs3:         move.w  #1,(a7)                 | floprd count = 1,
     1894                clr.w   -(a7)                   | ... side = 0,
     1895                clr.w   -(a7)                   | ... track = 0,
     1896                move.w  #1,-(a7)                | ... sector = 1,
     1897                move.w  d6,-(a7)                | ... drive number,
     1898                clr.l   -(a7)                   | ... filler,
     1899                move.l  #buffer,-(a7)           | ... buffer address,
     1900                jsr     floprd                  | Read boot sector
     1901                add.l   #16,a7                  | Cleanup stack
     1902                move.l  d0,-4(a6)               | Save error number
     1903                tst.l   -4(a6)                  | ... and test it
     1904                bge     rwabs11                 | Jump if OK
     1905
     1906                .page
     1907
    19081908                move.w  d6,(a7)
    19091909                move.l  -4(a6),d0
    19101910                move.w  d0,-(a7)
    1911                 jsr     criter                  * Call critical error code
    1912                 addq.l  #2,a7                   * Cleanup stack
     1911                jsr     criter                  | Call critical error code
     1912                addq.l  #2,a7                   | Cleanup stack
    19131913                move.l  d0,-4(a6)
    1914 *
     1914
    19151915rwabs11:        move.l  -4(a6),d0
    19161916                cmp.l   #RETRYIT,d0
    1917                 beq     rwabs3                  * Read again
    1918 *
    1919                 tst.l   -4(a6)                  * Test error number
    1920                 bge     rwabs4                  * OK ?
    1921 *
     1917                beq     rwabs3                  | Read again
     1918
     1919                tst.l   -4(a6)                  | Test error number
     1920                bge     rwabs4                  | OK ?
     1921
    19221922                move.l  -4(a6),d0
    1923                 bra     rwabser                 * ERROR
    1924 *
    1925 rwabs4:         clr.w   d7                      * Clear media change status
     1923                bra     rwabser                 | ERROR
     1924
     1925rwabs4:         clr.w   d7                      | Clear media change status
    19261926                bra     rwabs10
    1927 *
    1928 rwabs6:         move.l  #buffer,a0              * Address of sector buffer to a0
    1929                 move.b  8(a0,d7),d0             * Serial number
     1927
     1928rwabs6:         move.l  #buffer,a0              | Address of sector buffer to a0
     1929                move.b  8(a0,d7),d0             | Serial number
    19301930                ext.w   d0
    1931                 move.b  28(a5,d7),d1            * Compare to old one
     1931                move.b  28(a5,d7),d1            | Compare to old one
    19321932                ext.w   d1
    19331933                cmp.w   d1,d0
    1934                 beq     rwabs5                  * Jump if they're the same
    1935 *
    1936                 moveq.l #ERR14,d0               * ERROR -- "media changed"
     1934                beq     rwabs5                  | Jump if they're the same
     1935
     1936                moveq.l #ERR14,d0               | ERROR -- "media changed"
    19371937                bra     rwabser
    1938 *
    1939 rwabs5:         addq.w  #1,d7                   * Next byte of serial number
    1940 *
    1941 rwabs10:        cmp.w   #3,d7                   * All 3 bytes checked ?
    1942                 blt     rwabs6                  * Loop if not
    1943 *
    1944                 .page
    1945 *
    1946                 move.w  d6,a0                   * Point at wplatch for drive
    1947                 add.l   #wplatch,a0             * ...
    1948                 move.w  d6,a1                   * Point at wpstatus for drive
    1949                 add.l   #wpstatus,a1            * ...
    1950                 move.b  (a1),(a0)               * Move wpstatus to wplatch
    1951                 bne     rwabs9                  * Jump if set
    1952 *
    1953                 move.w  d6,a0                   * Set dskmode to "Unchanged"
    1954                 add.l   #dskmode,a0             * ...
    1955                 clr.b   (a0)                    * ...
    1956 *
    1957 rwabs7:         tst.w   nflops                  * Test nflops
     1938
     1939rwabs5:         addq.w  #1,d7                   | Next byte of serial number
     1940
     1941rwabs10:        cmp.w   #3,d7                   | All 3 bytes checked ?
     1942                blt     rwabs6                  | Loop if not
     1943
     1944                .page
     1945
     1946                move.w  d6,a0                   | Point at wplatch for drive
     1947                add.l   #wplatch,a0             | ...
     1948                move.w  d6,a1                   | Point at wpstatus for drive
     1949                add.l   #wpstatus,a1            | ...
     1950                move.b  (a1),(a0)               | Move wpstatus to wplatch
     1951                bne     rwabs9                  | Jump if set
     1952
     1953                move.w  d6,a0                   | Set dskmode to "Unchanged"
     1954                add.l   #dskmode,a0             | ...
     1955                clr.b   (a0)                    | ...
     1956
     1957rwabs7:         tst.w   nflops                  | Test nflops
    19581958                bne     rwabs8
    1959 *
    1960                 moveq.l #ERR02,d0               * ERROR -- "drive not ready"
     1959
     1960                moveq.l #ERR02,d0               | ERROR -- "drive not ready"
    19611961                bra     rwabser
    1962 *
    1963 rwabs8:         cmp.w   #1,8(a6)                * Check rwflag
     1962
     1963rwabs8:         cmp.w   #1,8(a6)                | Check rwflag
    19641964                ble     rwabs9
    1965 *
    1966                 subq.w  #2,8(a6)                * Adjust to 0|1
    1967 *
    1968 rwabs9:         move.w  14(a6),(a7)             * Setup count,
    1969                 move.w  d6,-(a7)                * ... drive,
    1970                 move.w  16(a6),-(a7)            * ... recno,
    1971                 move.l  10(a6),-(a7)            * ... buffer,
    1972                 move.w  8(a6),-(a7)             * ... rwflag
    1973                 bsr     floprw                  * Call floprw
    1974 *
    1975                 add.l   #10,a7                  * Cleanup stack
    1976 *
    1977 rwabser:        tst.l   (a7)+                   * Pop stack scratch
    1978                 movem.l (a7)+,d5-d7/a5          * Restore registers
    1979                 unlk    a6                      * Release temporaries
    1980                 rts                             * Return to caller
    1981 *
    1982                 .page
    1983 *
    1984 * floprw -- Floppy read / write driver
    1985 * ------    --------------------------
    1986 floprw:         link    a6,#-6                  * Reserve space for temps
    1987                 movem.l d2-d7/a5,-(a7)          * Save registers
    1988                 move.w  16(a6),d0               * Drive number to d0
    1989                 asl.w   #5,d0                   * Shift ( *32 )
    1990                 ext.l   d0                      * Sign extend it, too
    1991                 move.l  d0,a5                   * Result in a5
    1992                 add.l   #drvbpbs,a5             * Add base of BPB table
    1993                 btst    #0,13(a6)               * Buffer address even ?
    1994                 bne     floprw01                * Jump if not
    1995 *
    1996                 clr.w   d0                      * Clear odd flag
    1997                 bra     floprw02                * Go save the flag
    1998 *
    1999 floprw01:       moveq.l #1,d0                   * Set odd flag
    2000 *
    2001 floprw02:       move.w  d0,-2(a6)               * Save it
    2002                 tst.w   22(a5)                  * dspc set ?
    2003                 bne     floprw20                * Jump if so
    2004 *
    2005                 moveq.l #9,d0                   * Assume 9
    2006                 move.w  d0,22(a5)               * ... and make it the default
    2007                 move.w  d0,24(a5)               * ... for dspt and dspc
    2008 *
     1965
     1966                subq.w  #2,8(a6)                | Adjust to 0|1
     1967
     1968rwabs9:         move.w  14(a6),(a7)             | Setup count,
     1969                move.w  d6,-(a7)                | ... drive,
     1970                move.w  16(a6),-(a7)            | ... recno,
     1971                move.l  10(a6),-(a7)            | ... buffer,
     1972                move.w  8(a6),-(a7)             | ... rwflag
     1973                bsr     floprw                  | Call floprw
     1974
     1975                add.l   #10,a7                  | Cleanup stack
     1976
     1977rwabser:        tst.l   (a7)+                   | Pop stack scratch
     1978                movem.l (a7)+,d5-d7/a5          | Restore registers
     1979                unlk    a6                      | Release temporaries
     1980                rts                             | Return to caller
     1981
     1982                .page
     1983
     1984| floprw -- Floppy read / write driver
     1985| ------    --------------------------
     1986floprw:         link    a6,#-6                  | Reserve space for temps
     1987                movem.l d2-d7/a5,-(a7)          | Save registers
     1988                move.w  16(a6),d0               | Drive number to d0
     1989                asl.w   #5,d0                   | Shift ( |32 )
     1990                ext.l   d0                      | Sign extend it, too
     1991                move.l  d0,a5                   | Result in a5
     1992                add.l   #drvbpbs,a5             | Add base of BPB table
     1993                btst    #0,13(a6)               | Buffer address even ?
     1994                bne     floprw01                | Jump if not
     1995
     1996                clr.w   d0                      | Clear odd flag
     1997                bra     floprw02                | Go save the flag
     1998
     1999floprw01:       moveq.l #1,d0                   | Set odd flag
     2000
     2001floprw02:       move.w  d0,-2(a6)               | Save it
     2002                tst.w   22(a5)                  | dspc set ?
     2003                bne     floprw20                | Jump if so
     2004
     2005                moveq.l #9,d0                   | Assume 9
     2006                move.w  d0,22(a5)               | ... and make it the default
     2007                move.w  d0,24(a5)               | ... for dspt and dspc
     2008
    20092009floprw20:       bra     floprw18
    2010 *
    2011 floprw03:       tst.w   -2(a6)                  * Is odd flag set ?
    2012                 beq     floprw04                * Jump if not
    2013 *
    2014                 move.l  #buffer,d0              * Point to sector buffer
     2010
     2011floprw03:       tst.w   -2(a6)                  | Is odd flag set ?
     2012                beq     floprw04                | Jump if not
     2013
     2014                move.l  #buffer,d0              | Point to sector buffer
    20152015                bra     floprw05
    2016 *
    2017 floprw04:       move.l  10(a6),d0               * Get buffer address
    2018 *
    2019 floprw05:       move.l  d0,-6(a6)               * ... and save
    2020                 move.w  14(a6),d6               * Get recno  (lsn)
    2021                 ext.l   d6                      * Extend it to long
    2022                 divs.w  22(a5),d6               * Divide by dspc for track #
    2023                 move.w  14(a6),d4               * Get recno
    2024                 ext.l   d4                      * Extend to long
    2025                 divs.w  22(a5),d4               * Divide by dspc
    2026                 swap    d4                      * Use remainder as sector number
    2027                 cmp.w   24(a5),d4               * Compare with dspt
    2028                 bge     floprw06                * Greater than or equal ?
    2029 *
    2030                 clr.l   d5                      * Use side 0
     2016
     2017floprw04:       move.l  10(a6),d0               | Get buffer address
     2018
     2019floprw05:       move.l  d0,-6(a6)               | ... and save
     2020                move.w  14(a6),d6               | Get recno  (lsn)
     2021                ext.l   d6                      | Extend it to long
     2022                divs.w  22(a5),d6               | Divide by dspc for track #
     2023                move.w  14(a6),d4               | Get recno
     2024                ext.l   d4                      | Extend to long
     2025                divs.w  22(a5),d4               | Divide by dspc
     2026                swap    d4                      | Use remainder as sector number
     2027                cmp.w   24(a5),d4               | Compare with dspt
     2028                bge     floprw06                | Greater than or equal ?
     2029
     2030                clr.l   d5                      | Use side 0
    20312031                bra     floprw07
    2032 *
    2033 floprw06:       moveq.l #1,d5                   * Use side 1
    2034                 sub.w   24(a5),d4               * Subtract dspt from sector #
    2035 *
    2036                 .page
    2037 *
    2038 floprw07:       tst.w   -2(a6)                  * Is odd flag set ?
    2039                 beq     floprw08                * Jump if not
    2040 *
    2041                 moveq.l #1,d3                   * Set counter to 1
     2032
     2033floprw06:       moveq.l #1,d5                   | Use side 1
     2034                sub.w   24(a5),d4               | Subtract dspt from sector #
     2035
     2036                .page
     2037
     2038floprw07:       tst.w   -2(a6)                  | Is odd flag set ?
     2039                beq     floprw08                | Jump if not
     2040
     2041                moveq.l #1,d3                   | Set counter to 1
    20422042                bra     floprw10
    2043 *
    2044 floprw08:       move.w  24(a5),d0               * Get dspt
    2045                 sub.w   d4,d0                   * Subtract sector number
    2046                 cmp.w   18(a6),d0               * Compare with number of sectors
    2047                 bge     floprw09                * Jump if greater than or eq to
    2048 *
    2049                 move.w  24(a5),d3               * Get dspt
    2050                 sub.w   d4,d3                   * Subtract sector number
     2043
     2044floprw08:       move.w  24(a5),d0               | Get dspt
     2045                sub.w   d4,d0                   | Subtract sector number
     2046                cmp.w   18(a6),d0               | Compare with number of sectors
     2047                bge     floprw09                | Jump if greater than or eq to
     2048
     2049                move.w  24(a5),d3               | Get dspt
     2050                sub.w   d4,d3                   | Subtract sector number
    20512051                bra     floprw10
    2052 *
    2053 floprw09:       move.w  18(a6),d3               * Count = number of sectors
    2054 *
    2055 floprw10:       addq.w  #1,d4                   * Adjust sector number (1 org)
    2056 *
    2057 floprw11:       tst.w   8(a6)                   * Test r/w flag
    2058                 beq     floprw14                * Jump if it's a read
    2059 *
    2060                 move.l  -6(a6),d0               * Get buffer pointer
    2061                 cmp.l   10(a6),d0               * See if it's = buffer addr
    2062                 beq     floprw12                * Jump if so
    2063 *
    2064                 move.l  -6(a6),(a7)             * Get source address
    2065                 move.l  10(a6),-(a7)            * Destination address
    2066                 jsr     fastcopy                * Copy the sector
    2067                 addq.l  #4,a7                   * Cleanup stack
    2068 *
    2069 floprw12:       move.w  d3,(a7)                 * Number of sectors
    2070                 move.w  d5,-(a7)                * Side number
    2071                 move.w  d6,-(a7)                * Track number
    2072                 move.w  d4,-(a7)                * Sector number
    2073                 move.w  16(a6),-(a7)            * Drive number
    2074                 clr.l   -(a7)                   * Filler
    2075                 move.l  -6(a6),-(a7)            * Buffer address
    2076                 jsr     flopwr                  * Write sector
    2077                 add.l   #16,a7                  * Cleaup stack
    2078                 move.l  d0,d7                   * Save error code in d7
    2079                 tst.l   d7                      * Errors ?
    2080                 bne     floprw13                * Jump if so
    2081 *
    2082                 .page
    2083 *
    2084                 tst.w   fverify                 * Verify after write ?
    2085                 beq     floprw13                * Jump if not
    2086 *
    2087                 move.w  d3,(a7)                 * Number of sectors
    2088                 move.w  d5,-(a7)                * Side number
    2089                 move.w  d6,-(a7)                * Track number
    2090                 move.w  d4,-(a7)                * Sector number
    2091                 move.w  16(a6),-(a7)            * Drive number
    2092                 clr.l   -(a7)                   * Filler
    2093                 move.l  #buffer,-(a7)           * Buffer address
    2094                 jsr     flopver                 * Verify sector(s)
    2095                 add.l   #16,a7                  * Cleanup stack
    2096                 move.l  d0,d7                   * Save error code in d7
    2097                 tst.l   d7                      * Errors ?
    2098                 bne     floprw13                * Jump if so
    2099 *
    2100                 move.l  #buffer,(a7)            * Address of sector buffer
    2101                 bsr     itom                    * Convert first word of buffer
    2102                 tst.w   d0                      * Bad sectors ?
    2103                 beq     floprw13                * Jump if not
    2104 *
    2105                 moveq.l #ERR16,d7               * ERROR -- "Bad sectors"
    2106 *
     2052
     2053floprw09:       move.w  18(a6),d3               | Count = number of sectors
     2054
     2055floprw10:       addq.w  #1,d4                   | Adjust sector number (1 org)
     2056
     2057floprw11:       tst.w   8(a6)                   | Test r/w flag
     2058                beq     floprw14                | Jump if it's a read
     2059
     2060                move.l  -6(a6),d0               | Get buffer pointer
     2061                cmp.l   10(a6),d0               | See if it's = buffer addr
     2062                beq     floprw12                | Jump if so
     2063
     2064                move.l  -6(a6),(a7)             | Get source address
     2065                move.l  10(a6),-(a7)            | Destination address
     2066                jsr     fastcopy                | Copy the sector
     2067                addq.l  #4,a7                   | Cleanup stack
     2068
     2069floprw12:       move.w  d3,(a7)                 | Number of sectors
     2070                move.w  d5,-(a7)                | Side number
     2071                move.w  d6,-(a7)                | Track number
     2072                move.w  d4,-(a7)                | Sector number
     2073                move.w  16(a6),-(a7)            | Drive number
     2074                clr.l   -(a7)                   | Filler
     2075                move.l  -6(a6),-(a7)            | Buffer address
     2076                jsr     flopwr                  | Write sector
     2077                add.l   #16,a7                  | Cleaup stack
     2078                move.l  d0,d7                   | Save error code in d7
     2079                tst.l   d7                      | Errors ?
     2080                bne     floprw13                | Jump if so
     2081
     2082                .page
     2083
     2084                tst.w   fverify                 | Verify after write ?
     2085                beq     floprw13                | Jump if not
     2086
     2087                move.w  d3,(a7)                 | Number of sectors
     2088                move.w  d5,-(a7)                | Side number
     2089                move.w  d6,-(a7)                | Track number
     2090                move.w  d4,-(a7)                | Sector number
     2091                move.w  16(a6),-(a7)            | Drive number
     2092                clr.l   -(a7)                   | Filler
     2093                move.l  #buffer,-(a7)           | Buffer address
     2094                jsr     flopver                 | Verify sector(s)
     2095                add.l   #16,a7                  | Cleanup stack
     2096                move.l  d0,d7                   | Save error code in d7
     2097                tst.l   d7                      | Errors ?
     2098                bne     floprw13                | Jump if so
     2099
     2100                move.l  #buffer,(a7)            | Address of sector buffer
     2101                bsr     itom                    | Convert first word of buffer
     2102                tst.w   d0                      | Bad sectors ?
     2103                beq     floprw13                | Jump if not
     2104
     2105                moveq.l #ERR16,d7               | ERROR -- "Bad sectors"
     2106
    21072107floprw13:       bra     floprw15
    2108 *
    2109                 .page
    2110 *
    2111 floprw14:       move.w  d3,(a7)                 * Number of sectors
    2112                 move.w  d5,-(a7)                * Side number
    2113                 move.w  d6,-(a7)                * Track number
    2114                 move.w  d4,-(a7)                * Sector number
    2115                 move.w  16(a6),-(a7)            * Drive number
    2116                 clr.l   -(a7)                   * Filler
    2117                 move.l  -6(a6),-(a7)            * Sector buffer
    2118                 jsr     floprd                  * Read floppy sector(s)
    2119                 add.l   #16,a7                  * Cleanup stack
    2120                 move.l  d0,d7                   * Save error code in d7
    2121                 move.l  -6(a6),d0               * User buffer address
    2122                 cmp.l   10(a6),d0               * Is it the desired buffer ?
    2123                 beq     floprw15                * Jump if so
    2124 *
    2125                 move.l  10(a6),(a7)             * Push source address
    2126                 move.l  -6(a6),-(a7)            * Push destination address
    2127                 jsr     fastcopy                * Copy the sector
    2128                 addq.l  #4,a7                   * Cleanup stack
    2129 *
    2130 floprw15:       tst.l   d7                      * Error code set ?
    2131                 bge     floprw16                * Jump if not
    2132 *
    2133                 move.w  16(a6),(a7)             * Push drive number
    2134                 move.l  d7,d0                   * Error code
    2135                 move.w  d0,-(a7)                * ... onto stack
    2136                 jsr     criter                  * Call critical error handler
    2137                 addq.l  #2,a7                   * Cleanup stack
    2138                 move.l  d0,d7                   * Get error code
    2139 *
    2140 floprw16:       cmp.l   #RETRYIT,d7             * Re-try ?
    2141                 beq     floprw11                * Jump if so
    2142 *
    2143                 tst.l   d7                      * Check error code
    2144                 bge     floprw17                * Jump if no error
    2145 *
    2146                 move.l  d7,d0                   * Error code is the result
     2108
     2109                .page
     2110
     2111floprw14:       move.w  d3,(a7)                 | Number of sectors
     2112                move.w  d5,-(a7)                | Side number
     2113                move.w  d6,-(a7)                | Track number
     2114                move.w  d4,-(a7)                | Sector number
     2115                move.w  16(a6),-(a7)            | Drive number
     2116                clr.l   -(a7)                   | Filler
     2117                move.l  -6(a6),-(a7)            | Sector buffer
     2118                jsr     floprd                  | Read floppy sector(s)
     2119                add.l   #16,a7                  | Cleanup stack
     2120                move.l  d0,d7                   | Save error code in d7
     2121                move.l  -6(a6),d0               | User buffer address
     2122                cmp.l   10(a6),d0               | Is it the desired buffer ?
     2123                beq     floprw15                | Jump if so
     2124
     2125                move.l  10(a6),(a7)             | Push source address
     2126                move.l  -6(a6),-(a7)            | Push destination address
     2127                jsr     fastcopy                | Copy the sector
     2128                addq.l  #4,a7                   | Cleanup stack
     2129
     2130floprw15:       tst.l   d7                      | Error code set ?
     2131                bge     floprw16                | Jump if not
     2132
     2133                move.w  16(a6),(a7)             | Push drive number
     2134                move.l  d7,d0                   | Error code
     2135                move.w  d0,-(a7)                | ... onto stack
     2136                jsr     criter                  | Call critical error handler
     2137                addq.l  #2,a7                   | Cleanup stack
     2138                move.l  d0,d7                   | Get error code
     2139
     2140floprw16:       cmp.l   #RETRYIT,d7             | Re-try ?
     2141                beq     floprw11                | Jump if so
     2142
     2143                tst.l   d7                      | Check error code
     2144                bge     floprw17                | Jump if no error
     2145
     2146                move.l  d7,d0                   | Error code is the result
    21472147                bra     floprw19
    2148 *
    2149                 .page
    2150 *
    2151 floprw17:       move.w  d3,d0                   * Sector counter to d0
    2152                 ext.l   d0                      * Sign extend
    2153                 moveq.l #9,d1                   * Times 512
    2154                 asl.l   d1,d0                   * ...
    2155                 add.l   d0,10(a6)               * Update buffer address
    2156                 add.w   d3,14(a6)               * Update sector number
    2157                 sub.w   d3,18(a6)               * Update sector count
    2158 *
    2159 floprw18:       tst.w   18(a6)                  * More sectors ?
    2160                 bne     floprw03                * Jump if so
    2161 *
    2162                 clr.l   d0                      * Set "no error" as result
    2163 *
    2164 floprw19:       tst.l   (a7)+                   * Test top of stack
    2165                 movem.l (a7)+,d3-d7/a5          * Restore registers
    2166                 unlk    a6                      * Release stack space
    2167                 rts                             * Return to caller
    2168 *
    2169                 .page
    2170 *
    2171 * itom -- Convert 8086 integer format to 680000 integer format
    2172 * ----    ----------------------------------------------------
    2173 itom:           link    a6,#-4                  * Reserve stack for temps
    2174                 move.l  8(a6),a0                * Address of the number to a0
    2175                 move.b  1(a0),d0                * Get high byte
    2176                 ext.w   d0                      * Make it a word
    2177                 and.w   #$FF,d0                 * Isolate bits 0..7
    2178                 asl.w   #8,d0                   * Shift in bits 8..15
    2179                 move.l  8(a6),a1                * Address of the number to a1
    2180                 move.b  (a1),d1                 * Get low byte
    2181                 ext.w   d1                      * Extend to word
    2182                 and.w   #$FF,d1                 * Isolate bits 0..7
    2183                 or.w    d1,d0                   * Combine with bits 8..15
    2184                 unlk    a6                      * Release stack space
    2185                 rts                             * Return to caller
    2186 *
    2187                 .page
    2188 *
    2189 * flopini -- Initialize floppy drive
    2190 * -------    -----------------------
    2191 flopini:        lea     dsb0,a1                 * Point to dsb for drive A
    2192                 tst.w   12(a7)                  * Drive A wanted ?
    2193                 beq     flopin01                * Jump if so
    2194 *
    2195                 lea     dsb1,a1                 * Drive B dsb address to a1
    2196 *
    2197 flopin01:       move.w  seekrate,2(a1)          * Get seek rate
    2198                 moveq.l #ERR01,d0               * Set default error number
    2199                 clr.w   0(a1)                   * Set track number to 0
    2200                 bsr     floplock                * Setup floppy parameters
    2201                 bsr     select                  * Select drive and side
    2202                 move.w  #$FF00,0(a1)
    2203                 bsr     restore                 * Restore the drive
     2148
     2149                .page
     2150
     2151floprw17:       move.w  d3,d0                   | Sector counter to d0
     2152                ext.l   d0                      | Sign extend
     2153                moveq.l #9,d1                   | Times 512
     2154                asl.l   d1,d0                   | ...
     2155                add.l   d0,10(a6)               | Update buffer address
     2156                add.w   d3,14(a6)               | Update sector number
     2157                sub.w   d3,18(a6)               | Update sector count
     2158
     2159floprw18:       tst.w   18(a6)                  | More sectors ?
     2160                bne     floprw03                | Jump if so
     2161
     2162                clr.l   d0                      | Set "no error" as result
     2163
     2164floprw19:       tst.l   (a7)+                   | Test top of stack
     2165                movem.l (a7)+,d3-d7/a5          | Restore registers
     2166                unlk    a6                      | Release stack space
     2167                rts                             | Return to caller
     2168
     2169                .page
     2170
     2171| itom -- Convert 8086 integer format to 680000 integer format
     2172| ----    ----------------------------------------------------
     2173itom:           link    a6,#-4                  | Reserve stack for temps
     2174                move.l  8(a6),a0                | Address of the number to a0
     2175                move.b  1(a0),d0                | Get high byte
     2176                ext.w   d0                      | Make it a word
     2177                and.w   #0xFF,d0                | Isolate bits 0..7
     2178                asl.w   #8,d0                   | Shift in bits 8..15
     2179                move.l  8(a6),a1                | Address of the number to a1
     2180                move.b  (a1),d1                 | Get low byte
     2181                ext.w   d1                      | Extend to word
     2182                and.w   #0xFF,d1                | Isolate bits 0..7
     2183                or.w    d1,d0                   | Combine with bits 8..15
     2184                unlk    a6                      | Release stack space
     2185                rts                             | Return to caller
     2186
     2187                .page
     2188
     2189| flopini -- Initialize floppy drive
     2190| -------    -----------------------
     2191flopini:        lea     dsb0,a1                 | Point to dsb for drive A
     2192                tst.w   12(a7)                  | Drive A wanted ?
     2193                beq     flopin01                | Jump if so
     2194
     2195                lea     dsb1,a1                 | Drive B dsb address to a1
     2196
     2197flopin01:       move.w  seekrate,2(a1)          | Get seek rate
     2198                moveq.l #ERR01,d0               | Set default error number
     2199                clr.w   0(a1)                   | Set track number to 0
     2200                bsr     floplock                | Setup floppy parameters
     2201                bsr     select                  | Select drive and side
     2202                move.w  #0xFF00,0(a1)
     2203                bsr     restore                 | Restore the drive
    22042204                moveq.l #6,d7
    22052205                bsr     hseek1
    22062206                bne     flopin02
    2207 *
    2208                 bsr     restore                 * Restore the drive
    2209                 beq     flopok                  * Jump if no error
    2210 *
    2211 flopin02:       bra     flopfail                * Jump to error handler
    2212 *
    2213                 .page
    2214 *
    2215 * floprd -- Read floppy
    2216 * ------    -----------
    2217 floprd:         bsr     change                  * Disk changed ?
    2218                 moveq.l #ERR11,d0               * Set to "read error"
    2219                 bsr     floplock                * Set parameters
    2220 *
    2221 floprd01:       bsr     select                  * Select drive and side
    2222                 bsr     go2track                * Position on track
    2223                 bne     floprd02                * Try again on error
    2224 *
    2225                 move.w  #ERR01,deferr           * Set default error
    2226                 move.l  edma(a5),a0             * Get final DMA address
    2227                 move.l  cdma(a5),a2             * Get first DMA address
    2228                 move.l  #$40000,d7              * Set timeout counter
    2229                 move.b  #FL_RM,DSKCMD(a6)       * Start readng the disk
    2230 *
    2231 floprd03:       btst    #0,DSKCMD(a6)           * Disk busy yet ?
    2232                 bne     floprd05                * Jump if so
    2233 *
    2234                 subq.l  #1,d7                   * Decrement timeout counter
    2235                 beq     floprd04                * Jump if timed out
    2236 *
    2237                 bra     floprd03                * Go try for busy again
    2238 *
    2239 floprd05:       move.l  #$40000,d7              * Reset timeout counter
    2240                 bra     floprd09                * Go join main read loop
    2241 *
    2242 floprd07:       subq.l  #1,d7                   * Decrement timeout counter
    2243                 beq     floprd04                * Jump if timed out
    2244 *
    2245                 btst    #0,DSKCMD(a6)           * Done yet ?
    2246                 beq     floprd08                * Jump if so
    2247 *
    2248 floprd09:       btst    #1,DSKCMD(a6)           * DRQ set ?
    2249                 beq     floprd07                * Jump if not
    2250 *
    2251                 move.b  DSKDAT(a6),(a2)+        * Read the byte into the buffer
    2252                 cmp.l   a0,a2                   * Done reading ?
    2253                 bne     floprd07                * Jump if not
    2254 *
    2255                 .page
    2256 *
    2257 floprd08:       move.b  DSKCMD(a6),d0           * Read final status into d0
    2258                 and.b   #$1C,d0                 * Mask for error bits
    2259                 beq     flopok                  * Jump if no errors
    2260 *
    2261                 bsr     errbits                 * Determine error code
    2262 *
    2263 floprd02:       cmp.w   #1,retrycnt(a5)         * Re-try ?
    2264                 bne     floprd06                * Jump if not
    2265 *
    2266                 bsr     reseek                  * Home and repeat the seek
    2267 *
    2268 floprd06:       subq.w  #1,retrycnt(a5)         * Update re-try count
    2269                 bpl     floprd01                * Re-try if count still >0
    2270 *
    2271                 bra     flopfail                * Failure
    2272 *
    2273 floprd04:       move.w  #ERR02,curerr(a5)       * Set error code "not ready"
    2274                 bsr     rs1772                  * Reset the WD1772
    2275                 bra     floprd02                * See if it can be retried
    2276 *
    2277                 .page
    2278 *
    2279 * errbits -- Develop error code for floppy I/O error
    2280 * -------    ---------------------------------------
    2281 errbits:        moveq.l #ERR13,d1               * Write protect ?
    2282                 btst    #6,d0                   * ...
    2283                 bne     errbits1                * Jump if so
    2284 *
    2285                 moveq.l #ERR08,d1               * Record not found ?
    2286                 btst    #4,d0                   * ...
    2287                 bne     errbits1                * Jump if so
    2288 *
    2289                 moveq.l #ERR04,d1               * CRC error ?
    2290                 btst    #3,d0                   * ...
    2291                 bne     errbits1                * Jump if so
    2292 *
    2293                 moveq.l #ERR12,d1               * Lost data ?
    2294                 btst    #2,d0                   * ...
    2295                 bne     errbits1                * Jump if so
    2296 *
    2297                 move.w  deferr(a5),d1           * Use default error
    2298 *
    2299 errbits1:       move.w  d1,curerr(a5)           * ... as curerr
    2300                 rts                             * Return to caller
    2301 *
    2302                 .page
    2303 *
    2304 * flopwr -- Floppy write
    2305 * ------    ------------
    2306 flopwr:         bsr     change                  * Check for disk change
    2307                 moveq.l #ERR10,d0               * Set write error
    2308                 bsr     floplock                * Set parameters
    2309                 move.w  csect(a5),d0            * Get sector number in d0
    2310                 subq.w  #1,d0                   * ... -1
    2311                 or.w    ctrack(a5),d0           * OR with track number
    2312                 or.w    cside(a5),d0            * OR with side number
    2313                 bne     flopwr01                * Jump if not boot sector
    2314 *
    2315                 moveq.l #2,d0                   * Media change
    2316                 bsr     setdmode                * Set to "unsure"
    2317 *
    2318 flopwr01:       bsr     select                  * Select drive and side
    2319                 bsr     go2track                * Seek
    2320                 bne     flopwr06                * Re-try on error
    2321 *
    2322 flopwr02:       move.w  #ERR01,curerr(a5)       * Set for default error
    2323                 move.l  cdma(a5),a2             * Get I/O address
    2324                 move.l  #$40000,d7              * Set timeout counter
    2325                 move.w  ctrack(a5),d0           * Get track number
    2326                 cmpi.w  #40,d0                  * See if we need precomp
    2327                 bcs     flopwr10                * Jump if not
    2328 *
    2329                 move.b  #FL_WS,DSKCMD(a6)       * Write with precomp
    2330                 bra     flopwr08                * Go join main write loop
    2331 *
    2332 flopwr10:       move.b  #FL_WS+FL_NC,DSKCMD(a6) * Write  (no precomp)
    2333 *
    2334                 .page
    2335 *
    2336 flopwr08:       btst    #0,DSKCMD(a6)           * Busy yet ?
    2337                 bne     flopwr09                * Jump if so
    2338 *
    2339                 subq.l  #1,d7                   * Decrement tiemout count
    2340                 bne     flopwr08                * Jump if not timed out
    2341 *
    2342 flopwr13:       bsr     rs1772                  * Reset WD1772
    2343                 bra     flopwr05                * See if we can retry
    2344 *
    2345 flopwr11:       btst    #0,DSKCMD(a6)           * Done ?
    2346                 beq     flopwr04                * Jump if so
    2347 *
    2348 flopwr09:       btst    #1,DSKCMD(a6)           * DRQ set ?
    2349                 bne     flopwr12                * Jump if so
    2350 *
    2351                 subq.l  #1,d7                   * Decrement timeout counter
    2352                 beq     flopwr13                * Jump if timed out
    2353 *
    2354                 bra     flopwr11                * Jump if not
    2355 *
    2356 flopwr12:       move.b  (a2)+,DSKDAT(a6)        * Write byte to floppy
    2357                 bra     flopwr11                * Go get the next one
    2358 *
    2359                 .page
    2360 *
    2361 flopwr04:       move.b  DSKCMD(a6),d0           * Get floppy status
    2362                 bsr     errbits                 * Set error code
    2363                 btst    #6,d0                   * Write protect error ?
    2364                 bne     flopfail                * Fail if so
    2365 *
    2366                 and.b   #$5C,d0                 * Mask error bits
    2367                 bne     flopwr05                * Jump if an error occurred
    2368 *
    2369                 addq.w  #1,csect(a5)            * Update sector number
    2370                 add.l   #512,cdma(a5)           * Update DMA address
    2371                 subq.w  #1,ccount(a5)           * Decrement sector count
    2372                 beq     flopok                  * Jump if zero -- done
    2373 *
    2374                 bsr     select1                 * Set sector and DMA pointer
    2375                 bra     flopwr02                * Write next sector
    2376 *
    2377 flopwr05:       cmp.w   #1,retrycnt(a5)         * Second re-try ?
    2378                 bne     flopwr07                * Jump if not
    2379 *
    2380 flopwr06:       bsr     reseek                  * Restore and re-seek
    2381 *
    2382 flopwr07:       subq.w  #1,retrycnt(a5)         * Update re-try count
    2383                 bpl     flopwr01                * Re-try if still >0
    2384 *
    2385                 bra     flopfail                * ... else fail
    2386 *
    2387                 .page
    2388 *
    2389 * flopfmt -- Format a track on the floppy
    2390 * -------    ----------------------------
    2391 flopfmt:        cmp.l   #FMAGIC,22(a7)          * Is the magic right ?
    2392                 bne     flopfail                * Fail immediately if not
    2393 *
    2394                 bsr     change                  * Check for disk change
    2395                 moveq.l #ERR01,d0               * Set default error number
    2396                 bsr     floplock                * Set parameters
    2397                 bsr     select                  * Select drive and side
    2398                 move.w  14(a7),spt(a5)          * Set sectors per track,
    2399                 move.w  20(a7),interlv(a5)      * ... interleave,
    2400                 move.w  26(a7),virgin(a5)       * ... initial data,
    2401                 moveq.l #2,d0                   * Disk changed
    2402                 bsr     setdmode                * ...
    2403                 bsr     hseek                   * Seek
    2404                 bne     flopfail                * Fail if seek error occurs
    2405 *
    2406                 move.w  ctrack(a5),0(a1)        * Current track to DSB
    2407                 move.w  #ERR01,curerr(a5)       * Default to curerr
    2408                 bsr     fmtrack                 * Format the track
    2409                 bne     flopfail                * Fail if error occurs
    2410 *
    2411                 move.w  spt(a5),ccount(a5)      * Use spt as ccount
    2412                 move.w  #1,csect(a5)            * Start with sector 1
    2413                 bsr     verify1                 * Verify the sector
    2414                 move.l  cdma(a5),a2             * Get bad sector list
    2415                 tst.w   (a2)                    * Any bad ones ?
    2416                 beq     flopok                  * Jump if not
    2417 *
    2418                 move.w  #ERR16,curerr(a5)       * ERROR -- "bad sectors"
     2207
     2208                bsr     restore                 | Restore the drive
     2209                beq     flopok                  | Jump if no error
     2210
     2211flopin02:       bra     flopfail                | Jump to error handler
     2212
     2213                .page
     2214
     2215| floprd -- Read floppy
     2216| ------    -----------
     2217floprd:         bsr     change                  | Disk changed ?
     2218                moveq.l #ERR11,d0               | Set to "read error"
     2219                bsr     floplock                | Set parameters
     2220
     2221floprd01:       bsr     select                  | Select drive and side
     2222                bsr     go2track                | Position on track
     2223                bne     floprd02                | Try again on error
     2224
     2225                move.w  #ERR01,deferr           | Set default error
     2226                move.l  edma(a5),a0             | Get final DMA address
     2227                move.l  cdma(a5),a2             | Get first DMA address
     2228                move.l  #0x40000,d7             | Set timeout counter
     2229                move.b  #FL_RM,DSKCMD(a6)       | Start readng the disk
     2230
     2231floprd03:       btst    #0,DSKCMD(a6)           | Disk busy yet ?
     2232                bne     floprd05                | Jump if so
     2233
     2234                subq.l  #1,d7                   | Decrement timeout counter
     2235                beq     floprd04                | Jump if timed out
     2236
     2237                bra     floprd03                | Go try for busy again
     2238
     2239floprd05:       move.l  #0x40000,d7             | Reset timeout counter
     2240                bra     floprd09                | Go join main read loop
     2241
     2242floprd07:       subq.l  #1,d7                   | Decrement timeout counter
     2243                beq     floprd04                | Jump if timed out
     2244
     2245                btst    #0,DSKCMD(a6)           | Done yet ?
     2246                beq     floprd08                | Jump if so
     2247
     2248floprd09:       btst    #1,DSKCMD(a6)           | DRQ set ?
     2249                beq     floprd07                | Jump if not
     2250
     2251                move.b  DSKDAT(a6),(a2)+        | Read the byte into the buffer
     2252                cmp.l   a0,a2                   | Done reading ?
     2253                bne     floprd07                | Jump if not
     2254
     2255                .page
     2256
     2257floprd08:       move.b  DSKCMD(a6),d0           | Read final status into d0
     2258                and.b   #0x1C,d0                | Mask for error bits
     2259                beq     flopok                  | Jump if no errors
     2260
     2261                bsr     errbits                 | Determine error code
     2262
     2263floprd02:       cmp.w   #1,retrycnt(a5)         | Re-try ?
     2264                bne     floprd06                | Jump if not
     2265
     2266                bsr     reseek                  | Home and repeat the seek
     2267
     2268floprd06:       subq.w  #1,retrycnt(a5)         | Update re-try count
     2269                bpl     floprd01                | Re-try if count still >0
     2270
     2271                bra     flopfail                | Failure
     2272
     2273floprd04:       move.w  #ERR02,curerr(a5)       | Set error code "not ready"
     2274                bsr     rs1772                  | Reset the WD1772
     2275                bra     floprd02                | See if it can be retried
     2276
     2277                .page
     2278
     2279| errbits -- Develop error code for floppy I/O error
     2280| -------    ---------------------------------------
     2281errbits:        moveq.l #ERR13,d1               | Write protect ?
     2282                btst    #6,d0                   | ...
     2283                bne     errbits1                | Jump if so
     2284
     2285                moveq.l #ERR08,d1               | Record not found ?
     2286                btst    #4,d0                   | ...
     2287                bne     errbits1                | Jump if so
     2288
     2289                moveq.l #ERR04,d1               | CRC error ?
     2290                btst    #3,d0                   | ...
     2291                bne     errbits1                | Jump if so
     2292
     2293                moveq.l #ERR12,d1               | Lost data ?
     2294                btst    #2,d0                   | ...
     2295                bne     errbits1                | Jump if so
     2296
     2297                move.w  deferr(a5),d1           | Use default error
     2298
     2299errbits1:       move.w  d1,curerr(a5)           | ... as curerr
     2300                rts                             | Return to caller
     2301
     2302                .page
     2303
     2304| flopwr -- Floppy write
     2305| ------    ------------
     2306flopwr:         bsr     change                  | Check for disk change
     2307                moveq.l #ERR10,d0               | Set write error
     2308                bsr     floplock                | Set parameters
     2309                move.w  csect(a5),d0            | Get sector number in d0
     2310                subq.w  #1,d0                   | ... -1
     2311                or.w    ctrack(a5),d0           | OR with track number
     2312                or.w    cside(a5),d0            | OR with side number
     2313                bne     flopwr01                | Jump if not boot sector
     2314
     2315                moveq.l #2,d0                   | Media change
     2316                bsr     setdmode                | Set to "unsure"
     2317
     2318flopwr01:       bsr     select                  | Select drive and side
     2319                bsr     go2track                | Seek
     2320                bne     flopwr06                | Re-try on error
     2321
     2322flopwr02:       move.w  #ERR01,curerr(a5)       | Set for default error
     2323                move.l  cdma(a5),a2             | Get I/O address
     2324                move.l  #0x40000,d7             | Set timeout counter
     2325                move.w  ctrack(a5),d0           | Get track number
     2326                cmpi.w  #40,d0                  | See if we need precomp
     2327                bcs     flopwr10                | Jump if not
     2328
     2329                move.b  #FL_WS,DSKCMD(a6)       | Write with precomp
     2330                bra     flopwr08                | Go join main write loop
     2331
     2332flopwr10:       move.b  #FL_WS+FL_NC,DSKCMD(a6) | Write  (no precomp)
     2333
     2334                .page
     2335
     2336flopwr08:       btst    #0,DSKCMD(a6)           | Busy yet ?
     2337                bne     flopwr09                | Jump if so
     2338
     2339                subq.l  #1,d7                   | Decrement tiemout count
     2340                bne     flopwr08                | Jump if not timed out
     2341
     2342flopwr13:       bsr     rs1772                  | Reset WD1772
     2343                bra     flopwr05                | See if we can retry
     2344
     2345flopwr11:       btst    #0,DSKCMD(a6)           | Done ?
     2346                beq     flopwr04                | Jump if so
     2347
     2348flopwr09:       btst    #1,DSKCMD(a6)           | DRQ set ?
     2349                bne     flopwr12                | Jump if so
     2350
     2351                subq.l  #1,d7                   | Decrement timeout counter
     2352                beq     flopwr13                | Jump if timed out
     2353
     2354                bra     flopwr11                | Jump if not
     2355
     2356flopwr12:       move.b  (a2)+,DSKDAT(a6)        | Write byte to floppy
     2357                bra     flopwr11                | Go get the next one
     2358
     2359                .page
     2360
     2361flopwr04:       move.b  DSKCMD(a6),d0           | Get floppy status
     2362                bsr     errbits                 | Set error code
     2363                btst    #6,d0                   | Write protect error ?
     2364                bne     flopfail                | Fail if so
     2365
     2366                and.b   #0x5C,d0                | Mask error bits
     2367                bne     flopwr05                | Jump if an error occurred
     2368
     2369                addq.w  #1,csect(a5)            | Update sector number
     2370                add.l   #512,cdma(a5)           | Update DMA address
     2371                subq.w  #1,ccount(a5)           | Decrement sector count
     2372                beq     flopok                  | Jump if zero -- done
     2373
     2374                bsr     select1                 | Set sector and DMA pointer
     2375                bra     flopwr02                | Write next sector
     2376
     2377flopwr05:       cmp.w   #1,retrycnt(a5)         | Second re-try ?
     2378                bne     flopwr07                | Jump if not
     2379
     2380flopwr06:       bsr     reseek                  | Restore and re-seek
     2381
     2382flopwr07:       subq.w  #1,retrycnt(a5)         | Update re-try count
     2383                bpl     flopwr01                | Re-try if still >0
     2384
     2385                bra     flopfail                | ... else fail
     2386
     2387                .page
     2388
     2389| flopfmt -- Format a track on the floppy
     2390| -------    ----------------------------
     2391flopfmt:        cmp.l   #FMAGIC,22(a7)          | Is the magic right ?
     2392                bne     flopfail                | Fail immediately if not
     2393
     2394                bsr     change                  | Check for disk change
     2395                moveq.l #ERR01,d0               | Set default error number
     2396                bsr     floplock                | Set parameters
     2397                bsr     select                  | Select drive and side
     2398                move.w  14(a7),spt(a5)          | Set sectors per track,
     2399                move.w  20(a7),interlv(a5)      | ... interleave,
     2400                move.w  26(a7),virgin(a5)       | ... initial data,
     2401                moveq.l #2,d0                   | Disk changed
     2402                bsr     setdmode                | ...
     2403                bsr     hseek                   | Seek
     2404                bne     flopfail                | Fail if seek error occurs
     2405
     2406                move.w  ctrack(a5),0(a1)        | Current track to DSB
     2407                move.w  #ERR01,curerr(a5)       | Default to curerr
     2408                bsr     fmtrack                 | Format the track
     2409                bne     flopfail                | Fail if error occurs
     2410
     2411                move.w  spt(a5),ccount(a5)      | Use spt as ccount
     2412                move.w  #1,csect(a5)            | Start with sector 1
     2413                bsr     verify1                 | Verify the sector
     2414                move.l  cdma(a5),a2             | Get bad sector list
     2415                tst.w   (a2)                    | Any bad ones ?
     2416                beq     flopok                  | Jump if not
     2417
     2418                move.w  #ERR16,curerr(a5)       | ERROR -- "bad sectors"
    24192419                bra     flopfail
    2420 *
    2421                 .page
    2422 *
    2423 * fmtrack -- Do the dirty work of formatting a track
    2424 * -------    ---------------------------------------
    2425 fmtrack:        move.w  #ERR10,deferr(a5)       * Set default error number
    2426                 move.w  #1,d3                   * Start with sector 1
    2427                 move.l  cdma(a5),a2             * Get track buffer address
    2428                 move.w  #60-1,d1                * Set count = 60
    2429                 move.b  #$4E,d0                 * Write $4E as initial gap
    2430                 bsr     wmult                   * ...
    2431 *
    2432 fmtrak01:       move.w  d3,d4                   * Save sector number in d4
    2433 *
    2434 fmtrak02:       move.w  #12-1,d1                * Set count = 12
    2435                 clr.b   d0                      * Write $00 as sync
    2436                 bsr     wmult                   * ...
    2437                 move.w  #3-1,d1                 * Set count = 3
    2438                 move.b  #$F5,d0                 * Write $F5's
    2439                 bsr     wmult                   * ...
    2440                 move.b  #$FE,(a2)+              * Write $FE (address mark)
    2441                 move.b  ctrack+1,(a2)+          * Write track #
    2442                 move.b  cside+1,(a2)+           * Write side #
    2443                 move.b  d4,(a2)+                * Write sector #
    2444                 move.b  #2,(a2)+                * Write sector size code
    2445                 move.b  #$F7,(a2)+              * Write checksum code
    2446                 move.w  #22-1,d1                * Set count = 22
    2447                 move.b  #$4E,d0                 * Write gap
    2448                 bsr     wmult                   * ...
    2449                 move.w  #12-1,d1                * Set count = 12
    2450                 clr.b   d0                      * Write $00 as sync
    2451                 bsr     wmult                   * ...
    2452                 move.w  #3-1,d1                 * Set count = 3
    2453                 move.b  #$F5,d0                 * Write $F5's
    2454                 bsr     wmult                   * ...
    2455                 move.b  #$FB,(a2)+              * Write DAM
    2456                 move.w  #256-1,d1               * Set count = 256 words
    2457 *
    2458                 .page
    2459 *
    2460 fmtrak03:       move.b  virgin(a5),(a2)+        * Write virgin data in buffer
    2461                 move.b  virgin+1(a5),(a2)+      * ...
    2462                 dbf     d1,fmtrak03             * ...
    2463 *
    2464                 move.b  #$F7,(a2)+              * Write CRC code
    2465                 move.w  #40-1,d1                * Set count = 40
    2466                 move.b  #$4E,d0                 * Write gap
    2467                 bsr     wmult                   * ...
    2468                 add.w   interlv(a5),d4          * Add interleave to sector #
    2469                 cmp.w   spt(a5),d4              * Check against spt
    2470                 ble     fmtrak02                * Jump if not >
    2471 *
    2472                 addq.w  #1,d3                   * Starting sector +1
     2420
     2421                .page
     2422
     2423| fmtrack -- Do the dirty work of formatting a track
     2424| -------    ---------------------------------------
     2425fmtrack:        move.w  #ERR10,deferr(a5)       | Set default error number
     2426                move.w  #1,d3                   | Start with sector 1
     2427                move.l  cdma(a5),a2             | Get track buffer address
     2428                move.w  #60-1,d1                | Set count = 60
     2429                move.b  #0x4E,d0                | Write 0x4E as initial gap
     2430                bsr     wmult                   | ...
     2431
     2432fmtrak01:       move.w  d3,d4                   | Save sector number in d4
     2433
     2434fmtrak02:       move.w  #12-1,d1                | Set count = 12
     2435                clr.b   d0                      | Write 0x00 as sync
     2436                bsr     wmult                   | ...
     2437                move.w  #3-1,d1                 | Set count = 3
     2438                move.b  #0xF5,d0                | Write 0xF5's
     2439                bsr     wmult                   | ...
     2440                move.b  #0xFE,(a2)+             | Write 0xFE (address mark)
     2441                move.b  ctrack+1,(a2)+          | Write track #
     2442                move.b  cside+1,(a2)+           | Write side #
     2443                move.b  d4,(a2)+                | Write sector #
     2444                move.b  #2,(a2)+                | Write sector size code
     2445                move.b  #0xF7,(a2)+             | Write checksum code
     2446                move.w  #22-1,d1                | Set count = 22
     2447                move.b  #0x4E,d0                | Write gap
     2448                bsr     wmult                   | ...
     2449                move.w  #12-1,d1                | Set count = 12
     2450                clr.b   d0                      | Write 0x00 as sync
     2451                bsr     wmult                   | ...
     2452                move.w  #3-1,d1                 | Set count = 3
     2453                move.b  #0xF5,d0                | Write 0xF5's
     2454                bsr     wmult                   | ...
     2455                move.b  #0xFB,(a2)+             | Write DAM
     2456                move.w  #256-1,d1               | Set count = 256 words
     2457
     2458                .page
     2459
     2460fmtrak03:       move.b  virgin(a5),(a2)+        | Write virgin data in buffer
     2461                move.b  virgin+1(a5),(a2)+      | ...
     2462                dbf     d1,fmtrak03             | ...
     2463
     2464                move.b  #0xF7,(a2)+             | Write CRC code
     2465                move.w  #40-1,d1                | Set count = 40
     2466                move.b  #0x4E,d0                | Write gap
     2467                bsr     wmult                   | ...
     2468                add.w   interlv(a5),d4          | Add interleave to sector #
     2469                cmp.w   spt(a5),d4              | Check against spt
     2470                ble     fmtrak02                | Jump if not >
     2471
     2472                addq.w  #1,d3                   | Starting sector +1
    24732473                cmp.w   interlv(a5),d3
    24742474                ble     fmtrak01
    2475 *
    2476                 move.w  #1401-1,d1              * Set count = 1401
    2477                 move.b  #$4E,d0                 * Write final gap
    2478                 bsr     wmult                   * ...
    2479                 move.l  cdma(a5),a2             * Get buffer address
    2480                 move.l  #$40000,d7              * Set timeout count
    2481                 move.w  ctrack(a5),d0           * Get track number
    2482                 cmpi.w  #40,d0                  * Do we need precomp ?
    2483                 bcs     fmtrak08                * Jump if not
    2484 *
    2485                 move.b  #FL_WT,DSKCMD(a6)       * Start format with precomp
    2486                 bra     fmtrak07                * Go join main format loop
    2487 *
    2488 fmtrak08:       move.b  #FL_WT+FL_NC,DSKCMD(a6) * Start format without precomp
    2489 *
    2490                 .page
    2491 *
    2492 fmtrak07:       btst    #0,DSKCMD(a6)           * Busy yet ?
    2493                 bne     fmtrak09                * Jump if so
    2494 *
    2495 fmtrak04:       subq.l  #1,d7                   * Decrement timeout counter
    2496                 bne     fmtrak07                * Jump if not timed out
    2497 *
    2498 fmtrak05:       bsr     rs1772                  * Reset WD1772
    2499                 moveq.l #1,d7                   * Set error flag
    2500                 rts                             * Return to caller
    2501 *
    2502 fmtrak11:       btst    #0,DSKCMD(a6)           * Done ?
    2503                 beq     fmtrak06                * Jump if so
    2504 *
    2505 fmtrak09:       btst    #1,DSKCMD(a6)           * DRQ set ?
    2506                 bne     fmtrak10                * Jump if so
    2507 *
    2508                 subq.l  #1,d7                   * Decrement timeout coutner
    2509                 beq     fmtrak05                * Jump if timed out
    2510 *
    2511                 bra     fmtrak11                * Go check again
    2512 *
    2513 fmtrak10:       move.b  (a2)+,DSKDAT(a6)        * Write a byte of format
    2514                 bra     fmtrak11                * Go wait for DRQ
    2515 *
    2516 fmtrak06:       move.b  DSKCMD(a6),d0           * Get final status
    2517                 bsr     errbits                 * Set possible error code
    2518                 andi.b  #$44,d0                 * Check error bits
    2519                 rts                             * Return to caller with status
    2520 *
    2521 * wmult -- write multiple bytes into the track buffer
    2522 * -----    ------------------------------------------
    2523 wmult:          move.b  d0,(a2)+                * Move a byte into the buffer
    2524                 dbf     d1,wmult                * Loop until we're done
    2525 *
    2526                 rts                             * Return to caller
    2527 *
    2528                 .page
    2529 *
    2530 * flopver -- verify sector(s) on a floppy
    2531 * -------    ----------------------------
    2532 flopver:        bsr     change                  * Check for disk change
    2533                 moveq.l #ERR11,d0               * Set default to "read error"
    2534                 bsr     floplock                * Set parameters
    2535                 bsr     select                  * Select drive and side
    2536                 bsr     go2track                * Seek
    2537                 bne     flopfail                * Jump if seek error
    2538 *
    2539                 bsr     verify1                 * Verify the data
    2540                 bra     flopok                  * Done
    2541 *
    2542 * verify1 -- Verify the data for a sector
    2543 * -------    ----------------------------
    2544 verify1:        move.w  #ERR11,deferr(a5)       * Set default = "read error"
    2545                 move.l  cdma(a5),a2             * Pointer for bad sector list
    2546                 add.l   #512,cdma(a5)           * Update by length of a sector
    2547 *
    2548 verify01:       move.w  #2,retrycnt(a5)         * Set retrycnt for 2 attempts
    2549                 move.w  csect(a5),d7            * Get sector nubmer
    2550                 move.b  d7,DSKSEC(a6)           * Send to WD1772
    2551 *
    2552 verify02:       moveq.l #0,d6                   * Clear bad compare flag
    2553                 move.l  cdma(a5),a0             * Get compare address
    2554                 move.l  #$40000,d7              * Set timeout counter
    2555                 move.b  #FL_RS,DSKCMD(a6)       * Start the read
    2556 *
    2557 verify08:       btst    #0,DSKCMD(a6)           * Busy yet ?
    2558                 bne     verify09                * Jump if so
    2559 *
    2560                 subq.l  #1,d7                   * Decrement timeout counter
    2561                 beq     verify13                * Jump if timed out
    2562 *
    2563                 bra     verify08                * Wait for busy some more
    2564 *
    2565 verify09:       move.l  #$40000,d7              * Reset timeout counter
    2566                 bra     verify11                * Go join main compare loop
    2567 *
    2568 verify10:       subq.l  #1,d7                   * Decrement timeout counter
    2569                 beq     verify13                * Jump if timed out
    2570 *
    2571                 btst    #0,DSKCMD(a6)           * Done yet ?
    2572                 beq     verify12                * Jump if so
    2573 *
    2574                 .page
    2575 *
    2576 verify11:       btst    #1,DSKCMD(a6)           * DRQ set ?
    2577                 beq     verify10                * Jump if not
    2578 *
    2579                 move.b  DSKDAT(a6),d0           * Read data
    2580                 bra     verify10                * Continue reading
    2581 *
    2582 verify12:       move.b  DSKCMD(a6),d0           * Get final status
    2583                 bsr     errbits                 * Determine error code
    2584                 and.b   #$1C,d0                 * Mask RNF, CRC, LOST
    2585                 bne     verify06                * Jump to re-try if any set
    2586 *
    2587 verify05:       addq.w  #1,csect(a5)            * Update sector number
    2588                 subq.w  #1,ccount(a5)           * Update sector count
    2589                 bne     verify01                * Jump if more to do
    2590 *
    2591                 sub.l   #512,cdma(a5)           * Reset DMA pointer
    2592                 clr.w   (a2)                    * Set NIL in bad sector list
    2593                 rts                             * Return to caller
    2594 *
    2595 verify06:       cmp.w   #1,retrycnt(a5)         * Is it the 2nd attempt ?
    2596                 bne     verify07                * Jump if not
    2597 *
    2598                 bsr     reseek                  * Restore and re-seek
    2599 *
    2600 verify07:       subq.w  #1,retrycnt(a5)         * Decrement retry count
    2601                 bpl     verify02                * Re-try if still positive
    2602 *
    2603                 move.w  csect(a5),(a2)+         * Add to bad sector list
    2604                 bra     verify05                * Go do next sector
    2605 *
    2606 verify13:       move.w  #ERR02,curerr(a5)       * Set timeout error code
    2607                 bsr     rs1772                  * Reset WD1772
    2608                 bra     verify06                * See if we can retry it
    2609 *
    2610                 .page
    2611 *
    2612 * flopvbl -- Floppy VBL timer interrupt handling
    2613 * -------    -----------------------------------
    2614 flopvbl:        movem.l d0-d1/a0-a1/a5-a6,-(a7) * Save registers
    2615                 sub.l   a5,a5                   * Clear a5 for use as RAM base
    2616                 lea     FLOPPY,a6               * Base of floppy regs
    2617                 st      motoron(a5)             * Set motoron flag
    2618                 move.l  frclock(a5),d0          * Get interrupt count
    2619                 move.b  d0,d1                   * ...
    2620                 and.b   #7,d1                   * ... MOD 8
    2621                 bne     flopvb02                * Jump if not 8th int
    2622 *
    2623                 move.w  sr,-(a7)                * Save interrupt level
    2624                 ori.w   #IPL7,sr                * Mask off interrupts
    2625                 clr.w   deslflag(a5)            * Clear deselect flag
    2626                 move.b  mc1iorec+cfr1,d0        * Get port status
    2627                 ori.b   #1,d0                   * Set drive select bit
    2628                 move.b  d0,MC1ACIA+ACIA_CFR     * Send drive select to port
    2629                 move.b  d0,mc1iorec+cfr1        * Store updated port status
    2630                 move.w  (a7)+,sr                * Restore interrupt level
    2631                 lea     wpstatus(a5),a0         * Point at wpstatus for drive
    2632                 lea     dsb0(a5),a1             * Point at dsb0
    2633                 move.b  DSKCMD(a6),d0           * Read WD1772 status
    2634                 btst    #6,d0                   * Test write protect bit
    2635                 sne     (a0)                    * ... and save
    2636 *
    2637                 .page
    2638 *
    2639 flopvb02:       move.w  wpstatus(a5),d0         * Get wpstatus of drive A
    2640                 or.w    d0,wplatch(a5)          * OR into wplatch
    2641                 tst.w   deslflag(a5)            * Floppies already deselected ?
    2642                 bne     flopvb03                * Jump if so
    2643 *
    2644                 move.b  DSKCMD(a6),d0           * Read WD1772 status
    2645                 btst    #7,d0                   * Motor-on bit set ?
    2646                 bne     flopvb04                * Don't de-select if it is
    2647 *
    2648                 move.w  sr,-(a7)                * Save sr
    2649                 ori.w   #IPL7,sr                * Disable interrupts
    2650                 move.b  mc1iorec+cfr1,d0        * Get cfr1 image
    2651                 bclr    #0,d0                   * Clear d0  (drive select)
    2652                 move.b  d0,mc1iorec+cfr1        * Save new value
    2653                 move.b  d0,MC1ACIA+ACIA_CFR     * Send to hardware
    2654                 move.w  (a7)+,sr                * Restore sr  (enable ints)
    2655                 move.w  #1,deslflag(a5)         * Set the deselect flag
    2656 *
    2657 flopvb03:       clr.w   motoron(a5)             * Clear motoron flag
    2658 *
    2659 flopvb04:       movem.l (a7)+,d0-d1/a0-a1/a5-a6 * Restore registers
    2660                 rts                             * Return to caller
    2661 *
    2662                 .page
    2663 *
    2664 * floplock -- Setup floppy parameters
    2665 * --------    -----------------------
    2666 floplock:       movem.l d3-d7/a3-a6,flpregs     * Save registers
    2667                 move.w  sr,flpsrsv              * Save sr
    2668                 ori.w   #IPL7,sr                * Disable ints
    2669                 sub.l   a5,a5                   * Clear a5
    2670                 lea     FLOPPY,a6               * Base of floppy registers
    2671                 st      motoron(a5)             * Set motoron flag
    2672                 move.w  d0,deferr(a5)           * Set default error code
    2673                 move.w  d0,curerr(a5)           * ... current error code
    2674                 move.w  #1,flock(a5)            * Disable flopvbl routine
    2675                 move.l  8(a7),cdma(a5)          * Set cdma
    2676                 move.w  16(a7),cdev(a5)         * ... cdev
    2677                 move.w  18(a7),csect(a5)        * ... csect
    2678                 move.w  20(a7),ctrack(a5)       * ... ctrack
    2679                 move.w  22(a7),cside(a5)        * ... cside
    2680                 move.w  24(a7),ccount(a5)       * ... ccount
    2681                 move.w  #2,retrycnt(a5)         * ... retrycnt
    2682                 lea     dsb0(a5),a1             * Address of dsb0
    2683                 tst.w   cdev(a5)                * Drive A ?
    2684                 beq     floplk01                * Jump if so
    2685 *
    2686                 lea     dsb1(a5),a1             * Drive B, use dsb1
    2687 *
    2688 floplk01:       moveq.l #0,d7                   * Clear out d7
    2689                 move.w  ccount(a5),d7           * Get ccount
    2690                 lsl.w   #8,d7                   * ... * sector length  (512)
    2691                 lsl.w   #1,d7                   * ...
    2692                 move.l  cdma(a5),a0             * Get DMA start address
    2693                 add.l   d7,a0                   * Add length of sectors
    2694                 move.l  a0,edma(a5)             * Set edma  (end DMA address)
    2695                 tst.w   0(a1)                   * Check current track
    2696                 bpl     floplk03                * Jump if >= 0
    2697 *
    2698                 bsr     select                  * Select the drive
    2699                 clr.w   0(a1)                   * Set current track to 0
    2700                 bsr     restore                 * Restore drive to track 0
    2701                 beq     floplk03                * Jump if OK
    2702 *
    2703                 moveq.l #10,d7                  * Seek out to track 10
    2704                 bsr     hseek1                  * ...
    2705                 bne     floplk02                * Jump if an error occurred
    2706 *
    2707                 bsr     restore                 * Try the restore again
    2708                 beq     floplk03                * Jump if OK
    2709 *
    2710 floplk02:       move.w  #$FF00,0(a1)            * Recalibrate error
    2711 *
    2712 floplk03:       rts                             * Return to caller
    2713 *
    2714                 .page
    2715 *
    2716 * flopfail -- Floppy I/O failure exit
    2717 * --------    -----------------------
    2718 flopfail:       moveq.l #1,d0                   * Set media change to "unsure"
    2719                 bsr     setdmode                * ...
    2720                 move.w  curerr(a5),d0           * Get curerr
    2721                 ext.l   d0                      * ...
    2722                 bra     flopok1                 * Go set end status
    2723 *
    2724 * flopok -- Floppy I/O success exit
    2725 * ------    -----------------------
    2726 flopok:         clr.l   d0                      * Set error code = 0  (no error)
    2727 *
    2728 flopok1:        move.l  d0,-(a7)                * Push code onto stack
    2729                 move.w  0(a1),d7                * Get track number
    2730                 move.b  d7,DSKDAT(a6)           * Send to WD1772
    2731                 move.w  #FL_SK,d6               * Seek command to d6
    2732                 bsr     flopcmds                * Send command
    2733                 move.w  cdev(a5),d0             * Get drive number
    2734                 lsl.w   #2,d0                   * Use as index
    2735                 lea     acctim(a5),a0           * ... into acctim
    2736                 move.l  _hz_200(a5),0(a0,d0)    * Set last access time
     2475
     2476                move.w  #1401-1,d1              | Set count = 1401
     2477                move.b  #0x4E,d0                | Write final gap
     2478                bsr     wmult                   | ...
     2479                move.l  cdma(a5),a2             | Get buffer address
     2480                move.l  #0x40000,d7             | Set timeout count
     2481                move.w  ctrack(a5),d0           | Get track number
     2482                cmpi.w  #40,d0                  | Do we need precomp ?
     2483                bcs     fmtrak08                | Jump if not
     2484
     2485                move.b  #FL_WT,DSKCMD(a6)       | Start format with precomp
     2486                bra     fmtrak07                | Go join main format loop
     2487
     2488fmtrak08:       move.b  #FL_WT+FL_NC,DSKCMD(a6) | Start format without precomp
     2489
     2490                .page
     2491
     2492fmtrak07:       btst    #0,DSKCMD(a6)           | Busy yet ?
     2493                bne     fmtrak09                | Jump if so
     2494
     2495fmtrak04:       subq.l  #1,d7                   | Decrement timeout counter
     2496                bne     fmtrak07                | Jump if not timed out
     2497
     2498fmtrak05:       bsr     rs1772                  | Reset WD1772
     2499                moveq.l #1,d7                   | Set error flag
     2500                rts                             | Return to caller
     2501
     2502fmtrak11:       btst    #0,DSKCMD(a6)           | Done ?
     2503                beq     fmtrak06                | Jump if so
     2504
     2505fmtrak09:       btst    #1,DSKCMD(a6)           | DRQ set ?
     2506                bne     fmtrak10                | Jump if so
     2507
     2508                subq.l  #1,d7                   | Decrement timeout coutner
     2509                beq     fmtrak05                | Jump if timed out
     2510
     2511                bra     fmtrak11                | Go check again
     2512
     2513fmtrak10:       move.b  (a2)+,DSKDAT(a6)        | Write a byte of format
     2514                bra     fmtrak11                | Go wait for DRQ
     2515
     2516fmtrak06:       move.b  DSKCMD(a6),d0           | Get final status
     2517                bsr     errbits                 | Set possible error code
     2518                andi.b  #0x44,d0                | Check error bits
     2519                rts                             | Return to caller with status
     2520
     2521| wmult -- write multiple bytes into the track buffer
     2522| -----    ------------------------------------------
     2523wmult:          move.b  d0,(a2)+                | Move a byte into the buffer
     2524                dbf     d1,wmult                | Loop until we're done
     2525
     2526                rts                             | Return to caller
     2527
     2528                .page
     2529
     2530| flopver -- verify sector(s) on a floppy
     2531| -------    ----------------------------
     2532flopver:        bsr     change                  | Check for disk change
     2533                moveq.l #ERR11,d0               | Set default to "read error"
     2534                bsr     floplock                | Set parameters
     2535                bsr     select                  | Select drive and side
     2536                bsr     go2track                | Seek
     2537                bne     flopfail                | Jump if seek error
     2538
     2539                bsr     verify1                 | Verify the data
     2540                bra     flopok                  | Done
     2541
     2542| verify1 -- Verify the data for a sector
     2543| -------    ----------------------------
     2544verify1:        move.w  #ERR11,deferr(a5)       | Set default = "read error"
     2545                move.l  cdma(a5),a2             | Pointer for bad sector list
     2546                add.l   #512,cdma(a5)           | Update by length of a sector
     2547
     2548verify01:       move.w  #2,retrycnt(a5)         | Set retrycnt for 2 attempts
     2549                move.w  csect(a5),d7            | Get sector nubmer
     2550                move.b  d7,DSKSEC(a6)           | Send to WD1772
     2551
     2552verify02:       moveq.l #0,d6                   | Clear bad compare flag
     2553                move.l  cdma(a5),a0             | Get compare address
     2554                move.l  #0x40000,d7             | Set timeout counter
     2555                move.b  #FL_RS,DSKCMD(a6)       | Start the read
     2556
     2557verify08:       btst    #0,DSKCMD(a6)           | Busy yet ?
     2558                bne     verify09                | Jump if so
     2559
     2560                subq.l  #1,d7                   | Decrement timeout counter
     2561                beq     verify13                | Jump if timed out
     2562
     2563                bra     verify08                | Wait for busy some more
     2564
     2565verify09:       move.l  #0x40000,d7             | Reset timeout counter
     2566                bra     verify11                | Go join main compare loop
     2567
     2568verify10:       subq.l  #1,d7                   | Decrement timeout counter
     2569                beq     verify13                | Jump if timed out
     2570
     2571                btst    #0,DSKCMD(a6)           | Done yet ?
     2572                beq     verify12                | Jump if so
     2573
     2574                .page
     2575
     2576verify11:       btst    #1,DSKCMD(a6)           | DRQ set ?
     2577                beq     verify10                | Jump if not
     2578
     2579                move.b  DSKDAT(a6),d0           | Read data
     2580                bra     verify10                | Continue reading
     2581
     2582verify12:       move.b  DSKCMD(a6),d0           | Get final status
     2583                bsr     errbits                 | Determine error code
     2584                and.b   #0x1C,d0                | Mask RNF, CRC, LOST
     2585                bne     verify06                | Jump to re-try if any set
     2586
     2587verify05:       addq.w  #1,csect(a5)            | Update sector number
     2588                subq.w  #1,ccount(a5)           | Update sector count
     2589                bne     verify01                | Jump if more to do
     2590
     2591                sub.l   #512,cdma(a5)           | Reset DMA pointer
     2592                clr.w   (a2)                    | Set NIL in bad sector list
     2593                rts                             | Return to caller
     2594
     2595verify06:       cmp.w   #1,retrycnt(a5)         | Is it the 2nd attempt ?
     2596                bne     verify07                | Jump if not
     2597
     2598                bsr     reseek                  | Restore and re-seek
     2599
     2600verify07:       subq.w  #1,retrycnt(a5)         | Decrement retry count
     2601                bpl     verify02                | Re-try if still positive
     2602
     2603                move.w  csect(a5),(a2)+         | Add to bad sector list
     2604                bra     verify05                | Go do next sector
     2605
     2606verify13:       move.w  #ERR02,curerr(a5)       | Set timeout error code
     2607                bsr     rs1772                  | Reset WD1772
     2608                bra     verify06                | See if we can retry it
     2609
     2610                .page
     2611
     2612| flopvbl -- Floppy VBL timer interrupt handling
     2613| -------    -----------------------------------
     2614flopvbl:        movem.l d0-d1/a0-a1/a5-a6,-(a7) | Save registers
     2615                sub.l   a5,a5                   | Clear a5 for use as RAM base
     2616                lea     FLOPPY,a6               | Base of floppy regs
     2617                st      motoron(a5)             | Set motoron flag
     2618                move.l  frclock(a5),d0          | Get interrupt count
     2619                move.b  d0,d1                   | ...
     2620                and.b   #7,d1                   | ... MOD 8
     2621                bne     flopvb02                | Jump if not 8th int
     2622
     2623                move.w  sr,-(a7)                | Save interrupt level
     2624                ori.w   #IPL7,sr                | Mask off interrupts
     2625                clr.w   deslflag(a5)            | Clear deselect flag
     2626                move.b  mc1iorec+cfr1,d0        | Get port status
     2627                ori.b   #1,d0                   | Set drive select bit
     2628                move.b  d0,MC1ACIA+ACIA_CFR     | Send drive select to port
     2629                move.b  d0,mc1iorec+cfr1        | Store updated port status
     2630                move.w  (a7)+,sr                | Restore interrupt level
     2631                lea     wpstatus(a5),a0         | Point at wpstatus for drive
     2632                lea     dsb0(a5),a1             | Point at dsb0
     2633                move.b  DSKCMD(a6),d0           | Read WD1772 status
     2634                btst    #6,d0                   | Test write protect bit
     2635                sne     (a0)                    | ... and save
     2636
     2637                .page
     2638
     2639flopvb02:       move.w  wpstatus(a5),d0         | Get wpstatus of drive A
     2640                or.w    d0,wplatch(a5)          | OR into wplatch
     2641                tst.w   deslflag(a5)            | Floppies already deselected ?
     2642                bne     flopvb03                | Jump if so
     2643
     2644                move.b  DSKCMD(a6),d0           | Read WD1772 status
     2645                btst    #7,d0                   | Motor-on bit set ?
     2646                bne     flopvb04                | Don't de-select if it is
     2647
     2648                move.w  sr,-(a7)                | Save sr
     2649                ori.w   #IPL7,sr                | Disable interrupts
     2650                move.b  mc1iorec+cfr1,d0        | Get cfr1 image
     2651                bclr    #0,d0                   | Clear d0  (drive select)
     2652                move.b  d0,mc1iorec+cfr1        | Save new value
     2653                move.b  d0,MC1ACIA+ACIA_CFR     | Send to hardware
     2654                move.w  (a7)+,sr                | Restore sr  (enable ints)
     2655                move.w  #1,deslflag(a5)         | Set the deselect flag
     2656
     2657flopvb03:       clr.w   motoron(a5)             | Clear motoron flag
     2658
     2659flopvb04:       movem.l (a7)+,d0-d1/a0-a1/a5-a6 | Restore registers
     2660                rts                             | Return to caller
     2661
     2662                .page
     2663
     2664| floplock -- Setup floppy parameters
     2665| --------    -----------------------
     2666floplock:       movem.l d3-d7/a3-a6,flpregs     | Save registers
     2667                move.w  sr,flpsrsv              | Save sr
     2668                ori.w   #IPL7,sr                | Disable ints
     2669                sub.l   a5,a5                   | Clear a5
     2670                lea     FLOPPY,a6               | Base of floppy registers
     2671                st      motoron(a5)             | Set motoron flag
     2672                move.w  d0,deferr(a5)           | Set default error code
     2673                move.w  d0,curerr(a5)           | ... current error code
     2674                move.w  #1,flock(a5)            | Disable flopvbl routine
     2675                move.l  8(a7),cdma(a5)          | Set cdma
     2676                move.w  16(a7),cdev(a5)         | ... cdev
     2677                move.w  18(a7),csect(a5)        | ... csect
     2678                move.w  20(a7),ctrack(a5)       | ... ctrack
     2679                move.w  22(a7),cside(a5)        | ... cside
     2680                move.w  24(a7),ccount(a5)       | ... ccount
     2681                move.w  #2,retrycnt(a5)         | ... retrycnt
     2682                lea     dsb0(a5),a1             | Address of dsb0
     2683                tst.w   cdev(a5)                | Drive A ?
     2684                beq     floplk01                | Jump if so
     2685
     2686                lea     dsb1(a5),a1             | Drive B, use dsb1
     2687
     2688floplk01:       moveq.l #0,d7                   | Clear out d7
     2689                move.w  ccount(a5),d7           | Get ccount
     2690                lsl.w   #8,d7                   | ... | sector length  (512)
     2691                lsl.w   #1,d7                   | ...
     2692                move.l  cdma(a5),a0             | Get DMA start address
     2693                add.l   d7,a0                   | Add length of sectors
     2694                move.l  a0,edma(a5)             | Set edma  (end DMA address)
     2695                tst.w   0(a1)                   | Check current track
     2696                bpl     floplk03                | Jump if >= 0
     2697
     2698                bsr     select                  | Select the drive
     2699                clr.w   0(a1)                   | Set current track to 0
     2700                bsr     restore                 | Restore drive to track 0
     2701                beq     floplk03                | Jump if OK
     2702
     2703                moveq.l #10,d7                  | Seek out to track 10
     2704                bsr     hseek1                  | ...
     2705                bne     floplk02                | Jump if an error occurred
     2706
     2707                bsr     restore                 | Try the restore again
     2708                beq     floplk03                | Jump if OK
     2709
     2710floplk02:       move.w  #0xFF00,0(a1)           | Recalibrate error
     2711
     2712floplk03:       rts                             | Return to caller
     2713
     2714                .page
     2715
     2716| flopfail -- Floppy I/O failure exit
     2717| --------    -----------------------
     2718flopfail:       moveq.l #1,d0                   | Set media change to "unsure"
     2719                bsr     setdmode                | ...
     2720                move.w  curerr(a5),d0           | Get curerr
     2721                ext.l   d0                      | ...
     2722                bra     flopok1                 | Go set end status
     2723
     2724| flopok -- Floppy I/O success exit
     2725| ------    -----------------------
     2726flopok:         clr.l   d0                      | Set error code = 0  (no error)
     2727
     2728flopok1:        move.l  d0,-(a7)                | Push code onto stack
     2729                move.w  0(a1),d7                | Get track number
     2730                move.b  d7,DSKDAT(a6)           | Send to WD1772
     2731                move.w  #FL_SK,d6               | Seek command to d6
     2732                bsr     flopcmds                | Send command
     2733                move.w  cdev(a5),d0             | Get drive number
     2734                lsl.w   #2,d0                   | Use as index
     2735                lea     acctim(a5),a0           | ... into acctim
     2736                move.l  _hz_200(a5),0(a0,d0)    | Set last access time
    27372737                cmp.w   #1,nflops(a5)
    27382738                bne     flopok01
    2739 *
    2740                 move.l  _hz_200(a5),4(a0)       * Time for other drive
    2741 *
    2742 flopok01:       move.w  flpsrsv,sr              * Restore sr  (enable ints)
    2743                 move.l  (a7)+,d0                * Restore error number to d0
    2744                 movem.l flpregs,d3-d7/a3-a6     * Restore registers
    2745                 clr.w   flock                   * Release flopvbl routine
    2746                 rts                             * Return to caller
    2747 *
    2748                 .page
    2749 *
    2750 * hseek -- seek to track in ctrack
    2751 * -----    -----------------------
    2752 hseek:          move.w  ctrack,d7               * Get ctrack
    2753 *
    2754 * hseek1 -- seek to track in d7
    2755 * ------    -------------------
    2756 hseek1:         move.w  #ERR10,curerr           * Set curerr = "seek error"
    2757                 move.b  d7,DSKDAT(a6)           * Send track number to WD1772
    2758                 move.w  #FL_SK,d6               * Seek command
    2759                 bra     flopcmds                * Go send command to WD1772
    2760 *
    2761 * reseek -- Restore, then re-seek
    2762 * ------    ---------------------
    2763 reseek:         move.w  #ERR10,curerr           * Set curerr = "seek error"
    2764                 bsr     restore                 * Restore
    2765                 bne     reseek01                * Jump if error occurred
    2766 *
    2767                 clr.w   0(a1)                   * Clear current track to 0
    2768                 move.b  #0,DSKTRK(a6)           * Send track to WD1772
    2769                 move.b  #5,DSKDAT(a6)           * Setup to seek to track 5
    2770                 move.w  #FL_SK,d6               * Seek command
    2771                 bsr     flopcmds                * Seek
    2772                 bne     reseek01                * Jump if error
    2773 *
    2774                 move.w  #5,0(a1)                * Update current track = 5
    2775 *
    2776 * go2track -- seek with verify
    2777 * --------    ----------------
    2778 go2track:       move.w  #ERR10,curerr(a5)       * Set curerr = "seek error"
    2779                 move.w  ctrack(a5),d7           * Put track # in d7
    2780                 move.b  d7,DSKDAT(a6)           * Send track to WD1772
    2781                 moveq.l #FL_SV,d6               * Seek/verify command
    2782                 bsr     flopcmds                * Send command to floppy
    2783                 bne     reseek01                * Jump if error occurred
    2784 *
    2785                 move.w  ctrack(a5),0(a1)        * Update track number in dsb
    2786                 and.b   #$18,d7                 * Test for RNF, CRC, LOST
    2787 *
    2788 reseek01:       rts                             * Return to caller
    2789 *
    2790                 .page
    2791 *
    2792 * restore -- Restore to track 0
    2793 * -------    ------------------
    2794 restore:        clr.w   d6                      * Restore command
    2795                 bsr     flopcmds                * Send to WD1772
    2796                 bne     restor01                * Jump if an error occurred
    2797 *
    2798                 btst    #2,d7                   * Check track 0 bit
    2799                 eori    #0004,sr                * Invert Z flag in 680000 sr
    2800                 bne     restor01                * Jump if not track 0
    2801 *
    2802                 clr.w   0(a1)                   * Set track = 0 in dsb
    2803 *
    2804 restor01:       rts                             * Return to caller
    2805 *
    2806 * flopcmds -- Send command to WD1772 floppy controller
    2807 * --------    ----------------------------------------
    2808 flopcmds:       move.w  2(a1),d0                * Get seek rate from dsb
    2809                 and.b   #$3,d0                  * ...
    2810                 or.b    d0,d6                   * OR into command word
    2811                 move.l  #$40000,d7              * Set timeout counter
    2812                 btst    #7,DSKCMD(a6)           * Motor on ?
    2813                 bne     flopcm01                * Jump if so
    2814 *
    2815                 move.l  #$60000,d7              * Set longer timeout count
    2816 *
    2817 flopcm01:       move.b  d6,DSKCMD(a6)           * Write command from d6
    2818 *
    2819                 move.l  #$1000,d0               * Set initial busy timeout in d0
    2820 *
    2821 flopcm04:       btst    #0,DSKCMD(a6)           * Controller busy yet ?
    2822                 bne     flopcm02                * Jump if so
    2823 *
    2824                 subq.l  #1,d0                   * Decrement timeout counter
    2825                 beq     flopcm03                * Jump if timed out
    2826 *
    2827                 bra     flopcm04                * Wait for busy some more
    2828 *
    2829 flopcm02:       subq.l  #1,d7                   * Decrement timeout counter
    2830                 beq     flopcm03                * Jump if timed out
    2831 *
    2832                 btst    #0,DSKCMD(a6)           * WD1772 done ?
    2833                 bne     flopcm02                * Jump if not
    2834 *
    2835                 clr.l   d7                      * Clear out upper bits of d7
    2836                 move.b  DSKCMD(a6),d7           * Read status into LS byte of d7
    2837                 clr.l   d6                      * Clear error flag in d6
    2838                 rts                             * Return to caller
    2839 *
    2840 flopcm03:       bsr     rs1772                  * Reset WD1772  (end transfer)
    2841                 moveq.l #1,d6                   * Set error flag in d6
    2842                 rts                             * Return to caller
    2843 *
    2844                 .page
    2845 *
    2846 * rs1772 -- Reset WD1772 floppy controller
    2847 * ------    ------------------------------
    2848 rs1772:         move.b  #FL_FR,DSKCMD(a6)       * Send reset to WD1772
    2849                 move.w  #15,d7                  * Set delay count
    2850 *
    2851 rs1772a:        dbf     d7,rs1772a              * Delay a while
    2852                 rts                             * Return to caller
    2853 *
    2854 * select -- Select drive and side
    2855 * ------    ----------------------
    2856 select:         move.w  sr,-(a7)                * Save sr on stack
    2857                 ori.w   #IPL7,sr                * Disable interrupts
    2858                 clr.w   deslflag(a5)            * Clear deselect flag
    2859                 move.b  mc1iorec+cfr1,d0        * Get current MC1 cfr1 image
    2860                 ori.b   #1,d0                   * Select drive  (we only have 1)
    2861                 move.b  d0,mc1iorec+cfr1        * Store updated image
    2862                 move.b  d0,MC1ACIA+ACIA_CFR     * Send it to the MC1 ACIA
    2863                 move.w  cside(a5),d0            * Get side number  (LS bit)
    2864                 and.w   #1,d0                   * Mask off garbage bits
    2865                 andi.b  #$FE,mc2iorec+cfr1      * Mask off D0 in MC2 cfr1 image
    2866                 or.b    mc2iorec+cfr1,d0        * OR side with mc2iorec cfr1
    2867                 move.b  d0,mc2iorec+cfr1        * Store updated cfr1 image
    2868                 move.b  d0,MC2ACIA+ACIA_CFR     * Send it to the MC2 ACIA
    2869                 move.w  (a7)+,sr                * Restore interrupts
    2870                 move.w  0(a1),d7                * Get track from dsb
    2871                 move.b  d7,DSKTRK(a6)           * Send it to the WD1772
    2872                 clr.b   tmpdma(a5)              * Clear bits 31..24 of tmpdma
    2873 *
    2874 select1:        move.w  csect(a5),d7            * Get sector number
    2875                 move.b  d7,DSKSEC(a6)           * Send it to the WD1772
    2876                 move.l  cdma(a5),a0             * Setup transfer address in a0
    2877                 rts                             * Return to caller
    2878 *
    2879                 .page
    2880 *
    2881 * change -- Check for disk change status
    2882 * ------    ----------------------------
    2883 change:         cmp.w   #1,nflops               * Check # of floppies
     2739
     2740                move.l  _hz_200(a5),4(a0)       | Time for other drive
     2741
     2742flopok01:       move.w  flpsrsv,sr              | Restore sr  (enable ints)
     2743                move.l  (a7)+,d0                | Restore error number to d0
     2744                movem.l flpregs,d3-d7/a3-a6     | Restore registers
     2745                clr.w   flock                   | Release flopvbl routine
     2746                rts                             | Return to caller
     2747
     2748                .page
     2749
     2750| hseek -- seek to track in ctrack
     2751| -----    -----------------------
     2752hseek:          move.w  ctrack,d7               | Get ctrack
     2753
     2754| hseek1 -- seek to track in d7
     2755| ------    -------------------
     2756hseek1:         move.w  #ERR10,curerr           | Set curerr = "seek error"
     2757                move.b  d7,DSKDAT(a6)           | Send track number to WD1772
     2758                move.w  #FL_SK,d6               | Seek command
     2759                bra     flopcmds                | Go send command to WD1772
     2760
     2761| reseek -- Restore, then re-seek
     2762| ------    ---------------------
     2763reseek:         move.w  #ERR10,curerr           | Set curerr = "seek error"
     2764                bsr     restore                 | Restore
     2765                bne     reseek01                | Jump if error occurred
     2766
     2767                clr.w   0(a1)                   | Clear current track to 0
     2768                move.b  #0,DSKTRK(a6)           | Send track to WD1772
     2769                move.b  #5,DSKDAT(a6)           | Setup to seek to track 5
     2770                move.w  #FL_SK,d6               | Seek command
     2771                bsr     flopcmds                | Seek
     2772                bne     reseek01                | Jump if error
     2773
     2774                move.w  #5,0(a1)                | Update current track = 5
     2775
     2776| go2track -- seek with verify
     2777| --------    ----------------
     2778go2track:       move.w  #ERR10,curerr(a5)       | Set curerr = "seek error"
     2779                move.w  ctrack(a5),d7           | Put track # in d7
     2780                move.b  d7,DSKDAT(a6)           | Send track to WD1772
     2781                moveq.l #FL_SV,d6               | Seek/verify command
     2782                bsr     flopcmds                | Send command to floppy
     2783                bne     reseek01                | Jump if error occurred
     2784
     2785                move.w  ctrack(a5),0(a1)        | Update track number in dsb
     2786                and.b   #0x18,d7                | Test for RNF, CRC, LOST
     2787
     2788reseek01:       rts                             | Return to caller
     2789
     2790                .page
     2791
     2792| restore -- Restore to track 0
     2793| -------    ------------------
     2794restore:        clr.w   d6                      | Restore command
     2795                bsr     flopcmds                | Send to WD1772
     2796                bne     restor01                | Jump if an error occurred
     2797
     2798                btst    #2,d7                   | Check track 0 bit
     2799                eori    #0004,sr                | Invert Z flag in 680000 sr
     2800                bne     restor01                | Jump if not track 0
     2801
     2802                clr.w   0(a1)                   | Set track = 0 in dsb
     2803
     2804restor01:       rts                             | Return to caller
     2805
     2806| flopcmds -- Send command to WD1772 floppy controller
     2807| --------    ----------------------------------------
     2808flopcmds:       move.w  2(a1),d0                | Get seek rate from dsb
     2809                and.b   #0x3,d0                 | ...
     2810                or.b    d0,d6                   | OR into command word
     2811                move.l  #0x40000,d7             | Set timeout counter
     2812                btst    #7,DSKCMD(a6)           | Motor on ?
     2813                bne     flopcm01                | Jump if so
     2814
     2815                move.l  #0x60000,d7             | Set longer timeout count
     2816
     2817flopcm01:       move.b  d6,DSKCMD(a6)           | Write command from d6
     2818
     2819                move.l  #0x1000,d0              | Set initial busy timeout in d0
     2820
     2821flopcm04:       btst    #0,DSKCMD(a6)           | Controller busy yet ?
     2822                bne     flopcm02                | Jump if so
     2823
     2824                subq.l  #1,d0                   | Decrement timeout counter
     2825                beq     flopcm03                | Jump if timed out
     2826
     2827                bra     flopcm04                | Wait for busy some more
     2828
     2829flopcm02:       subq.l  #1,d7                   | Decrement timeout counter
     2830                beq     flopcm03                | Jump if timed out
     2831
     2832                btst    #0,DSKCMD(a6)           | WD1772 done ?
     2833                bne     flopcm02                | Jump if not
     2834
     2835                clr.l   d7                      | Clear out upper bits of d7
     2836                move.b  DSKCMD(a6),d7           | Read status into LS byte of d7
     2837                clr.l   d6                      | Clear error flag in d6
     2838                rts                             | Return to caller
     2839
     2840flopcm03:       bsr     rs1772                  | Reset WD1772  (end transfer)
     2841                moveq.l #1,d6                   | Set error flag in d6
     2842                rts                             | Return to caller
     2843
     2844                .page
     2845
     2846| rs1772 -- Reset WD1772 floppy controller
     2847| ------    ------------------------------
     2848rs1772:         move.b  #FL_FR,DSKCMD(a6)       | Send reset to WD1772
     2849                move.w  #15,d7                  | Set delay count
     2850
     2851rs1772a:        dbf     d7,rs1772a              | Delay a while
     2852                rts                             | Return to caller
     2853
     2854| select -- Select drive and side
     2855| ------    ----------------------
     2856select:         move.w  sr,-(a7)                | Save sr on stack
     2857                ori.w   #IPL7,sr                | Disable interrupts
     2858                clr.w   deslflag(a5)            | Clear deselect flag
     2859                move.b  mc1iorec+cfr1,d0        | Get current MC1 cfr1 image
     2860                ori.b   #1,d0                   | Select drive  (we only have 1)
     2861                move.b  d0,mc1iorec+cfr1        | Store updated image
     2862                move.b  d0,MC1ACIA+ACIA_CFR     | Send it to the MC1 ACIA
     2863                move.w  cside(a5),d0            | Get side number  (LS bit)
     2864                and.w   #1,d0                   | Mask off garbage bits
     2865                andi.b  #0xFE,mc2iorec+cfr1     | Mask off D0 in MC2 cfr1 image
     2866                or.b    mc2iorec+cfr1,d0        | OR side with mc2iorec cfr1
     2867                move.b  d0,mc2iorec+cfr1        | Store updated cfr1 image
     2868                move.b  d0,MC2ACIA+ACIA_CFR     | Send it to the MC2 ACIA
     2869                move.w  (a7)+,sr                | Restore interrupts
     2870                move.w  0(a1),d7                | Get track from dsb
     2871                move.b  d7,DSKTRK(a6)           | Send it to the WD1772
     2872                clr.b   tmpdma(a5)              | Clear bits 31..24 of tmpdma
     2873
     2874select1:        move.w  csect(a5),d7            | Get sector number
     2875                move.b  d7,DSKSEC(a6)           | Send it to the WD1772
     2876                move.l  cdma(a5),a0             | Setup transfer address in a0
     2877                rts                             | Return to caller
     2878
     2879                .page
     2880
     2881| change -- Check for disk change status
     2882| ------    ----------------------------
     2883change:         cmp.w   #1,nflops               | Check # of floppies
    28842884                bne     change02
    2885 *
    2886                 move.w  16(a7),d0               * Drive number to d0
     2885
     2886                move.w  16(a7),d0               | Drive number to d0
    28872887                cmp.w   disknum,d0
    2888                 beq     change01                * Jump if =
    2889 *
    2890                 move.w  d0,-(a7)                * Stack drive number
    2891                 move.w  #ERR17,-(a7)            * Stack error code
    2892                 bsr     criter                  * Do critical error routine
    2893                 addq.w  #4,a7                   * Cleanup stack
    2894                 move.w  #$FFFF,wplatch          * Status for drives = "unsure"
    2895                 move.w  16(a7),disknum          * Save disk number
    2896 *
    2897 change01:       clr.w   16(a7)                  * Clear disk number
    2898 *
    2899 change02:       rts                             * Return to caller
    2900 *
    2901 * setdmode -- Set drive change mode
    2902 * --------    ---------------------
    2903 setdmode:       lea     dskmode,a0              * Point at disk mode table
    2904                 move.b  d0,-(a7)                * Save mode on stack
    2905                 move.w  cdev(a5),d0             * Get drive number
    2906                 move.b  (a7)+,0(a0,d0)          * Set drive mode / cleanup stack
    2907                 rts                             * Return to caller
    2908 *
    2909                 .page
    2910 *
    2911 * bootload -- Load boot sector
    2912 * --------    ----------------
    2913 bootload:       link    a6,#0                   * Link stack frames
    2914                 movem.l d6-d7,-(a7)             * Save registers
    2915                 jsr     _hdvini                 * Init drive
    2916                 tst.w   nflops                  * See if any connected
    2917                 beq     bootld01                * Jump if drive there
    2918 *
    2919                 moveq.l #1,d0                   * "couldn't load"
     2888                beq     change01                | Jump if =
     2889
     2890                move.w  d0,-(a7)                | Stack drive number
     2891                move.w  #ERR17,-(a7)            | Stack error code
     2892                bsr     criter                  | Do critical error routine
     2893                addq.w  #4,a7                   | Cleanup stack
     2894                move.w  #0xFFFF,wplatch         | Status for drives = "unsure"
     2895                move.w  16(a7),disknum          | Save disk number
     2896
     2897change01:       clr.w   16(a7)                  | Clear disk number
     2898
     2899change02:       rts                             | Return to caller
     2900
     2901| setdmode -- Set drive change mode
     2902| --------    ---------------------
     2903setdmode:       lea     dskmode,a0              | Point at disk mode table
     2904                move.b  d0,-(a7)                | Save mode on stack
     2905                move.w  cdev(a5),d0             | Get drive number
     2906                move.b  (a7)+,0(a0,d0)          | Set drive mode / cleanup stack
     2907                rts                             | Return to caller
     2908
     2909                .page
     2910
     2911| bootload -- Load boot sector
     2912| --------    ----------------
     2913bootload:       link    a6,#0                   | Link stack frames
     2914                movem.l d6-d7,-(a7)             | Save registers
     2915                jsr     _hdvini                 | Init drive
     2916                tst.w   nflops                  | See if any connected
     2917                beq     bootld01                | Jump if drive there
     2918
     2919                moveq.l #1,d0                   | "couldn't load"
    29202920                bra     bootld02
    2921 *
    2922 bootld01:       moveq.l #2,d0                   * "no drive connected"
    2923 *
    2924 bootld02:       move.w  d0,d7                   * Save possible error in d7
     2921
     2922bootld01:       moveq.l #2,d0                   | "no drive connected"
     2923
     2924bootld02:       move.w  d0,d7                   | Save possible error in d7
    29252925                tst.w   nflops
    29262926                beq     bootld04
    2927 *
     2927
    29282928                cmp.w   #2,bootdev
    29292929                bge     bootld04
    2930 *
    2931                 move.w  #1,(a7)                 * Sector count = 1,
    2932                 clr.w   -(a7)                   * ... side = 0,
    2933                 clr.w   -(a7)                   * ... track = 0,
    2934                 move.w  #1,-(a7)                * ... sector = 1,
    2935                 move.w  bootdev,-(a7)           * ... drive = bootdev,
    2936                 clr.l   -(a7)                   * ... filler,
    2937                 move.l  #buffer,-(a7)           * ... buffer address
    2938                 jsr     floprd                  * Read the sector
    2939                 add.l   #16,a7                  * Cleanup stack
    2940                 tst.l   d0                      * Error ?
    2941                 bne     bootld03                * Jump if not
    2942 *
     2930
     2931                move.w  #1,(a7)                 | Sector count = 1,
     2932                clr.w   -(a7)                   | ... side = 0,
     2933                clr.w   -(a7)                   | ... track = 0,
     2934                move.w  #1,-(a7)                | ... sector = 1,
     2935                move.w  bootdev,-(a7)           | ... drive = bootdev,
     2936                clr.l   -(a7)                   | ... filler,
     2937                move.l  #buffer,-(a7)           | ... buffer address
     2938                jsr     floprd                  | Read the sector
     2939                add.l   #16,a7                  | Cleanup stack
     2940                tst.l   d0                      | Error ?
     2941                bne     bootld03                | Jump if not
     2942
    29432943                clr.w   d7
    29442944                bra     bootld04
    2945 *
     2945
    29462946bootld03:       tst.b   wpstatus
    29472947                bne     bootld04
    2948 *
    2949                 moveq.l #3,d0                   * "unreadable"
     2948
     2949                moveq.l #3,d0                   | "unreadable"
    29502950                bra     bootld07
    2951 *
     2951
    29522952bootld04:       tst.w   d7
    29532953                beq     bootld05
    2954 *
    2955                 move.w  d7,d0                   * Get old error code
     2954
     2955                move.w  d7,d0                   | Get old error code
    29562956                bra     bootld07
    2957 *
    2958                 .page
    2959 *
    2960 bootld05:       move.w  #256,(a7)               * Set count for 256 words
    2961                 move.l  #buffer,-(a7)           * Point at buffer
    2962                 bsr     chksum                  * Calculate checksum
    2963                 addq.l  #4,a7                   * Cleanup stack
    2964                 cmp.w   #$1234,d0               * Boot sector checksum ?
    2965                 bne     bootld06                * Jump if not
    2966 *
    2967                 clr.w   d0                      * Set flag for OK
    2968                 move.w  bootdev,booted          * Save last boot device
     2957
     2958                .page
     2959
     2960bootld05:       move.w  #256,(a7)               | Set count for 256 words
     2961                move.l  #buffer,-(a7)           | Point at buffer
     2962                bsr     chksum                  | Calculate checksum
     2963                addq.l  #4,a7                   | Cleanup stack
     2964                cmp.w   #0x1234,d0              | Boot sector checksum ?
     2965                bne     bootld06                | Jump if not
     2966
     2967                clr.w   d0                      | Set flag for OK
     2968                move.w  bootdev,booted          | Save last boot device
    29692969                bra     bootld07
    2970 *
    2971 bootld06:       moveq.l #4,d0                   * "not valid boot sector"
    2972 *
     2970
     2971bootld06:       moveq.l #4,d0                   | "not valid boot sector"
     2972
    29732973bootld07:       tst.l   (a7)+
    2974                 movem.l (a7)+,d7                * Restore registers
     2974                movem.l (a7)+,d7                | Restore registers
    29752975                unlk    a6
    2976                 rts                             * Return to caller
    2977 *
    2978                 .page
    2979 *
    2980 * chksum -- caluculate checksum
    2981 * ------    -------------------
     2976                rts                             | Return to caller
     2977
     2978                .page
     2979
     2980| chksum -- caluculate checksum
     2981| ------    -------------------
    29822982chksum:         link    a6,#0
    2983                 movem.l d6-d7,-(a7)             * Preserve registers
    2984                 clr.w   d7                      * Clear sum
    2985                 bra     chksum02                * Jump into loop
    2986 *
    2987 chksum01:       move.l  8(a6),a0                * Get buffer address
    2988                 move.w  (a0),d0                 * Get word
    2989                 add.w   d0,d7                   * Add to checksum in d7
    2990                 addq.l  #2,8(a6)                * Update buffer address
    2991 *
    2992 chksum02:       move.w  12(a6),d0               * Get word count
    2993                 subq.w  #1,12(a6)               * Decrement it
    2994                 tst.w   d0                      * Done ?
    2995                 bne     chksum01                * Loop if not
    2996 *
    2997                 move.w  d7,d0                   * Put result in d0
     2983                movem.l d6-d7,-(a7)             | Preserve registers
     2984                clr.w   d7                      | Clear sum
     2985                bra     chksum02                | Jump into loop
     2986
     2987chksum01:       move.l  8(a6),a0                | Get buffer address
     2988                move.w  (a0),d0                 | Get word
     2989                add.w   d0,d7                   | Add to checksum in d7
     2990                addq.l  #2,8(a6)                | Update buffer address
     2991
     2992chksum02:       move.w  12(a6),d0               | Get word count
     2993                subq.w  #1,12(a6)               | Decrement it
     2994                tst.w   d0                      | Done ?
     2995                bne     chksum01                | Loop if not
     2996
     2997                move.w  d7,d0                   | Put result in d0
    29982998                tst.l   (a7)+
    2999                 movem.l (a7)+,d7                * Restore registers
     2999                movem.l (a7)+,d7                | Restore registers
    30003000                unlk    a6
    3001                 rts                             * Return to caller
    3002 *
    3003                 .page
    3004 *
    3005 * mult32 -- 32 bit signed multiply
    3006 * ------    ----------------------
     3001                rts                             | Return to caller
     3002
     3003                .page
     3004
     3005| mult32 -- 32 bit signed multiply
     3006| ------    ----------------------
    30073007mult32:         link    a6,#-4
    30083008                clr.w   d2
    30093009                tst.l   8(a6)
    30103010                bge     mult32a
    3011 *
     3011
    30123012                neg.l   8(a6)
    30133013                addq.w  #1,d2
    3014 *
     3014
    30153015mult32a:        tst.l   12(a6)
    30163016                bge     mult32b
    3017 *
     3017
    30183018                neg.l   12(a6)
    30193019                addq.w  #1,d2
    3020 *
     3020
    30213021mult32b:        move.w  10(a6),d0
    30223022                mulu    14(a6),d0
     
    30323032                btst    #0,d2
    30333033                beq     mult32c
    3034 *
     3034
    30353035                neg.l   d0
    3036 *
     3036
    30373037mult32c:        unlk    a6
    30383038                rts
    3039 *
    3040                 .page
    3041 *
    3042 * rand -- Generate a random number
    3043 * ----    ------------------------
    3044 rand:           link    a6,#-4                  * Reserve stack for temps
    3045                 tst.l   rseed                   * See if the seed is zero
    3046                 bne     rand01                  * Jump if not
    3047 *
    3048                 move.l  _hz_200,d0              * Pick up the 200 Hz clock
    3049                 moveq.l #16,d1                  * Shift it left
    3050                 asl.l   d1,d0                   * ...
    3051                 or.l    _hz_200,d0              * OR in current 200 Hz clock
    3052                 move.l  d0,rseed                * Use that as the seed
    3053 *
    3054 rand01:         move.l  #$BB40E62D,-(a7)        * Put PI on the stack
    3055                 move.l  rseed,-(a7)             * ... and rseed, too
    3056                 bsr     mult32                  * Multiply them
    3057                 addq.l  #8,a7                   * Cleanup stack
    3058                 addq.l  #1,d0                   * Add 1 to the result
    3059                 move.l  d0,rseed                * Save as new seed
     3039
     3040                .page
     3041
     3042| rand -- Generate a random number
     3043| ----    ------------------------
     3044rand:           link    a6,#-4                  | Reserve stack for temps
     3045                tst.l   rseed                   | See if the seed is zero
     3046                bne     rand01                  | Jump if not
     3047
     3048                move.l  _hz_200,d0              | Pick up the 200 Hz clock
     3049                moveq.l #16,d1                  | Shift it left
     3050                asl.l   d1,d0                   | ...
     3051                or.l    _hz_200,d0              | OR in current 200 Hz clock
     3052                move.l  d0,rseed                | Use that as the seed
     3053
     3054rand01:         move.l  #0xBB40E62D,-(a7)       | Put PI on the stack
     3055                move.l  rseed,-(a7)             | ... and rseed, too
     3056                bsr     mult32                  | Multiply them
     3057                addq.l  #8,a7                   | Cleanup stack
     3058                addq.l  #1,d0                   | Add 1 to the result
     3059                move.l  d0,rseed                | Save as new seed
    30603060                move.l  rseed,d0
    3061                 asr.l   #8,d0                   * Make it a 24 bit number
    3062                 and.l   #$FFFFFF,d0             * ...
    3063                 unlk    a6                      * Release stack
    3064                 rts                             * Return to caller
    3065 *
    3066                 .page
    3067 *
    3068 * protobt -- Generate a prototype boot sector
    3069 * -------    --------------------------------
     3061                asr.l   #8,d0                   | Make it a 24 bit number
     3062                and.l   #0xFFFFFF,d0            | ...
     3063                unlk    a6                      | Release stack
     3064                rts                             | Return to caller
     3065
     3066                .page
     3067
     3068| protobt -- Generate a prototype boot sector
     3069| -------    --------------------------------
    30703070protobt:        link    a6,#-6
    3071                 movem.l d5-d7/a5,-(a7)          * Save registers
    3072                 tst.w   18(a6)                  * Test execflg
    3073                 bge     protbt03                * Jump if set
    3074 *
    3075                 move.w  #256,(a7)               * Count = 256 words
    3076                 move.l  8(a6),-(a7)             * Address of buffer
    3077                 bsr     chksum                  * Calculate checksum
    3078                 addq.l  #4,a7                   * Cleanup stack
    3079                 cmp.w   #$1234,d0               * Boot checksum ?
    3080                 beq     protbt01                * Jump if so
    3081 *
    3082                 clr.w   d0                      * Not executable
     3071                movem.l d5-d7/a5,-(a7)          | Save registers
     3072                tst.w   18(a6)                  | Test execflg
     3073                bge     protbt03                | Jump if set
     3074
     3075                move.w  #256,(a7)               | Count = 256 words
     3076                move.l  8(a6),-(a7)             | Address of buffer
     3077                bsr     chksum                  | Calculate checksum
     3078                addq.l  #4,a7                   | Cleanup stack
     3079                cmp.w   #0x1234,d0              | Boot checksum ?
     3080                beq     protbt01                | Jump if so
     3081
     3082                clr.w   d0                      | Not executable
    30833083                bra     protbt02
    3084 *
    3085 protbt01:       moveq.l #1,d0                   * Executable
    3086 *
    3087 protbt02:       move.w  d0,18(a6)               * Set execflg
    3088 *
    3089 protbt03:       tst.l   12(a6)                  * Serial number ?
    3090                 blt     protbt07                * Jump if not to be changed
    3091 *
    3092                 move.l  12(a6),d0               * Get it into d0
    3093                 cmp.l   #$FFFFFF,d0             * > $FFFFFF
    3094                 ble     protbt04                * Jump if not
    3095 *
    3096                 bsr     rand                    * Generate a random number
    3097                 move.l  d0,12(a6)               * Save as s/n
    3098 *
    3099 protbt04:       clr.w   d7                      * Clear counter
    3100                 bra     protbt06                * Enter move loop
    3101 *
    3102                 .page
    3103 *
    3104 protbt05:       move.l  12(a6),d0               * Get s/n
    3105                 and.l   #$FF,d0                 * Isolate low 8 bits
    3106                 move.w  d7,a1                   * Point to next byte
    3107                 add.l   8(a6),a1                * ...
    3108                 move.b  d0,8(a1)                * Write byte in buffer
    3109                 move.l  12(a6),d0               * Get s/n
    3110                 asr.l   #8,d0                   * Shift right 8 bits
    3111                 move.l  d0,12(a6)               * Save shifted value
    3112                 addq.w  #1,d7                   * Update counter
    3113 *
    3114 protbt06:       cmp.w   #3,d7                   * See if we're done
    3115                 blt     protbt05                * Loop if not
    3116 *
    3117 protbt07:       tst.w   16(a6)                  * Diskette size ?
    3118                 blt     protbt10                * Jump if not to be changed
    3119 *
    3120                 move.w  16(a6),d6               * Get diskette size
    3121                 muls.w  #19,d6                  * ... times 19 as pointer
    3122                 clr.w   d7                      * Clear counter
    3123                 bra     protbt09                * Go move in BPB
    3124 *
    3125 protbt08:       move.w  d7,a0                   * Get counter
    3126                 add.l   8(a6),a0                * Add base of buffer
    3127                 move.w  d6,a1                   * Get BPB pointer
    3128                 add.l   #pbpbtab,a1             * Add base of prototype BPB's
    3129                 move.b  (a1),11(a0)             * Copy BPB data
    3130                 addq.w  #1,d6                   * Update pointer
    3131                 addq.w  #1,d7                   * Update counter
    3132 *
    3133 protbt09:       cmp.w   #19,d7                  * Done ?
    3134                 blt     protbt08                * Loop if not
    3135 *
     3084
     3085protbt01:       moveq.l #1,d0                   | Executable
     3086
     3087protbt02:       move.w  d0,18(a6)               | Set execflg
     3088
     3089protbt03:       tst.l   12(a6)                  | Serial number ?
     3090                blt     protbt07                | Jump if not to be changed
     3091
     3092                move.l  12(a6),d0               | Get it into d0
     3093                cmp.l   #0xFFFFFF,d0            | > 0xFFFFFF
     3094                ble     protbt04                | Jump if not
     3095
     3096                bsr     rand                    | Generate a random number
     3097                move.l  d0,12(a6)               | Save as s/n
     3098
     3099protbt04:       clr.w   d7                      | Clear counter
     3100                bra     protbt06                | Enter move loop
     3101
     3102                .page
     3103
     3104protbt05:       move.l  12(a6),d0               | Get s/n
     3105                and.l   #0xFF,d0                | Isolate low 8 bits
     3106                move.w  d7,a1                   | Point to next byte
     3107                add.l   8(a6),a1                | ...
     3108                move.b  d0,8(a1)                | Write byte in buffer
     3109                move.l  12(a6),d0               | Get s/n
     3110                asr.l   #8,d0                   | Shift right 8 bits
     3111                move.l  d0,12(a6)               | Save shifted value
     3112                addq.w  #1,d7                   | Update counter
     3113
     3114protbt06:       cmp.w   #3,d7                   | See if we're done
     3115                blt     protbt05                | Loop if not
     3116
     3117protbt07:       tst.w   16(a6)                  | Diskette size ?
     3118                blt     protbt10                | Jump if not to be changed
     3119
     3120                move.w  16(a6),d6               | Get diskette size
     3121                muls.w  #19,d6                  | ... times 19 as pointer
     3122                clr.w   d7                      | Clear counter
     3123                bra     protbt09                | Go move in BPB
     3124
     3125protbt08:       move.w  d7,a0                   | Get counter
     3126                add.l   8(a6),a0                | Add base of buffer
     3127                move.w  d6,a1                   | Get BPB pointer
     3128                add.l   #pbpbtab,a1             | Add base of prototype BPB's
     3129                move.b  (a1),11(a0)             | Copy BPB data
     3130                addq.w  #1,d6                   | Update pointer
     3131                addq.w  #1,d7                   | Update counter
     3132
     3133protbt09:       cmp.w   #19,d7                  | Done ?
     3134                blt     protbt08                | Loop if not
     3135
    31363136protbt10:       clr.w   -6(a6)
    31373137                move.l  8(a6),-4(a6)
    31383138                bra     protbt12
    3139 *
    3140                 .page
    3141 *
    3142 protbt11:       move.l  -4(a6),a0               * Get buffer pointer
    3143                 move.w  (a0),d0                 * Get word from buffer
    3144                 add.w   d0,-6(a6)               * Sum for checksum
    3145                 addq.l  #2,-4(a6)               * Point at next word
    3146 *
    3147 protbt12:       move.l  8(a6),d0                * Get buffer address
    3148                 add.l   #$1FE,d0                * Plus sector length
    3149                 cmp.l   -4(a6),d0               * Done ?
    3150                 bhi     protbt11                * Loop if not
    3151 *
    3152                 move.w  #$1234,d0               * Checksum for boot sector
    3153                 sub.w   -6(a6),d0               * Subtract checksum for buffer
     3139
     3140                .page
     3141
     3142protbt11:       move.l  -4(a6),a0               | Get buffer pointer
     3143                move.w  (a0),d0                 | Get word from buffer
     3144                add.w   d0,-6(a6)               | Sum for checksum
     3145                addq.l  #2,-4(a6)               | Point at next word
     3146
     3147protbt12:       move.l  8(a6),d0                | Get buffer address
     3148                add.l   #0x1FE,d0               | Plus sector length
     3149                cmp.l   -4(a6),d0               | Done ?
     3150                bhi     protbt11                | Loop if not
     3151
     3152                move.w  #0x1234,d0              | Checksum for boot sector
     3153                sub.w   -6(a6),d0               | Subtract checksum for buffer
    31543154                move.l  -4(a6),a1
    3155                 move.w  d0,(a1)                 * Store checksum in buffer
    3156                 tst.w   18(a6)                  * Check execflg
    3157                 bne     protbt13                * Boot sector to be executable ?
    3158 *
    3159                 move.l  -4(a6),a0               * Mung checksum so it's not
     3155                move.w  d0,(a1)                 | Store checksum in buffer
     3156                tst.w   18(a6)                  | Check execflg
     3157                bne     protbt13                | Boot sector to be executable ?
     3158
     3159                move.l  -4(a6),a0               | Mung checksum so it's not
    31603160                addq.w  #1,(a0)
    3161 *
     3161
    31623162protbt13:       tst.l   (a7)+
    3163                 movem.l (a7)+,d6-d7/a5          * Restore registers
    3164                 unlk    a6                      * Release stack
    3165                 rts                             * Return to caller
    3166 *
    3167                 .endc
    3168 *
    3169 * criter -- Critical error handler
    3170 * ------    ----------------------
    3171 criter:         move.l  critvec,-(a7)           * Put error vector on stack
    3172                 moveq.l #-1,d0                  * Set default error return
    3173                 rts                             * "Return" to handler
    3174 *
    3175                 .page
    3176 *
     3163                movem.l (a7)+,d6-d7/a5          | Restore registers
     3164                unlk    a6                      | Release stack
     3165                rts                             | Return to caller
     3166
     3167                .endc
     3168
     3169| criter -- Critical error handler
     3170| ------    ----------------------
     3171criter:         move.l  critvec,-(a7)           | Put error vector on stack
     3172                moveq.l #-1,d0                  | Set default error return
     3173                rts                             | "Return" to handler
     3174
     3175                .page
     3176
    31773177                .ifne   BUCHLA
    3178 *
    3179 * api_int -- Analog processor interrupt handler
    3180 * -------    ----------------------------------
    3181 api_int:        movem.l d0-d1/a0-a1,-(a7)       * Save registers
    3182                 clr.l   d0                      * Read input port
    3183                 move.b  ANALOG,d0               * ... into d0[7..0]
    3184                 move.b  d0,api_inp              * ... and api_inp
    3185                 btst    #7,d0                   * Check for signal number flag
    3186                 bne     api_s0a                 * Jump if signal number read
    3187 *
    3188                 lea     api_tv,a0               * Get api_tv base in a0
    3189                 clr.w   d1                      * Get api_sv in d1
    3190                 move.b  api_sv,d1               * ...
    3191                 cmpi.b  #6,d1                   * Check range
    3192                 bgt     api_sve                 * Jump if out of range
    3193 *
    3194                 lsl.w   #2,d1                   * Develop jump address
    3195                 move.l  0(a0,d1.W),a1           * ... from api_tv in a1
    3196                 jmp     (a1)                    * Jump to state handler
    3197 *
    3198 api_s0:         btst    #7,d0                   * Check for signal number flag
    3199                 beq     api_ret                 * Jump if not signal number
    3200 *
    3201 api_s0a:        clr.b   api_val                 * Clear value byte
    3202                 andi.b  #$7F,d0                 * Mask off signal number flag
    3203                 cmpi.b  #82,d0                  * See if it's in range
    3204                 bgt     api_err                 * Jump if out of range (GT 82)
    3205 *
    3206                 move.b  d0,api_sig              * Store signal number
    3207                 beq     api_pub                 * Jump if it was "all off"
    3208 *
    3209                 lea     api_tab,a0              * Get sv table base
    3210                 move.b  0(a0,d0.W),api_sv       * Set sv for next time
    3211 *
    3212 api_ret:        movem.l (a7)+,d0-d1/a0-a1       * Restore registers
    3213                 rte                             * Return to interrupted code
    3214 *
    3215 api_err:        move.b  d0,api_bug              * Catch the bug
    3216                 clr.b   api_sv                  * Force state zero
    3217                 bra     api_ret                 * Go back to interrupted code
    3218 *
    3219 api_sve:        move.b  d1,api_svb              * Catch the bug
    3220                 clr.b   api_sv                  * Force state zero
    3221                 bra     api_ret                 * Go back to interrupted code
    3222 *
    3223                 .page
    3224 api_s1:         btst    #0,d0                   * See if it takes a value
    3225                 beq     api_s1a                 * Jump if not
    3226 *
    3227                 move.b  #2,api_sv               * Set sv for state 2
    3228                 bra     api_ret                 * Go return from interrupt
    3229 *
    3230 api_s1a:        clr.b   api_val                 * Clear value byte
    3231                 bra     api_pub                 * Go output to fifo
    3232 *
    3233 api_s2:         ori.b   #$80,d0                 * Set status = 1
    3234                 move.b  d0,api_val              * Set value byte
    3235                 bra     api_pub                 * Go output to fifo
    3236 *
    3237 api_s3:         ror.b   #1,d0                   * Set status in value byte
    3238                 andi.b  #$80,d0                 * ...
    3239                 move.b  d0,api_val              * ...
    3240                 move.b  #4,api_sv               * Set sv for state 4
    3241                 bra     api_ret                 * Go return from interrupt
    3242 *
    3243 api_s4:         or.b    d0,api_val              * Set value byte
    3244                 bra     api_pub                 * Go output to fifo
    3245 *
    3246 api_s5:         ror.b   #1,d0                   * Set status in value byte
    3247                 andi.b  #$80,d0                 * ...
    3248 *
    3249 api_s6:         move.b  d0,api_val              * Set value byte
    3250 *
    3251 api_pub:        movea.l api_fi,a0               * Get fifo input pointer in a0
    3252                 move.w  api_sig,(a0)+           * Store new input
    3253                 cmpa.l  #api_fe,a0              * Wrap around ?
    3254                 blt     api_pb1                 * Jump if not
    3255 *
    3256                 movea.l #api_fum,a0             * Wrap input pointer to start
    3257 *
    3258 api_pb1:        move.l  a0,api_fi               * Update input pointer
    3259                 cmpa.l  api_fo,a0               * Buffer full ?
    3260                 bne     api_pb3                 * Jump if not
    3261 *
    3262                 movea.l api_fo,a1               * Get fifo output pointer in a1
    3263                 adda.l  #2,a1                   * Increment it
    3264                 cmpa.l  #api_fe,a1              * Wrap around ?
    3265                 blt     api_pb2                 * Jump if not
    3266 *
    3267                 movea.l #api_fum,a1             * Wrap output pointer to start
    3268 *
    3269 api_pb2:        move.l  a1,api_fo               * Set new output pointer
    3270 *
    3271 api_pb3:        clr.b   api_sv                  * Set state to 0
    3272                 bra     api_ret                 * Return from interrupt
    3273 *
    3274                 .page
    3275 *
    3276 * api_get -- Get analog input
    3277 * -------    ----------------
    3278 api_get:        move.w  sr,-(a7)                * Save status register
    3279                 ori.w   #IPL3,sr                * Disable ANALOG I/O interrupts
    3280                 movea.l api_fo,a0               * Get fifo output pointer
    3281                 cmpa.l  api_fi,a0               * See if fifo is empty
    3282                 bne     api_g1                  * Jump if not
    3283 *
    3284                 moveq.l #-1,d0                  * Set empty-fifo value
    3285                 move.w  (a7)+,sr                * Restore interrupt mask
    3286                 rts                             * Return to caller
    3287 *
    3288 api_g1:         clr.l   d0                      * Get fifo value
    3289                 move.w  (a0)+,d0                * ...
    3290                 cmpa.l  #api_fe,a0              * See if pointer wrapped
    3291                 blt     api_g2                  * Jump if not
    3292 *
    3293                 movea.l #api_fum,a0             * Wrap the pointer around
    3294 *
    3295 api_g2:         move.l  a0,api_fo               * Update pointer
    3296                 move.w  (a7)+,sr                * Restore interrupt mask
    3297                 rts                             * Return to caller
    3298 *
    3299 * api_zap -- clear analog I/O FIFO
    3300 * -------    ---------------------
    3301 api_zap:        move.w  sr,-(a7)                * Save status register
    3302                 ori.w   #IPL3,sr                * Disable ANALOG I/O interrupts
    3303                 move.l  #api_fum,api_fi         * Clear analog processor fifo
    3304                 move.l  #api_fum,api_fo         * ...
    3305                 move.w  (a7)+,sr                * Restore interrupt mask
     3178
     3179| api_int -- Analog processor interrupt handler
     3180| -------    ----------------------------------
     3181api_int:        movem.l d0-d1/a0-a1,-(a7)       | Save registers
     3182                clr.l   d0                      | Read input port
     3183                move.b  ANALOG,d0               | ... into d0[7..0]
     3184                move.b  d0,api_inp              | ... and api_inp
     3185                btst    #7,d0                   | Check for signal number flag
     3186                bne     api_s0a                 | Jump if signal number read
     3187
     3188                lea     api_tv,a0               | Get api_tv base in a0
     3189                clr.w   d1                      | Get api_sv in d1
     3190                move.b  api_sv,d1               | ...
     3191                cmpi.b  #6,d1                   | Check range
     3192                bgt     api_sve                 | Jump if out of range
     3193
     3194                lsl.w   #2,d1                   | Develop jump address
     3195                move.l  0(a0,d1.W),a1           | ... from api_tv in a1
     3196                jmp     (a1)                    | Jump to state handler
     3197
     3198api_s0:         btst    #7,d0                   | Check for signal number flag
     3199                beq     api_ret                 | Jump if not signal number
     3200
     3201api_s0a:        clr.b   api_val                 | Clear value byte
     3202                andi.b  #0x7F,d0                | Mask off signal number flag
     3203                cmpi.b  #82,d0                  | See if it's in range
     3204                bgt     api_err                 | Jump if out of range (GT 82)
     3205
     3206                move.b  d0,api_sig              | Store signal number
     3207                beq     api_pub                 | Jump if it was "all off"
     3208
     3209                lea     api_tab,a0              | Get sv table base
     3210                move.b  0(a0,d0.W),api_sv       | Set sv for next time
     3211
     3212api_ret:        movem.l (a7)+,d0-d1/a0-a1       | Restore registers
     3213                rte                             | Return to interrupted code
     3214
     3215api_err:        move.b  d0,api_bug              | Catch the bug
     3216                clr.b   api_sv                  | Force state zero
     3217                bra     api_ret                 | Go back to interrupted code
     3218
     3219api_sve:        move.b  d1,api_svb              | Catch the bug
     3220                clr.b   api_sv                  | Force state zero
     3221                bra     api_ret                 | Go back to interrupted code
     3222
     3223                .page
     3224api_s1:         btst    #0,d0                   | See if it takes a value
     3225                beq     api_s1a                 | Jump if not
     3226
     3227                move.b  #2,api_sv               | Set sv for state 2
     3228                bra     api_ret                 | Go return from interrupt
     3229
     3230api_s1a:        clr.b   api_val                 | Clear value byte
     3231                bra     api_pub                 | Go output to fifo
     3232
     3233api_s2:         ori.b   #0x80,d0                | Set status = 1
     3234                move.b  d0,api_val              | Set value byte
     3235                bra     api_pub                 | Go output to fifo
     3236
     3237api_s3:         ror.b   #1,d0                   | Set status in value byte
     3238                andi.b  #0x80,d0                | ...
     3239                move.b  d0,api_val              | ...
     3240                move.b  #4,api_sv               | Set sv for state 4
     3241                bra     api_ret                 | Go return from interrupt
     3242
     3243api_s4:         or.b    d0,api_val              | Set value byte
     3244                bra     api_pub                 | Go output to fifo
     3245
     3246api_s5:         ror.b   #1,d0                   | Set status in value byte
     3247                andi.b  #0x80,d0                | ...
     3248
     3249api_s6:         move.b  d0,api_val              | Set value byte
     3250
     3251api_pub:        movea.l api_fi,a0               | Get fifo input pointer in a0
     3252                move.w  api_sig,(a0)+           | Store new input
     3253                cmpa.l  #api_fe,a0              | Wrap around ?
     3254                blt     api_pb1                 | Jump if not
     3255
     3256                movea.l #api_fum,a0             | Wrap input pointer to start
     3257
     3258api_pb1:        move.l  a0,api_fi               | Update input pointer
     3259                cmpa.l  api_fo,a0               | Buffer full ?
     3260                bne     api_pb3                 | Jump if not
     3261
     3262                movea.l api_fo,a1               | Get fifo output pointer in a1
     3263                adda.l  #2,a1                   | Increment it
     3264                cmpa.l  #api_fe,a1              | Wrap around ?
     3265                blt     api_pb2                 | Jump if not
     3266
     3267                movea.l #api_fum,a1             | Wrap output pointer to start
     3268
     3269api_pb2:        move.l  a1,api_fo               | Set new output pointer
     3270
     3271api_pb3:        clr.b   api_sv                  | Set state to 0
     3272                bra     api_ret                 | Return from interrupt
     3273
     3274                .page
     3275
     3276| api_get -- Get analog input
     3277| -------    ----------------
     3278api_get:        move.w  sr,-(a7)                | Save status register
     3279                ori.w   #IPL3,sr                | Disable ANALOG I/O interrupts
     3280                movea.l api_fo,a0               | Get fifo output pointer
     3281                cmpa.l  api_fi,a0               | See if fifo is empty
     3282                bne     api_g1                  | Jump if not
     3283
     3284                moveq.l #-1,d0                  | Set empty-fifo value
     3285                move.w  (a7)+,sr                | Restore interrupt mask
     3286                rts                             | Return to caller
     3287
     3288api_g1:         clr.l   d0                      | Get fifo value
     3289                move.w  (a0)+,d0                | ...
     3290                cmpa.l  #api_fe,a0              | See if pointer wrapped
     3291                blt     api_g2                  | Jump if not
     3292
     3293                movea.l #api_fum,a0             | Wrap the pointer around
     3294
     3295api_g2:         move.l  a0,api_fo               | Update pointer
     3296                move.w  (a7)+,sr                | Restore interrupt mask
     3297                rts                             | Return to caller
     3298
     3299| api_zap -- clear analog I/O FIFO
     3300| -------    ---------------------
     3301api_zap:        move.w  sr,-(a7)                | Save status register
     3302                ori.w   #IPL3,sr                | Disable ANALOG I/O interrupts
     3303                move.l  #api_fum,api_fi         | Clear analog processor fifo
     3304                move.l  #api_fum,api_fo         | ...
     3305                move.w  (a7)+,sr                | Restore interrupt mask
    33063306                rts
    3307 *
    3308                 .endc
    3309 *
    3310                 .page
    3311 *************************************************************************
    3312 *                                                                       *
    3313 *                       Constant definitions                            *
    3314 *                       --------------------                            *
    3315 *************************************************************************
    3316 *
     3307
     3308                .endc
     3309
     3310                .page
     3311|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     3312|                                                                       |
     3313|                       Constant definitions                            |
     3314|                       --------------------                            |
     3315|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     3316
    33173317                .even
    3318 *
     3318
    33193319                .ifne   BUCHLA
    3320 *
    3321 * Buchla 700 tables:
    3322 *
    3323 * t13tab -- Trap-13 pointer table -- Primary BIOS functions
    3324 * ------    -----------------------------------------------
    3325 t13tab:         dc.w    12                      * Number of Trap-13 routines
    3326 *
    3327                 dc.l    nullrts                 * 0 - (getmpb)
    3328                 dc.l    bconstat                * 1 - bconstat
    3329                 dc.l    bconin                  * 2 - bconin
    3330                 dc.l    bconout                 * 3 - bconout
    3331                 dc.l    rwabs                   * 4 - rwabs
    3332                 dc.l    setexec                 * 5 - setexec
    3333                 dc.l    nullrts                 * 6 - (tickcal)
    3334                 dc.l    getbpb                  * 7 - getbpb
    3335                 dc.l    bcostat                 * 8 - bcostat
    3336                 dc.l    mediach                 * 9 - mediach
    3337                 dc.l    drvmap                  * 10 - drvmap
    3338                 dc.l    nullrts                 * 11 - (shift)
    3339 *
    3340                 .page
    3341 *
    3342 * t14tab -- Trap-14 pointer table -- Extended BIOS functions (Buchla 700 only)
    3343 * ------    ------------------------------------------------------------------
    3344 t14tab:         dc.w    10                      * Number of trap14 routines
    3345 *
    3346                 dc.l    piorec                  * 0 - Get iorec address
    3347                 dc.l    setport                 * 1 - Set ACIA parameters
    3348                 dc.l    floprd                  * 2 - Read floppy
    3349                 dc.l    flopwr                  * 3 - Write floppy
    3350                 dc.l    flopfmt                 * 4 - Format floppy
    3351                 dc.l    flopver                 * 5 - Verify floppy
    3352                 dc.l    protobt                 * 6 - Create prototype boot sec.
    3353                 dc.l    rand                    * 7 - Generate random number
    3354                 dc.l    api_get                 * 8 - Get analog input
    3355                 dc.l    api_zap                 * 9 - Clear analog FIFO
    3356 *
    3357                 .endc
    3358 *
     3320
     3321| Buchla 700 tables:
     3322
     3323| t13tab -- Trap-13 pointer table -- Primary BIOS functions
     3324| ------    -----------------------------------------------
     3325t13tab:         dc.w    12                      | Number of Trap-13 routines
     3326
     3327                dc.l    nullrts                 | 0 - (getmpb)
     3328                dc.l    bconstat                | 1 - bconstat
     3329                dc.l    bconin                  | 2 - bconin
     3330                dc.l    bconout                 | 3 - bconout
     3331                dc.l    rwabs                   | 4 - rwabs
     3332                dc.l    setexec                 | 5 - setexec
     3333                dc.l    nullrts                 | 6 - (tickcal)
     3334                dc.l    getbpb                  | 7 - getbpb
     3335                dc.l    bcostat                 | 8 - bcostat
     3336                dc.l    mediach                 | 9 - mediach
     3337                dc.l    drvmap                  | 10 - drvmap
     3338                dc.l    nullrts                 | 11 - (shift)
     3339
     3340                .page
     3341
     3342| t14tab -- Trap-14 pointer table -- Extended BIOS functions (Buchla 700 only)
     3343| ------    ------------------------------------------------------------------
     3344t14tab:         dc.w    10                      | Number of trap14 routines
     3345
     3346                dc.l    piorec                  | 0 - Get iorec address
     3347                dc.l    setport                 | 1 - Set ACIA parameters
     3348                dc.l    floprd                  | 2 - Read floppy
     3349                dc.l    flopwr                  | 3 - Write floppy
     3350                dc.l    flopfmt                 | 4 - Format floppy
     3351                dc.l    flopver                 | 5 - Verify floppy
     3352                dc.l    protobt                 | 6 - Create prototype boot sec.
     3353                dc.l    rand                    | 7 - Generate random number
     3354                dc.l    api_get                 | 8 - Get analog input
     3355                dc.l    api_zap                 | 9 - Clear analog FIFO
     3356
     3357                .endc
     3358
    33593359                .even
    3360 *
     3360
    33613361                .ifeq   BUCHLA
    3362 *
    3363 * NASA 3D Helmet tables:
    3364 *
    3365 * t13tab -- Trap-13 pointer table -- Primary BIOS functions
    3366 * ------    -----------------------------------------------
    3367 t13tab:         dc.w    12                      * Number of Trap-13 routines
    3368 *
    3369                 dc.l    nullrts                 * 0 - (getmpb)
    3370                 dc.l    bconstat                * 1 - bconstat
    3371                 dc.l    bconin                  * 2 - bconin
    3372                 dc.l    bconout                 * 3 - bconout
    3373                 dc.l    nullrts                 * 4 - (rwabs)
    3374                 dc.l    setexec                 * 5 - setexec
    3375                 dc.l    nullrts                 * 6 - (tickcal)
    3376                 dc.l    nullrts                 * 7 - (getbpb)
    3377                 dc.l    bcostat                 * 8 - bcostat
    3378                 dc.l    nullrts                 * 9 - (mediach)
    3379                 dc.l    nullrts                 * 10 - (drvmap)
    3380                 dc.l    nullrts                 * 11 - (shift)
    3381 *
    3382                 .page
    3383 *
    3384 * t14tab -- Trap-14 pointer table -- Extended BIOS functions (Buchla 700 only)
    3385 * ------    ------------------------------------------------------------------
    3386 t14tab:         dc.w    10                      * Number of trap14 routines
    3387 *
    3388                 dc.l    piorec                  * 0 - Get iorec address
    3389                 dc.l    setport                 * 1 - Set ACIA parameters
    3390                 dc.l    nullrts                 * 2 - (Read floppy)
    3391                 dc.l    nullrts                 * 3 - (Write floppy)
    3392                 dc.l    nullrts                 * 4 - (Format floppy)
    3393                 dc.l    nullrts                 * 5 - (Verify floppy)
    3394                 dc.l    nullrts                 * 6 - (Create prototype boot sec.)
    3395                 dc.l    nullrts                 * 7 - (Generate random number)
    3396                 dc.l    nullrts                 * 8 - (Get analog input)
    3397                 dc.l    nullrts                 * 9 - (Clear analog FIFO)
    3398 *
    3399                 .endc
    3400 *
    3401                 .page
    3402 *
    3403 * cdt01 -- Character device dispatch table #1 -- input status
    3404 * -----    --------------------------------------------------
    3405 cdt01:          dc.l    sr1ist                  * 0 - PRT -- Printer
    3406                 dc.l    sr2ist                  * 1 - AUX -- Serial-2
    3407                 dc.l    sr2ist                  * 2 - CON -- Console
    3408 *
     3362
     3363| NASA 3D Helmet tables:
     3364
     3365| t13tab -- Trap-13 pointer table -- Primary BIOS functions
     3366| ------    -----------------------------------------------
     3367t13tab:         dc.w    12                      | Number of Trap-13 routines
     3368
     3369                dc.l    nullrts                 | 0 - (getmpb)
     3370                dc.l    bconstat                | 1 - bconstat
     3371                dc.l    bconin                  | 2 - bconin
     3372                dc.l    bconout                 | 3 - bconout
     3373                dc.l    nullrts                 | 4 - (rwabs)
     3374                dc.l    setexec                 | 5 - setexec
     3375                dc.l    nullrts                 | 6 - (tickcal)
     3376                dc.l    nullrts                 | 7 - (getbpb)
     3377                dc.l    bcostat                 | 8 - bcostat
     3378                dc.l    nullrts                 | 9 - (mediach)
     3379                dc.l    nullrts                 | 10 - (drvmap)
     3380                dc.l    nullrts                 | 11 - (shift)
     3381
     3382                .page
     3383
     3384| t14tab -- Trap-14 pointer table -- Extended BIOS functions (Buchla 700 only)
     3385| ------    ------------------------------------------------------------------
     3386t14tab:         dc.w    10                      | Number of trap14 routines
     3387
     3388                dc.l    piorec                  | 0 - Get iorec address
     3389                dc.l    setport                 | 1 - Set ACIA parameters
     3390                dc.l    nullrts                 | 2 - (Read floppy)
     3391                dc.l    nullrts                 | 3 - (Write floppy)
     3392                dc.l    nullrts                 | 4 - (Format floppy)
     3393                dc.l    nullrts                 | 5 - (Verify floppy)
     3394                dc.l    nullrts                 | 6 - (Create prototype boot sec.)
     3395                dc.l    nullrts                 | 7 - (Generate random number)
     3396                dc.l    nullrts                 | 8 - (Get analog input)
     3397                dc.l    nullrts                 | 9 - (Clear analog FIFO)
     3398
     3399                .endc
     3400
     3401                .page
     3402
     3403| cdt01 -- Character device dispatch table #1 -- input status
     3404| -----    --------------------------------------------------
     3405cdt01:          dc.l    sr1ist                  | 0 - PRT -- Printer
     3406                dc.l    sr2ist                  | 1 - AUX -- Serial-2
     3407                dc.l    sr2ist                  | 2 - CON -- Console
     3408
    34093409                .ifne   BUCHLA
    3410 *
    3411                 dc.l    mc1ist                  * 3 - MC1 -- MIDI-1
    3412                 dc.l    mc2ist                  * 4 - MC2 -- MIDI-2
    3413 *
    3414                 .endc
    3415 *
    3416 * cdt02 -- Character device dispatch table #2 -- input
    3417 * -----    -------------------------------------------
    3418 cdt02:          dc.l    sr1inp                  * 0 - PRT -- Printer
    3419                 dc.l    sr2inp                  * 1 - AUX -- Serial-2
    3420                 dc.l    sr2inp                  * 2 - CON -- Console
    3421 *
     3410
     3411                dc.l    mc1ist                  | 3 - MC1 -- MIDI-1
     3412                dc.l    mc2ist                  | 4 - MC2 -- MIDI-2
     3413
     3414                .endc
     3415
     3416| cdt02 -- Character device dispatch table #2 -- input
     3417| -----    -------------------------------------------
     3418cdt02:          dc.l    sr1inp                  | 0 - PRT -- Printer
     3419                dc.l    sr2inp                  | 1 - AUX -- Serial-2
     3420                dc.l    sr2inp                  | 2 - CON -- Console
     3421
    34223422                .ifne   BUCHLA
    3423 *
    3424                 dc.l    mc1inp                  * 3 - MC1 -- MIDI-1
    3425                 dc.l    mc2inp                  * 4 - MC2 -- MIDI-2
    3426 *
    3427                 .endc
    3428 *
    3429 * cdt03 -- Character device dispatch table #3 -- output
    3430 * -----    --------------------------------------------
    3431 cdt03:          dc.l    sr1out                  * 0 - PRT -- Printer
    3432                 dc.l    sr2out                  * 1 - AUX -- Serial-2
    3433                 dc.l    sr2out                  * 2 - CON -- Console
     3423
     3424                dc.l    mc1inp                  | 3 - MC1 -- MIDI-1
     3425                dc.l    mc2inp                  | 4 - MC2 -- MIDI-2
     3426
     3427                .endc
     3428
     3429| cdt03 -- Character device dispatch table #3 -- output
     3430| -----    --------------------------------------------
     3431cdt03:          dc.l    sr1out                  | 0 - PRT -- Printer
     3432                dc.l    sr2out                  | 1 - AUX -- Serial-2
     3433                dc.l    sr2out                  | 2 - CON -- Console
    34343434                .ifne   BUCHLA
    3435 *
    3436                 dc.l    mc1out                  * 3 - MC1 -- MIDI-1
    3437                 dc.l    mc2out                  * 4 - MC2 -- MIDI-2
    3438 *
    3439                 .endc
    3440 *
    3441 * cdt04 -- Character device dispatch table #4 -- output status
    3442 * -----    ---------------------------------------------------
    3443 cdt04:          dc.l    sr1ost                  * 0 - PRT -- Printer
    3444                 dc.l    sr2ost                  * 1 - AUX -- Serial-2
    3445                 dc.l    sr2ost                  * 2 - CON -- Console
     3435
     3436                dc.l    mc1out                  | 3 - MC1 -- MIDI-1
     3437                dc.l    mc2out                  | 4 - MC2 -- MIDI-2
     3438
     3439                .endc
     3440
     3441| cdt04 -- Character device dispatch table #4 -- output status
     3442| -----    ---------------------------------------------------
     3443cdt04:          dc.l    sr1ost                  | 0 - PRT -- Printer
     3444                dc.l    sr2ost                  | 1 - AUX -- Serial-2
     3445                dc.l    sr2ost                  | 2 - CON -- Console
    34463446                .ifne   BUCHLA
    3447 *
    3448                 dc.l    mc1ost                  * 3 - MC1 -- MIDI-1
    3449                 dc.l    mc2ost                  * 4 - MC2 -- MIDI-2
    3450 *
    3451                 .endc
    3452 *
    3453                 .page
    3454 *
    3455 * iorec defaults:
    3456 * ---------------
    3457 * Serial-1:
    3458 * ---------
     3447
     3448                dc.l    mc1ost                  | 3 - MC1 -- MIDI-1
     3449                dc.l    mc2ost                  | 4 - MC2 -- MIDI-2
     3450
     3451                .endc
     3452
     3453                .page
     3454
     3455| iorec defaults:
     3456| ---------------
     3457| Serial-1:
     3458| ---------
    34593459sr1dflt:        dc.l    sr1ibuf
    34603460                dc.w    SR1IBS
     
    34723472                dc.b    0,0
    34733473                dc.w    0,0
    3474 *
    3475 * Serial-2:
    3476 * ---------
     3474
     3475| Serial-2:
     3476| ---------
    34773477sr2dflt:        dc.l    sr2ibuf
    34783478                dc.w    SR2IBS
     
    34903490                dc.b    0,0
    34913491                dc.w    0,0
    3492 *
    3493                 .page
    3494 *
     3492
     3493                .page
     3494
    34953495                .ifne   BUCHLA
    3496 *
    3497 * MIDI-1:
    3498 * -------
     3496
     3497| MIDI-1:
     3498| -------
    34993499mc1dflt:        dc.l    mc1ibuf
    35003500                dc.w    MC1IBS
     
    35123512                dc.b    0,0
    35133513                dc.w    0,0
    3514 *
    3515 * MIDI-2:
    3516 * -------
     3514
     3515| MIDI-2:
     3516| -------
    35173517mc2dflt:        dc.l    mc2ibuf
    35183518                dc.w    MC2IBS
     
    35303530                dc.b    0,0
    35313531                dc.w    0,0
    3532 *
    3533                 .endc
    3534 *
    3535                 .page
    3536 *
    3537 * brtable -- Baud rate setup table
    3538 * -------    ---------------------
    3539 brtable:        dc.b    BR_19K2         * 0 - 19200 baud
    3540                 dc.b    BR_9600         * 1 -  9600 baud
    3541                 dc.b    BR_4800         * 2 -  4800 baud
    3542                 dc.b    BR_3600         * 3 -  3600 baud
    3543                 dc.b    BR_2400         * 4 -  2400 baud
    3544                 dc.b    BR_7200         * 5 -  7200 baud  (2000 on Atari)
    3545                 dc.b    BR_1800         * 6 -  1800 baud
    3546                 dc.b    BR_1200         * 7 -  1200 baud
    3547                 dc.b    BR_600          * 8 -   600 baud
    3548                 dc.b    BR_300          * 9 -   300 baud
    3549 *
    3550 * iortab -- iorec pointer table
    3551 * ------    -------------------
    3552 iortab:         dc.l    sr1iorec        * 0 - PRT Serial-1 Printer
    3553                 dc.l    sr2iorec        * 1 - AUX Serial-2 Host
    3554                 dc.l    sr2iorec        * 2 - CON Serial-2 Console
    3555 *
     3532
     3533                .endc
     3534
     3535                .page
     3536
     3537| brtable -- Baud rate setup table
     3538| -------    ---------------------
     3539brtable:        dc.b    BR_19K2         | 0 - 19200 baud
     3540                dc.b    BR_9600         | 1 -  9600 baud
     3541                dc.b    BR_4800         | 2 -  4800 baud
     3542                dc.b    BR_3600         | 3 -  3600 baud
     3543                dc.b    BR_2400         | 4 -  2400 baud
     3544                dc.b    BR_7200         | 5 -  7200 baud  (2000 on Atari)
     3545                dc.b    BR_1800         | 6 -  1800 baud
     3546                dc.b    BR_1200         | 7 -  1200 baud
     3547                dc.b    BR_600          | 8 -   600 baud
     3548                dc.b    BR_300          | 9 -   300 baud
     3549
     3550| iortab -- iorec pointer table
     3551| ------    -------------------
     3552iortab:         dc.l    sr1iorec        | 0 - PRT Serial-1 Printer
     3553                dc.l    sr2iorec        | 1 - AUX Serial-2 Host
     3554                dc.l    sr2iorec        | 2 - CON Serial-2 Console
     3555
    35563556                .ifne   BUCHLA
    3557 *
    3558                 dc.l    mc1iorec        * 3 - MC1 MIDI-1   MIDI port #1
    3559                 dc.l    mc2iorec        * 4 - MC2 MIDI-2   MIDI port #2
    3560 *
    3561                 .endc
    3562 *
    3563 * aciatab -- iorec and ACIA pointer table
    3564 * -------    ----------------------------
    3565 aciatab:        dc.l    sr1iorec,SR1ACIA        * 0 - PRT Serial-1
    3566                 dc.l    sr2iorec,SR2ACIA        * 1 - AUX Serial-2
    3567                 dc.l    sr2iorec,SR2ACIA        * 2 - CON Serial-2
    3568 *
     3557
     3558                dc.l    mc1iorec        | 3 - MC1 MIDI-1   MIDI port #1
     3559                dc.l    mc2iorec        | 4 - MC2 MIDI-2   MIDI port #2
     3560
     3561                .endc
     3562
     3563| aciatab -- iorec and ACIA pointer table
     3564| -------    ----------------------------
     3565aciatab:        dc.l    sr1iorec,SR1ACIA        | 0 - PRT Serial-1
     3566                dc.l    sr2iorec,SR2ACIA        | 1 - AUX Serial-2
     3567                dc.l    sr2iorec,SR2ACIA        | 2 - CON Serial-2
     3568
    35693569                .ifne   BUCHLA
    3570 *
    3571                 dc.l    mc1iorec,MC1ACIA        * 3 - MC1 MIDI-1
    3572                 dc.l    mc2iorec,MC2ACIA        * 4 - MC2 MIDI-2
    3573 *
    3574                 .endc
    3575 *
    3576                 .page
    3577 *
     3570
     3571                dc.l    mc1iorec,MC1ACIA        | 3 - MC1 MIDI-1
     3572                dc.l    mc2iorec,MC2ACIA        | 4 - MC2 MIDI-2
     3573
     3574                .endc
     3575
     3576                .page
     3577
    35783578                .ifne   BUCHLA
    3579 *
    3580 * pbpbtab -- Prototype BPB data table  (BPS..NHID)  19 bytes per entry
    3581 * -------    ---------------------------------------------------------
    3582 *
    3583 * 0 -- 40 tracks, single sided (180K)
    3584 *
    3585 pbpbtab:        dc.b    $00,$02,$01,$01,$00,$02,$40,$00
    3586                 dc.b    $68,$01,$FC,$02,$00,$09,$00,$01
    3587                 dc.b    $00,$00,$00
    3588 *
    3589 * 1 -- 40 tracks, double sided (360K)
    3590 *
    3591                 dc.b    $00,$02,$02,$01,$00,$02,$70,$00
    3592                 dc.b    $D0,$02,$FD,$02,$00,$09,$00,$02
    3593                 dc.b    $00,$00,$00
    3594 *
    3595 * 2 -- 80 tracks, single sided (360K)
    3596 *
    3597                 dc.b    $00,$02,$02,$01,$00,$02,$70,$00
    3598                 dc.b    $D0,$02,$F8,$05,$00,$09,$00,$01
    3599                 dc.b    $00,$00,$00
    3600 *
    3601 * 3 -- 80 tracks, double sided (720K)
    3602 *
    3603                 dc.b    $00,$02,$02,$01,$00,$02,$70,$00
    3604                 dc.b    $A0,$05,$F9,$05,$00,$09,$00,$02
    3605                 dc.b    $00,$00,$00
    3606 *
    3607 * VSDD initialization table
    3608 *
     3579
     3580| pbpbtab -- Prototype BPB data table  (BPS..NHID)  19 bytes per entry
     3581| -------    ---------------------------------------------------------
     3582
     3583| 0 -- 40 tracks, single sided (180K)
     3584
     3585pbpbtab:        dc.b    0x00,0x02,0x01,0x01,0x00,0x02,0x40,0x00
     3586                dc.b    0x68,0x01,0xFC,0x02,0x00,0x09,0x00,0x01
     3587                dc.b    0x00,0x00,0x00
     3588
     3589| 1 -- 40 tracks, double sided (360K)
     3590
     3591                dc.b    0x00,0x02,0x02,0x01,0x00,0x02,0x70,0x00
     3592                dc.b    0xD0,0x02,0xFD,0x02,0x00,0x09,0x00,0x02
     3593                dc.b    0x00,0x00,0x00
     3594
     3595| 2 -- 80 tracks, single sided (360K)
     3596
     3597                dc.b    0x00,0x02,0x02,0x01,0x00,0x02,0x70,0x00
     3598                dc.b    0xD0,0x02,0xF8,0x05,0x00,0x09,0x00,0x01
     3599                dc.b    0x00,0x00,0x00
     3600
     3601| 3 -- 80 tracks, double sided (720K)
     3602
     3603                dc.b    0x00,0x02,0x02,0x01,0x00,0x02,0x70,0x00
     3604                dc.b    0xA0,0x05,0xF9,0x05,0x00,0x09,0x00,0x02
     3605                dc.b    0x00,0x00,0x00
     3606
     3607| VSDD initialization table
     3608
    36093609                .even
    3610 *
    3611 vsddtab:        dc.w    $8252           * R0    Mode word 0
    3612                 dc.w    $E474           * R1    Mode word 1
    3613                 dc.w    $0006           * R2    Register window base
    3614                 dc.w    $0100           * R3    Data window base
    3615                 dc.w    $0000           * R4    Data length mask
    3616                 dc.w    $0000           * R5    Data segment base
    3617                 dc.w    $0001           * R6    Priority access count
    3618                 dc.w    $0040           * R7    ODT base
    3619                 dc.w    $0080           * R8    AT base
    3620                 dc.w    $0010           * R9    CLT base
    3621                 dc.w    $0011           * R10   CG bases
    3622                 dc.w    $0000           * R11   AT counter  (R/O)
    3623 *
    3624                 dc.w    $0C08           * R12   HC0 =  3, VC0 =   8
    3625                 dc.w    $140A           * R13   HC1 =  5, VC1 =  10
    3626                 dc.w    $9568           * R14   HC2 = 37, VC2 = 360
    3627                 dc.w    $A16A           * R15   HC3 = 40, VC3 = 362
    3628 *
    3629 vsddit01:       dc.w    $8253           * R0 with UCF = 1, DEN = 0
    3630 vsddit02:       dc.w    $825B           * R0 with UCF = 1, DEN = 1
    3631 *
    3632                 .page
    3633 *
    3634 * analog processor input state table
    3635 *
    3636 api_tab:        dc.b    0,1,1,1,1,1,1,1,1,1     * 0..9
    3637                 dc.b    1,1,1,1,1,1,1,1,1,1     * 10..19
    3638                 dc.b    1,1,1,1,1               * 20..24
    3639                 dc.b    3,3,3,3,3               * 25..29
    3640                 dc.b    3,3,3,3,3,3,3,3,3       * 30..38
    3641                 dc.b    5                       * 39
    3642                 dc.b    5,5,5,5,5,5,5,5,5,5     * 40..49
    3643                 dc.b    5,5,5                   * 50..52
    3644                 dc.b    3,3,3,3,3,3,3           * 53..59
    3645                 dc.b    5,5,5,5,5,5,5,5,5,5     * 60..69
    3646                 dc.b    5,5,5                   * 70..72
    3647                 dc.b    6,6,6,6,6,6,6           * 73..79
    3648                 dc.b    6,6,6                   * 80..82
    3649 *
     3610
     3611vsddtab:        dc.w    0x8252          | R0    Mode word 0
     3612                dc.w    0xE474          | R1    Mode word 1
     3613                dc.w    0x0006          | R2    Register window base
     3614                dc.w    0x0100          | R3    Data window base
     3615                dc.w    0x0000          | R4    Data length mask
     3616                dc.w    0x0000          | R5    Data segment base
     3617                dc.w    0x0001          | R6    Priority access count
     3618                dc.w    0x0040          | R7    ODT base
     3619                dc.w    0x0080          | R8    AT base
     3620                dc.w    0x0010          | R9    CLT base
     3621                dc.w    0x0011          | R10   CG bases
     3622                dc.w    0x0000          | R11   AT counter  (R/O)
     3623
     3624                dc.w    0x0C08          | R12   HC0 =  3, VC0 =   8
     3625                dc.w    0x140A          | R13   HC1 =  5, VC1 =  10
     3626                dc.w    0x9568          | R14   HC2 = 37, VC2 = 360
     3627                dc.w    0xA16A          | R15   HC3 = 40, VC3 = 362
     3628
     3629vsddit01:       dc.w    0x8253          | R0 with UCF = 1, DEN = 0
     3630vsddit02:       dc.w    0x825B          | R0 with UCF = 1, DEN = 1
     3631
     3632                .page
     3633
     3634| analog processor input state table
     3635
     3636api_tab:        dc.b    0,1,1,1,1,1,1,1,1,1     | 0..9
     3637                dc.b    1,1,1,1,1,1,1,1,1,1     | 10..19
     3638                dc.b    1,1,1,1,1               | 20..24
     3639                dc.b    3,3,3,3,3               | 25..29
     3640                dc.b    3,3,3,3,3,3,3,3,3       | 30..38
     3641                dc.b    5                       | 39
     3642                dc.b    5,5,5,5,5,5,5,5,5,5     | 40..49
     3643                dc.b    5,5,5                   | 50..52
     3644                dc.b    3,3,3,3,3,3,3           | 53..59
     3645                dc.b    5,5,5,5,5,5,5,5,5,5     | 60..69
     3646                dc.b    5,5,5                   | 70..72
     3647                dc.b    6,6,6,6,6,6,6           | 73..79
     3648                dc.b    6,6,6                   | 80..82
     3649
    36503650                .even
    3651 *
    3652 * analog processor state transfer vector
    3653 *
     3651
     3652| analog processor state transfer vector
     3653
    36543654api_tv:         dc.l    api_s0,api_s1,api_s2,api_s3
    36553655                dc.l    api_s4,api_s5,api_s6
    3656 *
    3657                 .endc
    3658 *
    3659                 .page
    3660 *************************************************************************
    3661 *                                                                       *
    3662 *                       RAM storage definitions                         *
    3663 *                       -----------------------                         *
    3664 *************************************************************************
    3665 *
     3656
     3657                .endc
     3658
     3659                .page
     3660|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     3661|                                                                       |
     3662|                       RAM storage definitions                         |
     3663|                       -----------------------                         |
     3664|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
     3665
    36663666                .bss
    36673667                .even
    3668 *
    3669 * RAM data area
    3670 * -------------
    3671 * WARNING:
    3672 * --------
    3673 * The variables from timevec through rsarea are permanently assigned so
    3674 * that we can link to certain bios variables without having to link to the
    3675 * bios object file itself.  Some of these get defined in hwdefs.s and in
    3676 * hwdefs.s so beware of changing them.
    3677 *
    3678 timevec:        ds.l    1               * System timer trap vector
    3679 critvec:        ds.l    1               * Critical error handler vector
    3680 termvec:        ds.l    1               * Process terminate hook vector
    3681 resvec3:        ds.l    1               * Reserved vector 3
    3682 resvec4:        ds.l    1               * Reserved vector 4
    3683 resvec5:        ds.l    1               * Reserved vector 5
    3684 resvec6:        ds.l    1               * Reserved vector 6
    3685 resvec7:        ds.l    1               * Reserved vector 7
    3686 *
    3687 fc_sw:          ds.w    1               * Frame clock switch (<0=dn, 0=off, >0=up)
    3688 fc_val:         ds.l    1               * Frame clock value  (0..FCMAX)
    3689 *
    3690 _wzcrsh:        ds.w    1               * Crash area: flag for ROMP
    3691 _crshsr:        ds.w    1               * Crash area: SR
    3692 _crshpc:        ds.l    1               * Crash area: PC
    3693 _crshsp:        ds.l    1               * Crash area: SP
    3694 _crshus:        ds.l    1               * Crash area: USP
    3695 _crshvc:        ds.l    1               * Crash area: vector # in MS byte
    3696 _crshrg:        ds.l    16              * Crash area: registers
    3697 _crshst:        ds.w    16              * Crash area: top 16 words of stack
    3698 *
    3699 * The area from biosram to SSTACK-1 is cleared on reset.
    3700 * ------------------------------------------------------
    3701 biosram         .equ    *               * Start of BIOS RAM variables
    3702 *
     3668
     3669| RAM data area
     3670| -------------
     3671| WARNING:
     3672| --------
     3673| The variables from timevec through rsarea are permanently assigned so
     3674| that we can link to certain bios variables without having to link to the
     3675| bios object file itself.  Some of these get defined in hwdefs.s and in
     3676| hwdefs.s so beware of changing them.
     3677
     3678timevec:        ds.l    1               | System timer trap vector
     3679critvec:        ds.l    1               | Critical error handler vector
     3680termvec:        ds.l    1               | Process terminate hook vector
     3681resvec3:        ds.l    1               | Reserved vector 3
     3682resvec4:        ds.l    1               | Reserved vector 4
     3683resvec5:        ds.l    1               | Reserved vector 5
     3684resvec6:        ds.l    1               | Reserved vector 6
     3685resvec7:        ds.l    1               | Reserved vector 7
     3686
     3687fc_sw:          ds.w    1               | Frame clock switch (<0=dn, 0=off, >0=up)
     3688fc_val:         ds.l    1               | Frame clock value  (0..FCMAX)
     3689
     3690_wzcrsh:        ds.w    1               | Crash area: flag for ROMP
     3691_crshsr:        ds.w    1               | Crash area: SR
     3692_crshpc:        ds.l    1               | Crash area: PC
     3693_crshsp:        ds.l    1               | Crash area: SP
     3694_crshus:        ds.l    1               | Crash area: USP
     3695_crshvc:        ds.l    1               | Crash area: vector # in MS byte
     3696_crshrg:        ds.l    16              | Crash area: registers
     3697_crshst:        ds.w    16              | Crash area: top 16 words of stack
     3698
     3699| The area from biosram to SSTACK-1 is cleared on reset.
     3700| ------------------------------------------------------
     3701biosram:                                | Start of BIOS RAM variables
     3702
    37033703                .ifne   BUCHLA
    3704 *
    3705 _hz_1k:         ds.l    1               * 1000 Hz clock
    3706 _hz_200:        ds.l    1               * 200 Hz clock
    3707 frclock:        ds.l    1               * 50 Hz clock
    3708 t1count:        ds.w    1               * Timer 1 count
    3709 t2count:        ds.w    1               * Timer 2 count
    3710 t3count:        ds.w    1               * Timer 3 count
    3711 *
    3712 seekrate:       ds.w    1               * Seek rate
    3713 cdev:           ds.w    1               * Current drive
    3714 ctrack:         ds.w    1               * Current track
    3715 csect:          ds.w    1               * Current sector
    3716 cside:          ds.w    1               * Current side
    3717 ccount:         ds.w    1               * Current sector count
    3718 spt:            ds.w    1               * Sectors per track
    3719 interlv:        ds.w    1               * Sector interleave count
    3720 virgin:         ds.w    1               * Initial formatting data
    3721 deferr:         ds.w    1               * Default error number
    3722 curerr:         ds.w    1               * Current error number
    3723 *
    3724 cdma:           ds.l    1               * Current DMA address
    3725 edma:           ds.l    1               * Ending DMA address
    3726 tmpdma:         ds.l    1               * Temporary DMA address
    3727 *
    3728                 .endc
    3729 *
    3730 rseed:          ds.l    1               * Random number seed
    3731 *
    3732 savptr:         ds.l    1               * Pointer to register save area
    3733 *
    3734 _rsflag:        ds.l    1               * Register save area overflow flag
    3735                 ds.l    18*32           * Register save area  (32 levels)
    3736 rsarea:         ds.l    1               * Dummy long word at top of save area
    3737 *
    3738 * ***** end of the permanently assigned bios variables *****
    3739 *
    3740                 .page
    3741 *
     3704
     3705_hz_1k:         ds.l    1               | 1000 Hz clock
     3706_hz_200:        ds.l    1               | 200 Hz clock
     3707frclock:        ds.l    1               | 50 Hz clock
     3708t1count:        ds.w    1               | Timer 1 count
     3709t2count:        ds.w    1               | Timer 2 count
     3710t3count:        ds.w    1               | Timer 3 count
     3711
     3712seekrate:       ds.w    1               | Seek rate
     3713cdev:           ds.w    1               | Current drive
     3714ctrack:         ds.w    1               | Current track
     3715csect:          ds.w    1               | Current sector
     3716cside:          ds.w    1               | Current side
     3717ccount:         ds.w    1               | Current sector count
     3718spt:            ds.w    1               | Sectors per track
     3719interlv:        ds.w    1               | Sector interleave count
     3720virgin:         ds.w    1               | Initial formatting data
     3721deferr:         ds.w    1               | Default error number
     3722curerr:         ds.w    1               | Current error number
     3723
     3724cdma:           ds.l    1               | Current DMA address
     3725edma:           ds.l    1               | Ending DMA address
     3726tmpdma:         ds.l    1               | Temporary DMA address
     3727
     3728                .endc
     3729
     3730rseed:          ds.l    1               | Random number seed
     3731
     3732savptr:         ds.l    1               | Pointer to register save area
     3733
     3734_rsflag:        ds.l    1               | Register save area overflow flag
     3735                ds.l    18|32           | Register save area  (32 levels)
     3736rsarea:         ds.l    1               | Dummy long word at top of save area
     3737
     3738| ||||| end of the permanently assigned bios variables |||||
     3739
     3740                .page
     3741
    37423742                .ifne   BUCHLA
    3743 *
    3744 acctim:         ds.l    2               * Accumulated disk time table
    3745 maxactim:       ds.l    1               * Maximum acctim value
    3746 hdv_init:       ds.l    1               * Disk init vector
    3747 hdv_bpb:        ds.l    1               * Disk get bpb vector
    3748 hdv_rw:         ds.l    1               * Disk r/w vector
    3749 hdv_boot:       ds.l    1               * Disk boot vector
    3750 hdv_mchg:       ds.l    1               * Disk media change vector
    3751 drvbits:        ds.l    1               * Drive map bits
    3752 dskbufp:        ds.l    1               * Disk buffer pointer
    3753                 .page
    3754 nflops:         ds.w    1               * Number of drives
    3755 disknum:        ds.w    1               * Current disk number
    3756 booted:         ds.w    1               * Most recent boot device or -1
    3757 flock:          ds.w    1               * Floppy semaphore
    3758 fverify:        ds.w    1               * Floppy verify flag
    3759 *
    3760 tdiv1:          ds.w    1               * Timer divider 1  (divides _hz_1k)
    3761 tdiv2:          ds.w    1               * Timer divider 2  (divides _hz_200)
    3762 *
    3763 retrycnt:       ds.w    1               * Re-try count
    3764 wpstatus:       ds.w    1               * Write protect status table
    3765 wplatch:        ds.w    1               * Write protect latch table
    3766 bootdev:        ds.w    1               * Boot device number
    3767 *
    3768 motoron:        ds.w    1               * Motor-on flag
    3769 deslflag:       ds.w    1               * Drive deselect flag
    3770 *
    3771                 .endc
    3772 *
    3773 flpsrsv:        ds.w    1               * Status register save area
    3774 flpregs:        ds.l    16              * Register save area
    3775 *
     3743
     3744acctim:         ds.l    2               | Accumulated disk time table
     3745maxactim:       ds.l    1               | Maximum acctim value
     3746hdv_init:       ds.l    1               | Disk init vector
     3747hdv_bpb:        ds.l    1               | Disk get bpb vector
     3748hdv_rw:         ds.l    1               | Disk r/w vector
     3749hdv_boot:       ds.l    1               | Disk boot vector
     3750hdv_mchg:       ds.l    1               | Disk media change vector
     3751drvbits:        ds.l    1               | Drive map bits
     3752dskbufp:        ds.l    1               | Disk buffer pointer
     3753                .page
     3754nflops:         ds.w    1               | Number of drives
     3755disknum:        ds.w    1               | Current disk number
     3756booted:         ds.w    1               | Most recent boot device or -1
     3757flock:          ds.w    1               | Floppy semaphore
     3758fverify:        ds.w    1               | Floppy verify flag
     3759
     3760tdiv1:          ds.w    1               | Timer divider 1  (divides _hz_1k)
     3761tdiv2:          ds.w    1               | Timer divider 2  (divides _hz_200)
     3762
     3763retrycnt:       ds.w    1               | Re-try count
     3764wpstatus:       ds.w    1               | Write protect status table
     3765wplatch:        ds.w    1               | Write protect latch table
     3766bootdev:        ds.w    1               | Boot device number
     3767
     3768motoron:        ds.w    1               | Motor-on flag
     3769deslflag:       ds.w    1               | Drive deselect flag
     3770
     3771                .endc
     3772
     3773flpsrsv:        ds.w    1               | Status register save area
     3774flpregs:        ds.l    16              | Register save area
     3775
    37763776                .ifne   BUCHLA
    3777 *
    3778 dsb0:           ds.l    1               * Drive A DSB
    3779 dsb1:           ds.l    1               * Drive B DSB
    3780 *
    3781 dskmode:        ds.b    2               * Disk change mode table
    3782 dskerrs:        ds.w    2               * Disk error code table
    3783 drvbpbs:        ds.w    16*2            * Disk BPB save area
    3784 *
    3785                 .endc
    3786 *
    3787                 .page
    3788 *
    3789 sr1iorec:       ds.b    IORECLN         * Serial-1 iorec structure
    3790 sr2iorec:       ds.b    IORECLN         * Serial-2 iorec structure
    3791 *
     3777
     3778dsb0:           ds.l    1               | Drive A DSB
     3779dsb1:           ds.l    1               | Drive B DSB
     3780
     3781dskmode:        ds.b    2               | Disk change mode table
     3782dskerrs:        ds.w    2               | Disk error code table
     3783drvbpbs:        ds.w    16|2            | Disk BPB save area
     3784
     3785                .endc
     3786
     3787                .page
     3788
     3789sr1iorec:       ds.b    IORECLN         | Serial-1 iorec structure
     3790sr2iorec:       ds.b    IORECLN         | Serial-2 iorec structure
     3791
    37923792                .ifne   BUCHLA
    3793 *
    3794 mc1iorec:       ds.b    IORECLN         * MIDI-1 iorec structure
    3795 mc2iorec:       ds.b    IORECLN         * MIDI-2 iorec structure
    3796 *
    3797                 .endc
    3798 *
    3799 sr1ibuf:        ds.b    SR1IBS          * Serial-1 input buffer
    3800 sr1obuf:        ds.b    SR1OBS          * Serial-1 output buffer
    3801 sr2ibuf:        ds.b    SR2IBS          * Serial-2 input buffer
    3802 sr2obuf:        ds.b    SR2OBS          * Serial-2 output buffer
    3803 *
     3793
     3794mc1iorec:       ds.b    IORECLN         | MIDI-1 iorec structure
     3795mc2iorec:       ds.b    IORECLN         | MIDI-2 iorec structure
     3796
     3797                .endc
     3798
     3799sr1ibuf:        ds.b    SR1IBS          | Serial-1 input buffer
     3800sr1obuf:        ds.b    SR1OBS          | Serial-1 output buffer
     3801sr2ibuf:        ds.b    SR2IBS          | Serial-2 input buffer
     3802sr2obuf:        ds.b    SR2OBS          | Serial-2 output buffer
     3803
    38043804                .ifne   BUCHLA
    3805 *
    3806 mc1ibuf:        ds.b    MC1IBS          * MIDI-1 input buffer
    3807 mc1obuf:        ds.b    MC1OBS          * MIDI-1 output buffer
    3808 mc2ibuf:        ds.b    MC2IBS          * MIDI-2 input buffer
    3809 mc2obuf:        ds.b    MC2OBS          * MIDI-2 output buffer
    3810 *
    3811 api_inp:        ds.b    1               * Analog processor input byte
    3812 api_bug:        ds.b    1               * Analog processor signal # "bug trap"
    3813 api_sv:         ds.b    1               * Analog processor state
    3814 api_svb:        ds.b    1               * Analog processor state "bug trap"
    3815 *
     3805
     3806mc1ibuf:        ds.b    MC1IBS          | MIDI-1 input buffer
     3807mc1obuf:        ds.b    MC1OBS          | MIDI-1 output buffer
     3808mc2ibuf:        ds.b    MC2IBS          | MIDI-2 input buffer
     3809mc2obuf:        ds.b    MC2OBS          | MIDI-2 output buffer
     3810
     3811api_inp:        ds.b    1               | Analog processor input byte
     3812api_bug:        ds.b    1               | Analog processor signal # "bug trap"
     3813api_sv:         ds.b    1               | Analog processor state
     3814api_svb:        ds.b    1               | Analog processor state "bug trap"
     3815
    38163816                .even
    3817 *
    3818 api_sig:        ds.b    1               * Analog signal number
    3819 api_val:        ds.b    1               * Analog value
    3820 *
    3821 api_fi:         ds.l    1               * Analog processor FIFO input pointer
    3822 api_fo:         ds.l    1               * Analog processor FIFO output pointer
    3823 api_fum:        ds.w    APISIZE         * Analog processor FIFO
    3824 api_fe          .equ    *               * End of analog processor FIFO
    3825 *
    3826                 .endc
    3827 *
     3817
     3818api_sig:        ds.b    1               | Analog signal number
     3819api_val:        ds.b    1               | Analog value
     3820
     3821api_fi:         ds.l    1               | Analog processor FIFO input pointer
     3822api_fo:         ds.l    1               | Analog processor FIFO output pointer
     3823api_fum:        ds.w    APISIZE         | Analog processor FIFO
     3824api_fe:                                 | End of analog processor FIFO
     3825
     3826                .endc
     3827
    38283828                .even
    3829 *
    3830 basepage:       ds.l    64              * Pseudo base page
    3831 *
    3832 buffer:         ds.b    1024            * Default disk buffer
    3833 *
    3834 biostop         .equ    *               * End of BIOS RAM
    3835 *
     3829
     3830basepage:       ds.l    64              | Pseudo base page
     3831
     3832buffer:         ds.b    1024            | Default disk buffer
     3833
     3834biostop:                                | End of BIOS RAM
     3835
    38363836                .end
  • rom/timeint.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * timeint.s -- timer interrupt handler
    3 * Version 9 -- 1988-06-20 -- D.N. Lynx Crowe
    4 * ------------------------------------------------------------------------------
    5 *
    6 * This code replaces the interrupt handler in bios.s, which is known to
    7 * have a bug in it, and adds support for the VSDD and an array of programable
    8 * timers with 1 Ms resolution.
    9 *
    10 * WARNING:  There are equates to addresses in the bios EPROM which may change
    11 * when the bios is reassembled.  If the bios is reassembled be sure to update
    12 * the equates flagged by "<<<=====".
    13 *
    14 * The addresses currently in the equates are for EPROMs dated 1988-04-18 or
    15 * 1988-06-20 ONLY.
    16 *
    17 * ------------------------------------------------------------------------------
    18 * Hardware timer usage:
    19 * ---------------------
    20 *       Timer 1         PLL divider for score clock -- fixed at 64
    21 *       Timer 2         PLL divider for score clock -- nominally 3200
    22 *       Timer 3         1 Ms Real Time Clock
    23 *
    24 * ------------------------------------------------------------------------------
    25 *
     1| ------------------------------------------------------------------------------
     2| timeint.s -- timer interrupt handler
     3| Version 9 -- 1988-06-20 -- D.N. Lynx Crowe
     4| ------------------------------------------------------------------------------
     5
     6| This code replaces the interrupt handler in bios.s, which is known to
     7| have a bug in it, and adds support for the VSDD and an array of programable
     8| timers with 1 Ms resolution.
     9
     10| WARNING:  There are equates to addresses in the bios EPROM which may change
     11| when the bios is reassembled.  If the bios is reassembled be sure to update
     12| the equates flagged by "<<<=====".
     13
     14| The addresses currently in the equates are for EPROMs dated 1988-04-18 or
     15| 1988-06-20 ONLY.
     16
     17| ------------------------------------------------------------------------------
     18| Hardware timer usage:
     19| ---------------------
     20|       Timer 1         PLL divider for score clock -- fixed at 64
     21|       Timer 2         PLL divider for score clock -- nominally 3200
     22|       Timer 3         1 Ms Real Time Clock
     23
     24| ------------------------------------------------------------------------------
     25
    2626                .text
    27 *
    28                 .xdef   _tsetup         * tsetup() -- timer setup function
    29                 .xdef   timeint         * timer interrupt handler
    30 *
    31                 .xdef   _timers         * timer array -- short timers[NTIMERS]
    32                 .xdef   _vi_clk         * VSDD scroll delay timer
    33                 .xdef   _vi_tag         * VSDD VI tag
    34                 .xdef   line            * Line we entered on
    35 *
    36                 .xref   lclsadr         * score object base address
    37                 .xref   lclscrl         * score object scroll offset
    38                 .xref   _v_odtab        * VSDD object descriptor table
    39                 .xref   _v_regs         * VSDD registers
    40 *
    41                 .page
    42 * ==============================================================================
    43 *
    44 * Equates to variables in bios.s:
    45 * -------------------------------
    46 * These variables are permanently assigned.
    47 *
    48 TIMEVEC         .equ    $00000400       * LONG - System timer trap vector
    49 *
    50 FC_SW           .equ    $00000420       * WORD - Frame clock switch
    51 FC_VAL          .equ    $00000422       * LONG - Frame clock value
    52 *
    53 HZ_1K           .equ    $0000049A       * LONG - 1000 Hz clock
    54 HZ_200          .equ    $0000049E       * LONG - 200 Hz clock
    55 FRCLOCK         .equ    $000004A2       * LONG - 50 Hz clock
    56 *
    57 T3COUNT         .equ    $000004AA       * WORD - Timer 3 count
    58 *
    59 * ------------------------------------------------------------------------------
    60 *
    61 * WARNING:  The address of "FLOCK" depends on the version of the bios EPROM.
    62 * The address below is for EPROMs dated 1988-04-18 ONLY.
    63 *
    64 FLOCK           .equ    $00000E0C       * WORD - Floppy semaphore       <<<=====
    65 *
    66 * ==============================================================================
    67 *
    68 * Equates to routines in bios.s:
    69 * ------------------------------
    70 *
    71 * WARNING:  The address of "FLOPVBL" depends on the version of the bios EPROM.
    72 * The address below is for EPROMs dated 1988-04-18 ONLY.
    73 *
    74 FLOPVBL         .equ    $001015EE       * floppy VI handler address     <<<=====
    75 *
    76 * ==============================================================================
    77 *
    78                 .page
    79 *
    80 * Hardware address equates:
    81 * -------------------------
    82 TI_VEC          .equ    $00000070       * Timer interrupt autovector
    83 *
    84 TIMER           .equ    $003A0001       * Timer base address
    85 *
    86 * ------------------------------------------------------------------------------
    87 *
    88 * Timer register equates:
    89 * -----------------------
    90 TIME_CRX        .equ    TIMER           * Control register 1 or 3
    91 TIME_CR2        .equ    TIMER+2         * Control register 2
    92 TIME_T1H        .equ    TIMER+4         * Timer 1 high byte
    93 TIME_T1L        .equ    TIMER+6         * Timer 1 low byte
    94 TIME_T2H        .equ    TIMER+8         * Timer 2 high byte
    95 TIME_T2L        .equ    TIMER+10        * Timer 2 low byte
    96 TIME_T3H        .equ    TIMER+12        * Timer 3 high byte
    97 TIME_T3L        .equ    TIMER+14        * Timer 3 low byte
    98 *
    99 * VSDD register offsets:
    100 * ----------------------
    101 VSDD_R5         .equ    10              * VSDD bank control register
    102 VSDD_R11        .equ    22              * VSDD access table register
    103 *
    104 * ==============================================================================
    105 *
    106 * Miscellaneous equates:
    107 * ----------------------
    108 IPL7            .equ    $0700           * IPL mask for interrupt disable
    109 *
    110 FCMAX           .equ    $00FFFFFF       * Maximum frame counter value
    111 FCMIN           .equ    $00000000       * Minimum frame counter value
    112 *
    113 NTIMERS         .equ    8               * Number of timers in the timer array
    114 *
    115 * ==============================================================================
    116 *
    117                 .page
    118 * ==============================================================================
    119 * _tsetup -- tsetup() -- timer setup function
    120 * ==============================================================================
    121 *
    122 _tsetup:        move.w  sr,-(a7)                * Save old interrupt mask
    123                 ori.w   #IPL7,sr                * Disable interrupts
    124 *
    125                 clr.w   FC_SW                   * Stop the frame clock
    126                 clr.l   FC_VAL                  * ... and reset it
    127                 clr.w   _vi_tag                 * Clear VSDD VI tag
    128                 clr.w   _vi_clk                 * Clear VSDD delay timer
    129                 clr.w   lclsadr                 * Clear score scroll address
    130                 clr.w   lclscrl                 * Clear score scroll offset
    131 *
    132                 lea     _timers,a0              * Point at timer array
    133                 move.w  #NTIMERS-1,d0           * Setup to clear timer array
    134 *
    135 tclr:           clr.w   (a0)+                   * Clear a timer array entry
    136                 dbra    d0,tclr                 * Loop until done
    137 *
    138                 move.l  #nullrts,TIMEVEC        * Set timer interrupt vector
    139                 move.l  #timeint,TI_VEC         * Set timer trap vector
    140 *
    141                 move.b  #$00,TIME_T1H           * Setup timer 1  (PLL)
    142                 move.b  #$1F,TIME_T1L           * ... for divide by 64
    143                 move.b  #$0C,TIME_T2H           * Setup timer 2  (FC)
    144                 move.b  #$7F,TIME_T2L           * ... for divide by 3200
    145                 move.b  #$03,TIME_T3H           * Setup timer 3  (RTC)
    146                 move.b  #$20,TIME_T3L           * ... for 1Ms interval
    147                 move.b  #$42,TIME_CRX           * Setup CR3
    148                 move.b  #$41,TIME_CR2           * Setup CR2
    149                 move.b  #$81,TIME_CRX           * Setup CR1
    150                 move.b  #$80,TIME_CRX           * Start the timers
    151 *
    152                 move.w  (a7)+,sr                * Restore interrupts
    153 *
    154 nullrts:        rts                             * Return to caller
    155 *
    156                 .page
    157 * ==============================================================================
    158 * timeint -- timer interrupt handler
    159 * ==============================================================================
    160 *
    161 timeint:        movem.l d0-d7/a0-a6,-(a7)       * Save registers
    162                 move.b  TIME_CR2,d0             * Get timer interrupt status
    163 * ------------------------------------------------------------------------------
    164 * process 1 MS timer
    165 * ------------------------------------------------------------------------------
    166                 btst.l  #2,d0                   * Check timer 3 status
    167                 beq     tmi02                   * Jump if not active
    168 *
    169                 move.b  TIME_T3H,d1             * Read timer 3 count
    170                 lsl.w   #8,d1                   * ...
    171                 move.b  TIME_T3L,d1             * ...
    172                 move.w  d1,T3COUNT              * ... and save it
    173 *
    174                 addq.l  #1,HZ_1K                * Update 1ms clock  (1 KHz)
    175 *
    176                 move.l  d0,-(a7)                * Preserve D0
    177 * ------------------------------------------------------------------------------
    178 * process VSDD timer
    179 * ------------------------------------------------------------------------------
    180                 tst.w   _vi_tag                 * Does the VSDD need service ?
    181                 beq     updtime                 * Jump if not
    182 *
    183                 move.w  _vi_clk,d0              * Get VSDD scroll delay timer
    184                 subq.w  #1,d0                   * Decrement timer
    185                 move.w  d0,_vi_clk              * Update timer
    186                 bne     updtime                 * Jump if it's not zero yet
    187 *
    188                 move.w  lclsadr,_v_odtab+12     * Update scroll address
    189                 move.w  lclscrl,_v_odtab+10     * Update scroll offset
    190                 clr.w   _vi_tag                 * Reset the tag
    191 *
    192                 .page
    193 *
    194 * ------------------------------------------------------------------------------
    195 * process programable timers
    196 * ------------------------------------------------------------------------------
    197 *
    198 updtime:        move.w  #NTIMERS-1,d0           * Setup timer array counter
    199                 lea     _timers,a0              * Point at timer array
    200 *
    201 tdcr:           move.w  (a0),d1                 * Get timer array entry
    202                 beq     tdcr1                   * Jump if already 0
    203 *
    204                 subq.w  #1,d1                   * Decrement timer
    205 *
    206 tdcr1:          move.w  d1,(a0)+                * Store updated timer value
    207                 dbra    d0,tdcr                 * Loop until done
    208 *
    209 * ------------------------------------------------------------------------------
    210 * process timer hook vector
    211 * ------------------------------------------------------------------------------
    212                 movea.l TIMEVEC,a0              * Get RTC vector
    213                 move.w  #1,-(a7)                * Pass 1 msec on stack
    214                 jsr     (a0)                    * Process RTC vector
    215                 addq.l  #2,a7                   * Clean up stack
    216 *
    217                 move.l  (a7)+,d0                * Restore D0
    218 *
    219                 .page
    220 * ------------------------------------------------------------------------------
    221 * process 5 Ms clock
    222 * ------------------------------------------------------------------------------
    223                 move.w  tdiv1,d1                * Update divider
    224                 addq.w  #1,d1                   * ...
    225                 move.w  d1,tdiv1                * ...
    226 *
    227                 cmpi.w  #5,d1                   * Do we need to update HZ_200 ?
    228                 blt     tmi02                   * Jump if not
    229 *
    230                 addq.l  #1,HZ_200               * Update 5ms clock   (200 Hz)
    231 * ------------------------------------------------------------------------------
    232 * process 20 Ms floppy clock
    233 * ------------------------------------------------------------------------------
    234                 move.w  tdiv2,d1                * Update divider
    235                 addq.w  #1,d1                   * ...
    236                 move.w  d1,tdiv2                * ...
    237 *
    238                 cmpi.w  #4,d1                   * Do we need to update FRCLOCK ?
    239                 blt     tmi01                   * Jump if not
    240 *
    241                 addq.l  #1,FRCLOCK              * Update 20 Ms clock  (50 Hz)
    242                 tst.w   FLOCK                   * See if floppy is active
    243                 bne     tmi00                   * Don't call FLOPVBL if so
    244 *
    245                 jsr     FLOPVBL                 * Check on the floppy
    246 *
    247 tmi00:          move.w  #0,tdiv2                * Reset tdiv2
    248 *
    249 tmi01:          move.w  #0,tdiv1                * Reset tdiv1
    250 *
    251                 .page
    252 * ------------------------------------------------------------------------------
    253 * process PLL timers
    254 * ------------------------------------------------------------------------------
    255 *
    256 tmi02:          btst.l  #0,d0                   * Check timer 1 int
    257                 beq     tmi03                   * Jump if not set
    258 *
    259                 move.b  TIME_T1H,d1             * Read timer 1 to clear int.
    260                 move.b  TIME_T1L,d1             * ...
    261 *
    262 tmi03:          btst.l  #1,d0                   * Check for timer 2 int.
    263                 beq     tmi04                   * Jump if not set
    264 *
    265                 move.b  TIME_T2H,d1             * Read timer 2 to clear int.
    266                 move.b  TIME_T2L,d1             * ...
    267 *
    268                 .page
    269 * ------------------------------------------------------------------------------
    270 * update score frame counter
    271 * ------------------------------------------------------------------------------
    272                 tst.w   FC_SW                   * Should we update the frame ?
    273                 beq     tmi04                   * Jump if not
    274 *
    275                 bmi     tmi05                   * Jump if we count down
    276 *
    277                 move.l  FC_VAL,d0               * Get the frame count
    278                 cmp.l   #FCMAX,d0               * See it we've topped out
    279                 bge     tmi06                   * Jump if limit was hit
    280 *
    281                 addq.l  #1,d0                   * Count up 1 frame
    282                 move.l  d0,FC_VAL               * Store updated frame count
    283                 bra     tmi04                   * Done
    284 *
    285 tmi07:          move.l  #FCMIN,FC_VAL           * Force hard limit, just in case
    286                 bra     tmi04                   * Done
    287 *
    288 tmi06:          move.l  #FCMAX,FC_VAL           * Force hard limit, just in case
    289                 bra     tmi04                   * Done
    290 *
    291 tmi05:          move.l  FC_VAL,d0               * Get the frame count
    292                 ble     tmi07                   * Done if already counted down
    293 *
    294                 subq.l  #1,d0                   * Count down 1 frame
    295                 move.l  d0,FC_VAL               * Store udpated frame count
    296                 bra     tmi04                   * Done
    297 *
    298                 nop                             * Filler to force equal paths
    299 *
    300 tmi04:          movem.l (a7)+,d0-d7/a0-a6       * Restore registers
    301                 rte                             * Return to interrupted code
    302 *
    303                 .page
    304 * ==============================================================================
     27
     28                .xdef   _tsetup         | tsetup() -- timer setup function
     29                .xdef   timeint         | timer interrupt handler
     30
     31                .xdef   _timers         | timer array -- short timers[NTIMERS]
     32                .xdef   _vi_clk         | VSDD scroll delay timer
     33                .xdef   _vi_tag         | VSDD VI tag
     34                .xdef   line            | Line we entered on
     35
     36                .xref   lclsadr         | score object base address
     37                .xref   lclscrl         | score object scroll offset
     38                .xref   _v_odtab        | VSDD object descriptor table
     39                .xref   _v_regs         | VSDD registers
     40
     41                .page
     42| ==============================================================================
     43
     44| Equates to variables in bios.s:
     45| -------------------------------
     46| These variables are permanently assigned.
     47
     48TIMEVEC         =       0x00000400      | LONG - System timer trap vector
     49
     50FC_SW           =       0x00000420      | WORD - Frame clock switch
     51FC_VAL          =       0x00000422      | LONG - Frame clock value
     52
     53HZ_1K           =       0x0000049A      | LONG - 1000 Hz clock
     54HZ_200          =       0x0000049E      | LONG - 200 Hz clock
     55FRCLOCK         =       0x000004A2      | LONG - 50 Hz clock
     56
     57T3COUNT         =       0x000004AA      | WORD - Timer 3 count
     58
     59| ------------------------------------------------------------------------------
     60
     61| WARNING:  The address of "FLOCK" depends on the version of the bios EPROM.
     62| The address below is for EPROMs dated 1988-04-18 ONLY.
     63
     64FLOCK           =       0x00000E0C      | WORD - Floppy semaphore       <<<=====
     65
     66| ==============================================================================
     67
     68| Equates to routines in bios.s:
     69| ------------------------------
     70
     71| WARNING:  The address of "FLOPVBL" depends on the version of the bios EPROM.
     72| The address below is for EPROMs dated 1988-04-18 ONLY.
     73
     74FLOPVBL         =       0x001015EE      | floppy VI handler address     <<<=====
     75
     76| ==============================================================================
     77
     78                .page
     79
     80| Hardware address equates:
     81| -------------------------
     82TI_VEC          =       0x00000070      | Timer interrupt autovector
     83
     84TIMER           =       0x003A0001      | Timer base address
     85
     86| ------------------------------------------------------------------------------
     87
     88| Timer register equates:
     89| -----------------------
     90TIME_CRX        =       TIMER           | Control register 1 or 3
     91TIME_CR2        =       TIMER+2         | Control register 2
     92TIME_T1H        =       TIMER+4         | Timer 1 high byte
     93TIME_T1L        =       TIMER+6         | Timer 1 low byte
     94TIME_T2H        =       TIMER+8         | Timer 2 high byte
     95TIME_T2L        =       TIMER+10        | Timer 2 low byte
     96TIME_T3H        =       TIMER+12        | Timer 3 high byte
     97TIME_T3L        =       TIMER+14        | Timer 3 low byte
     98
     99| VSDD register offsets:
     100| ----------------------
     101VSDD_R5         =       10              | VSDD bank control register
     102VSDD_R11        =       22              | VSDD access table register
     103
     104| ==============================================================================
     105
     106| Miscellaneous equates:
     107| ----------------------
     108IPL7            =       0x0700          | IPL mask for interrupt disable
     109
     110FCMAX           =       0x00FFFFFF      | Maximum frame counter value
     111FCMIN           =       0x00000000      | Minimum frame counter value
     112
     113NTIMERS         =       8               | Number of timers in the timer array
     114
     115| ==============================================================================
     116
     117                .page
     118| ==============================================================================
     119| _tsetup -- tsetup() -- timer setup function
     120| ==============================================================================
     121
     122_tsetup:        move.w  sr,-(a7)                | Save old interrupt mask
     123                ori.w   #IPL7,sr                | Disable interrupts
     124
     125                clr.w   FC_SW                   | Stop the frame clock
     126                clr.l   FC_VAL                  | ... and reset it
     127                clr.w   _vi_tag                 | Clear VSDD VI tag
     128                clr.w   _vi_clk                 | Clear VSDD delay timer
     129                clr.w   lclsadr                 | Clear score scroll address
     130                clr.w   lclscrl                 | Clear score scroll offset
     131
     132                lea     _timers,a0              | Point at timer array
     133                move.w  #NTIMERS-1,d0           | Setup to clear timer array
     134
     135tclr:           clr.w   (a0)+                   | Clear a timer array entry
     136                dbra    d0,tclr                 | Loop until done
     137
     138                move.l  #nullrts,TIMEVEC        | Set timer interrupt vector
     139                move.l  #timeint,TI_VEC         | Set timer trap vector
     140
     141                move.b  #0x00,TIME_T1H          | Setup timer 1  (PLL)
     142                move.b  #0x1F,TIME_T1L          | ... for divide by 64
     143                move.b  #0x0C,TIME_T2H          | Setup timer 2  (FC)
     144                move.b  #0x7F,TIME_T2L          | ... for divide by 3200
     145                move.b  #0x03,TIME_T3H          | Setup timer 3  (RTC)
     146                move.b  #0x20,TIME_T3L          | ... for 1Ms interval
     147                move.b  #0x42,TIME_CRX          | Setup CR3
     148                move.b  #0x41,TIME_CR2          | Setup CR2
     149                move.b  #0x81,TIME_CRX          | Setup CR1
     150                move.b  #0x80,TIME_CRX          | Start the timers
     151
     152                move.w  (a7)+,sr                | Restore interrupts
     153
     154nullrts:        rts                             | Return to caller
     155
     156                .page
     157| ==============================================================================
     158| timeint -- timer interrupt handler
     159| ==============================================================================
     160
     161timeint:        movem.l d0-d7/a0-a6,-(a7)       | Save registers
     162                move.b  TIME_CR2,d0             | Get timer interrupt status
     163| ------------------------------------------------------------------------------
     164| process 1 MS timer
     165| ------------------------------------------------------------------------------
     166                btst.l  #2,d0                   | Check timer 3 status
     167                beq     tmi02                   | Jump if not active
     168
     169                move.b  TIME_T3H,d1             | Read timer 3 count
     170                lsl.w   #8,d1                   | ...
     171                move.b  TIME_T3L,d1             | ...
     172                move.w  d1,T3COUNT              | ... and save it
     173
     174                addq.l  #1,HZ_1K                | Update 1ms clock  (1 KHz)
     175
     176                move.l  d0,-(a7)                | Preserve D0
     177| ------------------------------------------------------------------------------
     178| process VSDD timer
     179| ------------------------------------------------------------------------------
     180                tst.w   _vi_tag                 | Does the VSDD need service ?
     181                beq     updtime                 | Jump if not
     182
     183                move.w  _vi_clk,d0              | Get VSDD scroll delay timer
     184                subq.w  #1,d0                   | Decrement timer
     185                move.w  d0,_vi_clk              | Update timer
     186                bne     updtime                 | Jump if it's not zero yet
     187
     188                move.w  lclsadr,_v_odtab+12     | Update scroll address
     189                move.w  lclscrl,_v_odtab+10     | Update scroll offset
     190                clr.w   _vi_tag                 | Reset the tag
     191
     192                .page
     193
     194| ------------------------------------------------------------------------------
     195| process programable timers
     196| ------------------------------------------------------------------------------
     197
     198updtime:        move.w  #NTIMERS-1,d0           | Setup timer array counter
     199                lea     _timers,a0              | Point at timer array
     200
     201tdcr:           move.w  (a0),d1                 | Get timer array entry
     202                beq     tdcr1                   | Jump if already 0
     203
     204                subq.w  #1,d1                   | Decrement timer
     205
     206tdcr1:          move.w  d1,(a0)+                | Store updated timer value
     207                dbra    d0,tdcr                 | Loop until done
     208
     209| ------------------------------------------------------------------------------
     210| process timer hook vector
     211| ------------------------------------------------------------------------------
     212                movea.l TIMEVEC,a0              | Get RTC vector
     213                move.w  #1,-(a7)                | Pass 1 msec on stack
     214                jsr     (a0)                    | Process RTC vector
     215                addq.l  #2,a7                   | Clean up stack
     216
     217                move.l  (a7)+,d0                | Restore D0
     218
     219                .page
     220| ------------------------------------------------------------------------------
     221| process 5 Ms clock
     222| ------------------------------------------------------------------------------
     223                move.w  tdiv1,d1                | Update divider
     224                addq.w  #1,d1                   | ...
     225                move.w  d1,tdiv1                | ...
     226
     227                cmpi.w  #5,d1                   | Do we need to update HZ_200 ?
     228                blt     tmi02                   | Jump if not
     229
     230                addq.l  #1,HZ_200               | Update 5ms clock   (200 Hz)
     231| ------------------------------------------------------------------------------
     232| process 20 Ms floppy clock
     233| ------------------------------------------------------------------------------
     234                move.w  tdiv2,d1                | Update divider
     235                addq.w  #1,d1                   | ...
     236                move.w  d1,tdiv2                | ...
     237
     238                cmpi.w  #4,d1                   | Do we need to update FRCLOCK ?
     239                blt     tmi01                   | Jump if not
     240
     241                addq.l  #1,FRCLOCK              | Update 20 Ms clock  (50 Hz)
     242                tst.w   FLOCK                   | See if floppy is active
     243                bne     tmi00                   | Don't call FLOPVBL if so
     244
     245                jsr     FLOPVBL                 | Check on the floppy
     246
     247tmi00:          move.w  #0,tdiv2                | Reset tdiv2
     248
     249tmi01:          move.w  #0,tdiv1                | Reset tdiv1
     250
     251                .page
     252| ------------------------------------------------------------------------------
     253| process PLL timers
     254| ------------------------------------------------------------------------------
     255
     256tmi02:          btst.l  #0,d0                   | Check timer 1 int
     257                beq     tmi03                   | Jump if not set
     258
     259                move.b  TIME_T1H,d1             | Read timer 1 to clear int.
     260                move.b  TIME_T1L,d1             | ...
     261
     262tmi03:          btst.l  #1,d0                   | Check for timer 2 int.
     263                beq     tmi04                   | Jump if not set
     264
     265                move.b  TIME_T2H,d1             | Read timer 2 to clear int.
     266                move.b  TIME_T2L,d1             | ...
     267
     268                .page
     269| ------------------------------------------------------------------------------
     270| update score frame counter
     271| ------------------------------------------------------------------------------
     272                tst.w   FC_SW                   | Should we update the frame ?
     273                beq     tmi04                   | Jump if not
     274
     275                bmi     tmi05                   | Jump if we count down
     276
     277                move.l  FC_VAL,d0               | Get the frame count
     278                cmp.l   #FCMAX,d0               | See it we've topped out
     279                bge     tmi06                   | Jump if limit was hit
     280
     281                addq.l  #1,d0                   | Count up 1 frame
     282                move.l  d0,FC_VAL               | Store updated frame count
     283                bra     tmi04                   | Done
     284
     285tmi07:          move.l  #FCMIN,FC_VAL           | Force hard limit, just in case
     286                bra     tmi04                   | Done
     287
     288tmi06:          move.l  #FCMAX,FC_VAL           | Force hard limit, just in case
     289                bra     tmi04                   | Done
     290
     291tmi05:          move.l  FC_VAL,d0               | Get the frame count
     292                ble     tmi07                   | Done if already counted down
     293
     294                subq.l  #1,d0                   | Count down 1 frame
     295                move.l  d0,FC_VAL               | Store udpated frame count
     296                bra     tmi04                   | Done
     297
     298                nop                             | Filler to force equal paths
     299
     300tmi04:          movem.l (a7)+,d0-d7/a0-a6       | Restore registers
     301                rte                             | Return to interrupted code
     302
     303                .page
     304| ==============================================================================
    305305                .bss
    306 * ==============================================================================
    307 *
    308 * A note on tdiv1 and tdiv2:
    309 * --------------------------
    310 *
    311 * tdiv1 and tdiv2 are actually defined in the bios,  but since they could move
    312 * we define them here and ignore the ones in the bios.
    313 *
    314 tdiv1:          ds.w    1               * Timer divider 1  (divides HZ_1K)
    315 tdiv2:          ds.w    1               * Timer divider 2  (divides HZ_200)
    316 *
    317 * ------------------------------------------------------------------------------
    318 *
    319 _timers:        ds.w    NTIMERS         * Timer array -- short timers[16];
    320 *
    321 _vi_clk:        ds.w    1               * VSDD scroll delay timer
    322 _vi_tag:        ds.w    1               * VSDD VI 'needs service' tag
    323 *
    324 bank:           ds.w    1               * VSDD bank we enterd with
    325 line:           ds.w    1               * Line we came in on (for analysis)
    326 * ==============================================================================
    327 *
     306| ==============================================================================
     307
     308| A note on tdiv1 and tdiv2:
     309| --------------------------
     310
     311| tdiv1 and tdiv2 are actually defined in the bios,  but since they could move
     312| we define them here and ignore the ones in the bios.
     313
     314tdiv1:          ds.w    1               | Timer divider 1  (divides HZ_1K)
     315tdiv2:          ds.w    1               | Timer divider 2  (divides HZ_200)
     316
     317| ------------------------------------------------------------------------------
     318
     319_timers:        ds.w    NTIMERS         | Timer array -- short timers[16];
     320
     321_vi_clk:        ds.w    1               | VSDD scroll delay timer
     322_vi_tag:        ds.w    1               | VSDD VI 'needs service' tag
     323
     324bank:           ds.w    1               | VSDD bank we enterd with
     325line:           ds.w    1               | Line we came in on (for analysis)
     326| ==============================================================================
     327
    328328                .end
  • vlib/acctrl.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * acctrl.s -- VSDD access table control functions
    3 * Version 6 -- 1987-04-13 -- D.N. Lynx Crowe
    4 * (c) Copyright 1987 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *
    7 *       objclr(obj)
    8 *       unsigned int obj;
    9 *
    10 *               Clear bits in access table for object 'obj'.
    11 *               Disables object 'obj'.
    12 *
    13 *       objoff(obj, line, num)
    14 *       unsigned int obj, line, num;
    15 *
    16 *               Disable object obj at line thru line+num.
    17 *
    18 *       objon(obj, line, num)
    19 *       unsigned int obj, line, num;
    20 *
    21 *               Enable object obj at line thru line+num.
    22 *
    23 *
    24 *       Assumes VSDD is looking at bank 0.
    25 *       Assumes a screen height of 350 lines.
    26 *       No error checks are done, so beware.
    27 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| acctrl.s -- VSDD access table control functions
     3| Version 6 -- 1987-04-13 -- D.N. Lynx Crowe
     4| (c) Copyright 1987 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6
     7|       objclr(obj)
     8|       unsigned int obj;
     9
     10|               Clear bits in access table for object 'obj'.
     11|               Disables object 'obj'.
     12
     13|       objoff(obj, line, num)
     14|       unsigned int obj, line, num;
     15
     16|               Disable object obj at line thru line+num.
     17
     18|       objon(obj, line, num)
     19|       unsigned int obj, line, num;
     20
     21|               Enable object obj at line thru line+num.
     22
     23
     24|       Assumes VSDD is looking at bank 0.
     25|       Assumes a screen height of 350 lines.
     26|       No error checks are done, so beware.
     27| ------------------------------------------------------------------------------
    2828                .text
    29 *
     29
    3030                .xdef   _objclr,_objoff,_objon
    31 *
     31
    3232                .xref   _v_actab
    33 *
    34 SCSIZE          .equ    350             * Screen height
    35 *
    36 OBJ             .equ    8               * Object number argument offset
    37 LINE            .equ    10              * Beginning line argument offset
    38 NUM             .equ    12              * Object height argument offset
    39 * ------------------------------------------------------------------------------
     33
     34SCSIZE          =       350             | Screen height
     35
     36OBJ             =       8               | Object number argument offset
     37LINE            =       10              | Beginning line argument offset
     38NUM             =       12              | Object height argument offset
     39| ------------------------------------------------------------------------------
    4040                .page
    41 * ------------------------------------------------------------------------------
    42 *
    43 *       objclr(obj)
    44 *       unsigned int obj;
    45 *
    46 *               Disables object obj in access table by turning on
    47 *               its bit in all words of the access table.
    48 * ------------------------------------------------------------------------------
    49 _objclr:        link    a6,#0           * Link stack frames
    50                 move.w  OBJ(a6),d1      * Get object bit number in d1
    51                 lea     _v_actab,a0     * Get base of object table in a0
    52                 move.w  #SCSIZE-1,d2    * Put line count in d2
    53 *
    54 objclr1:        move.w  (a0),d0         * Get access table word
    55                 bset.l  d1,d0           * Set the bit
    56                 move.w  d0,(a0)+        * Update word in access table
    57                 dbf     d2,objclr1      * Loop until done
    58 *
    59                 unlk    a6              * Unlink stack frame
    60                 rts                     * Return to caller
    61 *
     41| ------------------------------------------------------------------------------
     42
     43|       objclr(obj)
     44|       unsigned int obj;
     45
     46|               Disables object obj in access table by turning on
     47|               its bit in all words of the access table.
     48| ------------------------------------------------------------------------------
     49_objclr:        link    a6,#0           | Link stack frames
     50                move.w  OBJ(a6),d1      | Get object bit number in d1
     51                lea     _v_actab,a0     | Get base of object table in a0
     52                move.w  #SCSIZE-1,d2    | Put line count in d2
     53
     54objclr1:        move.w  (a0),d0         | Get access table word
     55                bset.l  d1,d0           | Set the bit
     56                move.w  d0,(a0)+        | Update word in access table
     57                dbf     d2,objclr1      | Loop until done
     58
     59                unlk    a6              | Unlink stack frame
     60                rts                     | Return to caller
     61
    6262                .page
    63 * ------------------------------------------------------------------------------
    64 *       objoff(obj, line, num)
    65 *       unsigned int obj, line, num;
    66 *
    67 *               Turn on access table bits for object 'obj' at
    68 *               lines 'line' through 'line'+'num'.  Disables the object.
    69 *               Assumes object bits were set at those locations.
    70 * ------------------------------------------------------------------------------
    71 _objoff:        link    a6,#0           * Link stack frames
    72                 move.w  OBJ(a6),d1      * Get object bit number into d1
    73                 move.w  LINE(a6),d2     * Get top line number
    74                 add.w   d2,d2           * Convert to word offset
    75                 lea     _v_actab,a0     * Get base address of access table
    76                 move.w  0(a0,d2),d0     * Get top line access word
    77                 bset.l  d1,d0           * Set object bit
    78                 move.w  d0,0(a0,d2)     * Update word in access table
    79                 tst.w   NUM(a6)         * Number of lines = 0 ?
    80                 beq     objoff1         * Done if so
    81 *
    82                 move.w  NUM(a6),d2      * Get object depth
    83                 add.w   LINE(a6),d2     * Add to top line number
    84                 cmpi.w  #SCSIZE,d2      * Bottom line >= screen height ?
    85                 bge     objoff1         * Done if so
    86 *
    87                 add.w   d2,d2           * Convert to word offset
    88                 move.w  0(a0,d2),d0     * Get bottom line access word
    89                 bset.l  d1,d0           * Set object bit
    90                 move.w  d0,0(a0,d2)     * Update word in access table
    91 *
    92 objoff1:        unlk    a6              * Unlink stack frame
    93                 rts                     * Return to caller
    94 *
     63| ------------------------------------------------------------------------------
     64|       objoff(obj, line, num)
     65|       unsigned int obj, line, num;
     66
     67|               Turn on access table bits for object 'obj' at
     68|               lines 'line' through 'line'+'num'.  Disables the object.
     69|               Assumes object bits were set at those locations.
     70| ------------------------------------------------------------------------------
     71_objoff:        link    a6,#0           | Link stack frames
     72                move.w  OBJ(a6),d1      | Get object bit number into d1
     73                move.w  LINE(a6),d2     | Get top line number
     74                add.w   d2,d2           | Convert to word offset
     75                lea     _v_actab,a0     | Get base address of access table
     76                move.w  0(a0,d2),d0     | Get top line access word
     77                bset.l  d1,d0           | Set object bit
     78                move.w  d0,0(a0,d2)     | Update word in access table
     79                tst.w   NUM(a6)         | Number of lines = 0 ?
     80                beq     objoff1         | Done if so
     81
     82                move.w  NUM(a6),d2      | Get object depth
     83                add.w   LINE(a6),d2     | Add to top line number
     84                cmpi.w  #SCSIZE,d2      | Bottom line >= screen height ?
     85                bge     objoff1         | Done if so
     86
     87                add.w   d2,d2           | Convert to word offset
     88                move.w  0(a0,d2),d0     | Get bottom line access word
     89                bset.l  d1,d0           | Set object bit
     90                move.w  d0,0(a0,d2)     | Update word in access table
     91
     92objoff1:        unlk    a6              | Unlink stack frame
     93                rts                     | Return to caller
     94
    9595                .page
    96 * ------------------------------------------------------------------------------
    97 *       objon(obj, line, num)
    98 *       unsigned int obj, line, num;
    99 *
    100 *               Turn off access table bits for object 'obj'
    101 *               at 'line' thru 'line'+'num'.  Enables the object.
    102 * ------------------------------------------------------------------------------
    103 _objon:         link    a6,#0           * Link stack frames
    104                 move.w  OBJ(a6),d1      * Get object bit number into d1
    105                 move.w  LINE(a6),d2     * Get top line number
    106                 add.w   d2,d2           * Convert to word offset
    107                 lea     _v_actab,a0     * Get base address of access table
    108                 move.w  0(a0,d2),d0     * Get top line access word
    109                 bclr.l  d1,d0           * Clear object bit
    110                 move.w  d0,0(a0,d2)     * Update word in access table
    111                 tst.w   NUM(a6)         * Number of lines = 0 ?
    112                 beq     objon1          * Done if so
    113 *
    114                 move.w  NUM(a6),d2      * Get object depth
    115                 add.w   LINE(a6),d2     * Add top line number
    116                 cmpi.w  #SCSIZE,d2      * Bottom line >= screen height ?
    117                 bge     objon1          * Done if so
    118 *
    119                 add.w   d2,d2           * Convert to word offset
    120                 move.w  0(a0,d2),d0     * Get bottom line access word
    121                 bclr.l  d1,d0           * Clear object bit
    122                 move.w  d0,0(a0,d2)     * Update word in access table
    123 *
    124 objon1:         unlk    a6              * Unlink stack frame
    125                 rts                     * Return to caller
    126 *
     96| ------------------------------------------------------------------------------
     97|       objon(obj, line, num)
     98|       unsigned int obj, line, num;
     99
     100|               Turn off access table bits for object 'obj'
     101|               at 'line' thru 'line'+'num'.  Enables the object.
     102| ------------------------------------------------------------------------------
     103_objon:         link    a6,#0           | Link stack frames
     104                move.w  OBJ(a6),d1      | Get object bit number into d1
     105                move.w  LINE(a6),d2     | Get top line number
     106                add.w   d2,d2           | Convert to word offset
     107                lea     _v_actab,a0     | Get base address of access table
     108                move.w  0(a0,d2),d0     | Get top line access word
     109                bclr.l  d1,d0           | Clear object bit
     110                move.w  d0,0(a0,d2)     | Update word in access table
     111                tst.w   NUM(a6)         | Number of lines = 0 ?
     112                beq     objon1          | Done if so
     113
     114                move.w  NUM(a6),d2      | Get object depth
     115                add.w   LINE(a6),d2     | Add top line number
     116                cmpi.w  #SCSIZE,d2      | Bottom line >= screen height ?
     117                bge     objon1          | Done if so
     118
     119                add.w   d2,d2           | Convert to word offset
     120                move.w  0(a0,d2),d0     | Get bottom line access word
     121                bclr.l  d1,d0           | Clear object bit
     122                move.w  d0,0(a0,d2)     | Update word in access table
     123
     124objon1:         unlk    a6              | Unlink stack frame
     125                rts                     | Return to caller
     126
    127127                .end
  • vlib/glcplot.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * glcplot.s -- plot a pixel on the LCD display
    3 * Version 2 -- 1987-04-23 -- D.N. Lynx Crowe
    4 * (c) Copyright 1987 -- D.N. Lynx Crowe
    5 *
    6 *       GLCplot(x, y, val)
    7 *       unsigned x, y, val);
    8 *
    9 *               Plot a pixel at ('x', 'y') using lcdbase as the plane address
    10 *               in GLC RAM.  If 'val' is zero, the pixel is cleared,
    11 *               otherwise the pixel is cleared.  No error checking is done.
    12 *               Limits:  0 LE x LE 511,  0 LE y LE 63.
    13 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| glcplot.s -- plot a pixel on the LCD display
     3| Version 2 -- 1987-04-23 -- D.N. Lynx Crowe
     4| (c) Copyright 1987 -- D.N. Lynx Crowe
     5
     6|       GLCplot(x, y, val)
     7|       unsigned x, y, val);
     8
     9|               Plot a pixel at ('x', 'y') using lcdbase as the plane address
     10|               in GLC RAM.  If 'val' is zero, the pixel is cleared,
     11|               otherwise the pixel is cleared.  No error checking is done.
     12|               Limits:  0 LE x LE 511,  0 LE y LE 63.
     13| ------------------------------------------------------------------------------
    1414                .text
    15 *
     15
    1616                .xdef   _GLCplot
    1717                .xref   _lcd_a0,_lcd_a1,_lcdbase
    18 *
    19 XLOC            .equ    8                       * 'x' parameter offset
    20 YLOC            .equ    10                      * 'y' parameter offset
    21 VAL             .equ    12                      * 'val' parameter offset
    22 *
    23 G_CRSWR         .equ    $46                     * GLC set cursor command
    24 G_MWRITE        .equ    $42                     * GLC write command
    25 G_MREAD         .equ    $43                     * GLC read command
    26 *
     18
     19XLOC            =       8                       | 'x' parameter offset
     20YLOC            =       10                      | 'y' parameter offset
     21VAL             =       12                      | 'val' parameter offset
     22
     23G_CRSWR         =       0x46                    | GLC set cursor command
     24G_MWRITE        =       0x42                    | GLC write command
     25G_MREAD         =       0x43                    | GLC read command
     26
    2727                .page
    28 *
    29 _GLCplot:       link    a6,#0                   * Link stack frames
    30                 moveq   #63,d0                  * d0 = (63-y) * 85
    31                 sub.w   YLOC(a6),d0             * ...
    32                 mulu    #85,d0                  * ...
    33                 clr.l   d1                      * d1 = x/6
    34                 move.w  XLOC(a6),d1             * ...
    35                 divu    #6,d1                   * ...
    36                 add.w   d1,d0                   * d0 = (63-y)*85 + (x/6)
    37                 swap    d1                      * d2 = 7 - (x%6) % 8
    38                 moveq   #7,d2                   * ...
    39                 sub.w   d1,d2                   * ...
    40                 andi.w  #7,d2                   * ...
    41                 lsr.w   #3,d1                   * d1 = (x%6) / 8
    42                 add.w   d1,d0                   * d0 = cursor address
    43                 add.w   _lcdbase,d0             * ...
    44                 move.w  d0,d1                   * d1 = cursor address, too
    45                 move.b  #G_CRSWR,_lcd_a1        * Send cursor address to GLC
    46                 move.b  d0,_lcd_a0              * ...
    47                 lsr.w   #8,d0                   * ...
    48                 move.b  d0,_lcd_a0              * ...
    49                 move.b  #G_MREAD,_lcd_a1        * Read old pixel byte
    50                 move.b  _lcd_a1,d0              * ... into d0
    51                 tst.w   VAL(a6)                 * Check val for zero
    52                 beq     glcplt1                 * Jump if val EQ 0
    53 *
    54                 bset    d2,d0                   * Set the pixel to 1
    55                 bra     glcplt2                 * Go write pixel to GLC
    56 *
    57 glcplt1:        bclr    d2,d0                   * Clear the pixel to 0
    58 *
    59 glcplt2:        move.b  #G_CRSWR,_lcd_a1        * Send cursor address to GLC
    60                 move.b  d1,_lcd_a0              * ...
    61                 lsr.w   #8,d1                   * ...
    62                 move.b  d1,_lcd_a0              * ...
    63                 move.b  #G_MWRITE,_lcd_a1       * Setup GLC to write pixel
    64                 move.b  d0,_lcd_a0              * Write pixel
    65                 unlk    a6                      * Unlink stack frames
    66                 rts                             * Return to caller
    67 *
     28
     29_GLCplot:       link    a6,#0                   | Link stack frames
     30                moveq   #63,d0                  | d0 = (63-y) | 85
     31                sub.w   YLOC(a6),d0             | ...
     32                mulu    #85,d0                  | ...
     33                clr.l   d1                      | d1 = x/6
     34                move.w  XLOC(a6),d1             | ...
     35                divu    #6,d1                   | ...
     36                add.w   d1,d0                   | d0 = (63-y)|85 + (x/6)
     37                swap    d1                      | d2 = 7 - (x%6) % 8
     38                moveq   #7,d2                   | ...
     39                sub.w   d1,d2                   | ...
     40                andi.w  #7,d2                   | ...
     41                lsr.w   #3,d1                   | d1 = (x%6) / 8
     42                add.w   d1,d0                   | d0 = cursor address
     43                add.w   _lcdbase,d0             | ...
     44                move.w  d0,d1                   | d1 = cursor address, too
     45                move.b  #G_CRSWR,_lcd_a1        | Send cursor address to GLC
     46                move.b  d0,_lcd_a0              | ...
     47                lsr.w   #8,d0                   | ...
     48                move.b  d0,_lcd_a0              | ...
     49                move.b  #G_MREAD,_lcd_a1        | Read old pixel byte
     50                move.b  _lcd_a1,d0              | ... into d0
     51                tst.w   VAL(a6)                 | Check val for zero
     52                beq     glcplt1                 | Jump if val EQ 0
     53
     54                bset    d2,d0                   | Set the pixel to 1
     55                bra     glcplt2                 | Go write pixel to GLC
     56
     57glcplt1:        bclr    d2,d0                   | Clear the pixel to 0
     58
     59glcplt2:        move.b  #G_CRSWR,_lcd_a1        | Send cursor address to GLC
     60                move.b  d1,_lcd_a0              | ...
     61                lsr.w   #8,d1                   | ...
     62                move.b  d1,_lcd_a0              | ...
     63                move.b  #G_MWRITE,_lcd_a1       | Setup GLC to write pixel
     64                move.b  d0,_lcd_a0              | Write pixel
     65                unlk    a6                      | Unlink stack frames
     66                rts                             | Return to caller
     67
    6868                .end
  • vlib/tsplot4.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * tsplot4.s -- output characters to a 4-bit / pixel graphics window
    3 *    with variable vertical pitch
    4 * Version 1 -- 1987-08-04 -- D.N. Lynx Crowe
    5 * (c) Copyright 1987 -- D.N. Lynx Crowe
    6 * ------------------------------------------------------------------------------
    7 *
    8 *       tsplot4(obase, nw, fg, row, col, str. pitch)
    9 *       int *obase, nw, fg, row, col, pitch;
    10 *       char *str;
    11 *
    12 *               Outputs characters from the string at 'str' to an 'nw'
    13 *               character wide 4-bit per pixel graphics window at 'obase'
    14 *               at ('row','col'), using 'fg' as the foreground color.
    15 *               Uses cgtable[][256] as the VSDD formatted character
    16 *               generator table.  Assumes 12 bit high characters in the
    17 *               cgtable.  Uses 'pitch' as the vertical spacing between
    18 *               character rows.  No error checks are done.
    19 *               The string must fit the output area (no overlaps, single line).
    20 *
    21 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| tsplot4.s -- output characters to a 4-bit / pixel graphics window
     3|    with variable vertical pitch
     4| Version 1 -- 1987-08-04 -- D.N. Lynx Crowe
     5| (c) Copyright 1987 -- D.N. Lynx Crowe
     6| ------------------------------------------------------------------------------
     7
     8|       tsplot4(obase, nw, fg, row, col, str. pitch)
     9|       int |obase, nw, fg, row, col, pitch;
     10|       char |str;
     11
     12|               Outputs characters from the string at 'str' to an 'nw'
     13|               character wide 4-bit per pixel graphics window at 'obase'
     14|               at ('row','col'), using 'fg' as the foreground color.
     15|               Uses cgtable[][256] as the VSDD formatted character
     16|               generator table.  Assumes 12 bit high characters in the
     17|               cgtable.  Uses 'pitch' as the vertical spacing between
     18|               character rows.  No error checks are done.
     19|               The string must fit the output area (no overlaps, single line).
     20
     21| ------------------------------------------------------------------------------
    2222                .text
    23 *
     23
    2424                .xdef   _tsplot4
    25 *
     25
    2626                .xref   _cgtable
    27 *
    28 * Argument offsets from a6:
    29 *
    30 OBASE           .equ    8               * LONG - Output area base address
    31 NW              .equ    12              * WORD - Character width of output area
    32 FG              .equ    14              * WORD - Foreground color
    33 ROW             .equ    16              * WORD - Row
    34 COL             .equ    18              * WORD - Column
    35 STR             .equ    20              * LONG - String base address
    36 PITCH           .equ    24              * WORD - Vertical spacing between rows
    37 *
    38 * Program constant definitions:
    39 *
    40 HPIX            .equ    8               * Character width in pixels
    41 VPIX            .equ    12              * Character height in pixels
    42 HCW             .equ    4               * Horizontal character width (bytes)
    43 PSHIFT          .equ    12              * Pixel shift into MS bits
    44 HSHIFT          .equ    4               * Pixel right shift
    45 *
     27
     28| Argument offsets from a6:
     29
     30OBASE           =       8               | LONG - Output area base address
     31NW              =       12              | WORD - Character width of output area
     32FG              =       14              | WORD - Foreground color
     33ROW             =       16              | WORD - Row
     34COL             =       18              | WORD - Column
     35STR             =       20              | LONG - String base address
     36PITCH           =       24              | WORD - Vertical spacing between rows
     37
     38| Program constant definitions:
     39
     40HPIX            =       8               | Character width in pixels
     41VPIX            =       12              | Character height in pixels
     42HCW             =       4               | Horizontal character width (bytes)
     43PSHIFT          =       12              | Pixel shift into MS bits
     44HSHIFT          =       4               | Pixel right shift
     45
    4646                .page
    47 *
    48 * Register usage:
    49 *
    50 *       d0      output word and scratch
    51 *       d1      CG word and scratch
    52 *       d2      pixel counter
    53 *
    54 *       d3      foreground color (in the 4 ms bits)
    55 *       d4      background color (in the 4 ms bits)
    56 *       d5      width of the area in bytes
    57 *       d6      scan line counter
    58 *
    59 *       a0      CG table pointer
    60 *       a1      output area scan line pointer
    61 *       a2      input string character pointer
    62 *
    63 *       a3      output area character base pointer
    64 *
    65 *       a6      frame pointer
    66 *       a7      stack pointer
    67 *
     47
     48| Register usage:
     49
     50|       d0      output word and scratch
     51|       d1      CG word and scratch
     52|       d2      pixel counter
     53
     54|       d3      foreground color (in the 4 ms bits)
     55|       d4      background color (in the 4 ms bits)
     56|       d5      width of the area in bytes
     57|       d6      scan line counter
     58
     59|       a0      CG table pointer
     60|       a1      output area scan line pointer
     61|       a2      input string character pointer
     62
     63|       a3      output area character base pointer
     64
     65|       a6      frame pointer
     66|       a7      stack pointer
     67
    6868                .page
    69 *
    70 _tsplot4:       link    a6,#0           * Link stack frames
    71                 movem.l d3-d6/a3,-(a7)  * Save registers we use
    72                 move.w  #PSHIFT,d1      * Set shift constant
    73                 move.w  FG(a6),d3       * Setup foreground color
    74                 lsl.w   d1,d3           * ... in ms 4 bits of d3.W
    75                 move.w  NW(a6),d5       * Get line width in d5.W
    76                 lsl.w   #2,d5           * Multiply width by 4 for offset
    77                 move.w  ROW(a6),d0      * Calculate output address
    78                 move.w  PITCH(a6),d1    * ... PITCH
    79                 mulu    d1,d0           * ... * ROW
    80                 add.w   #VPIX-1,d0      * ... + VPIX-1
    81                 mulu    d5,d0           * ... * NW
    82                 clr.l   d1              * ...
    83                 move.w  COL(a6),d1      * ... +
    84                 lsl.w   #2,d1           * ... COL * 4
    85                 add.l   d1,d0           * ...
    86                 add.l   OBASE(a6),d0    * ... + OBASE
    87                 movea.l d0,a3           * Leave output address in a3
    88                 movea.l STR(a6),a2      * Put string address in a2
    89 *
    90 cgl0:           clr.l   d0              * Clear out upper bits of d0
    91                 move.b  (a2)+,d0        * Get next character
    92                 beq     cgl5            * Done if character EQ 0
    93 *
    94                 movea.l a3,a1           * Establish output pointer in a1
    95                 adda.l  #HCW,a3         * Update output pointer for next char.
    96                 lea     _cgtable,a0     * Establish CG pointer in a0
    97                 lsl.w   #1,d0           * ... 2 * character
    98                 adda.w  d0,a0           * ... + _cgtable address
    99                 move.w  #VPIX-1,d6      * Set scan line counter in d6
    100 *
     69
     70_tsplot4:       link    a6,#0           | Link stack frames
     71                movem.l d3-d6/a3,-(a7)  | Save registers we use
     72                move.w  #PSHIFT,d1      | Set shift constant
     73                move.w  FG(a6),d3       | Setup foreground color
     74                lsl.w   d1,d3           | ... in ms 4 bits of d3.W
     75                move.w  NW(a6),d5       | Get line width in d5.W
     76                lsl.w   #2,d5           | Multiply width by 4 for offset
     77                move.w  ROW(a6),d0      | Calculate output address
     78                move.w  PITCH(a6),d1    | ... PITCH
     79                mulu    d1,d0           | ... | ROW
     80                add.w   #VPIX-1,d0      | ... + VPIX-1
     81                mulu    d5,d0           | ... | NW
     82                clr.l   d1              | ...
     83                move.w  COL(a6),d1      | ... +
     84                lsl.w   #2,d1           | ... COL | 4
     85                add.l   d1,d0           | ...
     86                add.l   OBASE(a6),d0    | ... + OBASE
     87                movea.l d0,a3           | Leave output address in a3
     88                movea.l STR(a6),a2      | Put string address in a2
     89
     90cgl0:           clr.l   d0              | Clear out upper bits of d0
     91                move.b  (a2)+,d0        | Get next character
     92                beq     cgl5            | Done if character EQ 0
     93
     94                movea.l a3,a1           | Establish output pointer in a1
     95                adda.l  #HCW,a3         | Update output pointer for next char.
     96                lea     _cgtable,a0     | Establish CG pointer in a0
     97                lsl.w   #1,d0           | ... 2 | character
     98                adda.w  d0,a0           | ... + _cgtable address
     99                move.w  #VPIX-1,d6      | Set scan line counter in d6
     100
    101101                .page
    102 cgl1:           move.w  (a0),d1         * Get character generator word in d1
    103                 move.w  #(HPIX/2)-1,d2  * Set pixel counter in d2
    104                 clr.l   d4              * Get old output word as background
    105                 move.w  (a1),d4         * ...
    106                 swap    d4              * ...
    107 *
    108 cgl2:           lsr.w   #HSHIFT,d0      * Shift output word right 1 pixel
    109                 lsr.l   #HSHIFT,d4      * Shift background word 1 pixel
    110                 andi.l  #$FFFFF000,d4   * Mask for upper 4 bits of d4.W
    111                 btst.l  #0,d1           * Check CG word ls bit
    112                 beq     cgl3            * Set background color if bit EQ 0
    113 *
    114                 or.w    d3,d0           * OR foreground color into output word
    115                 bra     cgl4            * Go update CG word
    116 *
    117 cgl3:           or.w    d4,d0           * OR background color into output word
    118 *
    119 cgl4:           lsr.w   #1,d1           * Shift CG word right 1 pixel
    120                 dbf     d2,cgl2         * Loop for first 4 pixels
    121 *
    122                 move.w  d0,(a1)+        * Store first output word in scan line
    123                 move.w  #(HPIX/2)-1,d2  * Set pixel counter in d2
    124                 clr.l   d4              * Get old output word as background
    125                 move.w  (a1),d4         * ...
    126                 swap    d4              * ...
    127 *
    128 cgl2a:          lsr.w   #HSHIFT,d0      * Shift output word right 1 pixel
    129                 lsr.l   #HSHIFT,d4      * Shift background word 1 pixel
    130                 andi.l  #$FFFFF000,d4   * Mask for upper bits of d4.W
    131                 btst.l  #0,d1           * Check CG word ls bit
    132                 beq     cgl3a           * Set background color if bit EQ 0
    133 *
    134                 or.w    d3,d0           * OR foreground color into output word
    135                 bra     cgl4a           * Go update CG word
    136 *
    137 cgl3a:          or.w    d4,d0           * OR background color into output word
    138 *
    139 cgl4a:          lsr.w   #1,d1           * Shift CG word right 1 pixel
    140                 dbf     d2,cgl2a        * Loop for last 4 pixels
    141 *
    142                 move.w  d0,(a1)         * Store second output word in scan line
    143                 suba.w  d5,a1           * Update output pointer
    144                 suba.w  #2,a1           * ...
    145                 adda.l  #512,a0         * Update CG pointer for next scan line
    146                 dbf     d6,cgl1         * Loop for all scan lines
    147 *
    148                 bra     cgl0            * Loop for next character
    149 *
    150 cgl5:           movem.l (a7)+,d3-d6/a3  * Restore registers
    151                 unlk    a6              * Unlink stack frames
    152                 rts                     * Return to caller
    153 *
     102cgl1:           move.w  (a0),d1         | Get character generator word in d1
     103                move.w  #(HPIX/2)-1,d2  | Set pixel counter in d2
     104                clr.l   d4              | Get old output word as background
     105                move.w  (a1),d4         | ...
     106                swap    d4              | ...
     107
     108cgl2:           lsr.w   #HSHIFT,d0      | Shift output word right 1 pixel
     109                lsr.l   #HSHIFT,d4      | Shift background word 1 pixel
     110                andi.l  #0xFFFFF000,d4  | Mask for upper 4 bits of d4.W
     111                btst.l  #0,d1           | Check CG word ls bit
     112                beq     cgl3            | Set background color if bit EQ 0
     113
     114                or.w    d3,d0           | OR foreground color into output word
     115                bra     cgl4            | Go update CG word
     116
     117cgl3:           or.w    d4,d0           | OR background color into output word
     118
     119cgl4:           lsr.w   #1,d1           | Shift CG word right 1 pixel
     120                dbf     d2,cgl2         | Loop for first 4 pixels
     121
     122                move.w  d0,(a1)+        | Store first output word in scan line
     123                move.w  #(HPIX/2)-1,d2  | Set pixel counter in d2
     124                clr.l   d4              | Get old output word as background
     125                move.w  (a1),d4         | ...
     126                swap    d4              | ...
     127
     128cgl2a:          lsr.w   #HSHIFT,d0      | Shift output word right 1 pixel
     129                lsr.l   #HSHIFT,d4      | Shift background word 1 pixel
     130                andi.l  #0xFFFFF000,d4  | Mask for upper bits of d4.W
     131                btst.l  #0,d1           | Check CG word ls bit
     132                beq     cgl3a           | Set background color if bit EQ 0
     133
     134                or.w    d3,d0           | OR foreground color into output word
     135                bra     cgl4a           | Go update CG word
     136
     137cgl3a:          or.w    d4,d0           | OR background color into output word
     138
     139cgl4a:          lsr.w   #1,d1           | Shift CG word right 1 pixel
     140                dbf     d2,cgl2a        | Loop for last 4 pixels
     141
     142                move.w  d0,(a1)         | Store second output word in scan line
     143                suba.w  d5,a1           | Update output pointer
     144                suba.w  #2,a1           | ...
     145                adda.l  #512,a0         | Update CG pointer for next scan line
     146                dbf     d6,cgl1         | Loop for all scan lines
     147
     148                bra     cgl0            | Loop for next character
     149
     150cgl5:           movem.l (a7)+,d3-d6/a3  | Restore registers
     151                unlk    a6              | Unlink stack frames
     152                rts                     | Return to caller
     153
    154154                .end
  • vlib/vbank.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vbank.s -- VSDD bank switching control functions
    3 * Version 3 -- 1989-12-19 -- D.N. Lynx Crowe
    4 *
    5 *       unsigned
    6 *       vbank(b)
    7 *       unsigned b;
    8 *
    9 *               Set VSDD Data Segment bank to b.
    10 *               Return old bank select value.
    11 *
    12 *
    13 *       vfwait()
    14 *
    15 *               Wait for a FRAMESTOP update to transpire.
    16 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| vbank.s -- VSDD bank switching control functions
     3| Version 3 -- 1989-12-19 -- D.N. Lynx Crowe
     4
     5|       unsigned
     6|       vbank(b)
     7|       unsigned b;
     8
     9|               Set VSDD Data Segment bank to b.
     10|               Return old bank select value.
     11
     12
     13|       vfwait()
     14
     15|               Wait for a FRAMESTOP update to transpire.
     16| ------------------------------------------------------------------------------
    1717                .xdef   _vbank
    1818                .xdef   _vfwait
    19 *
     19
    2020                .xref   _v_regs
    21 *
     21
    2222                .text
    23 *
    24 B               .equ    8
    25 *
    26 OLDB            .equ    d6
    27 NEWB            .equ    d7
    28 *
    29 VSDD_R5         .equ    10
    30 VSDD_R11        .equ    22
    31 *
    32 VT_BASE         .equ    128             * word offset of VSDD Access Table
    33 *
    34 VT_1            .equ    VT_BASE+300     * high time
    35 VT_2            .equ    VT_BASE+2       * low time
    36 *
     23
     24B               =       8
     25
     26OLDB            =       d6
     27NEWB            =       d7
     28
     29VSDD_R5         =       10
     30VSDD_R11        =       22
     31
     32VT_BASE         =       128             | word offset of VSDD Access Table
     33
     34VT_1            =       VT_BASE+300     | high time
     35VT_2            =       VT_BASE+2       | low time
     36
    3737                .page
    38 * ------------------------------------------------------------------------------
    39 *       vbank(b) -- change VSDD Data Segment bank to b.  Return old bank.
    40 *       Assumes a 128K byte window, sets S15..S11 to zero.
    41 * ------------------------------------------------------------------------------
    42 *
     38| ------------------------------------------------------------------------------
     39|       vbank(b) -- change VSDD Data Segment bank to b.  Return old bank.
     40|       Assumes a 128K byte window, sets S15..S11 to zero.
     41| ------------------------------------------------------------------------------
    4342
    44 _vbank:         link    a6,#0                   * link stack frames
    45                 movem.l d5-d7,-(sp)             * preserve registers
    46                 move.w  _v_regs+VSDD_R5,OLDB    * get v_regs[5]
    47                 lsr.w   #6,OLDB                 * extract BS bits
    48                 move.w  OLDB,d0                 * ...
    49                 andi.w  #2,d0                   * ...
    50                 move.w  OLDB,d1                 * ...
    51                 lsr.w   #2,d1                   * ...
    52                 andi.w  #1,d1                   * ...
    53                 or.w    d1,d0                   * ...
    54                 move.w  d0,OLDB                 * ...
    55                 cmp.w   B(a6),OLDB              * see if they're what we want
    56                 bne     L2                      * jump if not
    57 *
    58                 move.w  B(a6),d0                * setup to return b
     43
     44_vbank:         link    a6,#0                   | link stack frames
     45                movem.l d5-d7,-(sp)             | preserve registers
     46                move.w  _v_regs+VSDD_R5,OLDB    | get v_regs[5]
     47                lsr.w   #6,OLDB                 | extract BS bits
     48                move.w  OLDB,d0                 | ...
     49                andi.w  #2,d0                   | ...
     50                move.w  OLDB,d1                 | ...
     51                lsr.w   #2,d1                   | ...
     52                andi.w  #1,d1                   | ...
     53                or.w    d1,d0                   | ...
     54                move.w  d0,OLDB                 | ...
     55                cmp.w   B(a6),OLDB              | see if they're what we want
     56                bne     L2                      | jump if not
     57
     58                move.w  B(a6),d0                | setup to return b
    5959                bra     L1
    60 *
    61 L2:             move.w  B(a6),NEWB              * get bank bits from b
    62                 lsl.w   #6,NEWB                 * shift bits from b into BS bits
    63                 move.w  NEWB,d0                 * ...
    64                 andi.w  #128,d0                 * ...
    65                 lsl.w   #2,NEWB                 * ...
    66                 andi.w  #256,NEWB               * ...
    67                 or.w    NEWB,d0                 * ...
    68                 move.w  d0,_v_regs+VSDD_R5      * set v_regs[5] with new BS bits
    69 *
    70 vw1b:           cmp.w   #VT_1,_v_regs+VSDD_R11  * wait for FRAMESTOP
    71                 bcc     vw1b                    * ...
    72 *
    73 vw2b:           cmp.w   #VT_1,_v_regs+VSDD_R11  * ...
    74                 bcs     vw2b                    * ...
    75 *
    76 vw3b:           cmp.w   #VT_1,_v_regs+VSDD_R11  * ...
    77                 bcc     vw3b                    * ...
    78 *
    79 vw4b:           cmp.w   #VT_2,_v_regs+VSDD_R11  * ...
    80                 bcs     vw4b                    * ...
    81 *
    82                 move.w  OLDB,d0                 * setup to return OLDB
    83 *
    84 L1:             tst.l   (sp)+                   * fixup stack
    85                 movem.l (sp)+,OLDB-NEWB         * restore registers
    86                 unlk    a6                      * unlink stack frames
    87                 rts                             * return to caller
    88 *
     60
     61L2:             move.w  B(a6),NEWB              | get bank bits from b
     62                lsl.w   #6,NEWB                 | shift bits from b into BS bits
     63                move.w  NEWB,d0                 | ...
     64                andi.w  #128,d0                 | ...
     65                lsl.w   #2,NEWB                 | ...
     66                andi.w  #256,NEWB               | ...
     67                or.w    NEWB,d0                 | ...
     68                move.w  d0,_v_regs+VSDD_R5      | set v_regs[5] with new BS bits
     69
     70vw1b:           cmp.w   #VT_1,_v_regs+VSDD_R11  | wait for FRAMESTOP
     71                bcc     vw1b                    | ...
     72
     73vw2b:           cmp.w   #VT_1,_v_regs+VSDD_R11  | ...
     74                bcs     vw2b                    | ...
     75
     76vw3b:           cmp.w   #VT_1,_v_regs+VSDD_R11  | ...
     77                bcc     vw3b                    | ...
     78
     79vw4b:           cmp.w   #VT_2,_v_regs+VSDD_R11  | ...
     80                bcs     vw4b                    | ...
     81
     82                move.w  OLDB,d0                 | setup to return OLDB
     83
     84L1:             tst.l   (sp)+                   | fixup stack
     85                movem.l (sp)+,OLDB-NEWB         | restore registers
     86                unlk    a6                      | unlink stack frames
     87                rts                             | return to caller
     88
    8989                .page
    90 *
    91 * ------------------------------------------------------------------------------
    92 *       vfwait() -- Wait for a FRAMESTOP update to transpire.
    93 * ------------------------------------------------------------------------------
    94 *
    95 _vfwait:        link    a6,#0                   * link stack frames
    96 *
    97 vw1a:           cmp.w   #VT_1,_v_regs+VSDD_R11  * wait for FRAMESTOP
    98                 bcc     vw1a                    * ...
    99 *
    100 vw2a:           cmp.w   #VT_1,_v_regs+VSDD_R11  * ...
    101                 bcs     vw2a                    * ...
    102 *
    103 vw3a:           cmp.w   #VT_1,_v_regs+VSDD_R11  * ...
    104                 bcc     vw3a                    * ...
    105 *
    106 vw4a:           cmp.w   #VT_2,_v_regs+VSDD_R11  * ...
    107                 bcs     vw4a                    * ...
    108 *
    109                 unlk    a6                      * unlink stack frames
    110                 rts                             * return to caller
    111 *
     90
     91| ------------------------------------------------------------------------------
     92|       vfwait() -- Wait for a FRAMESTOP update to transpire.
     93| ------------------------------------------------------------------------------
     94
     95_vfwait:        link    a6,#0                   | link stack frames
     96
     97vw1a:           cmp.w   #VT_1,_v_regs+VSDD_R11  | wait for FRAMESTOP
     98                bcc     vw1a                    | ...
     99
     100vw2a:           cmp.w   #VT_1,_v_regs+VSDD_R11  | ...
     101                bcs     vw2a                    | ...
     102
     103vw3a:           cmp.w   #VT_1,_v_regs+VSDD_R11  | ...
     104                bcc     vw3a                    | ...
     105
     106vw4a:           cmp.w   #VT_2,_v_regs+VSDD_R11  | ...
     107                bcs     vw4a                    | ...
     108
     109                unlk    a6                      | unlink stack frames
     110                rts                             | return to caller
     111
    112112                .end
  • vlib/vclrav.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vclrav.s -- clear a character's attributes in video RAM
    3 * Version 1 -- 1988-10-11 -- D.N. Lynx Crowe
    4 * (c) Copyright 1988 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *
    7 *       vclrav(adr, row, col, atr, len)
    8 *       unsigned int *adr, row, col, atr, len;
    9 *
    10 *               Clears attribute 'atr' at ('row', 'col') in the
    11 *               full attribute text object at 'adr'
    12 *               using a line length of 'len'.
    13 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| vclrav.s -- clear a character's attributes in video RAM
     3| Version 1 -- 1988-10-11 -- D.N. Lynx Crowe
     4| (c) Copyright 1988 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6
     7|       vclrav(adr, row, col, atr, len)
     8|       unsigned int |adr, row, col, atr, len;
     9
     10|               Clears attribute 'atr' at ('row', 'col') in the
     11|               full attribute text object at 'adr'
     12|               using a line length of 'len'.
     13| ------------------------------------------------------------------------------
    1414                .text
    15 *
     15
    1616                .xdef   _vclrav
    17 *
    18 P_ADR           .equ    8
    19 P_ROW           .equ    12
    20 P_COL           .equ    14
    21 P_ATR           .equ    16
    22 P_LEN           .equ    18
    23 *
    24 _vclrav:        link    a6,#0           * Link stack frame pointer
    25                 move.w  P_ROW(a6),d0    * Get row
    26                 mulu    P_LEN(a6),d0    * Multiply by len
    27                 clr.l   d1              * Clear out d1
    28                 move.w  P_COL(a6),d1    * Get col
    29                 add.l   d1,d0           * Add col into d0 to get char. #
    30                 move.l  d0,d1           * Develop cw = (cn/2)*6 in d1
    31                 andi.l  #$FFFFFFFE,d1   * ...
    32                 move.l  d1,d2           * ...
    33                 add.l   d1,d1           * ...
    34                 add.l   d2,d1           * ...
    35                 add.l   P_ADR(a6),d1    * Add sbase to cw
    36                 movea.l d1,a0           * a0 points at the word with the char.
    37                 btst.l  #0,d0           * Odd char. location ?
    38                 bne     vclrav1         * Jump if so
    39 *
    40                 addq.l  #2,a0           * Point at the attribute word
    41                 bra     vclravx         * Go set attribute
    42 *
    43 vclrav1:        addq.l  #4,a0           * Point at the attribute word
    44 *
    45 vclravx:        move.w  P_ATR(a6),d0    * Get attribute mask
    46                 not.w   d0              * Complement the mask
    47                 and.w   d0,(a0)         * Clear attributes in video RAM
    48                 unlk    a6              * Unlink the stack frame
    49                 rts                     * Return to caller
    50 *
     17
     18P_ADR           =       8
     19P_ROW           =       12
     20P_COL           =       14
     21P_ATR           =       16
     22P_LEN           =       18
     23
     24_vclrav:        link    a6,#0           | Link stack frame pointer
     25                move.w  P_ROW(a6),d0    | Get row
     26                mulu    P_LEN(a6),d0    | Multiply by len
     27                clr.l   d1              | Clear out d1
     28                move.w  P_COL(a6),d1    | Get col
     29                add.l   d1,d0           | Add col into d0 to get char. #
     30                move.l  d0,d1           | Develop cw = (cn/2)|6 in d1
     31                andi.l  #0xFFFFFFFE,d1  | ...
     32                move.l  d1,d2           | ...
     33                add.l   d1,d1           | ...
     34                add.l   d2,d1           | ...
     35                add.l   P_ADR(a6),d1    | Add sbase to cw
     36                movea.l d1,a0           | a0 points at the word with the char.
     37                btst.l  #0,d0           | Odd char. location ?
     38                bne     vclrav1         | Jump if so
     39
     40                addq.l  #2,a0           | Point at the attribute word
     41                bra     vclravx         | Go set attribute
     42
     43vclrav1:        addq.l  #4,a0           | Point at the attribute word
     44
     45vclravx:        move.w  P_ATR(a6),d0    | Get attribute mask
     46                not.w   d0              | Complement the mask
     47                and.w   d0,(a0)         | Clear attributes in video RAM
     48                unlk    a6              | Unlink the stack frame
     49                rts                     | Return to caller
     50
    5151                .end
  • vlib/vcputs.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vcputs.s -- output a character string to a 4-bit per pixel graphics window
    3 * Version 3 -- 1987-07-31 -- D.N. Lynx Crowe
    4 * (c) Copyright 1987 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *
    7 *       vcputs(obase, nw, fg, bg, row, col, str)
    8 *       int *obase, nw, fg, bg, row, col;
    9 *       char *str;
    10 *
    11 *               Outputs characters from the string at 'str' to an 'nw'
    12 *               character wide 4-bit per pixel graphics window at 'obase'
    13 *               at ('row','col'), using 'fg' as the foreground color, and
    14 *               'bg' as the background color.  Uses cgtable[][256] as the
    15 *               VSDD formatted character generator table.
    16 *               No error checks are done.
    17 *
    18 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| vcputs.s -- output a character string to a 4-bit per pixel graphics window
     3| Version 3 -- 1987-07-31 -- D.N. Lynx Crowe
     4| (c) Copyright 1987 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6
     7|       vcputs(obase, nw, fg, bg, row, col, str)
     8|       int |obase, nw, fg, bg, row, col;
     9|       char |str;
     10
     11|               Outputs characters from the string at 'str' to an 'nw'
     12|               character wide 4-bit per pixel graphics window at 'obase'
     13|               at ('row','col'), using 'fg' as the foreground color, and
     14|               'bg' as the background color.  Uses cgtable[][256] as the
     15|               VSDD formatted character generator table.
     16|               No error checks are done.
     17
     18| ------------------------------------------------------------------------------
    1919                .text
    20 *
     20
    2121                .xdef   _vcputs
    22 *
     22
    2323                .xref   _cgtable
    24 *
    25 * Argument offsets from a6:
    26 *
    27 OBASE           .equ    8               * Output area base address
    28 NW              .equ    12              * Character width of output area
    29 FG              .equ    14              * Foreground color
    30 BG              .equ    16              * Background color
    31 ROW             .equ    18              * Row
    32 COL             .equ    20              * Column
    33 STR             .equ    22              * String base address
    34 *
    35 * Program constant definitions:
    36 *
    37 HPIX            .equ    8               * Character width in pixels
    38 VPIX            .equ    12              * Character height in pixels
    39 HCW             .equ    4               * Horizontal character width (bytes)
    40 PSHIFT          .equ    12              * Pixel shift into MS bits
    41 HSHIFT          .equ    4               * Pixel right shift
    42 *
     24
     25| Argument offsets from a6:
     26
     27OBASE           =       8               | Output area base address
     28NW              =       12              | Character width of output area
     29FG              =       14              | Foreground color
     30BG              =       16              | Background color
     31ROW             =       18              | Row
     32COL             =       20              | Column
     33STR             =       22              | String base address
     34
     35| Program constant definitions:
     36
     37HPIX            =       8               | Character width in pixels
     38VPIX            =       12              | Character height in pixels
     39HCW             =       4               | Horizontal character width (bytes)
     40PSHIFT          =       12              | Pixel shift into MS bits
     41HSHIFT          =       4               | Pixel right shift
     42
    4343                .page
    44 *
    45 * Register usage:
    46 *
    47 *       d0      output word and scratch
    48 *       d1      CG word and scratch
    49 *       d2      pixel counter
    50 *
    51 *       d3      foreground color (in the 4 ms bits)
    52 *       d4      background color (in the 4 ms bits)
    53 *       d5      width of the area in bytes
    54 *       d6      scan line counter
    55 *
    56 *       a0      CG table pointer
    57 *       a1      output area scan line pointer
    58 *       a2      input string character pointer
    59 *
    60 *       a3      output area character base pointer
    61 *
     44
     45| Register usage:
     46
     47|       d0      output word and scratch
     48|       d1      CG word and scratch
     49|       d2      pixel counter
     50
     51|       d3      foreground color (in the 4 ms bits)
     52|       d4      background color (in the 4 ms bits)
     53|       d5      width of the area in bytes
     54|       d6      scan line counter
     55
     56|       a0      CG table pointer
     57|       a1      output area scan line pointer
     58|       a2      input string character pointer
     59
     60|       a3      output area character base pointer
     61
    6262                .page
    63 *
    64 _vcputs:        link    a6,#0           * Link stack frames
    65                 movem.l d3-d6/a3,-(a7)  * Save registers we use
    66                 move.w  #PSHIFT,d1      * Set shift constant
    67                 move.w  FG(a6),d3       * Setup foreground color
    68                 lsl.w   d1,d3           * ... in ms 4 bits of d3.W
    69                 move.w  BG(a6),d4       * Setup background color
    70                 lsl.w   d1,d4           * ... in ms 4 bits of d4.W
    71                 move.w  NW(a6),d5       * Get line width in d5.W
    72                 lsl.w   #2,d5           * Multiply width by 4 for offset
    73                 move.w  ROW(a6),d0      * Calculate output address
    74                 move.w  #VPIX,d1        * ... VPIX
    75                 mulu    d1,d0           * ... * ROW
    76                 add.w   #VPIX-1,d0      * ... + VPIX-1
    77                 mulu    d5,d0           * ... * NW
    78                 clr.l   d1              * ...
    79                 move.w  COL(a6),d1      * ... +
    80                 lsl.w   #2,d1           * ... COL * 4
    81                 add.l   d1,d0           * ...
    82                 add.l   OBASE(a6),d0    * ... + OBASE
    83                 movea.l d0,a3           * Leave output address in a3
    84                 movea.l STR(a6),a2      * Put string address in a2
    85 *
    86 cgl0:           clr.l   d0              * Clear out upper bits of d0
    87                 move.b  (a2)+,d0        * Get next character
    88                 beq     cgl5            * Done if character EQ 0
    89 *
    90                 movea.l a3,a1           * Establish output pointer in a1
    91                 adda.l  #HCW,a3         * Update output pointer for next char.
    92                 lea     _cgtable,a0     * Establish CG pointer in a0
    93                 lsl.w   #1,d0           * ... 2 * character
    94                 adda.w  d0,a0           * ... + _cgtable address
    95                 move.w  #VPIX-1,d6      * Set scan line counter in d6
    96 *
     63
     64_vcputs:        link    a6,#0           | Link stack frames
     65                movem.l d3-d6/a3,-(a7)  | Save registers we use
     66                move.w  #PSHIFT,d1      | Set shift constant
     67                move.w  FG(a6),d3       | Setup foreground color
     68                lsl.w   d1,d3           | ... in ms 4 bits of d3.W
     69                move.w  BG(a6),d4       | Setup background color
     70                lsl.w   d1,d4           | ... in ms 4 bits of d4.W
     71                move.w  NW(a6),d5       | Get line width in d5.W
     72                lsl.w   #2,d5           | Multiply width by 4 for offset
     73                move.w  ROW(a6),d0      | Calculate output address
     74                move.w  #VPIX,d1        | ... VPIX
     75                mulu    d1,d0           | ... | ROW
     76                add.w   #VPIX-1,d0      | ... + VPIX-1
     77                mulu    d5,d0           | ... | NW
     78                clr.l   d1              | ...
     79                move.w  COL(a6),d1      | ... +
     80                lsl.w   #2,d1           | ... COL | 4
     81                add.l   d1,d0           | ...
     82                add.l   OBASE(a6),d0    | ... + OBASE
     83                movea.l d0,a3           | Leave output address in a3
     84                movea.l STR(a6),a2      | Put string address in a2
     85
     86cgl0:           clr.l   d0              | Clear out upper bits of d0
     87                move.b  (a2)+,d0        | Get next character
     88                beq     cgl5            | Done if character EQ 0
     89
     90                movea.l a3,a1           | Establish output pointer in a1
     91                adda.l  #HCW,a3         | Update output pointer for next char.
     92                lea     _cgtable,a0     | Establish CG pointer in a0
     93                lsl.w   #1,d0           | ... 2 | character
     94                adda.w  d0,a0           | ... + _cgtable address
     95                move.w  #VPIX-1,d6      | Set scan line counter in d6
     96
    9797                .page
    98 cgl1:           move.w  (a0),d1         * Get character generator word in d1
    99                 move.w  #(HPIX/2)-1,d2  * Set pixel counter in d2
    100 *
    101 cgl2:           lsr.w   #HSHIFT,d0      * Shift output word right 1 pixel
    102                 btst.l  #0,d1           * Check CG word ls bit
    103                 beq     cgl3            * Set background color if bit EQ 0
    104 *
    105                 or.w    d3,d0           * OR foreground color into output word
    106                 bra     cgl4            * Go update CG word
    107 *
    108 cgl3:           or.w    d4,d0           * OR background color into output word
    109 *
    110 cgl4:           lsr.w   #1,d1           * Shift CG word right 1 pixel
    111                 dbf     d2,cgl2         * Loop for first 4 pixels
    112 *
    113                 move.w  d0,(a1)+        * Store first output word in scan line
    114                 move.w  #(HPIX/2)-1,d2  * Set pixel counter in d2
    115 *
    116 cgl2a:          lsr.w   #HSHIFT,d0      * Shift output word right 1 pixel
    117                 btst.l  #0,d1           * Check CG word ls bit
    118                 beq     cgl3a           * Set background color if bit EQ 0
    119 *
    120                 or.w    d3,d0           * OR foreground color into output word
    121                 bra     cgl4a           * Go update CG word
    122 *
    123 cgl3a:          or.w    d4,d0           * OR background color into output word
    124 *
    125 cgl4a:          lsr.w   #1,d1           * Shift CG word right 1 pixel
    126                 dbf     d2,cgl2a        * Loop for last 4 pixels
    127 *
    128                 move.w  d0,(a1)         * Store second output word in scan line
    129                 suba.w  d5,a1           * Update output pointer
    130                 suba.w  #2,a1           * ...
    131                 adda.l  #512,a0         * Update CG pointer for next scan line
    132                 dbf     d6,cgl1         * Loop for all scan lines
    133 *
    134                 bra     cgl0            * Loop for next character
    135 *
    136 cgl5:           movem.l (a7)+,d3-d6/a3  * Restore registers
    137                 unlk    a6              * Unlink stack frames
    138                 rts                     * Return to caller
    139 *
     98cgl1:           move.w  (a0),d1         | Get character generator word in d1
     99                move.w  #(HPIX/2)-1,d2  | Set pixel counter in d2
     100
     101cgl2:           lsr.w   #HSHIFT,d0      | Shift output word right 1 pixel
     102                btst.l  #0,d1           | Check CG word ls bit
     103                beq     cgl3            | Set background color if bit EQ 0
     104
     105                or.w    d3,d0           | OR foreground color into output word
     106                bra     cgl4            | Go update CG word
     107
     108cgl3:           or.w    d4,d0           | OR background color into output word
     109
     110cgl4:           lsr.w   #1,d1           | Shift CG word right 1 pixel
     111                dbf     d2,cgl2         | Loop for first 4 pixels
     112
     113                move.w  d0,(a1)+        | Store first output word in scan line
     114                move.w  #(HPIX/2)-1,d2  | Set pixel counter in d2
     115
     116cgl2a:          lsr.w   #HSHIFT,d0      | Shift output word right 1 pixel
     117                btst.l  #0,d1           | Check CG word ls bit
     118                beq     cgl3a           | Set background color if bit EQ 0
     119
     120                or.w    d3,d0           | OR foreground color into output word
     121                bra     cgl4a           | Go update CG word
     122
     123cgl3a:          or.w    d4,d0           | OR background color into output word
     124
     125cgl4a:          lsr.w   #1,d1           | Shift CG word right 1 pixel
     126                dbf     d2,cgl2a        | Loop for last 4 pixels
     127
     128                move.w  d0,(a1)         | Store second output word in scan line
     129                suba.w  d5,a1           | Update output pointer
     130                suba.w  #2,a1           | ...
     131                adda.l  #512,a0         | Update CG pointer for next scan line
     132                dbf     d6,cgl1         | Loop for all scan lines
     133
     134                bra     cgl0            | Loop for next character
     135
     136cgl5:           movem.l (a7)+,d3-d6/a3  | Restore registers
     137                unlk    a6              | Unlink stack frames
     138                rts                     | Return to caller
     139
    140140                .end
  • vlib/vcputsv.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vcputsv.s -- output characters to a 4-bit / pixel graphics window
    3 * with variable vertical pitch
    4 * Version 2 -- 1987-08-03 -- D.N. Lynx Crowe
    5 * (c) Copyright 1987 -- D.N. Lynx Crowe
    6 * ------------------------------------------------------------------------------
    7 *
    8 *       vcputsv(obase, nw, fg, bg, row, col, str. pitch)
    9 *       int *obase, nw, fg, bg, row, col, pitch;
    10 *       char *str;
    11 *
    12 *               Outputs characters from the string at 'str' to an 'nw'
    13 *               character wide 4-bit per pixel graphics window at 'obase'
    14 *               at ('row','col'), using 'fg' as the foreground color, and
    15 *               'bg' as the background color.  Uses cgtable[][256] as the
    16 *               VSDD formatted character generator table.  Assumes 12 bit
    17 *               high characters in the cgtable.  Uses 'pitch' as the vertical
    18 *               spacing between character rows.  No error checks are done.
    19 *               The string must fit the output area (no overlaps, single line).
    20 *
    21 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| vcputsv.s -- output characters to a 4-bit / pixel graphics window
     3| with variable vertical pitch
     4| Version 2 -- 1987-08-03 -- D.N. Lynx Crowe
     5| (c) Copyright 1987 -- D.N. Lynx Crowe
     6| ------------------------------------------------------------------------------
     7
     8|       vcputsv(obase, nw, fg, bg, row, col, str. pitch)
     9|       int |obase, nw, fg, bg, row, col, pitch;
     10|       char |str;
     11
     12|               Outputs characters from the string at 'str' to an 'nw'
     13|               character wide 4-bit per pixel graphics window at 'obase'
     14|               at ('row','col'), using 'fg' as the foreground color, and
     15|               'bg' as the background color.  Uses cgtable[][256] as the
     16|               VSDD formatted character generator table.  Assumes 12 bit
     17|               high characters in the cgtable.  Uses 'pitch' as the vertical
     18|               spacing between character rows.  No error checks are done.
     19|               The string must fit the output area (no overlaps, single line).
     20
     21| ------------------------------------------------------------------------------
    2222                .text
    23 *
     23
    2424                .xdef   _vcputsv
    25 *
     25
    2626                .xref   _cgtable
    27 *
    28 * Argument offsets from a6:
    29 *
    30 OBASE           .equ    8               * LONG - Output area base address
    31 NW              .equ    12              * WORD - Character width of output area
    32 FG              .equ    14              * WORD - Foreground color
    33 BG              .equ    16              * WORD - Background color
    34 ROW             .equ    18              * WORD - Row
    35 COL             .equ    20              * WORD - Column
    36 STR             .equ    22              * LONG - String base address
    37 PITCH           .equ    26              * WORD - Vertical spacing between rows
    38 *
    39 * Program constant definitions:
    40 *
    41 HPIX            .equ    8               * Character width in pixels
    42 VPIX            .equ    12              * Character height in pixels
    43 HCW             .equ    4               * Horizontal character width (bytes)
    44 PSHIFT          .equ    12              * Pixel shift into MS bits
    45 HSHIFT          .equ    4               * Pixel right shift
    46 *
     27
     28| Argument offsets from a6:
     29
     30OBASE           =       8               | LONG - Output area base address
     31NW              =       12              | WORD - Character width of output area
     32FG              =       14              | WORD - Foreground color
     33BG              =       16              | WORD - Background color
     34ROW             =       18              | WORD - Row
     35COL             =       20              | WORD - Column
     36STR             =       22              | LONG - String base address
     37PITCH           =       26              | WORD - Vertical spacing between rows
     38
     39| Program constant definitions:
     40
     41HPIX            =       8               | Character width in pixels
     42VPIX            =       12              | Character height in pixels
     43HCW             =       4               | Horizontal character width (bytes)
     44PSHIFT          =       12              | Pixel shift into MS bits
     45HSHIFT          =       4               | Pixel right shift
     46
    4747                .page
    48 *
    49 * Register usage:
    50 *
    51 *       d0      output word and scratch
    52 *       d1      CG word and scratch
    53 *       d2      pixel counter
    54 *
    55 *       d3      foreground color (in the 4 ms bits)
    56 *       d4      background color (in the 4 ms bits)
    57 *       d5      width of the area in bytes
    58 *       d6      scan line counter
    59 *
    60 *       a0      CG table pointer
    61 *       a1      output area scan line pointer
    62 *       a2      input string character pointer
    63 *
    64 *       a3      output area character base pointer
    65 *
    66 *       a6      frame pointer
    67 *       a7      stack pointer
    68 *
     48
     49| Register usage:
     50
     51|       d0      output word and scratch
     52|       d1      CG word and scratch
     53|       d2      pixel counter
     54
     55|       d3      foreground color (in the 4 ms bits)
     56|       d4      background color (in the 4 ms bits)
     57|       d5      width of the area in bytes
     58|       d6      scan line counter
     59
     60|       a0      CG table pointer
     61|       a1      output area scan line pointer
     62|       a2      input string character pointer
     63
     64|       a3      output area character base pointer
     65
     66|       a6      frame pointer
     67|       a7      stack pointer
     68
    6969                .page
    70 *
    71 _vcputsv:       link    a6,#0           * Link stack frames
    72                 movem.l d3-d6/a3,-(a7)  * Save registers we use
    73                 move.w  #PSHIFT,d1      * Set shift constant
    74                 move.w  FG(a6),d3       * Setup foreground color
    75                 lsl.w   d1,d3           * ... in ms 4 bits of d3.W
    76                 move.w  BG(a6),d4       * Setup background color
    77                 lsl.w   d1,d4           * ... in ms 4 bits of d4.W
    78                 move.w  NW(a6),d5       * Get line width in d5.W
    79                 lsl.w   #2,d5           * Multiply width by 4 for offset
    80                 move.w  ROW(a6),d0      * Calculate output address
    81                 move.w  PITCH(a6),d1    * ... PITCH
    82                 mulu    d1,d0           * ... * ROW
    83                 add.w   #VPIX-1,d0      * ... + VPIX-1
    84                 mulu    d5,d0           * ... * NW
    85                 clr.l   d1              * ...
    86                 move.w  COL(a6),d1      * ... +
    87                 lsl.w   #2,d1           * ... COL * 4
    88                 add.l   d1,d0           * ...
    89                 add.l   OBASE(a6),d0    * ... + OBASE
    90                 movea.l d0,a3           * Leave output address in a3
    91                 movea.l STR(a6),a2      * Put string address in a2
    92 *
    93 cgl0:           clr.l   d0              * Clear out upper bits of d0
    94                 move.b  (a2)+,d0        * Get next character
    95                 beq     cgl5            * Done if character EQ 0
    96 *
    97                 movea.l a3,a1           * Establish output pointer in a1
    98                 adda.l  #HCW,a3         * Update output pointer for next char.
    99                 lea     _cgtable,a0     * Establish CG pointer in a0
    100                 lsl.w   #1,d0           * ... 2 * character
    101                 adda.w  d0,a0           * ... + _cgtable address
    102                 move.w  #VPIX-1,d6      * Set scan line counter in d6
    103 *
     70
     71_vcputsv:       link    a6,#0           | Link stack frames
     72                movem.l d3-d6/a3,-(a7)  | Save registers we use
     73                move.w  #PSHIFT,d1      | Set shift constant
     74                move.w  FG(a6),d3       | Setup foreground color
     75                lsl.w   d1,d3           | ... in ms 4 bits of d3.W
     76                move.w  BG(a6),d4       | Setup background color
     77                lsl.w   d1,d4           | ... in ms 4 bits of d4.W
     78                move.w  NW(a6),d5       | Get line width in d5.W
     79                lsl.w   #2,d5           | Multiply width by 4 for offset
     80                move.w  ROW(a6),d0      | Calculate output address
     81                move.w  PITCH(a6),d1    | ... PITCH
     82                mulu    d1,d0           | ... | ROW
     83                add.w   #VPIX-1,d0      | ... + VPIX-1
     84                mulu    d5,d0           | ... | NW
     85                clr.l   d1              | ...
     86                move.w  COL(a6),d1      | ... +
     87                lsl.w   #2,d1           | ... COL | 4
     88                add.l   d1,d0           | ...
     89                add.l   OBASE(a6),d0    | ... + OBASE
     90                movea.l d0,a3           | Leave output address in a3
     91                movea.l STR(a6),a2      | Put string address in a2
     92
     93cgl0:           clr.l   d0              | Clear out upper bits of d0
     94                move.b  (a2)+,d0        | Get next character
     95                beq     cgl5            | Done if character EQ 0
     96
     97                movea.l a3,a1           | Establish output pointer in a1
     98                adda.l  #HCW,a3         | Update output pointer for next char.
     99                lea     _cgtable,a0     | Establish CG pointer in a0
     100                lsl.w   #1,d0           | ... 2 | character
     101                adda.w  d0,a0           | ... + _cgtable address
     102                move.w  #VPIX-1,d6      | Set scan line counter in d6
     103
    104104                .page
    105 cgl1:           move.w  (a0),d1         * Get character generator word in d1
    106                 move.w  #(HPIX/2)-1,d2  * Set pixel counter in d2
    107 *
    108 cgl2:           lsr.w   #HSHIFT,d0      * Shift output word right 1 pixel
    109                 btst.l  #0,d1           * Check CG word ls bit
    110                 beq     cgl3            * Set background color if bit EQ 0
    111 *
    112                 or.w    d3,d0           * OR foreground color into output word
    113                 bra     cgl4            * Go update CG word
    114 *
    115 cgl3:           or.w    d4,d0           * OR background color into output word
    116 *
    117 cgl4:           lsr.w   #1,d1           * Shift CG word right 1 pixel
    118                 dbf     d2,cgl2         * Loop for first 4 pixels
    119 *
    120                 move.w  d0,(a1)+        * Store first output word in scan line
    121                 move.w  #(HPIX/2)-1,d2  * Set pixel counter in d2
    122 *
    123 cgl2a:          lsr.w   #HSHIFT,d0      * Shift output word right 1 pixel
    124                 btst.l  #0,d1           * Check CG word ls bit
    125                 beq     cgl3a           * Set background color if bit EQ 0
    126 *
    127                 or.w    d3,d0           * OR foreground color into output word
    128                 bra     cgl4a           * Go update CG word
    129 *
    130 cgl3a:          or.w    d4,d0           * OR background color into output word
    131 *
    132 cgl4a:          lsr.w   #1,d1           * Shift CG word right 1 pixel
    133                 dbf     d2,cgl2a        * Loop for last 4 pixels
    134 *
    135                 move.w  d0,(a1)         * Store second output word in scan line
    136                 suba.w  d5,a1           * Update output pointer
    137                 suba.w  #2,a1           * ...
    138                 adda.l  #512,a0         * Update CG pointer for next scan line
    139                 dbf     d6,cgl1         * Loop for all scan lines
    140 *
    141                 bra     cgl0            * Loop for next character
    142 *
    143 cgl5:           movem.l (a7)+,d3-d6/a3  * Restore registers
    144                 unlk    a6              * Unlink stack frames
    145                 rts                     * Return to caller
    146 *
     105cgl1:           move.w  (a0),d1         | Get character generator word in d1
     106                move.w  #(HPIX/2)-1,d2  | Set pixel counter in d2
     107
     108cgl2:           lsr.w   #HSHIFT,d0      | Shift output word right 1 pixel
     109                btst.l  #0,d1           | Check CG word ls bit
     110                beq     cgl3            | Set background color if bit EQ 0
     111
     112                or.w    d3,d0           | OR foreground color into output word
     113                bra     cgl4            | Go update CG word
     114
     115cgl3:           or.w    d4,d0           | OR background color into output word
     116
     117cgl4:           lsr.w   #1,d1           | Shift CG word right 1 pixel
     118                dbf     d2,cgl2         | Loop for first 4 pixels
     119
     120                move.w  d0,(a1)+        | Store first output word in scan line
     121                move.w  #(HPIX/2)-1,d2  | Set pixel counter in d2
     122
     123cgl2a:          lsr.w   #HSHIFT,d0      | Shift output word right 1 pixel
     124                btst.l  #0,d1           | Check CG word ls bit
     125                beq     cgl3a           | Set background color if bit EQ 0
     126
     127                or.w    d3,d0           | OR foreground color into output word
     128                bra     cgl4a           | Go update CG word
     129
     130cgl3a:          or.w    d4,d0           | OR background color into output word
     131
     132cgl4a:          lsr.w   #1,d1           | Shift CG word right 1 pixel
     133                dbf     d2,cgl2a        | Loop for last 4 pixels
     134
     135                move.w  d0,(a1)         | Store second output word in scan line
     136                suba.w  d5,a1           | Update output pointer
     137                suba.w  #2,a1           | ...
     138                adda.l  #512,a0         | Update CG pointer for next scan line
     139                dbf     d6,cgl1         | Loop for all scan lines
     140
     141                bra     cgl0            | Loop for next character
     142
     143cgl5:           movem.l (a7)+,d3-d6/a3  | Restore registers
     144                unlk    a6              | Unlink stack frames
     145                rts                     | Return to caller
     146
    147147                .end
  • vlib/viint.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * viint.s -- VSDD Vertical Interval interrupt handler for the Buchla 700
    3 * Version 17 -- 1989-12-19 -- D.N. Lynx Crowe
    4 *
    5 *       VIint
    6 *
    7 *               VSDD Vertical Interval interrupt handler.  Enables display of
    8 *               any object whose bit is set in vi_ctl.  Bit 0 = object 0, etc.
    9 *
    10 *               SetPri() uses BIOS(B_SETV, 25, VIint) to set the interrupt
    11 *               vector and lets VIint() enable the object.  If vi_dis
    12 *               is set, SetPri() won't enable the interrupt or set the vector
    13 *               so that several objects can be started up at once.
    14 *
    15 *               This routine also sets the base address and scroll offset
    16 *               for the score display object if vi_sadr is non-zero,
    17 *               after a delay for VSDD FRAMESTOP synchronization.
    18 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| viint.s -- VSDD Vertical Interval interrupt handler for the Buchla 700
     3| Version 17 -- 1989-12-19 -- D.N. Lynx Crowe
     4
     5|       VIint
     6
     7|               VSDD Vertical Interval interrupt handler.  Enables display of
     8|               any object whose bit is set in vi_ctl.  Bit 0 = object 0, etc.
     9
     10|               SetPri() uses BIOS(B_SETV, 25, VIint) to set the interrupt
     11|               vector and lets VIint() enable the object.  If vi_dis
     12|               is set, SetPri() won't enable the interrupt or set the vector
     13|               so that several objects can be started up at once.
     14
     15|               This routine also sets the base address and scroll offset
     16|               for the score display object if vi_sadr is non-zero,
     17|               after a delay for VSDD FRAMESTOP synchronization.
     18| ------------------------------------------------------------------------------
    1919                .text
    20 *
    21                 .xdef   _VIint                  * Vertical Interval int. handler
    22 *
    23                 .xdef   _vi_sadr                * score object base address
    24                 .xdef   _vi_scrl                * score object scroll offset
    25                 .xdef   lclsadr                 * local scroll address
    26                 .xdef   lclscrl                 * local scroll offset
    27                 .xdef   vdelay                  * VSDD scroll delay
    28 *
    29                 .xdef   VIct1                   * VSDD interrupt R11
    30                 .xdef   VIct2                   * VSDD interrupt R11
    31                 .xdef   VIct3                   * VSDD interrupt R11
    32                 .xdef   VIct4                   * VSDD interrupt R11
    33 *
    34                 .xref   _v_regs                 * VSDD registers
    35                 .xref   _v_odtab                * VSDD object descriptor table
    36 *
    37                 .xref   _vi_clk                 * scroll delay timer
    38                 .xref   _vi_ctl                 * unblank control word
    39                 .xref   _vi_tag                 * VSDD 'needs service' tag
    40 *
    41                 .page
    42 *
    43 * Miscellaneous equates:
    44 * ----------------------
    45 *
    46 DELAY           .equ    17                      * FRAMESTOP sync delay in Ms
    47 STACKSR         .equ    32                      * offset to sr on stack
    48 V_BLA           .equ    4                       * V_BLA (blank) bit number
    49 VSDD_R5         .equ    10                      * VSDD R5 byte offset in _v_regs
    50 VSDD_R11        .equ    22                      * VSDD R11 byte offset in _v_regs
    51 *
    52 VT_BASE         .equ    128                     * word offset of VSDD Access Table
    53 *
    54 VT_1            .equ    VT_BASE+300             * high time
    55 VT_2            .equ    VT_BASE+2               * low time
    56 * ------------------------------------------------------------------------------
    57 *
    58 * Stack picture after movem.l at entry:
    59 * -------------------------------------
    60 *
    61 *       LONG    PC      +34
    62 *       WORD    SR      +32     STACKSR
    63 *       LONG    A6      +28
    64 *       LONG    A2      +24
    65 *       LONG    A1      +20
    66 *       LONG    A0      +16
    67 *       LONG    D3      +12
    68 *       LONG    D2      +8
    69 *       LONG    D1      +4
    70 *       LONG    D0      +0
    71 *
    72 * ------------------------------------------------------------------------------
    73 *
    74                 .page
    75 *
    76 * _VIint -- Vertical interval interrupt handler
    77 * ------    -----------------------------------
    78 _VIint:         movem.l d0-d3/a0-a2/a6,-(a7)    * save registers
    79                 addi.w  #$0100,STACKSR(a7)      * raise IPL in sr on the stack
    80 *
    81                 move.w  _v_regs+VSDD_R11,VIct1  * save the VSDD R11 value
    82 *
    83                 tst.w   _vi_sadr                * see if we should scroll
    84                 beq     viunbl                  * jump if not
    85 *
    86 * ------------------------------------------------------------------------------
    87 * setup delayed scroll parameters
    88 * ------------------------------------------------------------------------------
    89                 move.w  _v_regs+VSDD_R5,d0      * get VSDD R5
    90                 move.w  d0,d1                   * save it for later
    91                 andi.w  #$0180,d0               * see if we're already in bank 0
    92                 beq     dlyscrl                 * jump if so
    93 *
    94                 clr.w   _v_regs+VSDD_R5         * set bank 0
    95 *
    96                 move.w  _v_regs+VSDD_R11,VIct2  * save the VSDD R11 value
    97 *
    98 vw1a:           cmp.w   #VT_1,_v_regs+VSDD_R11  * wait for FRAMESTOP
    99                 bcc     vw1a                    * ...
    100 *
    101 vw2a:           cmp.w   #VT_1,_v_regs+VSDD_R11  * ...
    102                 bcs     vw2a                    * ...
    103 *
    104 vw3a:           cmp.w   #VT_1,_v_regs+VSDD_R11  * ...
    105                 bcc     vw3a                    * ...
    106 *
    107 vw4a:           cmp.w   #VT_2,_v_regs+VSDD_R11  * ...
    108                 bcs     vw4a                    * ...
    109 *
    110 dlyscrl:        tst.w   _vi_tag                 * wait for previous scroll
    111                 bne     dlyscrl                 * ...
    112 *
    113                 move.w  _vi_sadr,lclsadr        * save address for timeint
    114                 move.w  _vi_scrl,lclscrl        * save offset for timeint
    115                 clr.w   _vi_sadr                * reset for next time
    116                 clr.w   _vi_scrl                * ...
    117                 move.w  vdelay,_vi_clk          * set the scroll delay timer
    118                 st      _vi_tag                 * set the 'need service' tag
    119 * ------------------------------------------------------------------------------
    120 * check for unblank requests
    121 * ------------------------------------------------------------------------------
    122                 move.w  _vi_ctl,d2              * get the unblank control word
    123                 beq     viexit                  * exit if nothing to unblank
    124 *
    125                 bra     unblnk                  * go unblank some objects
    126 *
    127 viunbl:         move.w  _vi_ctl,d2              * get the unblank control word
    128                 beq     vidone                  * exit if nothing to unblank
    129 *
    130                 move.w  _v_regs+VSDD_R5,d0      * get VSDD R5
    131                 move.w  d0,d1                   * save it for later
    132                 andi.w  #$0180,d0               * see if we're already in bank 0
    133                 beq     unblnk                  * jump if so
    134 *
    135                 clr.w   _v_regs+VSDD_R5         * set bank 0
    136 *
    137                 move.w  _v_regs+VSDD_R11,VIct3  * save the VSDD R11 value
    138 *
    139 vw1b:           cmp.w   #VT_1,_v_regs+VSDD_R11  * wait for FRAMESTOP
    140                 bcc     vw1b                    * ...
    141 *
    142 vw2b:           cmp.w   #VT_1,_v_regs+VSDD_R11  * ...
    143                 bcs     vw2b                    * ...
    144 *
    145 vw3b:           cmp.w   #VT_1,_v_regs+VSDD_R11  * ...
    146                 bcc     vw3b                    * ...
    147 *
    148 vw4b:           cmp.w   #VT_2,_v_regs+VSDD_R11  * ...
    149                 bcs     vw4b                    * ...
    150 *
    151                 .page
    152 *
    153 * ------------------------------------------------------------------------------
    154 * unblank objects indicated by contents of d2  (loaded earlier from _vi_ctl)
    155 * ------------------------------------------------------------------------------
    156 *
    157 unblnk:         clr.w   d3                      * clear the counter
    158                 clr.w   _vi_ctl                 * clear the unblank control word
    159                 lea     _v_odtab,a1             * point at first object
    160 *
    161 vicheck:        btst    d3,d2                   * check the object bit
    162                 beq     vinext                  * go check next one if not set
    163 *
    164                 move.w  (a1),d0                 * get v_odtab[obj][0]
    165                 bclr    #V_BLA,d0               * clear the blanking bit
    166                 move.w  d0,(a1)                 * set v_odtab[obj][0]
    167 *
    168 vinext:         cmpi.w  #15,d3                  * see if we're done
    169                 beq     viexit                  * jump if so
    170 *
    171                 addq.l  #8,a1                   * point at next object
    172                 addq.w  #1,d3                   * increment object counter
    173                 bra     vicheck                 * go check next object
    174 *
    175 * ------------------------------------------------------------------------------
    176 * switch back to the bank the interrupted code was using if we changed it
    177 * ------------------------------------------------------------------------------
    178 *
    179 viexit:         move.w  d1,d0                   * see if we were in bank 0
    180                 andi.w  #$0180,d0               * ...
    181                 beq     vidone                  * jump if so
    182 *
    183 viwait:         tst.w   _vi_tag                 * wait for timer to run out
    184                 bne     viwait                  * ... so timeint sees bank 0
    185 *
    186                 move.w  d1,_v_regs+VSDD_R5      * restore v_regs[5] to old bank
    187 *
    188                 move.w  _v_regs+VSDD_R11,VIct4  * save the VSDD R11 value
    189 *
    190 vw1c:           cmp.w   #VT_1,_v_regs+VSDD_R11  * wait for FRAMESTOP
    191                 bcc     vw1c                    * ...
    192 *
    193 vw2c:           cmp.w   #VT_1,_v_regs+VSDD_R11  * ...
    194                 bcs     vw2c                    * ...
    195 *
    196 vw3c:           cmp.w   #VT_1,_v_regs+VSDD_R11  * ...
    197                 bcc     vw3c                    * ...
    198 *
    199 vw4c:           cmp.w   #VT_2,_v_regs+VSDD_R11  * ...
    200                 bcs     vw4c                    * ...
    201 *
    202 * ------------------------------------------------------------------------------
    203 * restore registers and return to interrupted code
    204 * ------------------------------------------------------------------------------
    205 *
    206 vidone:         movem.l (a7)+,d0-d3/a0-a2/a6    * restore registers
    207                 rte                             * return from interrupt
    208 *
    209                 .page
    210 *
    211 * ------------------------------------------------------------------------------
     20
     21                .xdef   _VIint                  | Vertical Interval int. handler
     22
     23                .xdef   _vi_sadr                | score object base address
     24                .xdef   _vi_scrl                | score object scroll offset
     25                .xdef   lclsadr                 | local scroll address
     26                .xdef   lclscrl                 | local scroll offset
     27                .xdef   vdelay                  | VSDD scroll delay
     28
     29                .xdef   VIct1                   | VSDD interrupt R11
     30                .xdef   VIct2                   | VSDD interrupt R11
     31                .xdef   VIct3                   | VSDD interrupt R11
     32                .xdef   VIct4                   | VSDD interrupt R11
     33
     34                .xref   _v_regs                 | VSDD registers
     35                .xref   _v_odtab                | VSDD object descriptor table
     36
     37                .xref   _vi_clk                 | scroll delay timer
     38                .xref   _vi_ctl                 | unblank control word
     39                .xref   _vi_tag                 | VSDD 'needs service' tag
     40
     41                .page
     42
     43| Miscellaneous equates:
     44| ----------------------
     45
     46DELAY           =       17                      | FRAMESTOP sync delay in Ms
     47STACKSR         =       32                      | offset to sr on stack
     48V_BLA           =       4                       | V_BLA (blank) bit number
     49VSDD_R5         =       10                      | VSDD R5 byte offset in _v_regs
     50VSDD_R11        =       22                      | VSDD R11 byte offset in _v_regs
     51
     52VT_BASE         =       128                     | word offset of VSDD Access Table
     53
     54VT_1            =       VT_BASE+300             | high time
     55VT_2            =       VT_BASE+2               | low time
     56| ------------------------------------------------------------------------------
     57
     58| Stack picture after movem.l at entry:
     59| -------------------------------------
     60
     61|       LONG    PC      +34
     62|       WORD    SR      +32     STACKSR
     63|       LONG    A6      +28
     64|       LONG    A2      +24
     65|       LONG    A1      +20
     66|       LONG    A0      +16
     67|       LONG    D3      +12
     68|       LONG    D2      +8
     69|       LONG    D1      +4
     70|       LONG    D0      +0
     71
     72| ------------------------------------------------------------------------------
     73
     74                .page
     75
     76| _VIint -- Vertical interval interrupt handler
     77| ------    -----------------------------------
     78_VIint:         movem.l d0-d3/a0-a2/a6,-(a7)    | save registers
     79                addi.w  #0x0100,STACKSR(a7)     | raise IPL in sr on the stack
     80
     81                move.w  _v_regs+VSDD_R11,VIct1  | save the VSDD R11 value
     82
     83                tst.w   _vi_sadr                | see if we should scroll
     84                beq     viunbl                  | jump if not
     85
     86| ------------------------------------------------------------------------------
     87| setup delayed scroll parameters
     88| ------------------------------------------------------------------------------
     89                move.w  _v_regs+VSDD_R5,d0      | get VSDD R5
     90                move.w  d0,d1                   | save it for later
     91                andi.w  #0x0180,d0              | see if we're already in bank 0
     92                beq     dlyscrl                 | jump if so
     93
     94                clr.w   _v_regs+VSDD_R5         | set bank 0
     95
     96                move.w  _v_regs+VSDD_R11,VIct2  | save the VSDD R11 value
     97
     98vw1a:           cmp.w   #VT_1,_v_regs+VSDD_R11  | wait for FRAMESTOP
     99                bcc     vw1a                    | ...
     100
     101vw2a:           cmp.w   #VT_1,_v_regs+VSDD_R11  | ...
     102                bcs     vw2a                    | ...
     103
     104vw3a:           cmp.w   #VT_1,_v_regs+VSDD_R11  | ...
     105                bcc     vw3a                    | ...
     106
     107vw4a:           cmp.w   #VT_2,_v_regs+VSDD_R11  | ...
     108                bcs     vw4a                    | ...
     109
     110dlyscrl:        tst.w   _vi_tag                 | wait for previous scroll
     111                bne     dlyscrl                 | ...
     112
     113                move.w  _vi_sadr,lclsadr        | save address for timeint
     114                move.w  _vi_scrl,lclscrl        | save offset for timeint
     115                clr.w   _vi_sadr                | reset for next time
     116                clr.w   _vi_scrl                | ...
     117                move.w  vdelay,_vi_clk          | set the scroll delay timer
     118                st      _vi_tag                 | set the 'need service' tag
     119| ------------------------------------------------------------------------------
     120| check for unblank requests
     121| ------------------------------------------------------------------------------
     122                move.w  _vi_ctl,d2              | get the unblank control word
     123                beq     viexit                  | exit if nothing to unblank
     124
     125                bra     unblnk                  | go unblank some objects
     126
     127viunbl:         move.w  _vi_ctl,d2              | get the unblank control word
     128                beq     vidone                  | exit if nothing to unblank
     129
     130                move.w  _v_regs+VSDD_R5,d0      | get VSDD R5
     131                move.w  d0,d1                   | save it for later
     132                andi.w  #0x0180,d0              | see if we're already in bank 0
     133                beq     unblnk                  | jump if so
     134
     135                clr.w   _v_regs+VSDD_R5         | set bank 0
     136
     137                move.w  _v_regs+VSDD_R11,VIct3  | save the VSDD R11 value
     138
     139vw1b:           cmp.w   #VT_1,_v_regs+VSDD_R11  | wait for FRAMESTOP
     140                bcc     vw1b                    | ...
     141
     142vw2b:           cmp.w   #VT_1,_v_regs+VSDD_R11  | ...
     143                bcs     vw2b                    | ...
     144
     145vw3b:           cmp.w   #VT_1,_v_regs+VSDD_R11  | ...
     146                bcc     vw3b                    | ...
     147
     148vw4b:           cmp.w   #VT_2,_v_regs+VSDD_R11  | ...
     149                bcs     vw4b                    | ...
     150
     151                .page
     152
     153| ------------------------------------------------------------------------------
     154| unblank objects indicated by contents of d2  (loaded earlier from _vi_ctl)
     155| ------------------------------------------------------------------------------
     156
     157unblnk:         clr.w   d3                      | clear the counter
     158                clr.w   _vi_ctl                 | clear the unblank control word
     159                lea     _v_odtab,a1             | point at first object
     160
     161vicheck:        btst    d3,d2                   | check the object bit
     162                beq     vinext                  | go check next one if not set
     163
     164                move.w  (a1),d0                 | get v_odtab[obj][0]
     165                bclr    #V_BLA,d0               | clear the blanking bit
     166                move.w  d0,(a1)                 | set v_odtab[obj][0]
     167
     168vinext:         cmpi.w  #15,d3                  | see if we're done
     169                beq     viexit                  | jump if so
     170
     171                addq.l  #8,a1                   | point at next object
     172                addq.w  #1,d3                   | increment object counter
     173                bra     vicheck                 | go check next object
     174
     175| ------------------------------------------------------------------------------
     176| switch back to the bank the interrupted code was using if we changed it
     177| ------------------------------------------------------------------------------
     178
     179viexit:         move.w  d1,d0                   | see if we were in bank 0
     180                andi.w  #0x0180,d0              | ...
     181                beq     vidone                  | jump if so
     182
     183viwait:         tst.w   _vi_tag                 | wait for timer to run out
     184                bne     viwait                  | ... so timeint sees bank 0
     185
     186                move.w  d1,_v_regs+VSDD_R5      | restore v_regs[5] to old bank
     187
     188                move.w  _v_regs+VSDD_R11,VIct4  | save the VSDD R11 value
     189
     190vw1c:           cmp.w   #VT_1,_v_regs+VSDD_R11  | wait for FRAMESTOP
     191                bcc     vw1c                    | ...
     192
     193vw2c:           cmp.w   #VT_1,_v_regs+VSDD_R11  | ...
     194                bcs     vw2c                    | ...
     195
     196vw3c:           cmp.w   #VT_1,_v_regs+VSDD_R11  | ...
     197                bcc     vw3c                    | ...
     198
     199vw4c:           cmp.w   #VT_2,_v_regs+VSDD_R11  | ...
     200                bcs     vw4c                    | ...
     201
     202| ------------------------------------------------------------------------------
     203| restore registers and return to interrupted code
     204| ------------------------------------------------------------------------------
     205
     206vidone:         movem.l (a7)+,d0-d3/a0-a2/a6    | restore registers
     207                rte                             | return from interrupt
     208
     209                .page
     210
     211| ------------------------------------------------------------------------------
    212212                .data
    213 * ------------------------------------------------------------------------------
    214 *
    215 vdelay:         .dc.w   DELAY                   * VSDD scroll delay
    216 *
    217 * ------------------------------------------------------------------------------
     213| ------------------------------------------------------------------------------
     214
     215vdelay:         .dc.w   DELAY                   | VSDD scroll delay
     216
     217| ------------------------------------------------------------------------------
    218218                .bss
    219 * ------------------------------------------------------------------------------
    220 *
    221 _vi_sadr:       .ds.w   1                       * score object base address
    222 _vi_scrl:       .ds.w   1                       * score object scroll offset
    223 *
    224 lclsadr:        .ds.w   1                       * local copy of vi_sadr
    225 lclscrl:        .ds.w   1                       * local copy of vi_scrl
    226 *
    227 VIct1:          .ds.w   1                       * VSDD R11 value at interrupt
    228 VIct2:          .ds.w   1                       * VSDD R11 value at interrupt
    229 VIct3:          .ds.w   1                       * VSDD R11 value at interrupt
    230 VIct4:          .ds.w   1                       * VSDD R11 value at interrupt
    231 *
     219| ------------------------------------------------------------------------------
     220
     221_vi_sadr:       .ds.w   1                       | score object base address
     222_vi_scrl:       .ds.w   1                       | score object scroll offset
     223
     224lclsadr:        .ds.w   1                       | local copy of vi_sadr
     225lclscrl:        .ds.w   1                       | local copy of vi_scrl
     226
     227VIct1:          .ds.w   1                       | VSDD R11 value at interrupt
     228VIct2:          .ds.w   1                       | VSDD R11 value at interrupt
     229VIct3:          .ds.w   1                       | VSDD R11 value at interrupt
     230VIct4:          .ds.w   1                       | VSDD R11 value at interrupt
     231
    232232                .end
  • vlib/vputa.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vputa.s -- store character attributes in video RAM
    3 * Version 1 -- 1988-03-14 -- D.N. Lynx Crowe
    4 * (c) Copyright 1988 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *
    7 *       vputa(sbase, row, col, attrib)
    8 *       unsigned int *sbase, row, col, attrib;
    9 *
    10 *               Stores attribute value 'attrib' for the character
    11 *               located at ('row','col') in VSDD RAM starting at 'sbase'.
    12 *               Assumes a 64 character line and full character attributes.
    13 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| vputa.s -- store character attributes in video RAM
     3| Version 1 -- 1988-03-14 -- D.N. Lynx Crowe
     4| (c) Copyright 1988 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6
     7|       vputa(sbase, row, col, attrib)
     8|       unsigned int |sbase, row, col, attrib;
     9
     10|               Stores attribute value 'attrib' for the character
     11|               located at ('row','col') in VSDD RAM starting at 'sbase'.
     12|               Assumes a 64 character line and full character attributes.
     13| ------------------------------------------------------------------------------
    1414                .text
    15 *
     15
    1616                .xdef   _vputa
    17 *
    18 SBASE           .equ    8               * LONG - 'sbase'
    19 ROW             .equ    12              * WORD - 'row'
    20 COL             .equ    14              * WORD - 'col'
    21 ATTR            .equ    16              * WORD - 'attrib'
    22 *
    23 _vputa:         link    a6,#0           * Link stack frame pointer
    24                 clr.l   d0              * Clear out d0
    25                 move.w  ROW(a6),d0      * Get row
    26                 lsl.l   #6,d0           * Multiply by 64  (shift left 6)
    27                 move.w  COL(a6),d1      * Get col
    28                 andi.l  #$0000003F,d1   * Mask down to 6 bits
    29                 or.l    d1,d0           * OR into d0 to get char. #
    30                 move.w  d0,d1           * Develop cw = (cn/2)*6 in d1
    31                 andi.l  #$FFFFFFFE,d1   * ...
    32                 move.l  d1,d2           * ...
    33                 add.l   d1,d1           * ...
    34                 add.l   d2,d1           * ...
    35                 add.l   SBASE(a6),d1    * Add sbase to cw
    36                 movea.l d1,a0           * a0 points at the word with the char.
    37                 btst.l  #0,d0           * Odd char. location ?
    38                 bne     vputa1          * Jump if so
    39 *
    40                 move.w  ATTR(a6),2(a0)  * Store new attribute word in video RAM
    41 *
    42 vputax:         unlk    a6              * Unlink the stack frame
    43                 rts                     * Done -- return to caller
    44 *
    45 vputa1:         move.w  ATTR(a6),4(a0)  * Store new attribute word in video RAM
    46                 bra     vputax          * Done -- go return to caller
    47 *
     17
     18SBASE           =       8               | LONG - 'sbase'
     19ROW             =       12              | WORD - 'row'
     20COL             =       14              | WORD - 'col'
     21ATTR            =       16              | WORD - 'attrib'
     22
     23_vputa:         link    a6,#0           | Link stack frame pointer
     24                clr.l   d0              | Clear out d0
     25                move.w  ROW(a6),d0      | Get row
     26                lsl.l   #6,d0           | Multiply by 64  (shift left 6)
     27                move.w  COL(a6),d1      | Get col
     28                andi.l  #0x0000003F,d1  | Mask down to 6 bits
     29                or.l    d1,d0           | OR into d0 to get char. #
     30                move.w  d0,d1           | Develop cw = (cn/2)|6 in d1
     31                andi.l  #0xFFFFFFFE,d1  | ...
     32                move.l  d1,d2           | ...
     33                add.l   d1,d1           | ...
     34                add.l   d2,d1           | ...
     35                add.l   SBASE(a6),d1    | Add sbase to cw
     36                movea.l d1,a0           | a0 points at the word with the char.
     37                btst.l  #0,d0           | Odd char. location ?
     38                bne     vputa1          | Jump if so
     39
     40                move.w  ATTR(a6),2(a0)  | Store new attribute word in video RAM
     41
     42vputax:         unlk    a6              | Unlink the stack frame
     43                rts                     | Done -- return to caller
     44
     45vputa1:         move.w  ATTR(a6),4(a0)  | Store new attribute word in video RAM
     46                bra     vputax          | Done -- go return to caller
     47
    4848                .end
  • vlib/vputc.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vputc.s -- store a character and attributes in video RAM
    3 * Version 3 -- 1987-03-30 -- D.N. Lynx Crowe
    4 * (c) Copyright 1987 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *
    7 *       vputc(sbase, row, col, c, attrib)
    8 *       unsigned int *sbase, row, col, c, attrib;
    9 *
    10 *               Stores character c at (row,col) in sbase with
    11 *               attribute value attrib.
    12 * ------------------------------------------------------------------------------
    13 *
     1| ------------------------------------------------------------------------------
     2| vputc.s -- store a character and attributes in video RAM
     3| Version 3 -- 1987-03-30 -- D.N. Lynx Crowe
     4| (c) Copyright 1987 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6
     7|       vputc(sbase, row, col, c, attrib)
     8|       unsigned int |sbase, row, col, c, attrib;
     9
     10|               Stores character c at (row,col) in sbase with
     11|               attribute value attrib.
     12| ------------------------------------------------------------------------------
     13
    1414                .text
    15 *
     15
    1616                .xdef   _vputc
    17 *
    18 _vputc:         link    a6,#0           * Link stack frame pointer
    19                 clr.l   d0              * Clear out d0
    20                 move.w  12(a6),d0       * Get row
    21                 lsl.l   #6,d0           * Multiply by 64  (shift left 6)
    22                 move.w  14(a6),d1       * Get col
    23                 andi.l  #$0000003F,d1   * Mask down to 6 bits
    24                 or.l    d1,d0           * OR into d0 to get char. #
    25                 move.w  d0,d1           * Develop cw = (cn/2)*6 in d1
    26                 andi.l  #$FFFFFFFE,d1   * ...
    27                 move.l  d1,d2           * ...
    28                 lsl.l   #1,d1           * ...
    29                 add.l   d2,d1           * ...
    30                 add.l   8(a6),d1        * Add sbase to cw
    31                 movea.l d1,a0           * a0 points at the word with the char.
    32                 btst.l  #0,d0           * Odd char. location ?
    33                 bne     vputc1          * Jump if so
    34 *
    35                 move.w  16(a6),d0       * Get ch
    36                 andi.w  #$00FF,d0       * Mask off garbage bits
    37                 move.w  (a0),d1         * Get word from video RAM
    38                 andi.w  #$FF00,d1       * Mask off old even character
    39                 or.w    d0,d1           * OR in the new character
    40                 move.w  d1,(a0)+        * Store the updated word in video RAM
    41                 move.w  18(a6),(a0)     * Store new attribute word in video RAM
    42 *
    43 vputcx:         unlk    a6              * Unlink the stack frame
    44                 rts                     * Return to caller
    45 *
    46 vputc1:         move.w  16(a6),d0       * Get ch
    47                 lsl.w   #8,d0           * Shift to high (odd) byte
    48                 move.w  (a0),d1         * Get word from video RAM
    49                 andi.w  #$00FF,d1       * Mask off old odd character
    50                 or.w    d0,d1           * OR in the new character
    51                 move.w  d1,(a0)+        * Store the updated word in video RAM
    52                 addq.l  #2,a0           * Point at the attribute word
    53                 move.w  18(a6),(a0)     * Store new attributes in video RAM
    54                 bra     vputcx          * Done -- go return to caller
    55 *
     17
     18_vputc:         link    a6,#0           | Link stack frame pointer
     19                clr.l   d0              | Clear out d0
     20                move.w  12(a6),d0       | Get row
     21                lsl.l   #6,d0           | Multiply by 64  (shift left 6)
     22                move.w  14(a6),d1       | Get col
     23                andi.l  #0x0000003F,d1  | Mask down to 6 bits
     24                or.l    d1,d0           | OR into d0 to get char. #
     25                move.w  d0,d1           | Develop cw = (cn/2)|6 in d1
     26                andi.l  #0xFFFFFFFE,d1  | ...
     27                move.l  d1,d2           | ...
     28                lsl.l   #1,d1           | ...
     29                add.l   d2,d1           | ...
     30                add.l   8(a6),d1        | Add sbase to cw
     31                movea.l d1,a0           | a0 points at the word with the char.
     32                btst.l  #0,d0           | Odd char. location ?
     33                bne     vputc1          | Jump if so
     34
     35                move.w  16(a6),d0       | Get ch
     36                andi.w  #0x00FF,d0      | Mask off garbage bits
     37                move.w  (a0),d1         | Get word from video RAM
     38                andi.w  #0xFF00,d1      | Mask off old even character
     39                or.w    d0,d1           | OR in the new character
     40                move.w  d1,(a0)+        | Store the updated word in video RAM
     41                move.w  18(a6),(a0)     | Store new attribute word in video RAM
     42
     43vputcx:         unlk    a6              | Unlink the stack frame
     44                rts                     | Return to caller
     45
     46vputc1:         move.w  16(a6),d0       | Get ch
     47                lsl.w   #8,d0           | Shift to high (odd) byte
     48                move.w  (a0),d1         | Get word from video RAM
     49                andi.w  #0x00FF,d1      | Mask off old odd character
     50                or.w    d0,d1           | OR in the new character
     51                move.w  d1,(a0)+        | Store the updated word in video RAM
     52                addq.l  #2,a0           | Point at the attribute word
     53                move.w  18(a6),(a0)     | Store new attributes in video RAM
     54                bra     vputcx          | Done -- go return to caller
     55
    5656                .end
  • vlib/vputcv.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vputcv.s -- store a character and attributes in video RAM
    3 * Version 1 -- 1988-10-05 -- D.N. Lynx Crowe
    4 * (c) Copyright 1988 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *
    7 *       vputcv(adr, row, col, chr, atr, cols)
    8 *       unsigned int *adr, row, col, chr, atr, cols;
    9 *
    10 *               Stores character 'chr' at ('row', 'col') in the
    11 *               full attribute text object at 'adr' with
    12 *               attribute value 'atr' using a line length of 'len'.
    13 * ------------------------------------------------------------------------------
    14 *
     1| ------------------------------------------------------------------------------
     2| vputcv.s -- store a character and attributes in video RAM
     3| Version 1 -- 1988-10-05 -- D.N. Lynx Crowe
     4| (c) Copyright 1988 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6
     7|       vputcv(adr, row, col, chr, atr, cols)
     8|       unsigned int |adr, row, col, chr, atr, cols;
     9
     10|               Stores character 'chr' at ('row', 'col') in the
     11|               full attribute text object at 'adr' with
     12|               attribute value 'atr' using a line length of 'len'.
     13| ------------------------------------------------------------------------------
     14
    1515                .text
    16 *
     16
    1717                .xdef   _vputcv
    18 *
    19 P_ADR           .equ    8
    20 P_ROW           .equ    12
    21 P_COL           .equ    14
    22 P_CHR           .equ    16
    23 P_ATR           .equ    18
    24 P_LEN           .equ    20
    25 *
     18
     19P_ADR           =       8
     20P_ROW           =       12
     21P_COL           =       14
     22P_CHR           =       16
     23P_ATR           =       18
     24P_LEN           =       20
     25
    2626                .page
    27 *
    28 _vputcv:        link    a6,#0           * Link stack frame pointer
    29                 move.w  P_ROW(a6),d0    * Get row
    30                 mulu    P_LEN(a6),d0    * Multiply by len
    31                 clr.l   d1              * Clear out d1
    32                 move.w  P_COL(a6),d1    * Get col
    33                 add.l   d1,d0           * Add col into d0 to get char. #
    34                 move.l  d0,d1           * Develop cw = (cn/2)*6 in d1
    35                 andi.l  #$FFFFFFFE,d1   * ...
    36                 move.l  d1,d2           * ...
    37                 add.l   d1,d1           * ...
    38                 add.l   d2,d1           * ...
    39                 add.l   P_ADR(a6),d1    * Add sbase to cw
    40                 movea.l d1,a0           * a0 points at the word with the char.
    41                 btst.l  #0,d0           * Odd char. location ?
    42                 bne     vputcv1         * Jump if so
    43 *
    44                 move.w  P_CHR(a6),d0    * Get chr
    45                 andi.w  #$00FF,d0       * Mask off garbage bits
    46                 move.w  (a0),d1         * Get word from video RAM
    47                 andi.w  #$FF00,d1       * Mask off old even character
    48                 or.w    d0,d1           * OR in the new character
    49                 move.w  d1,(a0)+        * Store the updated word in video RAM
    50                 bra     vputcvx         * Done -- go return to caller
    51 *
    52 vputcv1:        move.w  P_CHR(a6),d0    * Get chr
    53                 lsl.w   #8,d0           * Shift to high (odd) byte
    54                 move.w  (a0),d1         * Get word from video RAM
    55                 andi.w  #$00FF,d1       * Mask off old odd character
    56                 or.w    d0,d1           * OR in the new character
    57                 move.w  d1,(a0)+        * Store the updated word in video RAM
    58                 addq.l  #2,a0           * Point at the attribute word
    59 *
    60 vputcvx:        move.w  P_ATR(a6),(a0)  * Store new attributes in video RAM
    61                 unlk    a6              * Unlink the stack frame
    62                 rts                     * Return to caller
    63 *
     27
     28_vputcv:        link    a6,#0           | Link stack frame pointer
     29                move.w  P_ROW(a6),d0    | Get row
     30                mulu    P_LEN(a6),d0    | Multiply by len
     31                clr.l   d1              | Clear out d1
     32                move.w  P_COL(a6),d1    | Get col
     33                add.l   d1,d0           | Add col into d0 to get char. #
     34                move.l  d0,d1           | Develop cw = (cn/2)|6 in d1
     35                andi.l  #0xFFFFFFFE,d1  | ...
     36                move.l  d1,d2           | ...
     37                add.l   d1,d1           | ...
     38                add.l   d2,d1           | ...
     39                add.l   P_ADR(a6),d1    | Add sbase to cw
     40                movea.l d1,a0           | a0 points at the word with the char.
     41                btst.l  #0,d0           | Odd char. location ?
     42                bne     vputcv1         | Jump if so
     43
     44                move.w  P_CHR(a6),d0    | Get chr
     45                andi.w  #0x00FF,d0      | Mask off garbage bits
     46                move.w  (a0),d1         | Get word from video RAM
     47                andi.w  #0xFF00,d1      | Mask off old even character
     48                or.w    d0,d1           | OR in the new character
     49                move.w  d1,(a0)+        | Store the updated word in video RAM
     50                bra     vputcvx         | Done -- go return to caller
     51
     52vputcv1:        move.w  P_CHR(a6),d0    | Get chr
     53                lsl.w   #8,d0           | Shift to high (odd) byte
     54                move.w  (a0),d1         | Get word from video RAM
     55                andi.w  #0x00FF,d1      | Mask off old odd character
     56                or.w    d0,d1           | OR in the new character
     57                move.w  d1,(a0)+        | Store the updated word in video RAM
     58                addq.l  #2,a0           | Point at the attribute word
     59
     60vputcvx:        move.w  P_ATR(a6),(a0)  | Store new attributes in video RAM
     61                unlk    a6              | Unlink the stack frame
     62                rts                     | Return to caller
     63
    6464                .end
  • vlib/vputp.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vputp.s -- put a pixel into a 4-bit per pixel bitmap object
    3 * Version 4 -- 1987-08-04 -- D.N. Lynx Crowe
    4 * (c) Copyright 1987 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *       int
    7 *       vputp(octad, xloc, yloc, val)
    8 *       struct octent *octad;
    9 *       int xloc, yloc;
    10 *
    11 *               Puts the pixel value 'val' at ('xloc','yloc') in the
    12 *               4-bit per pixel bitmap object described by 'octad'.
    13 *
    14 *       -----
    15 *       struct octent {
    16 *
    17 *               uint    ysize,
    18 *                       xsize;
    19 *
    20 *               int     objx,
    21 *                       objy;
    22 *
    23 *               uint    *obase;
    24 *
    25 *               char    opri,
    26 *                       obank;
    27 *
    28 *               uint    odtw0,
    29 *                       odtw1;
    30 *       };
    31 *
     1| ------------------------------------------------------------------------------
     2| vputp.s -- put a pixel into a 4-bit per pixel bitmap object
     3| Version 4 -- 1987-08-04 -- D.N. Lynx Crowe
     4| (c) Copyright 1987 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6|       int
     7|       vputp(octad, xloc, yloc, val)
     8|       struct octent |octad;
     9|       int xloc, yloc;
     10
     11|               Puts the pixel value 'val' at ('xloc','yloc') in the
     12|               4-bit per pixel bitmap object described by 'octad'.
     13
     14|       -----
     15|       struct octent {
     16
     17|               uint    ysize,
     18|                       xsize;
     19
     20|               int     objx,
     21|                       objy;
     22
     23|               uint    |obase;
     24
     25|               char    opri,
     26|                       obank;
     27
     28|               uint    odtw0,
     29|                       odtw1;
     30|       };
     31
    3232                .text
    33 *
     33
    3434                .xdef   _vputp
    35 *
    36 OCTAD           .equ    8
    37 XLOC            .equ    12
    38 YLOC            .equ    14
    39 VAL             .equ    16
    40 *
    41 YSIZE           .equ    0
    42 XSIZE           .equ    2
    43 OBJX            .equ    4
    44 OBJY            .equ    6
    45 OBASE           .equ    8
    46 OPRI            .equ    12
    47 OBANK           .equ    13
    48 ODTW0           .equ    14
    49 ODTW1           .equ    16
    50 *
     35
     36OCTAD           =       8
     37XLOC            =       12
     38YLOC            =       14
     39VAL             =       16
     40
     41YSIZE           =       0
     42XSIZE           =       2
     43OBJX            =       4
     44OBJY            =       6
     45OBASE           =       8
     46OPRI            =       12
     47OBANK           =       13
     48ODTW0           =       14
     49ODTW1           =       16
     50
    5151                .page
    52 *
    53 _vputp:         link    a6,#0                   * Link stack frames
    54                 movea.l OCTAD(a6),a1            * Get OCTAD base into a1
    55                 move.w  XLOC(a6),d0             * Get XLOC into d0
    56                 cmp.w   XSIZE(a1),d0            * Check XLOC range
    57                 bge     vputerr                 * ERROR if too large
    58 *
    59                 tst.w   d0                      * Check XLOC sign
    60                 bmi     vputerr                 * ERROR if negative
    61 *
    62                 move.w  YLOC(a6),d1             * Get YLOC into d1 to test
    63                 cmp.w   YSIZE(a1),d1            * Check YLOC range
    64                 bge     vputerr                 * ERROR if too large
    65 *
    66                 tst.w   d1                      * Check YLOC sign
    67                 bmi     vputerr                 * ERROR if negative
    68 *
    69                 lsr.w   #2,d0                   * Divide XLOC by 4
    70                 move.w  XSIZE(a1),d1            * Get width into d1
    71                 lsr.w   #2,d1                   * Divide width by 4
    72                 mulu    YLOC(a6),d1             * Multiply width/4 by YLOC
    73                 ext.l   d0                      * Extend XLOC/4 to a long
    74                 add.l   d0,d1                   * ... and add it to d1
    75                 lsl.l   #1,d1                   * Make d1 a word offset
    76                 add.l   OBASE(a1),d1            * Add OBASE to d1
    77                 movea.l d1,a0                   * Make a0 point at bitmap data
    78                 move.w  XLOC(a6),d0             * Get XLOC
    79                 andi.l  #$03,d0                 * Mask to low 2 bits
    80                 add.l   d0,d0                   * Multiply by 2 for word index
    81                 move.l  d0,d1                   * Save index in d1
    82                 add.l   #MTAB,d0                * Add mask table base
    83                 movea.l d0,a2                   * a2 points at mask
    84                 add.l   #STAB,d1                * Add shift table base to index
    85                 move.l  d1,a1                   * a1 points at shift count
    86                 move.w  (a1),d0                 * Get shift count in d0
    87                 move.w  VAL(a6),d1              * Get new pixel in d1
    88                 andi.w  #$0F,d1                 * Mask down to 4 bits
    89                 lsl.w   d0,d1                   * Shift into position for OR
    90                 move.w  (a0),d0                 * Get old bitmap word in d0
    91                 and.w   (a2),d0                 * Mask out old pixel
    92                 or.w    d1,d0                   * OR in new pixel
    93                 move.w  d0,(a0)                 * Store updated word in bitmap
    94                 clr.l   d0                      * Set return value = 0 = OK
    95 *
    96 vputexit:       unlk    a6                      * Unlink stack frame
    97                 rts                             * Return to caller
    98 *
    99 vputerr:        moveq.l #-1,d0                  * Set return value = -1 = ERROR
    100                 bra     vputexit                * Go unlink stack and return
    101 *
     52
     53_vputp:         link    a6,#0                   | Link stack frames
     54                movea.l OCTAD(a6),a1            | Get OCTAD base into a1
     55                move.w  XLOC(a6),d0             | Get XLOC into d0
     56                cmp.w   XSIZE(a1),d0            | Check XLOC range
     57                bge     vputerr                 | ERROR if too large
     58
     59                tst.w   d0                      | Check XLOC sign
     60                bmi     vputerr                 | ERROR if negative
     61
     62                move.w  YLOC(a6),d1             | Get YLOC into d1 to test
     63                cmp.w   YSIZE(a1),d1            | Check YLOC range
     64                bge     vputerr                 | ERROR if too large
     65
     66                tst.w   d1                      | Check YLOC sign
     67                bmi     vputerr                 | ERROR if negative
     68
     69                lsr.w   #2,d0                   | Divide XLOC by 4
     70                move.w  XSIZE(a1),d1            | Get width into d1
     71                lsr.w   #2,d1                   | Divide width by 4
     72                mulu    YLOC(a6),d1             | Multiply width/4 by YLOC
     73                ext.l   d0                      | Extend XLOC/4 to a long
     74                add.l   d0,d1                   | ... and add it to d1
     75                lsl.l   #1,d1                   | Make d1 a word offset
     76                add.l   OBASE(a1),d1            | Add OBASE to d1
     77                movea.l d1,a0                   | Make a0 point at bitmap data
     78                move.w  XLOC(a6),d0             | Get XLOC
     79                andi.l  #0x03,d0                | Mask to low 2 bits
     80                add.l   d0,d0                   | Multiply by 2 for word index
     81                move.l  d0,d1                   | Save index in d1
     82                add.l   #MTAB,d0                | Add mask table base
     83                movea.l d0,a2                   | a2 points at mask
     84                add.l   #STAB,d1                | Add shift table base to index
     85                move.l  d1,a1                   | a1 points at shift count
     86                move.w  (a1),d0                 | Get shift count in d0
     87                move.w  VAL(a6),d1              | Get new pixel in d1
     88                andi.w  #0x0F,d1                | Mask down to 4 bits
     89                lsl.w   d0,d1                   | Shift into position for OR
     90                move.w  (a0),d0                 | Get old bitmap word in d0
     91                and.w   (a2),d0                 | Mask out old pixel
     92                or.w    d1,d0                   | OR in new pixel
     93                move.w  d0,(a0)                 | Store updated word in bitmap
     94                clr.l   d0                      | Set return value = 0 = OK
     95
     96vputexit:       unlk    a6                      | Unlink stack frame
     97                rts                             | Return to caller
     98
     99vputerr:        moveq.l #-1,d0                  | Set return value = -1 = ERROR
     100                bra     vputexit                | Go unlink stack and return
     101
    102102                .page
    103 *
     103
    104104                .data
    105 *
    106 MTAB:           dc.w    $FFF0,$FF0F,$F0FF,$0FFF * Mask table
    107 STAB:           dc.w    0,4,8,12                * Shift table
    108 *
     105
     106MTAB:           dc.w    0xFFF0,0xFF0F,0xF0FF,0x0FFF     | Mask table
     107STAB:           dc.w    0,4,8,12                | Shift table
     108
    109109                .end
  • vlib/vsetav.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vsetav.s -- set a character's attributes in video RAM
    3 * Version 1 -- 1988-10-11 -- D.N. Lynx Crowe
    4 * (c) Copyright 1988 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *
    7 *       vsetav(adr, row, col, atr, len)
    8 *       unsigned int *adr, row, col, atr, len;
    9 *
    10 *               Sets attribute 'atr' at ('row', 'col') in the
    11 *               full attribute text object at 'adr'
    12 *               using a line length of 'len'.
    13 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| vsetav.s -- set a character's attributes in video RAM
     3| Version 1 -- 1988-10-11 -- D.N. Lynx Crowe
     4| (c) Copyright 1988 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6
     7|       vsetav(adr, row, col, atr, len)
     8|       unsigned int |adr, row, col, atr, len;
     9
     10|               Sets attribute 'atr' at ('row', 'col') in the
     11|               full attribute text object at 'adr'
     12|               using a line length of 'len'.
     13| ------------------------------------------------------------------------------
    1414                .text
    15 *
     15
    1616                .xdef   _vsetav
    17 *
    18 P_ADR           .equ    8
    19 P_ROW           .equ    12
    20 P_COL           .equ    14
    21 P_ATR           .equ    16
    22 P_LEN           .equ    18
    23 *
    24 _vsetav:        link    a6,#0           * Link stack frame pointer
    25                 move.w  P_ROW(a6),d0    * Get row
    26                 mulu    P_LEN(a6),d0    * Multiply by len
    27                 clr.l   d1              * Clear out d1
    28                 move.w  P_COL(a6),d1    * Get col
    29                 add.l   d1,d0           * Add col into d0 to get char. #
    30                 move.l  d0,d1           * Develop cw = (cn/2)*6 in d1
    31                 andi.l  #$FFFFFFFE,d1   * ...
    32                 move.l  d1,d2           * ...
    33                 add.l   d1,d1           * ...
    34                 add.l   d2,d1           * ...
    35                 add.l   P_ADR(a6),d1    * Add sbase to cw
    36                 movea.l d1,a0           * a0 points at the word with the char.
    37                 btst.l  #0,d0           * Odd char. location ?
    38                 bne     vsetav1         * Jump if so
    39 *
    40                 addq.l  #2,a0           * Point at the attribute word
    41                 bra     vsetavx         * Go set attribute
    42 *
    43 vsetav1:        addq.l  #4,a0           * Point at the attribute word
    44 *
    45 vsetavx:        move.w  P_ATR(a6),d0    * Get new attributes
    46                 or.w    d0,(a0)         * Set new attributes in video RAM
    47                 unlk    a6              * Unlink the stack frame
    48                 rts                     * Return to caller
    49 *
     17
     18P_ADR           =       8
     19P_ROW           =       12
     20P_COL           =       14
     21P_ATR           =       16
     22P_LEN           =       18
     23
     24_vsetav:        link    a6,#0           | Link stack frame pointer
     25                move.w  P_ROW(a6),d0    | Get row
     26                mulu    P_LEN(a6),d0    | Multiply by len
     27                clr.l   d1              | Clear out d1
     28                move.w  P_COL(a6),d1    | Get col
     29                add.l   d1,d0           | Add col into d0 to get char. #
     30                move.l  d0,d1           | Develop cw = (cn/2)|6 in d1
     31                andi.l  #0xFFFFFFFE,d1  | ...
     32                move.l  d1,d2           | ...
     33                add.l   d1,d1           | ...
     34                add.l   d2,d1           | ...
     35                add.l   P_ADR(a6),d1    | Add sbase to cw
     36                movea.l d1,a0           | a0 points at the word with the char.
     37                btst.l  #0,d0           | Odd char. location ?
     38                bne     vsetav1         | Jump if so
     39
     40                addq.l  #2,a0           | Point at the attribute word
     41                bra     vsetavx         | Go set attribute
     42
     43vsetav1:        addq.l  #4,a0           | Point at the attribute word
     44
     45vsetavx:        move.w  P_ATR(a6),d0    | Get new attributes
     46                or.w    d0,(a0)         | Set new attributes in video RAM
     47                unlk    a6              | Unlink the stack frame
     48                rts                     | Return to caller
     49
    5050                .end
  • vlib/vsetcv.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vsetcv.s -- set a character's colors in video RAM
    3 * Version 1 -- 1988-10-11 -- D.N. Lynx Crowe
    4 * (c) Copyright 1988 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *
    7 *       vsetcv(adr, row, col, cfb, len)
    8 *       unsigned int *adr, row, col, cfb, len;
    9 *
    10 *               Sets colors 'cfb' at ('row', 'col') in the
    11 *               full attribute text object at 'adr'
    12 *               using a line length of 'len'.
    13 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| vsetcv.s -- set a character's colors in video RAM
     3| Version 1 -- 1988-10-11 -- D.N. Lynx Crowe
     4| (c) Copyright 1988 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6
     7|       vsetcv(adr, row, col, cfb, len)
     8|       unsigned int |adr, row, col, cfb, len;
     9
     10|               Sets colors 'cfb' at ('row', 'col') in the
     11|               full attribute text object at 'adr'
     12|               using a line length of 'len'.
     13| ------------------------------------------------------------------------------
    1414                .text
    15 *
     15
    1616                .xdef   _vsetcv
    17 *
    18 P_ADR           .equ    8
    19 P_ROW           .equ    12
    20 P_COL           .equ    14
    21 P_CFB           .equ    16
    22 P_LEN           .equ    18
    23 *
    24 _vsetcv:        link    a6,#0           * Link stack frame pointer
    25                 move.w  P_ROW(a6),d0    * Get row
    26                 mulu    P_LEN(a6),d0    * Multiply by len
    27                 clr.l   d1              * Clear out d1
    28                 move.w  P_COL(a6),d1    * Get col
    29                 add.l   d1,d0           * Add col into d0 to get char. #
    30                 move.l  d0,d1           * Develop cw = (cn/2)*6 in d1
    31                 andi.l  #$FFFFFFFE,d1   * ...
    32                 move.l  d1,d2           * ...
    33                 add.l   d1,d1           * ...
    34                 add.l   d2,d1           * ...
    35                 add.l   P_ADR(a6),d1    * Add sbase to cw
    36                 movea.l d1,a0           * a0 points at the word with the char.
    37                 btst.l  #0,d0           * Odd char. location ?
    38                 bne     vsetcv1         * Jump if so
    39 *
    40                 addq.l  #2,a0           * Point at the attribute word
    41                 bra     vsetcvx         * Go set attribute
    42 *
    43 vsetcv1:        addq.l  #4,a0           * Point at the attribute word
    44 *
    45 vsetcvx:        move.w  (a0),d0         * Get old attributes
    46                 andi.w  #$FF00,d0       * Remove old colors
    47                 or.w    P_CFB(a6),d0    * Get new colors
    48                 move.w  d0,(a0)         * Set new attributes in video RAM
    49                 unlk    a6              * Unlink the stack frame
    50                 rts                     * Return to caller
    51 *
     17
     18P_ADR           =       8
     19P_ROW           =       12
     20P_COL           =       14
     21P_CFB           =       16
     22P_LEN           =       18
     23
     24_vsetcv:        link    a6,#0           | Link stack frame pointer
     25                move.w  P_ROW(a6),d0    | Get row
     26                mulu    P_LEN(a6),d0    | Multiply by len
     27                clr.l   d1              | Clear out d1
     28                move.w  P_COL(a6),d1    | Get col
     29                add.l   d1,d0           | Add col into d0 to get char. #
     30                move.l  d0,d1           | Develop cw = (cn/2)|6 in d1
     31                andi.l  #0xFFFFFFFE,d1  | ...
     32                move.l  d1,d2           | ...
     33                add.l   d1,d1           | ...
     34                add.l   d2,d1           | ...
     35                add.l   P_ADR(a6),d1    | Add sbase to cw
     36                movea.l d1,a0           | a0 points at the word with the char.
     37                btst.l  #0,d0           | Odd char. location ?
     38                bne     vsetcv1         | Jump if so
     39
     40                addq.l  #2,a0           | Point at the attribute word
     41                bra     vsetcvx         | Go set attribute
     42
     43vsetcv1:        addq.l  #4,a0           | Point at the attribute word
     44
     45vsetcvx:        move.w  (a0),d0         | Get old attributes
     46                andi.w  #0xFF00,d0      | Remove old colors
     47                or.w    P_CFB(a6),d0    | Get new colors
     48                move.w  d0,(a0)         | Set new attributes in video RAM
     49                unlk    a6              | Unlink the stack frame
     50                rts                     | Return to caller
     51
    5252                .end
  • vlib/vsplot4.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vsplot4.s -- output characters to a 4-bit / pixel graphics window
    3 *    with variable vertical pitch, etc.
    4 * Version 1 -- 1988-10-07 -- D.N. Lynx Crowe
    5 * (c) Copyright 1988 -- D.N. Lynx Crowe
    6 * ------------------------------------------------------------------------------
    7 *
    8 *       vsplot4(obase, nw, fg, row, col, str, pitch, ht, cgtab)
    9 *       uint *obase, nw, fg, row, col, pitch, ht, cgtab[][256];
    10 *       char *str;
    11 *
    12 *               Outputs characters from the string at 'str' to an 'nw'
    13 *               character wide 4-bit per pixel graphics window at 'obase'
    14 *               at ('row','col'), using 'fg' as the foreground color.
    15 *               Uses cgtab[][256] as the VSDD formatted character
    16 *               generator table.  Assumes 'ht' bit high characters in the
    17 *               cgtable.  Uses 'pitch' as the vertical spacing between
    18 *               character rows.  No error checks are done.
    19 *               The string must fit the output area (no overlaps, single line).
    20 *               This function leaves the zero pixels alone and just sets the
    21 *               one pixels to the foreground color, allowing overlapping
    22 *               character cells.
    23 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| vsplot4.s -- output characters to a 4-bit / pixel graphics window
     3|    with variable vertical pitch, etc.
     4| Version 1 -- 1988-10-07 -- D.N. Lynx Crowe
     5| (c) Copyright 1988 -- D.N. Lynx Crowe
     6| ------------------------------------------------------------------------------
     7
     8|       vsplot4(obase, nw, fg, row, col, str, pitch, ht, cgtab)
     9|       uint |obase, nw, fg, row, col, pitch, ht, cgtab[][256];
     10|       char |str;
     11
     12|               Outputs characters from the string at 'str' to an 'nw'
     13|               character wide 4-bit per pixel graphics window at 'obase'
     14|               at ('row','col'), using 'fg' as the foreground color.
     15|               Uses cgtab[][256] as the VSDD formatted character
     16|               generator table.  Assumes 'ht' bit high characters in the
     17|               cgtable.  Uses 'pitch' as the vertical spacing between
     18|               character rows.  No error checks are done.
     19|               The string must fit the output area (no overlaps, single line).
     20|               This function leaves the zero pixels alone and just sets the
     21|               one pixels to the foreground color, allowing overlapping
     22|               character cells.
     23| ------------------------------------------------------------------------------
    2424                .text
    25 *
     25
    2626                .xdef   _vsplot4
    27 *
    28 * Argument offsets from a6:
    29 *
    30 OBASE           .equ    8               * LONG - Output area base address
    31 NW              .equ    12              * WORD - Character width of output area
    32 FG              .equ    14              * WORD - Foreground color
    33 ROW             .equ    16              * WORD - Row
    34 COL             .equ    18              * WORD - Column
    35 STR             .equ    20              * LONG - String base address
    36 PITCH           .equ    24              * WORD - Vertical spacing between rows
    37 HT              .equ    26              * WORD - Character height
    38 CGTAB           .equ    28              * LONG - Character generator pionter
    39 *
    40 * Program constant definitions:
    41 *
    42 HPIX            .equ    8               * Character width in pixels
    43 HCW             .equ    4               * Horizontal character width (bytes)
    44 PSHIFT          .equ    12              * Pixel shift into MS bits
    45 HSHIFT          .equ    4               * Pixel right shift
    46 *
     27
     28| Argument offsets from a6:
     29
     30OBASE           =       8               | LONG - Output area base address
     31NW              =       12              | WORD - Character width of output area
     32FG              =       14              | WORD - Foreground color
     33ROW             =       16              | WORD - Row
     34COL             =       18              | WORD - Column
     35STR             =       20              | LONG - String base address
     36PITCH           =       24              | WORD - Vertical spacing between rows
     37HT              =       26              | WORD - Character height
     38CGTAB           =       28              | LONG - Character generator pionter
     39
     40| Program constant definitions:
     41
     42HPIX            =       8               | Character width in pixels
     43HCW             =       4               | Horizontal character width (bytes)
     44PSHIFT          =       12              | Pixel shift into MS bits
     45HSHIFT          =       4               | Pixel right shift
     46
    4747                .page
    48 *
    49 * Register usage:
    50 *
    51 *       d0      output word and scratch
    52 *       d1      CG word and scratch
    53 *       d2      pixel counter
    54 *
    55 *       d3      foreground color (in the 4 ms bits)
    56 *       d4      background color (in the 4 ms bits)
    57 *       d5      width of the area in bytes
    58 *       d6      scan line counter
    59 *
    60 *       a0      CG table pointer
    61 *       a1      output area scan line pointer
    62 *       a2      input string character pointer
    63 *
    64 *       a3      output area character base pointer
    65 *
    66 *       a6      frame pointer
    67 *       a7      stack pointer
    68 *
     48
     49| Register usage:
     50
     51|       d0      output word and scratch
     52|       d1      CG word and scratch
     53|       d2      pixel counter
     54
     55|       d3      foreground color (in the 4 ms bits)
     56|       d4      background color (in the 4 ms bits)
     57|       d5      width of the area in bytes
     58|       d6      scan line counter
     59
     60|       a0      CG table pointer
     61|       a1      output area scan line pointer
     62|       a2      input string character pointer
     63
     64|       a3      output area character base pointer
     65
     66|       a6      frame pointer
     67|       a7      stack pointer
     68
    6969                .page
    70 *
    71 _vsplot4:       link    a6,#0           * Link stack frames
    72                 movem.l d3-d6/a3,-(a7)  * Save registers we use
    73                 move.w  #PSHIFT,d1      * Set shift constant
    74                 move.w  FG(a6),d3       * Setup foreground color
    75                 lsl.w   d1,d3           * ... in ms 4 bits of d3.W
    76                 move.w  NW(a6),d5       * Get line width in d5.W
    77                 lsl.w   #2,d5           * Multiply width by 4 for offset
    78                 move.w  ROW(a6),d0      * Calculate output address
    79                 move.w  PITCH(a6),d1    * ... PITCH
    80                 mulu    d1,d0           * ... * ROW
    81                 add.w   HT(a6),d0       * ... + HT-1
    82                 subq.w  #1,d0           * ...
    83                 mulu    d5,d0           * ... * NW
    84                 clr.l   d1              * ...
    85                 move.w  COL(a6),d1      * ... +
    86                 lsl.w   #2,d1           * ... COL * 4
    87                 add.l   d1,d0           * ...
    88                 add.l   OBASE(a6),d0    * ... + OBASE
    89                 movea.l d0,a3           * Leave output address in a3
    90                 movea.l STR(a6),a2      * Put string address in a2
    91 *
    92 cgl0:           clr.l   d0              * Clear out upper bits of d0
    93                 move.b  (a2)+,d0        * Get next character
    94                 beq     cgl5            * Done if character EQ 0
    95 *
    96                 movea.l a3,a1           * Establish output pointer in a1
    97                 adda.l  #HCW,a3         * Update output pointer for next char.
    98                 movea.l CGTAB(a6),a0    * Establish CG pointer in a0
    99                 lsl.w   #1,d0           * ... 2 * character
    100                 adda.w  d0,a0           * ... + cgtab address
    101                 move.w  HT(a6),d6       * Set scan line counter in d6
    102                 subq.w  #1,d6           * ...
    103 *
     70
     71_vsplot4:       link    a6,#0           | Link stack frames
     72                movem.l d3-d6/a3,-(a7)  | Save registers we use
     73                move.w  #PSHIFT,d1      | Set shift constant
     74                move.w  FG(a6),d3       | Setup foreground color
     75                lsl.w   d1,d3           | ... in ms 4 bits of d3.W
     76                move.w  NW(a6),d5       | Get line width in d5.W
     77                lsl.w   #2,d5           | Multiply width by 4 for offset
     78                move.w  ROW(a6),d0      | Calculate output address
     79                move.w  PITCH(a6),d1    | ... PITCH
     80                mulu    d1,d0           | ... | ROW
     81                add.w   HT(a6),d0       | ... + HT-1
     82                subq.w  #1,d0           | ...
     83                mulu    d5,d0           | ... | NW
     84                clr.l   d1              | ...
     85                move.w  COL(a6),d1      | ... +
     86                lsl.w   #2,d1           | ... COL | 4
     87                add.l   d1,d0           | ...
     88                add.l   OBASE(a6),d0    | ... + OBASE
     89                movea.l d0,a3           | Leave output address in a3
     90                movea.l STR(a6),a2      | Put string address in a2
     91
     92cgl0:           clr.l   d0              | Clear out upper bits of d0
     93                move.b  (a2)+,d0        | Get next character
     94                beq     cgl5            | Done if character EQ 0
     95
     96                movea.l a3,a1           | Establish output pointer in a1
     97                adda.l  #HCW,a3         | Update output pointer for next char.
     98                movea.l CGTAB(a6),a0    | Establish CG pointer in a0
     99                lsl.w   #1,d0           | ... 2 | character
     100                adda.w  d0,a0           | ... + cgtab address
     101                move.w  HT(a6),d6       | Set scan line counter in d6
     102                subq.w  #1,d6           | ...
     103
    104104                .page
    105 cgl1:           move.w  (a0),d1         * Get character generator word in d1
    106                 move.w  #(HPIX/2)-1,d2  * Set pixel counter in d2
    107                 clr.l   d4              * Get old output word as background
    108                 move.w  (a1),d4         * ...
    109                 swap    d4              * ...
    110 *
    111 cgl2:           lsr.w   #HSHIFT,d0      * Shift output word right 1 pixel
    112                 lsr.l   #HSHIFT,d4      * Shift background word 1 pixel
    113                 andi.l  #$FFFFF000,d4   * Mask for upper 4 bits of d4.W
    114                 btst.l  #0,d1           * Check CG word ls bit
    115                 beq     cgl3            * Set background color if bit EQ 0
    116 *
    117                 or.w    d3,d0           * OR foreground color into output word
    118                 bra     cgl4            * Go update CG word
    119 *
    120 cgl3:           or.w    d4,d0           * OR background color into output word
    121 *
    122 cgl4:           lsr.w   #1,d1           * Shift CG word right 1 pixel
    123                 dbf     d2,cgl2         * Loop for first 4 pixels
    124 *
    125                 move.w  d0,(a1)+        * Store first output word in scan line
    126                 move.w  #(HPIX/2)-1,d2  * Set pixel counter in d2
    127                 clr.l   d4              * Get old output word as background
    128                 move.w  (a1),d4         * ...
    129                 swap    d4              * ...
    130 *
    131 cgl2a:          lsr.w   #HSHIFT,d0      * Shift output word right 1 pixel
    132                 lsr.l   #HSHIFT,d4      * Shift background word 1 pixel
    133                 andi.l  #$FFFFF000,d4   * Mask for upper bits of d4.W
    134                 btst.l  #0,d1           * Check CG word ls bit
    135                 beq     cgl3a           * Set background color if bit EQ 0
    136 *
    137                 or.w    d3,d0           * OR foreground color into output word
    138                 bra     cgl4a           * Go update CG word
    139 *
    140 cgl3a:          or.w    d4,d0           * OR background color into output word
    141 *
    142 cgl4a:          lsr.w   #1,d1           * Shift CG word right 1 pixel
    143                 dbf     d2,cgl2a        * Loop for last 4 pixels
    144 *
    145                 move.w  d0,(a1)         * Store second output word in scan line
    146                 suba.w  d5,a1           * Update output pointer
    147                 suba.w  #2,a1           * ...
    148                 adda.l  #512,a0         * Update CG pointer for next scan line
    149                 dbf     d6,cgl1         * Loop for all scan lines
    150 *
    151                 bra     cgl0            * Loop for next character
    152 *
    153 cgl5:           movem.l (a7)+,d3-d6/a3  * Restore registers
    154                 unlk    a6              * Unlink stack frames
    155                 rts                     * Return to caller
    156 *
     105cgl1:           move.w  (a0),d1         | Get character generator word in d1
     106                move.w  #(HPIX/2)-1,d2  | Set pixel counter in d2
     107                clr.l   d4              | Get old output word as background
     108                move.w  (a1),d4         | ...
     109                swap    d4              | ...
     110
     111cgl2:           lsr.w   #HSHIFT,d0      | Shift output word right 1 pixel
     112                lsr.l   #HSHIFT,d4      | Shift background word 1 pixel
     113                andi.l  #0xFFFFF000,d4  | Mask for upper 4 bits of d4.W
     114                btst.l  #0,d1           | Check CG word ls bit
     115                beq     cgl3            | Set background color if bit EQ 0
     116
     117                or.w    d3,d0           | OR foreground color into output word
     118                bra     cgl4            | Go update CG word
     119
     120cgl3:           or.w    d4,d0           | OR background color into output word
     121
     122cgl4:           lsr.w   #1,d1           | Shift CG word right 1 pixel
     123                dbf     d2,cgl2         | Loop for first 4 pixels
     124
     125                move.w  d0,(a1)+        | Store first output word in scan line
     126                move.w  #(HPIX/2)-1,d2  | Set pixel counter in d2
     127                clr.l   d4              | Get old output word as background
     128                move.w  (a1),d4         | ...
     129                swap    d4              | ...
     130
     131cgl2a:          lsr.w   #HSHIFT,d0      | Shift output word right 1 pixel
     132                lsr.l   #HSHIFT,d4      | Shift background word 1 pixel
     133                andi.l  #0xFFFFF000,d4  | Mask for upper bits of d4.W
     134                btst.l  #0,d1           | Check CG word ls bit
     135                beq     cgl3a           | Set background color if bit EQ 0
     136
     137                or.w    d3,d0           | OR foreground color into output word
     138                bra     cgl4a           | Go update CG word
     139
     140cgl3a:          or.w    d4,d0           | OR background color into output word
     141
     142cgl4a:          lsr.w   #1,d1           | Shift CG word right 1 pixel
     143                dbf     d2,cgl2a        | Loop for last 4 pixels
     144
     145                move.w  d0,(a1)         | Store second output word in scan line
     146                suba.w  d5,a1           | Update output pointer
     147                suba.w  #2,a1           | ...
     148                adda.l  #512,a0         | Update CG pointer for next scan line
     149                dbf     d6,cgl1         | Loop for all scan lines
     150
     151                bra     cgl0            | Loop for next character
     152
     153cgl5:           movem.l (a7)+,d3-d6/a3  | Restore registers
     154                unlk    a6              | Unlink stack frames
     155                rts                     | Return to caller
     156
    157157                .end
  • vlib/vvputsv.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vvputsv.s -- output characters to a 4-bit / pixel graphics window
    3 * with variable vertical pitch
    4 * Version 1 -- 1988-10-07 -- D.N. Lynx Crowe
    5 * (c) Copyright 1988 -- D.N. Lynx Crowe
    6 * ------------------------------------------------------------------------------
    7 *
    8 *       vvputsv(obase, nw, fg, bg, row, col, str, pitch, ht, cgtab)
    9 *       uint *obase, nw, fg, bg, row, col, pitch, ht, cgtab[][256];
    10 *       char *str;
    11 *
    12 *               Outputs characters from the string at 'str' to an 'nw'
    13 *               character wide 4-bit per pixel graphics window at 'obase'
    14 *               at ('row','col'), using 'fg' as the foreground color, and
    15 *               'bg' as the background color.  Uses cgtab[][256] as the
    16 *               VSDD formatted character generator table.  Assumes 'ht' line
    17 *               high characters in the cg table.  Uses 'pitch' as the vertical
    18 *               spacing between character rows.  No error checks are done.
    19 *               The string must fit the output area (no overlaps, single line).
    20 *
    21 * ------------------------------------------------------------------------------
     1| ------------------------------------------------------------------------------
     2| vvputsv.s -- output characters to a 4-bit / pixel graphics window
     3| with variable vertical pitch
     4| Version 1 -- 1988-10-07 -- D.N. Lynx Crowe
     5| (c) Copyright 1988 -- D.N. Lynx Crowe
     6| ------------------------------------------------------------------------------
     7
     8|       vvputsv(obase, nw, fg, bg, row, col, str, pitch, ht, cgtab)
     9|       uint |obase, nw, fg, bg, row, col, pitch, ht, cgtab[][256];
     10|       char |str;
     11
     12|               Outputs characters from the string at 'str' to an 'nw'
     13|               character wide 4-bit per pixel graphics window at 'obase'
     14|               at ('row','col'), using 'fg' as the foreground color, and
     15|               'bg' as the background color.  Uses cgtab[][256] as the
     16|               VSDD formatted character generator table.  Assumes 'ht' line
     17|               high characters in the cg table.  Uses 'pitch' as the vertical
     18|               spacing between character rows.  No error checks are done.
     19|               The string must fit the output area (no overlaps, single line).
     20
     21| ------------------------------------------------------------------------------
    2222                .text
    23 *
     23
    2424                .xdef   _vvputsv
    25 *
    26 * Argument offsets from a6:
    27 *
    28 OBASE           .equ    8               * LONG - Output area base address
    29 NW              .equ    12              * WORD - Character width of output area
    30 FG              .equ    14              * WORD - Foreground color
    31 BG              .equ    16              * WORD - Background color
    32 ROW             .equ    18              * WORD - Row
    33 COL             .equ    20              * WORD - Column
    34 STR             .equ    22              * LONG - String base address
    35 PITCH           .equ    26              * WORD - Vertical spacing between rows
    36 HT              .equ    28              * WORD - Character height  (LE PITCH)
    37 CGTAB           .equ    30              * LONG - Character generator table
    38 *
    39 * Program constant definitions:
    40 *
    41 HPIX            .equ    8               * Character width in pixels
    42 HCW             .equ    4               * Horizontal character width (bytes)
    43 PSHIFT          .equ    12              * Pixel shift into MS bits
    44 HSHIFT          .equ    4               * Pixel right shift
    45 *
     25
     26| Argument offsets from a6:
     27
     28OBASE           =       8               | LONG - Output area base address
     29NW              =       12              | WORD - Character width of output area
     30FG              =       14              | WORD - Foreground color
     31BG              =       16              | WORD - Background color
     32ROW             =       18              | WORD - Row
     33COL             =       20              | WORD - Column
     34STR             =       22              | LONG - String base address
     35PITCH           =       26              | WORD - Vertical spacing between rows
     36HT              =       28              | WORD - Character height  (LE PITCH)
     37CGTAB           =       30              | LONG - Character generator table
     38
     39| Program constant definitions:
     40
     41HPIX            =       8               | Character width in pixels
     42HCW             =       4               | Horizontal character width (bytes)
     43PSHIFT          =       12              | Pixel shift into MS bits
     44HSHIFT          =       4               | Pixel right shift
     45
    4646                .page
    47 *
    48 * Register usage:
    49 *
    50 *       d0      output word and scratch
    51 *       d1      CG word and scratch
    52 *       d2      pixel counter
    53 *
    54 *       d3      foreground color (in the 4 ms bits)
    55 *       d4      background color (in the 4 ms bits)
    56 *       d5      width of the area in bytes
    57 *       d6      scan line counter
    58 *
    59 *       a0      CG table pointer
    60 *       a1      output area scan line pointer
    61 *       a2      input string character pointer
    62 *
    63 *       a3      output area character base pointer
    64 *
    65 *       a6      frame pointer
    66 *       a7      stack pointer
    67 *
     47
     48| Register usage:
     49
     50|       d0      output word and scratch
     51|       d1      CG word and scratch
     52|       d2      pixel counter
     53
     54|       d3      foreground color (in the 4 ms bits)
     55|       d4      background color (in the 4 ms bits)
     56|       d5      width of the area in bytes
     57|       d6      scan line counter
     58
     59|       a0      CG table pointer
     60|       a1      output area scan line pointer
     61|       a2      input string character pointer
     62
     63|       a3      output area character base pointer
     64
     65|       a6      frame pointer
     66|       a7      stack pointer
     67
    6868                .page
    69 *
    70 _vvputsv:       link    a6,#0           * Link stack frames
    71                 movem.l d3-d6/a3,-(a7)  * Save registers we use
    72                 move.w  #PSHIFT,d1      * Set shift constant
    73                 move.w  FG(a6),d3       * Setup foreground color
    74                 lsl.w   d1,d3           * ... in ms 4 bits of d3.W
    75                 move.w  BG(a6),d4       * Setup background color
    76                 lsl.w   d1,d4           * ... in ms 4 bits of d4.W
    77                 move.w  NW(a6),d5       * Get line width in d5.W
    78                 lsl.w   #2,d5           * Multiply width by 4 for offset
    79                 move.w  ROW(a6),d0      * Calculate output address
    80                 move.w  PITCH(a6),d1    * ... PITCH
    81                 mulu    d1,d0           * ... * ROW
    82                 add.w   #HT(a6),d0      * ... + HT-1
    83                 subq.w  #1,d0           * ...
    84                 mulu    d5,d0           * ... * NW
    85                 clr.l   d1              * ...
    86                 move.w  COL(a6),d1      * ... +
    87                 lsl.w   #2,d1           * ... COL * 4
    88                 add.l   d1,d0           * ...
    89                 add.l   OBASE(a6),d0    * ... + OBASE
    90                 movea.l d0,a3           * Leave output address in a3
    91                 movea.l STR(a6),a2      * Put string address in a2
    92 *
    93 cgl0:           clr.l   d0              * Clear out upper bits of d0
    94                 move.b  (a2)+,d0        * Get next character
    95                 beq     cgl5            * Done if character EQ 0
    96 *
    97                 movea.l a3,a1           * Establish output pointer in a1
    98                 adda.l  #HCW,a3         * Update output pointer for next char.
    99                 movea.l CGTAB(a6),a0    * Establish CG pointer in a0
    100                 lsl.w   #1,d0           * ... 2 * character
    101                 adda.w  d0,a0           * ... + cg table address
    102                 move.w  HT(a6),d6       * Set scan line counter in d6
    103                 subq.w  #1,d6           * ... to HT-1
    104 *
     69
     70_vvputsv:       link    a6,#0           | Link stack frames
     71                movem.l d3-d6/a3,-(a7)  | Save registers we use
     72                move.w  #PSHIFT,d1      | Set shift constant
     73                move.w  FG(a6),d3       | Setup foreground color
     74                lsl.w   d1,d3           | ... in ms 4 bits of d3.W
     75                move.w  BG(a6),d4       | Setup background color
     76                lsl.w   d1,d4           | ... in ms 4 bits of d4.W
     77                move.w  NW(a6),d5       | Get line width in d5.W
     78                lsl.w   #2,d5           | Multiply width by 4 for offset
     79                move.w  ROW(a6),d0      | Calculate output address
     80                move.w  PITCH(a6),d1    | ... PITCH
     81                mulu    d1,d0           | ... | ROW
     82                add.w   HT(a6),d0       | ... + HT-1
     83                subq.w  #1,d0           | ...
     84                mulu    d5,d0           | ... | NW
     85                clr.l   d1              | ...
     86                move.w  COL(a6),d1      | ... +
     87                lsl.w   #2,d1           | ... COL | 4
     88                add.l   d1,d0           | ...
     89                add.l   OBASE(a6),d0    | ... + OBASE
     90                movea.l d0,a3           | Leave output address in a3
     91                movea.l STR(a6),a2      | Put string address in a2
     92
     93cgl0:           clr.l   d0              | Clear out upper bits of d0
     94                move.b  (a2)+,d0        | Get next character
     95                beq     cgl5            | Done if character EQ 0
     96
     97                movea.l a3,a1           | Establish output pointer in a1
     98                adda.l  #HCW,a3         | Update output pointer for next char.
     99                movea.l CGTAB(a6),a0    | Establish CG pointer in a0
     100                lsl.w   #1,d0           | ... 2 | character
     101                adda.w  d0,a0           | ... + cg table address
     102                move.w  HT(a6),d6       | Set scan line counter in d6
     103                subq.w  #1,d6           | ... to HT-1
     104
    105105                .page
    106 cgl1:           move.w  (a0),d1         * Get character generator word in d1
    107                 move.w  #(HPIX/2)-1,d2  * Set pixel counter in d2
    108 *
    109 cgl2:           lsr.w   #HSHIFT,d0      * Shift output word right 1 pixel
    110                 btst.l  #0,d1           * Check CG word ls bit
    111                 beq     cgl3            * Set background color if bit EQ 0
    112 *
    113                 or.w    d3,d0           * OR foreground color into output word
    114                 bra     cgl4            * Go update CG word
    115 *
    116 cgl3:           or.w    d4,d0           * OR background color into output word
    117 *
    118 cgl4:           lsr.w   #1,d1           * Shift CG word right 1 pixel
    119                 dbf     d2,cgl2         * Loop for first 4 pixels
    120 *
    121                 move.w  d0,(a1)+        * Store first output word in scan line
    122                 move.w  #(HPIX/2)-1,d2  * Set pixel counter in d2
    123 *
    124 cgl2a:          lsr.w   #HSHIFT,d0      * Shift output word right 1 pixel
    125                 btst.l  #0,d1           * Check CG word ls bit
    126                 beq     cgl3a           * Set background color if bit EQ 0
    127 *
    128                 or.w    d3,d0           * OR foreground color into output word
    129                 bra     cgl4a           * Go update CG word
    130 *
    131 cgl3a:          or.w    d4,d0           * OR background color into output word
    132 *
    133 cgl4a:          lsr.w   #1,d1           * Shift CG word right 1 pixel
    134                 dbf     d2,cgl2a        * Loop for last 4 pixels
    135 *
    136                 move.w  d0,(a1)         * Store second output word in scan line
    137                 suba.w  d5,a1           * Update output pointer
    138                 suba.w  #2,a1           * ...
    139                 adda.l  #512,a0         * Update CG pointer for next scan line
    140                 dbf     d6,cgl1         * Loop for all scan lines
    141 *
    142                 bra     cgl0            * Loop for next character
    143 *
    144 cgl5:           movem.l (a7)+,d3-d6/a3  * Restore registers
    145                 unlk    a6              * Unlink stack frames
    146                 rts                     * Return to caller
    147 *
     106cgl1:           move.w  (a0),d1         | Get character generator word in d1
     107                move.w  #(HPIX/2)-1,d2  | Set pixel counter in d2
     108
     109cgl2:           lsr.w   #HSHIFT,d0      | Shift output word right 1 pixel
     110                btst.l  #0,d1           | Check CG word ls bit
     111                beq     cgl3            | Set background color if bit EQ 0
     112
     113                or.w    d3,d0           | OR foreground color into output word
     114                bra     cgl4            | Go update CG word
     115
     116cgl3:           or.w    d4,d0           | OR background color into output word
     117
     118cgl4:           lsr.w   #1,d1           | Shift CG word right 1 pixel
     119                dbf     d2,cgl2         | Loop for first 4 pixels
     120
     121                move.w  d0,(a1)+        | Store first output word in scan line
     122                move.w  #(HPIX/2)-1,d2  | Set pixel counter in d2
     123
     124cgl2a:          lsr.w   #HSHIFT,d0      | Shift output word right 1 pixel
     125                btst.l  #0,d1           | Check CG word ls bit
     126                beq     cgl3a           | Set background color if bit EQ 0
     127
     128                or.w    d3,d0           | OR foreground color into output word
     129                bra     cgl4a           | Go update CG word
     130
     131cgl3a:          or.w    d4,d0           | OR background color into output word
     132
     133cgl4a:          lsr.w   #1,d1           | Shift CG word right 1 pixel
     134                dbf     d2,cgl2a        | Loop for last 4 pixels
     135
     136                move.w  d0,(a1)         | Store second output word in scan line
     137                suba.w  d5,a1           | Update output pointer
     138                suba.w  #2,a1           | ...
     139                adda.l  #512,a0         | Update CG pointer for next scan line
     140                dbf     d6,cgl1         | Loop for all scan lines
     141
     142                bra     cgl0            | Loop for next character
     143
     144cgl5:           movem.l (a7)+,d3-d6/a3  | Restore registers
     145                unlk    a6              | Unlink stack frames
     146                rts                     | Return to caller
     147
    148148                .end
  • vlib/vwputp.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vwputp.s -- put a pixel into a 2-bit per pixel bitmap object
    3 * Version 2 -- 1987-04-14 -- D.N. Lynx Crowe
    4 * (c) Copyright 1987 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *       int
    7 *       vwputp(octad, xloc, yloc, val)
    8 *       struct octent *octad;
    9 *       int xloc, yloc;
    10 *
    11 *               Writes the pixel value 'val' into the 2-bit per pixel
    12 *               bitmap object described by 'octad' at ('xloc','yloc').
    13 *
    14 *       -----
    15 *
    16 *       struct octent {
    17 *
    18 *               uint    ysize,
    19 *                       xsize;
    20 *
    21 *               int     objx,
    22 *                       objy;
    23 *
    24 *               uint    *obase;
    25 *
    26 *               char    opri,
    27 *                       oflags;
    28 *
    29 *               uint    odtw0,
    30 *                       odtw1;
    31 *       };
    32 *
    33 *       Upper left corner of screen is (0,0) origin.
    34 *
     1| ------------------------------------------------------------------------------
     2| vwputp.s -- put a pixel into a 2-bit per pixel bitmap object
     3| Version 2 -- 1987-04-14 -- D.N. Lynx Crowe
     4| (c) Copyright 1987 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6|       int
     7|       vwputp(octad, xloc, yloc, val)
     8|       struct octent |octad;
     9|       int xloc, yloc;
     10
     11|               Writes the pixel value 'val' into the 2-bit per pixel
     12|               bitmap object described by 'octad' at ('xloc','yloc').
     13
     14|       -----
     15
     16|       struct octent {
     17
     18|               uint    ysize,
     19|                       xsize;
     20
     21|               int     objx,
     22|                       objy;
     23
     24|               uint    |obase;
     25
     26|               char    opri,
     27|                       oflags;
     28
     29|               uint    odtw0,
     30|                       odtw1;
     31|       };
     32
     33|       Upper left corner of screen is (0,0) origin.
     34
    3535                .text
    36 *
     36
    3737                .xdef   _vputp
    38 *
    39 OCTAD           .equ    8
    40 XLOC            .equ    12
    41 YLOC            .equ    14
    42 VAL             .equ    16
    43 *
    44 YSIZE           .equ    0
    45 XSIZE           .equ    2
    46 OBJX            .equ    4
    47 OBJY            .equ    6
    48 OBASE           .equ    8
    49 OPRI            .equ    12
    50 OFLAGS          .equ    13
    51 ODTW0           .equ    14
    52 ODTW1           .equ    16
    53 *
     38
     39OCTAD           =       8
     40XLOC            =       12
     41YLOC            =       14
     42VAL             =       16
     43
     44YSIZE           =       0
     45XSIZE           =       2
     46OBJX            =       4
     47OBJY            =       6
     48OBASE           =       8
     49OPRI            =       12
     50OFLAGS          =       13
     51ODTW0           =       14
     52ODTW1           =       16
     53
    5454                .page
    55 *
    56 _vwputp:        link    a6,#0                   * Link stack frames
    57                 movea.l OCTAD(a6),a1            * Get OCTAD base into a1
    58                 move.w  XLOC(a6),d0             * Get XLOC into d0
    59                 cmp.w   XSIZE(a1),d0            * Check XLOC range
    60                 bge     vputerr                 * ERROR if too large
    61 *
    62                 tst.w   d0                      * Check XLOC sign
    63                 bmi     vputerr                 * ERROR if negative
    64 *
    65                 move.w  YLOC(a6),d1             * Get YLOC into d1 to test
    66                 cmp.w   YSIZE(a1),d1            * Check YLOC range
    67                 bge     vputerr                 * ERROR if too large
    68 *
    69                 tst.w   d1                      * Check YLOC sign
    70                 bmi     vputerr                 * ERROR if negative
    71 *
    72                 lsr.w   #3,d0                   * Divide XLOC by 8
    73                 move.w  XSIZE(a1),d1            * Get width into d1
    74                 lsr.w   #3,d1                   * Divide width by 8
    75                 mulu    YLOC(a6),d1             * Multiply width/8 by YLOC
    76                 ext.l   d0                      * Extend XLOC/8 to a long
    77                 add.l   d0,d1                   * ... and add it to d1
    78                 add.l   OBASE(a1),d1            * Add OBASE to d1
    79                 movea.l d1,a0                   * Make a0 point at bitmap data
    80                 move.w  XLOC(a6),d0             * Get XLOC
    81                 andi.l  #$07,d0                 * Mask to low 3 bits
    82                 add.l   d0,d0                   * Multiply by 2 for word index
    83                 move.l  d0,d1                   * Save index in d1
    84                 add.l   #MTAB,d0                * Add mask table base
    85                 movea.l d0,a2                   * a2 points at mask
    86                 add.l   #STAB,d1                * Add shift table base to index
    87                 move.l  d1,a1                   * a1 points at shift count
    88                 move.w  (a1),d0                 * Get shift count in d0
    89                 move.w  VAL(a6),d1              * Get new pixel in d1
    90                 andi.w  #$03,d1                 * Mask down to 2 bits
    91                 lsl.w   d0,d1                   * Shift into position for OR
    92                 move.w  (a0),d0                 * Get old bitmap word in d0
    93                 and.w   (a2),d0                 * Mask out old pixel
    94                 or.w    d1,d0                   * OR in new pixel
    95                 move.w  d0,(a0)                 * Store updated word in bitmap
    96                 clr.l   d0                      * Set return value = 0 = OK
    97 *
    98 vputexit:       unlk    a6                      * Unlink stack frame
    99                 rts                             * Return to caller
    100 *
    101 vputerr:        moveq.l #-1,d0                  * Set return value = -1 = ERROR
    102                 bra     vputexit                * Go unlink stack and return
    103 *
    104 MTAB:           dc.w    $FFFC,$FFF3,$FFCF,$FF3F * Mask table
    105                 dc.w    $FCFF,$F3FF,$CFFF,$3FFF
    106 STAB:           dc.w    0,2,4,6,8,10,12,14      * Shift table
    107 *
     55
     56_vwputp:        link    a6,#0                   | Link stack frames
     57                movea.l OCTAD(a6),a1            | Get OCTAD base into a1
     58                move.w  XLOC(a6),d0             | Get XLOC into d0
     59                cmp.w   XSIZE(a1),d0            | Check XLOC range
     60                bge     vputerr                 | ERROR if too large
     61
     62                tst.w   d0                      | Check XLOC sign
     63                bmi     vputerr                 | ERROR if negative
     64
     65                move.w  YLOC(a6),d1             | Get YLOC into d1 to test
     66                cmp.w   YSIZE(a1),d1            | Check YLOC range
     67                bge     vputerr                 | ERROR if too large
     68
     69                tst.w   d1                      | Check YLOC sign
     70                bmi     vputerr                 | ERROR if negative
     71
     72                lsr.w   #3,d0                   | Divide XLOC by 8
     73                move.w  XSIZE(a1),d1            | Get width into d1
     74                lsr.w   #3,d1                   | Divide width by 8
     75                mulu    YLOC(a6),d1             | Multiply width/8 by YLOC
     76                ext.l   d0                      | Extend XLOC/8 to a long
     77                add.l   d0,d1                   | ... and add it to d1
     78                add.l   OBASE(a1),d1            | Add OBASE to d1
     79                movea.l d1,a0                   | Make a0 point at bitmap data
     80                move.w  XLOC(a6),d0             | Get XLOC
     81                andi.l  #0x07,d0                | Mask to low 3 bits
     82                add.l   d0,d0                   | Multiply by 2 for word index
     83                move.l  d0,d1                   | Save index in d1
     84                add.l   #MTAB,d0                | Add mask table base
     85                movea.l d0,a2                   | a2 points at mask
     86                add.l   #STAB,d1                | Add shift table base to index
     87                move.l  d1,a1                   | a1 points at shift count
     88                move.w  (a1),d0                 | Get shift count in d0
     89                move.w  VAL(a6),d1              | Get new pixel in d1
     90                andi.w  #0x03,d1                | Mask down to 2 bits
     91                lsl.w   d0,d1                   | Shift into position for OR
     92                move.w  (a0),d0                 | Get old bitmap word in d0
     93                and.w   (a2),d0                 | Mask out old pixel
     94                or.w    d1,d0                   | OR in new pixel
     95                move.w  d0,(a0)                 | Store updated word in bitmap
     96                clr.l   d0                      | Set return value = 0 = OK
     97
     98vputexit:       unlk    a6                      | Unlink stack frame
     99                rts                             | Return to caller
     100
     101vputerr:        moveq.l #-1,d0                  | Set return value = -1 = ERROR
     102                bra     vputexit                | Go unlink stack and return
     103
     104MTAB:           dc.w    0xFFFC,0xFFF3,0xFFCF,0xFF3F     | Mask table
     105                dc.w    0xFCFF,0xF3FF,0xCFFF,0x3FFF
     106STAB:           dc.w    0,2,4,6,8,10,12,14      | Shift table
     107
    108108                .end
  • vlib/vwputs.s

    rf40a309 r4f508e6  
    1 * ------------------------------------------------------------------------------
    2 * vwputs.s -- output a character string to a 2-bit per pixel graphics window
    3 * Version 9 -- 1987-07-28 -- D.N. Lynx Crowe
    4 * (c) Copyright 1987 -- D.N. Lynx Crowe
    5 * ------------------------------------------------------------------------------
    6 *
    7 *       vwputs(obase, nw, fg, bg, row, col, str)
    8 *       int *obase, nw, fg, bg, row, col;
    9 *       char *str;
    10 *
    11 *               Outputs characters from the string at 'str' to an 'nw'
    12 *               character wide 2-bit per pixel graphics window at 'obase'
    13 *               at ('row','col'), using 'fg' as the foreground color, and
    14 *               'bg' as the background color.  Uses cgtable[][256] as the
    15 *               VSDD formatted character generator table.
    16 *               No error checks are done.
    17 * ------------------------------------------------------------------------------
    18 *
     1| ------------------------------------------------------------------------------
     2| vwputs.s -- output a character string to a 2-bit per pixel graphics window
     3| Version 9 -- 1987-07-28 -- D.N. Lynx Crowe
     4| (c) Copyright 1987 -- D.N. Lynx Crowe
     5| ------------------------------------------------------------------------------
     6
     7|       vwputs(obase, nw, fg, bg, row, col, str)
     8|       int |obase, nw, fg, bg, row, col;
     9|       char |str;
     10
     11|               Outputs characters from the string at 'str' to an 'nw'
     12|               character wide 2-bit per pixel graphics window at 'obase'
     13|               at ('row','col'), using 'fg' as the foreground color, and
     14|               'bg' as the background color.  Uses cgtable[][256] as the
     15|               VSDD formatted character generator table.
     16|               No error checks are done.
     17| ------------------------------------------------------------------------------
     18
    1919                .text
    2020                .xdef   _vwputs
    21 *
     21
    2222                .xref   _cgtable
    23 *
    24 * Argument offsets from a6:
    25 *
    26 OBASE           .equ    8               * L:  Output area base address
    27 NW              .equ    12              * W:  Character width of output area
    28 FG              .equ    14              * W:  Foreground color
    29 BG              .equ    16              * W:  Background color
    30 ROW             .equ    18              * W:  Row
    31 COL             .equ    20              * W:  Column
    32 STR             .equ    22              * L:  String base address
    33 *
    34 * Miscellaneous constants:
    35 *
    36 HPIX            .equ    8               * Horizontal pixels in the character
    37 *
    38 NVPIX           .equ    12              * Vertical pixels in the character
    39 VPITCH          .equ    12              * Vertical pitch between characters
    40 *
    41 * Register usage:
    42 *
    43 *       d0      output word and scratch
    44 *       d1      CG word and scratch
    45 *       d2      pixel counter
    46 *       d3      foreground color (in the 2 ms bits)
    47 *       d4      background color (in the 2 ms bits)
    48 *       d5      width of the area in bytes
    49 *       d6      scan line counter
    50 *
    51 *       a0      CG table pointer
    52 *       a1      output area scan line pointer
    53 *       a2      input character pointer
    54 *       a3      output area character pointer
    55 *
     23
     24| Argument offsets from a6:
     25
     26OBASE           =       8               | L:  Output area base address
     27NW              =       12              | W:  Character width of output area
     28FG              =       14              | W:  Foreground color
     29BG              =       16              | W:  Background color
     30ROW             =       18              | W:  Row
     31COL             =       20              | W:  Column
     32STR             =       22              | L:  String base address
     33
     34| Miscellaneous constants:
     35
     36HPIX            =       8               | Horizontal pixels in the character
     37
     38NVPIX           =       12              | Vertical pixels in the character
     39VPITCH          =       12              | Vertical pitch between characters
     40
     41| Register usage:
     42
     43|       d0      output word and scratch
     44|       d1      CG word and scratch
     45|       d2      pixel counter
     46|       d3      foreground color (in the 2 ms bits)
     47|       d4      background color (in the 2 ms bits)
     48|       d5      width of the area in bytes
     49|       d6      scan line counter
     50
     51|       a0      CG table pointer
     52|       a1      output area scan line pointer
     53|       a2      input character pointer
     54|       a3      output area character pointer
     55
    5656                .page
    57 *
    58 _vwputs:        link    a6,#0           * Link stack frames
    59                 movem.l d3-d6/a3,-(a7)  * Save registers we use
    60                 move.w  #14,d1          * Set shift constant
    61                 move.w  FG(a6),d3       * Setup foreground color
    62                 lsl.w   d1,d3           * ... in ms 2 bits of d3
    63                 move.w  BG(a6),d4       * Setup background color
    64                 lsl.w   d1,d4           * ... in ms 2 bits of d4
    65                 move.w  NW(a6),d5       * Get width in characters in d5
    66                 lsl.w   #1,d5           * ... make it words
    67                 move.w  ROW(a6),d0      * Calculate output address
    68                 move.w  #VPITCH,d1      * ...
    69                 mulu    d1,d0           * ... ROW * VPITCH
    70                 add.w   #NVPIX-1,d0     * ... + NVPIX-1
    71                 mulu    d5,d0           * ... * NW
    72                 clr.l   d1              * ...
    73                 move.w  COL(a6),d1      * ... + (COL * 2)
    74                 lsl.l   #1,d1           * ...
    75                 add.l   d1,d0           * ...
    76                 add.l   OBASE(a6),d0    * ... + OBASE
    77                 movea.l d0,a3           * Leave output address in a3
    78                 movea.l STR(a6),a2      * Put string address in a2
    79 *
     57
     58_vwputs:        link    a6,#0           | Link stack frames
     59                movem.l d3-d6/a3,-(a7)  | Save registers we use
     60                move.w  #14,d1          | Set shift constant
     61                move.w  FG(a6),d3       | Setup foreground color
     62                lsl.w   d1,d3           | ... in ms 2 bits of d3
     63                move.w  BG(a6),d4       | Setup background color
     64                lsl.w   d1,d4           | ... in ms 2 bits of d4
     65                move.w  NW(a6),d5       | Get width in characters in d5
     66                lsl.w   #1,d5           | ... make it words
     67                move.w  ROW(a6),d0      | Calculate output address
     68                move.w  #VPITCH,d1      | ...
     69                mulu    d1,d0           | ... ROW | VPITCH
     70                add.w   #NVPIX-1,d0     | ... + NVPIX-1
     71                mulu    d5,d0           | ... | NW
     72                clr.l   d1              | ...
     73                move.w  COL(a6),d1      | ... + (COL | 2)
     74                lsl.l   #1,d1           | ...
     75                add.l   d1,d0           | ...
     76                add.l   OBASE(a6),d0    | ... + OBASE
     77                movea.l d0,a3           | Leave output address in a3
     78                movea.l STR(a6),a2      | Put string address in a2
     79
    8080                .page
    81 cgl0:           clr.l   d0              * Clear out upper bits of d0
    82                 move.b  (a2)+,d0        * Get next character
    83                 beq     cgl5            * Done if character EQ 0
    84 *
    85                 movea.l a3,a1           * Establish output pointer in a1
    86                 adda.l  #2,a3           * Update output pointer for next char.
    87                 lea     _cgtable,a0     * Establish CG pointer in a0
    88                 lsl.w   #1,d0           * ... 2 * character
    89                 adda.w  d0,a0           * ... + _cgtable address
    90                 move.w  #NVPIX-1,d6     * Set scan line counter in d6
    91 *
    92 cgl1:           move.w  #HPIX-1,d2      * Set pixel counter in d2
    93                 move.w  (a0),d1         * Get character generator word in d1
    94 *
    95 cgl2:           lsr.w   #2,d0           * Shift output word right 1 pixel
    96                 btst.l  #0,d1           * Check CG word ls bit
    97                 beq     cgl3            * Set background color if bit EQ 0
    98 *
    99                 or.w    d3,d0           * OR foreground color into output word
    100                 bra     cgl4            * Go update CG word
    101 *
    102 cgl3:           or.w    d4,d0           * OR background color into  output word
    103 *
    104 cgl4:           lsr.w   #1,d1           * Shift CG word right 1 pixel
    105                 dbf     d2,cgl2         * Loop for all 8 pixels
    106 *
    107                 move.w  d0,(a1)         * Store output word in output bitmap
    108                 suba.w  d5,a1           * Update output pointer
    109                 adda.l  #512,a0         * Update CG pointer for next scan line
    110                 dbf     d6,cgl1         * Loop for all scan lines
    111 *
    112                 bra     cgl0            * Loop for next character
    113 *
    114 cgl5:           movem.l (a7)+,d3-d6/a3  * Restore registers
    115                 unlk    a6              * Unlink stack frames
    116                 rts                     * Return to caller
    117 *
     81cgl0:           clr.l   d0              | Clear out upper bits of d0
     82                move.b  (a2)+,d0        | Get next character
     83                beq     cgl5            | Done if character EQ 0
     84
     85                movea.l a3,a1           | Establish output pointer in a1
     86                adda.l  #2,a3           | Update output pointer for next char.
     87                lea     _cgtable,a0     | Establish CG pointer in a0
     88                lsl.w   #1,d0           | ... 2 | character
     89                adda.w  d0,a0           | ... + _cgtable address
     90                move.w  #NVPIX-1,d6     | Set scan line counter in d6
     91
     92cgl1:           move.w  #HPIX-1,d2      | Set pixel counter in d2
     93                move.w  (a0),d1         | Get character generator word in d1
     94
     95cgl2:           lsr.w   #2,d0           | Shift output word right 1 pixel
     96                btst.l  #0,d1           | Check CG word ls bit
     97                beq     cgl3            | Set background color if bit EQ 0
     98
     99                or.w    d3,d0           | OR foreground color into output word
     100                bra     cgl4            | Go update CG word
     101
     102cgl3:           or.w    d4,d0           | OR background color into  output word
     103
     104cgl4:           lsr.w   #1,d1           | Shift CG word right 1 pixel
     105                dbf     d2,cgl2         | Loop for all 8 pixels
     106
     107                move.w  d0,(a1)         | Store output word in output bitmap
     108                suba.w  d5,a1           | Update output pointer
     109                adda.l  #512,a0         | Update CG pointer for next scan line
     110                dbf     d6,cgl1         | Loop for all scan lines
     111
     112                bra     cgl0            | Loop for next character
     113
     114cgl5:           movem.l (a7)+,d3-d6/a3  | Restore registers
     115                unlk    a6              | Unlink stack frames
     116                rts                     | Return to caller
     117
    118118                .end
Note: See TracChangeset for help on using the changeset viewer.