Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
CLUTSample.inc1.a
* |
* Apple Macintosh Developer Technical Support |
* |
* CLUTSample |
* |
* CLUTSample.inc1.a - Assembler Source |
* |
* |
* Loosely based in the sample SAMPLE this program shows |
* how to create a window and display on it the colors of the CLUT |
* associated with the device the window sits on top of. |
* |
* Left to the curious reader are some improvements such as, remembering the |
* positions of each open window, so if you use this program to monitor your |
* color tables it will position the windows in the last place you opened them. |
* The treatment of direct devices is kind of 'casual' a better color display may |
* be appropriate. Last, it may be desireable to change the size of the color |
* rectangles depending on the depth of the color table. |
* Check Sample sources for more detailed documentation. |
* ----------- DEBUGGING INFORMATION ------------- |
* This is used as a global switch to turn off the generation of debugging information. |
* The MACRO "DbgInfo" will generate this debugging information if set to 1. |
DebuggerInfo EQU 1 |
* ================================================ |
* -------- MACRO DEFINITIONS SECTION ---------- |
* ================================================ |
* ------------- GENERATE A PASCAL "CASE" OR "IF" SEQUENCE ------------- |
* The following macro is used to generate a branch based on an index value |
* in a D-register with a value from 0 to N. The branch is through a table |
* of relative addresses also generated by this macro. The macro is called |
* in one of two forms as follows: |
* {Form #1} Case# (Dreg,Default),case0,case1,...caseN |
* {Form #2} Case#.<size> (Dreg,IF),(cst0,case0),...,(cstN,caseN) |
* In Form #1, the "Default" specifies a label for any omitted case labels not |
* specified explicitly. The "case0", "case1",..."caseN" are case labels |
* identifying the various cases to be processed. A case label may be omitted, |
* in which case the "Default" is used. The "Default" may also be omitted, but |
* in that case all case labels must be specified. If there are fewer case labels |
* than there are cases, but there are N possible values for the case index, the |
* proper number of trailing commas must be supplied to generate the defaults. |
* In Form #2, the default is specified as the word "IF". In this form the macro |
* generates a set of compares (CMPI's) and branches (BEQ) for each specified |
* case (there is no implicit default). Each case is a constant/label pair. |
* The constant is compared (CMPI.W) and an branch is done (BEQ) to the case if |
* the Dreg equals the constant. A size may be specified for all the branches |
* as a <size> attribute to the Case# call itself. This must either be an "S" |
* or "W" to generate BEQ.S's or BEQ.W's. The default is for "S". |
MACRO |
Case#.&Size &IdxDef |
PRINT Push,NoMDir ; only list generated code |
LCLA &i ; index to macro parameters |
LCLA &n ; total number of macro parameters |
LCLC &Dreg,&Def ; the Dreg and Default parameters |
LCLC &sz ; the <size> value |
&Dreg SETC &IdxDef[1] ; pick off 1st opnd of sublist |
&Def SETC &IdxDef[2] ; pick off 2nd opnd of sublist |
&n SETA &Nbr(&Syslist) ; done for efficiency |
&i SETA 2 ; cases start at 2nd parameter |
IF &UpCase(&Def) <> 'IF' THEN |
.* Create the jump table and the index value |
* ----------------------------------------------- |
ADD &Dreg,&Dreg |
MOVE Case&SysNdx(&Dreg),&Dreg |
JMP Case&SysNdx(&Dreg) |
Case&SysNdx |
WHILE &i <= &n DO ; process each case label |
IF &SysList[&i] <> '' THEN |
DC.W &SysList[&i]-Case&SysNdx |
ELSE |
DC.W &Def-Case&SysNdx |
ENDIF |
&i: SETA &i+1 ; count off parameter |
ENDWHILE |
ELSE ; process (Cst,lbl) pairs |
.* Create a series of CMPI and BEQ instructions |
* ----------------------------------------------- |
&Sz: SETC &Default(&Size, 'S') ; setup size attribute |
WHILE &i <= &n DO ; process each (Cst,lbl) pair |
CMPI #&SysList[&i,1],&Dreg |
BEQ.&Sz &SysList[&i,2] |
&i: SETA &i+1 ; count off parameter |
ENDWHILE |
ENDIF |
PRINT Pop ; restore original print status |
ENDM |
* ------------- GENERATE DEBUGGER SYMBOL INFORMATION ------------- |
* This Macro will generate information for the debugger to read and display |
* as its module name. This aids in debugging Asm code while looking at it |
* in the debugger. This macro can only work if called at the end of stack |
* frame. The appearance of the Macro statement in the source code must occur |
* immediately after the final "JMP (A0)" or "RTS" instruction following the UNLINK. |
* Spaces may be included in the name, but no quotes are allowed. |
* {Form #1} DbgInfo ModName |
* {Form #2} DbgInfo.New Really Long Module Name For MacsBug 6.0 |
* There are now two naming conventions used in MacsBug, Form #1 is the older MacsBug, |
* or TMON, and Form #2 is the newer MacsBug 6.0. The older method would only |
* allow for a fixed length of eight characters. If a shorter name is passed to |
* this Macro, it will extend the length to 8 chars with trailing spaces. |
* MacsBug 6.0 will now allow for a variable length C type string. This Macro will |
* create the proper DC statements and takes into account word alignment issues. |
MACRO |
DbgInfo.&Opt &ModName# ; the name to be used in the Debugger |
PRINT Push,NoMDir ; Only list generated code |
LCLC &DbgName# ; name to generate for MacsBug |
LCLC &DbgTemp ; temporary name variable |
LCLC &New ; variable used to test old vs. new |
LCLC &S ; variable used to save PRINT state |
IF DebuggerInfo THEN ; do we want debugging info? |
IF &ModName# '' THEN ; did we get a module name? |
&New: SETC &UpCase(&Opt) ; make option all upper case |
IF (&New = 'NEW') THEN ; do we want new style? |
.* Create the new MacsBug naming convention |
* ----------------------------------------------- |
&DbgTemp: SETC &ModName# ; generate new type symbols |
IF &Len(&ModName#) < 32 THEN ; if module name < 32 chars |
IF &Len(&ModName#) // 2 = 0 THEN ; add space if even so that... |
&DbgTemp: SETC &Concat(&ModName#,' ') ; string length plus length byte... |
ENDIF ; will align to word boundary |
&DbgName#: SETC &Concat(&Chr($80 + &Len(&ModName#)), &DbgTemp) |
ELSE ; Length > 32 characters |
IF &Len(&ModName#) // 2 = 1 THEN ; add space if length is odd |
&DbgTemp: SETC &Concat(&ModName#,' ') |
ENDIF |
&DbgName#: SETC &Concat(&Chr($80), &Chr(&Len(&ModName#)), &DbgTemp) |
ENDIF |
ELSE ; make it the older style |
.* Create the older MacsBug naming convention |
* ----------------------------------------------- |
IF &Len(&ModName#) < 8 THEN ; if module name < 8 chars |
&DbgName#: SETC &Concat(&ModName#,' ') ; add at least 7 spaces |
&DbgName#: SETC &Concat(&Chr($80 + &ORD(&SubStr(&DbgName#,1,1))), &SubStr(&DbgName#,2,7)) |
ELSE ; there are at least 8 chars |
&DbgName#: SETC &Concat(&Chr($80 + &ORD(&SubStr(&ModName#,1,1))), &SubStr(&ModName#,2,7)) |
ENDIF |
ENDIF |
.* Create the DC.B with the debugger name, and include the NULs if new MacsBug option |
* ----------------------------------------------- |
&S: SETC &Setting('STRING') ; preserve STRING status |
IF &S 'ASIS' THEN ; only change it if not already ASIS |
STRING ASIS |
DC.B '&DbgName#' |
IF (&New = 'NEW') THEN |
DC.W 0 ; fake literal size for new MacsBug |
ENDIF |
STRING &S |
ELSE |
DC.B '&DbgName#' |
IF (&New = 'NEW') THEN |
DC.W 0 ; fake literal size for new MacsBug |
ENDIF |
ENDIF |
ENDIF |
ENDIF |
PRINT Pop ; restore original print status |
ENDM |
* ================================================ |
* --------------- EQUATE SECTION --------------- |
* ================================================ |
* Some various EQUATES we'll use throughout the program. |
* ----------------------------------------------- |
False EQU 0 ; the value of False |
True EQU $0100 ; and you thought True = 1, HA! |
NIL EQU 0 ; a NIL pointer to test against |
ToolTrapBit EQU 11 ; this bit is on for Tool traps |
WaitNextEvent EQU $A860 ; the WaitNextEvent trap number |
Unimplemented EQU $A89F ; the Unimplemented trap number |
EnvironsVersion EQU 1 ; this is the version of the SysEnvirons we want |
SleepValue EQU $7FFFFFFF ; the sleeping time ($7FFFFFFF = MaxLongInt) |
SuspendResume EQU 1 ; the suspend/resume event number of an OSEvent |
NoEvents EQU 0 ; no events mask |
ExtremeNeg EQU -32768 ; for wide open rects and regions, see AdjustCursor |
ExtremePos EQU 32767-1 ; -1 is because of a bug in regions, see AdjustCursor |
* This is the minimum result from the following equation: |
* applLimit - applZone = minimum heap size |
* for the application to run. It will insure that enough memory will |
* be around for reasonable-sized scraps, FKEYs, etc. to exist with the |
* application, and still give the application some 'breathing room'. |
* To derive this number, we ran under a MultiFinder partition that was |
* our requested minimum size, as given in the 'SIZE' resource. |
MinHeap EQU 21*1024 ; minimum heap size in bytes |
* This is the minimum exceptable result from PurgeSpace, when called |
* at initialization time, for the application to run. This number acts |
* as a double-check to insure that there really is enough memory for the |
* application to run, including what has been taken up already by |
* pre-loaded resources, the scrap, code, and other sundry memory blocks. |
MinSpace EQU 8*1024 ; minimum stack space in bytes |
* The following equates use for resources. That's why they have a "r" in front. |
* ----------------------------------------------- |
rMenuBar EQU 128 ; application's menu bar |
rUserAlert EQU 129 ; error alert for user |
rWindow EQU 128 ; application's window |
rAboutAlert EQU 128 ; about alert |
* The following equates are for menu definitions, obviously. |
* ----------------------------------------------- |
AppleMenu EQU 128 ; Apple menu |
AboutItem EQU 1 |
FileMenu EQU 129 ; File menu |
NewItem EQU 1 |
CloseItem EQU 2 |
QuitItem EQU 4 |
* ----------------------------------------------- |
DITopLeft EQU $00500070 ; position of Disk Init dialogs |
* ================================================ |
* ---------------- RECORD TYPES ---------------- |
* ================================================ |
* This section is declaring record structures. These records are |
* templates. No data is allocated at this point. These are just |
* structures, similar to Pascal TYPEs. They simply generate a list |
* of equate offsets. Since none of these types are defined already |
* in the MPW AIncludes, we'll need to define them. |
* ------------- MOUSE POINT TYPE ------------- |
Point RECORD 0 |
v DS.W 1 |
h DS.W 1 |
ORG v |
vh DS.W h |
ENDR |
* ------------- RECTANGLE TYPE ------------- |
Rect RECORD 0 |
Top DS.W 1 |
Left DS.W 1 |
Bottom DS.W 1 |
Right DS.W 1 |
ORG Top |
TopLeft DS.L 1 |
BotRight DS.L 1 |
ENDR |
* ------------- BITMAP TYPE ------------- |
BitMap RECORD 0 |
baseAddr DS.L 1 |
rowBytes DS.W 1 |
bounds DS.L Rect |
ENDR |
* ------------- EVENT RECORD TYPE ------------- |
EventRecord RECORD 0 |
What DS.W 1 |
Message DS.L 1 |
When DS.L 1 |
Where DS.L Point |
Modify DS.W 1 |
ENDR |
* ------------- THE QUICKDRAW WORLD ------------- |
MyQDGlobals RECORD 0,DECREMENT |
thePort DS.L 1 |
White DS.B 8 |
Black DS.B 8 |
Gray DS.B 8 |
LtGray DS.B 8 |
DkGray DS.B 8 |
Arrow DS.B cursRec |
ScreenBits DS.B BitMap |
RandSeed DS.L 1 |
ORG -GrafSize |
ENDR |
* ------------- ALL OF OUR GLOBAL DATA ------------- |
* Note the minimal amount of globals we're using. Data such as |
* the EventRecord, WindowRecords, etc. do not belong in global data |
* allocation. Only data that basically doesn't change through out the |
* execution of the program is considered global. The boolean flags are |
* global, since they affect the state of the program at any given time. |
* Also note that any appearance of a DS outside of a stack frame will |
* be allocated off of A5 and becomes part of global data storage. |
AppGlobals RECORD 0 ; this is our global data storage |
Stopped DS.W 1 ; boolean for the state of the light |
HasWNEvent DS.W 1 ; boolean for WaitNextEvent trap, see ForceEnvirons |
InBackground DS.W 1 ; boolean for if in background, see OSEvent |
StopRect DS Rect ; rect for the Stop light, set from a resource |
GoRect DS Rect ; rect for the Go light, set from a resource |
Mac DS SysEnvRec ; the system environment record, see ForceEnvirons |
ENDR |
* ------------- CLUT Window Data TYPEs ------------- |
ClutWData RECORD 0 |
UpdateRtn DS.L 1 |
MouseDnRtn DS.L 1 |
ClutWDataSize Equ * |
ENDR |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14