; Places a user defined routine in the VBL queue
;
; At each Vertical Blank Interrupt the computer will execute a bunch of
; system 'tasks', such as:
;
; 1) Checking to see if a new monitor was installed
; 2) Checking to see if the color palette has been changed
; 3) Disk drive routine is executed
;
; We can use this to make the computer execute our own routines during
; the VBL( Vertical BLank Interrupt).
;
; The maximum number of routines that can be executed in the VBL queue
; is 8 (see _nvbls $454 for value, it is initalized to 8)
;
; Address _vblqueue ($456) contains a pointer to the VBL queue
;
; When the computer starts to execute the routines in the queue
; it checks each address and the routine is executed unless the
; value is zero.
;
;
; What this program does:
; -----------------------
;      It will check each entry in the VBL queue and if that entry
;      contains a zero, we will place a pointer to our routine there.
;
;
;      jeff bilger
;      jmb8302@photon.tamu.edu
;      Texas A&M University
;
start:                                 ; Calculate length of program
   lea    program_end,a3               ; put last addr of prg in a3
   suba.l 4(a7),a3                     ; subtract basepage, a3 holds total length of prg

enter_super:
 move.l      #0,-(sp)            ; enter supervisor mode
 move.w      #$20,-(sp)          ; Supervisor Stack Ptr SSP
 trap        #1                  ; returned in d0
 addq.l      #6,sp
 movea.l     d0,a5               ; save SSP

Search_for_empty_slot:           ; Search for empty entry in queue
 lea    $456,a4                  ; put addr that holds ptr to queue in a4
 move.l (a4),a1                  ; put ptr to queue in a1
                                 ; To access 1st entry do (a1)
 move.l #0,d6                    ; for comparison purposes only
 move.l #6,d1                    ; Loop max of 7 times
loop:
 move.l (a1),d5                  ; place contents into d5
 cmp    d6,d5                    ; see if entry is 0
 beq    install_code             ; if so, place ptr to my code in entry
 addq.l #4,a1                    ; goto next entry (note:each entry is 1 longword or 4 bytes)
 dbra   d1,loop                  ; decrement d1, if > -1 goto loop


install_code:                    ; place addr of mycode in entry
 lea  my_routine,a6              ; put addr of routine in a6
 move.l  a6,(a1)                 ; store it in entry of queue

enter_user:                      ; enter user mode
 pea     (a5)                    ; restore SSP
 move.w  #$20,-(sp)
 trap    #1
 addq.l  #$6,sp

load_and_stay_res:               ; Keep code resident in memory
 move.w  #0,-(sp)                ;
 move.l  a3,-(sp)                ; a3 holds length of program
 move.w  #$31,-(sp)
 trap    #1
                                 ; DONT update stack!!!

my_routine:

; user routine. Install as LSR with GEMDOS $31 and end with rts!

 pea    string                   ; this code will just print a message
 move.w #$9,-(sp)
 trap   #1
 addq.l #6,sp
 rts








 data
string: dc.b "Taltos! Apr.3.93 in VBL",$d,$a,0
 bss
 align              ; align storage on word boundary
program_end:  ds.l  0
 end
   
