Changeset 4f508e6 in buchla-68k for rom


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.

Location:
rom
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.