

|
Volume Number: | 3 | |||
Issue Number: | 1 | |||
Column Tag: | Assembly Language Lab |
Rose Curve Generator
By Victor Barger, Waunakee, WI
An application of mathematics which produces fascinating designs is the graphing of trigonometric functions using polar coordinates. Each function leads to a beautiful design which bears a strong resemblance to a flower, such as the rose. With its excellent graphics capabilities and superior user interface, the Macintosh is perfect for quickly plotting “rose” functions on the screen with a program simple enough that anyone can use it. The application described in this article takes full advantage of these capabilities to allow the user to experience the graphic beauty of trigonometry.
Using Rose Curves
After launching Rose Curves, a window will open in the center of the screen and the default function will be drawn inside. (See Figure 1) Both the standard apple menu and a Control menu will be in the menu bar. The apple menu contains the item “About Rose Curves...” and the names of all desk accessories available to the user from the System file. Under the Control menu are two options: Change Parameters and Quit. When the Change Parameters item is selected a window similar to the one in Figure 2 is opened in the center of the screen. With this window the user can select the function to be drawn, choose the size of the drawing and indicate whether the drawing should be multilayered. Function and size are selected by clicking on the appropriate function name or size. For example, selecting cos (sin 100r) gives the design in Figure 3. If multilayered is selected, the function will be drawn at the original size and then shrunk repeatedly to create a “layered” effect, making the design more interesting: See Figure 4.
Entering the Program
Start up the Macintosh 68000 Development System. The startup disk should be titled ‘MDS1’ and the external disk ‘MDS2.’ The applications Edit, Asm, Link, Exec and RMaker should be on MDS1 and a folder entitled ‘.D Files’ with SysEqu.D, ToolEqu.D, QuickEqu.D, and MacTraps.D inside on MDS2. To make Rose Curves work on a Macintosh 512 with the old ROM, FixMath.Txt and FixMath.Rel must also be in the .D Files folder (The information on where to get these two files is under How Rose Curves Works). FixTraps.Txt and FixTraps.Rel are files which were distributed by Apple Computer under the Apple Software Supplement to aid assembly language programmers in calculating basic arithmetic and trigonometric functions. As the program is presented here, you have everything you need to type the program in and run it on a new ROM machine, since the FixTraps necessary for this program are explicitly defined with the ".TRAPS" statement at the start of the program. The program may also be entered into the new MPW assembler, or assembled with the Consulair C system, which includes the complete MDS assembler built-in.
To create the program, simply assemble the Rose.Asm listing. Then compile the resource file with RMaker. Finally execute the linker on the link file listing and the program object file and resource object file (both ".REL" files) will be linked together, an application generated, and the cute rose application icon should appear on the disk. Double click "Rose Curves" and your in business making fascinating polar coordinate art.
How Rose Curves Works
The program begins by initializing the standard managers, initializing its variables, setting up the menu bar and opening the window. The initialized variables are Equation, Scale, RealScale, Multilayered and drawn. Equation contains the item number of the selected function in the Change Parameters dialog. To obtain the real equation number, subtract 3 from Equation. Scale is the item number of the selected scale or “size” and RealScale is the actual scalar multiplied on each point before drawing it. Multilayered determines whether the rose will be layered. Finally, drawn is a boolean expression which determines whether the window needs to be updated by redrawing the rose (false) or simply by copying the rose from the offscreen bitmap (true). The offscreen bitmap is also created in this routine. To create a bitmap, create an area in memory with space for a pointer, a word and a rectangle. In Rose Curves, this appears at the end of the program under the label windowBitMap. Now select the rectangle of the bitmap and calculate the rowbytes with the equation
rowbytes = int((xright - xleft)/8+1)
If rowbytes is odd, round it up. Suppose our rectangle is 0, 0, 50, 96 (remember that a QuickDraw rectangle is stored as y1, x1, y2, x2). Then rowbytes would be 14 and the bitmap would look like this:
myBitMapDC.L0 ;pointer to bitmap storage DC14 ;rowbytes DC0, 0, 50, 96 ;boundsRect
The size of the bitmap storage must be determined before it can be created. Use the equation
size = rowbytes * (ybottom - ytop)
To create the bitmap, use the following routine.
move.l #size,D0 _NewPtr;allocate new pointer lea myBitMap,A1 move.l A0,(A1) ;put the pointer to the ;storage in myBitMap
To copy a picture from the current window to myBitMap, use this routine
pea aPort(A5) ;storage for the port _GetPort ;get the current port move.l aPort(A5),A0 ;put the port pointer in A0 pea portBits(A0) ;push ptr to port’s bitmap pea myBitMap ;push ptr to our bitMap pea srcRect ;push srcRect pea dstRect ;push dstRect clr -(SP) ;srcCopy clr.l -(SP) ;no mask region _CopyBits;copy the bits
Finally, remember to dispose of the bitmap’s storage after finishing with it. This is accomplished simply with
move.l myBitMap,A0 _DisposPtr
The EventLoop allows desk accessories to perform their periodic events by calling _SystemTask and, if an event occurs, branches to HandleEvent which transfers execution to the appropriate routine: Activate, Update, KeyDown or MouseDown. The Activate routine activates or deactivates the Rose Curves window depending on what the user requested. Update updates the window by either drawing the curve or using _CopyBits, depending on whether the curve had been drawn previously. KeyDown checks if the command-key was down when the KeyDown event occurred by testing bit eight of the ModifyReg. If bit eight equals one, a command-key was pressed and _MenuKey is called to determine the appropriate menuNumber and itemNumber for Choices, the routine which handles menu selections. MouseDown finds the area the mouse was clicked in using _FindWindow and jumps to the appropriate routine to handle the click.
Several other important routines are SystemEvent, InMenu, UnhiliteMenu, NextEvent InAppleMenu and ParameterChange. SystemEvent passes mouse clicks in system windows to the system for it to handle. InMenu converts a mouse click in the menu bar to the correct menuNumber and itemNumber for Choices. Choices then calls InAppleMenu if the click was in the apple menu, calls ParameterChange if the first item in the Control menu was selected, or quits to the Finder if Quit was selected. UnhiliteMenu unhighlights all menus in the menu bar and NextEvent returns to the EventLoop. InAppleMenu either displays the InfoAlert About Rose Curves... or opens the selected desk accessory using _OpenDeskAccessory. Finally, ParameterChange opens the parameter dialog, hilights the buttons which correspond to the Equation, Scale and Multilayered variables and monitors the user’s actions until the dialog is dismissed with the OK or Cancel button. If OK was selected, ParameterChange updates the variables Equation, Scale, RealScale and Multilayered before closing the dialog and returning to the EventLoop.
The heart of the program lies in the DrawRose subroutine. Before outlining how it operates, an explanation of the fixed-point math routines is needed. Fixed-point math is not as accurate as floating-point math, but much faster. With graphics programs, speed is often much more important than accuracy, especially when there is the possibility of losing the user’s attention. Since Apple elected not to implement the fixed-point routines into the old toolbox, they released the file's FixTraps. Txt and FixMath.Rel in the Apple Software Supplement of May 6, 1985. These files are available from local user groups, bulletin boards, Apple dealerships or directly from Apple. FixTraps.Txt includes a nice description of the “toolbox additions” and FixMath.Rel contains the actual routines. To use the fixed-point routines on a Macintosh with the old ROM, type ‘INCLUDE FixTraps.Txt’ at the beginning of your .Asm file. Also include the line ‘FixTraps’ after the name of the application under development in the .Link file. To use the fixed-point routines on a Macintosh with the new ROM, simply define the trap using .TRAP at the beginning of the ASM file as we did in our listing here. The complete list of new fixed-point traps is as follows:
Long2Fix $A83F
FracSin $A848
FracSqrt $A849
FracMul $A84A
FracDiv $A84B
FixAtan2 $A818
FixDiv $A84D
Fix2Long $A840
Fix2Frac $A841
Frac2Fix $A842
Fix2X $A843
X2Fix $A844
Frac2X $A845
X2Frac $A846
FracCos $A847
The fixed-point routines support three types of numbers: longint (long integer), fixed, and fract (fractional). Type longint represents integers between ±2147483647, type fixed represents fractional quantities between ±32768 with about 5 digits of accuracy and type fract represents fractional quantities between ±2 with about 9 digits of accuracy. Rose Curves uses _FracSin, _FracCos, _FixMul and _FracMul to perform its arithmetic operations. These routines work like any other toolbox trap: space is cleared on the stack for the result, the parameters are pushed on the stack and the trap is called. The Pascal definitions for these routines are
function FracSin( x : Fixed ) : Fract function FracCos( x : Fixed ) : Fract function FixMul( x, y : Fixed ) : Fixed function FracMul( x, y : Fract ) : Fract
With _FixMul and _FracMul it is possible to pass parameters of different types than specified. For example, one could pass x as type longint and y as type fixed to _FixMul and the result would be type longint. The following table contains the result types for multiplying different types using _FixMul and _FracMul.
_FixMul _FracMul
x y result x y result
fixed fixed fixed fract fract fract
longint fixed longint longint fract longint
fixed longint longint fract longint longint
fract fixed fract fixed fract fixed
fixed fract fract fract fixed fixed
Note: To convert a number to type Fract, multiply it by 65536. To convert a number to type Fixed, multiply it by 32768.
DrawRose begins by changing the cursor to a watch, setting the counter to 721 steps (1 + 360° x 1/increment), the increment to 572 (.5° in fixed-point radians) and the present angle to 0. It then loops until the counter is zero, evaluating the current function (bsr EvalFunction), converting the function result to rectangular coordinates and scaling and centering the points. After completing each layer, the program decreases the scale by 20 and redraws the curve if multilayered was selected. After drawing all of the layers, the variable drawn is set to true and the image in the window is copied onto the offscreen bitmap for future update events.
Possible Modifications
Rose Curves could be improved in several ways. The most obvious way would be to add more functions to the program. To accomplish this, add the “function” buttons in the Rose.R file and add the subroutines to evaluate the new functions to Rose.Asm. Note that the displacement to the function must be included in the equation table for the new subroutine to be executed. To do this, add the line DC functionLabel-EquationTable after the line DC Six-EquationTable. As more functions are added, keep adding the labels to the equation table. The second improvement would be to decrease the time required to draw the rose when multilayered is on. To do this, copy the image of the rose into an offscreen bitmap using _CopyBits after the first rose has been drawn. Then shrink CopyBits’ dstRect and copy the rose from the offscreen bitmap onto the screen. Although many times faster, this method greatly reduces the accuracy with which layers are drawn since they are being scaled by _CopyBits, not mathematically graphed. An option to this problem would be to include a checkbox in the Change Parameters dialog titled ‘Accurate Multilayers.’ If selected, Rose Curves would draw the layers using its normal drawing routine. If not, Rose Curves would use the copy-and-shrink method, thus giving the user the choice of accuracy or speed.
;File: Rose.Asm ;--------------------------------------------- ;Rose Curves draws curves expressed as a ; function of r and theta. ;Written by Victor Barger on April 2, 1986. ;--------------------------------------------- INCLUDEMacTraps.D INCLUDEQuickEqu.D INCLUDEToolEqu.D ;--------------------------------------------- .trap _FracMul $A84A ;New Roms .trap _FracCos $A847 .trap _FracSin $A848 ;---------------------------------------------- Radians EQU D3 TopButton EQU D3 BottomButtonEQU D4 ModifyReg EQU D4 Increment EQU D4 MenuReg EQU D5 Counter EQU D5 CheckBoxEQU D6 MenuItemReg EQU D6 FuncResultEQU A4 AppleMenuID EQU 1 ControlMenuID EQU 2 ParamDlgIDEQU 2000 DrawWindIDEQU 2001 InfoAlertID EQU 2002 InitialScaleEQU 13 RealInitScale EQU 460 ;------------------------------------------------- Start bsr InitManagers ;initialize managers bsr InitVariables;initialize variables bsr SetupMenu ;setup the menu bsr SetupWindow;draw the window EventLoop _SystemTask;periodic actions for da's clr -(SP) move #$0FFF,-(SP) pea EventRecord _GetNextEvent ;get the next event move (SP)+,D0 beq.s EventLoop;no event, loop back bsr HandleEvent;handle the event beq.s EventLoop;if 0, continue; else quit rts Beep move #12,-(SP) _SysBeep rts ;--------------------------------------------------- InitManagers pea -4(A5) _InitGraf _InitFonts move.l #$0000FFFF,D0 _FlushEvents _InitWindows _InitMenus clr.l -(SP) _InitDialogs _TEInit _InitCursor rts ;--------------------------------------------------- InitVariables move #3,Equation(A5) move #InitialScale,Scale(A5) move.l #RealInitScale,RealScale(A5) clr Multilayered(A5) ;not multilayered move.l #11520,D0 _NewPtr;create a new bit map lea windowBitMap,A1 move.l A0,(A1) ;remember the pointer clr drawn(A5) ;not drawn yet rts ;----------------------------------------------------- SetupMenu clr.l -(SP) move #AppleMenuID,-(SP) _GetRMenu;get the apple menu move.l (SP),AppleMenu(A5) move.l (SP),-(SP) clr -(SP) _InsertMenu;insert the menu in the menu bar move.l #'DRVR',-(SP) _AddResMenu;add the DA's to the apple menu clr.l -(SP) move #ControlMenuID,-(SP) _GetRMenu;get the control menu clr -(SP) _InsertMenu;insert the menu in the menu bar _DrawMenuBar ;draw the new menu bar rts ;------------------------------------------------------ SetupWindow clr.l -(SP) move #DrawWindID,-(SP) pea WindowStorage(A5) move.l #-1,-(SP) _GetNewWindow ;get the RoseCurves Window move.l (SP),DrawPtr(A5) _SetPort ;set the new grafport rts ;------------------------------------------------------ HandleEvent move Modify,ModifyReg move What,D0 add D0,D0 move EventTable(D0),D0 jmp EventTable(D0) EventTable DCNextEvent-EventTable DCMouseDown-EventTable DCNextEvent-EventTable DCKeyDown-EventTable DCNextEvent-EventTable DCKeyDown-EventTable DCUpdate-EventTable DCNextEvent-EventTable DCActivate-EventTable DCNextEvent-EventTable DCNextEvent-EventTable ;------------------------------------------------------- Activate move.l DrawPtr(A5),D0 cmp.l Message,D0 ;was it our window? bne NextEvent ;no, get next event btst #0,ModifyReg ;activate? beq NextEvent ;no, deactivate SetOurPort move.l DrawPtr(A5),-(SP) ;push pointer to draw window _SetPort ;set our port bra NextEvent ;------------------------------------------------------- Update move.l Message,D0 ;get the window ptr cmp.l DrawPtr(A5),D0 bne NextEvent tst drawn(A5) bne.s copyIt move.l DrawPtr(A5),-(SP) ;push window ptr _SetPort ;set the port move.l DrawPtr(A5),-(SP) _BeginUpdate move.l DrawPtr(A5),-(SP) _EndUpdate pea windowRect _EraseRect bsr DrawRose ;draw the rose bra NextEvent copyIt move.l DrawPtr(A5),-(SP) ;push window ptr _SetPort ;set the port move.l DrawPtr(A5),-(SP) _BeginUpdate pea windowBitMap ;get the rose from the bitMap move.l drawPtr(A5),A0 pea portBits(A0) ;put the rose in our window pea windowRect ;same rect for src and dest pea windowRect clr -(SP) ;srcCopy clr.l -(SP) ;no maskRgn _CopyBits;copy It move.l DrawPtr(A5),-(SP) _EndUpdate bra NextEvent ;----------------------------------------------------- KeyDown btst #8,ModifyReg ;is the command key down? beq NextEvent ;no, exit clr.l -(SP) ;space for menu and item move Message+2,-(SP);get character _MenuKey ;see if its a command move (SP)+,MenuReg;preserve menu move (SP)+,MenuItemReg ;and Menu item bra.s Choices ;------------------------------------------------------ MouseDown clr -(SP) ;space for result move.l Point,-(SP);get mouse coordinates pea WWindow ;push event window _FindWindow;find the window move (SP)+,D0 ;get region number add D0,D0 ;*2 for index into table move WindowTable(D0),D0 ;point to routine offset jmp WindowTable(D0);jump to routine WindowTable DCNextEvent-WindowTable ;in desk (not used) DCInMenu-WindowTable;in menu bar DCSystemEvent-WindowTable;in system window DCNextEvent-WindowTable ;in content (not used) DCNextEvent-WindowTable ;in drag (not used) DCNextEvent-WindowTable ;in grow (not used) DCQuitRoutine-WindowTable;in go away ;----------------------------------------------------- SystemEvent pea EventRecord;ptr to the event record move.l WWindow,-(SP);push window ptr _SystemClick ;let system take care of it bra NextEvent ;next event ;------------------------------------------------------- InMenu clr.l -(SP) ;space for menu choice move.l Point,-(SP);mouse at time of event _MenuSelect;menu select move (SP)+,MenuReg;preserve menu move (SP)+,MenuItemReg ;preserve menu item Choices cmp #2,MenuReg ;was it the control menu? bne.s NotQuit ;no cmp #2,MenuItemReg ;Quit selected? bne.s NotQuit ;no, continue bsr UnHiliteMenu ;unhilight the menu bar QuitRoutine move.l DrawPtr(A5),-(SP) ;push ptr to draw window _CloseWindow ;close the window move.l windowBitMap,A0 _DisposPtr ;dispose of the bitmap move #-1,D0;say it was Quit rts NotQuit cmp #1,MenuReg ;in apple menu? beq.s InAppleMenu;yes, go do apple menu cmp #2,MenuReg ;in file menu? beq ParameterChange;yes ChoiceReturn bsr UnHiliteMenu ;unhilight the menu bar ;fall through get next event ;--------------------------------------------------------- NextEvent moveq #0,D0 ;say it's not Quit rts ;return to event loop ;-------------------------------------------------------- UnhiliteMenu clr -(SP) ;all menus _HiLiteMenu;unhilite every one rts ;-------------------------------------------------------- InAppleMenu cmp #1,MenuItemReg beq.s Info move.l AppleMenu(A5),-(SP) move MenuItemReg,-(SP) pea DeskName _GetItem ;get name of the desk accessory clr -(SP) pea DeskName _OpenDeskAcc ;open the desk accessory move (SP)+,D0 RestoreOurPort bsr SetOurPort bra ChoiceReturn Info clr -(SP) move #InfoAlertID,-(SP) clr.l -(SP) _Alert ;handle the infoAlert move (SP)+,D0 bra RestoreOurPort ;--------------------------------------------------------- ParameterChange clr.l -(SP) move #ParamDlgID,-(SP) pea DStorage move.l #-1,-(SP) _GetNewDialog ;get the dialog move.l (SP),ParamDlgPtr(A5);preserve the dialogPtr _SetPort ;set the port move Equation(A5),TopButton;TopButton = current button ;highlighted in top section move TopButton,D0 bsr FindButton ;sub. to return handle move.l itemHandle(A5),-(SP) move #1,-(SP) _SetCtlValue ;highlight the button move Scale(A5),BottomButton;BottomButton = current ; button in bottom section move BottomButton,D0 bsr FindButton move.l itemHandle(A5),-(SP) move #1,-(SP) _SetCtlValue ;highlight the button move Multilayered(A5),CheckBox move #17,D0 bsr FindButton ;get handle to check-box move.l itemHandle(A5),-(SP) move CheckBox,-(SP) _SetCtlValue ;check or uncheck it RepeatLoop clr.l -(SP) pea ItemHit _ModalDialog ;modal dialog move ItemHit,D1 cmp #2,D1 ;was it Cancel? beq Done;yes cmp #1,D1 ;was it OK? beq SetNewParams ;yes cmp #9,D1 ;was it in the bottom set? bge.s BottomSet;yes move TopButton,D0 move D1,TopButton ;set new button number bsr FindButton ;get handle to last button move.l itemHandle(A5),-(SP) clr -(SP) _SetCtlValue ;unhighlight last button move TopButton,D0 bsr FindButton move.l itemHandle(A5),-(SP) move #1,-(SP) _SetCtlValue ;highlight new button bra.s RepeatLoop BottomSet cmp #14,D1;in bottom set? bge.s CheckForBox;no move BottomButton,D0 move D1,BottomButton bsr FindButton ;get handle to last button move.l itemHandle(A5),-(SP) clr -(SP) _SetCtlValue ;unhighlight last button move BottomButton,D0 bsr FindButton move.l itemHandle(A5),-(SP) move #1,-(SP) _SetCtlValue ;highlight new button bra RepeatLoop CheckForBox cmp #17,D1;click in the check box? bne RepeatLoop cmp #1,CheckBox bne.s NotOne move #0,CheckBox bra.s SetCheck NotOne move #1,CheckBox SetCheck move #17,D0 bsr FindButton ;get handle to check-box move.l itemHandle(A5),-(SP) move CheckBox,-(SP) _SetCtlValue ;check or uncheck it bra RepeatLoop SetNewParams clr drawn(A5) move TopButton,Equation(A5);set new equation number move BottomButton,Scale(A5);set new scale move CheckBox,Multilayered(A5) ;set multilayered move Scale(A5),D0 sub #9,D0 asl.l #2,D0 move.l ScaleTable(D0),RealScale(A5) ;look up real scale Done move.l ParamDlgPtr(A5),-(SP) _CloseDialog ;close the dialog bra RestoreOurPort ScaleTable DC.L 140,220,300,380,460 ;------------------------------------------------------ FindButton move.l ParamDlgPtr(A5),-(SP) move D0,-(SP) pea itemType pea itemHandle(A5) pea dispRect _GetDItem;get handle to itemnumber in D0 rts ;------------------------------------------------------- ;to convert a fract number to type fract, multipy by 65536 DrawRose clr.l -(SP) move #4,-(SP) _GetCursor ;get the watch cursor (ID=4) move.l (SP)+,D0 move.l D0,A0 move.l (A0),-(SP) _SetCursor ;set the new cursor move.l RealScale(A5),-(SP) ;preserve the realScale DrawRose1 move #720,Counter ;721 steps (360 x 2) move.l #572,Increment ;572 = .5° increment in radians ;(.5Π/180)*65536 moveq #0,Radians ;present degrees nextDegree bsr EvalFunction ;evaluate fn r(Radians) sub #14,SP move.l Radians,-(SP) _FracSin move.l FuncResult,-(SP) _FracMul ;y = fn r(Radians) * sin(Radians) move.l RealScale(A5),-(SP) _FixMul;y = y * realScale _HiWord move (SP)+,y(A5);y = int(y) sub #14,SP move.l Radians,-(SP) _FracCos move.l FuncResult,-(SP) _FracMul ;x = fn r(Radians) * cos(Radians) move.l RealScale(A5),-(SP) _FixMul;x = x * realScale _HiWord move (SP)+,x(A5);x = int(x) move x(A5),D0 add #154,D0 move D0,-(SP) ;x = x + 154 move y(A5),D0 add #144,D0 move D0,-(SP) ;y = y + 144 tst Radians bne.s NotFirst _MoveTo;moveto x,y if first point bra.s Skip NotFirst _LineTo;else lineto x,y Skip add.l Increment,Radians ;Radians = Radians + Increment dbra Counter,nextDegree ;loop back cmp #1,Multilayered(A5) ;another layer? bne.s NoExtraLayers;no move.l #20,D0 sub.l D0,RealScale(A5) ;decrease the real scale by 20 cmp.l RealScale(A5),D0 ;is the real scale = 20? bne DrawRose1 ;no, do next layer NoExtraLayers move #1,drawn(A5) ;the rose has been drawn move.l drawPtr(A5),A0 pea portBits(A0) ;put the rose in our window pea windowBitMap ;get from offscreen bitmap pea windowRect ;same size windowRect pea windowRect clr -(SP) ;srcCopy clr.l -(SP) ;no mask region _CopyBits;copy the bits move.l (SP)+,RealScale(A5) _InitCursor rts ;---------------------------------------------------- EvalFunction move Equation(A5),D0 sub #3,D0 add D0,D0 move EquationTable(D0),D0 jmp EquationTable(D0) EquationTable DCOne-EquationTable ;sin 4r DCTwo-EquationTable ;cos (2 sin r) DCThree-EquationTable ;cos (2 sin 2r) DCFour-EquationTable;cos (sin 100r) DCFive-EquationTable;cos (sin 8 r) DCSix-EquationTable ;cos (4 sin 2r) ;------------------------------------------------------- None move.l #0,FuncResult rts ;------------------------------------------------------- One ;sin 4r clr.l -(SP) move.l Radians,D0 asl.l #2,D0 move.l D0,-(SP) _FracSin move.l (SP)+,FuncResult ;fn r(Radians) = sin (Radians * 4) rts ;------------------------------------------------------- Two ;cos (2 sin r) subq #8,SP move.l Radians,-(SP) _FracSin move.l (SP),D0 asr.l #7,D0 asr.l #6,D0 ;convert to fixed x 2 move.l D0,(SP) _FracCos move.l (SP)+,FuncResult ;fn r(Radians) = cos (2 sin r) rts ;-------------------------------------------------------- Three ;cos (2 sin 2r) subq #8,SP move.l Radians,D0 asl.l #1,D0 move.l D0,-(SP) _FracSin move.l (SP),D0 asr.l #7,D0 asr.l #6,D0 ;convert to fixed x 2 move.l D0,(SP) _FracCos move.l (SP)+,FuncResult ;fn r(Radians) = cos (2 sin 2r) rts ;------------------------------------------------------- Four ;cos (sin 100r) sub #12,SP move.l Radians,-(SP) move.l #3276800,-(SP) _FixMul _FracSin move.l (SP),D0 asr.l #7,D0 asr.l #7,D0 ;convert to fixed move.l D0,(SP) _FracCos move.l (SP)+,FuncResult ;fn r(Radians) = cos (sin 100r) rts ;-------------------------------------------------------- Five ;cos (sin 8 r) subq #8,SP move.l Radians,D0 asl.l #3,D0 move.l D0,-(SP) _FracSin move.l (SP),D0 asr.l #7,D0 asr.l #7,D0 move.l D0,(SP) _FracCos move.l (SP)+,FuncResult ;fn r(Radians) = cos (sin 8r) rts ;--------------------------------------------------------- Six ;cos (4 sin 2r) subq #8,SP move.l Radians,D0 asl.l #1,D0 move.l D0,-(SP) _FracSin move.l (SP),D0 asr.l #7,D0 asr.l #5,D0 move.l D0,(SP) _FracCos move.l (SP)+,FuncResult ;fn r(Radians) = cos (4 sin 2r) rts ;------------------ Local Variables ----------------- EventRecord What: DC0 Message: DC.L 0 When: DC.L0 Point: DC.L0 Modify:DC0 WWindow: DC.L 0 windowRectDC0,0,288,308 windowBitMapDC.L 0 DC40 DC0,0,288,308 ItemHit DC0 itemTypeDC0 dispRectDC0,0,0,0 DStorageDCB DWindLen,0 DeskNameDCB 16,0 ;-------------- Application Globals ---------------- WindowStorage DSWindowSize ;storage for draw window DrawPtr DS.L1 ;pointer to draw window AppleMenu DS.L 1 ;apple menu EquationDS1 ;equation number Scale DS1 ;scale RealScale DS.L 1 ;longint real scale MultiLayeredDS 1 ;multilayered (0 = false, 1 = true) ParamDlgPtr DS.L 1 ;pointer to the parameter dialog itemHandleDS.L 1 ;itemHandle yDS1 ;y-value xDS1 ;x-value drawn DS1 ;-------------------------------------------------------- END

- SPREAD THE WORD:
- Slashdot
- Digg
- Del.icio.us
- Newsvine