Changeset 4f508e6 in buchla-68k for ram/timeint.s


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • ram/timeint.s

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