TimerTst.a

***********************************************************************
***
***     TimerTst
***     
***
***********************************************************************
 
 
                    STRING  ASIS
                    INCLUDE 'Traps.a'
                    INCLUDE 'QuickEqu.a'
                    INCLUDE 'SysEqu.a'
                    PRINT   ON
                    BLANKS          OFF     ; allow comments without semicolons
 
T1Arbitrate EQU    $B3F         ; (byte) $FF if Timer T1 up for grabs.  
; VIA Offsets
 
vBufB           EQU      0          ; BUFFER B
vBufAH          EQU      $200       ; buffer a (with handshake) [ Dont use! ]
vDIRB           EQU      $400       ; DIRECTION B
vDIRA           EQU      $600       ; DIRECTION A
vT1C            EQU      $800       ; TIMER 1 COUNTER (L.O.)
vT1CH           EQU      $A00       ; timer 1 counter (high order)
vT1L            EQU      $C00       ; TIMER 1 LATCH (L.O.)
vT1LH           EQU      $E00       ; timer 1 latch (high order)
vT2C            EQU      $1000      ; TIMER 2 LATCH (L.O.)
vT2CH           EQU      $1200      ; timer 2 counter (high order)
vSR             EQU      $1400      ; SHIFT REGISTER
vACR            EQU      $1600      ; AUX. CONTROL REG.
vPCR            EQU      $1800      ; PERIPH. CONTROL REG.
vIFR            EQU      $1A00      ; INT. FLAG REG.
vIER            EQU      $1C00      ; INT. ENABLE REG.
vBufA           EQU      $1E00      ; BUFFER A
 
vBufD           EQU      $1E00      ; disk head select buffer
 
*********
* Types *
*********
 
* To illustrate how the template type feature works the following templates are
* declared and used instead of the simple offsets defined in the equate files.
* By using these, the Assember source appromixates very closely the Pascal
* source for referencing the corresponding information.  Perhaps someday we will
* have a set of "equate" files that define types just like Pascal USES units do!
 
Point           RECORD          0           Point = RECORD CASE INTEGER OF
v               DS.W            1                     1: (v: INTEGER;
h               DS.W            1                         h: INTEGER);
                ORG             v                     2: (vh: ARRAY[1..2]
vh              DS.W            h                                OF INTEGER)
                ENDR                                END;
 
Rect            RECORD          0           Rect  = RECORD CASE INTEGER OF
top             DS.W            1                     1: (top:    INTEGER;
left            DS.W            1                         left:   INTEGER;
bottom          DS.W            1                         bottom: INTEGER;
right           DS.W            1                         right:  INTEGER);
                ORG             top
topLeft         DS.L            Point                 2:  (topLeft:  Point;
botRight        DS.L            Point                 3:  (botRight: Point)
                ENDR                                END;
 
BitMap          RECORD          0           BitMap = RECORD
baseAddr        DS.L            1                     baseAddr: QDPtr;
rowBytes        DS.W            1                     rowBytes: INTEGER;
bounds          DS.L            Rect                  bounds:    Rect
                ENDR                                END;
 
EventRecord     RECORD          0           EventRecord = RECORD
what            DS.W            1                     what:    INTEGER;
message         DS.L            1                     message:   LONGINT;
when            DS.L            1                     when:    LONGINT;
where           DS.L            Point                 where:       Point;
modifiers       DS.W            1                     modifiers: INTEGER
                ENDR                                END;
 
                EJECT
 
***********************
* QuickDraw's Globals *
***********************
 
* The following data module is used to define the QuickDraw global data area.
*               -----------
 
QuickDraw       RECORD          ,DECREMENT
thePort         DS.L            1
white           DS.B            8
black           DS.B            8
gray            DS.B            8
ltGray          DS.B            8
dkGray          DS.B            8
arrow           DS.B            cursRec
screenBits      DS.B            BitMap
randSeed        DS.L            1
                ORG             -grafSize
                ENDR
 
******************************** Entry *******************************
 
Entry   MAIN
        ALIGN 2
        WITH            QuickDraw
        bra.s       real                            ;jump around handler and globals
        
******************************* Globals ******************************
 
oldVector   DC.L    0                               ;old timer 1 vector
valid       DC.B    0                               ;validity check for app
pad         DC.B    0                               ;pad for even addresses
Where       DC.W    0
counter     DC.L    0
WndPtr      DC.L    0                               ;my window pointer
WhichWnd    DC.L    0
clrRect     DC.L    0
            DC.L    0
theStr      DC.L    0                               ;this'll be a string when it grows up
            DC.L    0
            DC.L    0
            DC.L    0
            DC.L    0                               ;that oughta be enough (19 chars + count)
 
******************************* Handler ******************************
 
myHandler
    
        movem.l     a0/d0,-(a7)
        lea         valid,a0
        clr.b       (a0)                            ;mark counter invalid
        lea         counter,a0
        addq.l      #1,(a0)                         ;bump our counter
        lea         valid,a0
        st.b        (a0)                            ;mark count valid
        MOVE.L      VIA,A0                          ; get VIA base address
        MOVE.B      vT1C(A0),D0                     ;clear interrupt flag
        movem.l     (a7)+,a0/d0
        rts
        
****************************** Main Code *****************************
 
real    
        btst.b      #7,T1Arbitrate                  ;see if time one is free
        beq         outtahere                       ;hi bit clear means timer in use
        
        move.b      #1,T1Arbitrate                  ;claim it
        
        PEA         thePort                         ;Initialize QuickDraw
        _InitGraf
        _InitFonts                                  ;Initialize Font Manager
        MOVE.L      #$0000FFFF,D0                   ;Discard any previous events
        _FlushEvents                                ;FlushEvents(EventEvent, 0);
        _InitWindows                                ;Initialize Window Manager
 
        clr.l       -(a7)                           ;room for pointer (result)
        move.w      #256,-(a7)                      ;push resource ID
        clr.l       -(a7)                           ;wStorage is nil, let WMgr handle storage
        move.l      #-1,-(a7)                       ;make it the top window
        _GetNewWindow
        lea         WndPtr,a0
        move.l      (a7)+,(a0)                      ;get our pointer
        tst.l       (a0)                            ;make sure it's not nil
        beq         outtahere                       ;nil pointer, so give up
        
        move.l      WndPtr,-(a7)
        _SetPort
        
        lea         oldVector,a0
        move.l      LVL1DT+$18,(a0)                 ;keep the old vector around
        lea         myHandler,a0
        move.l      a0,LVL1DT+$18
        
        lea         clrRect,a0
        move.l      #$00200000,(a0)
        move.l      #$004000FF,4(a0)
        
        MOVE.L      VIA,A0                          ; get VIA base address
 
        OR.B        #$40,VACR(A0)                   ; turn on continous interrupts
        MOVE.W      #100,D0                         ; ticks per half-cycle (<C541 18dec86 mgl> corrected value)
        MOVE.B      D0,vT1C(A0)                     ; Load low byte into counter/latch.
        ROR.W       #8,D0                           ; Get high byte.
        MOVE.B      D0,vT1CH(A0)                    ; Load high byte and off we go!
        or.b        #$C0,vIER(a0)                   ; enable timer 1 interrupts
        
theLoop
        move.w      #5,-(a7)                        ;horizontal point
        move.w      #25,-(a7)                       ;vertival point
        _MoveTo
        
        lea         theStr,a0
        lea         valid,a1
validLoop
        tst.b       (a1)
        beq.s       validLoop
        move.l      counter,d0
        move.w      #0,-(a7)
        _Pack7                                      ;do a NumToString
        
        move.l      WndPtr,a0
        pea         PortRect(a0)
        _EraseRect
        pea         theStr
        _DrawString
        
        clr.w       -(a7)
        _button                                     ;see if mouse is down
        tst.b       (a7)+
        beq.s       theLoop
                        
quit    
        move.l      WndPtr,-(a7)
        _CloseWindow    
 
        MOVE.L      VIA,A0                          ; get VIA base address
        move.b      #$40,vIER(a0)                   ; disable timer 1 interrupts
        MOVE.b      #0,D0                           ;kill de timers?
        MOVE.B      D0,vT1C(A0)                     ; Load low byte into counter/latch.
        MOVE.B      D0,vT1CH(A0)                    ; Load high byte and off we go!
        
        move.l      ticks,d0                        ;give any interrupts laying around a chanceÉ
delayLoop                                           ;call me paraniod
        move.l      ticks,d1
        sub.l       d0,d1
        cmp.l       #10,d1
        ble.s       delayLoop
        move.l      oldVector,LVL1DT+$18            ;restore the old timer 1 vector
        move.b      #$FF,T1Arbitrate                ;mark timer free
        
outtahere
    
        _exitToShell
        END