Oct 89 Letters
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
Im 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 Im 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.
;
; Ive 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 doesnt bomb, but the file comes up blank, that is, just
; ... the 512-byte header + those 10 bytes and nothing else.
; ... I think its 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; Everythings 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 ; Everythings 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
Onstads Answer
Flashpoint
San Francisco, CA
Paul Onstads 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.
MPWs -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 wasnt my own fault, but I would be interested in knowing if any of your readers have had a similar problem.