mfpr #^x11,r7 ;move scb addr to r7
movab ^X200(r7),r7 ;move addr of scb+512 to r7
movzbl #^X7f,r9 ;put 127 decimal in r9
scbloop:
moval xfcme,-(r7)
sobgeq r9,scbloop ;...in the SCB
And here's the routine the exceptions will trap to. Dump is a routine that translate the bytes to hex and prints them out as a string.
xfcme:
movl sp,r0
dump #40,(r0)
halt
To test the exception handling routine, I needed to cause one and see if my routine executed. The easiest most reliable way to cause an exception is to execute the XFC (eXtended Function Call) instruction. This is an opcode reserved by DIgital for customer use (and that's me!). XFC 's exception vector is at offset ^X14 in the SCB. Since I set 'em all pointing to my routine, I got that covered. I wrote a program to test it and loaded it to run. When it ran, I got my routine called, so it's a success.
Here's the test program, It's not much of a program, being one instruction long and all...
xfc
Here's a test run
>>>B XQA0
ATTEMPTING BOOTSTRAP
5F70000000001F04FFFF00A06850E2FF0C204002FFFF0000000000000000000000500000FFBF0080
00008FE4 06
Above is the result - it booted, executed the XFC instruction, trapped to my routine. It printed out 10 longwords worth of bytes, and then halted. The last line shows the halt address, and the halt cause, 06, which is , program executed a HALT instruction in kernel mode.
Ok, we've got exceptions handled, now on to the second page of the SCB, which handles interrupts.
The next 128 vectors (the second page) are for device interrupts. In this particular project, only one device will be interrupting - the DEQNA. The RQDX3 can interrupt, but they aren't required - I'll treat it like it's a programmed IO device. The DEQNA doesn't have its vector set by jumpers on the card, like most DEC peripherals. YOu can set it by writing to a device register. It defaults to 774. Since there's only one device interrupting in this application, I put its interrupt routine address in all 128 addresses in the interrupt part of the SCB. That way, it works no matter what the card is set to use. This is lazy, and I admit, funny things will happen if any other card interrupts, but, it seems to work fine. I filled them in in like wise to the way I did the first page
Here, the routine bing is the interrupt service routine - the name bing was chosen as a tribute to the RSX interrupt method as described in "The Hamster Theory of RSX". If you haven't read it, stop right now and do a search for it. I'd provide a link to it, but the author doesn't like links to his pages. You'll never find a better explanation of how an OS works than this one. Be sure and read the version that has pictures. Anyway....
mfpr #^x11,r7 ;move scb addr to r7
movab ^X200(r7),r7 ;move addr of scb+512 to r7
movzbl #^X7f,r9 ;put 127 decimal in r9
sc2loop:
moval bing,(r7)+
sobgeq r9,sc2loop
mess preXFC
xfc
mess postXFC
OK, the SCB is all set up. One last detail regarding interrupts, and it took me a few days to puzzle it out. I couldn't understand why the DEQNA wasn't interrupting when it received a packet. I finally realized that the card was interrupting at IPL4. The MicroVAX 1 sets the IPL to 31 after a power on, so the IPL 4 interrupt was getting ignored. I set the IPL to 1, and now the DEQNA interrupts could be acknowledged. The IPL is read and written from internal processor register ^X12.
mtpr #1,#^X12 ;set it to 1, so DEQNA can interrupt
Alright that's it for the SCB, exceptions and interrupts. Next, part 4 will deal with doing DEQNA IO.
No comments:
Post a Comment
Comments?