home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1986
/
11
/
katz.nov
< prev
next >
Wrap
Text File
|
1986-12-01
|
25KB
|
1,285 lines
Listing One
; < MandelZoom.ASM > Sat 30 Nov '85 h. katz
; Sun 4 May '86
INCLUDE MacTraps.D
String_Format 3 ; pre-length DC.B and PEA Strings
XREF Convert_2_Fixed_Point ; Procedure defined in < Str2FP.ASM >
MACRO Fix_Squared Rn = ; a Mac-style macro
clr.l -(sp) ; ( Mac-Mac ? )
move.l {Rn}, -(sp)
move.l {Rn}, -(sp)
_FixMul
move.l (sp)+, {Rn} |
MouseDown EQU 1 ; for _GetNextEvent
numToString EQU 0 ; for _Pack7 conversions
stringToNum EQU 1
Gray EQU -24 ; offset from QDVars Ptr
White EQU -8
portRect EQU 16 ; offset from start of Window Record
pnPat EQU 58 ; offset from start of Window Record
X_Screen_Offset equ 4
Y_Screen_Offset equ 4
Row_Pixels equ 256
Col_Pixels equ 256
PenSize equ 2
HiLite_Off equ 0
HiLite_On equ 1
Radio_Item_1 equ 9
Radio_Item_2 equ 10
Radio_Item_3 equ 11
X_Org_Item equ 12 ; Item Numbers in Params DITL
Y_Org_Item equ 13
Side_Length_Item equ 14
Count_Item_1 equ 15
Org_Spacing equ 24 ; Space tween X, Y, and S
Max_Count_Digits equ 4 ; Num Digits in 'Count' Item Strings
Count_Str_X equ 5 ; X_coord of Counts
Count_Str_Y equ 114 ; Y_coord of 1st ( Max ) Count
Count_Str_Size equ 10 ; Bytes wide
Legend_Plot_Item equ 1
Legend_Quit_Item equ 2
Pattern_Spacing equ 30 ; Delta-Y for both Counts & Patts
Pattern_X equ 62 ; Left for Patts in Legend DLOG
Pattern_Y equ 86 ; Top for 1st Patt in Legend DLOG
Pattern_Size equ 8 ; Bytes
X_Org_Scr_X equ 10
X_Org_Scr_Y equ 24
Time_Scr_X equ 10
Time_Scr_Y equ 16
st First_Entry(A5)
sf Radio_1_State(A5)
st Radio_2_State(A5) ; default Pen is 2 X 2
sf Radio_3_State(A5)
BSR InitManagers
BSR Save_Mouse_State
BSR Draw_Menu_Title
MainLine
BSR Open_Params_DLOG
tst.b First_Entry(A5)
BNE.s @Set_Radios
BSR Reload_DITL ; 2nd time around -
; get old Parameters
@Set_Radios
sf First_Entry(A5)
BSR Set_Radio_Buttons
BSR Get_Param_Items ; Get User Choice / if OK, Toggle Radio
; Buttons, Convert & Save Counts
bMI Exit_To_Shell
BSR Save_Param_Items ; Save Str Counts / Convert 3 Fix-Pt Nums
pea paramsDLOGStorage
_CloseDialog
BSR Draw_Mandel_Window
BSR Open_Legend_DLOG
BSR Draw_Patterns
BSR Draw_Org_Strings
BSR Timer_On
BSR Do_Mandelbrot
bMI Exit_To_Shell ; These 2 in case we've interrupted
bHI Do_Another ; plotting in the middle
BSR Timer_Off
BSR Write_Time
Wait_4_Command
BSR Get_Next_Event
bEQ Wait_4_Command ; No Event
BSR Was_Dialog_Event
bEQ Wait_4_Command ; 0 => Hang Around a Bit
bMI Exit_To_Shell ; - => Quit
; + => do another
Do_Another
pea MandelWindStorage
_CloseWindow
pea LegendDLOGStorage
_CloseDialog
BRA MainLine
Exit_To_Shell
_ExitToShell
Save_Mouse_State ; if the Mouse is Down on Launch, we'll
; _SetPat and _Line for EVERY Point
sf Mouse_Down(A5)
clr -(sp)
_Button
tst (sp)+
beq @rts
st Mouse_Down(A5)
@rts RTS
Draw_Menu_Title
move.l #$000F0010, -(sp)
_MoveTo
pea MBarTitle
_DrawString
RTS
Reload_DITL
lea TempStr, A2
move #0, D3
move #X_Org_Item, D4
BSR Get_Item_Text
move.l ItemHandle, -(sp)
pea X_Org_Str
_SetIText
move #Y_Org_Item, D4
BSR Get_Item_Text
move.l ItemHandle, -(sp)
pea Y_Org_Str
_SetIText
move #Side_Length_Item, D4
BSR Get_Item_Text
move.l ItemHandle, -(sp)
pea Side_Length
_SetIText
lea TempStr, A2
lea Count_Strings, A3
move #0, D3
move #Count_Item_1, D4
@Reset_Counts
BSR Get_Item_Text
move.l ItemHandle, -(sp)
move.l A3, -(sp) ; Addr of Current Count_String
_SetIText
add.l #Count_Str_Size, A3
add #1, D4 ; next Item Number in DLOG
add #1, D3 ; increment loop counter
cmp #4, D3 ; done all 4 ?
BMI @Reset_Counts ; no
RTS
Get_Next_Event
clr -(sp)
move #-1, -(sp)
pea EventRecord
_GetNextEvent
tst.b (sp)+
RTS
Was_Dialog_Event
clr.b -(sp)
pea EventRecord
_IsDialogEvent
tst.b (sp)+ ; EQ = No Event
bNE.s @1 ; NE = Was DLOG Event
RTS
@1 clr.b -(sp)
pea EventRecord
pea theDialog
pea ItemHit
_DialogSelect
tst.b (sp)+
bNE.s Get_Legend_DLOG_Item
clr.b -(sp)
pea EventRecord
pea ParamsDLOGStorage
pea ItemHit
_DialogSelect
tst.b (sp)+
move #0, D0
RTS
Get_Legend_DLOG_Item
move ItemHit, D0
cmp #Legend_Plot_Item, D0
bEQ @Return_Plus
cmp #Legend_Quit_Item, D0
bEQ @Return_Minus
move #0, D0
RTS
@Return_Minus ; = Quitting
move #-1, D0
RTS
@Return_Plus ; = Do Another Mandelbrot
move #1, D0
RTS
Timer_On
clr.l -(sp)
_TickCount
move.l (sp)+, Start_Time(A5)
RTS
Timer_Off
_PenNormal
move #4, -(sp) ; Wake the Poor User
_SysBeep
clr.l -(sp)
_TickCount
move.l (sp)+, D3
sub.l Start_Time(A5), D3 ; ( Stop - Start ) in Ticks
divu #60, D3 ; Num_Seconds (in Low Word)
RTS
MenuRect dc 0, 10, 19, 200
Write_Time
pea MandelWindStorage
pea TempSTR
_GetWTitle
lea TempSTR, a2
move.l a2, a3 ; save start addr
clr.l d5 ; clear out old junk
move.b (a2)+, d5 ; Length Byte
adda.l d5, a2 ; point past last Char in Str
lea ' : ', a0 ; addr of length byte
clr.l d1
move.b (a0)+, d1 ; save new length
add.b d1, d5
move.b d5, (a3) ; put back new length byte
sub #1, d1
@Loop_1
move.b (a0)+, (a2)+ ; add new string to end
dbra d1, @Loop_1
move.b -(a2), d4 ; save last char
ext.l D3 ; Elapsed Time in seconds
move.l D3, D0
move.l a2, a0
move #NumToString, -(sp)
_Pack7
clr.l d1
move.b (a2), d1 ; save New Length Byte
move.b d4, (a2) ; restore last Char of 1st String
add.b d1, d5 ; new length
move.b d5, (a3) ; and put back in Length Byte
adda.l d1, a2 ; point to end of string
adda.l #1, a2 ; points 1 past end
lea ' seconds', a1
move.b (a1)+, d1 ; save new Length Byte
ext.w d1
add.b d1, d5 ; new total Length of Strings
move.b d5, (a3) ; put it back in Length Byte
@Loop_2
move.b (a1)+, (a2)+ ; append 'Seconds' to end
sub #1, d1
bhi @Loop_2
pea MandelWindStorage
pea TempSTR
_SetWTitle
RTS
Do_Mandelbrot
pea MandelWindStorage
move.l (sp), -(sp) ; copy WPtr for _SetWTitle trap
_SetPort ; draw in this Window
tst.b Radio_1_State(A5)
beq.s @1
pea '1 X 1'
bra @SetTitle
@1 tst.b Radio_2_State(A5)
beq.s @2
pea '2 X 2'
bra.s @SetTitle
@2 pea '4 X 4'
@SetTitle
_SetWTitle
@Set_Pen_Size
move #PenSize, D3
tst.b Radio_2_State(A5) ; Draw with 2 X 2 Pen ?
BNE @Set_Pen ; yes
add D3, D3 ; Pen = 4 X 4
tst.b Radio_3_State(A5) ; Draw with 4 X 4 ?
BNE @Set_Pen ; yes
move #1, D3 ; Draw with 1 X 1
@Set_Pen
move D3, Pix_Per_Pt(A5)
move D3, -(sp)
move (sp), -(sp)
_PenSize
@Set_Plot_Size
lea MandelWindStorage, a0
move portRect+4(a0), d4 ; Window.Bottom
move #Y_Screen_Offset, d0
sub d0, d4 ; frame at Bott
sub d3, d4 ; move up 1 PenSize from Bott
move d4, Y_Start(a5)
sub d0, d4 ; adjust for frame at Top
move d4, Num_Rows(a5)
move portRect+6(a0), d4 ; Window.Right
move #X_Screen_Offset, d0
asl #1, d0 ; frame at Left & Right
sub d0, d4
sub d3, d4 ; allow for penWidth
move d4, Num_Cols(a5)
@Get_C_Increment
move.l Y_side(A5), D0
move Num_Rows(A5), D5
ext.l d5
divu Pix_Per_Pt(A5), D5 ; = # of Plottable Pts on Y-Axis
BSR Get_Del_Factor ; Del_Y returned as Fixed Pt
move.l D4, Del_C_imag(A5) ; in D4
clr.l -(sp)
move Num_Cols(a5), -(sp) ; numerator
move Num_Rows(a5), -(sp) ; denominator
_FixRatio ; Fixed-Pt Ratio on stack
move.l (sp)+, d0 ; temp save it
clr.l -(sp)
move.l d0, -(sp) ; Num_Cols/Num_Rows
move.l Y_Side(a5), -(sp) ; x Y_Side
_FixMul ; --------
move.l (sp)+, X_Side(a5) ; = X_Side
move.l X_Side(A5), D0
move Num_Cols(A5), D5
ext.l d5
divu Pix_Per_Pt(A5), D5 ; = # of Plottable Pts on X-Axis
BSR Get_Del_Factor
move.l D4, Del_C_Real(A5)
BRA Continue
Get_Del_Factor
move.l D0, D3 ; save the fractional part
swap D0 ; and get the whole part
clr.l -(sp)
move D0, -(sp) ; side ( integer part )
move D5, -(sp) ; pts per side
_FixRatio ; = length ( integer ) / point
move.l (sp)+, D4 ; save the ( int ) fraction
sf D6 ; positive fraction
tst D3
bpl @1
st D6 ; negative fraction
lsr #1, D3 ; zero the hi bit so _FixRatio doesn't
; think the number is Negative
@1 clr.l -(sp)
move D3, -(sp) ; side ( fract part )
move D5, -(sp) ; pts per side
_FixRatio ; = length ( fract ) / point
move.l (sp)+, D3
swap D3 ; move the 'integer' part of the 'fraction'
tst.b D6 ; back into the fractional lo word
bpl @2
lsl #1, D3 ; restore the 'negative' hi bit
@2 and.l #$FFFF, D3
add.l D3, D4
RTS
Continue
clr Row_Count(A5)
move.l Y_Origin(A5), C_Imag(A5)
move Y_Start(a5), Y_Current(A5)
Do_Next_Row
clr Col_Count(A5)
move #X_Screen_Offset, -(sp) ; For next row
move Y_Current(A5), -(sp) ; move absolute to start
_MoveTo
st First_Pt(A5) ; 1st_Point := TRUE;
move.l X_Origin(A5), C_Real(A5) ; for start of new row
BSR Do_Points
move Row_Count(A5), D0
add Pix_Per_Pt(A5), D0
move D0, Row_Count(A5)
cmp Num_Rows(A5), D0
bMI @CheckDLOG
move #0, d0
BRA @Return_To_Mainline
@CheckDLOG
BSR Get_Next_Event
bEQ.s @Setup_Next_Row
BSR Was_Dialog_Event
bEQ.s @Setup_Next_Row
@Return_To_Mainline
RTS
@Setup_Next_Row
move Pix_Per_Pt(A5), D0
sub D0, Y_Current(A5)
move.l C_imag(A5), D0 ; set up Y for next row
add.l Del_C_Imag(A5), D0
move.l D0, C_Imag(A5)
BRA.s Do_Next_Row
Do_Points
move.l C_Real(A5), D5 ; Initialize Z = C for new point
move.l C_Imag(A5), D6
move #1, Iter_Count(A5) ; Do up to Counts(A5) times per Point
lea Patterns, A4 ; reset Pattern Ptr
Iterate
move.l D5, D3 ; Save Current Z_Real
move.l D6, D4 ; Save Current Z_Imag
Fix_Squared D3 ; Z_Real^2
Fix_Squared D4 ; Z_Imag^2
move.l D4, D7
add.l D3, D7 ; Size^2 = Z_Real^2 + Z_Imag^2
@Test_Size
move Iter_Count(A5), D0
cmp.l #$40000, D7 ; Size^2 > 4 means TIME TO PLOT
BHI.s @Plot
@Test_Count
add #1, D0
move D0, Iter_Count(A5)
cmp Counts(A5), D0
BPL.s @Plot
@Get_New_Z
sub.l D4, D3 ; Z_Real = Z_Real^2 - Z_Imag^2
clr.l -(sp)
move.l D5, -(sp)
move.l D6, -(sp)
_FixMul
move.l (sp)+, D6 ; Z_Real * Z_Imag
add.l D6, D6 ; Z_Imag = 2 * Z_Real * Z_Imag
move.l D3, D5 ; Z_Real
add.l C_Real(A5), D5
add.l C_Imag(A5), D6
BRA.s Iterate
@Plot
BSR Get_Pattern ; A4 = Ptr to New Pattern
tst.b First_Pt(A5) ; IF NOT 1st_Point
BEQ @Test_Mouse ; Test_Mouse { see if batching }
sf First_Pt(A5) ; ELSE
; 1st_Point = FALSE;
move.l A4, A2 ; Old_Pat := New_Pat;
BRA @Set_Pattern
@Test_Mouse
tst.b Mouse_Down(A5) ; IF NOT Batch_Plot
BNE.s @Draw_Line ; Draw_Line ( Old_Pat )
cmp.l A2, A4 ; ELSE
BNE @Draw_Line ; IF NOT ( New_Pat = Old_Pat )
; Draw_Line ( Old_Pat )
; ELSE
; Init_Line_Amount;
add Pix_Per_Pt(A5), A3; Do_Next_Pt;
BRA @Skip_Draw
@Draw_Line
move A3, -(sp)
move #0, -(sp)
_Line ; Draw_Line ( Old_Pat )
@Set_Pattern
move.l A4, -(sp) ; set the New Pattern
_PenPat
move.l A4, A2 ; Old_Pat := New_Pat
move Pix_Per_Pt(A5), A3
@Skip_Draw
move Col_Count(A5), D0
add Pix_Per_Pt(A5), D0
move D0, Col_Count(A5)
cmp Num_Cols(A5), D0
BMI.s @Update_Z_Real
; we've finished the Line - if we need to draw to finish up
; do it here
cmp Pix_Per_Pt(A5), A3
BEQ @rts ; we've just drawn
move A3, -(sp) ; else draw what we didn't
move #0, -(sp)
_Line
@rts RTS
@Update_Z_Real
move.l C_Real(A5), D0
add.l Del_C_Real(A5), D0
move.l D0, C_Real(A5)
BRA Do_Points
Get_Pattern ; Point to a New PenPat, according to which
; Range the Iter_Count ( D0 ) falls in
cmp 0+Counts(A5), D0 ; >= Black
BPL.s @0
add #8, A4
cmp 2+Counts(A5), D0 ; >= DarkGray
BPL.s @0
add #8, A4
cmp 4+Counts(A5), D0 ; >= LtGray
BPL.s @0
add #8, A4
cmp 6+Counts(A5), D0 ; >= White
BPL.s @0
add #8, A4 ; < Gray
@0 RTS
Open_Params_DLOG
clr.l -(sp) ; space for funct result
move #100, -(sp)
pea ParamsDLOGStorage
move.l #-1, -(sp) ; in front of everything
_GetNewDialog
move.l (sp)+, d0
RTS
Set_Radio_Buttons
move #HiLite_On, D3
tst.b Radio_1_State(A5)
BPL @2
move #Radio_Item_1, D4
BRA HiLite_Control
@2 tst.b Radio_2_State(A5)
BPL @3
move #Radio_Item_2, D4
BRA HiLite_Control
@3 move #Radio_Item_3, D4
BRA HiLite_Control
HiLite_Control
pea ParamsDLOGStorage
move D4, -(sp) ; ItemNumber
pea ItemType
pea ItemHandle
pea ItemBox
_GetDItem
move.l ItemHandle, -(sp)
move D3, -(sp)
_SetCtlValue
RTS
Get_Param_Items
pea ParamsDLOGStorage ; Select 'X_Org' Parameter
move #X_Org_Item, -(sp) ; for Quick Replacement
move #0, -(sp)
move #32767, -(sp)
_SelIText
ModalDLOG
clr.l -(sp) ; no filterProc
pea ItemHit
_ModalDialog
move ItemHit, D0
tst D0
BEQ ModalDLOG
cmp #1, D0 ; Clicked 'OK' = We're Done Dialoging ?
BEQ Validate_Items ; yes - Validate & Convert numeric entries
cmp #2, D0 ; Clicked 'Quit' ?
BEQ Set_Exit_Flag ; yes - tell MainLine
cmp #Radio_Item_1, D0 ; Clicked a Radio Button for penSize ?
bMI ModalDLOG ; no - wait for 'OK' or 'Quit'
cmp #Radio_Item_3, D0
bHI ModalDLOG ; no - wait for 'OK' or 'Quit'
BSR Toggle_Radio_Buttons ; yes
BRA ModalDLOG ; and wait for 'OK' or 'Quit'
Set_Exit_Flag
move #-1, D0
RTS
Toggle_Radio_Buttons
move D0, D5 ; ( D0 gets trashed by ROM calls )
move #HiLite_Off, D3 ;
move #Radio_Item_1, D4 ; turn off Everything
BSR HiLite_Control
move #Radio_Item_2, D4
BSR HiLite_Control
move #Radio_Item_3, D4
BSR HiLite_Control
sf Radio_1_State(A5) ; Flag them as OFF
sf Radio_2_State(A5)
sf Radio_3_State(A5)
move #HiLite_On, D3 ; turn ON the Radio Item
move D5, D4 ; that was Clicked
BSR HiLite_Control
cmp #Radio_Item_1, D5 ; and Flag the apt Item
BNE @2 ; as ON
st Radio_1_State(A5)
RTS
@2 cmp #Radio_Item_2, D5
BNE @3
st Radio_2_State(A5)
RTS
@3 st Radio_3_State(A5)
RTS
Validate_Items
move #0, D3 ; Count - 1
lea Count_Strings, A2
move #Count_Item_1, D4 ; Item # of 1st Count (MaxCount)
@0 BSR Get_Item_Text ; get the next Item Text
BSR Convert_2_Int ; Convert theString to Integer
add #10, A2 ; point to next String
add #1, D4 ; and its Item Number
add #1, D3 ; for Next Count Range
cmp #4, D3 ; Done all 4 Count Ranges ?
BMI @0 ; not yet
RTS ; Return to MainLine
Get_Item_Text ; A2 points to the String
pea ParamsDLOGStorage ; DLOG Ptr
move D4, -(sp) ; Item Number
pea ItemType ; Not Used
pea ItemHandle ; passed to following ROM call
pea ItemBox ; Not Used
_GetDItem
move.l ItemHandle, -(sp)
move.l A2, -(sp)
_GetIText
RTS
Convert_2_Int
move.l A2, A0
move #StringToNum, -(sp)
_Pack7 ; Convert Count to Numeric
move D3, D5 ; Which Count Range ?
add D5, D5 ; Words => Bytes for Offset
lea Counts(A5), A0
move D0, 0(A0, D5) ; Index & Save the Count
; ( Ignore the Hi Byte )
RTS
Save_Param_Items
move #0, D3 ; D3 not used here
move #X_Org_Item, D4
lea X_Org_Str, A2 ; Following routine deposits
BSR Get_Item_Text ; DITL text in (A2)
; A2 (input) points to Decimal DITL String
; D0 (returned) contains Fixed-Point Conversion
BSR Convert_2_Fixed_Point ; XREF routine to convert from
move.l D0, X_Origin(A5) ; STR format to Fixed-Point
; format via SANE intermediary
move #Y_Org_Item, D4
lea Y_Org_Str, A2
BSR Get_Item_Text
BSR Convert_2_Fixed_Point
move.l D0, Y_Origin(A5)
move #Side_Length_Item, D4
lea Side_Length, A2
BSR Get_Item_Text
BSR Convert_2_Fixed_Point
move.l D0, Y_Side(A5)
RTS
Draw_Org_Strings
move #X_Org_Scr_X, -(sp)
move #X_Org_Scr_Y, D3
move D3, -(sp)
_MoveTo
pea 'X '
_DrawString
pea X_Org_Str
_DrawString
move #X_Org_Scr_X, -(sp)
add #Org_Spacing, D3
move D3, -(sp)
_MoveTo
pea 'Y '
_DrawString
pea Y_Org_Str
_DrawString
move #X_Org_Scr_X, -(sp)
add #Org_Spacing, D3
move D3, -(sp)
_MoveTo
pea 'S '
_DrawString
pea Side_Length
_DrawString
RTS
Open_Legend_DLOG
clr.l -(sp) ; space for Funct result
move #101, -(sp)
pea LegendDLOGStorage
move.l #-1, -(sp) ; in front of everything
_GetNewDialog
move.l (sp), -(sp)
_SetPort ; so Title prints
_SelectWindow ; so _DialogSelect works
RTS
Draw_Patterns
clr -(sp) ; Save Digit Char Width
move #'1', -(sp) ; in D4 for Right-Justifying
_CharWidth
move (sp)+, D4
move #Count_Str_Y, Legend_Y_Pos(A5)
move #0, D3
lea Count_Strings, A3 ; Addr of 1st Count Str
@Draw_Counts
move #Count_Str_X, -(sp)
move Legend_Y_Pos(A5), -(sp)
_MoveTo
cmp.b #Max_Count_Digits, (A3) ; Truncate STRs if too long
BMI @0
move.b #Max_Count_Digits, (A3)
@0 clr.l D0 ; Right-Justify Count_Strings
move #Max_Count_Digits, D0
clr D1
move.b (A3), D1 ; Byte Count for String
sub D1, D0 ; Del_Digits = Max_Digits - Actual Digits
mulu D4, D0 ; times Digit Char_Width
move.l D0, -(sp) ; = amount to space over
_Move ; Relative Move
move.l A3, -(sp)
_DrawString ; Write the Count Range Str
move.l (A5), A2 ; QD Vars Ptr
pea Gray(A2)
_PenPat
move.l #$FFFB0006, -(sp) ; Move Up & Over a Bit
_Move ; Draw a Short Gray Line to
move.l #$0000000D, -(sp) ; separate the Patt_Rects
_Line
_PenNormal ; Back to Black for Next String
move Legend_Y_Pos(A5), D0 ; move down for Next String
add #Pattern_Spacing, D0
move D0, Legend_Y_Pos(A5)
add.l #Count_Str_Size, A3 ; point to Next String
add #1, D3
cmp #4, D3
BMI @Draw_Counts
move #Pattern_Y, Legend_Y_Pos(A5)
move #0, D3
lea Patterns, A3
@Draw_Patterns
move Legend_Y_Pos(A5), D0 ; Top
swap D0
move #Pattern_X, D0 ; Left
lea TempRect, A0
move.l D0, (A0)+ ; TopLeft
add.l #$00130013, D0 ; 19 X 19
move.l D0, (A0) ; BottomRight
pea TempRect
move.l (sp), -(sp) ; push 2 copies of Rect Addr
move.l (sp), -(sp)
_FrameRect
move.l #$00010001, -(sp)
_InsetRect
move.l A3, -(sp)
_FillRect
move Legend_Y_Pos(A5), D0 ; move down for Next String
add #Pattern_Spacing, D0
move D0, Legend_Y_Pos(A5)
add.l #Pattern_Size, A3 ; point to Next Pattern
add #1, D3
cmp #5, D3
BMI @Draw_Patterns
RTS
Draw_Mandel_Window
clr.l -(sp)
move #101, -(sp)
pea MandelWindStorage
move.l #-1, -(sp)
_GetNewWindow
_SetPort ; nuthin hops if we don't do this
lea MandelWindStorage, A0
pea portRect(A0)
_EraseRect
RTS
InitManagers
pea -4(A5)
_InitGraf
_InitFonts
_InitWindows
_InitMenus
clr.l -(sp)
_InitDialogs
_TEInit
_InitCursor ; the slings and arrows . . .
RTS
; ----------------- Constants ( in Code Space ) -------------------
MBarTitle dc.b 'Dr. Dobb''s MandelZoom'
.ALIGN 2
MandelWindStorage dcb.b 156, 0
ParamsDLOGStorage dcb.b 170, 0
LegendDLOGStorage dcb.b 170, 0
ItemHit dc.w 0
ItemType dc.w 0 ; Not Used
ItemHandle dc.l 0 ; passed from _GetDItem to _GetIText
ItemBox dcb.l 2, 0 ; Not Used
theString dcb.b 256, 0
theDialog dc.l 0 ; for dialogPtr returned by _IsDialogEvent
X_Org_Str dcb.b 10, 0
Y_Org_Str dcb.b 10, 0
Side_Length dcb.b 10, 0
Count_Strings dcb.b 40, 0 ; 4 X 10 Bytes each
TempRect dcb.l 2, 0 ; holds the Patt Rects for the Legend
TempSTR dcb.b 40, 0
EventRecord
What: dc.w 0
Message: dc.l 0
When: dc.l 0
Where: dc.l 0
Modifiers: dc.w 0
Patterns
dc.l $FFFFFFFF ; 4 pixels per 4 = black
dc.l $FFFFFFFF
dc.l $FFAAFFAA ; 3 pixels per 4 = dark gray
dc.l $FFAAFFAA
dc.l $AA00AA00 ; 1 pixel per 4 = light gray
dc.l $AA00AA00
dc.l $00000000 ; 0 pixels per 4 = pure white
dc.l $00000000
dc.l $AA55AA55 ; 2 pixels per 4 = gray
dc.l $AA55AA55
; ------------------ Variables ( off A5 ) ----------------------
X_Origin ds.l 1 ; Fixed-Pt conversions from
Y_Origin ds.l 1 ; User Entries in Params DLOG
X_Side ds.l 1
Y_Side ds.l 1 ; Set to X_Side for now
Y_Start ds 1 ; where Pen first Plots
Num_Rows ds 1
Num_Cols ds 1
Pix_Per_Pt ds 1
Counts ds.w 4 ; 4 INTEGERs dividing the Iterative
; Domain into 5 Ranges (& Patterns)
Iter_Count ds.w 1
Row_Count ds.w 1
Col_Count ds.w 1
y_current ds.w 1
x_current ds.w 1
C_Real ds.w 1
ds.w 1
C_imag ds.w 1
ds.w 1
Z_Real ds.w 1
ds.w 1
Z_imag ds.w 1
ds.w 1
Del_C_Real ds.l 1
Del_C_imag ds.l 1
Legend_Y_Pos ds.w 1
Start_Time ds.l 1
Radio_1_State ds.b 1
Radio_2_State ds.b 1
Radio_3_State ds.b 1
First_Entry ds.b 1
Mouse_Down ds.b 1
First_Pt ds.b 1
END
Listing Two
; < Str2FP.INC > Thur 10 April '86 h. katz
; Mon 14 April '86
; This File is Linked with MandelZoom.ASM to provide String-to Floating-Point
; and Floating-Point to Fixed-Point Conversions for the
; X_Org, Y_Org, and Side_Len DITL Parameters
; At present only Single-Precision SANE Conversions are used
; A2 = ptr to the Decimal String on Input
; D0 = the Fixed-Pt Number for Output
String_Format 3
Include MacTraps.D
Include SANEMacs.Txt
XDEF Convert_2_Fixed_Point
Sign EQU 0 ; Byte Offsets in Decimal Record
Exp EQU 2
Sig EQU 4
FP_Sign EQU 31 ; Bit Offsets in Single-Precision Result
FP_Exp EQU 30
FP_Sig EQU 22
SP_Exp_Bias EQU 127
DP_Exp_Bias EQU 1023 ; Code for Double-Precision not written
Convert_2_Fixed_Point
lea Temp_String, a0 ; make a copy of incoming string
move.b (a2), d0 ; its length
@0 move.b (a2)+, (a0)+
DBRA d0, @0
lea Temp_String, a0 ; replace ptr to theString
BSR Build_Decimal_Record
pea Decimal_Record
pea FP_Num
FDEC2S ; a SANE 'trap'
BSR Build_Fixed_Pt
RTS ; to Mandelbrot
Build_Fixed_Pt
sf d2 ; assume Positive
lea FP_Num, a0
move.l (a0), d1 ; save the Exponent
lsl.l #1, d1 ; shift Sign into Carry
bcc @1 ; was Positve
st d2 ; flag as Negative
@1 swap d1 ; move Exp into Low Word
lsr.w #8, d1 ; shift Exp to Right
sub.b #SP_Exp_Bias, d1 ; unbias it
move.l (a0), d0 ; move orig FP_Num into register
and.l #$007FFFFF, d0 ; clear Exp
bset.l #23, d0 ; add the leading '1' bit
tst.b d2
beq @2 ; num is +
neg.l d0
@2 sub.b #7, d1 ; Neg(7-Exp) is amount to shift
neg.b d1
bmi @Shift_Left
asr.l d1, d0
bra @rts
@Shift_Left
neg.b d1 ; Max Left Shift not checked for yet
asl.l d1, d0
@rts RTS
Build_Decimal_Record
; Strip the Sign Char
; Strip the Decimal_Pt and Decrease the Exponent Accordingly
; Finally Strip Leading Zeroes
lea Decimal_Record, a1 ; Zero the Record
move.l #0, (a1)+
move.l #0, (a1)+
move.l #0, (a1)+
move.l #0, (a1)+
lea Decimal_Record, a1
cmp.b #'+', 1(a0) ; Strip the Plus Sign, if any
BNE @Strip_Minus_Sign
BSR Shift_Count_Byte
bra Strip_Decimal_Pt
@Strip_Minus_Sign
cmp.b #'-', 1(a0)
BNE Strip_Decimal_Pt
move.b #1, Sign(a1) ; Mark Dec_Rec Sign as Negative
BSR Shift_Count_Byte
Strip_Decimal_Pt
move.b (a0), Sig(a1) ; move Count to Decimal_Record
lea 1+Sig(a1), a2 ; point to 1st Digit
add.l #1, a0 ; points to 1st Digit in Src Str
clr d0
move.b Sig(a1), d0 ; length of String
sub.b #1, d0 ; - 1 for DBRA
sf d1 ; Passed_Decimal_Pt Flag = FALSE
@0 cmp.b #'.', (a0)
beq @Found_Decimal_Pt
move.b (a0)+, (a2)+ ; shift the digit to Decimal_Rec
tst.b d1 ; are we past the Decimal Pt ?
beq @Test_EOStr
sub #1, Exp(a1)
bra @Test_EOStr
@Found_Decimal_Pt
st d1
add.l #1, a0 ; point past decimal point
sub.b #1, Sig(a1) ; Count := Count - 1
@Test_EOStr
DBRA d0, @0
Strip_Leading_Zeroes
lea Sig(a1), a0 ; point @ Count Byte in
move.b (a0), d0 ; Decimal_Record Sig Field
sub.b #1, d0 ; setup for DBRA
ext.w d0
sf d1 ; No Leading Zeroes (yet)
@Loop_1
cmp.b #'0', 1(a0)
BNE @Test_4_Shift ; Encountered a Signif Digit -> Done
st d1
BSR Shift_Count_Byte
DBRA d0, @Loop_1
@Test_4_Shift
tst.b d1 ; Any Non-Significant Zeroes Found ?
BEQ @rts ; no
lea Sig(a1), a1 ; point to Sig Count Byte
move.b (a0), d0 ; a0 is Count Byte (wherever it is)
ext.w d0
@Loop_2
move.b (a0)+, (a1)+ ; shift Count + Digits to Left
DBRA d0, @Loop_2
@rts RTS
Shift_Count_Byte
sub.b #1, (a0) ; Length = Length - 1
move.b (a0)+, (a0) ; move Count Byte over one
RTS
; ----------------------------------------------------------
FP_Num dc.b 8, 0 ; working space for both
; Single & Double Precision numbers
Decimal_Record
dc.w 0 ; Sign
dc.w 0 ; Exp
dcb.b 12, 0 ; Sig
Temp_String dcb.b 12, 0
END