VBL - the V ertical BL ank Interrupt routines. =============================================== By Mike Barnard The VBL is one of the most useful interrupts in the ST TOS. Each time the Video Shifter reaches the end of the currently displayed screen, it generates an interrupt signal (level 4 for the vbl queue) which tells the 68000 that the VBL queue is waiting to be processed. As with all interrupts, the processor runs on until the interrupt mask is able to accept the VBL queue as top priority. When control is transferred to the VBL routine it does the following tasks. 1. It increases the counter 'frclock' ($466) by one. This counts the number of frames displayed, regardless of what happens later in the queue. 2. Tests the variable 'vblsem' ($452) to see if the VBL has been software disabled. If vblsem is 0 or negative then it has and the routine immediately exits and returns control of the processor to the program. 3. All registers are saved to the stack. 4. It increases the counter 'vbclock' ($462) by one. This counts the number of times the VBL routine is executed. 5. It then checks to see if a different monitor has been connected. This is because the refresh rate of 70Hz required by a monochrome monitors could do damage to a colour monitor designed to refresh at 50 or 60Hz. If a change has been made, the video shifter is reprogrammed accordingly. (More detail required, please). 6. A routine to flash the cursor. (Any useful details anyone?). 7. Test 'colorptr' ($45A) for 0. If it's anything other than 0 this is considered the address of a new colour palette and the 16 words from here are loaded into the video shifter as a new palette, colorptr is then cleared again. (This is how the BIOS call changes the palette). 8. Test 'screenpt' ($45E) for 0. If other than zero it's considered to be the base address of the screen. ???? (logical or physical?) (Where is the other address stored?) (More detail...) 9. The floppy disc routines are run. My information is limited to... a. Decide if a disc has been changed within a drive. b. Deselect the drives after the disc controller has turned the drive motor off. 10. Now the VBL queue is processed. This is where we put our routines. 11. The variable 'dmpflg' ($4EE) is examined. If it's zero, a hardcopy of the screen is outputted. The flag is set during the IKBD's interrupt routine if ALT+HELP are pressed together. 12. The register contents are restored. 13. The book 'Atari ST Anatomy' by First Publishing says that 'vblsem' is released'. It doesn't say how. Anyone with more information, please? 14. RTE, return from exception. The original program continues as if nothing had happened. Much! All this happens at the refresh rate of your monitor, 50, 60 or even 70 times a second. The VBL queue is a vector array. That is, a list (queue) of addresses held in protected memory. Each entry may hold either an address or zero (i.e. empty). The variable 'vblqueue' ($456) holds the address of the start of this array. The variable 'nvbls' ($454) holds the size of this array, normally 8 longwords of memory, i.e. 8 entries. (If there is not enough space with 8 entries then you can increase the number in 'nvbls' to however many you need, but you will have to move the queue to an area of memory with enough room to store the extra addresses and change the contents of 'vblqueue' to the address of the new array. Also, don't forget to restore the original values on exiting from your program). The TOS VBL routine tests each of the entries in turn and if the entry is not zero it is considered as the start address of a routine to be run. If it is zero, it is ignored. So, how can we use the VBL queue for ourselves? Firstly write the routine you wish to run. Maybe it increases a counter for something, or looks at joystick input? If it's in the VBL queue it WILL BE PROCESSED AT LEAST 50 TIMES A SECOND! So make it as short and as fast as you possibly can. Don't use the VBL without real need. If your routine takes (for example) 250 cycles to run, then it takes 12,500 cycles a second from the 8,000,000 the processor has. Add that on to the amount of time the rest of the VBL routine takes for itself and any other routines you may also have in the queue and your program may slow down considerably. My books say that your VBL routine can use all the CPU registers as normal EXCEPT the user stack pointer. It must end in RTS. I haven't experimented with this yet, but I ASSUME this to mean the command '- (sp)' and similar stack commands, are a no-go. Again, will someone fill in more detail please? So, now you have a short, fast routine. Label it. Our next job is to add the address of this label to the VBL queue. The area of memory holding the VBL queue and pointers is PROTECTED memory, i.e. an area of RAM that can only be accessed in supervisor mode. This is to stop stray program commands wiping out vital parts of the OS or its data and variables. But we need to access it so we must switch from user mode to supervisor mode. You have two choices. There is a system trap that switches the CPU from user to super and back again, (GEMDOS $20 - SUPER), and another trap that takes the address of a routine and runs that routine in super. (XBIOS 38 - SUPEXEC). Which to choose? That's your choice. Some people use gem20 to set the whole of their program to super mode at or near the start of their source and leave it that way throughout the whole program. Restoring to user mode at the end, I hope! Then you can access protected memory and OS variables at will. Others try to follow the 'rules' (ha!) and give the address of any routines that want to access protected memory to supexec which runs them in super for you, returning in user mode again. You'll have to work out the fine detail of this bit yourself. If you're reading this you're a programmer, of some sort, aren't you? But the outline is: Into super mode, (allows access to protected memory). Search the queue for an empty slot, (value of 0). Save the address of the slot you're about to fill. Put the address of your routine into the slot. Return to user mode. (Maybe). Continue with the program. Your vbl routine is now running each frame. On exiting your program, restore the value of 0 to the slot or it will stay there. CRRRRRRAAAAAASH, BOMMMMB!! Pooooow, zap, pop. I hope this helps any beginners to programming and perhaps any experts could fill in the gaps in my knowledge of interrupt programming.