|
Volume Number: | 5 | |
Issue Number: | 10 | |
Column Tag: | Letters |
Letters
By David E. Smith, Editor & Publisher, MacTutor
Any sympathetic souls
John Love, III
Springfield, VA
I’m having absolutely NO luck with MACDTS, or anyone else for that matter, trying to solve my following 2 separate & distinct problems. I KNOW this is an AWFUL lot, but I’m going crazy ?!*!?
; 1) Using _CopyBits to create a color PICT2 file: entireScreenpointer; My globals screenMap pointer; ... pictBoundsrect ; ... picHdl handle ; ... clr.w -(sp) bsr TestForColor pop.w d0 beq.s .bitMap ; ---------- .pixMap GetCWMgrPort !entireScreen move.l entireScreen,a0 lea portPixMap(a0),a1 move.l a1,screenMap move.l portPixMap(a0),a1 move.l (a1),a1 ; Handle -- Pointer. bra.s .setBounds ; .bitMap GetWMgrPort!entireScreen move.l entireScreen,a0 lea portBits(a0),a1 move.l a1,.screenMap ; ~~~~~~~~~~ .setBoundsmove.l bounds+topLeft(a1),pictBounds+topLeft move.l bounds+botRight(a1),pictBounds+botRight ; ---------- .setPortSetPort entireScreen ClipRect !pictBounds ; etc .macDraw2 OpenPicture!pictBounds,=picHdl CopyBits screenMap,screenMap,!pictBounds,!pictBounds,#srcCopy,#0 ClosePicture ; etc ; above code works in black-and-white mode, but NOT in color. ; ; I’ve tried : move.lentireScreen,a0 ;move.l portPixMap(a0),screenMap ; Also :move.l entireScreen,a0 ;move.l portPixMap(a0),a1 ;move.l (a1),screenMap ; ; ... but neither permutation works --> an empty picHdl (10 bytes, obviously ; ... corresponding to just the picSize & picFrame fields). ; ... it doesn’t bomb, but the file comes up blank, that is, just ; ... the 512-byte header + those 10 bytes and nothing else. ; ... I think it’s kinda interesting that ONLY upon ; ;move.l portPixMap(a0),screenMap ; ; ... do I get a PICT2 file, albeit an empty one. ; ... In the other two cases, I get just a PICT file. ; ;SIGH !! ; ------------------------------ ; 2) Switching color on & off on the fly, that is, changing the MODE: ; following was deduced from the “Cards and Drivers ...” book. ; This book is supposed to be official stuff from Apple, yet ; MacDTS fails to respond in other than purely qualitative prose. ; ; All my code does is turn video to a constant gray all over ; as if I had turned the video OFF. All further execution ceases !! ; No bomb, but I must re-boot. ; My calling stuff: origModeinteger ; My globals paramBlkRec byte ioFQElSize ; ... VDPgInfobyteVDPageInfo ; ... clr.w -(sp) bsr TestForColor pop.w d0 beq.s .notColor ; ---------- ; Save the current mode for reseting when done ; and then set to black-and-white: .itsColor clr.w -(sp) ; result = Error code. push.l MainDevice pea paramBlkRec; VARed ... pea VDPgInfo bsr GetMode lea VDPgInfo,a1 move.w csMode(a1),origMode ; ... for reseting later. pop.w d0 bsr testError ; Returns if d0 <> 0. ; ---------- clr.w -(sp) push.l MainDevice push.w #oneBitMode; ... for black-and-white. bsr SetDeviceMode pop.w d0 bsr testError .notColor ; etc .onExitingclr.w -(sp) bsr TestForColor pop.w d0 beq.s .byeBye ; ---------- ; Reset the mode to its original value: .resetColor clr.w-(sp) push.l MainDevice push.w .origMode bsr SetDeviceMode pop.w d0 bsr .testError .byeBye ; etc ; All my subroutine children: ; ====================================== ; FUNCTION TestForColor : BOOLEAN; ; Test for the presence of a Mac with Color QuickDraw AND a Color ; Monitor that the user has set to Color via the Control Panel ; or by using the “Switch-A-Roo” FKEY: TestForColorfunc boolean noParms locals .theWorld byte sysEnv1Size; Mac II stuff. endLocals enter movem.ld1-d7/a0-a5,-(sp) ; Save all your pennies !! ; ========== clr.w .result ; Assume NO color = B&W. move.w #1,d0 ; Version #1. lea .theWorld,a0 _SysEnvirons tst.w d0 bne.s .notColor ; ---------- .noErrortst.b hasColorQD(a0) ; A0 --> theWorld. beq.s .notColor ; ---------- GetGDevice =a1 ; Handle --> move.l (a1),a1 ; Pointer. move.l gdPMap(a1),a0; Ditto ... move.l (a0),a0 cmpi.w #1,pmPixelSize(a0) beq.s .notColor .color st.result ; ---------- .notColor ; ========== .end movem.l (sp)+,d1-d7/a0-a5 ; Withdraw life savings !! exit ; ====================================== ; FUNCTION WhereIsTheDevice (whatDevice: GDHandle) : dceHandle; ; Slot #, Slot ID, etc ?? WhereIsTheDevice funchandle .whatDevice handle endParms noLocals .devRefNumrequ d1 enter movem.ld1-d7/a0-a5,-(sp) ; Save your goodies !! ; ========== clr.l .result ; Assume nowhere !! move.l .whatDevice,a0 move.l (a0),a0 ; Handle --> Pointer. move.w gdRefNum(a0),.devRefNum ; tst.w.devRefNum beq.s .end; Nowhere !! ; ---------- not.w .devRefNum ; = Unit # lsl.w #2,.devRefNum; 4 bytes per entry. move.l UTableBase,a1; --> DCE Table. move.l (a1,.devRefNum),.result ; = dceHandle. ; ========== .end movem.l (sp)+,d1-d7/a0-a5 ; Dig up your treasure !! exit ; ====================================== ; FUNCTION GetMode (whatDevice: GDHandle; VAR paramBlk: paramBlkRec; ; VAR VDPgInfo: VDPgInfoRec) : INTEGER; ; csMode, csPage, etc ?? GetMode funcinteger; Error code. .whatDevice handle .paramBlk var .VDPgInfo var endParms noLocals .paramBlkPtrrequ a0 .dceHandlerequ a1 .dcePtr requa1 enter movem.ld1-d7/a0-a5,-(sp) ; Save your goodies !! ; ========== move.w #-1,.result; Assume a problem. move.l .paramBlk,.paramBlkPtr; A Pointer. move.l #ioFQElSize-1,d0 .clearBlk1clr.b (.paramBlkPtr)+ dbra d0,.clearblk1 ; ---------- move.l .VDPgInfo,a2 ; Another Pointer. move.l #VDPageInfo-1,d2 .clearBlk2clr.b (a2)+ dbra d2,.clearBlk2 clr.l -(sp) ; FUNCTIONal result. push.l .whatDevice bsr WhereIsTheDevice pop.l .dceHandle cmpi.l #0,.dceHandle beq.s .end; Oh-Oh !! move.l (.dceHandle),.dcePtr ; ---------- move.l .paramBlk,.paramBlkPtr; Reset. ; clr.lioCompletion(.paramBlkPtr) move.w dCtlRefNum(.dcePtr),ioRefNum(.paramBlkPtr) ; move.b #fsCurPerm,ioPermssn(.paramBlkPtr) ; = 0 ; clr.lioMix(.paramBlkPtr) ; clr.wioFlags(.paramBlkPtr) move.b dCtlSlot(.dcePtr),ioSlot(.paramBlkPtr) move.b dCtlSlotID(.dcePtr),ioID(.paramBlkPtr) move.w #cscGetMode,csCode(.paramBlkPtr) move.l .VDPgInfo,csParam(.paramBlkPtr) ; VARed. _Status,immed move.w d0,.result ; ========== .end movem.l (sp)+,d1-d7/a0-a5 ; Dig up your treasure !! exit ; ====================================== ; FUNCTION SetMode (whatDevice: GDHandle; paramBlk: paramBlkPtr; ; VDPgInfo: VDPgInfoPtr) : INTEGER; ; ; csMode, csPage, etc !! SetMode funcinteger; Error code. .whatDevice handle .paramBlk pointer .VDPgInfo pointer endParms noLocals .paramBlkPtrrequ a0 .dceHandlerequ a1 .dcePtr requa1 enter movem.ld1-d7/a0-a5,-(sp) ; ========== clr.l -(sp) ; FUNCTIONal result. push.l .whatDevice bsr WhereIsTheDevice pop.l .dceHandle cmpi.l #0,.dceHandle bne.s .setNewMode; Everything’s cool !! .itsNowhere move.w #-1,d0 bra.s .ohOh ; ---------- .setNewMode move.l (.dceHandle),.dcePtr move.l .paramBlk,.paramBlkPtr move.w #cscSetMode,csCode(.paramBlkPtr) move.l .VDPgInfo,csParam(.paramBlkPtr) _Control,immed .ohOh move.wd0,.result ; ========== .end movem.l (sp)+,d1-d7/a0-a5 exit ; ====================================== ; FUNCTION SetDeviceMode (whatDevice: GDHandle; mode: INTEGER) : INTEGER; ; ; Set the specified Device to a particular color mode: SetDeviceMode funcinteger; Error code. .whatDevice handle .mode integer endParms locals .paramBlkRecbyte ioFQElSize .VDPgInfo byte VDPageInfo endLocals .paramBlkPtrrequ a0 .dceHandlerequ a1 .dcePtr requa1 enter movem.ld1-d7/a0-a5,-(sp) ; ========== .getOldStuffclr.w-(sp) ; result = Error code. push.l .whatDevice pea .paramBlkRec ; VARed ... pea .VDPgInfo bsr GetMode pop.w d0 bne.s .ohOh .whereInThe?clr.l-(sp) ; FUNCTIONal result. push.l .whatDevice bsr WhereIsTheDevice pop.l .dceHandle cmpi.l #0,.dceHandle bne.s .setGray ; Everything’s cool !! .itsNowhere move.w #-1,d0 bra.s .ohOh ; ---------- .setGraymove.l (.dceHandle),.dcePtr; Recommended middle step. lea .paramBlkRec,.paramBlkPtr move.w #cscGrayPage,csCode(.paramBlkPtr) lea .VDPgInfo,a2 move.l a2,csParam(.paramBlkPtr) _Control,immed tst.w d0 ; bne.s.ohOh ; This call is optional. .setNewMode clr.w-(sp) ; Error code. push.l .whatDevice pea .paramBlkRec lea .VDPgInfo,a1 move.w .mode,csMode(a1) ; Change the mode. pea .VDPgInfo bsr SetMode pop.w d0 .ohOh move.wd0,.result ; ========== .end movem.l (sp)+,d1-d7/a0-a5 exit
Onstad’s Answer
Flashpoint
San Francisco, CA
Paul Onstad’s question in the August 1989 issue of MacTutor on page 4: you must do a CreateResFile() after the Create to add the resource map data to the resource fork. [Note: you must Create FIRST, CreateResFile SECOND.]
Segmented XCMD Problem Solved
Peter B. Nagel
Denver, CO
With several gentle nudges from various helpful persons on CompuServe, I was able quite successfully to implement a solution in HyperTMON to the segmented XCMD problem that three individuals described in the Mousehole Report column in your August issue.
MPW’s -ss linker option will allow the creation of XCMD segments well in excess of the normal 32k limit on the intra-code segment addresses. Through a judicious resorting of my linked modules, I was able to create XCMDs approaching 38k. To enlarge an XCMD beyond that limit, however, I found that it was necessary, and certainly possible, to segment XCMDs through the use of separate code resources.
To do this, create and link a separate code resource whose entry point jumps to a case statement that branches to the appropriate procedures and functions in the resource. Then define a parameter block with sufficient fields to hold all the possible parameters that could be passed to all the procedures and functions in that code resource. From within the XCMD, then, you can include the following code (minus appropriate error checking) to retrieve the separate code resource, initialize the parameter block, and jump to you external code:
Procedure JumpToNewCode(paramBlkHndl: paramHndl; procAddress: Ptr); InLine $205F, { MOVE.L (A7)+, A0; address of procedure} $4E90, { JSR (A0); jump to procedure} Procedure CallNewCode(selector: integer; param1: integer; param2: longint; param3: Ptr; Var param4: Handle; Var param5: Boolean); Var paramBlkHndl : paramHndl; codeAddr : Handle; Begin {Procedure CallNewCode} codeAddr := GetResource(‘CODE’, 1234); MoveHHi(codeAddr); HLock(codeAddr); paramBlkHndl := NewHandle(sizeof(paramHndl)); with paramBlkHndl^^ do begin {fill in parameters} end; JumpToNewCode(paramBlkHndl, StripAddress(codeAddr^)); HUnlock(codeAddr); HPurge(codeAddr); with paramBlkHndl^^ do begin {return Var values} end; DisposHandle(paramBlkHndl); end; {Procedure CallNewCode}
At one time, it appeared that, when memory became really tight, HyperCard may have been unceremoniously disposing of my code resources, and so I ended up calling BlockMove to place them in nonrelocatable blocks, since I needed them around at all times. I am still not sure that it wasn’t my own fault, but I would be interested in knowing if any of your readers have had a similar problem.
- SPREAD THE WORD:
- Slashdot
- Digg
- Del.icio.us
- Newsvine