Delving for Video Interrupt Information

So, you want to help find the magic information to clear interrupts on your video controller to help BSD run better on your system. You will need MacsBug and some very basic understanding of Motorola 68k assembly language. I wrote up these instructions using MacsBug version 6.5d9. Macsbug is available via FTP from Apple. If this link doesn't work, look for MacsBug in the directory listing.

With MacsBug installed, boot your system with the control key down and it will drop you into MacsBug right after putting "Debugger Installed" under "Welcome to Macintosh." To exit MacsBug, you can enter the command "g" to go to the next instruction (which in this case will continue the boot process). To reboot the machine, you can use the command "rb".

Finding the interrupt handler's function

Note: These directions will work to find the same information for non- display cards as well, but they will also need full-fledged drivers to be really functional.

The following commands will find the information that we need to have in order to clear video interrupts on your system. It might be useful to make a log file of your session with MacsBug. You may do this with the "log filename" command where filename will be the log file's name--found in the "System Folder".

The first step is to list the drivers in the system. This and the subsequent examples are from my Quadra 700 with a Macintosh 2-page display card and monitor installed and nothing attached to the internal video port. To list the drivers, use the 'drvr' command. In the examples below, what you type is bracketed with >>>> and <<<< I tried to make it bold, but at least Netscape renders "bold" preformatted text just like regular preformatted text.

>>>> drvr <<<<

 Displaying Driver Control Entries
  dRef dNum Driver                      Flg  Ver   qHead   Storage Dely  Drvr at DCE at
  FFFE 0001 .Sony                       bPO   #2 00000000 00000000 0000 4086C3E0 00006220
  FFFC 0003 .Sound                      bPO   #0 00000000 00006630 0000 408E59F0 000065F0
  FFFB 0004 .Sony                       bPO   #2 00000000 00000000 0000 4086C3E0 00006220
  FFFA 0005 .AIn                        bPC   #6 00000000 00000000 0000 4086ABCA 000067D0
  FFF9 0006 .AOut                       bPC   #6 00000000 00000000 0000 4086ABE2 00006810
  FFF8 0007 .BIn                        bPC   #6 00000000 00000000 0000 4086ABFA 00006850
  FFF7 0008 .BOut                       bPC   #6 00000000 00000000 0000 4086AC12 00006890
  FFDE 0021 .PTAD!011.6F                bPO   #0 00000000 00002064 0001 00013468 000125C0
  FFDA 0025 .PTAD!051.6F                bPO   #0 00000000 00002070 0001 0000A558 00008EB0
  FFCF 0030 .Display_Video_Apple_WVC    bHO   #0 00000000 00002124 0000 00006FD0 00006670
  FFCC 0033 .EDisk                      bPC   #0 00000000 00000000 0000 408E7500 000065B0
  #64 Unit Table entries, #11 in use, #53 free

Note that the italicized line is for my display card. Most graphics display drivers will start with ".Display". Of this information, we want the value in the next to the last column, "Drvr at"--in this case, 00006FD0. This is the block of memory at the head of the driver. We are looking for the drivers "open" routine as that is most likely where the driver installs it's video interrupt handling routine.

>>>> dm 6fd0 <<<<

 Displaying memory from 6fd0
  00006FD0  4C00 0000 0000 0000  0134 0000 01DA 05F8  [text representation of bytes]
The 8th and 9th bytes from this address make up the offset to the open routine. So we find an offset of 0134 from 00006FD0. We disassemble the code from that point, looking for the _SIntInstall trap. For this video card, that was quite a ways down. MacsBug will also let you search for this routine, but I chose to do it the hard way.
>>>> il 6fd0 + 134 <<<<

 Disassembling from 6fd0 + 134
  No procedure name
            00007104   MOVEQ      #$1A,D0                                 | 701A
	    [...]
            0000757C   RTS                                                | 4E75
            0000757E   LEA        *+$0356,A2                 ; 000078D4   | 45FA 0354
            00007582   MOVEQ      #$10,D0                                 | 7010
            00007584   _NewPtr    ,Sys,Immed                 ; A71E       | A71E
            00007586   BNE.S      *+$0026                    ; 000075AC   | 6624
            00007588   MOVE.W     #$0006,$0004(A0)                        | 317C 0006 0004
            0000758E   MOVE.L     A2,$0008(A0)                            | 214A 0008
            00007592   MOVEA.L    $002A(A1),A2                            | 2469 002A
            00007596   MOVE.L     A2,$000C(A0)                            | 214A 000C
            0000759A   MOVE.B     $0028(A1),D0                            | 1029 0028
            0000759E   _SIntInstall                          ; A075       | A075
            000075A0   BNE.S      *+$000C                    ; 000075AC   | 660A
            000075A2   ADDA.L     #$000A0000,A2                           | D5FC 000A 0000
Look for the value that is being placed in $0008(A0). This is a pointer to the interrupt handling function for this card. In this case, it's the contents of register A2, which is loaded with the value 78d4. The value that is placed in $000C(A0) is what will be in register A1 in the interrupt routine. In this case, it is being pulled out of a structure--I happen to know that it's the slot's base address. You may have to trace the driver's Open routine to find this out in the general case, but that will vary from driver to driver. If you can't figure it out, it's usually a reasonable guess that the value is the slot's base address.
>>>> il 78d4 <<<<

 Disassembling from 78d4
  No procedure name
            000078D4   MOVE.L     A1,D0                                   | 2009
            000078D6   ADDA.L     #$000A0000,A1                           | D3FC 000A 0000
            000078DC   CLR.B      (A1)                                    | 4211
            000078DE   ROL.L      #$8,D0                                  | E198
            000078E0   ANDI.W     #$000F,D0                               | 0240 000F
            000078E4   MOVEA.L    JVBLTask,A0                             | 2078 0D28
            000078E8   JSR        (A0)                                    | 4E90
            000078EA   MOVEQ      #$01,D0                                 | 7001
            000078EC   RTS                                                | 4E75

We can see here that the card takes the $000A00000 and adds it to the contents of A1 (which is the base address for this nubus slot. Then a byte is cleared at that address and the VBL task manager is called. The part that we are interested in is clear operation. To clear an interrupt on this card, all you have to do is write a zero to that address. Well, at least CLR.B that byte which will actually perform a read operation, too, if I recall correctly. Some cards will have a much more complex routine. If necessary, you can simply list the routine from your MacsBug log (RTS usually marks the end of a routine, as it does here) when you send in your report.

Remember, enter the 'g' command here, and your mac will continue booting to the Finder.

Identifying your card

So, armed with that information, we only need to know how to identify your card to BSD. Newer kernels (post-March 31, 1997) will complain that they can not install an interrupt function, and they specify the card ID. If you have that, skip down to Letting us know.

If you have an older kernel, you can get this info with the Slots program. This should also be available on Apple's ftp site and from puma. Make sure the the "Use Config ROM" option on the "Slots" menu is checked, and look at the slot information for your card. It should look something like the following:

The information that we need is referenced off the sResource directory entry '0x80' and then off the sResource directory entry '0x01'. For my video card, the information is:

0003 0001 0001 0006
This tells us that this card is an Apple display card of type 6.

Letting us know

When you have collected this information, please email it to Scott Reynolds or Allen Briggs. Thanks! If you are unsure of what you are seeing, mail your MacsBug log to Allen and ask for some help.

Video interrupts that we know

The following video interrupts are known:
Internal Video on SE/30,IIsi,IIci,IIvx,IIvi,P600,Q700,Q650
SE/30 Internal Video
Apple Toby Frame Buffer (0003 0001 0001 0001)
Samsung/Cornerstone 768x1006 (0003 0001 0001 0001)
Apple Macintosh Two-Page Display (0003 0001 0001 0006)
Apple Macintosh High-Res Video Display (0003 0001 0001 0013)
RasterOps Colorboard 264 (I think) (0003 0001 0001 013B)
RasterOps Colorboard 364 (0003 0001 0001 026F)
Radius Precisioncolor 8xj (0003 0001 0001 040B)
E-Machines Futura II LX (0003 0001 0001 0417)
E-Machines Futura II SX/DSP (0003 0001 0001 042F)
The Futura cards had flash ROM version is 1.1 (12 jan. 1994). The version number and date are displayed by the slots program. They were upgraded to this version with "Futura II LX.image" and "Futura II SX/DSP.image" files with a program called "Mr. Flash".

briggs@macbsd.com

Fri May 2 22:32:16 EDT 1997