louis@asterix.drev.dnd.ca (Louis Demers) (03/14/90)
Hi, Background: We are developing a piece of lab equipment which is controlled by a Macintosh II. We developed our own controllers which will be interfaced to the mac using GreenSpring IO card and some custom Industry Pack. The control registers can be configured at different addresses. Problems: When we access one of the registers and the controllers is not turned on, we crash with a bus errors. We suffer the same faith when we access the registers at the wrong address. Wish: I wish I could try to access an address and if the controller were turned off or not at this particular address, I would like to tell the user to check the power to the card or the address configuration. This could take the form of a subroutine with could be declared like this: int TryIT(Ptr memoryAddress,long *value) the return value could indicate if the access was successful and the parameter value could returned the actual value read. Question: Anybody has suggestions or better yet, code to do this ? Can it be done only in C ? I work with MPW 3.0 C and C++. ( I hate assembler but I feel like this time I won't be able to avoid it &-) Thanks in advance, Louis -- | Louis Demers | DREV, Defence Research Establishment,Valcartier | | louis@asterix.drev.dnd.ca | POBox 8800, Courcelette,Quebec, CANADA, G0A 1R0 | | (131.132.48.2) | Office: (418) 844-4424 fax (418) 844-4511 | +---------------------------+-------------------------------------------------+
ts@cup.portal.com (Tim W Smith) (03/18/90)
Try something like this:
long saveBusErrorVector;
if ( setjmp( something ) )
{
*(long *)8 = saveBusErrorVector;
return GOT_A_BUS_ERROR;
}
saveBusErrorVector = *(long *)8;
*(long *)8 = MyBusErrorHandler();
/* access your board */
*(long *)8 = saveBusErrorVector;
return DID_NOT_GET_A_BUS_ERROR;
The function MyBusErrorHandler would look something like this:
SetupA5(); /* or whatever your development
* system uses */
longjmp( something );
Check the Motorola manual to see what bus error does to the interrupt
level. I would guess that it is treated like a level 7 interrupt, and
thus sets the interupt level to 7. If so, you will have to do something
about this. This will require assembly language.
Tim Smith
ps: when I say "this will require assembly language", I am assuming
we are all gentle people who would not even think of casting a string
pointer to a function pointer and calling it, or any other such things
best not mentioned in polite company...
ting@mergsun.UUCP (Steve Ting) (03/20/90)
From article <1990Mar13.192544.1617@asterix.drev.dnd.ca>, by louis@asterix.drev.dnd.ca (Louis Demers): > Hi, > > Background: > We are developing a piece of lab equipment which is controlled by > a Macintosh II. We developed our own controllers which will be > interfaced to the mac using GreenSpring IO card and some custom > Industry Pack. The control registers can be configured at > different addresses. > > Problems: > When we access one of the registers and the controllers is not > turned on, we crash with a bus errors. We suffer the same faith > when we access the registers at the wrong address. > > Wish: > I wish I could try to access an address and if the controller > were turned off or not at this particular address, I would like to > tell the user to check the power to the card or the address > configuration. This could take the form of a subroutine with > could be declared like this: > int TryIT(Ptr memoryAddress,long *value) > the return value could indicate if the access was successful and > the parameter value could returned the actual value read. > > Question: > Anybody has suggestions or better yet, code to do this ? > Can it be done only in C ? I work with MPW 3.0 C and C++. > ( I hate assembler but I feel like this time I won't be able to > avoid it &-) > > Thanks in advance, > Louis >; Louis, You need to find your controller's base address first, before you can access it's registers. Normally, you have a configuration rom on your board with a ID number to identify it. Using the following, if GetSlotBase returns 0, then your software should not try to access the board. sID EQU your_ID ------------------------------------------------------------------------------ ; GetSlotBase ; ; returns slotBase in D0, clear D0 if no card found GetSlotBase PROC StackFrame RECORD {A6Link} LocalSpBlock DS SpBlock LocalSInfoRecord DS SInfoRecord LocalSize EQU LocalSpBlock - * A6Link DS.L 1 Return DS.L 1 ENDR WITH StackFrame,LocalSpBlock Link A6,#LocalSize MOVEM.L A0/A1/A4/D1/D2,-(SP) MOVEQ #BeginSlot,D2 ;;check slots in reverse order (EI9) nxt CMPI #EndSlot,D2 ;;exhausted all the slots? BGE.S mor CLR.L D0 ; yes: return nothing in D0 JMP Eop mor MOVE.B D2,spSlot(A6) ; no: continue searching next slot LEA LocalSInfoRecord(A6),A1 MOVE.L A1,spResult(A6) LEA LocalSpBlock(A6),A0 _SReadInfo MOVE.B D2,spSlot(A6) CLR.B spId(A6) CLR.B spExtDev(A6) MOVEQ #1,D1 MOVE.W D1,spCategory(A6) CLR.W spCType(A6) CLR.W spDrvrSW(A6) CLR.W spDrvrHW(A6) LEA LocalSpBlock(A6),A0 _SNextTypesRsrc MOVE.B #32,spId(A6) LEA LocalSpBlock(A6),A0 _SReadWord LEA spResult(A6),A4 SUBI.W #sId,2(A4) DBEQ D2,nxt ; on exit, D2 <- 0000000s MOVE.L D2,D0 ; D0 <- 0000000s LSL.W #4,D0 ; D0 <- 000000s0 OR.B D2,D0 ; D0 <- 000000ss OR.W #$F00,D0 ; D0 <- 00000Fss LSL.W #4,D0 ; D0 <- 0000Fss0 SWAP D0 ; D0 <- Fss00000 Eop MOVEM.L (SP)+,A0/A1/A4/D1/D2 UNLK A6 RTS ENDWITH ; StackFrame,LocalSpBlock ENDPROC ;GetSlotBase Hope this helps, Steven Ting Linotype Company