2IMGSHEP@@@ 8L2C)pJJJJ IH(ȱH:=IH[H`@HcH  $ +   I/H`JLNGȄBȄF aK  haaFF  mJm# KKJ UJ )J ۈ) ;J3ȱJFȱJGJKaȄM  aaNNJFLGJL L? &PRODOS `DaElH$?EGvѶK+`L HHLy XP LM ŠϠĠӠS)*+,+`F)) (*=GJFjJJA QE'+ '== `@ STSP8QSS8 m P o R(8RLnSOS BOOT 1.1 SOS.KERNEL SOS KRNLI/O ERRORFILE 'SOS.KERNEL' NOT FOUND%INVALID KERNEL FILE: xةw,@  ȱlmi8#)!) >dLԡm#i㰼m#iЕOLԡȱfg hi !dLԡ憦  Ljmkm l y`2 Lԡ8(Je稽)ʈ@LWAP2006Z; ' ,@(DEMO.ASM1^& & (DEMO.MAC2 <Z l(WIND.ASM;>Z k )TASKS.ASMLG[Z l*COLORS.ASM,Z l*CONICS.ASM \Z j7)DDESK.ASM,+Z2 Z( *DMENUS.ASM5\fZ k9)DMENU.ASM(Z k##LIB Z _'LIB.EQU dZ c'LIB.REF8 Z k 'LIB.MAC! $Z [ +GLOBALS.ASM,!Z j7'LIB.ASM>$Z c (UTIL.ASMR <Z *SCREEN.ASMrZ c +MENUTIL.ASM;sZ c'+CONTROL.ASMMZ o'MGR.ASM ( LZ )EVENT.ASM1IZ [,)PANEL.ASMABZ j(FILE.ASM Z c/ LIB.ROOT Z ) LIB.AmZ ) DEMO.LNK#Z  _PAINT.ROOT Z ) PAINT.A ^Z ) $DEMOiFZ g:TEMPZ ^1)PMENU.ASM4&Z \*PMENUS.ASM9nZ g)TOOLS.ASMIuZ 8"+SPARKLE.ASMG:Z g+STRETCH.ASMf.>XZ j(RSRC.ASM.wXZ j:'DOC.ASM ,Z l)PDESK.ASM*Z2 Z0 ,FASTDRAG.ASMZ 8& )PAINT.ASM*Q  )PAINT.MAC Z rPAINT.LNK"%Z  _DEMO.ROOT$ Z ( DEMO.A-NZ ) PAINT.BLDzZ _7DEMO.BLD{Z g*%PAINT}UӦZ gPAINT.LSTDEMO.LST (SCREEN.0AZ l NOTICE"  ?******************************************************************* * * * Version 1.0 * * January 31, 1987 * * * * (c) Copyright 1986, 1987 Apple Computer, Inc. * * * * All rights reserved.   !"#$%&'()*+,-./0 * * * * This program and its derivatives are licensed only for * * use on Apple computers. * * * * Works based on this program must contain and * * conspicuously display this notice. * * * * This software is provided for your evaluation and to * * assist you in developing software for the Apple IIGS * * computer. * * * * This is not a distribution license. Distribution of * * this and other Apple software requires a separate * * license. Contact the Software Licensing Department of * * Apple Computer, Inc. for details. * * * * DISCLAIMER OF WARRANTY * * * * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT * * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, * * WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS * * FOR ANY PARTICULAR PURPOSE. THE ENTIRE RISK AS TO * * THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH * * YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND * * NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE) * * ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, * * REPAIR OR CORRECTION. * * * * Apple does not warrant that the functions * * contained in the Software will meet your requirements * * or that the operation of the Software will be * * uninterrupted or error free or that defects in the * * Software will be corrected. * * * * SOME STATES DO NOT ALLOW THE EXCLUSION * * OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY * * NOT APPLY TO YOU. THIS WARRANTY GIVES YOU SPECIFIC * * LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS * * WHICH VARY FROM STATE TO STATE. * * * ******************************************************************* * LIST OFF GEN off SYMBOL off KEEP demo 65816 on *===== * * ZeroPage space (and initial program branch) * mcopy demo.mac ZeroPage START jmp Demo copy lib.equ copy lib.ref FirstSCB gequ $E19D00 END *===== * * Demo globals * DemoGlobals DATA using LibGlobals Nichts gequ 0 Lines gequ 2 Dithers gequ 4 Conics gequ 6 Colors gequ 8 Slides gequ 10 Polygons gequ 12 Macrame gequ 14 CurrentTask gequ NextZeroPage NewTask gequ CurrentTask+2 NextTask gequ NewTask+2 TaskTable dc i2'NoEvent' dc i2'LinesTask' ; Region Ops dc i2'DithersTask' ; Rectangles dc i2'ConicsTask' ; Conics dc i2'ColorsTask' ; Colors dc i2'SlidesTask' ; Slide Show dc i2'PolygonsTask' ; Polygons dc i2'MacrameTask' ; Macrame ClickHandler dc i2'0' PauseFlag dc i2'0' ColorToggle dc i2'0' CurrentDemo dc i2'1' Windowing dc i2'$FFFF' CanWindow dc i2'$FFFF' *Sounding dc i2'$FFFF' WaveCount dc i2'0' Animating dc i2'0' SlideCount dc i2'0' * Menu manager stuff DemosMenu gequ 4 ; overlaps goodies * Globals used by the window manager WindowRect ds 8 ContentRect ds 8 CloseBox ds 8 CloseLite ds 8 WindowRgn ds 4 ContentRgn ds 4 Clipper ds 4 YLine ds 2 LineStart ds 2 LineStop ds 2 LineCount ds 2 PushCount ds 2 DemoTitleBar dc i1'DemoEnd-DemoTitleBar-1' dc c'File Edit Demos Options' DemoEnd anop WindowTitle dc i1'StrEnd1-WindowTitle-1' dc c' Cortland Region Ops Demo 200 x 640 ' StrEnd1 anop ds 256 ; just to be sure END *===== * * Demo * Demo START using LibGlobals using DemoGlobals jsr OpenLibrary jsr WindowsInit lda #DemoEvents sta StdEvents pea Arrow jsr SetCursor PushPtr DemoTitleBar jsr SetTitleBar jsl InitDemo _ShowCursor lda #Macrame sta NewTask jsl Installer jsr EventManager ; main event loop where all happens stz NewTask ; shut down the window jsl Installer jsl DemoCleanup jsr WindowsShutdown jsr CloseLibrary ; close the library brk $F0 ; we don't return (_PQuit) END copy tasks.asm copy colors.asm copy dmenus.asm copy wind.asm copy dmenu.asm copy conics.asm copy ddesk.asm *===== * * Init demo * InitDemo START using LibGlobals using DemoGlobals stz PauseFlag stz QuitFlags stz ColorToggle pea KeyDownEvent pea KeyHandler jsr SetHandler pea MouseDownEvent pea HandleMouse jsr SetHandler stz CurrentTask ; set up our initial task stz Windowing ; full windows at first jsr setstandards ; set up the right colors jsr DrawScreen rtl END *===== * * Demo cleanup * DemoCleanup START using LibGlobals using DemoGlobals lda Animating ; turn off animation interrupts beq AnimateOkay jsr Animate AnimateOkay lda ClockToggle ; turn off 1 second interrupts beq ClockOkay jsr ClockShutdown ClockOkay rtl *===== * * Hard references * CallTable anop dc r'ChooseColor' dc r'RandomLine' dc r'LinesStartup' dc r'ColorsStartup' dc r'ConicsStartup' dc r'SlidesStartup' dc r'DithersStartup' dc r'PolygonsStartup' dc r'MacrameStartup' dc r'Installer' dc r'KeyHandler' dc r'HandleApple' dc r'HandleFile' dc r'HandleEdit' dc r'HandleDemos' dc r'HandleOptions' dc r'MenuRelease' dc r'MenuTrack' dc r'MeecesUp' dc r'HandleMouse' END **************************************************************** * * Installer * **************************************************************** Installer START using LibGlobals using DemoGlobals lda QuitFlags bne JustShutdown PushLong ScreenRgn ; open up the clipping _SetClip _HideCursor ; put the cursor away PushPtr UserBackground ; get a pointer to the current pattern _BackPat ; set the current pattern PushLong BackgrndRgn ; the background area _EraseRgn ; clear to pastel blue _ShowCursor ; put it back up JustShutdown ldx CurrentTask ; they're all multiples of 2 beq NothingActive jsr (ShutdownTask,x) ; shut down the task bra NothingActive ; jump around casetab ShutdownTask dc i2'NoEvent' ; NoEvent dc i2'LinesShutdown' ; Lines dc i2'DithersShutdown' ; Rectangles dc i2'ConicsShutdown' ; Conics dc i2'ColorsShutdown' ; Colors dc i2'SlidesShutdown' ; Slide Show dc i2'PolygonsShutdown' ; Polygons dc i2'MacrameShutdown' ; Macrame NothingActive ldx NewTask ; get the new task stx CurrentTask ; save it txa lsr A ; get a sta CurrentDemo ; remember it for menus beq Idle ; jump around casetab jsr (StartupTask,x) ; start up the task Done rtl Idle pea NullEvent ; turn off all tasks pea NoEvent ; point handler at an rts jsr SetHandler ; set it rtl ; and return StartupTask dc i2'NoEvent' ; NoEvent dc i2'LinesStartup' ; Lines dc i2'DithersStartup' ; Rectangles dc i2'ConicsStartup' ; Conics dc i2'ColorsStartup' ; Colors dc i2'SlidesStartup' ; Slide Show dc i2'PolygonsStartup' ; Polygons dc i2'MacrameStartup' ; Macrame END **************************************************************** * * KeyHandler * **************************************************************** KeyHandler START using LibGlobals using DemoGlobals lda EvtMsg and #$00FF cmp #32 ; is it a space? bne NotSpace TogglePause ENTRY lda PauseFlag eor #$FFFF sta PauseFlag beq ReEnableTask pea NullEvent pea NoEvent jsr SetHandler rts ReEnableTask pea NullEvent ldx CurrentTask ; what are we running now lda TaskTable,x ; get the address pha ; push it jsr SetHandler ; previous task is back in business rts NotSpace cmp #49 ; is it a '1' bne NotOne lda ColorToggle eor #$FFFF sta ColorToggle rts NotOne rts END **************************************************************** * * HandleMouse * **************************************************************** HandleMouse START using LibGlobals using DemoGlobals pea MouseDownEvent pea NoEvent jsr SetHandler lda EvtWhere ; get y coordinate bmi EatIt ; if <0, wait for mouseup cmp #12 ; was it in menu bar bpl CheckClick ; go see if the user wants it * It was in the menu bar. Let's reroute NullEvent to MenuTrack and MouseUp * event to MenuRelease. PushLong ScreenRgn _SetClip ; open it up so text will work pea MouseUpEvent pea MenuRelease jsr SetHandler pea NullEvent pea MenuTrack jsr SetHandler rts CheckClick lda CurrentTask ; make sure we have a window up beq Eatit lda ClickHandler beq Eatit ldx #0 jsr (ClickHandler,x) rts * It was somewhere else. Let's just eat the release so nothing bad happens. Eatit pea MouseUpEvent pea MeecesUp jsr SetHandler pea NullEvent pea NoEvent jsr SetHandler rts END **************************************************************** * * MeecesUp * **************************************************************** MeecesUp START using LibGlobals using DemoGlobals jsr RestoreTask jsr RestoreMenus rts END **************************************************************** * * MenuTrack * **************************************************************** MenuTrack START using LibGlobals lda MousePos+2 ; push horizontal value pha lda MousePos ; push vertical value pha jsr TrackMenu rts END **************************************************************** * * HandleApple * **************************************************************** HandleApple START using LibGlobals using DemoGlobals cmp #1 bne TryClock jsr AboutBox rts TryClock cmp #2 ; is it the Alarm Clock bne TryModeSwitch lda ClockToggle beq TurnClockOn jsr ClockShutdown stz ClockToggle rts TurnClockOn pea 544 ; x value for display pea 9 ; y value for display jsr ClockInit lda #1 sta ClockToggle rts TryModeSwitch cmp #3 bne TryColorPanel lda FirstScb and #$00FF eor #$80 pha pha _SetAllSCBs pla and #$80 beq ModeIs320 pei (MyColorTable) ; do this first so it looks good PushPtr OldTable ; it was read from battery ram _SetColorTable rts ModeIs320 jsr Synthesize pei (MyColorTable) PushPtr Table320 _SetColorTable rts Table320 dc i2'0,0,0,$0999,0,0,0,0,0,0,0,0,$0777,0,0,$FFFF' TryColorPanel cmp #4 bne Done jsr ColorPanel rts Done rts Synthesize lda OldTable+2 jsr Disemble lda Temp sta Table320+8 ; entry 4 sta Table320+10 ; 5 sta Table320+12 ; 6 lda Temp+2 sta Table320+14 ; 7 lda OldTable+4 jsr Disemble lda Temp sta Table320+16 sta Table320+18 sta Table320+20 lda Temp+2 sta Table320+22 lda OldTable+10 jsr Disemble lda Temp+2 sta Table320+26 lda Temp sta Table320+2 ldx Table320+10 jsr Combine sta Table320+10 lda Temp ldx Table320+18 jsr Combine sta Table320+18 lda OldTable+12 jsr Disemble lda Temp+2 sta Table320+28 lda Temp sta Table320+4 ldx Table320+12 jsr Combine sta Table320+12 lda Temp ldx Table320+20 jsr Combine sta Table320+20 rts Disemble tay and #$0F00 clc adc #$0100 lsr A and #$0F00 sta Temp tya and #$00F0 clc adc #$0010 lsr A and #$00F0 ora Temp sta Temp tya and #$000F ina lsr A and #$000F ora Temp sta Temp tya and #$0F00 eor #$0F00 lsr A and #$0F00 eor #$0F00 sta Temp+2 tya and #$00F0 eor #$00F0 lsr A and #$00F0 eor #$00F0 ora Temp+2 sta Temp+2 tya and #$000F eor #$000F lsr A and #$000F eor #$000F ora Temp+2 sta Temp+2 rts Combine tay and #$0F00 sta Temp+4 txa and #$0F00 clc adc Temp+4 beq DD1 dea DD1 and #$0F00 sta Temp+6 tya and #$00F0 sta Temp+4 txa and #$00F0 clc adc Temp+4 beq DD2 dea DD2 and #$00F0 ora Temp+6 sta Temp+6 tya and #$000F sta Temp+4 txa and #$000F clc adc Temp+4 beq DD3 dea DD3 and #$000F ora Temp+6 rts END **************************************************************** * * HandleFile * **************************************************************** HandleFile START using LibGlobals using DemoGlobals cmp #9 bne NotSave jsr HiliteFile jsr DumpScreen jsr HiliteFile rts NotSave cmp #$0A ; is it Quit? bne NotQuit inc QuitFlags NotQuit rts END **************************************************************** * * HandleEdit * **************************************************************** HandleEdit START rts END **************************************************************** * * HandleDemos * **************************************************************** HandleDemos START using LibGlobals using DemoGlobals asl A cmp CurrentTask beq Done sta NewTask jsl Installer Done rts END **************************************************************** * * HandleOptions * **************************************************************** HandleOptions START using LibGlobals using DemoGlobals cmp #1 ; is it colors? bne NotColors lda ColorToggle eor #$FFFF sta ColorToggle rts NotColors cmp #2 ; Pausing? bne NotPausing jsr TogglePause rts NotPausing cmp #3 ; Window/Full Screen? bne NotWindowing * Deinstall the task, then start it up again with MACRO &lab PushPtr &TheLabel &lab dc i1'$F4' dc i'&TheLabel|-16' dc i1'$F4' dc i'&TheLabel' MEND MACRO &LAB PUSHWORD &WHATTOPUSH LCLC &CHAR &CHAR AMID &WHATTOPUSH,1,1 AIF "&CHAR"="#",.IMMEDIATE &LAB LDA &WHATTOPUSH PHA MEXIT .IMMEDIATE &CHAR AMID &WHATTOPUSH,2,100 &LAB DC I1'$F4' DC I2'&CHAR' MEND MACRO &LAB PUSHLONG &WHATTOPUSH LCLC &CHAR &CHAR AMID &WHATTOPUSH,1,1 AIF "&CHAR"="#",.IMMEDIATE &LAB LDA &WHATTOPUSH+2 PHA LDA &WHATTOPUSH PHA MEXIT .IMMEDIATE &CHAR AMID &WHATTOPUSH,2,100 &LAB13456789 DC I1'$F4' DC I2'(&CHAR)|-16' DC I1'$F4' DC I2'&CHAR' MEND MACRO &lab MoveLong &From,&To &lab lda &From sta &To lda &From+2 sta &To+2 MEND MACRO &lab _DisposHandle &lab ldx #$1002 jsl $E10000 MEND MACRO &lab _SetHeartBeat &lab ldx #$1203 jsl $E10000 MEND MACRO &lab _DelHeartBeat &lab ldx #$1303 jsl $E10000 MEND MACRO &lab _SetColorTable &lab ldx #4+256*14 jsl $E10000 MEND MACRO &lab _SetClip &lab ldx #4+256*36 jsl $E10000 MEND MACRO &lab _MoveTo &lab ldx #4+256*58 jsl $E10000 MEND MACRO &lab _LineTo &lab ldx #4+256*60 jsl $E10000 MEND MACRO &lab _FrameRect &lab ldx #4+256*83 jsl $E10000 MEND MACRO &lab _PaintRect &lab ldx #4+256*84 jsl $E10000 MEND MACRO &lab _DisposeRgn &lab ldx #4+256*104 jsl $E10000 MEND MACRO &lab _CopyRgn &lab ldx #4+256*105 jsl $E10000 MEND MACRO &lab _RectRgn &lab ldx #4+256*108 jsl $E10000 MEND MACRO &lab _OpenRgn &lab ldx #4+256*109 jsl $E10000 MEND MACRO &lab _CloseRgn &lab ldx #4+256*110 jsl $E10000 MEND MACRO &lab _SectRgn &lab ldx #4+256*113 jsl $E10000 MEND MACRO &lab _UnionRgn &lab ldx #4+256*114 jsl $E10000 MEND MACRO &lab _DiffRgn &lab ldx #4+256*115 jsl $E10000 MEND MACRO &lab _XorRgn &lab ldx #4+256*116 jsl $E10000 MEND MACRO &lab _EmptyRgn &lab ldx #4+256*120 jsl $E10000 MEND MACRO &lab _PaintRgn &lab ldx #4+256*122 jsl $E10000 MEND MACRO &lab _EraseRgn &lab ldx #4+256*123 jsl $E10000 MEND MACRO &lab _HideCursor &lab ldx #4+256*144 jsl $E10000 MEND MACRO &lab _ShowCursor &lab ldx #4+256*145 jsl $E10000 MEND MACRO &lab _SetTextMode &lab ldx #4+256*156 jsl $E10000 MEND MACRO &lab _SetForeColor &lab ldx #4+256*160 jsl $E10000 MEND MACRO &lab _SetBackColor &lab ldx #4+256*162 jsl $E10000 MEND MACRO &lab _DrawString &lab ldx #4+256*165 jsl $E10000 MEND MACRO &lab _StringWidth &lab ldx #4+256*169 jsl $E10000 MEND MACRO &lab _PaintPoly &lab ldx #4+256*189 jsl $E10000 MEND MACRO &lab _OpenPoly &lab ldx #4+256*193 jsl $E10000 MEND MACRO &lab _ClosePoly &lab ldx #4+256*194 jsl $E10000 MEND MACRO &lab _KillPoly &lab ldx #4+256*195 jsl $E10000 MEND MACRO &lab _PenSize &lab ldx #4+256*44 jsl $E10000 MEND MACRO &lab _BackPat &lab ldx #4+256*52 jsl $E10000 MEND MACRO &lab _FixMul &lab ldx #$0F0B jsl $E10000 MEND MACRO &lab _FrameOval &lab ldx #4+256*88 jsl $E10000 MEND MACRO &lab _PaintArc &lab ldx #4+256*99 jsl $E10000 MEND MACRO &lab _SetAllSCBs &lab ldx #4+256*20 jsl $E10000 MEND MACRO &lab _EraseRect &lab ldx #4+256*85 jsl $E10000 MEND MACRO &lab _PaintPixels &lab ldx #4+256*127 jsl $E10000 MEND MACRO &lab _DrawChar &lab ldx #4+256*164 jsl $E10000 MEND MACRO &lab _GetClip &lab ldx #4+256*37 jsl $E10000 MEND MACRO &lab _ReadAsciiTime &lab ldx #$0F03 jsl $E10000 MEND MACRO &lab _SetVector &lab ldx #$1003 jsl $E10000 MEND MACRO &lab _GetVector &lab ldx #$1103 jsl $E10000 MEND MACRO &lab _IntSource &lab ldx #$2303 jsl $E10000 MEND MACRO &lab _SetSCB &lab ldx #4+256*18 jsl $E10000 MEND MACRO &lab _GetColorTable &lab ldx #4+256*15 jsl $E10000 MEND MACRO &lab _GetSCB &lab ldx #4+256*19 jsl $E10000 MEND **************************************************************** * * WindowsInit * **************************************************************** WindowsInit START using LibGlobals using DemoGlobals jsr NewRegion sta Clipper stx Clipper+2 jsr NewRegion sta WindowRgn stx WindowRgn+2 jsr NewRegion sta ContentRgn stx ContentRg:<=>?@ABCDEFGHIJn+2 lda #22 sta WindowRect lda #192 sta WindowRect+4 lda #20 sta WindowRect+2 lda #620 sta WindowRect+6 * Initialize the close box rect lda WindowRect ; Y1 clc adc #3 sta CloseBox adc #7 sta CloseBox+4 lda WindowRect+2 ; X1 adc #13 sta CloseBox+2 adc #16 sta CloseBox+6 * Initialize the rect we hilite when the close box is hit lda CloseBox ina sta CloseLite lda CloseBox+2 ina ina sta CloseLite+2 lda CloseBox+4 dea sta CloseLite+4 lda CloseBox+6 dea dea sta CloseLite+6 * Fetch the current clipping PushLong Clipper _GetClip PushLong WindowRgn PushPtr WindowRect _RectRgn rts END **************************************************************** * * WindowShutdown * **************************************************************** WindowsShutdown START using LibGlobals using DemoGlobals MoveLong Clipper,Handle ldx #Handle jsr UnlockHandle PushLong Clipper _DisposeRgn MoveLong ContentRgn,Handle ldx #Handle jsr UnlockHandle PushLong ContentRgn _DisposeRgn MoveLong WindowRgn,Handle ldx #Handle jsr UnlockHandle PushLong WindowRgn _DisposeRgn rts END **************************************************************** * * SetWindowTitle * **************************************************************** SetWindowTitle START using LibGlobals using DemoGlobals plx ; pull return address pla ; pull string pointer sta Pointer pla sta Pointer+2 phx ; push return address back lda [Pointer] and #$00FE ; just the length byte (made even) tay ; point y at last word in string CopyLoop lda [Pointer],y ; get a word sta WindowTitle,y ; save a word dey dey bpl CopyLoop rts END **************************************************************** * * DrawWindow * **************************************************************** DrawWindow START using LibGlobals using DemoGlobals pea $0002 pea $0001 _PenSize ; PenSize(2,1) * Set the pen and background colors as well as the text colors. pea $0000 ; black jsr SetPenColor ; set it pea $FFFF ; white jsr SetBackColor ; set it PushWord #$0000 ; black text _SetForeColor PushWord #$FFFF ; on a white background _SetBackColor * Clear the window and frame it PushPtr WindowRect _EraseRect PushPtr WindowRect _FrameRect * Draw the close box PushPtr CloseBox _FrameRect * Draw the cross piece under the title lda WindowRect+6 ; X2 dea dea dea pha lda WindowRect ; Y1 clc adc #12 ; add 12 pha ; push it pha ; fake it pha ; push it again lda WindowRect+2 ; X1 sta 3,s ; store it in the right place _MoveTo ; Y1+12,X1 _LineTo ; Y1+12,X2 * Draw four little lines left of the close box lda WindowRect ; Y1 ina ina ina sta YLine lda WindowRect+2 ; X1 clc adc #4 sta LineStart adc #5 sta LineStop lda #4 sta LineCount jsr TitleLines ; draw them based on x,y registers * Now draw the longer lines lda WindowRect ; Y1 ina ina ina sta YLine lda WindowRect+2 ; X1 clc adc #31 sta LineStart lda WindowRect+6 ; X2 sec sbc #6 sta LineStop lda #4 sta LineCount jsr TitleLines ; draw them based on x,y registers * Create the content rect lda WindowRect ; get Y1 clc adc #13 sta ContentRect lda WindowRect+4 ; get Y2 dea ; decrement it sta ContentRect+4 lda WindowRect+2 ina ina sta ContentRect+2 lda WindowRect+6 dea dea sta ContentRect+6 PushLong ContentRgn ; push nil PushPtr ContentRect ; push a pointer to it _RectRgn ; create a rectangular content region pea 0 PushPtr WindowTitle _StringWidth pla eor #$FFFF ; negate it ina ; -x+1 clc adc WindowRect+2 ; Width + WindowLeft adc WindowRect+6 ; Width + (Window.Center * 2) lsr A ; Window.Center - (Width div 2) pha ; push X lda WindowRect ; get top clc adc #10 ; position for text in window pha ; push Y _MoveTo PushPtr WindowTitle ; push the string _DrawString rts TitleLines lda LineCount sta PushCount TitleLoop lda LineStart pha lda YLine pha _MoveTo lda LineStop pha lda Yline pha ina ina sta YLine _LineTo dec LineCount bne TitleLoop rts END **************************************************************** * * ChooseColor * **************************************************************** ChooseColor START using LibGlobals using DemoGlobals pea 0 pea 0 pea 255 jsr Prndm ; leaves a number (0..255) TOS ldy ColorToggle beq BrightColors cpy #$FFFF bne BrightColors KMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ jsr SetPenPattern rts BrightColors jsr SetPenColor rts END **************************************************************** * * Procedure MaybeDrawWindow * **************************************************************** MaybeDrawWindow START using LibGlobals using DemoGlobals lda Windowing beq FullScreen jsr DrawWindow rts FullScreen lda BackgrndRect sta ContentRect lda BackgrndRect+2 sta ContentRect+2 lda BackgrndRect+4 sta ContentRect+4 lda BackgrndRect+6 sta ContentRect+6 PushLong BackgrndRgn PushLong ContentRgn _CopyRgn rts END **************************************************************** * * Procedure RandomLline * **************************************************************** RandomLine START using LibGlobals using DemoGlobals pea $000A ; h=10 pea $0005 ; v=5 _PenSize pea 0 ; function return pea 0 ; lower limit pea 200 ; upper limit jsr Prndm ; get a number 0 <= x <= 200 pla sta TempRect pea 0 pea 0 lda ScreenRect+6 pha jsr Prndm ; Prndm(0,Right) pla sta TempRect+2 pea 0 pea 0 pea 200 jsr Prndm pla sta TempRect+4 pea 0 pea 0 lda ScreenRect+6 pha jsr Prndm pla sta TempRect+6 jsr ChooseColor lda TempRect+2 pha lda TempRect pha _MoveTo ; MoveTo (h,v); lda TempRect+6 pha lda TempRect+4 pha _LineTo ; LineTo (h,v) rts END **************************************************************** * * Lines * **************************************************************** LinesStartup START using LibGlobals using DemoGlobals pea NullEvent pea LinesTask jsr SetHandler lda #Lines sta CurrentTask stz LineCount PushPtr LinesTitle jsr SetWindowTitle jsr MaybeDrawWindow rts **************************************************************** * * Lines Data * **************************************************************** HalfX ds 2 TempRgn ds 4 NextRgn ds 4 TempRect dc i4'Y1' ds 2 Y1 ds 2 X1 ds 2 Y2 ds 2 X2 ds 2 Operation dc i2'6' LinesTitle anop dc i1'LinesTEnd-LinesTitle-1' dc c' Region Ops Demo ' LinesTEnd anop **************************************************************** * * LinesShutdown * **************************************************************** LinesShutdown ENTRY rts **************************************************************** * * AddToClipping * **************************************************************** AddToClipping ENTRY jsr NewRegion sta TempRgn stx TempRgn+2 jsr NewRegion sta NextRgn stx NextRgn+2 pea 0 pea 0 pea 99 jsr Prndm ; random top pla sta Y1 ; save it pea 0 pea 0 pea 320 jsr Prndm pla sta X1 pea 0 pea 100 pea 200 jsr Prndm pla sta Y2 ; save it pea 0 pea 320 pea 640 jsr Prndm pla sta X2 ; save it and #1 beq MakeRect _OpenRgn PushLong TempRect _FrameOval PushLong TempRgn _CloseRgn bra ClipIt MakeRect PushLong TempRgn ; our destination PushLong TempRect ; our source _RectRgn ; create a rectangular region ClipIt PushLong Clipper ; first region PushLong TempRgn ; add on region PushLong NextRgn ; destination lda Operation ; random op ina ina and #6 ; 0,2,4,6 sta Operation tax jmp (CaseTable,x) ; do this op CaseTable dc i'SectCall' dc i'DiffCall' dc i'UnionCall' dc i'XorCall' SectCall _SectRgn ; Clipper & TempRgn bra Continue DiffCall _DiffRgn ; Clipper - TempRgn bra Continue UnionCall _UnionRgn ; Clipper + TempRgn bra Continue XorCall _XorRgn ; Clipper % TempRgn Continue pea 0 PushLong NextRgn _EmptyRgn pla beq NotEmpty PushLong NextRgn _DisposeRgn Movelong TempRgn,NextRgn bra Join NotEmpty PushLong TempRgn _DisposeRgn ; kill this one, too Join PushLong NextRgn PushLong ContentRgn PushLong Clipper _SectRgn PushLong NextRgn _DisposeRgn ; kill it rts ; all done **************************************************************** * * ScreenTask * **************************************************************** ScreenTask ENTRY jsr AddToClipping PushLong ContentRgn _SetClip pea 0 pea 0 pea 15 jsr Prndm lda 1,s ; get top of stack pha ; push it as a parameter jsr SetBackColor pea 0 pea 0 pea 14 jsr Prndm pla sec ; to add 1 adc 1,s ; add in the previous color and #$000F ; clear unused bits plx ; get rid of background color pha ; push the right one jsr SetPenColor PushLong ContentRgn _EraseRgn PushLong Clipper _PaintRgn rts **************************************************************** * * LinesTask * **************************************************************** LinesTask ENTRY lda LineCount bne DrawLine jsr ScreenTask lda #$80 sta LineCount DrawLine dec LineCount PushLong Clipper ; make Clipper the clip region _SetClip jsr RandomLine rts END **************************************************************** * * Dithers * **************************************************************** DithersStartup START using LibGlobals using DemoGlobals pea NullEvent pea DithersTask jsr SetHandler lda #Dithers sta CurrentTask PushPtr DithersTitle jsr SetWindowTitle jsr MaybeDrawWindow rts **************************************************************** * * Dithers Data * **************************************************************** TempRect dc i4'Y1' ds 2 Y1 ds 2 X1 ds 2 Y2 ds 2 X2 ds 2 DithersTitle anop dc i1'DithersTEnd-DithersTitle-1' dc c' Rectangles Demo ' DithersTEnd anop **************************************************************** * * DithersShutdown * **************************************************************** DithersShutdown ENTRY rts **************************************************************** * * DithersTask * **************************************************************** DithersTask ENTRY using LibGlobals using DemoGlobals PushLong ContentRgn _SetClip pea 0 pea 0 lda ContentRect pha lda ContentRect+4 dea ; don't generate a null rectangle pha jsr Prndm pla sta Y1 pha ; push it again lda ContentRect+4 pha jsr Prndm pla sta Y2 pea 0 pea 0 lda ContentRect+2 pha lda ContentRect+6 dea pha jsr Prndm pla sta X1 pha ; push it again lda ContentRect+6 pha jsr Prndm pla sta X2 jsr ChooseColor PushLong TempRect _PaintRect rts END *===== * * Slide Show * SlidesStartup START using LibGlobals using DemoGlobals pea NullEvent pea SlidesTask jsr SetHandler lda #Slides sta CurrentTask PushPtr SlidesTitle jsr SetWindowTitle jsr MaybeDrawWindow stz SlideTimer stz SlideTimer+2 lda SlideChar ; start over at A and #$FF00 ora #$0040 sta SlideChar * Copy palette 0 to 1 pea 0 PushPtr TempTable _GetColorTable pea 1 PushPtr TempTable _SetColorTable * Change scan lines [12..199] to use palette 1 lda #12 ; first scan line SCBLoop sta Temp pha ; push scan line pea $0081 ; 640 mode, palette 1 _SetSCB ; switch over to using 1 lda Temp ina cmp #200 bne SCBLoop rts *===== * * Read image * NextImage pea Watch jsr SetCursor lda SlideChar and #$00FF cmp #$005A ; is it already a Z? bne JustBump lda #$0040 ; pred('A) JustBump ina ; next letter sta Temp lda SlideChar and #$FF00 ; clear character ora Temp ; OR in the character sta SlideChar ; put it back PushPtr SlideFilename ; the name of the file PushLong BuffPtr ; push our menu buffer PushLong #$8000 ; read 64 blocks, unpacked jsr LoadFile ; do it bcc GotAFile lda SlideChar ; start over at A and #$FF00 ora #$0040 sta SlideChar GotAFile php ; save state pea Arrow jsr SetCursor plp ; restore state rtl ; leave carry set accordingly *===== * * Slides Data * SlideTimer ds 4 TimerValue dc i4'$1000' TempTable ds 34 NextSCB ds 2 NextScanline ds 2 SlideFilename dc i1'7' dc c'SLIDE.' SlideChar dc c'A.' SlidesTitle anop dc i1'SlidesTEnd-SlidesTitle-1' dc c' Apple IIgs Imaging ' SlidesTEnd anop *===== * * SlidesShutdown * SlidesShutdown ENTRY jsr BottomCorners * Change scan lines [12..199] to use palette 0 and be in 640 mode lda #12 ; first scan line SCBLoop3 sta Temp pha ; push scan line pea $0080 ; 640 mode, palette 1 _SetSCB ; switch over to using 1 lda Temp ina cmp #200 bne SCBLoop3 rts *===== * * SlidesTask * SlidesTask ENTRY sec lda SlideTimer sbc #1 sta SlideTimer bcs KeepTicking dec SlideTimer+2 bmi NextSlide KeepTicking rts NextSlide jsl NextImage bcc DisplayImage stz SlideTimer stz SlideTimer+2 rts DisplayImage lda TimerValue sta SlideTimer lda TimerValue+2 sta SlideTimer+2 * Draw the image to the screen. Set palettes a scan line at a time WindowOffset equ 5605 PictureOffset equ 4325 ; SlideOffset-10 lines (1600) WindowWidth equ 150 ; width in bytes WindowHeight equ 156 ; number of lines to transfer FullOffset equ 1920 FullWidth equ 160 FullHeight equ 188 LeftMask equ Prndm_Lo RightMask equ Prndm_Hi ShowPainting ENTRY PaletteOffset equ $7E00 ; offset to palette 0 SCBOffset equ $7D00 ; offset to 1st SCB * Copy palette 1 to 2 pea 1 PushPtr TempTable _GetColorTable pea 2 PushPtr TempTable _SetColorTable * Change scan lines [12..199] to use palette 2 lda #SCBOffset+12 sta NextSCB lda #12 ; first scan line sta NextScanline SCBLoop2 sta Temp pha ; for _SetSCB call pea 0 ; result pha ; push scan line _GetSCB pla ; SCB and #$FFF0 ; save all but palette ora #$0002 ; set palette 2 pha ; push the new scb _SetSCB ; switch over to using 2 lda Temp ina cmp #200 bne SCBLoop2 pea 1 ; palette lda BuffPtr ; push pointer to palette 0 of image clc adc #PaletteOffset tax lda BuffPtr+2 bcc NBP ina NBP pha phx _SetColorTable _HideCursor lda BuffPtr sta Pointer sta Handle lda BuffPtr+2 sta Pointer+2 sta Handle+2 lda #($2000+FullOffset) sta Screen lda #$00E1 sta Screen+2 lda #FullWidth sta FastWidth lda #FullHeight sta FastHeight lda #$FFFF sta LeftMask lda #$FFFF sta RightMask NextLine lda NextScanline pha ina sta NextScanline ldy NextSCB ; get next SCB lda [Handle],y iny sty NextSCB and #$00F0 ; clear palette number ora #$0001 pha _SetSCB ; change from palette 2 to 1 ldy FastWidth ; set y dey ; decrement y by 2, point at last word dey lda [Pointer],y ; get the source and RightMask ; 2 black pixels on the right (maybe) sta [Screen],y ; save it away dey dey NextWord lda [Pointer],y ; get the source sta [Screen],y ; save it to storage dey ; dock y dey ; dock it again bne NextWord ; if it isn't negative, do some more lda [Pointer] ; get left edge source and LeftMask ; 2 black pixels on the left sta [Screen] ; put the left edge dec FastHeight beq FinishUp lda Screen ; get the last screen position clc adc #160 ; increment by a scan line of bytes sta Screen ; save it for next time lda Pointer ; get the source pointer clc adc #160 sta Pointer ; save it for next time bcc NoBumpPtr inc Pointer+2 NoBumpPtr brl NextLine ; go do another one * We may have to repaint the blue rounded corners, but only if we are * not in 320 mode. FinishUp lda $E12000+SCBOffset+12 ; quick test for 640 mode and #$0080 beq Mandolin jsr BottomCorners Mandolin _ShowCursor rts END **************************************************************** * * Polygons * **************************************************************** PolygonsStartup START using LibGlobals using DemoGlobals pea NullEvent pea PolygonsTask jsr SetHandler lda #Polygons sta CurrentTask PushPtr PolygonsTitle jsr SetWindowTitle jsr MaybeDrawWindow rts **************************************************************** * * Polygons Data * **************************************************************** Points ds 2 PolygonsTitle anop dc i1'PolygonsTEnd-PolygonsTitle-1' dc c' Polygons Demo ' PolygonsTEnd anop **************************************************************** * * PolygonsShutdown * **************************************************************** PolygonsShutdown ENTRY rts **************************************************************** * * PolygonsTask * **************************************************************** PolygonsTask ENTRY PushLong ContentRgn _SetClip pea 0 pea 2 pea 12 jsr Prndm pla sta Points pea 0 pea 0 _OpenPoly pla sta Handle pla sta Handle+2 pea 0 lda ContentRect+2 ina ina pha lda ContentRect+6 dea dea pha jsr Prndm pea 0 lda ContentRect ina ina pha lda ContentRect+4 dea dea pha jsr Prndm _MoveTo PointLoop pea 0 lda ContentRect+2 ina ina pha lda ContentRect+6 dea dea pha jsr Prndm pea 0 lda ContentRect ina ina pha lda ContentRect+4 dea dea pha jsr Prndm _LineTo dec Points bne PointLoop _ClosePoly jsr ChooseColor PushLong Handle _PaintPoly PushLong Handle _KillPoly rts END **************************************************************** * * Macrame * **************************************************************** MacrameStartup START using LibGlobals using DemoGlobals pea NullEvent pea MacrameTask jsr SetHandler lda #Macrame sta CurrentTask PushPtr MacrameTitle jsr SetWindowTitle jsr MaybeDrawWindow PushLong ContentRgn _SetClip pea 0 ; black jsr SetPenColor PushPtr ContentRect _PaintRect stz PtsToGo stz SpiroColor clc lda ContentRect+4 adc ContentRect lsr A sta MidHeight sec lda ContentRect+4 sbc ContentRect lsr A dea sta MaxRadius lsr A lsr A sta MinRadius ; MaxRadius div 4 rts **************************************************************** * * Macrame Data * **************************************************************** PtCtr ds 2 NextPoint ds 2 PtsToGo ds 2 Angle ds 10 ; index into Sin/CosTabs (0..23)*4 Radius ds 10 ; current radius MidHeight ds 2 OldMacX ds 2 OldMacY ds 2 SpiroColor ds 2 MinRadius ds 2 MaxRadius ds 2 SinTab dc i4'$00000000' ; 0 dc i4'$00004241' ; 15 dc i4'$00008000' ; 30 dc i4'$0000B505' ; 45 dc i4'$0000DD64' ; 60 dc i4'$0000F747' ; 75 dc i4'$00010000' ; 90 dc i4'$0000F747' ; 105 dc i4'$0000DD64' ; 120 dc i4'$0000B505' ; 135 dc i4'$00008000' ; 150 dc i4'$00004241' ; 165 dc i4'$00000000' ; 180 dc i4'$FFFFBDBF' ; 195 dc i4'$FFFF8000' ; 210 dc i4'$FFFF4AFB' ; 225 dc i4'$FFFF229C' ; 240 dc i4'$FFFF08B9' ; 255 dc i4'$FFFF0000' ; 270 dc i4'$FFFF08B9' ; 285 dc i4'$FFFF229C' ; 300 dc i4'$FFFF4AFB' ; 315 dc i4'$FFFF8000' ; 330 dc i4'$FFFFBDBF' ; 345 * The cosine table has the aspect ratio built in, so that values are extended * in the horizontal direction and will look symmetrical. CosTab dc i4'$0002CCCD' ; 0 dc i4'$0002B460' ; 15 dc i4'$00026CC4' ; 30 dc i4'$0001FAD6' ; 45 dc i4'$00016666' ; 60 dc i4'$0000B986' ; 75 dc i4'$00000000' ; 90 dc i4'$FFFF467A' ; 105 dc i4'$FFFE999A' ; 120 dc i4'$FFFE052A' ; 135 dc i4'$FFFD933C' ; 150 dc i4'$FFFD4BA0' ; 165 dc i4'$FFFD3333' ; 180 dc i4'$FFFD4BA0' ; 195 dc i4'$FFFD933C' ; 210 dc i4'$FFFE052A' ; 225 dc i4'$FFFE999A' ; 240 dc i4'$FFFF467A' ; 255 dc i4'$00000000' ; 270 dc i4'$0000B986' ; 285 dc i4'$00016666' ; 300 dc i4'$0001FAD6' ; 315 dc i4'$00026CC4' ; 330 dc i4'$0002B460' ; 345 MacrameTitle anop dc i1'MacrameTEnd-MacrameTitle-1' dc c' Macrame Demo ' MacrameTEnd anop **************************************************************** * * MacrameShutdown * **************************************************************** MacrameShutdown ENTRY rts **************************************************************** * * MacrameTask * **************************************************************** MacrameTask ENTRY PushLong ContentRgn _SetClip lda PtsToGo bne DrawNextPoint ldx #0 PtLoop stx PtCtr pea 0 lda MinRadius pha lda MaxRadius pha jsr Prndm pla ldx PtCtr sta Radius,x pea 0 pea 0 pea 23 jsr Prndm pla asl A ; each entry is 4 bytes wide asl A ldx PtCtr sta Angle,x inx inx cpx #10 bmi PtLoop DnLoop ldx #8 stx NextPoint * Call CalcPoint to seed OldMacX and OldMacY. This will also advance Angle * for the last of the five points, but Angle is arbitrary anyway, so what * the heck. jsr CalcPoint ; to seed OldMacX and OldMacY lda #120 sta PtsToGo pea 0 pea 0 pea 14 jsr Prndm pla ina clc adc SpiroColor and #$000F ; one of 16 colors (0..15) sta SpiroColor DrawNextPoint lda OldMacX pha lda OldMacY pha _MoveTo lda SpiroColor pha jsr SetPenColor pea $0002 ; h=2 pea $0001 ; v=1 _PenSize jsr CalcPoint ; resets OldMacX and OldMacY lda OldMacX pha lda OldMacY pha _LineTo dec PtsToGo rts CalcPoint pea 0 ; the function result pea 0 ldx NextPoint lda Radius,x pha ; push the radius pea 0 ; no fractional part lda Angle,x ; get the current angle index tax lda CosTab+2,x ; push the corresponding cos value pha lda CosTab,x pha _FixMul ; calculate R * CosTab(Angle) clc pla ; discard the fractional part pla adc #320 sta OldMacX ; this is where we are headed pea 0 ; function result pea 0 ldx NextPoint ; get the same point lda Radius,x pha ; push the radius pea 0 ; no fractional part lda Angle,x ; get the current angle index tax lda SinTab+2,x ; push the corresponding sin value pha lda SinTab,x pha _FixMul ; calculate R * CosTab(Angle) clc pla ; discard the fractional part pla adc MidHeight sta OldMacY ; this is where we are headed ldx NextPoint lda Angle,x ina ; bump Angle to next one ina ina ina cmp #96 bmi NoZeroAngle lda #0 NoZeroAngle sta Angle,x inx inx cpx #10 bmi NoZeroX ldx #0 NoZeroX stx NextPoint rts END **************************************************************** * * Animate * **************************************************************** Animate START using LibGlobals using DemoGlobals SpinMax equ 128 lda Animating bne Inanimate inc Animating ; animating := true stz Suspended ; suspended := false lda #SpinFaster sta ControlTable+22 ; up arrow lda #SpinSlower sta ControlTable+20 ; line feed lda #SpinPause sta ControlTable+18 ; tab * Initialize VBL task and starting spin value lda MyColorTable sta SpinColorTable lda SpinValue sta TaskValue PushPtr SpinTask _SetHeartBeat rts Inanimate stz Animating ; animating := false stz ControlTable+22 ; up arrow stz ControlTable+20 ; line feed stz ControlTable+18 ; tab stz ControlTable+16 ; backspace stz ControlTable+42 ; forward space stz TaskValue ; shut down the VBL PushPtr SpinTask _DelHeartBeat jsr ReadPalette pei (MyColorTable) ; the color table PushPtr OldTable _SetColorTable ; put it back to normal rts SpinSlower lda SpinValue cmp #SpinMax bpl NoBump inc SpinValue NoBump rts SpinFaster lda SpinValue cmp #1 beq NoDock dec SpinValue NoDock rts * SpinPause and SpinResume are made entries for the color wheel code, so * it can stop animation and restart it without interfering with other * stuff. It will call it when you make a color table change. SpinPause ENTRY lda Animating beq NotAnimating lda Suspended bne NotAnimating inc Suspended lda #SpinResume sta ControlTable+18 lda #SpinStep sta ControlTable+42 ; forward space lda #SpinBackstep sta ControlTable+16 stz TaskValue NotAnimating rts Suspended dc i2'0' SpinColorTable dc i2'1' SpinResume ENTRY lda Animating beq NotAnimating lda Suspended beq NotAnimating stz Suspended lda #SpinPause sta ControlTable+18 stz ControlTable+42 stz ControlTable+16 lda SpinValue sta TaskValue rts SpinStep lda SpinTab+2 clc adc #3 sta SpinTab+2 sta SpinTab+18 lda SpinTab+4 clc adc #5 sta SpinTab+4 sta SpinTab+20 lda SpinTab+10 clc adc #7 sta SpinTab+10 sta SpinTab+26 lda SpinTab+12 clc adc #11 sta SpinTab+12 sta SpinTab+28 lda SpinColorTable pha PushPtr SpinTab _SetColorTable ; change it rts SpinBackstep lda SpinTab+2 ora #$F000 sec sbc #3 sta SpinTab+2 sta SpinTab+18 lda SpinTab+4 ora #$F000 sec sbc #5 sta SpinTab+4 sta SpinTab+20 lda SpinTab+10 ora #$F000 sec sbc #7 sta SpinTab+10 sta SpinTab+26 lda SpinTab+12 ora #$F000 sec sbc #11 sta SpinTab+12 sta SpinTab+28 pei (MyColorTable) PushPtr SpinTab _SetColorTable ; change it rts SpinTab dc i2'$0000,$0F00,$00F0,$0FFF' dc i2'$0000,$000F,$0FF0,$0FFF' dc i2'$0000,$0F00,$00F0,$0FFF' dc i2'$0000,$000F,$0FF0,$0FFF' SpinValue dc i2'16' SpinTask dc i4'0' TaskValue dc i2'16' TaskSig dc i2'$A55A' rep #$30 jsr SpinStep lda SpinValue sta TaskValue sep #$30 rtl ; return to interrupt handler END *===== * * Dump screen * DumpScreen START pea Watch jsr SetCursor _HideCursor * First copy the screen into BuffPtr so we can clean up the bottom and add * the scan line and palette information. lda #($2000+12*160) sta FastSrc lda #$00E1 sta FastSrc+2 lda BuffPtr sta FastDst lda BuffPtr+2 sta FastDst+2 lda #160 sta FastSLen sta FastDLen sta FastWidth lda #200-12 sta FastHeight jsr FastCopy * Clear the last 12 lines to black lda #12 sta FastHeight dec FastWidth dec FastWidth NextLine ldy FastWidth ; set y lda #0 ; black FillLoop sta [FastDst],y ; store black dey dey bpl FillLoop ; if it isn't negative, do some more lda FastDst ; get the last screen position clc adc FastDLen ; increment by a scan line of bytes sta FastDst ; save it for next time bcc NBFD inc FastDst+2 NBFD dec FastHeight ; one less scan line bne NextLine ; if not zero, do the next line * Copy the palette information over phb pea $E1E1 plb plb ldy #0 MoreSCBCopy lda $9D00,y ; offset to SCB info sta [FastDst],y ; copy standard SCB into BuffPtr iny iny cpy #$300 bne MoreSCBCopy plb PushPtr DumpFilename ; the name of the file PushLong BuffPtr ; push our menu buffer PushLong #$8000 ; write 64 blocks, unpacked jsr SaveFile ; do it pea Arrow jsr SetCursor _ShowCursor rts DumpFileName dc i1'8' dc c'SCREEN.0' END **************************************************************** * * Colors * **************************************************************** ColorsStartup START using LibGlobals using DemoGlobals pea NullEvent pea ColorsTask jsr SetHandler lda #Colors sta CurrentTask PushPtr ColorsTitle jsr SetWindowTitle jsr DrawWindow jsr NewRegion sta RectsRgn stx RectsRgn+2 lda #255 sta CurrentColor PushLong ContentRgn _SetClip * We desire a region which is a big, black triangle covering the lower left * portion of the content region of the window. We'll start by drawing the * diagonal line which cuts through each of the small color boxes. _OpenRgn lda ContentRect+2 ; X1 pha clc lda ContentRect ; Y1 adc #3 ; a crude guess pha _MoveTo lda ContentRect+6 ; X2 pha sec lda ContentRect+4 ; Y2 sbc #4 ; another crude guess pha _LineTo * We are going to ignore the vertical lines. Putline wouldn't add them * to the region anyway. So all we have to do is draw the bottom line. lda ContentRect+2 ; X1 pha lda ContentRect+4 ; Y2 pha _MoveTo lda ContentRect+6 ; X2 pha lda ContentRect+4 ; Y2 pha _LineTo PushLong RectsRgn _CloseRgn pea $0000 jsr SetPenColor PushLong RectsRgn _PaintRgn lda #16 sta RowCtr lda #41 ; initial Y1 sta Y1 clc bra NoBumpRow NextRow clc lda Y1 adc #9 ; space between rect tops sta Y1 NoBumpRow adc #8 ; size of a rect sta Y2 lda #16 sta ColumnCtr lda #32 ; initial X1 sta X1 clc bra NoBumpColumn NextColumn clc lda X1 adc #36 ; space between rect lefts sta X1 NoBumpColumn adc #32 ; size of a rect sta X2 lda CurrentColor pha jsr SetPenPattern dec CurrentColor PushPtr Y1 _PaintRect dec ColumnCtr bne NextColumn dec RowCtr bne NextRow rts **************************************************************** * * Colors Data * **************************************************************** Y1 ds 2 X1 ds 2 Y2 ds 2 X2 ds 2 RowCtr ds 2 ColumnCtr ds 2 CurrentColor ds 2 RectsRgn ds 4 ColorsTitle anop dc i1'ColorsTEnd-ColorsTitle-1' dc c' Colors Demo ' ColorsTEnd anop **************************************************************** * * ColorsShutdown * **************************************************************** ColorsShutdown ENTRY PushLong RectsRgn _DisposeRgn rts **************************************************************** * * ColorsTask * **************************************************************** ColorsTask ENTRY PushLong ContentRgn _SetClip * jsr DoColors rts END **************************************************************** * * ConicStartup * **************************************************************** ConicsStartup START using LibGlobals using DemoGlobals pea NullEvent pea ConicsTask jsr SetHandler lda #Conics sta CurrentTask PushPtr ConicsTitle jsr SetWindowTitle jsr MaybeDrawWindow rts **************************************************************** * * Conics Data * **************************************************************** Y1 ds 2 X1 ds 2 Y2 ds 2 X2 ds 2 ConicsTitle anop dc i1'ConicsTEnd-ConicsTitle-1' dc c' Conics Demo ' ConicsTEnd anop **************************************************************** * * ConicsShutdown * **************************************************************** ConicsShutdown ENTRY rts **************************************************************** * * ConicsTask * **************************************************************** ConicsTask ENTRY PushLong ContentRgn _SetClip pea 0 pea 0 lda ContentRect pha lda ContentRect+4 dea ; don't generate a null rectangle pha pha jsr Prndm pla sta Y1 pha ; push it again lda ContentRect+4 pha jsr Prndm pla sta Y2 pea 0 pea 0 lda ContentRect+2 pha lda ContentRect+6 dea pha jsr Prndm pla sta X1 pha ; push it again lda ContentRect+6 pha jsr Prndm pla sta X2 jsr ChooseColor * jsr RandomPenSize PushPtr Y1 pea 0 pea 0 pea 359 jsr Prndm lda 1,s pea 0 clc adc #5 pha clc adc #350 pha jsr Prndm _PaintArc rts PushWandH pea 0 ; push OvalWidth pea 0 sec lda X2 sbc X1 pha jsr Prndm pea 0 ; push OvalHeight pea 0 sec lda Y2 sbc Y1 pha jsr Prndm pla ; pull ovalheight ply ; pull ovalwidth plx ; pull return phy ; push ovalwidth pha ; push ovalheight phx ; push return rts RandomPenSize pea 0 pea 1 pea 20 jsr Prndm pla tax asl A pha sta $2002 phx stx $2000 _PenSize rts END ************************************************************** * * AboutBox * ************************************************************* AboutBox START using LibGlobals using DemoGlobals Height equ 122 Width equ 120 StartByte equ 20 StartLine equ 50 TextItems equ 12 * Initialize parameters for the About Box. pea $FBFF ; block out almost everything jsr SaveState PushLong ScreenRgn _SetClip jsr HiLiteApple lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(StartLine*160+StartByte) ; offset ($2000) to first pixel sta MenuStart ; in bytes jsr SaveScreen ; save out what's underneath stz FastFlags ; nothing fancy, just a standard window jsr DrawFastWindow ; let's draw a fast window pea 0 _SetForeColor pea 3 _SetBackColor lda #0 ; number of items to print TextLoop sta TextCtr asl A ; multiply by 8 asl A asl A tax lda TextTable+6,x pha lda TextTable+4,x pha lda TextTable+2,x pha lda TextTable,x pha _MoveTo _DrawString lda TextCtr ina ; decrement counter cmp #TextItems bmi TextLoop pea MouseUpEvent ; point mouse releases at us pea ClearAbout jsr SetHandler rts TextCtr ds 2 TextTable anop dc i2'61,90' dc i4'S1' dc i2'73,90' dc i4'S2' dc i2'85,90' dc i4'S3' dc i2'94,90' dc i4'S4' dc i2'103,90' dc i4'S5' dc i2'112,90' dc i4'S6' dc i2'121,90' dc i4'S7' dc i2'130,90' dc i4'S8' dc i2'139,90' dc i4'S9' dc i2'148,90' dc i4'S10' dc i2'157,90' dc i4'S11' dc i2'166,90' dc i4'S12' S1 dc i1'S2-S1-1' dc c'LW/Demo Copyright (C) 1987' dc c' by Apple Computer' S2 dc i1'S3-S2-1' dc c' Version' dc c' 1.0 - January 31, 1987' S3 dc i1'S4-S3-1' dc c'LW/Demo features the Apple IIgs Super-Hires 640 mode. It' S4 dc i1'S5-S4-1' dc c'generates 16 bright colors using simple dithering and a special' S5 dc i1'S6-S5-1' dc c'feature of the Apple IIgs hardware, namely that even and odd' S6 dc i1'S7-S6-1' dc c'pixels may be assigned independent color palettes. For even' S7 dc i1'S8-S7-1' dc c'pixels, the four standard colors are black, red, green, and' S8 dc i1'S9-S8-1' dc c'white. For odd pixels, the four colors are black, blue, yellow,' S9 dc i1'S10-S9-1' dc c'and white. When viewed as a pair, 16 dithered colors are the' S10 dc i1'S11-S10-1' dc c'result, essentially lowering the resolution to 320. However,' S11 dc i1'S12-S11-1' dc c'since any pixel can be black or white, the resolution in black' S12 dc i1'S13-S12-1' dc c'and white remains at 640, allowing crisp, 80-column text.' S13 anop ClearAbout jsr RestoreScreen ; put the window back jsr RestoreState ; reset the current task jsr HiliteApple ; turn off the about box rts ; get out of here END *===== * * Desk clock * DeskClock START using LibGlobals ClockOn dc i2'0' ClockFlag dc i2'0' ClockX ds 2 ClockY ds 2 OldVector ds 4 TimeStr dc c'MM/DD/YY 12:00:00 am ' ClockInit ENTRY lda ClockOn beq NotOn jsr ClockShutdown NotOn plx ; pull return pla ; get Y sta ClockY ; save it pla ; get X sta ClockX ; save it phx ; push return back inc ClockOn ; we're here! jsr ShowClock ; draw us pea 0 ; space for result pea 0 pea $15 ; one second interrupt handler _GetVector pla ; get low word sta OldVector pla ; get high word sta OldVector+2 pea $15 ; one second interrupt handler PushPtr ClockInterrupt _SetVector ; set the vector pea $06 ; specify 1 second source _IntSource ; turn source on rts ClockInterrupt anop ; interrupts run in 8 bit mode longa off phb phk ; set our program bank plb inc ClockFlag ; bump our semaphore pea 0 ; set bank 0 plb plb lda #$02 tsb $C032 ; fiddle with interrupt stuff plb clc rtl longa on ClockUpdate ENTRY lda ClockOn bne ClockIsOn rts ClockIsOn lda ClockFlag bne ShowClock rts ShowClock anop PushPtr TimeStr _ReadAsciiTime lda TimeStr+8 and #$7F7F sta TimeStr+8 lda TimeStr+10 and #$7F7F sta TimeStr+10 lda TimeStr+12 and #$7F7F sta TimeStr+12 lda TimeStr+14 and #$7F7F sta TimeStr+14 lda TimeStr+16 and #$7F7F sta TimeStr+16 lda TimeStr+18 and #$7F7F * If it's two spaces ($2020) nothing happens, but if it's 'AM' or 'PM', then * it becomes 'am' or 'pm'. ora #$2020 sta TimeStr+18 BlankingEntry stz ClockFlag PushLong ScreenRgn _SetClip pea $0000 ; black text _SetForeColor pea $0003 ; white background _SetBackColor lda ClockX pha lda ClockY pha _MoveTo lda TimeStr+8 and #$FF00 ; remove space ora #$000F ; add in length, plus extra spaces sta TimeStr+8 PushLong #TimeStr+8 _DrawString rts ClockShutdown ENTRY pea $07 ; disable 1 second interrupt source _IntSource pea $15 ; 1 second interrupts PushLong OldVector ; push old vector _SetVector ; set it back where it was stz ClockOn ; shut down our own flag stz ClockFlag ; and make sure we're cool lda #$FFFF ; all white sta FastColor lda #(135+2*160) ; bytes to start sta FastStart lda #24 ; width sta FastWidth lda #8 ; height sta FastHeight jsr FastFill ; clear it rts ; go home END ************************************************************** * * SaveState/RestoreState * ************************************************************* SaveState START using LibGlobals using DemoGlobals plx ; get local return ply ; get event mask sty EventMask ; save this, too phx ; push return back ldx #0 SaveLoop tya ; get mask back lsr A ; look at the bottom bit tay ; update mask bcc DontSave ; if its not set, continue lda EventTable,x ; get the current event sta SavedEvent,x ; save it lda #NoEvent ; zero out the old one sta EventTable,x ; by setting it to a null return DontSave inx ; bump x to next entry inx cpx #32 ; are we done yet? bne SaveLoop ; if not, continue jsr NewRegion sta SaveClip stx SaveClip+2 PushLong SaveClip _GetClip rts SavedEvent dc 16i2'NoEvent' SaveClip ds 4 EventMask ds 2 RestoreState ENTRY ldy EventMask ; get event mask ldx #0 RestoreLoop tya ; get mask back lsr A ; look at the bottom bit tay ; update mask bcc DontRestore ; if its not set, continue lda SavedEvent,x ; get the current event sta EventTable,x ; save it lda #NoEvent ; zero out the old one sta SavedEvent,x ; by setting it to a null return DontRestore inx ; bump x to next entry inx cpx #32 ; are we done yet? bne RestoreLoop ; if not, continue PushLong SaveClip _SetClip MoveLong SaveClip,Handle ldx #Handle jsr UnlockHandle PushLong Handle _DisposeRgn rts END * Table of Contents * * 1. Menus.Asm * * SetAppleMenu Set initial values based on the Apple menu * DoApple Show the Apple menu * DoFile Show the File menu * DoEdit Show the Edit menu * DoDemos Show the Demos menu * DoOptions Show the Options menu **************************************************************** * * AppleMenu * **************************************************************** DoApple START using LibGlobals using ScreenGlobals using DemoGlobals Height equ 46 Width equ 38 ; number of bytes for menu (192 pixels) StartByte equ 2 Border equ 28 ; Apple menu text start lda #AppleMenu sta CurrentMenu * Initialize menu parameters for the Apple menu. lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(12*160+StartByte) ; offset from $2000 to first pixel sta MenuStart ; in bytes lda #StartByte sta MenuByte lda #(StartByte+Width) sta MenuEnd jsr SaveScreen ; save out what's underneath jsr DrawBlankMenu ; draw a blank menu field jsr SetFadeInfo ; set up fast fade values * Draw all the black line dividers lda #(23*160+StartByte) ; offset for the underline sta MenuLineStart jsr DrawMenuLine ; draw a line under the About item MyFirstSCB equ $E19D00 * Set up menu flags lda #MenuActive ; get active flag ldy #(MenuActive+MenuOverlined) ; get active flag sta MenuData+4 ; About box sty MenuData+12 ; Alarm clock sta MenuData+20 ; 320/640 Mode stz MenuData+28 ; ColorPanel lda >MyFirstSCB and #$80 beq NoPanelActive lda #MenuActive sta MenuData+28 NoPanelActive anop * Set up drawing colors PushWord #0 ; black text _SetForeColor PushWord #3 ; white background _SetBackColor * About Box - active pea Border ; H pea 21 ; V _MoveTo PushPtr Apple1 _DrawString * Clock - active pea Border pea 32 _MoveTo lda ClockToggle bne HideIt PushPtr Apple2a bra ClockIt HideIt PushPtr Apple2b ClockIt _DrawString * 320/640 Mode pea Border pea 43 _MoveTo lda MyFirstSCB ; to get rid of the link error and #$80 beq BackTo640 PushPtr Apple3a ; 320 Mode bra DoDraw BackTo640 PushPtr Apple3b DoDraw _DrawString * Color Panel - active in 640 mode pea Border pea 54 _MoveTo PushPtr Apple4 _DrawString PushWord StdTextMode _SetTextMode lda MyFirstSCB and #$80 bne PanelActive lda #(160*45+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr PanelActive rts HiLiteApple ENTRY lda #11 ; scan lines in title bar sta FastHeight lda #12 ; width to hilite, in bytes sta FastWidth lda #StartByte ; offset from $2000 to first pixel sta FastStart ; in bytes lda AppleToggle eor #$FFFF sta AppleToggle beq NormalApple lda #0000 ; black sta FastColor jsr FastFill ; erase to black PushPtr BlackAppleInfo _PaintPixels rts NormalApple lda #$FFFF ; white sta FastColor jsr FastFill PushPtr AppleInfo _PaintPixels rts Apple1 dc i1'16' dc c'About LW/Demo...' Apple2a dc i1'10' dc c'Show Clock' Apple2b dc i1'10' dc c'Hide Clock' Apple3a dc i1'8' dc c'320 Mode' Apple3b dc i1'8' dc c'640 Mode' Apple4 dc i1'11' dc c'Color Panel' SetFadeInfo ENTRY ; call after savescreen lda MenuWidth ; get menu width dea dea dea ; take away left edge dea ; take away right edge sta FastWidth ; save it, too lda #$DDDD ; fade it to pastel blue sta FastColor ; the color used in the OR operation PushWord #$8003 ; black text, anded _SetTextMode rts END **************************************************************** * * DoFile * **************************************************************** DoFile START using LibGlobals using DemoGlobals Height equ 112 Width equ 40 StartByte equ 12 Border equ 68 lda #FileMenu sta CurrentMenu * Initialize menu parameters for the File menu. lda #Height sta MenuHeight lda #Width sta MenuWidth lda #(12*160+StartByte) sta MenuStart lda #StartByte sta MenuByte lda #(StartByte+Width) sta MenuEnd jsr SaveScreen ; save what's under the menu jsr DrawBlankMenu ; draw a blank menu jsr SetFadeInfo ; set up fast fade values * Set initial flags lda #MenuActive ; get active flag ldy #(MenuActive+MenuOverlined) ; active and overlined stz MenuData+4 ; New... stz MenuData+12 ; Open... (-) stz MenuData+20 ; Close stz MenuData+28 ; Save stz MenuData+36 ; Save as... stz MenuData+44 ; Save a copy as... stz MenuData+52 ; Revert (-) stz MenuData+60 ; Page setup sta MenuData+68 ; Print (-) sty MenuData+76 ; Quit is active * Draw all the black line dividers lda #(34*160+StartByte) ; offset for the underline sta MenuLineStart jsr DrawMenuLine ; draw a line under the About item lda #(89*160+StartByte) ; offset for the underline sta MenuLineStart jsr DrawMenuLine ; draw a line under the About item lda #(111*160+StartByte) ; offset for the underline sta MenuLineStart jsr DrawMenuLine ; draw a line under the About item * Draw all the text PushWord #0 ; black text _SetForeColor PushWord #3 ; white background _SetBackColor * New pea Border ; H pea 21 ; V _MoveTo PushPtr File1 _DrawString lda #(160*12+StartByte+1) sta FastStart ; start there lda #10 ; let's cheat and always do 10 sta FastHeight ; save it jsr FastOr ; nothing left but to do it * Open pea Border pea 32 _MoveTo PushPtr File2 _DrawString lda #(160*23+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Close pea Border pea 43 _MoveTo PushPtr File3 _DrawString lda #(160*35+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Save pea Border pea 54 _MoveTo PushPtr File4 _DrawString lda #(160*45+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Save as... pea Border pea 65 _MoveTo PushPtr File5 _DrawString lda #(160*56+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Save a copy as... pea Border pea 76 _MoveTo PushPtr File6 _DrawString lda #(160*67+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Revert pea Border pea 87 _MoveTo PushPtr File7 _DrawString lda #(160*78+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Page Setup pea Border pea 98 _MoveTo PushPtr File8 _DrawString lda #(160*90+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Print pea Border pea 109 _MoveTo PushPtr File9 _DrawString * lda #(160*100+StartByte+1) * sta FastStart * lda #10 ; let's cheat and always do 10 * sta FastHeight * jsr FastOr * Quit pea Border ; Quit pea 120 _MoveTo PushPtr File10 _DrawString PushWord StdTextMode _SetTextMode rts HiLiteFile ENTRY lda #11 ; scan lines in title bar sta FastHeight lda #14 ; width to hilite, in bytes sta FastWidth lda #StartByte ; offset from $2000 to first pixel sta FastStart ; in bytes lda #$FFFF ; invert all sta FastColor jsr FastXor rts File1 dc i1'6' dc c'New...' File2 dc i1'7' dc c'Open...' ; followed by a line File3 dc i1'5' dc c'Close' File4 dc i1'4' dc c'Save' File5 dc i1'10' dc c'Save as...' File6 dc i1'17' dc c'Save a copy as...' File7 dc i1'6' dc c'Revert' ; followed by a line File8 dc i1'13' dc c'Page Setup...' File9 dc i1'11' dc c'Dump Screen' ; followed by a line File10 dc i1'4' dc c'Quit' END **************************************************************** * * DoEdit * **************************************************************** DoEdit START using LibGlobals using DemoGlobals Height equ 68 Width equ 36 ; number of bytes for menu StartByte equ 24 Border equ 116 ; Edit menu text start lda #EditMenu sta CurrentMenu * Initialize menu parameters for the Edit menu. lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(12*160+StartByte) ; offset from $2000 to first pixel sta MenuStart ; in bytes lda #StartByte sta MenuByte lda #(StartByte+Width) sta MenuEnd jsr SaveScreen ; save out what's underneath jsr DrawBlankMenu ; draw a blank menu field jsr SetFadeInfo ; set up fast fade values * Black line lda #(23*160+StartByte) ; offset for the underline sta MenuLineStart jsr DrawMenuLine ; draw a line under the About item * Set initial flags lda #MenuActive ; get active flag stz MenuData+4 ; 1st item inactive stz MenuData+12 ; 2nd item inactive stz MenuData+20 stz MenuData+28 stz MenuData+36 stz MenuData+44 * All items in this list are inactive. Draw them, then fade them out. PushWord #0 _SetForeColor PushWord #3 _SetBackColor * Undo pea Border ; H pea 21 ; V _MoveTo PushPtr Edit1 _DrawString lda #(160*12+StartByte+1) sta FastStart ; start there lda #10 ; let's cheat and always do 10 sta FastHeight ; save it jsr FastOr ; nothing left but to do it * Cut pea Border pea 32 _MoveTo PushPtr Edit2 _DrawString lda #(160*24+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Copy pea Border pea 43 _MoveTo PushPtr Edit3 _DrawString lda #(160*34+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Paste pea Border pea 54 _MoveTo PushPtr Edit4 _DrawString lda #(160*45+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Clear pea Border pea 65 _MoveTo PushPtr Edit5 _DrawString lda #(160*56+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Select All pea Border pea 76 _MoveTo PushPtr Edit6 _DrawString lda #(160*67+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr PushWord StdTextMode _SetTextMode rts HiLiteEdit ENTRY lda #11 ; scan lines in title bar sta FastHeight lda #14 ; width to hilite, in bytes sta FastWidth lda #StartByte ; offset from $2000 to first pixel sta FastStart ; in bytes lda #$FFFF ; invert all sta FastColor jsr FastXor rts Edit1 dc i1'4' dc c'Undo' Edit2 dc i1'3' dc c'Cut' Edit3 dc i1'4' dc c'Copy' Edit4 dc i1'5' dc c'Paste' Edit5 dc i1'5' dc c'Clear' Edit6 dc i1'10' dc c'Select All' END **************************************************************** * * DoDemos * **************************************************************** DoDemos START using LibGlobals using DemoGlobals Height equ 79 Width equ 32 ; number of bytes for menu StartByte equ 37 Border equ 168 ; Demos menu text start lda #DemosMenu sta CurrentMenu * Initialize menu parameters for the Demos menu. lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(12*160+StartByte) ; offset from $2000 to first pixel sta MenuStart ; in bytes lda #StartByte sta MenuByte lda #(StartByte+Width) sta MenuEnd jsr SaveScreen ; save out what's underneath jsr DrawBlankMenu ; draw a blank menu field jsr SetFadeInfo ; set up fast fade values * Set initial flags lda #MenuActive ; get active flag sta MenuData+4 ; Region Clipping sta MenuData+12 ; Rectangles sta MenuData+20 ; Conics sta MenuData+28 ; Colors sta MenuData+36 ; Slide Show sta MenuData+44 ; Polygons sta MenuData+52 ; Macrame PushWord #0 ; black text _SetForeColor PushWord #3 ; white background _SetBackColor * Clipping pea Border ; H pea 21 ; V _MoveTo PushPtr Demos1 _DrawString * Rectangles pea Border pea 32 _MoveTo PushPtr Demos2 _DrawString * Conics pea Border pea 43 _MoveTo PushPtr Demos3 _DrawString * Paint pea Border pea 54 _MoveTo PushPtr Demos4 _DrawString * Slide Show pea Border pea 65 _MoveTo PushPtr Demos5 _DrawString * lda SlideCount * bne GotSlides * * lda #(160*56+StartByte+1) * sta FastStart * lda #10 ; let's cheat and always do 10 * sta FastHeight * jsr FastOr * *GotSlides anop * Polygons pea Border pea 76 _MoveTo PushPtr Demos6 _DrawString * Macrame pea Border pea 87 _MoveTo PushPtr Demos7 _DrawString * Set the check mark on the current demo ldx CurrentDemo beq OutOfHere pea Border-12 lda #10 clc MoreChecks adc #11 dex bne MoreChecks pha ; push V _MoveTo pea 18 ; push check mark _DrawChar OutOfHere PushWord StdTextMode _SetTextMode rts HiLiteDemos ENTRY lda #11 ; scan lines in title bar sta FastHeight lda #14 ; width to hilite, in bytes sta FastWidth lda #StartByte ; offset from $2000 to first pixel sta FastStart ; in bytes lda #$FFFF ; invert all sta FastColor jsr FastXor rts Demos1 dc i1'8' dc c'Clipping' Demos2 dc i1'10' dc c'Rectangles' Demos3 dc i1'6' dc c'Conics' Demos4 dc i1'6' dc c'Colors' Demos5 dc i1'10' dc c'Slide Show' Demos6 dc i1'8' dc c'Polygons' Demos7 dc i1'7' dc c'Macrame' END **************************************************************** * * DoOptions * **************************************************************** DoOptions START using LibGlobals using DemoGlobals Height equ 46 Width equ 40 ; number of bytes for menu StartByte equ 52 Border equ 224 ; Options menu text start lda #OptionsMenu sta CurrentMenu * Initialize menu parameters for the Options menu. lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(12*160+StartByte) ; offset from $2000 to first pixel sta MenuStart ; in bytes lda #StartByte sta MenuByte lda #(StartByte+Width) sta MenuEnd jsr SaveScreen ; save out what's underneath jsr DrawBlankMenu ; draw a blank menu field jsr SetFadeInfo ; set up fast fade values * Set initial flags lda #MenuActive ; get active flag sta MenuData+4 ; 16/136 Colors sta MenuData+12 ; Pause/Continue sta MenuData+20 ; Window/Full screen sta MenuData+28 ; Animation On/Off PushWord #0 ; black text _SetForeColor PushWord #3 ; white background _SetBackColor * 16/136 Colors pea Border ; H pea 21 ; V _MoveTo lda ColorToggle beq Color136 PushPtr Options1b bra CDraw Color136 PushPtr Options1a CDraw _DrawString * Pause/Continue pea Border pea 32 _MoveTo lda PauseFlag beq NoPausing PushPtr Options2b bra CPause NoPausing PushPtr Options2a CPause _DrawString * Window/Full Screen pea Border pea 43 _MoveTo lda Windowing beq WindowOn PushPtr Options3b bra CWindow WindowOn PushPtr Options3a CWindow _DrawString lda CanWindow bne WeGotWindows lda #(160*45+StartByte+1) sta FastStart ; start there lda #10 ; let's cheat and always do 10 sta FastHeight ; save it jsr FastOr ; nothing left but to do it WeGotWindows anop * Animation pea Border pea 54 _MoveTo lda Animating beq NoAnimate PushPtr Options4b bra CAnimate NoAnimate PushPtr Options4a CAnimate _DrawString PushWord StdTextMode _SetTextMode rts HiLiteOptions ENTRY lda #11 ; scan lines in title bar sta FastHeight lda #18 ; width to hilite, in bytes sta FastWidth lda #StartByte ; offset from $2000 to first pixel sta FastStart ; in bytes lda #$FFFF ; invert all sta FastColor jsr FastXor rts Options1a dc i1'10' dc c'136 Colors' Options1b dc i1'9' dc c'16 Colors' Options2a dc i1'5' dc c'Pause' Options2b dc i1'8' dc c'Continue' Options3a dc i1'7' dc c'Windows' Options3b dc i1'11' dc c'Full Screen' Options4a dc i1'17' dc c'Turn Animation On' Options4b dc i1'18' dc c'Turn Animation Off' END * Table of Contents * * 1. Menu.Asm * * MenuInit Initialize the menu module * MenuShutdown Close down the menu module * ClearMenu Clear the current menu, if any * TrackMenu Tracks the mouse in the menu bar * ReleaseMenu Handles a release in the menu manager **************************************************************** * * MenuInit * **************************************************************** MenuInit START   using LibGlobals using DemoGlobals lda #$8000 ; size of the handle ldx #BuffHandle ; where to put it jsr GetNewHandle ; allocate, lock, and dereference sta BuffPtr stx BuffPtr+2 stz CurrentMenu stz AppleToggle lda #MenuData sta MenuInfo lda #^MenuData sta MenuInfo+2 rts END **************************************************************** * * MenuShutdown * **************************************************************** MenuShutdown START using LibGlobals using DemoGlobals ldx #BuffHandle ; where to put it jsr UnlockHandle ; allocate, lock, and dereference PushLong BuffHandle _DisposHandle rts END **************************************************************** * * ClearMenu * **************************************************************** ClearMenu START using LibGlobals using DemoGlobals lda CurrentMenu beq Done jsr RestoreScreen lda CurrentMenu cmp #AppleMenu bne TryFile jsr HiliteApple bra Done TryFile cmp #FileMenu bne TryEdit jsr HiliteFile bra Done TryEdit cmp #EditMenu bne TryDemos jsr HiliteEdit bra Done TryDemos cmp #DemosMenu bne TryOptions jsr HiliteDemos bra Done TryOptions cmp #OptionsMenu bne Done jsr HiliteOptions Done stz CurrentMenu stz CurrentItem stz NewItem rts END **************************************************************** * * TrackMenu * **************************************************************** TrackMenu START using LibGlobals using DemoGlobals MenuLast equ 284 pla ; pull return ply ; get vertical plx ; get horizontal pha ; put return back tya cmp #12 ; set flags on Y-12 bmi InMenuBar ; see if there are items to check * We're in the item area, maybe lda CurrentMenu ; make sure we have items showing beq ClearItem ; if not, just leave sty Temp ; look at it tya ; get the vertical back sec sbc #(12-2) ; menu bar - menu border and shadow cmp MenuHeight ; are we somewhere in it bpl ClearItem ; if not, make sure nothing is lit txa ; get the horizontal lsr A ; divide by 4 pixels/byte lsr A cmp MenuByte ; is it past the left edge? bmi ClearItem ; no, clear it cmp MenuEnd ; is it before the right edge? bpl ClearItem ; no, clear it * It's somewhere in the item area. All we have to do is figure out * which one it is. ldx #$FFFF ; start with -1 tya ; get vertical back dea ; subtract the black line off ItemLoop inx ; bump x sec sbc #11 ; subtract item height bpl ItemLoop ; loop 'til it goes negative stx NewItem ; save the pointer jsr TrackItems ; track it rts ClearItem stz NewItem ; nothing to show jsr TrackItems ; track it rts * We're in the menu bar itself for this one. InMenuBar lda CurrentItem ; is there an item active? beq ItemOut stz NewItem phx jsr TrackItems ; clear any active items plx ItemOut txa ; get the horizontal cmp #8 ; set flags on X-8 bmi ClearIt ; if <8, clear any menus cmp #MenuLast ; set flags on X-MenuLast bpl ClearIt ; if >=MenuLast, clear any menus * We've found something cmp #48 bpl TryFile * It was the Apple menu lda CurrentMenu cmp #AppleMenu beq IgnoreApple jsr ClearMenu jsr HiliteApple jsr DoApple IgnoreApple rts * It was the file menu, by default ClearIt jsr ClearMenu stz CurrentItem rts TryFile cmp #96 bpl TryEdit lda CurrentMenu cmp #FileMenu beq IgnoreFile jsr ClearMenu jsr HiliteFile jsr DoFile IgnoreFile rts TryEdit cmp #148 bpl TryDemos lda CurrentMenu cmp #EditMenu beq IgnoreEdit jsr ClearMenu jsr HiliteEdit jsr DoEdit IgnoreEdit rts TryDemos cmp #208 bpl TryOptions lda CurrentMenu cmp #DemosMenu beq IgnoreDemos jsr ClearMenu jsr HiliteDemos jsr DoDemos IgnoreDemos rts TryOptions lda CurrentMenu cmp #OptionsMenu beq IgnoreOptions jsr ClearMenu jsr HiliteOptions jsr DoOptions IgnoreOptions rts END **************************************************************** * * TrackItems * **************************************************************** TrackItems START using LibGlobals using DemoGlobals ExtraHeight equ Prndm_K lda CurrentItem ; nop beq DontClear cmp NewItem beq Done jsr InvertItem DontClear stz CurrentItem lda NewItem beq Done dea ; zero base it asl A ; multiply by 8 asl A asl A clc adc #4 ; offset to flags tay lda [MenuInfo],y ; get flags tax ; save it and #MenuActive beq Done stz ExtraHeight txa ; get flags back and #MenuOverlined ; is there a line above us? beq NoOverline lda #10 ; spaces for overlined item sta ItemHeight lda #160 sta ExtraHeight bra T1 NoOverline lda #11 sta ItemHeight T1 pea 0 ; function return lda NewItem ; push new item dea ; zero base the item pha ; push it pea 1760 ; bytes between item starts jsr Multiply ; multiply them pla ; get result clc ; clear carry for adds adc ExtraHeight ; add in overline if necessary adc MenuStart ; add in offset to first item sta ItemStart ; save it jsr InvertItem lda NewItem sta CurrentItem Done rts END **************************************************************** * * ReleaseMenu * **************************************************************** ReleaseMenu START * Function returning the release (1..ItemLast) using LibGlobals using DemoGlobals pla ; get return ply ; get vertical plx ; get horizontal pha ; push return back phx ; push horizontal back phy ; push vertical back jsr TrackMenu ; update for the last time * Now let's see if we caught anything lda CurrentItem ; did we catch anything? sta 3,s ; just in case it's zero beq NoFlash ; ignore the fancy stuff lda CurrentMenu ; which menu is it xba ; swap the bytes ora CurrentItem ; or in the current item sta 3,s ; save it in the result jsr InvertItem ; flash it for now jsr InvertItem jsr InvertItem jsr InvertItem jsr InvertItem NoFlash jsr ClearMenu ; take the menu down rts ; and go home END * LIST OFF GEN off SYMBOL off KEEP lib 65816 on **************************************************************** * * Library - a library of useful routines and infrequently * assembled doodads. * **************************************************************** mcopy lib.mac Library START copy lib.equ copy lib.ref END copy globals.asm  copy lib.asm copy util.asm copy screen.asm copy menutil.asm copy control.asm copy mgr.asm copy event.asm copy panel.asm copy file.asm * Table of Contents * * 1. Equates.Asm * * ZeroPage usage * Zero page usage ZPHandle gequ 0 MyColorTable gequ ZPHandle+4 MyId gequ MyColorTable+2 ; value passed to _NewHandle, others MyAttributes gequ MyId+2 ; value passed to _NewHandle OldDirect gequ MyAttributes+2 AppDirect gequ OldDirect+2 OldBorderColor gequ AppDirect+2 FileSaver gequ OldBorderColor+2 BatteryRam gequ FileSaver+4 Handle gequ BatteryRam+2 Pointer gequ Handle+4 UserLocked gequ Pointer+4 * Math variables Seed gequ UserLocked+2 Temp gequ Seed+2 Multiplicand gequ Temp+4 ; These three can be used as temps Operand gequ Multiplicand+2 Factor gequ Operand+2 Prndm_Lo gequ Factor+2 ; so can these, upon occasion Prndm_Hi gequ Prndm_Lo+2 Prndm_K gequ Prndm_Hi+2 Prndm_A gequ Prndm_K+2 Prndm_B gequ Prndm_A+2 Prndm_AC gequ Prndm_B+2 Prndm_BC gequ Prndm_AC+2 * Fastrect variables FastHeight gequ Prndm_BC+2 FastWidth gequ FastHeight+2 FastStart gequ FastWidth+2 FastColor gequ FastStart+2 FastFlags gequ FastColor+2 FastTitle gequ FastFlags+2 FastWindow gequ FastTitle+4 * Menu manager variables MenuWidth gequ FastWindow+4 MenuHeight gequ MenuWidth+2 MenuDiff gequ MenuHeight+2 MenuStart gequ MenuDiff+2 MenuLineStart gequ MenuStart+2 MenuPtr gequ MenuLineStart+2 MenuLines gequ MenuPtr+4 Screen gequ MenuLines+2 BuffHandle gequ Screen+4 ;100 BuffPtr gequ BuffHandle+4 MenuInfo gequ BuffPtr+4 MenuByte gequ MenuInfo+4 MenuEnd gequ MenuByte+2 NewItem gequ MenuEnd+2 CurrentItem gequ NewItem+2 ItemHeight gequ CurrentItem+2 ItemStart gequ ItemHeight+2 * Control manager variables CtrlPtr gequ ItemStart+2 CtrlV gequ CtrlPtr+4 CtrlH gequ CtrlV+2 CtrlY1 gequ CtrlH+2 CtrlX1 gequ CtrlY1+2 CtrlY2 gequ CtrlX1+2 CtrlX2 gequ CtrlY2+2 CtrlFound gequ CtrlX2+2 CtrlHeight gequ CtrlFound+2 CtrlMsg gequ CtrlHeight+2 FastSrc gequ CtrlMsg+2 FastSLen gequ FastSrc+4 FastDst gequ FastSLen+2 FastDLen gequ FastDst+4 * Resource manager variables RsrcPtr gequ FastDLen+2 RsrcIndex gequ RsrcPtr+4 RsrcCtr gequ RsrcIndex+2 RsrcMax gequ RsrcCtr+2 NextZeroPage gequ RsrcMax+2 ;168 * Zero page allocation QDOffset gequ $100 EMOffset gequ $400 BRamOffset gequ $500 * Constants MaxInt gequ $3FFF CtrlSize gequ $2000 NullEvent gequ 0 MouseDownEvent gequ 1 MouseUpEvent gequ 2 KeyDownEvent gequ 3 KeyUpEvent gequ 4 AutoKeyEvent gequ 5 UpdateEvent gequ 6 DiskEvent gequ 7 ActivateEvent gequ 8 SwitcherEvent gequ 9 DeskAccEvent gequ 10 DevDriverEvent gequ 11 App1Event gequ 12 App2Event gequ 13 App3Event gequ 14 App4Event gequ 15 AppleMenu gequ 1 FileMenu gequ 2 EditMenu gequ 3 GoodiesMenu gequ 4 OptionsMenu gequ 5 MenuString gequ 0 ; pointer to item name string MenuFlags gequ 4 ; active / checked MenuShortcut gequ 6 ; shortcut character MenuCheck gequ 7 ; check style MenuActive gequ $0001 MenuChecked gequ $8000 MenuOverlined gequ $0002 * Fast window equates UnderBarFlag gequ $0001 CrossBarsFlag gequ $0002 CloseBoxFlag gequ $0004 ZoomBoxFlag gequ $0008 GrowBoxFlag gequ $0010 VScrollFlag gequ $0020 HScrollFlag gequ $0040 TitleFlag gequ $0080 * Control manager equates DrawMsg gequ 0 OffMsg gequ 1 OnMsg gequ 2 DownMsg gequ 3 UpdateMsg gequ 4 TrackMsg gequ 5 UnDrawMsg gequ 6 LastMsg gequ 7 PushButton gequ 0 SlideBar gequ 1 Button gequ 2 String gequ 3 CopyBlock gequ 4 Grid gequ 5 Dialog gequ 6 VScrollBar gequ 7 HScrollBar gequ 8 PatternGrid gequ 9 MaskGrid gequ 10 Line gequ 11 Rect gequ 12 Oval gequ 13 RRect gequ 14 Polygon gequ 15 Arc gequ 16 Arrow gequ 0 Pencil gequ 1 Watch gequ 2 Cross gequ 3 Square gequ 4 Brush gequ 5 LastCursor gequ 6 * Table of Contents * * References - this file contains hard references to all the routines * found in Library and should be included at the root level of your * program. * * Globals.Asm dc r'LibGlobals' * Lib.Asm dc r'OpenLibrary' dc r'CloseLibrary' * Util.Asm dc r'SetPenColor' dc r'SetBackColor' dc r'LoadColor' dc r'WaitForKey' dc r'Prndm' dc r'DerefHandle' dc r'UnlockHandle' dc r'ResizeHandle' dc r'GetNewHandle' dc r'NewRegion' dc r'Multiply' * Screen.Asm dc r'SetStdPort' dc r'ScreenGlobals' dc r'DrawMenu' dc r'SetTitleBar' dc r'DrawScreen' dc r'InitScreen' * Menu.Asm dc r'MenuInit' dc r'MenuShutdown' dc r'ClearMenu' dc r'TrackMenu' dc r'TrackItems' dc r'ReleaseMenu' * Menutil.Asm dc r'FastOps' dc r'MenuOpInit' dc r'SaveScreen' dc r'DrawBlankMenu' dc r'InvertItem' dc r'RestoreScreen' dc r'DrawMenuLine' dc r'DrawDialogTop' dc r'DrawCrossbars' dc r'DrawCloseBox' dc r'DrawFastWindow' dc r'PaintCorners' dc r'ReadPattern' dc r'BlankScreen' * Menus.Asm dc r'DoApple' dc r'DoFile' dc r'DoEdit' * dc r'DoGoodies' dc r'DoOptions' * Event.Asm dc r'GetHandler' dc r'SetHandler' dc r'ResetHandler' dc r'DeskEvent' dc r'EventManager' dc r'RestoreEvents' dc r'CheckMM' * Desk.Asm dc r'AboutBox' dc r'DeskClock' dc r'SaveState' * File.Asm dc r'FileStuff' * Panel.Asm dc r'ColorPanel' dc r'HexDigit' dc r'DrawColorValue' dc r'UpdateSliders' dc r'UpdateColors' dc r'UpdateTests' dc r'ShowFatBits' dc r'RotateButton' dc r'PanelData' * Control.Asm dc r'CtrlData' dc r'FastCopy' dc r'DrawCtrl' dc r'HitTest' dc r'PushButtonMgr' dc r'SlideMgr' dc r'ButtonMgr' dc r'StringMgr' dc r'CopyMgr' dc r'GridMgr' dc r'MsgResource' dc r'MsgControl' * Mgr.Asm dc r'DialogMgr' dc r'VScrollMgr' dc r'HscrollMgr' dc r'PatternGridMgr' dc r'LineMgr' dc r'RectMgr' dc r'OvalMgr' dc r'RoundRectMgr' dc r'ArcMgr' dc r'PolygonMgr' MACRO &lab PushPtr &TheLabel &lab dc i1'$F4' dc i'&TheLabel|-16' dc i1'$F4' dc i'&TheLabel' MEND MACRO &LAB PUSHWORD &WHATTOPUSH LCLC &CHAR &CHAR AMID &WHATTOPUSH,1,1 AIF "&CHAR"="#",.IMMEDIATE &LAB LDA &WHATTOPUSH PHA MEXIT .IMMEDIATE &CHAR AMID &WHATTOPUSH,2,100 &LAB DC I1'$F4' DC I2'&CHAR' MEND MACRO &LAB PUSHLONG &WHATTOPUSH LCLC &CHAR &CHAR AMID &WHATTOPUSH,1,1 AIF "&CHAR"="#",.IMMEDIATE &LAB LDA &WHATTOPUSH+2 PHA LDA &WHATTOPUSH PHA MEXIT .IMMEDIATE &CHAR AMID &WHATTOPUSH,2,100 &LAB "#$%&'()* DC I1'$F4' DC I2'(&CHAR)|-16' DC I1'$F4' DC I2'&CHAR' MEND MACRO &lab MoveLong &From,&To &lab lda &From sta &To lda &From+2 sta &To+2 MEND MACRO &lab ShadowOFF &lab anop AIF S:LONGA=1,.A php lda #%00011110 sta >$E0C035 plp MEXIT .A php sep #$30 longa off lda #%00011110 sta >$E0C035 longa on plp MEND MACRO &lab _TLStartup &lab ldx #$0201 jsl $E10000 MEND MACRO &lab _TLShutdown &lab ldx #$0301 jsl $E10000 MEND MACRO &lab _MMStartup &lab ldx #$0202 jsl $E10000 MEND MACRO &lab _MMShutDown &lab ldx #$0302 jsl $E10000 MEND MACRO &lab _NewHandle &lab ldx #$0902 jsl $E10000 MEND MACRO &lab _SetHandleSize &lab ldx #$1902 jsl $E10000 MEND MACRO &lab _DisposHandle &lab ldx #$1002 jsl $E10000 MEND MACRO &lab _MTStartup &lab ldx #3+256*2 jsl $E10000 MEND MACRO &lab _MTShutDown &lab ldx #3+256*3 jsl $E10000 MEND MACRO &lab _WriteBRAM &lab ldx #$0903 jsl $E10000 MEND MACRO &lab _ReadBRAM &lab ldx #$0A03 jsl $E10000 MEND MACRO &lab _ReadBParam &lab ldx #$0C03 jsl $E10000 MEND MACRO &lab _QDStartup &lab ldx #4+256*2 jsl $E10000 MEND MACRO &lab _QDShutDown &lab ldx #4+256*3 jsl $E10000 MEND MACRO &lab _GrafOff &lab ldx #4+256*11 jsl $E10000 MEND MACRO &lab _SetColorTable &lab ldx #4+256*14 jsl $E10000 MEND MACRO &lab _SetAllSCBs &lab ldx #4+256*20 jsl $E10000 MEND MACRO &lab _SetMasterSCB &lab ldx #4+256*22 jsl $E10000 MEND MACRO &lab _SetClip &lab ldx #4+256*36 jsl $E10000 MEND MACRO &lab _MoveTo &lab ldx #4+256*58 jsl $E10000 MEND MACRO &lab _LineTo &lab ldx #4+256*60 jsl $E10000 MEND MACRO &lab _FrameRect &lab ldx #4+256*83 jsl $E10000 MEND MACRO &lab _EraseRect &lab ldx #4+256*85 jsl $E10000 MEND MACRO &lab _NewRgn &lab ldx #4+256*103 jsl $E10000 MEND MACRO &lab _DisposeRgn &lab ldx #4+256*104 jsl $E10000 MEND MACRO &lab _CopyRgn &lab ldx #4+256*105 jsl $E10000 MEND MACRO &lab _RectRgn &lab ldx #4+256*108 jsl $E10000 MEND MACRO &lab _SectRgn &lab ldx #4+256*113 jsl $E10000 MEND MACRO &lab _PaintPixels &lab ldx #4+256*127 jsl $E10000 MEND MACRO &lab _SetCursor &lab ldx #4+256*142 jsl $E10000 MEND MACRO &lab _GetCursorAdr &lab ldx #4+256*143 jsl $E10000 MEND MACRO &lab _HideCursor &lab ldx #4+256*144 jsl $E10000 MEND MACRO &lab _ShowCursor &lab ldx #4+256*145 jsl $E10000 MEND MACRO &lab _SetTextMode &lab ldx #4+256*156 jsl $E10000 MEND MACRO &lab _SetForeColor &lab ldx #4+256*160 jsl $E10000 MEND MACRO &lab _SetBackColor &lab ldx #4+256*162 jsl $E10000 MEND MACRO &lab _DrawString &lab ldx #4+256*165 jsl $E10000 MEND MACRO &lab _StringWidth &lab ldx #4+256*169 jsl $E10000 MEND MACRO &lab _PenSize &lab ldx #4+256*44 jsl $E10000 MEND MACRO &lab _PenPat &lab ldx #4+256*48 jsl $E10000 MEND MACRO &lab _BackPat &lab ldx #4+256*52 jsl $E10000 MEND MACRO &lab _EMStartUp &lab ldx #6+256*2 jsl $E10000 MEND MACRO &lab _EMShutDown &lab ldx #6+256*3 jsl $E10000 MEND MACRO &lab _GetNextEvent &lab ldx #6+256*10 jsl $E10000 MEND MACRO &lab _UDivide &lab ldx #$0B0B jsl $E10000 MEND MACRO &lab _PaintRect &lab ldx #4+256*84 jsl $E10000 MEND MACRO &lab _GetColorTable &lab ldx #4+256*15 jsl $E10000 MEND MACRO &lab _PaintRgn &lab ldx #4+256*122 jsl $E10000 MEND MACRO &lab _FrameOval &lab ldx #4+256*88 jsl $E10000 MEND MACRO &lab _PaintOval &lab ldx #4+256*89 jsl $E10000 MEND MACRO &lab _FrameRRect &lab ldx #4+256*93 jsl $E10000 MEND MACRO &lab _PaintRRect &lab ldx #4+256*94 jsl $E10000 MEND MACRO &lab ErrorDeath &text &lab bcc end&syscnt pea 0 pea 0 pha ldx #$2A0B jsl $E10000 pla sta >y&syscnt pla sta >y&syscnt+2 pea x&syscnt|-16 pea x&syscnt ldx #$200C jsl $E10000 brk $F0 x&syscnt dc c"&text" dc c' Error was $' y&syscnt ds 4 dc i1'13,10,0' end&syscnt anop mend MACRO &lab _LoadTools &lab ldx #$0E01 jsl $E10000 MEND MACRO &lab _QUIT ¶ms &lab jsl $E100A8 dc i2"$29" dc i4"¶ms" MEND MACRO &lab _CREATE ¶ms &lab jsl $E100A8 dc i2"1" dc i4"¶ms" MEND MACRO &lab _DESTROY ¶ms &lab jsl $E100A8 dc i2"2" dc i4"¶ms" MEND MACRO &lab _OPEN ¶ms &lab jsl $E100A8 dc i2"$10" dc i4"¶ms" MEND MACRO &lab _READ ¶ms &lab jsl $E100A8 dc i2"$12" dc i4"¶ms" MEND MACRO &lab _CLOSE ¶ms &lab jsl $E100A8 dc i2"$14" dc i4"¶ms" MEND MACRO &lab _WRITE ¶ms &lab jsl $E100A8 dc i2"$13" dc i4"¶ms" MEND * Table of Contents * * 1. Globals.Asm * * LibGlobals **************************************************************** * * VAR LibGlobals * **************************************************************** LibGlobals DATA * Some standard definitions StdPenSize dc i'1,2' StdFGColor dc i'$0000' StdBGColor dc i'$FFFF' StdTextMode dc i'0' StdPalette dc i2'$0000,$0F00,$00F0,$0FFF' ; Black, Red, Green, White dc i2'$0000,$000F,$0FF0,$0FFF' ; B+-./0123456789:;<lack, Blue, Yellow, White dc i2'$0000,$0F00,$00F0,$0FFF' dc i2'$0000,$000F,$0FF0,$0FFF' * Some useful tables ColorTab dc i1'$00,$11,$22,$33' dc i1'$44,$55,$66,$77' dc i1'$88,$99,$AA,$BB' dc i1'$CC,$DD,$EE,$FF' WideColorTab dc i2'$0000,$1111,$2222,$3333' dc i2'$4444,$5555,$6666,$7777' dc i2'$8888,$9999,$AAAA,$BBBB' dc i2'$CCCC,$DDDD,$EEEE,$FFFF' * Screen rect and region information FakeScreenRgn dc i4'ScreenFake' ds 2 ScreenRgn ds 4 ScreenFake dc i'$64' ScreenRect dc i'0,0,$C8' ScreenRight dc i'$280' dc i2'$00,$08,$278,$3FFF' ; $12 dc i2'$01,$04,$08,$278,$27C,$3FFF' ; $1E dc i2'$02,$02,$04,$27C,$27E,$3FFF' ; $2A dc i2'$04,$00,$02,$27E,$280,$3FFF' ; $36 dc i2'$C4,$00,$02,$27E,$280,$3FFF' ; $42 dc i2'$C6,$02,$04,$27C,$27E,$3FFF' ; $4E dc i2'$C7,$04,$08,$278,$27C,$3FFF' ; $5A dc i2'$C8,$08,$278,$3FFF' ; $62 dc i2'$3FFF' ; $64 * Background rect, region, and pattern information BackgrndRgn ds 4 BackgrndRect dc i2'$0C,$00,$C8,$280' UserBackground dc h'D1D9111D19119D91D1D9111D19119D91' dc h'D1D9111D19119D91D1D9111D19119D91' * Some temporary variables TempPattern ds 32 TempRect ds 8 TempRgn ds 4 * Globals used by the event manager EventRecord ds 2 ; event code EvtMsg ds 4 EvtWhen ds 4 MousePos anop EvtWhere ds 4 EvtMods ds 2 QuitFlags dc i2'0' StdEvents dc i2'NoEvent' EventTable dc i'NoEvent' ; 0 dc i'NoEvent' ; 1 dc i'NoEvent' ; 2 dc i'NoEvent' ; 3 dc i'NoEvent' ; 4 dc i'NoEvent' ; 5 dc i'NoEvent' ; 6 dc i'NoEvent' ; 7 dc i'NoEvent' ; 8 dc i'NoEvent' ; 9 dc i'DeskEvent' ; 10 dc i'NoEvent' ; 11 dc i'NoEvent' ; 12 dc i'NoEvent' ; 13 dc i'NoEvent' ; 14 dc i'NoEvent' ; 15 ControlTable dc i2'0,0,0,0,0,0,0,0' dc i2'0,0,0,0,0,0,0,0' dc i2'0,0,0,0,0,0,0,0' dc i2'0,0,0,0,0,0,0,0' * Globals used by the menu manager MenuRect dc i2'0,0,11,640' CurrentMenu ds 2 AppleToggle ds 2 ; suspect? MenuData ds 128 ; enough for 16 menu items * Globals used by various desk accessories ClockToggle ds 2 CenterColor ds 2 OldTable ds 32 NewTable ds 32 CurrentCursor dc i2'Arrow' CursorTable anop ArrowCursor ds 4 PencilCursor dc i4'PencilMask' WatchCursor dc i4'WatchMask' CrossCursor dc i4'CrossMask' SquareCursor dc i4'SquareMask' BrushCursor dc i4'BrushMask' PencilMask dc i2'10,4' dc h'0000000000000000' dc h'000000FF00000000' dc h'00000F0FF0000000' dc h'0000F0FFF0000000' dc h'000F0FFF00000000' dc h'00F0FFF000000000' dc h'0F0FFF0000000000' dc h'0FFFF00000000000' dc h'0FFF000000000000' dc h'0000000000000000' dc h'000000FF00000000' dc h'00000FFFF0000000' dc h'0000FFFFFF000000' dc h'000FFFFFFF000000' dc h'00FFFFFFF0000000' dc h'0FFFFFFF00000000' dc h'FFFFFFF000000000' dc h'FFFFFF0000000000' dc h'F0FFF00000000000' dc h'FFFF000000000000' dc i2'8,2' WatchMask dc i2'9,3' dc h'03FFFC000000' dc h'03FFFC000000' dc h'3F000FC00000' dc h'F00F00F00000' dc h'F0FF00FF0000' dc h'F00000F00000' dc h'3F000FC00000' dc h'03FFFC000000' dc h'03FFFC000000' dc h'03FFFC000000' dc h'03FFFC000000' dc h'3FFFFFC00000' dc h'FFFFFFF00000' dc h'FFFFFFFF0000' dc h'FFFFFFF00000' dc h'3FFFFFC00000' dc h'03FFFC000000' dc h'03FFFC000000' dc i2'4,6' CrossMask dc i2'7,4' dc h'0000F00000000000' dc h'0000F00000000000' dc h'0000F00000000000' dc h'FFFFFFFFF0000000' dc h'0000F00000000000' dc h'0000F00000000000' dc h'0000F00000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc i2'3,8' SquareMask dc i2'9,4' dc h'FFFFFFFFFFF00000' dc h'F000000000F00000' dc h'F000000000F00000' dc h'F000000000F00000' dc h'F000000000F00000' dc h'F000000000F00000' dc h'F000000000F00000' dc h'F000000000F00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc i2'4,10' BrushMask dc i2'9,4' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'FFFFFFFFFFF00000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc h'0000000000000000' dc i2'4,10' StdPatterns anop StdGray dc 32i1'$CC' ; gray StdPastelBlue dc 32i1'$DD' ; pastel blue StdYellow dc 32i1'$EE' ; yellow StdWhite dc 32i1'$FF' ; white StdGreen dc 32i1'$88' ; green StdTurquoise dc 32i1'$99' ; turquoise StdChartreuse dc 32i1'$AA' ; chartreuse StdPastelGreen dc 32i1'$BB' ; pastel green StdRed dc 32i1'$44' ; red StdViolet dc 32i1'$55' ; violet StdOrange dc 32i1'$66' ; orange StdPink dc 32i1'$77' ; pink StdBlack dc 32i1'$00' ; black StdBlue dc 32i1'$11' ; blue StdGold dc 32i1'$22' ; gold StdGrey dc 32i1'$33' ; grey StdColorTab dc i4'StdBlack' dc i4'StdBlue' dc i4'StdGold' dc i4'StdGrey' dc i4'StdRed' dc i4'StdViolet' dc i4'StdOrange' dc i4'StdPink' dc i4'StdGreen' dc i4'StdTurquoise' dc i4'StdChartreuse' dc i4'StdPastelGreen' dc i4'StdGray' dc i4'StdPastelBlue' dc i4'StdYellow' dc i4'StdWhite' END * Table of Contents * * 2. Lib.Asm * * OpenLibrary First application call, opens managers * Input: Zero page to use * CloseLibrary Shuts down all managers and prepares for exit * **************************************************************** * * Procedure OpenLibrary * **************************************************************** OpenLibrary START using LibGlobals longa off longi off =?@ABCDEFGHIJKLMNOP clc xce rep #$30 longa on longi on ShadowOff phk ; set the data bank plb _TLStartup ; start up the Tool Locator ErrorDeath '_TLStartup failed.' PushWord #0 ; and the Memory Manager _MMStartup ErrorDeath '_MMStartup failed.' pla sta AbsID _MTStartup ; now Miscellaneous Tools ErrorDeath '_MTStartup failed.' PushLong #0 ; space for handle PushLong #$600 ; QD (3), EM (1), QT (1), App (1) PushWord AbsID PushWord #$C001 ; locked, fixed, fixed bank PushLong #0 _NewHandle ErrorDeath '_NewHandle failed fetching 6 zero pages.' * The stack currently has the handle on it for these zero pages. We save * the current zero page, then set the direct page to the stack so we can * get dereference the handle. We only need the low word (the high word is * guaranteed zero). As soon as we get it, we set the application zero page. * Then we save the OldDirect and the Handle onto ZeroPage as we pull them * off the stack. phd ; push old direct page tsc ; get stack tcd ; map direct page onto stack lda [3] ; it's a bank 0 pointer! tcd ; now we've got it sta AppDirect pla sta OldDirect pla sta ZPHandle pla sta ZPHandle+2 lda AbsId sta MyId * Initialize QuickDraw II clc lda AppDirect adc #QDOffset ; move it past other zeropages pha ; push zero page to use PushWord #$80 ; the Mode we start in PushWord #164 ; max width PushWord MyID ; my id for mem mgr _QDStartup phb pea 0 plb plb clc lda AppDirect adc #BRamOffset sta BatteryRam pea 0 pha _ReadBRam plb ldx #BRamOffset ; offset to BatteryRam space lda $1C,x ; display border color and #$0F sta OldBorderColor sep #$30 longa off longi off lda >$00C034 and #$F0 ; clear lower bits ora #$02 ; set dark blue sta >$00C034 rep #$30 longa on longi on jsr ReadPattern ; read BatteryRam background jsr ReadPalette ; read BatteryRam Palette lda #0 ; the VGC is FIXED!!! sta MyColorTable pei (MyColorTable) ; do this first so it looks good PushPtr OldTable ; it was read from battery ram _SetColorTable lda #$0080 ; 640 mode ora MyColorTable ; add in color table pha pha _SetMasterSCB _SetAllSCBs jsr BlankScreen ; fill with background pattern * Now that we have the screen set up in our special 640 mode, we are ready * to handle alerts and stuff. Start by checking the memory manager for * integrity. AlertHeight equ 48 AlertWidth equ 130 AlertByte equ 15 AlertLine equ 40 jsr CheckMM bcc MMOkay jsr $FF1800 ; install another peeker cli ; turn on desk accessory interrupts lda #AlertHeight ; number of scan lines in full menu sta MenuHeight lda #AlertWidth ; width of menu in bytes sta MenuWidth lda #(AlertLine*160+AlertByte) ; offset ($2000) to first pixel sta MenuStart ; in bytes lda #0 sta FastFlags jsr DrawFastWindow ; let's draw a fast window pea 100 pea 60 _MoveTo PushPtr MemoryAlert _DrawString jsr WaitForKey brk $AC clc ; native mode, 16 bit registers xce rep #$30 * Initialize the Event Manager - zero page to use already on stack MMOkay clc lda AppDirect adc #EMOffset ; move it past other zeropages pha ; push zero page to use PushWord #20 ; queue size PushWord #0 ; x min for clamp PushWord #640 ; VGC anomaly is FIXED!!! PushWord #0 PushWord #200 PushWord MyId ; mm id _EMStartUp PushLong #ToolTable ; load the tools we need _LoadTools ErrorDeath '_LoadTools failed.' * And initialize a few miscellaneous things lda #0 sta QuitFlags sta MyAttributes sta CurrentMenu sta CurrentItem sta ClockToggle lda #$DDDD sta CenterColor * Initialize the application environment jsr NewRegion sta ScreenRgn ; get a new one stx ScreenRgn+2 jsr NewRegion sta BackgrndRgn stx BackgrndRgn+2 lda #$CAFE ; a suitably random number sta Seed ; save it on zero page jsr CursorStartup jsr InitScreen jsr MenuInit rts AbsID ds 2 ToolTable dc i2'2' ; two tools I need, for now dc i2'4,$0100' ; quickdraw dc i2'6,$0100' ; event manager MemoryAlert dc i1'MemAlertEnd-MemoryAlert-1' dc c'Memory manager inconsistency found.' MemAlertEnd anop END **************************************************************** * * Procedure CloseLibrary * **************************************************************** CloseLibrary START using LibGlobals PushLong ScreenRgn _DisposeRgn PushLong BackgrndRgn _DisposeRgn jsr MenuShutdown _EMShutdown _GrafOff phb pea 0 plb plb pea 0 pei (BatteryRam) _ReadBRam plb jsr WritePattern ; save BatteryRam background jsr WritePalette ; save BatteryRam Palette phb pea 0 plb plb pea 0 pei (BatteryRam) _WriteBRam plb ldx #BRamOffset ; offset to BatteryRam space lda $1C,x ; display border color and #$000F sta Temp ; push it so we can use it sep #$30 longa off longi off lda >$00C034 and #$F0 ; clear lower bits ora Temp ; set it to the new value sta >$00C034 rep #$30 longa on longi on _QDShutdown _MTShutdown pei OldDirect ; copy old direct page pei MyId PushLong ZPHandle _DisposHandle _MMShutdown ; MyId is already TOS _TLShutdown pld ; restore old direct page _Quit QuitParams ; Do a ProDOS Quit call brk $AC ; we don't return QuitParams dc i4'0' dc i'$4000' ; am restartable in memory END * Table of Contents * * 3. Util.Asm * * SetPenColor New pen color is passed in the A register * Input: Pen color * SetBackColor New background color is passed in the A register * Input: Pen color * WaitForKey Waits for a character - competes with the event manager * Prndm Pseudo random number generator * NewRegion Allocates a new region, returning the handle in A & X * Multiply QSTUVWXYZ[\]^_`abcdefghijklmnopTakes two unsigned arguments off the stack, multiplies * them and returns the 16 bit unsigned result * CursorStartup Initialize the cursor stuff, fetching the arrow cursor * information, explicitly. * SetCursor Select a cursor pattern. **************************************************************** * * Procedure SetPenColor * **************************************************************** SetPenColor START Using LibGlobals plx pla phx jsr LoadColor PushPtr TempPattern _PenPat rts SetPenPattern ENTRY plx pla phx jsr LoadPattern PushPtr TempPattern _PenPat rts END **************************************************************** * * Procedure SetBackColor * **************************************************************** SetBackColor START Using LibGlobals plx pla phx jsr LoadColor PushPtr TempPattern _BackPat rts SetBackPattern ENTRY plx pla phx jsr LoadPattern PushPtr TempPattern _BackPat rts END **************************************************************** * * Procedure LoadColor; private * **************************************************************** LoadColor START Using LibGlobals * the A register comes in as a color 0..15 and #$000F ; 0..15 tax ; get index lda ColorTab,x ; get byte of this color and #$00FF ; clear to one byte sta Temp xba ; swap bytes ora Temp ; now we have a full word of it sta Temp ; save it sta Temp+2 ; save it again bra Loader LoadPattern ENTRY * the A register comes in as a color 0..255 and #$00FF ; 0..255 sta Temp ; save it xba ; swap bytes ora Temp ; copy them back in to the high byte sta Temp ; Temp has a double copy asl A asl A asl A asl A and #$0FF0 ; nibbles are now switched sta Temp+2 ; save it xba ; swap bytes ora Temp+2 ; replicate the nibbles sta Temp+2 ; Temp+2 has a switched double copy Loader ldx #0 PenLoop lda Temp sta TempPattern,x inx inx lda Temp+2 sta TempPattern,x inx inx cpx #32 bcc PenLoop rts END *===== * * WaitForKey * WaitForKey START sep #%00110000 longa off longi off Loop lda $C000 bpl Loop sta $C010 and #$7F Done rep #%00110000 rts longa on longi on END *===== * * Prndm(0,A-1) * Prndm START using LibGlobals Big equ $7FFF * Input is the function return and the range, lower limit pushed on * the stack first, followed by the upper limit. Output is either * the low value (if the range is <0) or a number from Lo to Hi, inclusive, * left on the top of the stack. ply ; pull return pla ; pull upper limit plx ; pull lower limit stx Prndm_Lo ; save it * K := J - I + 1 sta Prndm_Hi ; save this, too phy ; push return back sec sbc Prndm_Lo ; get the difference bpl WorkToDo lda Prndm_Lo sta 3,s ; return the result rts ; return WorkToDo ina ; bump by 1 sta Prndm_K ; save it * A := abs(Seed) * B := A div 16; lda Seed ; get Seed bpl Okay eor #$FFFF ; negate it ina Okay sta Prndm_A ; save it lsr A ; divide by 16 lsr A lsr A lsr A sta Prndm_B ; save it * AC := Big - A lda #Big ; get Big sec sbc Prndm_A sta Prndm_AC ; save it * BC := Big - B lda #Big ; get Big sec sbc Prndm_B sta Prndm_BC ; save it * A := (A and BC) or (AC and B) lda Prndm_A and Prndm_BC sta Prndm_A lda Prndm_B and Prndm_AC ora Prndm_A sta Prndm_A * B := (A mod 16) * 2048 and #$000F ; mod 16 xba ; x 256 asl A ; x 512 asl A ; x 1024 asl A ; x 2048 sta Prndm_B ; save it * AC := Big - A * BC := Big - B lda #Big ; get Big sec sbc Prndm_A sta Prndm_AC ; save it lda #Big sec sbc Prndm_B sta Prndm_BC * A := (A and BC) or (AC and B) lda Prndm_A and Prndm_BC sta Prndm_A lda Prndm_AC and Prndm_B ora Prndm_A * Seed := A sta Seed lda Prndm_K * Prndm := (A mod K) + Lo pea 0 pea 0 pei (Seed) pei (Prndm_K) _Udivide pla pla ; remainder clc adc Prndm_Lo ; add in lo value sta 3,s ; set return value rts END **************************************************************** * * DerefHandle * **************************************************************** DerefHandle START * enter with zero page offset to src in X * sample usage: * * ldx #RgnHandleA * jsr DerefHandle * sta RgnPtrA * stx RgnPtrA+2 lda 0,x sta Temp lda 2,x sta Temp+2 QuickDeref ENTRY ; enter here if Temp has handle already * sample usage: * jsr QuickDeref ; Temp still has handle * sta RgnPtrA * stx RgnPtrA+2 * handle is in Temp; lock it down ldy #4 lda [Temp],y tax and #$7FFF sta UserLocked txa ora #$8000 sta [Temp],y * dereference it, leaving low word in A and high word in X ldy #2 lda [Temp],y tax lda [Temp] rts END **************************************************************** * * Procedure UnlockHandle * **************************************************************** UnlockHandle START * enter with zero page offset to handle in x * Sample usage * * ldx #RgnHandleA * jsr UnlockHandle lda 0,x sta Temp lda 2,x sta Temp+2 * unlock it ldy #4 lda [Temp],y and #$7FFF sta [Temp],y * leave with Temp still holding the handle so related routines * can use it rts END **************************************************************** * * ResizeHandle * **************************************************************** ResizeHandle START * enter with pointer to handle on zero page in x * Sample usage * * lda NewHandleSize * ldx #RgnHandleA * jsr ResizeHandle * sta RgnPtrA * stx RgnPtrA+2 pha ; push size (02) pea 0 ; push 0 for high word of size (04) pha ; push low word of size (06) jsr UnlockHandle ; pass X as pointer * UnlockHandle leaves a copy of the handle in Temp for us. Long word size * is still on the stack pei Temp+2 ; push handle high (08) pei Temp ; push handle low (0A) _SetHandleSize ; handle size is at top of stack (02) bcs Error ; we found an error, A & X are invalid NewEntry ENTRY jsr QuickDeref ; handle still in Temp, redereference it sta Temp ; pointer is in A & X stx Temp+2 pla ; get size back (00) sta [Temp] ; set size for regions, invpt buffers lda Temp ; pointer is in A & X rts Error ply ; error in A, carry is still set (00) ldx #$FFFF ; invalidate pointer rts END **************************************************************** * * GetNewHandle * **************************************************************** GetNewHandle START * It accepts a size in A and an offset to the zero page handle variable * in X. Upon return it has initialized a new handle, dereferenced it, * and set the first two bytes of the handle data to the length of the * handle, which is what regions and buffers want. Because it sets the * length it assumes the size (in A) will never be less than 2 bytes. * It puts a copy of the new handle into the location pointed at by X. * The dereferenced pointer is returned in A and X. pha ; save size phx ; save offset pea 0 ; make room for result pea 0 pea 0 ; high word of count pha ; push the requested size pei (MyId) pei (MyAttributes) pea 0 ; push location requirements pea 0 _NewHandle ; allocate a new one ply sty Temp ply sty Temp+2 bcs HandleError ; if an error, clean up plx ; get offset back sty 2,x ; save high word to real handle ldy Temp ; get low word back sty 0,x ; save low word to real handle * The size is still on the stack. This now looks like we've just resized * a handle, so branch upwards and use the code we've already written. bra NewEntry ; pointer will come back in A and X HandleError ply ; discard offset ply ; discard size rts END **************************************************************** * * Procedure NewRegion - returns region handle in A & X * **************************************************************** NewRegion START pea 0 pea 0 _NewRgn pla plx rts END **************************************************************** * * Function Multiply(Operand,Factor):Multiplicand * **************************************************************** Multiply START plx ; get return pla ; get factor sta Factor ; save it pla ; get operand sta Operand ; save it pla ; pull function return sta Multiplicand ; save value to add More lda Operand beq Through lsr A ; get least significant bit sta Operand ; save operand bcc NoAdd ; if 0, don't add this time around lda Multiplicand clc adc Factor ; add in the factor sta Multiplicand ; save result NoAdd lda Factor ; get factor back asl A ; multiply by 2 sta Factor ; save it bra More Through pei (Multiplicand) ; push result phx ; push return address rts END **************************************************************** * * CursorStartup * **************************************************************** CursorStartup START using LibGlobals pea $0000 pea $0000 _GetCursorAdr pla sta ArrowCursor pla sta ArrowCursor+2 stz CurrentCursor rts SetCursor ENTRY ; input is TOS, scalar cursor index plx ; pull return pla ; pull cursor phx ; push return bmi UseArrow cmp #LastCursor bmi CompareCursors UseArrow lda #0 CompareCursors cmp CurrentCursor bne UpdateCursor rts UpdateCursor sta CurrentCursor asl A asl A tax lda CursorTable+2,x pha lda CursorTable,x pha _SetCursor rts END * Table of Contents * * 1. Screen.Asm * * ScreenGlobals Data section used by the draw apple procedure * DrawMenu Draws the menu bar * DrawScreen Redraws the menu and background. * InitScreen Initializes the screen values and color tables. **************************************************************** * * Screen Globals * **************************************************************** ScreenGlobals DATA ScreenPtr equ $E12000qstuvwxyz{|}~ AppleInfo dc i4'SrcLocInfo' ; Source Loc info dc i4'DstLocInfo' ; Destination Loc info dc i4'SrcRect' dc i4'DstRect' XferMode dc i2'0' ; for copy dc i4'0' ; pointer to region SrcLocInfo dc i1'$80' ; mode 640 dc i1'0' ; reserved dc i4'PixelMap' dc i2'6' ; width in bytes SrcBounds dc i2'0,0,11,24' ; bounds rect DstLocInfo dc i1'$80' ; mode 640 dc i1'0' ; reserved dc i4'$E12000' ; the screen dc i2'160' ; width in bytes DstBounds dc i2'0,0,200,640' ; bounds rect SrcRect dc i2' 0, 0,11,24' DstRect dc i2' 0,20,11,44' PixelMap anop ! 02468ACE 246 dc h'FFFFFFFFFFFF' ; 0 dc h'FFFFFC883FFF' ; 1 dc h'FFFFC883FFFF' ; 2 dc h'FC88808883FF' ; 3 dc h'CEEEEEEEEE3F' ; 4 dc h'C66666663FFF' ; 5 dc h'C44444443FFF' ; 6 dc h'C5555555553F' ; 7 dc h'FC11111113FF' ; 8 dc h'FFC11F113FFF' ; 9 dc h'FFFFFFFFFFFF' ; 10 BlackAppleInfo dc i4'BlkLocInfo' ; Source Loc info dc i4'DstLocInfo' ; Destination Loc info dc i4'SrcRect' dc i4'DstRect' dc i2'0' ; for copy dc i4'0' ; pointer to region BlkLocInfo dc i1'$80' ; mode 640 dc i1'0' ; reserved dc i4'BlackMap' dc i2'6' ; width in bytes dc i2'0,0,11,24' ; bounds rect BlackMap anop ! 02468ACE 246 dc h'000000000000' ; 0 dc h'000000880000' ; 1 dc h'000008800000' ; 2 dc h'008880888800' ; 3 dc h'0EEEEEEEEE00' ; 4 dc h'266666660000' ; 5 dc h'044444440000' ; 6 dc h'055555555500' ; 7 dc h'011111111000' ; 8 dc h'001110110000' ; 9 dc h'000000000000' ; 10 StdTitleBar dc i1'StdEnd-StdTitleBar-1' dc c'File Edit Goodies Options' StdEnd anop TitleBar ds 256 ; just to be sure END **************************************************************** * * SetStdPort * **************************************************************** SetStdPort START using LibGlobals PushWord StdFGColor ; black jsr SetPenColor PushWord StdBGColor ; white jsr SetBackColor PushLong StdPenSize ; PenSize(2,1) _PenSize PushWord StdFGColor ; black _SetForeColor PushWord StdBGColor ; white _SetBackColor PushWord StdTextMode _SetTextMode rts END **************************************************************** * * DrawMenu * **************************************************************** DrawMenu START using LibGlobals using ScreenGlobals jsr SetStdPort ; set up the standard environment PushPtr MenuRect _EraseRect PushPtr AppleInfo _PaintPixels lda MenuRect+2 ; X1 pha lda MenuRect+4 ; Y2 pha _MoveTo lda MenuRect+6 ; X2 pha lda MenuRect+4 ; Y2 pha _LineTo pea 60 ; x pea 9 ; y _MoveTo PushPtr TitleBar _DrawString rts END **************************************************************** * * SetTitleBar * **************************************************************** SetTitleBar START using LibGlobals using ScreenGlobals plx ; pull return address pla ; pull string pointer sta Pointer pla sta Pointer+2 phx ; push return address back lda [Pointer] and #$00FE ; just the length byte (made even) tay ; point y at last word in string CopyLoop lda [Pointer],y ; get a word sta TitleBar,y ; save a word dey dey bpl CopyLoop rts END **************************************************************** * * DrawScreen * **************************************************************** DrawScreen START using LibGlobals jsr BlankScreen PushLong ScreenRgn _SetClip ; erase only the screen rectangle jsr DrawMenu ; it will set standards for us PushLong BackgrndRgn _SetClip rts END **************************************************************** * * Procedure InitScreen * **************************************************************** InitScreen START using LibGlobals using ScreenGlobals PushPtr FakeScreenRgn PushLong ScreenRgn _CopyRgn PushLong BackgrndRgn PushPtr BackgrndRect _RectRgn MoveLong BackgrndRgn,TempRgn jsr NewRegion sta BackgrndRgn stx BackgrndRgn+2 PushLong ScreenRgn PushLong TempRgn PushLong BackgrndRgn _SectRgn PushLong TempRgn _DisposeRgn jsr SetStdPort ; colors, pensize PushLong ScreenRgn ; get the real one _SetClip ; open up the clipping PushPtr StdTitleBar jsr SetTitleBar rts END * Table of Contents * * 1. Menutil.Asm * * FastOps Routine that contains fast rectangle entry points * FastFill Fill a rectangle with FastColor * FastXor Xor a rectangle with FastColor * FastOr Or a rectangle with FastColor * FastAnd And a rectangle with FastColor * MenuOpInit Common code to set up initial values * SaveScreen Save part of the screen * DrawBlankMenu Draw a blank, shadowed menu *  InvertItem Invert an item on the screen * RestoreScreen Restore part of the screen * DrawMenuLine Draw a horizontal line on the screen * DrawFastWindow Draw a fast, shadowed window, with accoutrements * PaintCorners Paints both (or just bottom) corners in dark blue * ReadPattern Loads (and saves) user background pattern (and palette) * BlankScreen Fills the screen with the current background/palette **************************************************************** * * FastOps * **************************************************************** FastOps START using LibGlobals Fill_Op equ 0 Xor_Op equ 2 Or_Op equ 4 And_Op equ 6 FastFill ENTRY pea Fill_Op bra FastCommon FastXor ENTRY pea Xor_Op bra FastCommon FastOr ENTRY pea Or_Op bra FastCommon FastAnd ENTRY pea And_Op FastCommon _HideCursor plx ; get operation back lda #$2000 ; screen start clc adc FastStart ; first byte to be affected sta Screen ; where we start, each time lda #$00E1 ; high word of pointer sta Screen+2 ; set high word bra CutInside ; jump into it NextLine lda Screen ; get the last screen position clc adc #160 ; increment by a scan line of bytes sta Screen ; save it for next time CutInside ldy FastWidth ; set y dey ; decrement y by 2, point at last word dey jsr (LoopTable,x) ; call inner loop dec FastHeight ; one less scan line bne NextLine ; if not zero, do the next line _ShowCursor rts ; depart LoopTable dc i2'FillStart' ; Fill_Op dc i2'XorLoop' ; Xor_Op dc i2'OrLoop' ; Or_Op dc i2'AndLoop' ; And_Op FillStart lda FastColor ; fetch the color FillLoop sta [Screen],y ; store the color dey ; dock y dey ; dock it again bpl FillLoop ; if it isn't negative, do some more rts XorLoop lda [Screen],y ; get data from screen eor FastColor ; xor it sta [Screen],y ; put it away dey ; dock y dey ; dock it again bpl XorLoop ; if it isn't negative, do some more rts OrLoop lda [Screen],y ; get data from screen ora FastColor ; or it sta [Screen],y ; put it away dey ; dock y dey ; dock it again bpl OrLoop ; if it isn't negative, do some more rts AndLoop lda [Screen],y ; get data from screen and FastColor ; and it sta [Screen],y ; put it away dey ; dock y dey ; dock it again bpl AndLoop ; if it isn't negative, do some more rts END **************************************************************** * * MenuOpInit * **************************************************************** MenuOpInit START using LibGlobals lda #$2000 ; first byte of the screen clc adc MenuStart ; offset to first screen byte of menu sta Screen ; where we start, each time lda #$00E1 ; high word of pointer sta Screen+2 ; set high word lda MenuHeight ; initialize our line counter sta MenuLines lda BuffPtr ; initialize our buffer pointer sta MenuPtr lda BuffPtr+2 sta MenuPtr+2 rts END **************************************************************** * * SaveScreen * **************************************************************** SaveScreen START using LibGlobals _HideCursor jsr MenuOpInit ; common code to set things up bra CutInside ; jump into it NextLine lda Screen ; get the last screen position clc adc #160 ; increment by a scan line of bytes sta Screen ; save it for the next time lda MenuPtr ; get pointer to save area clc adc MenuWidth sta MenuPtr bcc CutInside inc MenuPtr+2 CutInside ldy MenuWidth ; set y dey ; decrement y by 2, point at last word dey NextWord lda [Screen],y ; get data from screen sta [MenuPtr],y ; save it to storage dey ; dock y dey ; dock it again bpl NextWord ; if it isn't negative, do some more dec MenuLines ; one less scan line bne NextLine ; if not zero, do the next line _ShowCursor rts END **************************************************************** * * DrawBlankMenu * **************************************************************** DrawBlankMenu START using LibGlobals _HideCursor jsr MenuOpInit dec MenuLines ; to allow for blue line dec MenuLines ; to allow for black line ldx #3 ; amount of unshadowed vertical bra CutInside ; jump into it NextLine lda #$FF0F ; 2 black pixels on the left sta [Screen] ; put the left edge lda Screen ; get the last screen position clc adc #160 ; increment by a scan line of bytes sta Screen ; save it for next time dec MenuLines ; one less scan line beq FinishUp ; if not zero, do the next line CutInside ldy MenuWidth ; set y dey ; decrement y by 2, point at last word dey dex ; decrement ShadowStart bpl NoShadow lda #$11F0 sta [Screen],y ; put 2 white, 3 black, 3 blue pixels bra PutEdge NoShadow lda [Screen],y ; get what is already there and #$3FF0 ; clear border ora #$00F0 ; add white on the left PutEdge sta [Screen],y ; store it dey ; look at the next word dey lda #$FFFF ; all white NextWord sta [Screen],y ; save it to storage dey ; dock y dey ; dock it again bne NextWord ; if it isn't negative, do some more bra NextLine * We come here to put the black and blue lines down for the * bottom edge and for the shadow. FinishUp lda #$1100 ; get black 'n blue ldy MenuWidth ; get right edge dey ; look at last word dey sta [Screen],y ; put right edge dey dey lda #$0000 ; get all black NextBottom sta [Screen],y ; save it to storage dey ; dock y dey ; dock it again bpl NextBottom ; if it isn't negative, do some more * Note we stored zeros all the way to the left edge lda Screen clc adc #160 ; increment by a scan line of bytes sta Screen ; save it for next time lda #$1111 ; get all blues ldy MenuWidth ; get right edge dey ; look at last word dey NextBlue sta [Screen],y ; save the blue line dey ; dock y dey ; dock it again bne NextBlue ; if it isn't 0, do some more * Note we left the last 4 pixels alone _ShowCursor rts ; go back home END **************************************************************** * * InvertItem * **************************************************************** InvertItem START using LibGlobals _HideCursor lda ItemHeight sta MenuLines lda #$2000 ; screen start clc adc ItemStart ; first byte to be affected sta Screen ; where we start, each time lda #$00E1 ; high word of pointer sta Screen+2 ; set high word bra CutInside ; jump in there NextLine lda [Screen] ; get what's there already eor #$FF0F ; 2 black pixels on the left sta [Screen] ; put the left edge lda Screen ; get the last screen position clc adc #160 ; increment by a scan line of bytes sta Screen ; save it for next time dec MenuLines ; one less scan line beq FinishUp ; if not zero, do the next line CutInside ldy MenuWidth ; set y dey ; decrement y by 2, point at last word dey lda [Screen],y ; get what's there already eor #$00F0 ; 2 pixels, just left of right edge sta [Screen],y ; put 2 white, 3 black, 3 blue pixels dey ; look at the next word dey NextWord lda [Screen],y ; get what's there already eor #$FFFF ; invert it sta [Screen],y ; save it to storage dey ; dock y dey ; dock it again bne NextWord ; if it isn't negative, do some more bra NextLine FinishUp _ShowCursor rts END **************************************************************** * * RestoreScreen * **************************************************************** RestoreScreen START using LibGlobals _HideCursor jsr MenuOpInit bra CutInside ; jump into it NextLine lda Screen ; get the last screen position clc adc #160 ; increment by a scan line of bytes sta Screen ; save it for next time bcs Done ; if carry is set, we've blown it lda MenuPtr ; get pointer to save area clc adc MenuWidth sta MenuPtr bcc CutInside inc MenuPtr+2 CutInside ldy MenuWidth ; set y dey ; decrement y by 2, point at last word dey NextWord lda [MenuPtr],y ; get data from storage sta [Screen],y ; save it to the screen dey ; dock y dey ; dock it again bpl NextWord ; if it isn't negative, do some more dec MenuLines ; one less scan line bne NextLine ; if not zero, do the next line Done _ShowCursor rts ; go back home END **************************************************************** * * DrawMenuLine * **************************************************************** DrawMenuLine START using LibGlobals _HideCursor lda #$2000 ; screen start clc adc MenuLineStart ; first byte to be affected sta Screen ; where we start, each time lda #$00E1 ; high word of pointer sta Screen+2 ; set high word ldy MenuWidth ; set y dey ; decrement y by 2, point at last word dey lda #$1100 ; get some black and blue sta [Screen],y ; write the right edge dey dey lda #$0000 ; get some black NextWord sta [Screen],y ; write to the screen dey ; dock y dey ; dock it again bpl NextWord ; if it isn't negative, do some more _ShowCursor rts END **************************************************************** * * DrawDialogTop * **************************************************************** DrawDialogTop START using LibGlobals _HideCursor lda #$2000 ; screen start clc adc MenuStart ; first byte to be affected sta Screen ; where we start, each time lda #$00E1 ; high word of pointer sta Screen+2 ; set high word ldy MenuWidth ; set y dey ; decrement y by 2, point at last word dey lda [Screen],y ; get the right edge and #$3F00 ; clear border but not screen sta [Screen],y ; write the right edge dey dey lda #$0000 ; get some black NextWord sta [Screen],y ; write to the screen dey ; dock y dey ; dock it again bpl NextWord ; if it isn't negative, do some more _ShowCursor rts END **************************************************************** * * DrawCrossBars * **************************************************************** DrawCrossBars START using LibGlobals lda MenuWidth ; dock it by 2 words (left and right) dea dea dea dea sta FastWidth lda #1 sta FastHeight clc lda MenuStart adc #(3*160+2) sta FastStart stz FastColor jsr FastFill * Now we have to patch up the left edge. Use the fact that Screen * is left sitting right where we stopped. Dock it by one byte and store * a word of zeros. dec Screen lda #0 sta [Screen] lda #1 sta FastHeight lda FastStart clc adc #320 sta FastStart jsr FastFill dec Screen lda #0 sta [Screen] lda #1 sta FastHeight lda FastStart clc adc #320 sta FastStart jsr FastFill dec Screen lda #0 sta [Screen] lda #1 sta FastHeight lda FastStart clc adc #320 sta FastStart jsr FastFill dec Screen lda #0 sta [Screen] rts END **************************************************************** * * DrawCloseBox * **************************************************************** DrawCloseBox START using LibGlobals clc lda MenuStart ; get beginning of window adc #(3*160+$2002) ; point at the start of the close box sta Screen ; now we have a pointer to it lda #$C003 sta [Screen] ; draw it ldy #960 sta [Screen],y lda #$C303 ldy #320 sta [Screen],y ldy #640 sta [Screen],y lda #$C3FF ldy #160 sta [Screen],y ldy #480 sta [Screen],y ldy #800 sta [Screen],y lda #0 ldy #2 sta [Screen],y ldy #962 sta [Screen],y lda #$FFFF ldy #162 sta [Screen],y ldy #322 sta [Screen],y ldy #482 sta [Screen],y ldy #642 sta [Screen],y ldy #802 sta [Screen],y lda #$3C00 ldy #4 sta [Screen],y ldy #964 sta [Screen],y lda #$3CFC ldy #324 sta [Screen],y ldy #644 sta [Screen],y lda #$3FFC ldy #164 sta [Screen],y ldy #484 sta [Screen],y ldy #804 sta [Screen],y rts END **************************************************************** * * DrawFastWindow * **************************************************************** DrawFastWindow START * DrawFastWindow does exactly that, it blasts a window up on the screen. * It throws up the basic framework and then adds other doodads that may * have been requested (CloseBox, ZoomBox, Scrollboxes, Growbox, Title). * MenuHeight (scan lines), MenuWidth (width in bytes), MenuStart (byte * offset from $2000 to first pixel) have been set. If necessary the screen * has been presaved. using LibGlobals _HideCursor ; knock it up a notch jsr DrawBlankMenu jsr DrawDialogTop lda FastFlags and #UnderBarFlag beq NoUnderBar clc lda MenuStart adc #(12*160) ; bump it to where the underline is sta MenuLineStart jsr DrawMenuLine ; draw the shadowed line NoUnderBar lda FastFlags and #CrossBarsFlag beq NoCrossBars jsr DrawCrossBars NoCrossBars lda FastFlags and #CloseBoxFlag beq NoCloseBox jsr DrawCloseBox NoCloseBox lda FastFlags and #ZoomBoxFlag beq NoZoomBox clc NoZoomBox lda FastFlags and #GrowBoxFlag beq NoGrowBox clc NoGrowBox lda FastFlags and #VScrollFlag beq NoVScroll clc NoVScroll lda FastFlags and #HScrollFlag beq NoHScroll clc NoHScroll lda FastFlags and #TitleFlag beq NoTitle clc NoTitle _ShowCursor rts END **************************************************************** * * PaintCorners * **************************************************************** PaintCorners START _HideCursor lda #$1111 ; clear away 8 pixels sta $E12000 ; save (left:0) sta $E12000+160-2 ; 8 of 10 lda $E12000+160-4 and #$F0FF ; 2 more pixels ora #$0100 ; add in blue sta $E12000+160-4 ; save (right:0) lda $E12000+160 ; get 8 pixels, clear first 4 and #$FF00 ora #$0011 sta $E12000+160 ; save (left:1) lda $E12000+160*2-2 ; clear last 6 pixels and #$00F0 ora #$1101 sta $E12000+160*2-2 ; save (right:1) lda $E12000+160*2 ; clear away 2 pixels and #$FF0F ora #$0010 sta $E12000+160*2 ; save (left:2) lda $E12000+160*3-1 ; clear away 4+2 pixels and #$0F00 ora #$1011 sta $E12000+160*3-1 ; save (right:2, left:3) lda $E12000+160*4-1 ; clear away 4 pixels and #$FF00 ora #$0011 sta $E12000+160*4-1 ; save (right:3) bra TopEntry BottomCorners ENTRY _HideCursor TopEntry lda $E12000+160*196 ; get what's there and #$FF0F ; clear away two pixels ora #$0010 ; add in dark blue sta $E12000+160*196 ; save (left:196) lda $E12000+160*197-1 ; clear away 4+2 pixels and #$0F00 ; clear away 6 pixels ora #$1011 ; add in dark blue sta $E12000+160*197-1 ; save (right:196,left:197) lda #$1111 ; clear away 4+4 pixels sta $E12000+160*198-1 ; save (right:197,left:198) lda $E12000+160*199-2 ; clear away 6 pixels and #$00F0 ora #$1101 sta $E12000+160*199-2 ; save (right:198) lda #$1111 ; clear away 8 pixels sta $E12000+160*199 ; save (left:199) sta $E12000+160*200-2 ; 8 of 10, save (right:199) lda $E12000+160*200-4 and #$F0FF ; 2 more pixels ora #$0100 ; add in blue sta $E12000+160*200-4 ; save (right:199) _ShowCursor rts END **************************************************************** * * ReadPattern, ReadPalette, SavePattern, SavePalette * **************************************************************** ReadPattern START * These routines use bank 0 memory that should be recently read * from the Battery ram. Use _ReadBRam before both reads and writes * (in case the desk accessories change something) and use _WriteBRam * after the last of a series of writes. using LibGlobals ldx #BRamOffset ; battery ram counter ldy #0 ; pattern counter PatternLoop lda $61,x ; zero page, and then some sta UserBackground,y ; save it sta UserBackground+8,y ; save it in the high part, too inx inx iny iny cpy #8 bmi PatternLoop rts ReadPalette ENTRY * Initialize white and black stz OldTable stz OldTable+8 stz OldTable+16 stz OldTable+24 lda #$FFFF sta OldTable+6 sta OldTable+14 sta OldTable+22 sta OldTable+30 ldx #BRamOffset ; battery ram counter ldy #0 PaletteLoop lda $69,x ; get palette value phx ; save counter ldx PaletteOffset,y ; get offset to correct value sta OldTable,x ; save it sta OldTable+16,x plx ; retrieve index inx inx iny iny cpy #8 bmi PaletteLoop rts PaletteOffset dc i2'2,4,10,12' WritePattern ENTRY ldx #BRamOffset ; battery ram counter ldy #0 ; pattern counter PatternLoup lda UserBackground,y ; current value sta $61,x ; save it inx inx iny iny cpy #8 bmi PatternLoup rts WritePalette ENTRY ldx #BRamOffset ; battery ram counter ldy #0 PaletteLoup phx ldx PaletteOffset,y ; get offset to correct value lda OldTable,x ; get value plx sta $69,x inx inx iny iny cpy #8 bmi PaletteLoup rts END **************************************************************** * * BlankScreen * **************************************************************** BlankScreen START using LibGlobals ldx #6 LoadLoop lda UserBackground,x sta Temp,x ; block of 32 temp variables dex dex bpl LoadLoop lda #$2000 sta Temp+8 lda #$20A0 sta Temp+12 lda #$2140 sta Temp+16 lda #$21E0 sta Temp+20 lda #$00E1 sta Temp+10 sta Temp+14 sta Temp+18 sta Temp+22 ldx #0 ; our scan line counter ScanLoop ldy #158 lda Temp Loop0 sta [Temp+8],y dey dey bpl Loop0 ldy #158 lda Temp+2 Loop1 sta [Temp+12],y dey dey bpl Loop1 ldy #158 lda Temp+4 Loop2 sta [Temp+16],y dey dey bpl Loop2 ldy #158 lda Temp+6 Loop3 sta [Temp+20],y dey dey bpl Loop3 txa clc adc #4 cmp #200 bpl Done tax ; back where it belongs lda Temp+8 clc adc #4*160 sta Temp+8 lda Temp+12 clc adc #4*160 sta Temp+12 lda Temp+16 clc adc #4*160 sta Temp+16 lda Temp+20 clc adc #4*160 sta Temp+20 brl ScanLoop Done jsr PaintCorners rts END ************************************************************** * * CtrlData * ************************************************************** CtrlData DATA PushButtonOff anop dc h'F00000000FFF' ; 0 dc h'00EEEEEE00FF' ; 1 dc h'0EEEEEEEE01F' ; 2 dc h'0EEEEEEEE01F' ; 3 dc h'0EEEEEEEE01F' ; 4 dc h'0EEEEEEEE01F' ; 5 dc h'00EEEEEE001F' ; 6 dc h'F0000000011F' ; 7 dc h'FF11111111FF' ; 8 PushButtonOn anop dc h'F00000000FFF' ; 0 dc h'0066666600FF' ; 1 dc h'06666666601F' ; 2 dc h'06666666601F' ; 3 dc h'06666666601F' ; 4 dc h'06666666601F' ; 5 dc h'00666666001F' ; 6 dc h'F0000000011F' ; 7 dc h'FF11111111FF' ; 8 PushButtonDown anop dc h'FFFFFFFFFFFF' ; 0 dc h'FF00000000FF' ; 1 dc h'F0066666600F' ; 2 dc h'F0666666660F' ; 3 dc h'F0666666660F' ; 4 dc h'F0666666660F' ; 5 dc h'F0666666660F' ; 6 dc h'F0066666600F' ; 7 dc h'FF00000000FF' ; 8 SlideOff anop dc h'FFF0000000000FFF' ; 0 dc h'FF002222222200FF' ; 1 dc h'F00222222222200F' ; 2 dc h'0022222222222200' ; 3 dc h'F00222222222200F' ; 4 dc h'FF002222222200FF' ; 5 dc h'FFF0000000000FFF' ; 6 SlideOn anop dc h'FFF0000000000FFF' ; 0 dc h'FF006666666600FF' ; 1 dc h'F00666666666600F' ; 2 dc h'0066666666666600' ; 3 dc h'F00666666666600F' ; 4 dc h'FF006666666600FF' ; 5 dc h'FFF0000000000FFF' ; 6 TopBar anop dc h'FFFF00000000FFFF' dc h'FFF02EEEEEEC0FFF' BarOff anop dc h'FFF0EEEEEEEE0FFF' dc h'FFF0EEEEEEEE0FFF' dc h'FFF0EEEEEEEE0FFF' dc h'FFF0EEEEEEEE0FFF' dc h'FFF0EEEEEEEE0FFF' dc h'FFF0EEEEEEEE0FFF' dc h'FFF0EEEEEEEE0FFF' dc h'FFF02EEEEEEC0FFF' BottomBar anop dc h'FFFF00000000FFFF' BarOn anop dc h'FFF0666666660FFF' ; 0 dc h'FFF0666666660FFF' ; 1 dc h'FFF0666666660FFF' ; 2 dc h'FFF0666666660FFF' ; 3 dc h'FFF0666666660FFF' ; 4 dc h'FFF0666666660FFF' ; 5 dc h'FFF0666666660FFF' ; 6 ButtonOff anop dc h'FF000000000000000000000000000000000000000000000000FF' dc h'C033333333333333333333333333333333333333333333333003' dc h'0333333333333333333333333333333333333333333333333330' dc h'0333333333333333333333333333333333333333333333333330' dc h'0333333333333333333333333333333333333333333333333330' dc h'0333333333333333333333333333333333333333333333333330' dc h'0333333333333333333333333333333333333333333333333330' dc h'0333333333333333333333333333333333333333333333333330' dc h'0333333333333333333333333333333333333333333333333330' dc h'0333333333333333333333333333333333333333333333333330' dc h'C033333333333333333333333333333333333333333333333003' dc h'FF000000000000000000000000000000000000000000000000FF' ButtonOn anop dc h'FF000000000000000000000000000000000000000000000000FF' dc h'C037777777777777777777777777777777777777777777777403' dc h'0777777777777777777777777777777777777777777777777770' dc h'0777777777777777777777777777777777777777777777777770' dc h'0777777777777777777777777777777777777777777777777770' dc h'0777777777777777777777777777777777777777777777777770' dc h'0777777777777777777777777777777777777777777777777770' dc h'0777777777777777777777777777777777777777777777777770' dc h'0777777777777777777777777777777777777777777777777770' dc h'0777777777777777777777777777777777777777777777777770' dc h'C037777777777777777777777777777777777777777777777403' dc h'FF000000000000000000000000000000000000000000000000FF' ButtonDown anop dc h'FF000000000000000000000000000000000000000000000000FF' dc h'C004444444444444444444444444444444444444444444444403' dc h'0444444444444444444444444444444444444444444444444440' dc h'0444444444444444444444444444444444444444444444444440' dc h'0444444444444444444444444444444444444444444444444440' dc h'0444444444444444444444444444444444444444444444444440' dc h'0444444444444444444444444444444444444444444444444440' dc h'0444444444444444444444444444444444444444444444444440' dc h'0444444444444444444444444444444444444444444444444440' dc h'0444444444444444444444444444444444444444444444444440' dc h'C004444444444444444444444444444444444444444444444403' dc h'FF000000000000000000000000000000000000000000000000FF' Jumper ds 4 Nuller ds 4 Upper ds 4 Vector ds 4 Manager dc i2'PushButtonMgr' dc i2'SlideMgr' dc i2'ButtonMgr' dc i2'StringMgr' dc i2'CopyMgr' dc i2'GridMgr' dc i2'DialogMgr' dc i2'VScrollMgr' dc i2'HScrollMgr' dc i2'PatternGridMgr' dc i2'MaskGridMgr' dc i2'LineMgr' dc i2'RectMgr' dc i2'OvalMgr' dc i2'RoundRectMgr' dc i2'ArcMgr' dc i2'PolygonMgr' END **************************************************************** * * FastCopy!(FastSrc,FastSLen,FastDst,FastDLen,FastWidth,FastHeight) * **************************************************************** FastCopy START bra CutInside NextLine lda FastSrc ; get the last screen position clc adc FastSLen ; increment by a scan line of bytes sta FastSrc ; save it for next time bcc IncrementDst inc FastSrc+2 IncrementDst lda FastDst ; get pointer to save area clc adc FastDLen sta FastDst bcc CheckHeight inc FastDst+2 CheckHeight dec FastHeight ; one less scan line bne CutInside ; if not zero, do the next line rts CutInside ldy FastWidth ; set y dey ; decrement y by 2, point at last word dey NextWord lda [FastSrc],y ; get data from Src sta [FastDst],y ; save it to Dst dey ; dock y by a word dey bpl NextWord ; if it isn't negative, do some more bra NextLine ; update pointers even if we're done END ************************************************************** * * DrawCtrl!(FastSrc,FastSLen,CtrlV,CtrlH,FastWidth,FastHeight) * ************************************************************** DrawCtrl START using CtrlData pea 0 pei (CtrlV) pea 160 jsr Multiply ; do it (THVRf) pla ; (THVR) sta Temp ; save result lda CtrlH lsr A ; divide by 4 to get byte offset lsr A clc adc Temp ; add in V adc #$2000 ; add in screen beginning sta FastDst ; this is the destination lda #$00E1 ; screen bank sta FastDst+2 lda #160 ; distance (bytes) between scanlines sta FastDLen jsr FastCopy rts END ************************************************************** * * HitTest * ************************************************************** HitTest START using LibGlobals lda MousePos cmp CtrlY1 bmi NoHit cmp CtrlY2 bpl NoHit lda MousePos+2 cmp CtrlX1 bmi NoHit cmp CtrlX2 bpl NoHit sec rts NoHit clc rts END ************************************************************** * * PushButtonMgr!(CtrlPtr,CtrlMsg) * ************************************************************** PushButtonMgr START using LibGlobals using CtrlData ldy #2 ; offset to state info lda [CtrlPtr],y ; check for init cmp #LastMsg ; see if it isn't an address bcs Okay sta CtrlMsg ; swap our initial message in lda #PushButtonOff sta [CtrlPtr],y ; just in case it drops through Okay lda CtrlMsg cmp #DrawMsg beq DrawButton cmp #OffMsg bne NotOff lda #PushButtonOff sta [CtrlPtr],y bra DrawButton NotOff cmp #OnMsg bne NotOn lda #PushButtonOn sta [CtrlPtr],y bra DrawButton NotOn cmp #DownMsg bne NotDown lda #PushButtonDown sta [CtrlPtr],y bra DrawButton NotDown cmp #TrackMsg bne NotTrack brl TrackPusher NotTrack clc rts DrawButton lda [CtrlPtr],y ; get state information sta FastSrc ; save it phk phk pla and #$00FF sta FastSrc+2 lda #6 sta FastWidth sta FastSLen lda #9 sta FastHeight ldy #6 lda [CtrlPtr],y ; get H sta CtrlH ldy #4 lda [CtrlPtr],y ; get V sta CtrlV jsr DrawCtrl clc rts TrackPusher ldy #4 ; Y1 lda [CtrlPtr],y sta CtrlY1 clc adc #9 sta CtrlY2 ldy #6 lda [CtrlPtr],y ; X1 sta CtrlX1 clc adc #24 sta CtrlX2 jsr HitTest bcs GotOne rts GotOne ldy #8 lda [CtrlPtr],y beq NoHandler sta Jumper ldx #0 jsr (Jumper,x) NoHandler sec rts END ************************************************************** * * SlideMgr!(CtrlPtr,CtrlMsg) * ************************************************************** SlideMgr START using CtrlData using LibGlobals ldy #2 ; offset to state info lda [CtrlPtr],y ; check for init cmp #LastMsg ; see if it isn't an address bcs Okay * It wasn't initialized, so we have to draw the whole thing. Drawing jsr DrawSlidebar ldy #2 lda #SlideOff sta [CtrlPtr],y ; just in case it drops through clc rts ; okay, go home Okay lda CtrlMsg cmp #TrackMsg bne NotTrack brl TrackSlider NotTrack lda CtrlMsg cmp #DrawMsg bne NotDraw bra Drawing NotDraw cmp #UpdateMsg bne NotUpdate jsr UpdateSlider clc rts NotUpdate clc rts ; for the moment, ignore all else DrawSlideBar pea 0 ldy #4 ; get V lda [CtrlPtr],y sta CtrlV ; keep a copy pha pea 160 ; * 160 jsr Multiply pla sta Temp ; save result ldy #6 ; get H lda [CtrlPtr],y sta CtrlH ; keep a copy lsr A ; divide by 4 to get byte offset lsr A clc adc Temp adc #$2000 sta FastDst ; set up FastFill lda #$00E1 sta FastDst+2 lda #160 sta FastDLen lda #8 sta FastWidth sta FastSLen * Now we set up FastSrc and FastSLen (multiple times) and call FastCopy ldy #8 lda [CtrlPtr],y ; get height sta CtrlHeight ; save it lda #TopBar bra Inward CopyLoop lda #BarOff ; address of data Inward sta FastSrc phk phk pla and #$00FF sta FastSrc+2 lda CtrlHeight ; get total height left cmp #7 beq LastOne bcc LastOne sbc #7 ; how convenient - the carry is set sta CtrlHeight ; update it lda #7 sta FastHeight jsr FastCopy bra CopyLoop LastOne ina ; add in the bottom line sta FastHeight dea ; we were just kidding asl A ; multiply by 8 bytes/line asl A asl A eor #$FFFF ; negate it ina clc adc #BottomBar ; where we should start sta FastSrc phk phk pla and #$00FF sta FastSrc+2 jsr FastCopy bra DrawSlider UpdateSlider ldy #10 ; offset to old position lda [CtrlPtr],y clc ldy #4 ; offset to top of slide adc [CtrlPtr],y ; add in top adc #3 ; add in offset to top sta CtrlV ; where we start ldy #6 ; offset to H lda [CtrlPtr],y sta CtrlH lda #BarOff sta FastSrc ; FastSLen was set above phk phk pla and #$00FF sta FastSrc+2 lda #7 ; height of the slider sta FastHeight lda #8 sta FastWidth sta FastSLen jsr DrawCtrl ; and fall through * Now all we have to do is draw the slider at the new position DrawSlider ldy #12 ; offset to new position lda [CtrlPtr],y ldy #10 ; offset to old position sta [CtrlPtr],y ; update it clc ldy #4 ; offset to top of slide adc [CtrlPtr],y ; add in top adc #3 ; add in offset to top sta CtrlV ; where we start lda #SlideOff ldy #2 sta [CtrlPtr],y ; the slider is off sta FastSrc ; FastSLen was set above phk phk pla and #$00FF sta FastSrc+2 lda #7 ; height of the slide sta FastHeight jsr DrawCtrl clc rts * In TrackSlider we first see if it's anywhere in the control, remembering * the top and bottom in CtrlV and CtrlH. If it is, adjust CtrlY1 and CtrlY2 * to be the thumb top and bottom. If not there, inset CtrlX1 and CtrlX2, * swap CtrlV, CtrlY2, and CtrlY1, and see if its above the thumb. If not, * CtrlY1 := CtrlV and CtrlY2 := CtrlH, and see if its below the thumb. * If not, forget it. TrackSlider ldy #4 ; get top lda [CtrlPtr],y sta CtrlY1 ; save top sta CtrlV ; for later, maybe clc ldy #8 adc [CtrlPtr],y ; add height to get bottom sta CtrlY2 ; save bottom sta CtrlH ; for later, maybe ldy #6 ; get left lda [CtrlPtr],y sta CtrlX1 ; save it clc adc #32 sta CtrlX2 ; save right jsr HitTest bcs GotOne rts GotOne ldy #10 ; offset to old position lda [CtrlPtr],y clc adc CtrlY1 ; add in top base ina ; bump by top sluff ina ina sta CtrlY1 ; save thumb top clc adc #7 sta CtrlY2 ; save thumb bottom jsr HitTest bcc NotThumb brl SetupThumb NotThumb lda CtrlX1 clc adc #6 sta CtrlX1 lda CtrlX2 sec sbc #6 sta CtrlX2 ldx CtrlY1 ; top of thumb lda CtrlV ; top of slide sta CtrlY1 ; new top lda CtrlY2 ; save old bottom in V sta CtrlV stx CtrlY2 ; new bottom jsr HitTest bcc NotTopSlider brl SetupTop NotTopSlider lda CtrlV ; get saved top sta CtrlY1 lda CtrlH ; get saved bottom sta CtrlY2 jsr HitTest bcs SetupBottom rts SetupBottom inc CtrlFound ; we will manage it pea BottomHandler pea BottomRelease jsr TrackSetup rts SetupTop inc CtrlFound pea TopHandler pea TopRelease jsr TrackSetup rts SetupThumb inc CtrlFound pea ThumbHandler pea ThumbRelease jsr TrackSetup lda MousePos sec sbc CtrlY1 ; remove thumb position sta CtrlY2 ; better be less than 7 rts BottomHandler jsr HitTest bcs GotBottom rts GotBottom lda #1 jsr Updater ldy #10 lda [CtrlPtr],y ; get old value clc ldy #4 ; get top base adc [CtrlPtr],y clc adc #7 ; add size of thumb sta CtrlY1 ; update top of bottom rts BottomRelease jsr BottomHandler ; give it a final kick jsr TrackCleanup rts TopHandler jsr HitTest bcs GotTop rts GotTop lda #-1 jsr Updater ldy #10 lda [CtrlPtr],y ; get old value clc ; add base adc CtrlY1 ina ; add top sluff ina ina sta CtrlY2 ; update bottom of top rts TopRelease jsr TopHandler jsr TrackCleanup rts ThumbHandler sec lda MousePos ; get current Y sbc CtrlY2 ; subtract anchor sec sbc CtrlY1 ; subtract current thumb position bne GotThumb rts GotThumb jsr Updater ldy #10 lda [CtrlPtr],y ; get old value clc ldy #4 adc [CtrlPtr],y ; add top base sta CtrlY1 ; save our index rts ; all done ThumbRelease jsr ThumbHandler jsr TrackCleanup rts TrackSetup pea 0 pea NullEvent jsr GetHandler pla sta Nuller ; and save it above pea 0 pea MouseUpEvent jsr GetHandler pla sta Upper plx ; get return ply ; get release handler pla ; get track handler phx ; push return pea MouseUpEvent phy ; push release pea NullEvent pha ; push track handler jsr SetHandler ; set track handler jsr SetHandler ; set release handler sec ; we handled it rts TrackCleanup pea NullEvent lda Nuller pha jsr SetHandler pea MouseUpEvent lda Upper pha jsr SetHandler rts Updater sta Temp ; save delta ldy #10 ; fetch old value lda [CtrlPtr],y clc adc Temp bpl NotNegative lda [CtrlPtr],y ; old value is now -delta bne SwitchIt rts SwitchIt eor #$FFFF ina bra JumpInThere NotNegative clc adc #12 ; excess height-1 ldy #8 ; offset to height cmp [CtrlPtr],y ; is it off the end? bmi NotTooHigh lda [CtrlPtr],y ; get height sec sbc #13 ; remove excess height sec ldy #10 sbc [CtrlPtr],y ; remove current value bne JumpInThere rts JumpInThere sta Temp NotTooHigh lda Temp clc ; calculate new value ldy #10 adc [CtrlPtr],y ldy #12 sta [CtrlPtr],y ; save it _HideCursor jsr UpdateSlider ; redraw it _ShowCursor ldy #14 lda [CtrlPtr],y beq NoManager sta Jumper ldx #0 jsr (Jumper,x) ; parameter is delta:integer NoManager rts END ************************************************************** * * ButtonMgr!(CtrlPtr,CtrlMsg) * ************************************************************** ButtonMgr START using LibGlobals using CtrlData ldy #2 ; offset to state info lda [CtrlPtr],y ; check for init cmp #LastMsg ; see if it isn't an address bcs Okay sta CtrlMsg ; swap our initial message in lda #ButtonOff sta [CtrlPtr],y ; just in case it drops through ldy #14 lda #$8003 ; the default sta [CtrlPtr],y Okay lda CtrlMsg cmp #DrawMsg beq DrawButton cmp #OffMsg bne NotOff ldy #2 lda #ButtonOff sta [CtrlPtr],y ldy #14 lda #$8003 sta [CtrlPtr],y bra DrawButton NotOff cmp #OnMsg bne NotOn ldy #2 lda #ButtonOn sta [CtrlPtr],y ldy #14 lda #$8003 sta [CtrlPtr],y bra DrawButton NotOn cmp #DownMsg bne NotDown ldy #2 lda #ButtonDown sta [CtrlPtr],y ldy #14 lda #$8001 sta [CtrlPtr],y bra DrawButton NotDown cmp #TrackMsg bne NotTrack brl TrackButton NotTrack clc rts DrawButton ldy #2 lda [CtrlPtr],y ; get state information sta FastSrc ; save it phk phk pla and #$00FF sta FastSrc+2 lda #26 sta FastWidth sta FastSLen lda #12 sta FastHeight ldy #6 lda [CtrlPtr],y ; get H sta CtrlH ldy #4 lda [CtrlPtr],y ; get V sta CtrlV jsr DrawCtrl * Now center the text inside the control ldy #12 ; high word of text pointer lda [CtrlPtr],y tax pha ldy #10 lda [CtrlPtr],y pha pea 0 ; function result phx ; push it again pha _StringWidth ; get the width pla lsr A ; divide by 2 sta Temp clc lda CtrlH ; get start adc #52 ; generalize this later sec sbc Temp ; subtract half the string width pha ; push it clc lda CtrlV adc #9 ; offset to baseline pha _MoveTo ldy #14 lda [CtrlPtr],y pha _SetTextMode _DrawString ; pointer is on top of stack PushWord StdTextMode _SetTextMode clc rts TrackButton ldy #2 lda [CtrlPtr],y cmp #ButtonOff bne NotInactive clc rts NotInactive ldy #4 ; Y1 lda [CtrlPtr],y sta CtrlY1 clc adc #12 sta CtrlY2 ldy #6 lda [CtrlPtr],y ; X1 sta CtrlX1 clc adc #104 sta CtrlX2 jsr HitTest bcs GotOne rts GotOne inc CtrlFound ; we will manage it pea 0 pea NullEvent jsr GetHandler pla sta Nuller ; and save it above pea 0 pea MouseUpEvent jsr GetHandler pla sta Upper pea NullEvent pea ButtonTracker jsr SetHandler pea MouseUpEvent pea ButtonRelease jsr SetHandler TurnItOn ldy #2 lda #ButtonDown sta [CtrlPtr],y ldy #14 lda #$8001 sta [CtrlPtr],y _HideCursor jsr DrawButton ; draw it _ShowCursor * pea SteadyHum * jsr SoundEffects sec ; we handled it rts ButtonTracker jsr HitTest ; are we inside? ldy #2 lda [CtrlPtr],y bcc NoHit ; the result of HitTest cmp #ButtonDown ; is it already down? beq LeaveIt jsr TurnItOn LeaveIt clc rts NoHit cmp #ButtonOn ; is it already just "on"? beq LeaveIt TurnItOff lda #ButtonOn sta [CtrlPtr],y ldy #14 lda #$8003 sta [CtrlPtr],y _HideCursor jsr DrawButton _ShowCursor * pea Silence * jsr SoundEffects rts ButtonRelease jsr ButtonTracker ; to put it in it's final state pea NullEvent lda Nuller pha jsr SetHandler pea MouseUpEvent lda Upper pha jsr SetHandler ldy #2 lda [CtrlPtr],y cmp #ButtonDown bne NoHandler jsr TurnItOff ; restore it ldy #16 lda [CtrlPtr],y ; get handler beq NoHandler sta Jumper ldx #0 jsr (Jumper,x) NoHandler clc rts END *===== * * StringMgr * StringMgr START using LibGlobals * dc i2'StringMgr' * dc i2'DrawMsg' * dc i2'0,0' ; y,x * dc i4'MyString' ; string ptr * dc i4'Mode' ; text mode lda CtrlMsg beq DrawString clc rts DrawString ldy #6 ; offset to H lda [CtrlPtr],y pha ldy #4 ; offset to V lda [CtrlPtr],y pha _MoveTo ldy #12 lda [CtrlPtr],y sta Temp cmp StdTextMode beq DontBother pha _SetTextMode DontBother ldy #10 lda [CtrlPtr],y pha ldy #8 lda [CtrlPtr],y pha _DrawString lda Temp cmp StdTextMode beq DidntChange PushWord StdTextMode _SetTextMode DidntChange clc rts END ************************************************************** * * CopyMgr!(CtrlPtr,CtrlMsg) * ************************************************************** CopyMgr START using CtrlData lda CtrlMsg cmp #DrawMsg beq CopyIt clc rts CopyIt ldy #12 ; offset to block pointer lda [CtrlPtr],y sta FastSrc ldy #14 lda [CtrlPtr],y sta FastSrc+2 ldy #8 ; offset to width lda [CtrlPtr],y sta FastWidth sta FastSLen ldy #10 ; offset to height lda [CtrlPtr],y sta FastHeight ldy #6 ; offset to H lda [CtrlPtr],y sta CtrlH ldy #4 ; offset to V lda [CtrlPtr],y sta CtrlV jsr DrawCtrl Done clc rts END ************************************************************** * * GridMgr!(CtrlPtr,CtrlMsg) * ************************************************************** GridMgr START using CtrlData using LibGlobals lda CtrlMsg cmp #TrackMsg beq TrackIt clc rts TrackIt jsr GridSetup jsr HitTest bcs GotOne rts GotOne ldy #2 ; single or multiple tracking? lda [CtrlPtr],y beq SingleTrack brl MultiTrack SingleTrack ldy #14 ; get dX lda [CtrlPtr],y sta CtrlH stz Temp lda CtrlX1 dea ; so we fall within bounds clc bra XIn XLoop inc Temp XIn adc CtrlH cmp MousePos+2 bmi XLoop pei (Temp) ; push X grid value (0 based) ina ; set up horizontal rect values sta CtrlX2 sec sbc CtrlH sta CtrlX1 ldy #12 ; get dY lda [CtrlPtr],y sta CtrlV stz Temp lda CtrlY1 dea ; so we fall within bounds clc bra YIn YLoop inc Temp YIn adc CtrlV cmp MousePos bmi YLoop pei (Temp) ; push Y grid value (0 based) ina ; set up vertical rect values sta CtrlY2 sec sbc CtrlV sta CtrlY1 ldy #16 lda [CtrlPtr],y sta Jumper ldx #0 jsr (Jumper,x) ; parameters are H,V from 0,0 NoHandler sec rts MultiTrack inc CtrlFound ; we will manage it pea 0 ; capture current handlers pea NullEvent jsr GetHandler pla sta Nuller pea 0 pea MouseUpEvent jsr GetHandler pla sta Upper pea NullEvent pea GridTracker jsr SetHandler pea MouseUpEvent pea GridRelease jsr SetHandler jsr SingleTrack ; do one sec rts GridTracker jsr GridSetup jsr HitTest ; are we inside? bcc NoHit ; the result of HitTest jsr SingleTrack ; pretend we're single tracking clc NoHit rts GridRelease pea NullEvent lda Nuller pha jsr SetHandler pea MouseUpEvent lda Upper pha jsr SetHandler bra GridTracker ; track one last time GridSetup ldy #4 ; get Y1 lda [CtrlPtr],y sta CtrlY1 ldy #6 ; get X1 lda [CtrlPtr],y sta CtrlX1 ldy #8 ; get Y2 lda [CtrlPtr],y sta CtrlY2 ldy #10 ; get X2 lda [CtrlPtr],y sta CtrlX2 rts END ************************************************************** * * MsgResource(RsrcPtr,Msg) * ************************************************************* MsgResource START using CtrlData _HideCursor plx ; pull return pla ; get message sta CtrlMsg pla ; pull address of resource sta RsrcPtr pla sta RsrcPtr+2 phx ; push return back lda [RsrcPtr] ; get number of resources asl A ; double it for a word offset ina ; add in last word ina sta RsrcMax ; just past last resource lda #2 sta RsrcCtr ; init our counter pei (CtrlMsg) ; save it in case they change it RsrcLoop ldy RsrcCtr cpy RsrcMax bpl Done lda [RsrcPtr],y ; get the part offset iny ; bump y to next part iny sty RsrcCtr ; save it tay ; get the offset back lda [RsrcPtr],y ; get the manager number asl A ; make it a word offset tax ; save it tya ; get offset to control clc ; set CtrlPtr to point at control adc RsrcPtr sta CtrlPtr lda #0 adc RsrcPtr+2 sta CtrlPtr+2 lda 1,s ; update CtrlMsg sta CtrlMsg jsr (Manager,x) ; handle it bcs Done ; if they handled it (carry) we quit bra RsrcLoop Done pla ; we don't need CtrlMsg anymore _ShowCursor rts END ************************************************************** * * MsgControl(CtrlPtr,Msg) * ************************************************************* MsgControl START using CtrlData _HideCursor plx ; pull return pla ; get message sta CtrlMsg pla ; pull address of control sta CtrlPtr pla sta CtrlPtr+2 phx ; push return back lda [CtrlPtr] ; get the manager asl A ; make it a word offset tax ; save it jsr (Manager,x) ; handle it _ShowCursor rts END *===== * * DialogMgr * DialogMgr START using LibGlobals lda CtrlMsg cmp #DrawMsg beq DrawDialog clc rts DrawDialog jsr CopyCtrlRect sec lda CtrlY2 sbc CtrlY1 sta MenuHeight lda CtrlX1 lsr A sta CtrlX1 lda CtrlX2 clc adc #3 lsr A   !"#$%&'()*+,-./ sta CtrlX2 sec sbc CtrlX1 sta MenuWidth ldy CtrlY1 lda #0 DAgain dey bmi GotStart clc adc #160 bra DAgain GotStart clc adc CtrlX1 sta MenuStart jsr SaveScreen stz FastFlags jsr DrawFastWindow clc rts CopyCtrlRect ENTRY ldy #4 lda [CtrlPtr],y ; get bottom sta CtrlY1 ldy #6 lda [CtrlPtr],y ; subtract top sta CtrlX1 ldy #8 lda [CtrlPtr],y sta CtrlY2 ldy #10 lda [CtrlPtr],y sta CtrlX2 rts END *===== * * VScrollMgr * VScrollMgr START using LibGlobals lda CtrlMsg beq DrawVBar clc rts DrawVBar clc rts END ************************************************************** * * HScrollMgr * ************************************************************** HscrollMgr START using LibGlobals lda CtrlMsg beq DrawHBar clc rts DrawHBar clc rts END ************************************************************** * * PatternGridMgr * ************************************************************** PatternGridMgr START MaskGridMgr ENTRY using LibGlobals using CtrlData * dc i2'PatternGrid' ; draw a line grid * dc i2'DrawMsg' ; only draw * dc i2'19,384' ; top, left * dc i2'0,0' ; space for bottom, right * dc i2'8,16' ; dy, dx (not counting lines) * dc i2'4,4' ; x units, y units * dc i4'StdPatterns' ; pointer to standard patterns * dc i2'0' ; no manager yet lda CtrlMsg cmp #DrawMsg beq DrawGrid cmp #TrackMsg bne NotTracking brl TrackGrid NotTracking clc rts DrawGrid ldy #6 ; left lda [CtrlPtr],y sta CtrlX1 ldy #18 ; x divisions lda [CtrlPtr],y sta CtrlH ldy #14 ; delta x lda [CtrlPtr],y ina ; add in x pensize ina sta Temp+6 ; h increment lda CtrlX1 ldx CtrlH XLoop clc adc Temp+6 dex bne XLoop sta CtrlX2 ; ignore last pensize ina ; last pensize ina ldy #10 sta [CtrlPtr],y ldy #4 ; top lda [CtrlPtr],y sta CtrlY1 ldy #16 ; y divisions lda [CtrlPtr],y sta CtrlV ldy #12 ; delta y lda [CtrlPtr],y ina ; add in y pensize sta Temp+4 ; v increment lda CtrlY1 ldx CtrlV YLoop clc adc Temp+4 dex bne YLoop sta CtrlY2 ; ignore last pensize ina ; last pensize ldy #8 sta [CtrlPtr],y pea 2 pea 1 _PenSize ; set it pea $0000 ; black jsr SetPenColor lda CtrlV sta Temp ; counter lda CtrlY1 bra HCut HLoop clc lda Temp+2 ; temp2 is currenty adc Temp+4 ; temp4 is dy, from above HCut sta Temp+2 pei (CtrlX1) pha _MoveTo pei (CtrlX2) pei (Temp+2) _LineTo dec Temp bpl HLoop lda CtrlH sta Temp ; counter lda CtrlX1 bra VCut VLoop clc lda Temp+2 ; temp2 is currentx adc Temp+6 ; temp6 is dx, from above VCut sta Temp+2 pha pei (CtrlY1) _MoveTo pei (Temp+2) pei (CtrlY2) _LineTo dec Temp bpl VLoop * Now we fill with patterns (or masks, later on) RCtr equ Temp CCtr equ Temp+2 Rdx equ Temp+4 Cdy equ Temp+6 MyRect equ Temp+8 PatPointer equ Temp+16 ldy #20 lda [CtrlPtr],y ; fetch pattern pointer sta PatPointer ldy #22 lda [CtrlPtr],y sta PatPointer+2 ora PatPointer bne APattern clc rts APattern ldy #12 lda [CtrlPtr],y ; fetch dy sta Cdy ldy #14 lda [CtrlPtr],y ; fetch dx sta Rdx lda CtrlY1 sta MyRect+4 lda CtrlV sta RCtr NextRow lda MyRect+4 ina ; skip over pen sta MyRect clc adc Cdy sta MyRect+4 lda CtrlX1 sta MyRect+6 lda CtrlH sta CCtr NextColumn lda MyRect+6 ina ina sta MyRect+2 clc adc Rdx sta MyRect+6 lda [CtrlPtr] cmp #PatternGrid beq NotAMask jsr ExpandMask bra NoBumpPatPtr NotAMask lda PatPointer+2 pha lda PatPointer pha clc adc #32 sta PatPointer bcc NoBumpPatPtr inc PatPointer+2 NoBumpPatPtr _PenPat pea 0 tdc clc adc #MyRect pha _PaintRect dec CCtr bne NextColumn dec RCtr bne NextRow rts * It was a mask, not a pattern, so we need to expand it, and update * PatPointer by 8 bytes when we are done. Currently expand it to * a 640 style pattern (ie, 8 by 8, not 8 by 16) ExpandMask ldy #0 sty PatOffset ExpandLoop lda [PatPointer],y sta PatValue iny sty PatByte ldy PatOffset and #$00F0 ; get high nibble lsr A lsr A lsr A lsr A tax lda Masker,x ; double the nibble sta MaskPat,y iny lda PatValue and #$000F tax lda Masker,x ; double it sta MaskPat,y iny sty PatOffset ldy PatByte cpy #8 bmi ExpandLoop plx stx PatByte PushPtr MaskPat ldx PatByte phx lda PatPointer clc adc #8 sta PatPointer bcc NoBumpMaskPtr inc PatPointer+2 NoBumpMaskPtr rts MaskPat ds 34 PatByte ds 2 PatOffset ds 2 PatValue ds 2 Masker dc i1'$00,$03,$0C,$0F,$30,$33,$3C,$3F' dc i1'$C0,$C3,$CC,$CF,$F0,$F3,$FC,$FF' * Handle tracking for the grid TrackGrid jsr GridSetup jsr HitTest bcs GotOne rts GotOne ldy #2 ; single or multiple tracking? lda [CtrlPtr],y beq SingleTrack brl MultiTrack SingleTrack ldy #14 ; get dX lda [CtrlPtr],y ina ; add in pensize ina sta CtrlH stz Temp lda CtrlX1 dea ; so we fall within bounds clc bra XIn TXLoop inc Temp XIn adc CtrlH cmp MousePos+2 bmi TXLoop pei (Temp) ; push X grid value (0 based) ina ; set up horizontal rect values sta CtrlX2 sec sbc CtrlH sta CtrlX1 ldy #12 ; get dY lda [CtrlPtr],y ina ; add in pensize sta CtrlV stz Temp lda CtrlY1 dea ; so we fall within bounds clc bra YIn TYLoop inc Temp YIn adc CtrlV cmp MousePos bmi TYLoop pei (Temp) ; push Y grid value (0 based) ina ; set up vertical rect values sta CtrlY2 sec sbc CtrlV sta CtrlY1 ldy #24 lda [CtrlPtr],y beq NoHandler sta Jumper ldx #0 jsr (Jumper,x) ; parameters are H,V from 0,0 sec rts NoHandler pla pla sec rts MultiTrack inc CtrlFound ; we will manage it pea 0 ; capture current handlers pea NullEvent jsr GetHandler pla sta Nuller pea 0 pea MouseUpEvent jsr GetHandler pla sta Upper pea NullEvent pea GridTracker jsr SetHandler pea MouseUpEvent pea GridRelease jsr SetHandler jsr SingleTrack ; do one sec rts GridTracker jsr GridSetup jsr HitTest ; are we inside? bcc NoHit ; the result of HitTest jsr SingleTrack ; pretend we're single tracking clc NoHit rts GridRelease pea NullEvent lda Nuller pha jsr SetHandler pea MouseUpEvent lda Upper pha jsr SetHandler bra GridTracker ; track one last time GridSetup ldy #4 ; get Y1 lda [CtrlPtr],y sta CtrlY1 ldy #6 ; get X1 lda [CtrlPtr],y sta CtrlX1 ldy #8 ; get Y2 lda [CtrlPtr],y sta CtrlY2 ldy #10 ; get X2 lda [CtrlPtr],y sta CtrlX2 rts END ************************************************************** * * LineMgr * ************************************************************** LineMgr START using LibGlobals * dc i2'Line' * dc i2'DrawMsg' * dc i2'21,146,30,172' * dc i4'StdBlack' * dc i2'1,2' ; pensize lda CtrlMsg beq DrawLine clc rts DrawLine ldy #18 ; pensize lda [CtrlPtr],y pha ldy #16 lda [CtrlPtr],y pha _PenSize ldy #14 lda [CtrlPtr],y pha ldy #12 lda [CtrlPtr],y pha _PenPat ldy #6 lda [CtrlPtr],y pha ldy #4 lda [CtrlPtr],y pha _MoveTo ldy #10 lda [CtrlPtr],y pha ldy #8 lda [CtrlPtr],y pha _LineTo clc rts END ************************************************************** * * RectMgr * ************************************************************** RectMgr START using LibGlobals * dc i2'Rect' * dc i2'DrawMsg' * dc i2'21,146,30,172' * dc i4'StdBlack' * dc i4'StdTurquoise' lda CtrlMsg beq DrawRect clc rts DrawRect clc lda CtrlPtr adc #4 sta Temp lda CtrlPtr+2 adc #0 sta Temp+2 ldy #16 ; offset to interior patptr lda [CtrlPtr],y sta Temp+4 ldy #18 lda [CtrlPtr],y sta Temp+6 ora Temp+4 beq NoInterior pei (Temp+6) pei (Temp+4) _PenPat pei (Temp+2) pei (Temp) _PaintRect NoInterior ldy #12 lda [CtrlPtr],y sta Temp+4 ldy #14 lda [CtrlPtr],y sta Temp+6 ora Temp+4 beq Done pei (Temp+6) pei (Temp+4) _PenPat pei (Temp+2) pei (Temp) _FrameRect Done clc rts END ************************************************************** * * OvalMgr * ************************************************************** OvalMgr START using LibGlobals * dc i2'Oval' ; a fast copy * dc i2'DrawMsg' ; never more than draw * dc i2'21,146,30,172' ; oval rect * dc i4'StdBlack' ; frame color * dc i4'StdTurquoise' ; interior color lda CtrlMsg beq DrawOval clc rts DrawOval clc lda CtrlPtr adc #4 sta Temp lda CtrlPtr+2 adc #0 sta Temp+2 ldy #16 ; offset to interior patptr lda [CtrlPtr],y sta Temp+4 ldy #18 lda [CtrlPtr],y sta Temp+6 ora Temp+4 beq NoInterior pei (Temp+6) pei (Temp+4) _PenPat pei (Temp+2) pei (Temp) _PaintOval NoInterior ldy #12 lda [CtrlPtr],y sta Temp+4 ldy #14 lda [CtrlPtr],y sta Temp+6 ora Temp+4 beq Done pei (Temp+6) pei (Temp+4) _PenPat pei (Temp+2) pei (Temp) _FrameOval Done clc rts END ************************************************************** * * RoundRectMgr * ************************************************************** RoundRectMgr START using LibGlobals * dc i2'Rect' * dc i2'DrawMsg' * dc i2'21,146,30,172' * dc i4'StdBlack' * dc i4'StdTurquoise' * dc i2'0,0' ; curvature lda CtrlMsg beq DrawRRect clc rts DrawRRect clc lda CtrlPtr adc #4 sta Temp lda CtrlPtr+2 adc #0 sta Temp+2 ldy #20 ; fetch curvature lda [CtrlPtr],y sta Temp+8 ldy #22 lda [CtrlPtr],y sta Temp+10 ldy #16 ; offset to interior patptr lda [CtrlPtr],y sta Temp+4 ldy #18 lda [CtrlPtr],y sta Temp+6 ora Temp+4 beq NoInterior pei (Temp+6) pei (Temp+4) _PenPat pei (Temp+2) pei (Temp) pei (Temp+10) pei (Temp+8) _PaintRRect NoInterior ldy #12 lda [CtrlPtr],y sta Temp+4 ldy #14 lda [CtrlPtr],y sta Temp+6 ora Temp+4 beq Done pei (Temp+6) pei (Temp+4) _PenPat pei (Temp+2) pei (Temp) pei (Temp+10) pei (Temp+8) _FrameRRect Done clc rts END ************************************************************** * * ArcMgr * ************************************************************** ArcMgr START using LibGlobals lda CtrlMsg beq DrawArc clc rts DrawArc clc rts END ************************************************************** * * PolygonMgr * ************************************************************** PolygonMgr START using LibGlobals lda CtrlMsg beq DrawPoly clc rts DrawPoly clc rts END * Table of Contents * ================= * Event.Asm * * GetHandler(Function,Event):Handler * SetHandler(Event,Handler) * ResetHandler(EventType) * DeskEvent * EventManager *===== * * Function GetHandler(event):handler * GetHandler START using LibGlobals ReturnAddress equ 1 Result equ ReturnAddress+2 plx ; pull return address pla ; pull event number phx ; push ret023456789:;<=>?urn address asl A ; make it a word offset tax ; use it as an index lda EventTable,x sta Result,s rts END *===== * * Procedure SetHandler(event,handler) * SetHandler START using LibGlobals plx ; pull return address ply ; pull address of handler pla ; pull associated event # phx ; push return back asl A ; make it a word offset tax ; use it as an index tya ; get the address back sta EventTable,x NoEvent ENTRY rts END *===== * * Procedure ResetHandler * ResetHandler START using LibGlobals plx ; pull return pla ; pull event number phx ; push return back asl A ; make event a word offset tax ; use it as an index lda #NoEvent ; get the null routine address sta EventTable,x rts END *===== * * Desk Event * DeskEvent START * We had a desk accessory event. Read the current border color * and compare it with OldBorderColor. If they are different, he * changed it, so we want to honor that change. Set the high bit * of OldBorderColor to 1, and change the low byte to the new color. * The next time we get an event, check to see if the high bit is * set. If so, don't muck with the border color. lda OldBorderColor bpl CheckForChange rts CheckForChange pea 0 pea $1C ; Display border color _ReadBParam pla ; get value and #$0F cmp OldBorderColor beq ResetBlue ora #$8000 ; set the high bit sta OldBorderColor ; and reset our flag rts ResetBlue sep #$30 longa off longi off lda >$00C034 and #$F0 ; clear lower bits ora #$02 ; set dark blue sta >$00C034 rep #$30 longa on longi on rts END *===== * * EventManager * EventManager START using LibGlobals lda QuitFlags ; check for quitting bne AllDone jsr ClockUpdate ; give the clock some time PushWord #0 ; make room for result PushWord #$FFFF PushPtr EventRecord _GetNextEvent pla ; ignore this, check the real one lda EventRecord cmp #KeyDownEvent bne NotControlChar lda EvtMsg cmp #32 bpl NotControlChar tay ; make a copy asl A ; make it an offset tax lda ControlTable,x beq NotControlChar tya ; get the copy back jsr (ControlTable,x) ; jump into the nether regions bra EventManager NotControlChar lda EventRecord asl A tax jsr (EventTable,x) bra EventManager AllDone rts END *===== * * Restore events * RestoreEvents START using LibGlobals lda StdEvents beq NoStd ldx #0 jsr (StdEvents,x) NoStd rts END *===== * * Check memory manager consistency - put up an alert if it fails * CheckMM START lda #$00E1 sta Handle+2 lda #$1600 sta Handle lda [Handle] sta Temp ldy #2 lda [Handle],y sta Temp+2 NextHandle ldy #16 lda [Temp],y ; get next handle low sta Handle ldy #18 lda [Temp],y sta Handle+2 ora Handle beq GoodMM * Make sure the backpointer is correct - the first one is 00/0000 ldy #12 lda [Handle],y cmp Temp bne BadMM ldy #14 lda [Handle],y cmp Temp+2 bne BadMM * Make sure Temp.Addr + Temp.Size is less than or equal to Handle.Addr lda [Temp] ; get address clc ldy #8 ; offset to size adc [Temp],y ; add in low sta Temp+4 ldy #2 lda [Temp],y ldy #10 adc [Temp],y sta Temp+6 ldy #2 lda [Handle],y cmp Temp+6 bcc BadMM bne Update lda [Handle] cmp Temp+4 bcc BadMM Update MoveLong Handle,Temp bra NextHandle GoodMM lda [Temp] cmp #$C000 bne BadMM ldy #2 lda [Temp],y cmp #$00E1 bne BadMM clc rts AlertHeight equ 48 AlertWidth equ 130 AlertByte equ 15 AlertLine equ 40 MemoryAlert dc i1'MemAlertEnd-MemoryAlert-1' dc c'Memory manager inconsistency found.' MemAlertEnd anop BadMM jsr $FF1800 ; install another peeker cli ; turn on desk accessory interrupts lda #AlertHeight ; number of scan lines in full menu sta MenuHeight lda #AlertWidth ; width of menu in bytes sta MenuWidth lda #(AlertLine*160+AlertByte) ; offset ($2000) to first pixel sta MenuStart ; in bytes lda #0 sta FastFlags jsr DrawFastWindow ; let's draw a fast window pea 0 jsr SetPenColor pea 100 pea 60 _MoveTo PushPtr MemoryAlert _DrawString DoItAgain lda #1 lda #2 bra DoItAgain END ************************************************************** * * HexDigit * ************************************************************* HexDigit START cmp #$30 ; is it >='0' bmi Nope cmp #$3A ; is it >'9' bpl Maybe and #$000F ; strip extraneous bits clc ; no error rts Nope lda #0 sec @BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ rts Maybe cmp #$41 ; is it >='A' bmi Nope cmp #$47 ; is it >'F' bpl MaybeNot sec sbc #$37 ; subtract 55 clc rts MaybeNot cmp #$61 ; is it >='a' bmi Nope cmp #$67 ; is it >'f' bpl Nope sec sbc #$57 ; subtract 87 clc rts END ************************************************************** * * DrawColorValue * ************************************************************* DrawColorValue START pla ; get local return sta Temp ; save it on our zero page _MoveTo ; move to the draw point ply ; get the color value pei (Temp) ; put return value back * Fetch the high byte before we start mucking around with 8 bit mode tya ; get the value and #$0F00 ; get the red value xba ; put it in the low byte sep #$30 ; character addressing longa off longi off tax ; get the index lda CharTab,x sta MyString+1 tya ; get the value back and #$F0 ; note we have 8 bit operands lsr A ; put it in the low nibble lsr A lsr A lsr A tax lda CharTab,x sta MyString+2 tya ; get the value back and #$0F tax lda CharTab,x sta MyString+3 rep #$30 longa on longi on PushPtr MyString _DrawString rts CharTab dc i1'$30,$31,$32,$33,$34,$35,$36,$37,$38,$39' dc i1'$41,$42,$43,$44,$45,$46' MyString dc i1'$03,$20,$20,$20' END ************************************************************** * * UpdateSliders * ************************************************************* UpdateSliders START using LibGlobals using PanelData Odd1Red ENTRY lda OldTable+2 ldx Slider1+10 jsr AddRed bra FixOdd1 Odd1Green ENTRY lda OldTable+2 ldx Slider2+10 jsr AddGreen bra FixOdd1 Odd1Blue ENTRY lda OldTable+2 ldx Slider3+10 jsr AddBlue FixOdd1 sta OldTable+2 sta OldTable+18 bra FixItUp Odd2Red ENTRY lda OldTable+4 ldx Slider4+10 jsr AddRed bra FixOdd2 Odd2Green ENTRY lda OldTable+4 ldx Slider5+10 jsr AddGreen bra FixOdd2 Odd2Blue ENTRY lda OldTable+4 ldx Slider6+10 jsr AddBlue FixOdd2 sta OldTable+4 sta OldTable+20 bra FixItUp Even1Red ENTRY lda OldTable+10 ldx Slider7+10 jsr AddRed bra FixEven1 Even1Green ENTRY lda OldTable+10 ldx Slider8+10 jsr AddGreen bra FixEven1 Even1Blue ENTRY lda OldTable+10 ldx Slider9+10 jsr AddBlue FixEven1 sta OldTable+10 sta OldTable+26 bra FixItUp Even2Red ENTRY lda OldTable+12 ldx SliderA+10 jsr AddRed bra FixEven2 Even2Green ENTRY lda OldTable+12 ldx SliderB+10 jsr AddGreen bra FixEven2 Even2Blue ENTRY lda OldTable+12 ldx SliderC+10 jsr AddBlue FixEven2 sta OldTable+12 sta OldTable+28 FixItUp pei (MyColorTable) ; table we're using PushPtr OldTable ; where we'll hide it _SetColorTable ; set it rts AddRed and #$00FF ; A = table, X = slider sta Temp txa lsr A xba and #$0F00 eor #$0F00 ora Temp rts AddGreen and #$0F0F sta Temp txa asl A asl A asl A and #$00F0 eor #$00F0 ora Temp rts AddBlue and #$0FF0 sta Temp txa lsr A and #$000F eor #$000F ora Temp rts END ************************************************************** * * UpdateColors * ************************************************************* UpdateColors START using LibGlobals using PanelData pei (MyColorTable) ; table we're using PushPtr NewTable ; where we'll hide it _GetColorTable ; get it * In our model, the extreme ends of the color table (white and black) * do not change. If we can't assume this model what we're doing here * is dead anyway, so we'll expect only the four modifiable colors to * be changing. ldy #2 ldx #0 jsr CheckSlider ldy #4 ldx #Slider4-Slider1 jsr CheckSlider ldy #10 ldx #Slider7-Slider1 jsr CheckSlider ldy #12 ldx #SliderA-Slider1 * jsr CheckSlider * Y points at the table entry. X is the offset to the slider resource CheckSlider lda NewTable,y ; get the new value and #$0FFF ; only valid data cmp OldTable,y bne ItChanged rts ItChanged sta OldTable,y sta OldTable+16,y eor #$0FFF ; reverse the values pha ; save it and #$0F00 ; isolate red xba asl A ; multiply by 2 cmp Slider1+10,x beq Not1 sta Slider1+12,x ; new value position phx ; save x lda #^Slider1 ; PushPtr Slider1,x pha clc txa adc #Slider1 pha pea UpdateMsg jsr MsgControl plx Not1 lda 1,s ; get xor'd value back and #$00F0 ; isolate green lsr A ; lower nibble * 2 lsr A lsr A cmp Slider2+10,x beq Not2 sta Slider2+12,x phx lda #^Slider2 ; PushPtr Slider2,x pha clc txa adc #Slider2 pha pea UpdateMsg jsr MsgControl plx Not2 pla ; get xor'd value back and #$000F ; isolate blue asl A cmp Slider3+10,x beq Done sta Slider3+12,x lda #^Slider3 ; PushPtr Slider3,x pha clc txa adc #Slider3 pha pea UpdateMsg jsr MsgControl Done rts END ************************************************************** * * UpdateLights * ************************************************************** UpdateTests START using LibGlobals using PanelData MaxTest equ 4 ldx TestIndex jsr (Tests,x) ldx TestIndex inx inx cpx #MaxTest bne DontDoIt ldx #0 DontDoIt stx TestIndex rts Tests dc i2'TestStandard' dc i2'TestDesktop' TestStandard lda StdPalette+2 cmp OldTable+2 bne NonStandard lda StdPalette+4 cmp OldTable+4 bne NonStandard lda StdPalette+10 cmp OldTable+10 bne NonStandard lda StdPalette+12 cmp OldTable+12 bne NonStandard lda Button1+2 cmp Button3+2 ; Quit is always on bne AlreadyOff PushPtr Button1 pea OffMsg jsr MsgControl AlreadyOff rts NonStandard lda Button1+2 cmp Button3+2 beq AlreadyOn PushPtr Button1 pea OnMsg jsr MsgControl AlreadyOn rts TestDeskTop ldx #14 DeskLoop lda GridPattern,x cmp UserBackground,x bne Different dex dex bpl DeskLoop lda Button2+2 cmp Button3+2 ; Quit is always on bne DesktopOff PushPtr Button2 pea OffMsg jsr MsgControl DesktopOff rts Different lda Button2+2 cmp Button3+2 beq DesktopOn PushPtr Button2 pea OnMsg ; fix this maybe later jsr MsgControl DesktopOn rts SetStandards ENTRY pei (MyColorTable) PushPtr StdPalette _SetColorTable ; set it rts SetDesktop ENTRY ldx #14 CopyLoop lda GridPattern,x sta UserBackground,x sta OldPattern,x dex dex bpl CopyLoop inc ChangeDesktop rts END ************************************************************** * * PanelData * ************************************************************** PanelData DATA using LibGlobals using CtrlData Height equ 140 Width equ 130 StartByte equ 15 StartLine equ 40 TextItems equ 5 PanelFlags equ UnderBarFlag+TitleFlag ChangeDesktop dc i2'0' FirstClick dc i2'0' Restoring dc i2'0' DRect dc i2'132,210,173,308' ; V = 9*4 + 3 + 2 / H= 22*4 + 6 + 4 PRect dc i2'132,332,157,432' PatRect dc i2'133,334,156,430' ; just inside PRect GridRect1 dc i2'58,244,62,402' GridRect2 dc i2'62,244,111,254' GridRect3 dc i2'62,392,111,402' GridRect4 dc i2'111,244,115,402' GridRect5 dc i2'57,242,116,404' CurrentButton dc i2'1' EntryOffset dc i2'0,2,4,10,12' GridColor dc i2'$0F' GridColorHigh dc i2'$F0' GridPattern dc 34i1'$DD' ; pastel blue, like the desktop OldPattern dc 34i1'$DD' ; use 34 so we can write by overlapping TestIndex dc i2'0' PanelRsrc dc i2'17' ; number of resources PushButtonTab dc i2'Slider1-PanelRsrc' dc i2'Slider2-PanelRsrc' dc i2'Slider3-PanelRsrc' dc i2'Slider4-PanelRsrc' dc i2'Slider5-PanelRsrc' dc i2'Slider6-PanelRsrc' dc i2'Slider7-PanelRsrc' dc i2'Slider8-PanelRsrc' dc i2'Slider9-PanelRsrc' dc i2'SliderA-PanelRsrc' dc i2'SliderB-PanelRsrc' dc i2'SliderC-PanelRsrc' dc i2'Button1-PanelRsrc' dc i2'Button2-PanelRsrc' dc i2'Button3-PanelRsrc' dc i2'PattrnGrid-PanelRsrc' dc i2'ColorGrid-PanelRsrc' Slider1 dc i2'SlideBar' ; part type dc i2'DrawMsg' ; initial message dc i2'56,76' ; where to draw it dc i2'42' ; height dc i2'16' ; initial slider value dc i2'16' ; new slider value dc i2'Odd1Red' ; handler (passed delta:integer) Slider2 dc i2'SlideBar' dc i2'DrawMsg' dc i2'56,116' dc i2'42' dc i2'16' dc i2'16' dc i2'Odd1Green' Slider3 dc i2'SlideBar' dc i2'DrawMsg' dc i2'56,156' dc i2'42' dc i2'16' dc i2'16' dc i2'Odd1Blue' Slider4 dc i2'SlideBar' dc i2'DrawMsg' dc i2'56,452' dc i2'42' dc i2'16' dc i2'16' dc i2'Odd2Red' Slider5 dc i2'SlideBar' dc i2'DrawMsg' dc i2'56,492' dc i2'42' dc i2'16' dc i2'16' dc i2'Odd2Green' Slider6 dc i2'SlideBar' dc i2'DrawMsg' dc i2'56,532' dc i2'42' dc i2'16' dc i2'16' dc i2'Odd2Blue' Slider7 dc i2'SlideBar' dc i2'DrawMsg' dc i2'109,76' dc i2'44' dc i2'16' dc i2'16' dc i2'Even1Red' Slider8 dc i2'SlideBar' dc i2'DrawMsg' dc i2'109,116' dc i2'44' dc i2'16' dc i2'16' dc i2'Even1Green' Slider9 dc i2'SlideBar' dc i2'DrawMsg' dc i2'109,156' dc i2'44' dc i2'16' dc i2'16' dc i2'Even1Blue' SliderA dc i2'SlideBar' dc i2'DrawMsg' dc i2'109,452' dc i2'44' dc i2'16' dc i2'16' dc i2'Even2Red' SliderB dc i2'SlideBar' dc i2'DrawMsg' dc i2'109,492' dc i2'44' dc i2'16' dc i2'16' dc i2'Even2Green' SliderC dc i2'SlideBar' dc i2'DrawMsg' dc i2'109,532' dc i2'44' dc i2'16' dc i2'16' dc i2'Even2Blue' Button1 dc i2'Button' ; an action button dc i2'OffMsg' ; initial message dc i2'161,84' ; coordinates dc i2'26' ; width dc i4'Button1Text' ; pointer to text dc i2'0' ; text mode dc i2'SetStandards' ; release handler Button1Text dc i1'Button2-Button1Text-1' dc c'Standards' Button2 dc i2'Button' dc i2'OffMsg' dc i2'161,332' dc i2'26' dc i4'Button2Text' dc i2'0' dc i2'SetDesktop' Button2Text dc i1'Button3-Button2Text-1' dc c'Set DeskTop' Button3 dc i2'Button' dc i2'OnMsg' dc i2'161,460' dc i2'26' dc i4'Button3Text' dc i2'0' dc i2'ClearPanel' Button3Text dc i1'PattrnGrid-Button3Text-1' dc c'Quit' PattrnGrid dc i2'Grid' dc i2'1' ; single hit=0, multi hit=1 dc i2'133,212,173,308' ; CtrlY1,CtrlX1,CtrlY2,CtrlX2 dc i2'10,24' ; CtrlV,CtrlH (dV,dH) dc i2'GridIron' ; manager ColorGrid dc i2'PatternGrid' ; draw a line grid dc i2'0' ; only draw dc i2'62,254' ; top, left dc i2'0,0' ; space for bottom, right dc i2'11,32' ; dy, dx (not counting lines) dc i2'4,4' ; x units, y units dc i4'StdPatterns' ; pointer to standard patterns dc i2'ChangeColor' ; selects a standard color EndPanel anop StaticRsrc dc i2'1' dc i2'PanelTitle-StaticRsrc' ds 2 PanelTitle dc i2'String' dc i2'DrawMsg' dc i2'50,280' dc i4'PanelTitleStr' dc i2'$8003' PanelTitleStr dc i1'EndStatic-PanelTitleStr-1' dc c'Color Panel' EndStatic anop END ************************************************************** * * ColorPanel * ************************************************************** ColorPanel START using LibGlobals using PanelData * Initialize parameters for the Color Panel. ldx #14 CopyGridLoop lda UserBackground,x sta GridPattern,x sta OldPattern,x dex dex bpl CopyGridLoop PushLong ScreenRgn _SetClip jsr HiLiteApple lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(StartLine*160+StartByte) ; offset ($2000) to first pixel sta MenuStart ; in bytes jsr SaveScreen ; save out what's underneath lda #PanelFlags sta FastFlags jsr DrawFastWindow ; let's draw a fast window pea 0 _SetForeColor pea 3 _SetBackColor pea 0 jsr SetPenColor pea 2 pea 1 _PenSize jsr ShowFatbits ; fatbits of desktop pattern PushPtr UserBackground _PenPat PushPtr PRect _PaintRect pea $0000 jsr SetPenColor PushPtr PRect ; Pattern rect _FrameRect stz ChangeDesktop * Draw the color table values. Force this using update by setting the * values in OldTable to illegal ones. lda #$F000 ; an illegal color (we hope) sta OldTable+2 sta OldTable+4 sta OldTable+10 sta OldTable+12 jsr UpdateColors stz TestIndex jsr UpdateTests * reinitialize sliders so they will be drawn - fix this design flaw soon lda #DrawMsg ldx #2 ; offset to state info sta Slider1,x sta Slider2,x sta Slider3,x sta Slider4,x sta Slider5,x sta Slider6,x sta Slider7,x sta Slider8,x sta Slider9,x sta SliderA,x sta SliderB,x sta SliderC,x * draw the panel resource (which has controls) PushPtr PanelRsrc pea DrawMsg jsr MsgResource * draw the static (non-control) resources PushPtr StaticRsrc pea DrawMsg jsr MsgResource jsr ShowGridColor pea NullEvent ; block out window stuff pea HandlePanel ; point it at us jsr SetHandler pea MouseDownEvent ; block out mouse presses pea PanelDown jsr SetHandler pea MouseUpEvent ; point mouse releases at us pea NoEvent jsr SetHandler pea KeyDownEvent ; block out all non-control chars pea KeyPanel jsr SetHandler rts CheckPencil lda MousePos ; get Y cmp DRect ; Mouse.Y-DRect.Y1 bmi UseArrow cmp DRect+4 ; Mouse.Y-DRect.Y2 bpl UseArrow lda MousePos+2 ; get X cmp DRect+2 bmi UseArrow cmp DRect+6 bpl UseArrow pea Pencil jsr SetCursor rts UseArrow pea Arrow jsr SetCursor rts HandlePanel jsr CheckPencil jsr UpdateColors jsr UpdateTests rts KeyPanel lda EvtMsg and #$00FF cmp #$002E ; is it a period bne NotAPeriod ; no, continue jsr RotateButton rts NotAPeriod jsr HexDigit ; A=char,input; A=value,output bcs NotAHexDigit jsr RotateTable NotAHexDigit rts RotateTable pha ; save value pei (MyColorTable) ; table we're using PushPtr NewTable ; update our current color table _GetColorTable ; get it pla ; get the value back sta Temp ; save it lda CurrentButton asl A tax lda EntryOffset,x tax lda NewTable,x asl A asl A asl A asl A and #$0FF0 ora Temp ; or in the value sta NewTable,x ; put it back in the old table sta NewTable+16,x ; update the 2nd half of the table pei (MyColorTable) PushPtr NewTable _SetColorTable ; set it rts ClearPanel ENTRY jsr RestoreScreen ; put the window back lda ChangeDesktop beq NoNeed PushPtr UserBackground _PenPat bra NoNeed ; background setter PushLong BackgrndRgn _PaintRgn NoNeed jsr RestoreEvents ; restore events jsr HiliteApple ; turn off the about box rts ; get out of here PanelDown jsr CheckPencil ; to ensure we have the right cursor stz CtrlFound lda #1 sta FirstClick stz Restoring PushPtr PanelRsrc pea TrackMsg jsr MsgResource lda CtrlFound beq FixItUp rts FixItUp pea MouseUpEvent pea PanelUp jsr SetHandler pea MouseDownEvent pea NoEvent jsr SetHandler rts PanelUp pea MouseDownEvent pea PanelDown jsr SetHandler pea MouseUpEvent pea NoEvent jsr SetHandler Not8Up rts END ************************************************************** * * ShowFatbits * ************************************************************* ShowFatbits START using LibGlobals using PanelData pea $0000 ; black jsr SetPenColor PushPtr DRect _PaintRect lda #(133*160+53+$2000) ; first byte of fatbits rect sta Screen lda #$00E1 sta Screen+2 ldy #0 stz PatternCtr bra Inside1 NextLine tya clc adc #(320-24) tay clc ldx PartialCtr stx PatternCtr Inside1 lda #9 ; initialize vertical count sta VCtr bra Inside2 NextV tya clc adc #(160-24) tay Inside2 lda #2 ; two pairs per scan line sta PairCtr ; initialize our counter ldx PatternCtr stx PartialCtr NextPair ldx PartialCtr lda GridPattern,x ; load the value inx ; bump x to next byte stx PartialCtr ; save it pha ; save value and #$00F0 ; get left nibble lsr A ; make it a word offset lsr A lsr A tax lda WideColorTab,x ; get a word of the color sta [Screen],y ; draw it iny iny sta [Screen],y ; draw it iny iny and #$F0FF ; blacken the rightmost pixels sta [Screen],y ; draw it again iny iny pla ; get background source back and #$000F ; get the right nibble asl A ; make it a word offset tax lda WideColorTab,x ; get a word of color sta [Screen],y ; draw it iny iny sta [Screen],y ; draw it a second time iny iny and #$F0FF ; blacken the rightmost pixels sta [Screen],y ; draw it the third time iny ; bump y to the next square iny dec PairCtr bne NextPair dec VCtr bne NextV lda PartialCtr ; get current byte offset cmp #8 ; have we done 8 bytes? bne NextLine ; no, keep going rts PatternCtr ds 2 PartialCtr ds 2 VCtr ds 2 PairCtr ds 2 GridIron ENTRY plx ; pull return pla ; Y value asl A ; * 2 sta Temp pla ; X value phx ; push return back sta Temp+2 ; we'll need it again lsr A ; byte offset clc adc Temp ; y*2 + x/2 = byte within table tax lda GridPattern,x ; get old value tay ; save it lda Temp+2 and #$0001 ; mod 1 beq HighNibble tya and #$000F cmp GridColor ; do the colors match? bne LowsDontMatch ; no, maybe we want to color them lda Restoring ; are we already restoring? bne RestoreLow ; yes, go restore it lda FirstClick ; is this the first time through? bne FirstLow ; yes, so set toggle rts ; no, so we can leave FirstLow stz FirstClick ; next time isn't the first inc Restoring ; but we will be restoring RestoreLow lda OldPattern,x ; get the old value and #$000F sta Temp lda GridPattern,x and #$FFF0 ora Temp bra FixLow LowsDontMatch lda Restoring ; are we restoring? beq UpdateLow ; no, so color it rts UpdateLow stz FirstClick ; next time isn't the first tya and #$FFF0 ora GridColor FixLow sta GridPattern,x sta GridPattern+8,x and #$000F ; just the low nibble brl ColorIt HighNibble tya and #$00F0 cmp GridColorHigh ; do the colors match? bne HighsDontMatch ; no, maybe we want to color them lda Restoring ; are we already restoring? bne RestoreHigh ; yes, go restore it lda FirstClick ; is this the first time through? bne FirstHigh ; yes, so set toggle rts ; no, so we can leave FirstHigh stz FirstClick ; next time isn't the first inc Restoring ; but we will be restoring RestoreHigh lda OldPattern,x ; get the old value and #$00F0 sta Temp lda GridPattern,x and #$FF0F ora Temp bra FixHigh HighsDontMatch lda Restoring ; are we restoring beq UpdateHigh rts UpdateHigh stz FirstClick tya and #$FF0F ora GridColorHigh FixHigh sta GridPattern,x sta GridPattern+8,x lsr A ; put it in the low nibble lsr A lsr A lsr A and #$000F ColorIt pha ; a should contain color of square jsr SetPenColor pea 0 ; push pointer to little rect tdc clc adc #CtrlY1 pha dec CtrlY2 ; don't paint too much dec CtrlX2 dec CtrlX2 _PaintRect PushPtr GridPattern _PenPat PushPtr PatRect _PaintRect rts ChangeColor ENTRY plx pla ; y eor #$0003 ; invert it asl A ; * 4 asl A sta Temp pla ; x clc adc Temp ; color number sta GridColor asl A asl A asl A asl A sta GridColorHigh ldx #14 CopyLoop lda GridPattern,x sta OldPattern,x dex dex bpl CopyLoop ShowGridColor ENTRY lda GridColor pha jsr SetPenColor PushPtr GridRect1 _PaintRect PushPtr GridRect2 _PaintRect PushPtr GridRect3 _PaintRect PushPtr GridRect4 _PaintRect pea 0 jsr SetPenColor PushPtr GridRect5 _FrameRect rts END ************************************************************** * * RotateButton * ************************************************************* RotateButton START using PanelData lda CurrentButton ; inc (1..4) and #$0003 ina sta CurrentButton rts END *===== * * FileStuff(FileNamePtr,DataPtr,Length) * * This routine retrieves parameters, namely DataPtr (4 byte), * Length (4 byte), and PathName (4 byte). * FileStuff START ply ; pull local return plx ; get main return pla ; get length, low sta ReadSize ; save it sta WriteSize pla ; get length, high sta ReadSize+2 sta WriteSize+2 pla ; pull data pointer sta ReadDest sta WriteSrc pla sta ReadDest+2 sta WriteSrc+2 pla ; pull file name pointer sta OpenName sta DestroyName sta CreateName pla sta OpenName+2 sta DestroyName+2 sta CreateName+2 phx ; put the returns back phy rts *===== * * LoadFile(FileName,DataPtr,Length) * * This routine loads Length bytes from FileName to the location * specified by the 4 byte pointer in DataPtr. * LoadFile ENTRY jsr FileStuff _Open OpenParams bcc Okay1 bra Error Okay1 lda OpenID sta ReadID sta CloseID _Read ReadParams bcc Okay2 bra Error Okay2 _Close CloseParams rts ; leave carry as is Error sec rts *===== * * SaveFile(FileName,DataPtr,Length) * * This routine saves the data at DataPtr (4 byte) of length * Length (4 byte) to the file described by FileName (4 byte * pointer to a string with a preceding length byte). * * The file is first deleted, then created as a binary file. SaveFile ENTRY ; save file entry point jsr FileStuff ; set up parameters _Destroy DestroyParams _Create Createparams bcs Error _Open OpenParams lda OpenID sta WriteID sta CloseID _Write WriteParams bcs Error _Close CloseParams rts OpenParams anop OpenID ds 2 OpenName ds 4 ds 4 ReadParams anop ReadID ds 2 ReadDest ds 4 ; where to put the data ReadSize ds 4 ; this many bytes ds 4 ; how many xfered WriteParams anop WriteId ds 2 WriteSrc ds 4 ; where to get the data WriteSize ds 4 ; this many bytes ds 4 ; how many xfered? CloseParams anop CloseID ds 2 DestroyParams anop DestroyName ds 4 ; name to destroy CreateParams anop CreateName ds 4 ; pathname dc i2'$00C3' ; (destroy, rename, write, read) dc i2'$0006' ; file type dc i4'$00000000' ; aux_type dc i2'$0001' ; storage type (seedling) dc i2'$0000' ; create date dc i2'$0000' ; create time END keep demo link/all demo link lib.a E Z ,@ LN #File Edit Demos Options( Cortland Region Ops Demo 200 x 640 % - D%x' 3[ 6"^"""" Od""""  1 s2  1` 1` O`'-'/'1'3'H'HKHIHi"` ," s2hZ'&H s2h\' s2h^'&H s2h`' \'HZ'H:"`'H^'H<"hjklmnopqrstuvwxyz{|}~` NW 7 ` Region Ops Demo ` 3 3c s2h@ s2hd s2h@ s2h)'m"HHX"HHn"HHHHl"OHMHHHHH)|q"s"r"t"HHx"hHHh"HHh"HHKHIHOHMHq"HHh"` KHIH$" s2H 1 s2h8c)H 1KHIH{"OHMHz"`W WWWOHMH$" C` N 7 ` Rectangles Demo `KHIH$"-H1:H s2hH1H s2h/H3:H s2hH3H s2h HHT"` N d 7 -/b) @b5"5" "H""` 3b)Z@"b)"b[fHdH jY b) @b 3(kSLIDE.A. Apple IIgs Imaging Q; "H""`8--/0`"-/`1-3/5"5" }W Y"HH"h) H""di~fHڢ""df'\^<:,.YHYWȌW) H"<%.\\%,\:\i\i ) Q;"` N  7 ` Polygons Demo `KHIH$" s2h"hh/H3::H s2-H1::H s2:"/H3::H s2-H1::H s2<"Т" HH"HH"` N 7 KHIH$" 1-T" % 1m-J 81-J:) JJ' `ABdGGdABJ""J`lffzF* : w7` : <>'I'@ m74"`@ m73"`About LW/Demo... Show Clock Hide Clock320 Mode640 Mode Color PanelL::::<݅@"`'pN(LR l4n 7 48 1'''( ((("(*(2(LT 697T 69lET 69""D:"Q"ᩍ> : w7D :"X"m> : w7D+:"`"> : w7D6:"f"-> : w7DA:"k" #> : w7DL:"v")> : w7DW:""0> : w7Db:""M8> : w7Dm:""Dx:""N&H"` :< >@ r7`New...Open...CloseSave Save as...Save a copy as...Revert Page Setup... Dump ScreenQuit'DN$LRl<n 7 48 1xT 69'''( ((""t:""ᩙ> : w7t :""> : w7t+:""Y> : w7t6:"#"9> : w7tA:")"#> : w7tL:"/")> : w7N&H"` :<>@ r7`UndoCutCopyPasteClear Select All'ON LR%lEn 7 48 1'''( ((("":"" :""+:""6:""A:""L:""W:"" i H:""N&H"` :<%>@ r7`Clipping RectanglesConicsColors Slide ShowPolygonsMacrame'.N(LR4l\n 7 48 1'''("":"" :""+:" " U> : w76:"!1"N&H"` :<4>@ r7` 136 Colors 16 ColorsPauseContinueWindows Full ScreenTurn Animation OnTurn Animation Off 3MO 3EG 3IK%)'l+%i5i9'i 7i;5=7?9:A;::COHMH%"GHEH%l"`MO 3OHMHh"IK 3KHIHh"EG 3GHEHh"`hhڧ)`," 1 1""%U"%S"5S"+:::H%i HHH':"<"%Q'iSiUW %Q'iS+8UW %i -):1'/+::3KHIH-l""hIm'm+JH%i H:""`WYSHQH:"UHQHQ<"W`` T3df'''hj`` 3bH`H"`'6 8' & 9  t 'drdp`hzH 03'("8 NJJl0n:8 p `dp `rdp 00'   ` dr``'  9 I`ɔ'   `'  t :`'   `rpO 8drpF: ih)5d0) t0 tp:H 3he0eRv 8pr`hzHZ $r'r 8 8 8 8 8 ` N 7 ` Conics Demo `KHIH$"-H1:H s2hH1H s2h/H3:H s2hH3H s2h g s2iHi^H s2c"`8H s28H s2hzZH` s2h H ڎ ,"` !&H&H$" zNxLTR 7dB :"" HHHH:"" 0L N`=ZKIZUZ^Z gZ`pZyZZZWZZZ LLW/Demo Copyright (C) 1987 by Apple ComputerM by Art Cabral Version 1.0A1 - January 31, 19879LW/Demo features the Apple IIgs Super-Hires 640 mode. It?generates 16 bright colors using simple dithering and a specialsince any pixel can be black or white, the resolution in black9and white remains at 640, allowing crisp, 80-column text. 8 " `MM/DD/YY 12:00:00 am V  y!h\ hZ V "h^ h`  "#"`KX  2kV `X `b "j )j l )l n )n p )p r )r t ) t X &H&H$"""Z H\ H:"j ) j j "`#"` H^ H"V X @><: m7`z"ڢJ z'!Nz' 3 """H "H%"`NNNNNNNNNNNNNNNN"J !z'N! "H "H$" "" 3HHh"`v'# NP# Nd 6k! # f( y!kv'9&H&H$""'4"'H'H{""ᦤ"Ny{ J#kN NkNmP zh') "I N N`H N`1 I``N Np'07 "&H&H$"% N# N` `# NN N` % $&`r'Hp'H $` k`f( y!f(`  z f(`\)IHH"h)j("` P$&$"` w #U``l( $".$0$2$$4$n( $"6$8$:$$<$t( $$@$"($0$ %%0$"8$ %%8$v( $$B$"*$2$ %%2$":$ %%:$`)iJ)")iJ)"")J)"")IJ)I$)IJ)I$$)IJ)I$$`)&)e&:)()&)e&:)(()&)e&:)(` 9 9` v'`` Ť""` I` #`Ԥd""Ih""` # `` % $&r'Hp'H Ch) )%`N#g%%%% $&# N H N`N N`P# NN NOHMH$"`"3DUfw""33DDUUffww&dx?x|?|~?~?~?|~?x|?x?? NNNNNNNNNNNNNNNNND (l))X**  ????  J  DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUffffffffffffffffffffffffffffffffwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww""""""""""""""""""""""""""""""""33333333333333333333333333333333-(-H-h-,,,,,(,H,h,++++005(K"LH *"h&.h(.. "_TLStartup failed. Error was $ "LH *"h~.h.`. "_MMStartup failed. Error was $ h0"LH *"h.h.. "_MTStartup failed. Error was $ 0H "bH *"h[/h]/'/ "_NewHandle failed fetching 6 zero pages. Error was $ ;[[ h hh0 iHH" iH "᫢)04) 40 ; ;j("ᩀHH"" 1< RO?"X0NLRB :d<:"0" d20 iHH"0"LH *"h0h00 "_LoadTools failed. Error was $ v''rf(ݍh( 3&& 3''ʅ 3 6 `#Memory manager inconsistency found.&H&Hh"'H'Hh" " " " < < "᫢)"04)"40"" HH"""+")1@h 2:'0"`h 52:'0"`h 2:'4"`h 52:'4"`)p&)"""$)""" )$$$":'$:' `0)0`zh,.Z8,,`0 I2JJJJ48268482%824%622) 48268482%826%42 0 0 "hhe,`"$") """`"$")"`HH 3$"" 3"$h""`z`HH "z"z$ "zz`g"h`h*h(h&(J(&e*&* *&`"h(h((`h00ͪ(`( (H(H"`4"424:4B4    ,?ȃ?fff?DDD?UUUU??4"424:44 &fffDDDUUUU%File Edit Goodies Options$J&H 1L&H 1H&HF&H,"J&H"L&H"N&H"` 6'U"3"'H'H:"'H'H<"< :"5"`hhڧ)5` 1<&H&H$" Q6'H'H$"`&&H&Hi"'H'H'l"'b''d' 3''&H&Hd'Hb'H'H'Hq"d'Hb'Hh" 6&H&H$"4 6` " e>\^\i\<7:"`7777@\`\E@\`\@\`\%@\` eR\^NZdVfX`" 7\i\VeLVXL\VZݢ"`" 7ZZ\\i\Z%L\\)? \\ʩL\\\i\L\"`"tZ ev\^\I\\i\ZL\I\\I\Ӣ"`" 7\i\VeLVXLV\Zۢ"`" eT\^L\\"`" eR\^L\)?\\"`L::::<:Ri>d@ m7\\:>i@> m7\\:>i@> m7\\:>i@> m7\\`Ri!\\\à@\\à\\ \\\\B\\\"\<\\!) >!@!) @!!) !") ""ᯀ) ) ^) ^`) "`a'"'0`j(r(z((p(x(((iھ;j(z(0` 'a0`ھ;j(i0`'" * .@!2!6,048"*$.&2(6i$*i*.i.2i26i6 :`ffffff`fff`fff`fff`fffff`ffffffffffffffffff`"""""""" """""""""" """"ffffffff`ffffffffff`ffff..ffffffffffffffffffffffffffff333333333333333333333330333333333333333333333333033333333333333333333333303333333333333333333333330333333333333333333333333033333333333333333333333303333333333333333333333330333333333333333333333333033333333333333333333333303333333333333333333333307wwwwwwwwwwwwwwwwwwwwwwtwwwwwwwwwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwwwwwwwpwwwwwwwwwwwwwwwwwwwwwwwwp7wwwwwwwwwwwwwwwwwwwwwwtDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD@DDDDDDDDDDDDDDDDDDDDDDDD@DDDDDDDDDDDDDDDDDDDDDDDD@DDDDDDDDDDDDDDDDDDDDDDDD@DDDDDDDDDDDDDDDDDDDDDDDD@DDDDDDDDDDDDDDDDDDDDDDDD@DDDDDDDDDDDDDDDDDDDDDDDD@DDDDDDDDDDDDDDDDDDDDDDDD@DDDDDDDDDDDDDDDDDDDDDDDBICFGFHHI6J>JFJFJLSMM!NNNe搥e:`<| 3h"~JJe"i 9B`p'ŀ0ń r'ł0ņ8``xKKh) 9B3 xwxi|x~=KKh):< dB x xwxi|_=xKKh): dB`x|wx~xi B` xei BJi8|| B|~ B`E%E qE`,EFE qE`MEjE qEp'8倅` B` E xwxi` E E` B` E xe` ,E E`8p'8` E xwx` ME E` Nh B NhBzhZH N N8` BH NBH N`" xe" x`Ii x0x8 8 x`"" wx x" D"x BB`x_>xxO_>xx8?xx!@xx `xKKh)< :x~x| dB xH xHH"hJ"~i48"H|i H:"xH""N&H"`x_>`xi xih B` Nh B NhBG NG N@xx" F"8` Bx @ aG`ɗ??xx" F"` G BH NBH Nx@ Gx BB``xHxH:" x"N&H" xHxH""N& N&H"`` xxx< x:x~x| dB`` FI B`xTx~d":"e~r'0"8~ x|d":"e|p'0"8|xBB8` Nh B NhB#I N0I N H8` FI B H` BH NBH Nݠxxx x`"hhhڧ ԌĢ#Ȅ exezBh"`"hhxhzڧx B"`` J8倅NJiJ8傅L0ieR 7dB :`xxx x````` `xx~x(~e( xxx| x&|e&x," 1|"$e&$ԂH:"Ԇ$<""~"$e($HԀ:"$Ԅ<""x2x42` x(x&.|".*e(.0~$0,e&0x  K4H2Hi 240"{i*HT"$о"Ш`L2 LȌLL)JJJJ LKȭ L) LKȌLL0LKLڥ2i24` 03>o>oos9t $4DTdt5G8L*P8t*P8*P8*P8*P8*PmL,Qmt,Qm,&Qm,7Qm,BQm,MQTTR StandardsLTR Set DeskTopTVQuit4 W > +X2U Color Panel'\S~S&H&H$" NLR 7B :"" 1," 5W'0"ST" 1SS"Sl(n(t(v( QS DRSSSSTT&T6TFTVTfTvTS cIU cI XcV NV NN NmV N`p' S0Sr'S0 S 3` 3` ;V Q DR`h'). *Y` 7P V`H("h"LS NS( )"((("` 8S'0"'H'Hz" FO ` ;VdS SS cI`"W NN N`V NN N` 1 ST"Us\^W i(WW WiWWWW\SWH)JJJ&\ȗ\)\h) &\ȗ\)\WпWШWЋ`h "hڅ$Je"\S$)H)XS# S S`S S~S)"\S)" S`S) XS\SdS)I)ZS# S S`S S~S)"\S)" S`S) ZS\SdSJJJJ)H 1{iHƄƆƆT"\S0"ST"`hI "he"XS ZS\S~SXSH 1$ST",ST"4ST" 'C F I L O Z !] '` 'c 'f 'i 'l o r | ; j( j(     !    '  ' 3  '  !    ' ' '              " & ) 4 > A D N Q T ^ a d n q v y     3 9B% G ( G 7 Y= 3T W N_ ib ie 7h Ok 3n eq gw cz K~ I / - 3 1 / 1 3 1 g e 1 g e _WWW[a Y'Y-Y3]6c:1=c@WCWMaR_zg~eKI'748169'''(( &f(+.36VY^ax%{%N&w7''m744m733M'i7l48o1x'{'~'( ((("(*(2(696969QQw7XX w7` `4w7DfGf[w7kknkw7vvw7w7w7 !$.N&Nr7'748169'''( ((,w7<?Sw7cfzw7##w7))w7//w7N&r7>'Z7]48`1f'i'l'o(r (u(x(!8;EiN&r7'7481'''(#(+03JORWZqvy~  w7!11N&r7E3HMKON3QETGW3ZI]Kc%i)o'u+x%59'7;5=7?9A;COMGE%%MO3OMIK3 K IEG%3(G,EH`1f1}%%%%55+%'%Q'SUW%Q'S+U W %-)1!'&/)+.31K5I9-<-IL\'_+d%svWYSQUQQWT3''''3'8'9t'/'X^i}''9I''t:'813<8J$S'[8^8a8d8g8jqtN|7 KI-1s21s2/3s23s2s2s2+.2s2<?Cs2Vs2o!r&v&7:L NK `'/W7?G M 8P "S { V  y! \  Z  V   ^  `    X  V  X  b  b  j  j  l !l !n  !n  !p !p !r !r !t (!t +!X .!&2!&Q!Z U!\ `!j i!j l!j o!j !` !^ !V !X !m7!"!z'!!!N!z'!3! "!"!"! "!N!N!N!N!N!N!N!N!N!N"N"N"N"N "N "N"""!""z'%"N("!2""6" "A" "F""N"3_"b"v'e"k"#n"Nt"P#w"N|""6"!"# "f("y!"v'"&"&"'"'"'"'"""N""""y"{"" ""#"N#N#N## #m #P  #z###h'#%#-#N0#N9#=#NF#L#T#NW#NZ#p'd#&h#&v#%y#N###N#####N#N#N#%#$&#r'#p'#$#k#f(#y!#f(#z #f($j( $j($P$$&$$&$L$#UQ$l(T$$Y$.$\$0$_$2$d$4$g$n(j$$o$6$r$8$u$:$z$<$}$t($$$@$$($$0$$%%$0$$8$$%%$8$$v($$$B$$*$$2$$%%$2$$:$$%%$:$m%9p% s%9|%v'%"%%%#%"%%%"%# %%%$&%r'%p'%C%%%N%#%g%%%%%%%%$&&#&N &&&N&N!&N(&P#+&N1&N4&N7&O;&M&&x'Nz'N|'N~'N'N'N'N'N'N'N'N'N'N'N'N'N'N(((l)()(X*(*---(--H--h--,-,-,-,-,-(,-H,-h,-+-+-+-+-&.-(.-.-.I.~.N..R.`.U.`..0.........0/[//]//'//'/t/0/;/;/j(/j(/1</RO0:$00'0010d2Z00]00x00}0000000v'0'0f(0h(030&0&030'0'030601& 1&+1'/1':1^1<a1<111 21:'1:'1521:'1:'1 21:'2:'2522:'2:'%2p&S2:'Z2:'333C333(3(3(3(3(3(3(344"44244:44B4444"44244:4446J&616L&61!6H&%6F&06J&;6L&F6N&R66U6'X6'b63e63o6's6'~6'6'65656561<6&6&6Q66'6'6&6&6&6&6'6'7'7'7'7b'7'7d'737'!7'$7&(7&,7d'07b'47'87'C7d'G7b'R76U7&Y7&d74g74j76777777777787<87979m79m79m79m7:48:f9:69:9:9;';"';j(;r(;z(;(;p(;x(;(;(;;;j(;z( <'<;"J)BFJ+BFJ-BL/BSM1BM3B!N5BN7BNmB3B9BBp'Br'B<B<B<B)=CdB2CB?CBECBTCCZC_=yCDC3C=C=C9BC>D9BD=5DdBMD_=dDdBDBDBDBDBDED%EDqED,EDFEDqEDMEDjEDqEDp'EBEE&EE)EE-EB6EEGE,EJEEOEp'ZEEkEMEnEExEN|E BENEBENENE BENEBENED FBFB#F_>?F_>VF?mF@FdBFN& G_>.GBIBBINIBIBIJJ7J:J1[KKKLK LKLKLK LKKK LK LKKKLKLKLKKKKKLLL LBELr'hLp'~LBLBLNL BLNLBLLLNLLLNL/LLLLBL/LL BLNLBLNNz'Nz'NNNz'Ov'O Of'Of'Of'&Oh'1O'7O'QlQCQv(FQpTIQ}QNQv(QQTTQQWQv(ZQ(_Qj(bQj(Q(Q(QQQQQQQ(Qj(Qj(Qz(QSQSQSQSRI RSRSRSRS#RI,RS1RS4RS:RSARIERSHR[RKRSXRS[R_R]RR`RR&cRl(hRT&kRn(pRZ&sRt(xR\&{Rv(RTRTRTRTRIRTRTRTRTRIR\SR'RTRTRTRTRIRTRTRTRTRIRP&RP&R\SR'R~SSSSPSPSPTPTP$TP4TQDTQTT&QdT7QtTBQTMQTTTRTTTRTTTVTWT+UXUU'U'*U\S-U~S4U&8U&CUUU7]U:wU1U5WU'U'USUSU1USUSUSUl(Un(Ut(Uv(UQUSUDRUSUSUSUSUTUTU&TU6TUFTUVTUfTUvTUSUSVcIVU VUVcIVXVcVVN#VV&VN,VN/VN5VmV8VNXZSCX SHXSNXSQX STX~S\X\SfX SlXSsXZSvX\SyXdSX1X\SX\SXSXSXXSXZSX\SX~SXXSX1X$SX$SX,SX,SX4SY4S Y=MenuLast, clear any menus * We've found something cmp #48 bpl TryFile * It was the Apple menu lda CurrentMenu cmp #AppleMenu beq IgnoreApple jsr ClearMenu jsr HiliteApple jsr DoApple IgnoreApple rts * It was the file menu, by default ClearIt jsr ClearMenu stz CurrentItem rts TryFile cmp #96 bpl TryEdit lda CurrentMenu cmp #FileMenu beq IgnoreFile jsr ClearMenu jsr HiliteFile jsr DoFile IgnoreFile rts TryEdit cmp #148 bpl TryGoodies lda CurrentMenu cmp #EditMenu beq IgnoreEdit jsr ClearMenu jsr HiliteEdit jsr DoEdit IgnoreEdit rts TryGoodies cmp #224 bpl TryOptions lda CurrentMenu cmp #GoodiesMenu beq IgnoreGoodies jsr ClearMenu jsr HiliteGoodies jsr DoGoodies IgnoreGoodies rts TryOptions lda CurrentMenu cmp #OptionsMenu beq IgnoreOptions jsr ClearMenu jsr HiliteOptions jsr DoOptions IgnoreOptions rts END **************************************************************** * * TrackItems * **************************************************************** TrackItems START using LibGlobals ExtraHeight equ Prndm_K lda CurrentItem ; nop beq DontClear cmp NewItem beq Done jsr InvertItem DontClear stz CurrentItem lda NewItem beq Done dea ; zero base it asl A ; multiply by 8 asl A asl A clc adc #4 ; offset to flags tay lda [MenuInfo],y ; get flags tax ; save it and #MenuActive beq Done stz ExtraHeight txa ; get flags back and #MenuOverlined ; is there a line above us? beq NoOverline lda #10 ; spaces for overlined item sta ItemHeight lda #160 sta ExtraHeight bra T1 NoOverline lda #11 sta ItemHeight T1 pea 0 ; function return lda NewItem ; push new item dea ; zero base the item pha ; push it pea 1760 ; bytes between item starts jsr Multiply ; multiply them pla ; get result clc ; clear carry for adds adc ExtraHeight ; add in overline if necessary adc MenuStart ; add in offset to first item sta ItemStart ; save it jsr InvertItem lda NewItem sta CurrentItem Done rts END **************************************************************** * * ReleaseMenu * **************************************************************** ReleaseMenu START * Function returning the release (1..ItemLast) using LibGlobals jsr TrackMenu ; update for the last time * Now let's see if we caught anything lda CurrentItem ; did we catch anything? sta 3,s ; just in case it's zero beq NoFlash ; ignore the fancy stuff lda CurrentMenu ; which menu is it xba ; swap the bytes ora CurrentItem ; or in the current item sta 3,s ; save it in the result jsr InvertItem ; flash it for now jsr InvertItem jsr InvertItem jsr InvertItem jsr InvertItem NoFlash jsr ClearMenu ; take the menu down rts ; and go home END * Table of Contents * * 1. Menus.Asm * * SetAppleMenu Set initial values based on the Apple menu * DoApple Show the Apple menu * DoFile Show the File menu * DoEdit Show the Edit menu * DoGoodies Show the Goodies menu * DoOptions Show the Options menu **************************************************************** * * AppleMenu * **************************************************************** DoApple  START using LibGlobals using ScreenGlobals Height equ 46 Width equ 38 ; number of bytes for menu StartByte equ 2 Border equ 28 ; Apple menu text start MyFirstSCB equ $E19D00 lda #AppleMenu sta CurrentMenu * Initialize menu parameters for the Apple menu. lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(12*160+StartByte) ; offset from $2000 to first pixel sta MenuStart ; in bytes lda #StartByte sta MenuByte lda #(StartByte+Width) sta MenuEnd jsr SaveScreen ; save out what's underneath jsr DrawBlankMenu ; draw a blank menu field jsr SetFadeInfo ; set up fast fade values * Draw all the black line dividers lda #(23*160+StartByte) ; offset for the underline sta MenuLineStart jsr DrawMenuLine ; draw a line under the About item * Set up menu flags lda #MenuActive ; get active flag ldy #(MenuActive+MenuOverlined) ; get active flag sta MenuData+4 ; About box (-) sty MenuData+12 ; Alarm clock stz MenuData+20 lda MyFirstScb and #$80 beq NoPanelToday lda #MenuActive sta MenuData+20 NoPanelToday lda #MenuActive sta MenuData+28 ; 320/640 Mode * Set up drawing colors PushWord #0 ; black text _SetForeColor PushWord #3 ; white background _SetBackColor * About Box - active pea Border ; H pea 21 ; V _MoveTo PushPtr Apple1 _DrawString * Clock - active pea Border pea 32 _MoveTo lda ClockToggle bne HideIt PushPtr Apple2a bra ClockIt HideIt PushPtr Apple2b ClockIt _DrawString * Control Panel - faded pea Border pea 43 _MoveTo PushPtr Apple3 _DrawString lda MyFirstScb and #$80 bne HaveControls lda #(160*34+StartByte+1) sta FastStart ; start there lda #10 ; let's cheat and always do 10 sta FastHeight ; save it jsr FastOr ; nothing left but to do it HaveControls pea Border pea 54 _MoveTo lda MyFirstScb and #$80 bne Do320 PushPtr Apple4b bra Joined Do320 PushPtr Apple4a Joined _DrawString PushWord StdTextMode _SetTextMode rts HiLiteApple ENTRY lda #11 ; scan lines in title bar sta FastHeight lda #12 ; width to hilite, in bytes sta FastWidth lda #StartByte ; offset from $2000 to first pixel sta FastStart ; in bytes lda AppleToggle eor #$FFFF sta AppleToggle beq NormalApple lda #0000 ; black sta FastColor jsr FastFill ; erase to black PushPtr BlackAppleInfo _PaintPixels rts NormalApple lda #$FFFF ; white sta FastColor jsr FastFill PushPtr AppleInfo _PaintPixels rts Apple1 dc i1'17' dc c'About LW/Paint...' Apple2a dc i1'10' dc c'Show Clock' Apple2b dc i1'10' dc c'Hide Clock' Apple3 dc i1'11' dc c'Color Panel' Apple4a dc i1'8' dc c'320 Mode' Apple4b dc i1'8' dc c'640 Mode' SetFadeInfo ENTRY ; call after savescreen lda MenuWidth ; get menu width dea dea dea ; take away left edge dea ; take away right edge sta FastWidth ; save it, too lda #$DDDD ; fade it to pastel blue sta FastColor ; the color used in the OR operation PushWord #$8003 ; black text, anded _SetTextMode rts END **************************************************************** * * DoFile * **************************************************************** DoFile START using LibGlobals Height equ 112 Width equ 40 StartByte equ 12 Border equ 68 lda #FileMenu sta CurrentMenu * Initialize menu parameters for the File menu. lda #Height sta MenuHeight lda #Width sta MenuWidth lda #(12*160+StartByte) sta MenuStart lda #StartByte sta MenuByte lda #(StartByte+Width) sta MenuEnd jsr SaveScreen ; save what's under the menu jsr DrawBlankMenu ; draw a blank menu jsr SetFadeInfo ; set up fast fade values * Set initial flags lda #MenuActive ; get active flag ldy #(MenuActive+MenuOverlined) ; active and overlined ldx #MenuOverlined ; just overlined, not active stz MenuData+4 ; New... stz MenuData+12 ; Open... (-) stx MenuData+20 ; Close sta MenuData+28 ; Save stz MenuData+36 ; Save as... stz MenuData+44 ; Save a copy as... sta MenuData+52 ; Revert (-) stz MenuData+60 ; Page setup stz MenuData+68 ; Print (-) sty MenuData+76 ; Quit is active * Draw all the black line dividers lda #(34*160+StartByte) ; offset for the underline sta MenuLineStart jsr DrawMenuLine ; draw a line under the About item lda #(89*160+StartByte) ; offset for the underline sta MenuLineStart jsr DrawMenuLine ; draw a line under the About item lda #(111*160+StartByte) ; offset for the underline sta MenuLineStart jsr DrawMenuLine ; draw a line under the About item * Draw all the text PushWord #0 ; black text _SetForeColor PushWord #3 ; white background _SetBackColor * New pea Border ; H pea 21 ; V _MoveTo PushPtr File1 _DrawString lda #(160*12+StartByte+1) sta FastStart ; start there lda #10 ; let's cheat and always do 10 sta FastHeight ; save it jsr FastOr ; nothing left but to do it * Open pea Border pea 32 _MoveTo PushPtr File2 _DrawString lda #(160*23+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Close pea Border pea 43 _MoveTo PushPtr File3 _DrawString lda #(160*35+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Save pea Border pea 54 _MoveTo PushPtr File4 _DrawString * lda #(160*45+StartByte+1) * sta FastStart * lda #10 ; let's cheat and always do 10 * sta FastHeight * jsr FastOr * Save as... pea Border pea 65 _MoveTo PushPtr File5 _DrawString lda #(160*56+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Save a copy as... pea Border pea 76 _MoveTo PushPtr File6 _DrawString lda #(160*67+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Revert pea Border pea 87 _MoveTo PushPtr File7 _DrawString * lda #(160*78+StartByte+1) * sta FastStart * lda #10 ; let's cheat and always do 10 * sta FastHeight * jsr FastOr * Page Setup pea Border pea 98 _MoveTo PushPtr File8 _DrawString lda #(160*90+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Print pea Border pea 109 _MoveTo PushPtr File9 _DrawString lda #(160*100+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Quit pea Border ; Quit pea 120 _MoveTo PushPtr File10 _DrawString PushWord StdTextMode _SetTextMode rts HiLiteFile ENTRY lda #11 ; scan lines in title bar sta FastHeight lda #14 ; width to hilite, in bytes sta FastWidth lda #StartByte ; offset from $2000 to first pixel sta FastStart ; in bytes lda #$FFFF ; invert all sta FastColor jsr FastXor rts File1 dc i1'6' dc c'New...' File2 dc i1'7' dc c'Open...' ; followed by a line File3 dc i1'5' dc c'Close' File4 dc i1'4' dc c'Save' File5 dc i1'10' dc c'Save as...' File6 dc i1'17' dc c'Save a copy as...' File7 dc i1'6' dc c'Revert' ; followed by a line File8 dc i1'13' dc c'Page Setup...' File9 dc i1'8' dc c'Print...' ; followed by a line File10 dc i1'4' dc c'Quit' END **************************************************************** * * DoEdit * **************************************************************** DoEdit START using LibGlobals Height equ 57 Width equ 26 ; number of bytes for menu StartByte equ 24 Border equ 116 ; Edit menu text start lda #EditMenu sta CurrentMenu * Initialize menu parameters for the Edit menu. lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(12*160+StartByte) ; offset from $2000 to first pixel sta MenuStart ; in bytes lda #StartByte sta MenuByte lda #(StartByte+Width) sta MenuEnd jsr SaveScreen ; save out what's underneath jsr DrawBlankMenu ; draw a blank menu field jsr SetFadeInfo ; set up fast fade values * Black line lda #(23*160+StartByte) ; offset for the underline sta MenuLineStart jsr DrawMenuLine ; draw a line under the About item * Set initial flags lda #MenuActive ; get active flag sta MenuData+4 ; 1st item inactive stz MenuData+12 ; 2nd item inactive stz MenuData+20 stz MenuData+28 stz MenuData+36 stz MenuData+44 * All items in this list are inactive. Draw them, then fade them out. PushWord #0 _SetForeColor PushWord #3 _SetBackColor * Undo pea Border ; H pea 21 ; V _MoveTo PushPtr Edit1 _DrawString * lda #(160*12+StartByte+1) * sta FastStart ; start there * lda #10 ; let's cheat and always do 10 * sta FastHeight ; save it * jsr FastOr ; nothing left but to do it * Cut pea Border pea 32 _MoveTo PushPtr Edit2 _DrawString lda #(160*24+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Copy pea Border pea 43 _MoveTo PushPtr Edit3 _DrawString lda #(160*34+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Paste pea Border pea 54 _MoveTo PushPtr Edit4 _DrawString lda #(160*45+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Clear pea Border pea 65 _MoveTo PushPtr Edit5 _DrawString lda #(160*56+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr PushWord StdTextMode _SetTextMode rts HiLiteEdit ENTRY lda #11 ; scan lines in title bar sta FastHeight lda #14 ; width to hilite, in bytes sta FastWidth lda #StartByte ; offset from $2000 to first pixel sta FastStart ; in bytes lda #$FFFF ; invert all sta FastColor jsr FastXor rts Edit1 dc i1'4' dc c'Undo' Edit2 dc i1'3' dc c'Cut' Edit3 dc i1'4' dc c'Copy' Edit4 dc i1'5' dc c'Paste' Edit5 dc i1'5' dc c'Clear' END **************************************************************** * * DoGoodies * **************************************************************** DoGoodies START using LibGlobals Height equ 112 Width equ 36 ; number of bytes for menu StartByte equ 37 Border equ 168 ; Goodies menu text start lda #GoodiesMenu sta CurrentMenu * Initialize menu parameters for the Goodies menu. lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(12*160+StartByte) ; offset from $2000 to first pixel sta MenuStart ; in bytes lda #StartByte sta MenuByte lda #(StartByte+Width) sta MenuEnd jsr SaveScreen ; save out what's underneath jsr DrawBlankMenu ; draw a blank menu field jsr SetFadeInfo ; set up fast fade values * Set initial flags lda #MenuActive ; get active flag stz MenuData+4 ; Grid stz MenuData+12 ; Fatbits stz MenuData+20 ; Set Font stz MenuData+28 ; Edit Pattern stz MenuData+36 ; Edit Mask stz MenuData+44 ; Edit Angles stz MenuData+52 ; Custom Brush stz MenuData+60 ; Custom Bucket stz MenuData+68 ; Custom Lasso stz MenuData+76 ; Custom Spatula PushWord #0 ; black text _SetForeColor PushWord #3 ; white background _SetBackColor * Grid pea Border ; H pea 21 ; V _MoveTo PushPtr Goodies1 _DrawString lda #(160*12+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Fatbits pea Border pea 32 _MoveTo PushPtr Goodies2 _DrawString lda #(160*23+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Set Font pea Border pea 43 _MoveTo PushPtr Goodies3 _DrawString lda #(160*34+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Edit Pattern pea Border pea 54 _MoveTo PushPtr Goodies4 _DrawString lda #(160*45+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Edit Mask pea Border pea 65 _MoveTo PushPtr Goodies5 _DrawString lda #(160*56+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Edit Angles pea Border pea 76 _MoveTo PushPtr Goodies6 _DrawString lda #(160*67+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Custom Brush pea Border pea 87 _MoveTo PushPtr Goodies7 _DrawString lda #(160*78+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Custom Bucket pea Border pea 98 _MoveTo PushPtr Goodies8 _DrawString lda #(160*89+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Custom Lasso pea Border pea 109 _MoveTo PushPtr Goodies9 _DrawString lda #(160*100+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr * Custom Spatula pea Border pea 120 _MoveTo PushPtr Goodies10 _DrawString lda #(160*111+StartByte+1) sta FastStart lda #10 ; let's cheat and always do 10 sta FastHeight jsr FastOr PushWord StdTextMode _SetTextMode rts HiLiteGoodies ENTRY lda #11 ; scan lines in title bar sta FastHeight lda #18 ; width to hilite, in bytes sta FastWidth lda #StartByte ; offset from $2000 to first pixel sta FastStart ; in bytes lda #$FFFF ; invert all sta FastColor jsr FastXor rts Goodies1 dc i1'4' dc c'Grid' Goodies2 dc i1'7' dc c'Fatbits' Goodies3 dc i1'8' dc c'Set Font' Goodies4 dc i1'12' dc c'Edit Pattern' Goodies5 dc i1'9' dc c'Edit Mask' Goodies6 dc i1'11' dc c'Edit Angles' Goodies7 dc i1'12' dc c'Custom Brush' Goodies8 dc i1'13' dc c'Custom Bucket' Goodies9 dc i1'12' dc c'Custom Lasso' Goodies10 dc i1'14' dc c'Custom Spatula' END **************************************************************** * * DoOptions * **************************************************************** DoOptions START using LibGlobals Height equ 57 Width equ 40 ; number of bytes for menu StartByte equ 55 Border equ 240 ; Options menu text start lda #OptionsMenu sta CurrentMenu * Initialize menu parameters for the Options menu. lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(12*160+StartByte) ; offset from $2000 to first pixel sta MenuStart ; in bytes lda #StartByte sta MenuByte lda #(StartByte+Width) sta MenuEnd jsr SaveScreen ; save out what's underneath jsr DrawBlankMenu ; draw a blank menu field jsr SetFadeInfo ; set up fast fade values * Set initial flags lda #MenuActive ; get active flag stz MenuData+4 ; 16/136 Colors stz MenuData+12 ; Pause/Continue stz MenuData+20 ; Window/Full screen stz MenuData+28 ; Sound On/Off stz MenuData+36 ; Animation On/Off PushWord #0 ; black text _SetForeColor PushWord #3 ; white background _SetBackColor * Invert pea Border ; H pea 21 ; V _MoveTo PushPtr Options1 _DrawString lda #(160*12+StartByte+1) sta FastStart ; start there lda #10 ; let's cheat and always do 10 sta FastHeight ; save it jsr FastOr ; nothing left but to do it * Fill pea Border pea 32 _MoveTo PushPtr Options2 _DrawString lda #(160*23+StartByte+1) sta FastStart ; start there lda #10 ; let's cheat and always do 10 sta FastHeight ; save it jsr FastOr ; nothing left but to do it * Flip Horizontal pea Border pea 43 _MoveTo PushPtr Options3 _DrawString lda #(160*34+StartByte+1) sta FastStart ; start there lda #10 ; let's cheat and always do 10 sta FastHeight ; save it jsr FastOr ; nothing left but to do it * Flip Vertical pea Border pea 54 _MoveTo PushPtr Options4 _DrawString lda #(160*45+StartByte+1) sta FastStart ; start there lda #10 ; let's cheat and always do 10 sta FastHeight ; save it jsr FastOr ; nothing left but to do it * Rotate pea Border pea 65 _MoveTo PushPtr Options5 _DrawString lda #(160*56+StartByte+1) sta FastStart ; start there lda #10 ; let's cheat and always do 10 sta FastHeight ; save it jsr FastOr ; nothing left but to do it PushWord StdTextMode _SetTextMode rts HiLiteOptions ENTRY lda #11 ; scan lines in title bar sta FastHeight lda #18 ; width to hilite, in bytes sta FastWidth lda #StartByte ; offset from $2000 to first pixel sta FastStart ; in bytes lda #$FFFF ; invert all sta FastColor jsr FastXor rts Options1 dc i1'6' dc c'Invert' Options2 dc i1'4' dc c'Fill' Options3 dc i1'15' dc c'Flip Horizontal' Options4 dc i1'13' dc c'Flip Vertical' Options5 dc i1'6' dc c'Rotate' END *===== * * Load toolkit * LoadToolkit START using LibGlobals using PaintGlobals using RsrcData PushLong ScreenRgn _SetClip ldx #Handle lda #KitHeight*KitWidth jsr GetNewHandle sta KitPtr sta Pointer stx KitPtr+2 stx Pointer+2 lda Handle sta KitHandle lda Handle+2 s  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEta KitHandle+2 lda #$0000 ; clear it to black ldy #KitHeight*KitWidth-2 LoadLoop sta [Pointer],y dey dey bpl LoadLoop stz KitActive jsr SwitchToolKit lda #KitHeight ; number of scan lines in full menu sta MenuHeight lda #KitWidth ; width of menu in bytes sta MenuWidth lda #(KitLine*160+KitByte) ; offset ($2000) to first pixel sta MenuStart ; in bytes lda #0 sta FastFlags jsr DrawFastWindow ; let's draw a fast window * draw the static (non-control) ToolKit resources PushPtr KitRsrc pea DrawMsg jsr MsgResource ToolkitIcon ENTRY ; port should be standard pea $0000 jsr SetPenColor pea 318 pea 0 _MoveTo pea 318 pea 11 _LineTo pea 350 pea 0 _MoveTo pea 350 pea 11 _LineTo pea 382 pea 0 _MoveTo pea 382 pea 11 _LineTo pea 414 pea 0 _MoveTo pea 414 pea 11 _LineTo pea 446 pea 0 _MoveTo pea 446 pea 11 _LineTo pea 478 pea 0 _MoveTo pea 478 pea 11 _LineTo jsr DrawMenuIcon UpdateTKIcon ENTRY PushLong FillPatPtr _PenPat PushPtr IconRect2 _PaintRect PushLong LinePatPtr _PenPat PushPtr IconRect3 _PaintRect PushLong BackPatPtr _PenPat PushPtr IconRect4 _PaintRect PushPtr StdWhite _PenPat PushPtr IconRect5 _PaintRect rts *===== * * SwitchToolKit * SwitchToolKit ENTRY Mask1 equ $0F00 Mask2 equ $F0FF Pick1 equ $E12000+KitLine*160+KitByte+KitWidth-2 Pick2 equ $E12000+(KitLine+KitHeight-1)*160+KitByte _HideCursor lda KitActive bne DontSave jsr HideSparkle lda >Pick1 and #Mask1 sta Save1 lda >Pick1+160 and #Mask1 sta Save2 lda >Pick1+320 and #Mask1 sta Save3 lda >Pick2 sta Save4 DontSave lda KitPtr sta FastSrc lda KitPtr+2 sta FastSrc+2 lda #KitWidth sta FastSLen sta FastWidth lda #KitHeight sta FastHeight lda #$2000+KitLine*160+KitByte sta FastDst lda #$00E1 sta FastDst+2 lda #160 sta FastDLen jsr FastSwitch lda KitActive bne DontFix lda >Pick1 and #Mask2 ora Save1 sta >Pick1 lda >Pick1+160 and #Mask2 ora Save2 sta >Pick1+160 lda >Pick1+320 and #Mask2 ora Save3 sta >Pick1+320 lda Save4 sta >Pick2 DontFix lda KitActive eor #1 sta KitActive bne LeaveIconsOff jsr ShowSparkle LeaveIconsOff _ShowCursor rts Save1 ds 2 Save2 ds 2 Save3 ds 2 Save4 ds 2 FastSwitch ENTRY bra CutInside NextLine lda FastSrc ; get the last screen position clc adc FastSLen ; increment by a scan line of bytes sta FastSrc ; save it for next time bcc IncrementDst inc FastSrc+2 IncrementDst lda FastDst ; get pointer to save area clc adc FastDLen sta FastDst bcc CheckHeight inc FastDst+2 CheckHeight dec FastHeight ; one less scan line bne CutInside ; if not zero, do the next line rts CutInside ldy FastWidth ; set y dey ; decrement y by 2, point at last word dey NextWord lda [FastSrc],y ; get data from Src tax lda [FastDst],y ; save it to Dst sta [FastSrc],y ; switch it txa sta [FastDst],y ; switch this too dey ; dock y by a word dey bpl NextWord ; if it isn't negative, do some more bra NextLine ; update pointers even if we're done END *===== * * Update the toolkit * UpdateToolkit START using LibGlobals using PaintGlobals using RsrcData PickStdColor ENTRY plx ; pull return pla ; Y value and #$0003 ; 0..3 eor #$0003 ; 3..0 asl A ; * 4 asl A sta Temp pla ; X value and #$0003 phx ; push return back ora Temp ; now we have the color value asl A asl A tax lda StdColorTab+2,x sta Temp+6 lda StdColorTab,x bra PX1 PickUserColor ENTRY plx ; pull return pla ; Y value and #$0003 eor #$0003 ; 3..0 asl A ; times 2 sta Temp asl A asl A clc adc Temp ; * 10 sta Temp pla ; X value phx ; push return back clc adc Temp asl A asl A tax lda UserColorTab+2,x sta Temp+6 lda UserColorTab,x PX1 sta Temp+4 PushPtr PaintPort _SetPort pei (Temp+6) pei (Temp+4) _PenPat PushLong StdPortPtr _SetPort lda KitActive bne KitIsOn jsr SwitchToolKit KitIsOn lda ClickOptions ; get flags and #AppleKey ; apple key bne LineChange lda ClickOptions and #FunctionKey bne BackChange lda Temp+4 sta FillPatPtr sta FOvalIcon+16 sta FRectIcon+16 sta FRRectIcon+16 lda Temp+6 sta FillPatPtr+2 sta FOvalIcon+18 sta FRectIcon+18 sta FRRectIcon+18 PushLong FillPatPtr _PenPat PushPtr IconRect2 _PaintRect jsr DrawMenuIcon brl Glowing LineChange lda Temp+4 sta LinePatPtr sta FOvalIcon+12 sta FRectIcon+12 sta FRRectIcon+12 lda Temp+6 sta LinePatPtr+2 sta FOvalIcon+14 sta FRectIcon+14 sta FRRectIcon+14 PushLong LinePatPtr _PenPat PushPtr IconRect3 _PaintRect brl Glowing BackChange lda Temp+4 sta BackPatPtr lda Temp+6 sta BackPatPtr+2 PushLong BackPatPtr _PenPat PushPtr IconRect4 _PaintRect bra Glowing PickUserMask ENTRY plx ; pull return pla ; Y value and #$0003 ; 0..3 eor #$0003 ; 3..0 asl A ; * 4 asl A sta Temp pla ; X value and #$0003 phx ; push return back ora Temp ; now we have the mask value asl A asl A tax lda UserMaskTab+2,x sta MaskPatPtr+2 lda UserMaskTab,x sta MaskPatPtr rts Glowing PushPtr GlowRsrc pea DrawMsg jsr MsgResource PushLong FillPatPtr _PenPat rts ChangeTool ENTRY plx ; pull return pla ; Y value and #$0007 asl A ; * 8 asl A asl A sta Temp pla ; X value and #$0007 phx ; push return back ora Temp ; now we have the tool number asl A ; make it a table offset cmp PaintTool bne Implemented NotImplemented rts Implemented stz SparkleState tax lda ToolTable,x beq NotImplemented stx PaintTool sta PaintCursor DrawMenuIcon ENTRY lda PaintTool asl A ; make it a pointer offset tax lda IconTable,x sta Pointer lda IconTable+2,x sta Pointer+2 ldy #IconMaxlen-2 IconCopy lda [Pointer],y sta LocalIcon,y dey dey bpl IconCopy PushPtr StdWhite _PenPat PushPtr IconRect1 _PaintRect ldx LocalIcon cpx #CopyBlock beq NotRect lda IconRect1 ina sta LocalIcon+4 lda IconRect1+2 ina ina sta LocalIcon+6 lda IconRect1+4 dea cpx #Line bne DMI1 dea DMI1 sta LocalIcon+8 lda IconRect1+6 dea dea cpx #Line bne DMI2 dea dea DMI2 sta LocalIcon+10 bra WasRect NotRect lda IconRect1 sta LocalIcon+4 lda IconRect1+2 sta LocalIcon+6 WasRect PushPtr LocalRsrc pea DrawMsg jsr MsgResource rts LocalRsrc dc i2'1' dc i2'LocalIcon-LocalRsrc' dc i2'0' LocalIcon ds 30 ToolTable dc i2'0,0,0,0,Cross,Cross,Cross,Cross' dc i2'Cross,Cross,0,0,Cross,Brush,0,0' dc i2'Square,Cross,0,Brush,0,Pencil,0,Cross' END *===== * * Hysterisis * Hysterisis START using LibGlobals using PaintGlobals sec lda X2 sbc MousePos+2 bpl NoInvertX eor #$FFFF ina NoInvertX cmp #2 bcc CheckY rts ; leave with carry set CheckY sec lda Y2 sbc MousePos bpl NoInvertY eor #$FFFF ina NoInvertY cmp #1 ; leave with carry correct rts *===== * * CheckTool * SparklerTool equ 46 CheckTool ENTRY lda MousePos ; get Y cmp PaintRect ; Mouse.Y-DRect.Y1 bmi UseArrow cmp PaintRect+4 ; Mouse.Y-DRect.Y2 bpl UseArrow lda MousePos+2 ; get X cmp PaintRect+2 bmi UseArrow cmp PaintRect+6 bpl UseArrow * It was in the content rect - now see if the kit is active and if it is * in that region. lda KitActive beq CheckSparks lda MousePos cmp #KitTop bmi CheckSparks cmp #KitBottom bpl CheckSparks lda MousePos+2 cmp #KitLeft bmi CheckSparks cmp #KitRight bmi UseArrow CheckSparks lda PaintTool cmp #SparklerTool beq CheckSparkler UseToolCursor lda PaintCursor pha jsr SetCursor sec rts UseArrow pea Arrow jsr SetCursor clc rts CheckSparkler lda Sparkling beq UseToolCursor lda FullSparkler bne CS1 lda MousePos cmp SparkleRect bmi UseToolCursor cmp SparkleRect+4 bpl UseToolCursor lda MousePos+2 ; get X cmp SparkleRect+2 bmi UseToolCursor cmp SparkleRect+6 bpl UseToolCursor CS1 pea ArrowCursor jsr SetCursor sec rts CopyMouse ENTRY lda MousePos sta Y2 lda MousePos+2 sta X2 * Normalize NormalRect so Y1 <= Y2 and X1 <= X2 lda Y1 cmp Y2 bpl YOutOfOrder sta NormalRect lda Y2 ina sta NormalRect+4 bra NormalizeX YOutOfOrder ina sta NormalRect+4 lda Y2 sta NormalRect NormalizeX lda X1 cmp X2 bpl XOutOfOrder sta NormalRect+2 lda X2 ina ina sta NormalRect+6 bra PushNormal XOutOfOrder ina ina sta NormalRect+6 lda X2 sta NormalRect+2 PushNormal plx stx Temp PushPtr NormalRect pei (Temp) rts END *===== * * Undo and Fixundo * Undo START * Undo switches all or part of the undo bitmap with the corresponding portion * of the screen, after turning off the toolkit and the cursor. It uses * undorect to figure out what should be switched. using LibGlobals using PaintGlobals lda #200 cmp UndoRect+4 bpl BottomOk sta UndoRect+4 BottomOk lda UndoRect cmp UndoRect+4 bpl NoUndo lda UndoRect+2 cmp UndoRect+6 bmi UndoItUp NoUndo rts UndoItUp _HideCursor lda KitActive pha beq KitAlreadyDown jsr SwitchToolkit KitAlreadyDown jsr SetUndoParams jsr FastSwitch pla beq KitStaysDown jsr SwitchToolKit KitStaysDown _ShowCursor rts *===== * * SetUndoParams * * SetUndoParams sets up FastSrc and FastDst for either a copy or a switch * based upon UndoRect. SetUndoParams pea 0 lda UndoRect ; top, in screen coordinates pha pea 160 jsr Multiply pla sta Temp ; bytes to top,0 lda UndoRect+2 ; left lsr A ; div 4 to get number of bytes lsr A clc adc Temp sta Temp ; bytes to top,left clc adc #$2000 ; screen offset sta FastSrc ; actual screen byte position lda #$00E1 sta FastSrc+2 lda Temp ; bytes to top,left sec sbc #(160*12) ; subtract menu bar clc adc UndoPtr sta FastDst lda UndoPtr+2 bcc NB1 ina NB1 sta FastDst+2 lda UndoRect+2 lsr A lsr A sta Temp lda UndoRect+6 ; right/4 rounded up clc adc #3 lsr A lsr A sec sbc Temp ; width, in bytes sta FastWidth ror A ; is it odd? bcc NotOdd inc FastWidth NotOdd lda #160 sta FastSLen sta FastDLen sec lda UndoRect+4 sbc UndoRect sta FastHeight rts *===== * * Fixundo * FixUndo ENTRY * FixUndo is called when the mouse is clicked. It copies from the * screen within UndoRect into the undo bit image using FastCopy. lda UndoRect cmp UndoRect+4 bpl NoChange lda UndoRect+2 cmp UndoRect+6 bmi FixItUp NoChange rts FixItUp jsr SetUndoParams _HideCursor jsr FastCopy ; copy screen to Undo bit image _ShowCursor rts NormalToUndo ENTRY lda NormalRect sta UndoRect lda NormalRect+2 sta UndoRect+2 lda NormalRect+4 sta UndoRect+4 lda NormalRect+6 sta UndoRect+6 rts END *===== * * Start tool * StartTool START using LibGlobals using PaintGlobals using RsrcData lda KitActive ; take down the toolkit beq LeaveItAlone jsr SwitchToolKit LeaveItAlone anop lda PaintTool cmp #46 beq DontFix jsr FixUndo DontFix lda MousePos sta Y1 sta Y2 sta NormalRect sta NormalRect+4 sta UndoRect ina sta UndoRect+4 lda MousePos+2 sta X1 sta X2 sta NormalRect+2 sta NormalRect+6 sta UndoRect+2 ina ina sta UndoRect+6 PushPtr PaintPort ; set our port _SetPort ldx PaintTool ; call the tool jsr (ClickTable,x) PushLong StdPortPtr ; put the system port back _SetPort lda #1 sta Clicked ; we're working pea NullEvent pea PaintDrag jsr SetHandler pea MouseUpEvent pea PaintRelease jsr SetHandler rts *===== * * Some handy quick escapes * SetInverse pea $8002 _PenMode PushPtr StdBlack _PenPat rts SetNormal pea $0000 _PenMode PushLong FillPatPtr _PenPat NullClick rts ClickTable dc i2'ClickPencil' ; poly dc i2'ClickPencil' ; filled poly dc i2'ClickPencil' ; blob dc i2'ClickPencil' ; filled blob dc i2'SetInverse' ; oval dc i2'SetInverse' ; filled oval dc i2'SetInverse' ; rect dc i2'SetInverse' ; filled rect dc i2'SetInverse' ; round rect dc i2'SetInverse' ; filled round rect dc i2'ClickPencil' ; lobucket dc i2'ClickPencil' ; spatula dc i2'SetNormal' ; urchin dc i2'ClickSilk' ; silk screen dc i2'ClickPencil' ; text dc i2'ClickPencil' ; lasso dc i2'ClickEraser' ; eraser dc i2'SetInverse' ; lines dc i2'ClickPencil' ; hibucket dc i2'ClickBrush' ; brush dc i2'ClickPencil' ; spraycan dc i2'ClickPencil' ; pencil dc i2'ClickPencil' ; hand dc i2'ClickSparkler' ; sparkler *===== * * ClickPencil * ClickPencil ldx #42 stx PaintTool ; defaults lda #2 pha sta PaintPen+2 lda #1 pha sta PaintPen _PenSize PushLong FillPatPtr _PenPat pea $0000 _PenMode rts *===== * * ClickEraser * ClickEraser PushLong BackPatPtr _PenPat lda #22 pha sta PaintPen+2 lda #9 pha sta PaintPen _PenSize bra BrushErase *===== * * ClickBrush * ClickSilk PushLong MaskPatPtr _SetPenMask ClickBrush PushLong FillPatPtr _PenPat lda BrushSize+2 pha sta PaintPen+2 lda BrushSize pha sta PaintPen _PenSize BrushErase pea $0000 _PenMode sec lda Y1 sbc HalfBrush sta BrushY sec lda X1 sbc HalfBrush+2 sta BrushX rts END *===== * * PaintDrag * PaintDrag START using LibGlobals using PaintGlobals lda MousePos cmp PaintRect bpl OverTheTop lda PaintRect sta MousePos OverTheTop jsr Hysterisis bcs Dragging rts Dragging PushPtr PaintPort _SetPort ldx PaintTool jsr (DragTable,x) PushLong StdPortPtr _SetPort rts DragTable ENTRY dc i2'0' ; poly dc i2'0' ; filled poly dc i2'0' ; blob dc i2'0' ; filled blob dc i2'DragOval' ; oval dc i2'DragOval' ; filled oval dc i2'DragRect' ; rect dc i2'DragRect' ; filled rect dc i2'DragRRect' ; round rect dc i2'DragRRect' ; filled round rect dc i2'0' ; lobucket dc i2'0' ; spatula dc i2'UrchinLine' ; urchin dc i2'DragBrush' ; silk screen dc i2'0' ; text dc i2'0' ; lasso dc i2'DragBrush' ; eraser dc i2'DragLine' ; line dc i2'0' ; hibucket dc i2'DragBrush' ; brush dc i2'0' ; spraycan dc i2'DragPencil' ; pencil dc i2'0' ; hand dc i2'DragSparkler' ; sparkler *===== * * Add mouse coordinates to the Undo rect * AddMouseToUndo ENTRY lda MousePos cmp UndoRect+4 bmi AMTop cmp PaintRect+4 ; clamp undo to its own rect bmi AM1 lda PaintRect+6 AM1 sta UndoRect+4 bra AMRight AMTop cmp UndoRect bpl AMRight cmp PaintRect bpl Am2 lda PaintRect AM2 sta UndoRect AMRight lda MousePos+2 cmp UndoRect+6 bmi AMLeft cmp PaintRect+6 bmi AM3 lda PaintRect+6 AM3 sta UndoRect+6 rts AMLeft cmp UndoRect+2 bpl AMDone cmp PaintRect+2 bpl AM4 lda PaintRect+2 AM4 sta UndoRect+2 AMDone rts *===== * * DragPencil * DragPencil ENTRY lda MousePos+2 cmp PaintRect+2 ; compare to left bpl LeftOkay lda PaintRect+2 sta MousePos+2 bra CheckTop LeftOkay cmp PencilRight bmi CheckTop lda PencilRight sta MousePos+2 CheckTop lda MousePos cmp PaintRect bpl TopOkay lda PaintRect sta MousePos bra DoneClamping TopOkay cmp PaintRect+4 bmi DoneClamping lda PaintRect+4 sta MousePos DoneClamping jsr AddMouseToUndo lda X2 pha lda Y2 pha _MoveTo lda MousePos+2 sta X2 pha lda MousePos sta Y2 pha _LineTo rts *===== * * Drag brush * DragBrush ENTRY jsr AddMouseToUndo lda BrushX ; these are already offset by HalfBrush pha lda BrushY pha _MoveTo sec lda MousePos+2 sta X2 ; so hysterisis will work sbc HalfBrush+2 sta BrushX pha sec lda MousePos sta Y2 sbc HalfBrush sta BrushY pha _LineTo rts *===== * * Drag Lines, Rects, RRects, Ovals * DragRect PushPtr NormalRect _HideCursor _FrameRect jsr CopyMouse _FrameRect _ShowCursor rts UrchinLine jsr AddMouseToUndo DragLine jsr RubberLine lda MousePos sta Y2 lda MousePos+2 sta X2 RubberLine ENTRY lda X1 pha lda Y1 pha _MoveTo lda X2 pha lda Y2 pha _HideCursor _LineTo _ShowCursor rts DragOval PushPtr NormalRect _HideCursor _FrameOval jsr CopyMouse _FrameOval _ShowCursor rts DragRRect _HideCursor PushPtr NormalRect pea 34 pea 17 _FrameRRect jsr CopyMouse pea 34 pea 17 _FrameRRect _ShowCursor rts END *===== * * PaintRelease * PaintRelease START using LibGlobals using PaintGlobals jsr CheckTool ; swap the cursor back, maybe lda MousePos ; don't let us paint into the menu bar cmp PaintRect bpl TopOkay lda PaintRect sta MousePos TopOkay PushPtr PaintPort _SetPort ldx PaintTool jsr (ReleaseTable,x) PushLong StdPortPtr _SetPort jsr PaintEvents rts ReleaseTable ENTRY dc i2'0' ; poly dc i2'0' ; filled poly dc i2'0' ; blob dc i2'0' ; filled blob dc i2'ReleaseOval' ; oval dc i2'ReleaseFOval' ; filled oval dc i2'ReleaseRect' ; rect dc i2'ReleaseFRect' ; filled rect dc i2'ReleaseRRect' ; round rect dc i2'ReleaseFRRect' ; filled round rect dc i2'0' ; lobucket dc i2'0' ; spatula dc i2'ReleaseUrchin' ; urchin dc i2'ReleaseSilk' ; silk screen dc i2'0' ; text dc i2'0' ; lasso dc i2'ReleaseBrush' ; eraser dc i2'ReleaseLine' ; lines dc i2'0' ; hibucket dc i2'ReleaseBrush' ; brush dc i2'0' ; spraycan dc i2'ReleasePencil' ; pencil dc i2'0' ; hand dc i2'ReleaseSparkler' ; sparkler *===== * * Release Pencil * ReleasePencil jsr DragPencil lda UndoRect cmp UndoRect+4 bmi PencilMoved lda UndoRect+2 cmp UndoRect+6 bmi PencilMoved lda Y1 ina sta Y2 lda X1 ina ina sta X2 PushPtr Y1 _PaintRect PencilMoved inc UndoRect+4 ; account for the pensize inc UndoRect+6 inc UndoRect+6 rts *===== * * Release Brush * ReleaseSilk jsr DragBrush PushPtr AllWhiteMask _SetPenMask bra BrushJoin ReleaseBrush jsr DragBrush BrushJoin lda UndoRect cmp UndoRect+4 bmi BrushMoved lda UndoRect+2 cmp UndoRect+6 bmi BrushMoved lda BrushY sta Y1 clc adc BrushSize sta Y2 lda BrushX sta X1 clc adc BrushSize+2 sta X2 PushPtr Y1 _PaintRect BrushMoved sec lda UndoRect sbc HalfBrush cmp PaintRect bpl RB1 lda PaintRect RB1 sta UndoRect ; top is set sec lda UndoRect+2 sbc HalfBrush+2 bpl RB2 lda #0 RB2 sta UndoRect+2 ; left is set sec lda UndoRect+4 sbc HalfBrush clc adc BrushSize cmp PaintRect+4 bmi RB3 lda PaintRect+4 RB3 sta UndoRect+4 ; bottom is set sec lda UndoRect+6 sbc HalfBrush+2 clc adc BrushSize+2 cmp PaintRect+6 bmi RB4 lda PaintRect+6 RB4 sta UndoRect+6 ; right is set lda #2 sta PaintPen+2 pha lda #1 sta PaintPen pha _PenSize rts *===== * * Release Line, Rect, Oval, RRect * ReleaseLine jsr RubberLine ; turn the old one off pea $0000 _PenMode lda MousePos sta Y2 lda MousePos+2 sta X2 PushLong LinePatPtr _PenPat jsr RubberLine jsr AddMouseToUndo ReleaseUrchin inc UndoRect+4 ; y pensize inc UndoRect+6 ; x pensize inc UndoRect+6 rts ReleaseRect PushPtr NormalRect _FrameRect pea $0000 _PenMode PushLong LinePatPtr _PenPat jsr CopyMouse ; pushes NormalRect ptr _FrameRect jsr NormalToUndo rts ReleaseFRect PushPtr NormalRect _FrameRect pea $0000 _PenMode PushLong FillPatPtr _PenPat jsr CopyMouse _PaintRect PushLong LinePatPtr _PenPat PushPtr NormalRect _FrameRect jsr NormalToUndo rts ReleaseOval PushPtr NormalRect _FrameOval pea $0000 _PenMode PushLong LinePatPtr _PenPat jsr CopyMouse ; pushes NormalRect ptr _FrameOval jsr NormalToUndo rts ReleaseFOval PushPtr NormalRect _FrameOval pea $0000 _PenMode PushLong FillPatPtr _PenPat jsr CopyMouse _PaintOval PushLong LinePatPtr _PenPat PushPtr NormalRect _FrameOval jsr NormalToUndo rts ReleaseRRect PushPtr NormalRect pea 34 pea 17 _FrameRRect pea $0000 _PenMode PushLong LinePatPtr _PenPat jsr CopyMouse ; pushes NormalRect ptr pea 34 pea 17 _FrameRRect jsr NormalToUndo rts ReleaseFRRect PushPtr NormalRect pea 34 pea 17 _FrameRRect pea $0000 _PenMode PushLong FillPatPtr _PenPat jsr CopyMouse pea 34 pea 17 _PaintRRect PushLong LinePatPtr _PenPat PushPtr NormalRect pea 34 pea 17 _FrameRRect jsr NormalToUndo rts END *===== * * ClickSparkler * ClickSparkler START using LibGlobals using PaintGlobals stz InSparkle lda MousePos cmp SparkleRect bmi NotInIt cmp SparkleRect+4 bpl NotInIt lda MousePos+2 cmp SparkleRect+2 bmi NotInIt cmp SparkleRect+6 bpl NotInit inc InSparkle NotInIt lda MousePos+2 FHIJKLMNOPQRSTUVWXYZ[\]^_`abcd; align it to a byte and #$FFFC sta X1 sta X2 sta NormalRect+2 sta NormalRect+6 sta UndoRect+2 ina ina sta UndoRect+6 lda InSparkle beq NewSparkle lda SparkleRect sta NormalRect lda SparkleRect+2 sta NormalRect+2 lda SparkleRect+4 sta NormalRect+4 lda SparkleRect+6 sta NormalRect+6 * lda ClickOptions * and #AppleKey * beq NotStretching * brl StretchSparkle NotStretching lda #RubberRect bra SetEnv NewSparkle lda Sparkling beq PreEnv jsr UnSparkle lda SparkleRect sta UndoRect lda SparkleRect+2 sta UndoRect+2 lda SparkleRect+4 sta UndoRect+4 lda SparkleRect+6 sta UndoRect+6 PreEnv jsr FixUndo ; if we're new, let someone else do it lda #DragSparkler SetEnv ldx #46 sta DragTable,x pea $8002 ; set inverse _PenMode PushPtr SparklePat _PenPat lda #0 sta FullSparkler lda #0 sta Sparkling rts PullSparkler _HideCursor PushPtr NormalRect _FrameRect jsr CopyNormal ; copy normalized rect plx ; local return pla ; are we stretching? phx ; push return back bne PullJoin NotBlting jsr CopyMouse PullJoin _FrameRect _ShowCursor rts YankSparkler ldx #1 bra YankEntry DragSparkler ENTRY ldx #0 YankEntry lda MousePos+2 ; align to a byte pha ; save it for hysterisis and #$FFFC sta MousePos+2 phx jsr PullSparkler pla ; restore it for hysterisis sta MousePos+2 sta X2 rts XSparkler lda MousePos+2 pha lda XConstraint sta MousePos+2 pea 1 ; stretch it jsr PullSparkler pla sta MousePos+2 sta X2 rts YSparkler lda MousePos pha lda YConstraint sta MousePos pea 1 ; stretch it jsr PullSparkler pla sta MousePos sta Y2 rts RubberRect lda X2 ; get old X and #$FFFC ; align to a byte sta Temp lda MousePos+2 ; get currentX and #$FFFC ; align this too sec sbc Temp ; get X movement beq CheckYMove bpl Positive eor #$FFFF ina Positive cmp #2 bpl MoveOkay rts CheckYMove lda Y2 cmp MousePos bne MoveOkay rts MoveOkay lda MousePos+2 sta X2 and #$FFFC sta MousePos+2 sec sbc X1 ; calc delta moved, total sta Temp+2 clc adc SparkleRect+2 cmp PaintRect+2 bpl LeftOkay lda PaintRect+2 sec sbc SparkleRect+2 sta Temp+2 ; fix amount to move bra CheckVert LeftOkay lda SparkleRect+6 clc adc Temp+2 cmp PencilRight ; (PaintRect+6)-2 bmi CheckVert lda PencilRight sec sbc SparkleRect+6 sta Temp+2 CheckVert lda MousePos sta Y2 sec sbc Y1 ; calc delta moved, total sta Temp clc adc SparkleRect cmp PaintRect bpl TopOkay lda PaintRect sec sbc SparkleRect sta Temp ; fix amount to move bra CheckDone TopOkay lda SparkleRect+4 clc adc Temp cmp PaintRect+4 bmi CheckDone lda PaintRect+4 sec sbc SparkleRect+4 sta Temp CheckDone lda Temp ora Temp+2 bne ItMoved rts ItMoved _HideCursor PushPtr NormalRect _FrameRect jsr CopyNormal ; copy normalized rect lda SparkleRect clc adc Temp sta NormalRect lda SparkleRect+4 clc adc Temp sta NormalRect+4 lda SparkleRect+2 clc adc Temp+2 sta NormalRect+2 lda SparkleRect+6 clc adc Temp+2 sta NormalRect+6 jsr ScrollSparkle ; from old NormalRect to new one PushPtr NormalRect _FrameRect _ShowCursor rts * The StretchSparkle routine has been circumvented in this version StretchSparkle lda #-1 sta XConstraint ; illegal screen values sta YConstraint lda MousePos sec sbc SparkleRect sta Temp ; dt lda SparkleRect+4 sec sbc MousePos sta Temp+2 ; db cmp Temp ; db-dt bmi LowerHalf * We hit somewhere on the top row, so Bottom is an anchor ldx SparkleRect+4 stx Temp+4 lsr A ; db/2 cmp Temp ; db/2-dt bpl FindX stx YConstraint lda SparkleRect sta Temp+4 bra FindX LowerHalf ldx SparkleRect ; Top is an anchor stx Temp+4 lsr Temp cmp Temp ; db-dt/2 bmi FindX lda SparkleRect+4 sta YConstraint FindX lda MousePos+2 sec sbc SparkleRect+2 sta Temp ; dl lda SparkleRect+6 sec sbc MousePos+2 sta Temp+2 ; dr cmp Temp ; dr-dl bmi RightHalf * We hit somewhere on the left row, so Right is an anchor ldx SparkleRect+6 stx Temp+6 lsr A ; dr/2 cmp Temp ; dr/2-dl bpl FullyConstrained lda YConstraint bpl DragInstead stx XConstraint lda SparkleRect+2 sta Temp+6 bra FullyConstrained DragInstead brl NotStretching RightHalf ldx SparkleRect+2 ; Left is an anchor stx Temp+6 lsr Temp cmp Temp ; db-dt/2 bmi FullyConstrained lda YConstraint bpl DragInstead lda SparkleRect+6 ; Right is also a constraint sta XConstraint * Temp+4 and Temp+6 contain the anchors to be used in the drag rect call. * This drag rect is unique in that the corner does not fall on the cursor, * but falls relative to where the cursor was at click time. If either * XConstraint or YConstraint are > 0 then we have the second type of dragging * which also uses a relative cursor position. FullyConstrained anop lda Temp+4 sta Y1 lda Temp+6 sta X1 lda SparkleRect sta SourceRect lda SparkleRect+2 sta SourceRect+2 lda SparkleRect+4 sta SourceRect+4 lda SparkleRect+6 sta SourceRect+6 lda YConstraint bmi NotY lda #YSparkler brl SetEnv NotY lda XConstraint bmi NotX lda #XSparkler brl SetEnv NotX lda #YankSparkler brl SetEnv *===== * * Release sparkler * ReleaseSparkler ENTRY lda NormalRect cmp NormalRect+4 bpl EmptySparkler sta SparkleRect lda NormalRect+2 cmp NormalRect+6 bmi GotSparkler EmptySparkler stz Sparkling bra RS1 GotSparkler sta SparkleRect+2 lda NormalRect+4 sta SparkleRect+4 lda NormalRect+6 sta SparkleRect+6 lda #1 sta Sparkling lda NormalRect cmp PaintRect bne NotFull lda NormalRect+2 cmp PaintRect+2 bne NotFull lda NormalRect+4 cmp PaintRect+4 bne NotFull lda NormalRect+6 cmp #640 ; VGC is fixed!!! beq SetFull NotFull stz FullSparkler bra RS1 SetFull lda #1 sta FullSparkler RS1 pea $0000 _PenMode PushLong FillPatPtr _PenPat rts ShowSparkle ENTRY lda SparkleState sta Sparkling bne FrameSparkle rts HideSparkle ENTRY lda Sparkling sta SparkleState UnSparkle ENTRY lda Sparkling beq NotThisTime stz Sparkling FrameSparkle _HideCursor pea $8002 ; set inverse _PenMode PushPtr SparklePat _PenPat PushPtr SparkleRect _FrameRect pea $0000 _PenMode _ShowCursor NotThisTime rts ScrollSparkle lda ScrollRect ; for updating sta Rect1 lda ScrollRect+2 sta Rect1+2 lda ScrollRect+4 ; get src sta Rect1+4 sec sbc ScrollRect ; calculate height sta FastHeight lda ScrollRect+6 sta Rect1+6 sec sbc ScrollRect+2 lsr A lsr A sta FastWidth pea 0 lda ScrollRect pha pea 160 jsr Multiply pla sta Temp lda ScrollRect+2 lsr A lsr A clc adc Temp sta Temp ; for UpdatePtr clc adc #$2000 sta SrcPtr sta UDstPtr lda #$00E1 sta SrcPtr+2 sta UDstPtr+2 lda Temp sec sbc #160*12 ; offset into undo buffer clc adc UndoPtr sta USrcPtr lda UndoPtr+2 bcc NB7 ina NB7 sta USrcPtr+2 pea 0 lda NormalRect sta Rect2 pha pea 160 jsr Multiply pla sta Temp lda NormalRect+2 sta Rect2+2 lsr A lsr A clc adc Temp clc adc #$2000 sta DstPtr lda #$00E1 sta DstPtr+2 lda #160 sta SrcLen sta DstLen sta UpdateLen jsr FastDrag lda NormalRect+4 sta Rect2+4 lda NormalRect+6 sta Rect2+6 jsr UpdateRectRgn rts * PushPtr ScrollRect * lda NormalRect+2 ; dest * sec * sbc ScrollRect+2 ; X1-Normalrect.X1 * pha * lda NormalRect * sec * sbc ScrollRect ; Y1-NormalRect.Y1 * pha * PushLong UpdateRgn * lda NormalRect * cmp ScrollRect * bpl TopOk * sta ScrollRect *TopOk lda NormalRect+2 * cmp ScrollRect+2 * bpl LeftOk * sta ScrollRect+2 *LeftOk lda NormalRect+4 * cmp ScrollRect+4 * bmi BottomOk * sta ScrollRect+4 *BottomOk lda NormalRect+6 * cmp ScrollRect+6 * bmi RightOk * sta ScrollRect+6 *RightOk _ScrollRect * rts CopyNormal lda NormalRect sta ScrollRect lda NormalRect+2 sta ScrollRect+2 lda NormalRect+4 sta ScrollRect+4 lda NormalRect+6 sta ScrollRect+6 rts ScrollRect ds 8 END * * Stretch.Asm * * Watch out for 32 bit _Multiply below so we can support BIG pixel maps *===== * * Stretch pixels * StretchPixels START using PaintGlobals SrcXect gequ NextZeroPage DstXect gequ SrcXect+4 SrcBits gequ DstXect+4 DstBits gequ SrcBits+4 StretchMode gequ DstBits+4 SrcVSize gequ StretchMode+2 SrcHSize gequ SrcVSize+2 DstVSize gequ SrcHSize+2 DstHSize gequ DstVSize+2 VError gequ DstHSize+2 HError gequ VEreghijklmnopqrstuvwxyz{|}~ror+2 CurrentY gequ Herror+2 ShiftCount gequ CurrentY+2 SrcLimit gequ ShiftCount+2 DstLimit gequ SrcLimit+2 DestNibble gequ DstLimit+2 LastNibble gequ DestNibble+2 ByteLimit gequ LastNibble+2 NextFlag gequ ByteLimit+2 LoNib gequ NextFlag+2 Nibs gequ LoNib+2 NextNib gequ Nibs+2 Hinc gequ NextNib+2 ScratchHandle gequ Hinc+2 SrcBuf gequ ScratchHandle+4 DstBuf gequ SrcBuf+4 SrcCtr gequ DstBuf+4 EqualFlag gequ SrcCtr+2 o_Mode gequ 0 o_BaseAddr gequ 2 o_Width gequ 6 o_Bounds gequ 8 * We will stretch from SrcXect into the menu buffer, then we will transfer * the new one on the screen and update from the undo buffer as appropriate. plx ; pull return pla ; pull dst low sta DstXect pla sta DstXect+2 pla sta SrcXect pla sta SrcXect+2 phx lda >$2000 ldy #0 CopyAgain lda [SrcXect],y sta LocalSrc,y lda [DstXect],y sta LocalDst,y iny iny cpy #8 bmi CopyAgain lsr LocalSrc+2 ; make the x values in "320" mode lsr LocalSrc+6 lsr LocalDst+2 dec LocalDst+4 ; stupid, stupid, bug dec LocalDst+6 ; because of that stupid bug lsr LocalDst+6 lda #LocalSrc ; point SrcXect and DstXect at locals sta SrcXect lda #^LocalSrc sta SrcXect+2 lda #LocalDst sta DstXect lda #^LocalDst sta DstXect+2 * Set up SrcBits lda #^SrcLocInfo sta SrcBits+2 lda #SrcLocInfo sta SrcBits ldy #o_BaseAddr lda UndoPtr sta [SrcBits],y ldy #o_BaseAddr+2 lda UndoPtr+2 sta [SrcBits],y ldy #o_Width lda #160 sta [SrcBits],y * Set up DstBits lda #^DstLocInfo sta DstBits+2 lda #DstLocInfo sta DstBits ldy #o_BaseAddr lda BuffPtr sta [DstBits],y ldy #o_BaseAddr+2 lda BuffPtr+2 sta [DstBits],y lda LocalDst+2 ; put Dst.Left on a byte boundary lsr A ; byte number we start on sta Temp lda LocalDst+6 ; put Dst.Right on a byte boundary ina lsr A ; byte number we end on sec sbc Temp ; width, in bytes sta DestBytes ina and #$FFFE ; width, in words * 2 sta DestWords2 ldy #o_Width sta [DstBits],y lda LocalDst ldy #o_Bounds sta [DstBits],y ; move the port to match the DstXect lda LocalDst+2 ldy #o_Bounds+2 sta [DstBits],y stz StretchMode jsl StretchBits * result has been placed in BuffPtr - FastCopy it to the screen using * DstXect lda BuffPtr sta FastSrc lda BuffPtr+2 sta FastSrc+2 lda DestWords2 ; use DestBytes when FastCopy can sta FastSLen sta FastWidth ldy #4 lda [DstXect],y sec sbc [DstXect] sta FastHeight ldy #2 lda [DstXect],y lsr A ; only once, we are in "320" mode sta Temp pea 0 lda [DstXect] pha pea 160 jsr Multiply pla clc adc Temp clc adc #$2000 sta FastDst lda #$00E1 sta FastDst+2 lda #160 sta FastDLen jsr FastCopy rts ; and leave DestBytes ds 2 DestWords2 ds 2 LocalSrc ds 8 LocalDst ds 8 SrcLocInfo dc i2'$0000' ; mode 320 dc i4'$000000' ; put UndoPtr here dc i2'160' ; width in bytes dc i2'12,0,200,320' ; bounds rect DstLocInfo dc i2'$0000' ; mode 320 dc i4'$000000' ; put BuffPtr here dc i2'160' ; put DstWidth here dc i2'0,0,200,320' ; bounds rect END *===== * * StretchBits * * SrcBits, DstBits, SrcXect, DstXect, StretchBits START * Transfer a rectangle of bits from SrcBits to DstBits, stretching * or compressing according to SrcXect and DstXect. The transfer is * clipped to the intersection of RgnA, RgnB, and RgnC. * Transfer modes 0..7 only. If stretching or compressing, the src * and dst bitmaps are assumed not to overlap. * Calc DstXect Height:Width Longint using PaintGlobals ; TEMPORARY!!! ldy #4 lda [DstXect],y sec sbc [DstXect] sta DstVSize ldy #6 lda [DstXect],y sec ldy #2 sbc [DstXect],y sta DstHSize * Calc SrcXect Height:Width Longint ldy #4 lda [SrcXect],y sec sbc [SrcXect] sta SrcVSize ldy #6 lda [SrcXect],y sec ldy #2 sbc [SrcXect],y * Save as SrcSizes then compare to DstSizes - if same, call Rgnblt and go home sta SrcHSize cmp DstHSize bne NotEqual lda SrcVSize cmp DstVSize bne NotEqual *! * Set up the appropriate parameters * jsl RgnBlt rtl NotEqual jsl SetupStretch ; set ShiftCount, Horiz routine bcc SetupOkay rtl SetupOkay lda [DstXect] sta CurrentY lda SrcHSize ; src width jsl ConvertToBytes ; uses ShiftCount to return A = bytes sta SrcLimit and #$FFFC ; clear to nearest long word clc adc #8 ; give us some extra slop pha ; save intermediate result lda DstHSize ; destination width jsl ConvertToBytes ; zero base it sta DstLimit and #$FFFC clc adc #8 ; some more extra slop clc adc 1,s ; add in src buffer length ldx #ScratchHandle ; length is passed in A, where in X jsr GetNewHandle sta SrcBuf ; SrcBuf is at start of Scratch stx SrcBuf+2 pla ; retrieve src buf len clc ; DstBuf is at end of Scratch adc SrcBuf sta DstBuf bcc NBPtr ; X is still SrcBuf+2 inx NBPtr stx DstBuf+2 * brk $AC pea 0 ; result lda [SrcXect] ; get top ldy #o_Bounds sec sbc [SrcBits],y ; make it global pha ; push top ldy #o_Width lda [SrcBits],y pha ; push width jsr Multiply ; _Multiply ldy #2 lda [SrcXect],y ; get left ldy #o_Bounds+2 sec sbc [SrcBits],y jsl ConvertToBytes sta Temp pla clc adc Temp clc ldy #o_BaseAddr ; careful!!! 32 bit multiply? adc [SrcBits],y sta SrcPtr ldy #o_BaseAddr+2 lda [SrcBits],y bcc NB3 ina NB3 sta SrcPtr+2 pea 0 ; result lda [DstXect] ; get top ldy #o_Bounds sec sbc [DstBits],y ; make it global pha ; push top ldy #o_Width lda [DstBits],y pha ; push width jsr Multiply ; _Multiply ldy #2 lda [DstXect],y ; get left ldy #o_Bounds+2 sec sbc [DstBits],y jsl ConvertToBytes sta Temp pla clc adc Temp clc ldy #o_BaseAddr adc [DstBits],y sta DstPtr ldy #o_BaseAddr+2 lda [DstBits],y bcc NB4 ina NB4 sta DstPtr+2 * Init error term for DDA * brk $AC lda SrcVSize lsr A eor #$FFFF ina sta VError ; VError := -Denom.V/2 lda SrcHSize jsl ConvertToBytes ina sta SrcLimit bra NBS1 * Get first scanline of Src into SrcBuf NextSrc lda SrcPtr clc ldy #o_Width adc [SrcBits],y sta SrcPtr bcc NBS1 inc SrcPtr+2 NBS1 ldy #0 SrcCopyLoop lda [SrcPtr],y sta [SrcBuf],y iny iny cpy SrcLimit bmi SrcCopyLoop NextSrc2 lda VError clc adc DstVSize sta VError dea bpl SrcOk MergeIt jsl ToMerge SrcOk lda EqualFlag bne GoUseSrc jsl ToStretch NxtMask lda EqualFlag ; no horizontal change if <> 0 beq GoUseDst GoUseSrc ldy #0 UseSrcLoop lda [SrcBuf],y sta [DstPtr],y iny iny cpy SrcLimit bmi UseSrcLoop bra CopyDone GoUseDst ldy #0 DstCopyLoop lda [DstBuf],y ; copy (modified) scan line to dst sta [DstPtr],y iny iny cpy DstLimit bmi DstCopyLoop CopyDone lda DstPtr clc ldy #o_Width adc [DstBits],y sta DstPtr bcc NBD1 inc DstPtr+2 NBD1 lda CurrentY ina ldy #4 cmp [DstXect],y beq Done sta CurrentY lda VError sec sbc SrcVSize ; subtract increment sta VError ; VError := VError - Denom.V bpl NxtMask brl NextSrc * Entire StretchBits complete. Restore and go home Done anop ldx #ScratchHandle jsr UnlockHandle PushLong ScratchHandle _DisposHandle GoHome rtl *===== * * ConvertToBytes * ConvertToBytes ENTRY ldx ShiftCount beq OkayAsIs dea ; subtract 1 pixel bmi ItWasZero ShiftLoop lsr A dex bne ShiftLoop ItWasZero ina ; add 1 byte OkayAsIs rtl *===== * * RgnBlt * RgnBlt anop rtl *===== * * SetupStretch * * Calc case jump and horizontal fraction SetupStretch stz ShiftCount ldy #o_Mode lda [SrcBits],y cmp [DstBits],y beq StretchModeOk BadMode sec rtl StretchModeOk cmp #$0000 ; only 320 mode for now beq Do320Mode brl Not320Mode Do320Mode lda #1 sta ShiftCount lda SrcHSize bmi BadMode lda DstHSize bmi BadMode stz EqualFlag cmp SrcHSize bne NotEqual320 inc EqualFlag bra NoCalc320 NotEqual320 pea 0 ; FixRatio result pea 0 bmi Shrinking320 lda >JmpStretch320 sta >ToStretch lda >JmpStretch320+2 sta >ToStretch+2 pei SrcHSize ; push denominator (Src width) pei DstHSize ; push numerator (Dst width) bra FixRatio320 Shrinking320 lda >JmpShrink320 sta >ToStretch lda >JmpShrink320+2 sta >ToStretch+2 pei DstHSize pei SrcHSize FixRatio320 _FixRatio pla ; this is the error part sta HInc ; which we save pla ; this better be zero lda #$8000 sta HError clc rtl NoCalc320 lda >JmpNoChange sta >ToStretch lda >JmpNoChange+2 sta >ToStretch+2 clc rtl Not320Mode sec rtl *===== * * ToMerge * ToMerge lda SrcPtr clc ldy #o_Width adc [SrcBits],y sta SrcPtr bcc MergeJsl inc SrcPtr+2 MergeJsl jsl >SimpleMerge lda VError clc adc DstVSize ; add destination size sta VError ; VError := VError + Numer.V dea bmi ToMerge ; loop while VError <= 0 rtl ; space keeper SimpleMerge ldy #0 sep #$20 longa off SrcMerger lda [SrcPtr],y cmp [SrcBuf],y bpl DontMerge sta [SrcBuf],y DontMerge iny cpy SrcLimit bmi SrcMerger rep #$20 longa on rtl *===== * * ToStretch * ToStretch jmp >NoChange JmpNoChange jmp >NoChange JmpStretch320 jmp >Stretch320 JmpShrink320 jmp >Shrink320 NoChange rtl *===== * * Stretch320 * * Stretch a source row to the destination row, which will be contained * within our own buffer, so don't bother with the ending pixel - just * blast it in there as needed (allocate some slop up above). Stretch320 stz HError ; tracks the DDL term stz SrcCtr ; tracks SrcBuf y stz NextFlag ; remembers partial source bytes stz DestNibble ; current nibble stz LastNibble ; DDL nibble counter * Determine how many bits to expand on this stretch run. Assume 16 bit mode. * Leave the result in the x register. Next2Bit ldx #0 ; zero our counter lda HError H2Loop inx ; bump x until HError spills over clc adc HInc bcc H2Loop sta HError ; save DDL term txa ; get number of nibbles to do clc adc LastNibble ; add nibbles done sta LastNibble ; new nibble limit ina lsr A ; half the nibbles = the bytes sta ByteLimit * Load the next nibble into LoNib and Nibs. Assume 16 bit mode. lda NextFlag beq ReadNibs stz NextFlag lda NextNib and #$0F ; just the lower nibble sta LoNib asl A asl A asl A asl A ora LoNib sta Nibs bra GotNibble ReadNibs inc NextFlag ldy SrcCtr lda [SrcBuf],y ; pick up 2 nibbles of information iny sty SrcCtr sta NextNib ; save it in x and #$F0 ; grab the first nibble sta Temp ; save the high nibble lsr A ; shift it down lsr A lsr A lsr A sta LoNib ora Temp ; now we have a composite byte sta Nibs GotNibble lda DestNibble ; fetch the next nibble lsr A ; are we on a byte boundary tay ; point y at the correct byte bcc ByteBoundary ; yes, ignore the partial stuff lda [DstBuf],y ; no, OR in the new nibble and #$FFF0 ; clear first byte, second nibble ora LoNib ; or in the second nibble sta [DstBuf],y ; store the composite byte iny tya ; y points at next byte asl A ; A points at next nibble cmp LastNibble ; are we done for now? bpl NextSrc2Bit ; if <0, drop into storing full bytes * More to do. We know we are on a byte boundary now, so we can store a full * byte at a time until we run out of room. If we go too far, no big deal. ByteBoundary sep #$20 ; no abs. refs, we promise! lda Nibs Nib2Loop sta [DstBuf],y ; store a full byte until we run out iny cpy ByteLimit bmi Nib2Loop rep #$20 ; see, kept our promise! lda LastNibble NextSrc2Bit sta DestNibble cpy DstHSize bmi Next2Bit rtl *===== * * Shrink320 * * Shrink a 320 mode source row into the destination buffer. Shrink320 stz HError ; tracks the DDL term stz SrcCtr ; tracks SrcBuf y * Load NextFlag with oddness of SrcRect when we get fancy stz NextFlag ; remembers partial source bytes stz DestNibble ; current nibble stz LastNibble ; DDL nibble counter * Determine how many src nibbles to consume on this shrink run. Assume * 16 bit mode. Leave the result in the x register. NextSh320 lda #$000F ; a white nibble sta Nibs ; Nibs is our best bet yet ldx #0 ; zero our counter lda HError Sh320Loop inx ; bump x until HError spills over clc adc HInc bcc Sh320Loop sta HError ; save DDL term * Examine X nibbles, saving the lowest value found in Nibs. lda NextFlag beq ReadSh320 AnotherSh320 stz NextFlag lda NextNib and #$0F ; just the lower nibble cmp Nibs bpl TillSh320 sta Nibs TillSh320 dex beq CommonSh320 ReadSh320 inc NextFlag ldy SrcCtr lda [SrcBuf],y ; pick up 2 nibbles of information iny sty SrcCtr sta NextNib ; save it in x and #$00F0 ; grab the first nibble lsr A ; shift it down lsr A lsr A lsr A cmp Nibs bpl Okay320 sta Nibs Okay320 dex bne AnotherSh320 CommonSh320 lda DestNibble ; fetch the next nibble lsr A ; are we on a byte boundary tay ; point y at the correct byte bcc Sh320ByteBndry ; yes, ignore the partial stuff lda [DstBuf],y ; no, OR in the new nibble and #$FFF0 ; clear first byte, second nibble ora Nibs ; or in the second nibble sta [DstBuf],y ; store the composite byte bra BumpDstSh320 Sh320ByteBndry lda Nibs asl A ; shift it into the high nibble asl A asl A asl A sta [DstBuf],y BumpDstSh320 lda DestNibble ina sta DestNibble cmp DstHSize bmi NextSh320 rtl *===== * * ToModeHandler * ToModeHandler anop rtl END ************************************************************** * * Procedure RsrcData * ************************************************************* RsrcData DATA using LibGlobals GlowRsrc dc i2'3' dc i2'FOvalIcon-GlowRsrc' dc i2'FRectIcon-GlowRsrc' dc i2'FRRectIcon-GlowRsrc' IconMaxLen equ 24 IconTable dc i4'PolyIcon' dc i4'FPolyIcon' dc i4'BlobIcon' dc i4'FBlobIcon'  dc i4'OvalIcon' dc i4'FOvalIcon' dc i4'RectIcon' dc i4'FRectIcon' dc i4'RRectIcon' dc i4'FRRectIcon' dc i4'LoBucketIcon' dc i4'SpatulaIcon' dc i4'UrchinIcon' dc i4'SilkIcon' dc i4'TextIcon' dc i4'LassoIcon' dc i4'EraserIcon' dc i4'LineIcon' dc i4'HiBucketIcon' dc i4'BrushIcon' dc i4'SprayCanIcon' dc i4'PencilIcon' dc i4'HandIcon' dc i4'SparklerIcon' KitRsrc dc i2'17' dc i2'IconGrid-KitRsrc' dc i2'StdColorGrid-KitRsrc' dc i2'UserColorGrid-KitRsrc' dc i2'UserMaskGrid-KitRsrc' dc i2'OvalIcon-KitRsrc' dc i2'FOvalIcon-KitRsrc' dc i2'RectIcon-KitRsrc' dc i2'FRectIcon-KitRsrc' dc i2'RRectIcon-KitRsrc' dc i2'FRRectIcon-KitRsrc' dc i2'UrchinIcon-KitRsrc' dc i2'SilkIcon-KitRsrc' dc i2'EraserIcon-KitRsrc' dc i2'LineIcon-KitRsrc' dc i2'BrushIcon-KitRsrc' dc i2'PencilIcon-KitRsrc' dc i2'SparklerIcon-KitRsrc' IconGrid dc i2'PatternGrid' ; draw a line grid dc i2'DrawMsg' ; only draw dc i2'19,14' ; top, left dc i2'0,0' ; space for bottom, right dc i2'11,30' ; dy, dx (not counting lines) dc i2'3,8' ; y units, x units dc i4'0' ; no patterns yet dc i2'ChangeTool' ; no manager yet PolyIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'20,16' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'PolyImage' ; big block below FPolyIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'20,48' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'FPolyImage' ; big block below BlobIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'20,80' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'BlobImage' ; big block below FBlobIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'20,112' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'FBlobImage' ; big block below OvalIcon dc i2'Oval' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'21,146,30,172' ; oval rect dc i4'StdBlack' ; frame color dc i4'0' ; no interior color FOvalIcon dc i2'Oval' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'21,178,30,204' ; oval rect dc i4'StdBlack' ; frame color dc i4'StdRed' ; interior color RectIcon dc i2'Rect' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'21,210,30,236' ; rect dc i4'StdBlack' ; frame color dc i4'0' ; no interior color FRectIcon dc i2'Rect' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'21,242,30,268' ; oval rect dc i4'StdBlack' ; frame color dc i4'StdRed' ; interior color RRectIcon dc i2'RRect' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'33,18,42,44' ; rrect rect dc i4'StdBlack' ; frame color dc i4'0' ; no interior color dc i2'7,17' ; curvature FRRectIcon dc i2'RRect' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'33,50,42,76' ; rrect rect dc i4'StdBlack' ; frame color dc i4'StdRed' ; interior color dc i2'7,17' ; curvature LoBucketIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'32,80' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'LoBucketImage' ; big block below SpatulaIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'32,112' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'SpatulaImage' ; big block below UrchinIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'32,144' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'UrchinImage' ; big block below SilkIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'32,176' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'SilkImage' ; big block below TextIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'32,208' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'TextImage' ; big block below LassoIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'32,240' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'LassoImage' ; big block below EraserIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'44,16' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'EraserImage' ; big block below LineIcon dc i2'Line' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'46,52,52,72' ; line dc i4'StdBlack' ; line color dc i2'1,2' ; pen size HiBucketIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'44,80' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'HiBucketImage' ; big block below BrushIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'44,112' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'BrushImage' ; big block below SprayCanIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'44,144' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'SprayCanImage' ; big block below PencilIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'44,176' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'PencilImage' ; big block below HandIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'44,208' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'HandImage' ; big block below SparklerIcon dc i2'CopyBlock' ; a fast copy dc i2'DrawMsg' ; never more than draw dc i2'44,240' ; y,x dc i2'8' ; width in bytes dc i2'11' ; height dc i4'SparklerImage' ; big block below PolyImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' FPolyImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' BlobImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' FBlobImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' LoBucketImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' SpatulaImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' UrchinImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFF4FFFFFFF0' dc h'FFFF4FF4FF4FFFF0' dc h'FF4FF4F4F4FF4FF0' dc h'FFF44F444F44FFF0' dc h'F4444444444444F0' dc h'FFF44F444F44FFF0' dc h'FF4FF4F4F4FF4FF0' dc h'FFFF4FF4FF4FFFF0' dc h'FFFFFFF4FFFFFFF0' dc h'FFFFFFFFFFFFFFF0' SilkImage dc h'FFFFFFFFFFFFFFF0' dc h'F0000000000000F0' dc h'F0F1F1F1F1F1F0F0' dc h'F0111111111110F0' dc h'F0F1F1F1F1F1F0F0' dc h'F0111111111110F0' dc h'F0F1F1F1F1F1F0F0' dc h'F0111111111110F0' dc h'F0F1F1F1F1F1F0F0' dc h'F0000000000000F0' dc h'FFFFFFFFFFFFFFF0' TextImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFF00000FFFFF0' dc h'FFFF0199980FFFF0' dc h'FFF019000180FFF0' dc h'FFF09030F000FFF0' dc h'FFF090F0FFFFFFF0' dc h'FFF09030F000FFF0' dc h'FFF019000180FFF0' dc h'FFFF0199980FFFF0' dc h'FFFFF00000FFFFF0' dc h'FFFFFFFFFFFFFFF0' LassoImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' EraserImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFC0000000003F0' dc h'FFC37777777700F0' dc h'FC000000000070F0' dc h'F0777777777070F0' dc h'F077777777700FF0' dc h'FC0000000003FFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' HiBucketImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' BrushImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFF00000FFFF0' dc h'FFFFF026603FFFF0' dc h'FFFFF06660FFFFF0' dc h'FFFFF06660FFFFF0' dc h'FFFFF00000FFFFF0' dc h'FFFFFC1DC3FFFFF0' dc h'FFFFFF0D0FFFFFF0' dc h'FFFFFC1DC3FFFFF0' dc h'FFFFFF000FFFFFF0' dc h'FFFFFFFFFFFFFFF0' SprayCanImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' PencilImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFF00FFFF0' dc h'FFFFFFFF0770FFF0' dc h'FFFFFFF0E070FFF0' dc h'FFFFFF0E660FFFF0' dc h'FFFFF0E660FFFFF0' dc h'FFFF0E660FFFFFF0' dc h'FFF02660FFFFFFF0' dc h'FFF0220FFFFFFFF0' dc h'FFF000FFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' HandImage dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' dc h'FFFFFFFFFFFFFFF0' SparklerImage dc h'FFFFFFFFFFFFFFF0' dc h'F00FF00FF00FF0F0' dc h'FFFFFFFFFFFFF0F0' dc h'FFFFFFFFFFFFFFF0' dc h'F0FFFFFFFFFFFFF0' dc h'F0FFFFFFFFFFF0F0' dc h'FFFFFFFFFFFFF0F0' dc h'FFFFFFFFFFFFFFF0' dc h'F0FFFFFFFFFFFFF0' dc h'F0FF00FF00FF00F0' dc h'FFFFFFFFFFFFFFF0' StdColorGrid dc i2'PatternGrid' ; draw a line grid dc i2'DrawMsg' ; only draw dc i2'19,282' ; top, left dc i2'0,0' ; space for bottom, right dc i2'8,16' ; dy, dx (not counting lines) dc i2'4,4' ; x units, y units dc i4'StdPatterns' ; pointer to standard patterns dc i2'PickStdColor' ; selects a standard color UserColorGrid dc i2'PatternGrid' ; draw a line grid dc i2'DrawMsg' ; only draw dc i2'19,356' ; top, left dc i2'0,0' ; space for bottom, right dc i2'8,16' ; dy, dx (not counting lines) dc i2'4,10' ; y units, x units dc i4'UserPatterns' ; pointer to patterns dc i2'PickUserColor' ; no manager yet UPat anop UserPatterns dc 8i4'$E6E66E6E' dc 8i4'$E2E22E2E' dc 8i4'$E3E33E3E' dc 8i4'$D8D88D8D' dc 8i4'$C8C88C8C' dc 8i4'$C9C99C9C' dc 8i4'$C4C44C4C' dc 8i4'$B7B77B7B' dc 8i4'$B6B66B6B' dc 8i4'$A6A66A6A' dc 8i4'$98988989' dc 8i4'$76766767' dc 8i4'$63633636' dc 8i4'$54544545' dc 8i4'$62622626' dc 8i4'$F5F55F5F' ; was 32322323 dc 8i4'$E6E66E6E' dc 8i4'$E2E22E2E' dc 8i4'$E3E33E3E' dc 8i4'$D8D88D8D' dc 8i4'$C8C88C8C' dc 8i4'$C9C99C9C' dc 8i4'$C4C44C4C' dc 8i4'$B7B77B7B' dc 8i4'$B6B66B6B' dc 8i4'$A6A66A6A' dc 8i4'$98988989' dc 8i4'$76766767' dc 8i4'$63633636' dc 8i4'$54544545' dc 8i4'$62622626' dc 8i4'$F5F55F5F' ; was 32322323 dc 8i4'$B6B66B6B' dc 8i4'$A6A66A6A' dc 8i4'$98988989' dc 8i4'$76766767' dc 8i4'$63633636' dc 8i4'$54544545' dc 8i4'$62622626' dc 8i4'$F5F55F5F' ; was 32322323 UserColorTab dc i4'UPat+960' dc i4'UPat+992' dc i4'UPat+1024' dc i4'UPat+1056' dc i4'UPat+1088' dc i4'UPat+1120' dc i4'UPat+1152' dc i4'UPat+1184' dc i4'UPat+1216' dc i4'UPat+1248' dc i4'UPat+640' dc i4'UPat+672' dc i4'UPat+704' dc i4'UPat+736' dc i4'UPat+768' dc i4'UPat+800' dc i4'UPat+832' dc i4'UPat+864' dc i4'UPat+896' dc i4'UPat+928' dc i4'UPat+320' dc i4'UPat+352' dc i4'UPat+384' dc i4'UPat+416' dc i4'UPat+448' dc i4'UPat+480' dc i4'UPat+512' dc i4'UPat+544' dc i4'UPat+576' dc i4'UPat+608' dc i4'UPat' dc i4'UPat+32' dc i4'UPat+64' dc i4'UPat+96' dc i4'UPat+128' dc i4'UPat+160' dc i4'UPat+192' dc i4'UPat+224' dc i4'UPat+256' dc i4'UPat+288' UserMaskGrid dc i2'MaskGrid' ; draw a line grid dc i2'DrawMsg' ; only draw dc i2'19,548' ; top, left dc i2'0,0' ; space for bottom, right dc i2'8,16' ; dy, dx (not counting lines) dc i2'4,4' ; x units, y units dc i4'UserMasks' ; user masks dc i2'PickUserMask' ; no manager yet UserMasks dc 4i2'$FFFF' ; no mask dc 4i2'$AA55' ; stipple dc 4i2'$2288' ; stipple dc 4i2'$8822' ; stipple dc 4i2'$1144' ; stipple dc 4i2'$4411' ; stipple dc 4i2'$33CC' ; stipple dc 4i2'$CC33' ; stipple dc 4i2'$33FF' ; stipple dc 4i2'$FF33' ; stipple dc 4i2'$0033' ; stipple dc 4i2'$3300' ; stipple dc 4i2'$EEBB' ; stipple dc 4i2'$BBEE' ; stipple dc 4i2'$EEFF' ; stipple dc 4i2'$FEFF' ; stipple UserMaskTab dc i4'UserMasks+96' dc i4'UserMasks+104' dc i4'UserMasks+112' dc i4'UserMasks+120' dc i4'UserMasks+64' dc i4'UserMasks+72' dc i4'UserMasks+80' dc i4'UserMasks+88' dc i4'UserMasks+32' dc i4'UserMasks+40' dc i4'UserMasks+48' dc i4'UserMasks+56' dc i4'UserMasks' dc i4'UserMasks+8' dc i4'UserMasks+16' dc i4'UserMasks+24' END *===== * * Dump screen * DumpScreen START pea Watch jsr SetCursor _HideCursor * First copy the screen into BuffPtr so we can clean up the bottom and add * the scan line and palette information. lda #($2000+12*160) sta FastSrc lda #$00E1 sta FastSrc+2 lda BuffPtr sta FastDst lda BuffPtr+2 sta FastDst+2 lda #160  sta FastSLen sta FastDLen sta FastWidth lda #200-12 sta FastHeight jsr FastCopy * Clear the last 12 lines to black lda #12 sta FastHeight dec FastWidth dec FastWidth NextLine ldy FastWidth ; set y lda #0 ; black FillLoop sta [FastDst],y ; store black dey dey bpl FillLoop ; if it isn't negative, do some more lda FastDst ; get the last screen position clc adc FastDLen ; increment by a scan line of bytes sta FastDst ; save it for next time bcc NBFD inc FastDst+2 NBFD dec FastHeight ; one less scan line bne NextLine ; if not zero, do the next line * Copy the palette information over phb pea $E1E1 plb plb ldy #0 MoreSCBCopy lda $9D00,y ; offset to SCB info sta [FastDst],y ; copy standard SCB into BuffPtr iny iny cpy #$300 bne MoreSCBCopy plb PushPtr DumpFilename ; the name of the file PushLong BuffPtr ; push our menu buffer PushLong #$8000 ; write 64 blocks, unpacked jsr SaveFile ; do it pea Arrow jsr SetCursor _ShowCursor rts DumpFileName dc i1'8' dc c'SCREEN.0' **************************************************************** * * LoadDocument * **************************************************************** LoadDocument ENTRY pea Watch jsr SetCursor PushPtr DumpFileName lda BuffPtr+2 ; menu space pha lda BuffPtr pha pea 0 pea $8000 jsr LoadFile bcs DoneLoading lda BuffPtr sta Pointer lda BuffPtr+2 sta Pointer+2 jsr ShowPainting DoneLoading pea Arrow jsr SetCursor rts END *===== * * Show painting * ShowPainting START _HideCursor phb ; save data bank pea $E1E1 plb ; set data bank to screen plb lda #($2000+12*160) sta Screen lda #160 sta FastWidth lda #188 sta FastHeight NextLine ldy FastWidth ; set y dey ; decrement y by 2, point at last word dey lda [Pointer],y ; get the source sta (Screen),y ; save it away dey dey NextWord lda [Pointer],y ; get the source sta (Screen),y ; save it to storage dey ; dock y dey ; dock it again bne NextWord ; if it isn't negative, do some more lda [Pointer] ; get left edge source sta (Screen) ; put the left edge dec FastHeight beq FinishUp lda Screen ; get the last screen position clc adc #160 ; increment by a scan line of bytes sta Screen ; save it for next time lda Pointer ; get the source pointer clc adc #160 sta Pointer ; save it for next time bcc NoBumpPtr inc Pointer+2 NoBumpPtr brl NextLine ; go do another one FinishUp plb ; restore data bank jsr BottomCorners _ShowCursor rts END ************************************************************** * * AboutBox * ************************************************************* AboutBox START using LibGlobals Height equ 122 Width equ 120 StartByte equ 20 StartLine equ 50 TextItems equ 12 * Initialize parameters for the About Box. pea $FBFF ; block out almost everything jsr SaveState PushLong ScreenRgn _SetClip  jsr HiLiteApple lda #Height ; number of scan lines in full menu sta MenuHeight lda #Width ; width of menu in bytes sta MenuWidth lda #(StartLine*160+StartByte) ; offset ($2000) to first pixel sta MenuStart ; in bytes jsr SaveScreen ; save out what's underneath stz FastFlags ; nothing fancy, just a standard window jsr DrawFastWindow ; let's draw a fast window pea 0 _SetForeColor pea 3 _SetBackColor lda #0 ; number of items to print TextLoop sta TextCtr asl A ; multiply by 8 asl A asl A tax lda TextTable+6,x pha lda TextTable+4,x pha lda TextTable+2,x pha lda TextTable,x pha _MoveTo _DrawString lda TextCtr ina ; decrement counter cmp #TextItems bmi TextLoop pea MouseUpEvent ; point mouse releases at us pea ClearAbout jsr SetHandler rts TextCtr ds 2 TextTable anop dc i2'61,90' dc i4'S1' dc i2'73,90' dc i4'S2' dc i2'85,90' dc i4'S3' dc i2'94,90' dc i4'S4' dc i2'103,90' dc i4'S5' dc i2'112,90' dc i4'S6' dc i2'121,90' dc i4'S7' dc i2'130,90' dc i4'S8' dc i2'139,90' dc i4'S9' dc i2'148,90' dc i4'S10' dc i2'157,90' dc i4'S11' dc i2'166,90' dc i4'S12' S1 dc i1'S2-S1-1' dc c'LW/Paint Copyright (C)' dc c' 1987 by Apple Computer' S2 dc i1'S3-S2-1' dc c' Version' dc c' 1.0 - January 31, 1987' S3 dc i1'S4-S3-1' dc c'LW/Paint is a paint program in the tradition of Bill Atkinson''s' S4 dc i1'S5-S4-1' dc c'MacPaint, written in order to test Quickdraw II and to provide a' S5 dc i1'S6-S5-1' dc c'tool for generation of 640 mode screens.' S6 dc i1'S7-S6-1' dc c' ' S7 dc i1'S8-S7-1' dc c'The toolkit can be toggled on and off with the space bar or by' S8 dc i1'S9-S8-1' dc c'clicking in the menu bar to the right of Options. If you click' S9 dc i1'S10-S9-1' dc c'there and drag, you can release in the color or tool of your' S10 dc i1'S11-S10-1' dc c'choice. The toolkit will then vanish. Save and Revert operate' S11 dc i1'S12-S11-1' dc c'on the file "Screen.0" in the current (prefix) directory.' S12 dc i1'S13-S12-1' dc c' ' S13 anop ClearAbout jsr RestoreScreen ; put the window back jsr RestoreState ; reset the current task jsr HiliteApple ; turn off the about box rts ; get out of here END ************************************************************** * * Desk Clock * ************************************************************* DeskClock START using LibGlobals ClockOn dc i2'0' ClockFlag dc i2'0' ClockX ds 2 ClockY ds 2 OldVector ds 4 TimeStr dc c'MM/DD/YY 12:00:00 am ' ClockInit ENTRY lda ClockOn beq NotOn jsr ClockShutdown NotOn plx ; pull return pla ; get Y sta ClockY ; save it pla ; get X sta ClockX ; save it phx ; push return back inc ClockOn ; we're here! jsr ShowClock ; draw us pea 0 ; space for result pea 0 pea $15 ; one second interrupt handler _GetVector pla ; get low word sta OldVector pla ; get high word sta OldVector+2 pea $15 ; one second interrupt handler PushPtr ClockInterrupt _SetVector ; set the vector pea $06 ; specify 1 second source _IntSource ; turn source on rts ClockInterrupt anop ; interrupts run in 8 bit mode longa off phb phk ; set our program bank plb inc ClockFlag ; bump our semaphore pea 0 ; set bank 0 plb plb lda #$02 tsb $C032 ; fiddle with interrupt stuff plb clc rtl longa on ClockUpdate ENTRY lda ClockOn bne ClockIsOn rts ClockIsOn lda ClockFlag bne ShowClock rts ShowClock anop PushPtr TimeStr _ReadAsciiTime lda TimeStr+8 and #$7F7F sta TimeStr+8 lda TimeStr+10 and #$7F7F sta TimeStr+10 lda TimeStr+12 and #$7F7F sta TimeStr+12 lda TimeStr+14 and #$7F7F sta TimeStr+14 lda TimeStr+16 and #$7F7F sta TimeStr+16 lda TimeStr+18 and #$7F7F * If it's two spaces ($2020) nothing happens, but if it's 'AM' or 'PM', then * it becomes 'am' or 'pm'. ora #$2020 sta TimeStr+18 BlankingEntry stz ClockFlag PushLong ScreenRgn _SetClip pea $0000 ; black text _SetForeColor pea $0003 ; white background _SetBackColor lda ClockX pha lda ClockY pha _MoveTo lda TimeStr+8 and #$FF00 ; remove space ora #$000F ; add in length, plus extra spaces sta TimeStr+8 PushLong #TimeStr+8 _DrawString rts ClockShutdown ENTRY pea $07 ; disable 1 second interrupt source _IntSource pea $15 ; 1 second interrupts PushLong OldVector ; push old vector _SetVector ; set it back where it was stz ClockOn ; shut down our own flag stz ClockFlag ; and make sure we're cool lda #$FFFF ; all white sta FastColor lda #(135+2*160) ; bytes to start sta FastStart lda #24 ; width sta FastWidth lda #8 ; height sta FastHeight jsr FastFill ; clear it rts ; go home END ************************************************************** * * SaveState/RestoreState * ************************************************************* SaveState START using LibGlobals plx ; get local return ply ; get event mask sty EventMask ; save this, too phx ; push return back ldx #0 SaveLoop tya ; get mask back lsr A ; look at the bottom bit tay ; update mask bcc DontSave ; if its not set, continue lda EventTable,x ; get the current event sta SavedEvent,x ; save it lda #NoEvent ; zero out the old one sta EventTable,x ; by setting it to a null return DontSave inx ; bump x to next entry inx cpx #32 ; are we done yet? bne SaveLoop ; if not, continue jsr NewRegion sta SaveClip stx SaveClip+2 PushLong SaveClip _GetClip rts SavedEvent dc 16i2'NoEvent' SaveClip ds 4 EventMask ds 2 RestoreState ENTRY ldy EventMask ; get event mask ldx #0 RestoreLoop tya ; get mask back lsr A ; look at the bottom bit tay ; update mask bcc DontRestore ; if its not set, continue lda SavedEvent,x ; get the current event sta EventTable,x ; save it lda #NoEvent ; zero out the old one sta SavedEvent,x ; by setting it to a null return DontRestore inx ; bump x to next entry inx cpx #32 ; are we done yet? bne RestoreLoop ; if not, continue PushLong SaveClip _SetClip MoveLong SaveClip,Handle ldx #Handle jsr UnlockHandle PushLong Handle _DisposeRgn rts END *===== * * FastDrag(SrcPtr,DstPtr,SrcLen,DstLen,FastWidth,FastHeight) * FastDrag START lda FastHeight beq Done bmi Done lda FastWidth dea bmi Done bne NotSingle bra Cut1 SingleLoop1 jsr BumpPtrs Cut1 lda [DstPtr] and #$FF00 sta Temp lda [SrcPtr] and #$00FF ora Temp sta [DstPtr]  dec FastHeight bne SingleLoop1 rts NotSingle lda SrcPtr+2 cmp DstPtr+2 bcc DstBigger bne SrcBigger lda SrcPtr cmp DstPtr bcc DstBigger bne SrcBigger Done rts ; all done! That was easy! SrcBigger lda SrcPtr+2 ; save for comparison with DstPtr sta Temp+2 lda SrcPtr sta Temp clc adc FastWidth sta SrcPtr bcs ND4 dec SrcPtr+2 ; because y will be very big ND4 lda DstPtr clc adc FastWidth sta DstPtr bcs ND5 dec DstPtr+2 ND5 lda FastWidth eor #$FFFF ina sta FastWidth bra Cut2 NextLine1 jsr BumpPtrs Cut2 ldy FastWidth tya ror A bcc NextWord1 lda [SrcPtr],y sta [DstPtr],y iny ; a single byte width blows up NextWord1 lda [SrcPtr],y sta [DstPtr],y iny iny bne NextWord1 dec FastHeight bne NextLine1 rts DstBigger pea 0 pei FastHeight pei SrcLen jsr Multiply pla clc adc SrcPtr sta SrcPtr bcc NB4 inc SrcPtr+2 NB4 pea 0 pei FastHeight pei DstLen jsr Multiply pla clc adc DstPtr sta DstPtr bcc NextLine2 inc DstPtr+2 NextLine2 lda SrcPtr sec sbc SrcLen sta SrcPtr bcs ND1 dec SrcPtr+2 ND1 lda DstPtr sec sbc DstLen sta DstPtr bcs ND2 dec DstPtr+2 ND2 ldy FastWidth dey dey tya ror A bcc NextWord2 lda [SrcPtr],y sta [DstPtr],y dey ; a single byte width blows up NextWord2 lda [SrcPtr],y sta [DstPtr],y dey dey bpl NextWord2 dec FastHeight bne NextLine2 rts BumpPtrs lda SrcPtr ; bump them even the first time clc adc SrcLen sta SrcPtr bcc NB1 inc SrcPtr+2 NB1 lda DstPtr clc adc DstLen sta DstPtr bcc NB2 inc DstPtr+2 NB2 rts END *===== * * UpdateRectRgn(Rect1,Rect2,USrcPtr,UDstPtr,SrcLen,DstLen) * UpdateRectRgn START lda Rect1 cmp Rect2+4 bpl DoItAll lda Rect1+2 cmp Rect2+6 bpl DoItAll lda Rect1+4 cmp Rect2 bmi DoItAll lda Rect1+6 cmp Rect2+2 bpl CheckTop DoItAll lda Rect1 sta UpdateRect lda Rect1+4 sta UpdateRect+4 Horizontal lda Rect1+2 sta UpdateRect+2 lda Rect1+6 sta UpdateRect+6 jsr UpdateIt rts CheckTop lda Rect1 cmp Rect2 bpl CheckLeft lda Rect1 sta UpDateRect lda Rect2 sta UpdateRect+4 jsr Horizontal CheckLeft lda Rect1+2 cmp Rect2+2 bpl CheckRight lda Rect1+2 sta UpdateRect+2 lda Rect2+2 sta UpdateRect+6 jsr Vertical CheckRight lda Rect2+6 cmp Rect1+6 bpl CheckBottom lda Rect2+6 sta UpdateRect+2 lda Rect1+6 sta UpdateRect+6 jsr Vertical CheckBottom lda Rect2+4 cmp Rect1+4 bpl DoneUpdate lda Rect2+4 sta UpdateRect lda Rect1+4 sta UpdateRect+4 jsr Horizontal DoneUpdate rts Vertical lda Rect1 cmp Rect2 bpl UseR1 lda Rect2 UseR1 sta UpdateRect lda Rect2+4 cmp Rect1+4 bmi UseR2 lda Rect1+4 UseR2 sta UpdateRect+4 UpdateIt lda UpdateRect+4 sec sbc UpdateRect sta FastHeight lda UpdateRect+2 lsr A lsr A sta Temp lda UpdateRect+6 lsr A lsr A sec sbc Temp sta FastWidth * Add in the distance to the top stz Temp stz Temp+2 lda UpdateRect sec sbc Rect1 beq TopEqual pha ; to save it pea 0 pha pei SrcLen jsr Multiply plx ; pull result pla ; pull saved operand phx ; save multiply result pea 0 pei DstLen pha jsr Multiply pla sta Temp+2 ; Distance to first line of UDst part pla sta Temp * Add in the distance to the right TopEqual lda Rect1+2 lsr A lsr A sta Temp+4 lda UpdateRect+2 lsr A lsr A sec sbc Temp+4 sta Temp+4 ; save it, we'll need it again clc adc Temp ; add in beginning of USrc line clc adc USrcPtr sta SrcPtr lda USrcPtr+2 bcc NB1 ina NB1 sta SrcPtr+2 lda Temp+4 ; get it back clc adc Temp+2 ; add in beginning of UDst line clc adc UDstPtr sta DstPtr lda UDstPtr+2 bcc NB2 ina NB2 sta DstPtr+2 jsr FastDrag rts END ******************************************************************* * * * Version 1.0 * * January 31, 1987 * * * * (c) Copyright 1986, 1987 Apple Computer, Inc. * * * * All rights reserved.    * * * * This program and its derivatives are licensed only for * * use on Apple computers. * * * * Works based on this program must contain and * * conspicuously display this notice. * * * * This software is provided for your evaluation and to * * assist you in developing software for the Apple IIGS * * computer. * * * * This is not a distribution license. Distribution of * * this and other Apple software requires a separate * * license. Contact the Software Licensing Department of * * Apple Computer, Inc. for details. * * * * DISCLAIMER OF WARRANTY * * * * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT * * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, * * WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS * * FOR ANY PARTICULAR PURPOSE. THE ENTIRE RISK AS TO * * THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH * * YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND * * NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE) * * ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING, * * REPAIR OR CORRECTION. * * * * Apple does not warrant that the functions * * contained in the Software will meet your requirements * * or that the operation of the Software will be * * uninterrupted or error free or that defects in the * * Software will be corrected. * * * * SOME STATES DO NOT ALLOW THE EXCLUSION * * OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY * * NOT APPLY TO YOU. THIS WARRANTY GIVES YOU SPECIFIC * * LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS * * WHICH VARY FROM STATE TO STATE. * * * ******************************************************************* * LIST OFF GEN off SYMBOL off KEEP paint 65816 on *===== * ZeroPage space (and initial program branch) * mcopy paint.mac ZeroPage START jmp Paint copy lib.equ copy lib.ref dc r'DoGoodies' ; because Demo doesn't use it SrcPtr gequ FastSrc DstPtr gequ FastDst SrcLen gequ FastSLen DstLen gequ FastDLen Rect1 gequ CtrlY1 Rect2 gequ FastTitle UpdateRect gequ RsrcPtr USrcPtr gequ FastColor UDstPtr gequ CtrlFound UpdateLen gequ RsrcMax END *===== * * PaintGlobals * PaintGlobals DATA using LibGlobals using RsrcData StdPortPtr ds 4 PaintPort ds 170 ; size of a port, by latest listing PaintTool dc i2'42' ; pencil for starters PaintCursor dc i2'Pencil' ; likewise PaintPen dc i2'1,2' PaintFColor dc i2'0' PaintBColor dc i2'$FFFF' FillPatPtr dc i4'StdRed' BackPatPtr dc i4'StdWhite' LinePatPtr dc i4'StdBlack' MaskPatPtr dc i4'Dither50' PaintRect dc i2'12,0,200,640' ; clipping rect for the screen PaintRgn ds 4 UndoHandle ds 4 UndoPtr ds 4 UndoRect dc i2'0,0,0,0' ChangeRect dc i2'0,0,0,0' ChangeFlag dc i2'0' NormalRect ds 8 UpdateRgn ds 4 Clicked dc i2'0' ClickOptions dc i2'0' Y1 ds 2 X1 ds 2 Y2 ds 2 X2 ds 2 PencilRight dc i2'638' ; VGC dependency is FIXED!!! BrushSize dc i2'9,22' HalfBrush dc i2'4,10' BrushX ds 2 BrushY ds 2 SparkleState dc i2'0' Sparkling dc i2'0' FullSparkler dc i2'0' InSparkle dc i2'0' XConstraint dc i2'-1' YConstraint dc i2'-1' SourceRect ds 8 SparkleRect dc i2'0,0,0,0' SparklePat dc 2i2'$0F0F' dc 2i2'$F0F0' dc 2i2'$0F0F' dc 2i2'$F0F0' dc 2i2'$0F0F' dc 2i2'$F0F0' dc 2i2'$0F0F' dc 2i2'$F0F0' AllWhiteMask dc 4i2'$FFFF' Dither50 dc 4i2'$AA55' PaintTitle anop dc i1'PaintTEnd-PaintTitle-1' dc c' Paint ' PaintTEnd anop AppleKey equ $0100 FunctionKey equ $0800 ControlKey equ $1000 ShiftKey equ $0200 KitHeight gequ 44 KitWidth gequ 156 KitLine gequ 16 KitByte gequ 2 KitTop gequ 16 KitLeft gequ 8 KitBottom gequ 60 KitRight gequ 632 KitHandle ds 4 KitPtr ds 4 KitActive dc i2'0' ColorRect dc i2'20,290,30,318' ColorFrame dc i2'19,288,31,320' MaskRect dc i2'20,338,30,366' MaskFrame dc i2'19,336,31,368' IconRect1 dc i2'0,320,11,350' ; tool IconRect2 dc i2'0,352,11,382' ; fill color IconRect3 dc i2'0,384,11,414' ; line color IconRect4 dc i2'0,416,11,446' ; background color IconRect5 dc i2'0,448,11,478' ; mask END copy pmenu.asm copy pmenus.asm copy tools.asm copy sparkle.asm copy rsrc.asm copy doc.asm copy pdesk.asm copy fastdrag.asm *===== * * Paint * Paint START using LibGlobals using PaintGlobals jsr OpenLibrary pea Arrow jsr SetCursor jsr DrawScreen _ShowCursor jsr InitPaint jsr EventManager ; main event loop where all happens jsr PaintCleanup lda ClockToggle ; turn off 1 second interrupts beq ClockOkay jsr ClockShutdown ClockOkay jsr CloseLibrary ; close the library brk $F0 ; we don't return (_PQuit) END *===== * * InitPaint - initializes ports and other variables * InitPaint START using LibGlobals using PaintGlobals lda #PaintEvents sta StdEvents pea 0 pea 0 _GetPort pla sta StdPortPtr pla sta StdPortPtr+2 PushPtr PaintPort _OpenPort PushPtr PaintRect _SetPortRect jsr setstandards ;set up right colors jsr NewRegion sta PaintRgn stx PaintRgn+2 PushLong BackgrndRgn PushLong PaintRgn _CopyRgn PushLong PaintRgn _SetClip PushLong PaintPen _PenSize PushWord PaintFColor _SetForeColor PushWord PaintBColor _SetBackColor PushLong FillPatPtr _PenPat PushPtr BackPatPtr _BackPat PushLong StdPortPtr _SetPort jsr LoadDocument ldx #Handle lda #$8000 jsr GetNewHandle sta UndoPtr stx UndoPtr+2 lda Handle sta UndoHandle lda Handle+2 sta UndoHandle+2 jsr NewRegion sta UpdateRgn stx UpdateRgn+2 lda PaintRect sta UndoRect lda PaintRect+2 sta UndoRect+2 lda PaintRect+4 sta UndoRect+4 lda PaintRect+6 sta UndoRect+6 jsr FixUndo jsr LoadToolkit PaintEvents ENTRY pea NullEvent ; static event handler pea PaintTask jsr SetHandler pea MouseDownEvent pea PaintClick jsr SetHandler stz Clicked pea MouseUpEvent pea NoEvent jsr SetHandler pea KeyDownEvent pea PaintKeys jsr SetHandler rts END *===== * * PaintCleanup * PaintCleanup START using PaintGlobals using RsrcData PushPtr PaintPort _ClosePort PushLong UpdateRgn _DisposeRgn lda KitHandle sta Handle lda KitHandle+2 sta Handle+2 ldx #Handle jsr UnlockHandle PushLong Handle _DisposHandle lda UndoHandle sta Handle lda UndoHandle+2 sta Handle+2 ldx #Handle jsr UnlockHandle PushLong Handle _DisposHandle rts END *===== * * PaintTask * PaintTask START jsr CheckTool pea KeyDownEvent ; key handler pea PaintKeys jsr SetHandler rts ; nothing else for the nonce END *===== * * PaintClick * PaintClick START using LibGlobals using PaintGlobals using RsrcData lda MousePos+4 sta ClickOptions jsr CheckTool ; carry set if in paintrect bcc NotATool jsr StartTool rts NotATool jsr MenuClick bcc NotAMenu rts NotAMenu PushPtr KitRsrc pea TrackMsg jsr MsgResource pea MouseDownEvent ; mouse downs pea PaintClick jsr SetHandler ; back in business rts END *===== * * MenuClick * MenuClick START using LibGlobals using PaintGlobals using RsrcData lda MousePos ; get y coordinate cmp #12 ; was it in menu bar bmi MenuHit ; go see if the user wants it clc rts MenuHit lda MousePos+2 cmp #320 bmi NotTooling jsr SwitchToolkit lda KitActive beq MH1 pea MouseUpEvent pea Tooler jsr SetHandler pea NullEvent pea NoEvent jsr SetHandler pea KeyDownEvent pea NoEvent jsr SetHandler MH1 sec rts NotTooling pea MouseDownEvent pea NoEvent jsr SetHandler pea MouseUpEvent pea MenuRelease jsr SetHandler pea KeyDownEvent pea NoEvent jsr SetHandler pea NullEvent pea TrackMenu ; in the library jsr SetHandler sec ; we've got it rts Tooler lda MousePos cmp #12 bpl MH2 jsr RestoreEvents rts MH2 PushPtr KitRsrc pea TrackMsg jsr MsgResource jsr SwitchToolKit jsr RestoreEvents rts END *===== * * MenuRelease * MenuRelease START using LibGlobals using PaintGlobals pea 0 jsr ReleaseMenu jsr PaintEvents ; restore default events pla ; get result tay ; save it xba ; swap the bytes and #$00FF ; clear away the item number asl A ; make it a word offset tax tya ; get the item number back and #$00FF ; clear away the menu number jsr (MenuTable,x) rts MenuTable dc i2'NoEvent' dc i2'AppleMenu' dc i2'FileMenu' dc i2'EditMenu' dc i2'GoodiesMenu' dc i2'OptionsMenu' *===== * * Apple menu * MyFirstSCB equ $E19D00 AppleMenu cmp #1 bne TryClock jsr AboutBox rts TryClock cmp #2 ; is it the Alarm Clock bne TryColorPanel lda ClockToggle beq TurnClockOn jsr ClockShutdown stz ClockToggle rts TurnClockOn pea 544 ; x value for display pea 9 ; y value for display jsr ClockInit lda #1 sta ClockToggle rts TryColorPanel cmp #3 bne TryModeSwitch jsr ColorPanel rts TryModeSwitch cmp #4 bne Done lda MyFirstScb and #$00FF eor #$80 pha pha _SetAllSCBs pla and #$80 beq ModeIs320 pei (MyColorTable) ; do this first so it looks good PushPtr OldTable ; it was read from battery ram _SetColorTable Done rts ModeIs320 jsr Synthesize pei (MyColorTable) PushPtr Table320 _SetColorTable rts Table320 dc i2'0,0,0,$0999,0,0,0,0,0,0,0,0,$0777,0,0,$FFFF' Synthesize lda OldTable+2 jsr Disemble lda Temp sta Table320+8 ; entry 4 sta Table320+10 ; 5 sta Table320+12 ; 6 lda Temp+2 sta Table320+14 ; 7 lda OldTable+4 jsr Disemble lda Temp sta Table320+16 sta Table320+18 sta Table320+20 lda Temp+2 sta Table320+22 lda OldTable+10 jsr Disemble lda Temp+2 sta Table320+26 lda Temp sta Table320+2 ldx Table320+10 jsr Combine sta Table320+10 lda Temp ldx Table320+18 jsr Combine sta Table320+18 lda OldTable+12 jsr Disemble lda Temp+2 sta Table320+28 lda Temp sta Table320+4 ldx Table320+12 jsr Combine sta Table320+12 lda Temp ldx Table320+20 jsr Combine sta Table320+20 rts Disemble tay and #$0F00 clc adc #$0100 lsr A and #$0F00 sta Temp tya and #$00F0 clc adc #$0010 lsr A and #$00F0 ora Temp sta Temp tya and #$000F ina lsr A and #$000F ora Temp sta Temp tya and #$0F00 eor #$0F00 lsr A and #$0F00 eor #$0F00 sta Temp+2 tya and #$00F0 eor #$00F0 lsr A and #$00F0 eor #$00F0 ora Temp+2 sta Temp+2 tya and #$000F eor #$000F lsr A and #$000F eor #$000F ora Temp+2 sta Temp+2 rts Combine tay and #$0F00 sta Temp+4 MACRO &lab _QTStartup &lab ldx #$0220 jsl $E10000 MEND MACRO &lab _QTShutdown &lab ldx #$0320 jsl $E10000 MEND MACRO &lab _InitMenus &lab ldx #$0A20 jsl $E10000 MEND MACRO &lab _DisposeMenu &lab ldx #$0E20 jsl $E10000 MEND MACRO &lab _MenuResource &lab ldx #$1A20 jsl $E10000 MEND MACRO &lab _SetHandler &lab ldx #$1220 jsl $E10000 MEND MACRO &lab _EventHandler &lab ldx #$1320 jsl $E10000 MEND MACRO &lab _Signal &lab ldx #$1720 jsl $E10000 MEND MACRO &lab _InitEvents &lab ldx #$1820  !jsl $E10000 MEND MACRO &lab PushPtr &TheLabel &lab dc i1'$F4' dc i'&TheLabel|-16' dc i1'$F4' dc i'&TheLabel' MEND MACRO &LAB PUSHWORD &WHATTOPUSH LCLC &CHAR &CHAR AMID &WHATTOPUSH,1,1 AIF "&CHAR"="#",.IMMEDIATE &LAB LDA &WHATTOPUSH PHA MEXIT .IMMEDIATE &CHAR AMID &WHATTOPUSH,2,100 &LAB DC I1'$F4' DC I2'&CHAR' MEND MACRO &LAB PUSHLONG &WHATTOPUSH LCLC &CHAR &CHAR AMID &WHATTOPUSH,1,1 AIF "&CHAR"="#",.IMMEDIATE &LAB LDA &WHATTOPUSH+2 PHA LDA &WHATTOPUSH PHA MEXIT .IMMEDIATE &CHAR AMID &WHATTOPUSH,2,100 &LAB DC I1'$F4' DC I2'(&CHAR)|-16' DC I1'$F4' DC I2'&CHAR' MEND MACRO &lab ShadowOFF &lab anop AIF S:LONGA=1,.A php lda #%00011110 sta >$E0C035 plp MEXIT .A php sep #$30 longa off lda #%00011110 sta >$E0C035 longa on plp MEND MACRO &lab _TLStartup &lab ldx #$0201 jsl $E10000 MEND MACRO &lab _TLShutdown &lab ldx #$0301 jsl $E10000 MEND MACRO &lab _MMStartup &lab ldx #$0202 jsl $E10000 MEND MACRO &lab _MMShutDown &lab ldx #$0302 jsl $E10000 MEND MACRO &lab _ShowCursor &lab ldx #4+256*145 jsl $E10000 MEND MACRO &lab _SetPortRect &lab ldx #4+256*31 jsl $E10000 MEND MACRO &lab MoveLong &From,&To &lab lda &From sta &To lda &From+2 sta &To+2 MEND MACRO &lab _DisposHandle &lab ldx #$1002 jsl $E10000 MEND MACRO &lab _OpenPort &lab ldx #4+256*24 jsl $E10000 MEND MACRO &lab _ClosePort &lab ldx #4+256*26 jsl $E10000 MEND MACRO &lab _SetPort &lab ldx #4+256*27 jsl $E10000 MEND MACRO &lab _GetPort &lab ldx #4+256*28 jsl $E10000 MEND MACRO &lab _SetClip &lab ldx #4+256*36 jsl $E10000 MEND MACRO &lab _MoveTo &lab ldx #4+256*58 jsl $E10000 MEND MACRO &lab _LineTo &lab ldx #4+256*60 jsl $E10000 MEND MACRO &lab _FrameRect &lab ldx #4+256*83 jsl $E10000 MEND MACRO &lab _PaintRect &lab ldx #4+256*84 jsl $E10000 MEND MACRO &lab _DisposeRgn &lab ldx #4+256*104 jsl $E10000 MEND MACRO &lab _CopyRgn &lab ldx #4+256*105 jsl $E10000 MEND MACRO &lab _HideCursor &lab ldx #4+256*144 jsl $E10000 MEND MACRO &lab _SetForeColor &lab ldx #4+256*160 jsl $E10000 MEND MACRO &lab _SetBackColor &lab ldx #4+256*162 jsl $E10000 MEND MACRO &lab _DrawString &lab ldx #4+256*165 jsl $E10000 MEND MACRO &lab _PenSize &lab ldx #4+256*44 jsl $E10000 MEND MACRO &lab _PenPat &lab ldx #4+256*48 jsl $E10000 MEND MACRO &lab _BackPat &lab ldx #4+256*52 jsl $E10000 MEND MACRO &lab _PenMode &lab ldx #4+256*46 jsl $E10000 MEND MACRO &lab _FrameOval &lab ldx #4+256*88 jsl $E10000 MEND MACRO &lab _PaintOval &lab ldx #4+256*89 jsl $E10000 MEND MACRO &lab _FrameRRect &lab ldx #4+256*93 jsl $E10000 MEND MACRO &lab _PaintRRect &lab ldx #4+256*94 jsl $E10000 MEND MACRO &lab _ReadAsciiTime &lab ldx #$0F03 jsl $E10000 MEND MACRO &lab _SetVector &lab ldx #$1003 jsl $E10000 MEND MACRO &lab _GetVector &lab ldx #$1103 jsl $E10000 MEND MACRO &lab _IntSource &lab ldx #$2303 jsl $E10000 MEND MACRO &lab _GetClip &lab ldx #4+256*37 jsl $E10000 MEND MACRO &lab _SetAllSCBs &lab ldx #4+256*20 jsl $E10000 MEND MACRO &lab _SetColorTable &lab ldx #4+256*14 jsl $E10000 MEND MACRO &lab _SetPenMask &lab ldx #4+256*50 jsl $E10000 MEND MACRO &lab _SelectCursor &lab ldx #$0920 jsl $E10000 MEND MACRO &lab _FixRatio &lab ldx #$0E0B jsl $E10000 MEND MACRO &lab _GetNextEvent &lab ldx #6+256*10 jsl $E10000 MEND MACRO &lab ErrorDeath &text &lab bcc end&syscnt pea 0 pea 0 pha ldx #$2A0B jsl $E10000 pla sta >y&syscnt pla sta >y&syscnt+2 pea x&syscnt|-16 pea x&syscnt ldx #$200C jsl $E10000 brk $F0 x&syscnt dc c"&text" dc c' Error was $' y&syscnt ds 4 dc i1'13,10,0' end&syscnt anop mend MACRO &lab _LoadTools &lab ldx #$0E01 jsl $E10000 MEND MACRO &lab _NewHandle &lab ldx #$0902 jsl $E10000 MEND MACRO &lab _QUIT ¶ms &lab jsl $E100A8 dc i2"$29" dc i4"¶ms" MEND MACRO &lab _QTBuffer &lab ldx #$1B20 jsl $E10000 MEND MACRO &lab _PaintPixels &lab ldx #4+256*127 jsl $E10000 MEND MACRO &lab _SetTextMode &lab ldx #4+256*156 jsl $E10000 MEND MACRO &lab _SetPrefix &Params &lab jsl $E100A8 dc i2"$09" dc i4"&Params" MEND MACRO &lab _GetPrefix &Params &lab jsl $E100A8 dc i2"$0A" dc i4"&Params" MEND MACRO &lab PushFPtr &ThePtr,&TheField &lab lda &ThePtr clc adc &TheField tax lda &ThePtr+2 adc #0 pha phx MEND keep paint link/all paint link lib.a echo "Assembling lib..." assemble lib echo "Assembling Paint..." assemble paint.asm echo "Linking Paint and Lib..." alink paint.lnk echo "Paint built." echo "Assembling lib..." assemble lib echo "Assembling Demo..." assemble demo.asm echo "Linking Demo and Lib..." alink demo.lnk echo "Demo built." T@n ,@ L5 ;*@@(A] ~  UUUU Paint "> @RnPp@ ^` ~   ` tGdf<< : K6:")"n:H"` : <> : KD :"6"m> : KD+:">"> : KD6:"D"DA:"I" #> : KDL:"T")> : KDW:"f"Db:"m"M8> : KDm:"{"ᩍ>> : KDx:""n:H"` :< >@ K`New...Open...CloseSave Save as...Save a copy as...Revert Page Setup...Print...Quit<9NLRl2n L TL xT VM <<<"<*<2<""t:""t :""> : Kt+:""Y> : Kt6:""9> : KtA:""#> : Kn:H"` :<>@ K`UndoCutCopyPasteClear : K :" "ᩆ> : K+:" "f> : K6:" "F> : KA:" "&#> : KL:" "*> : KW:" "0> : Kb:"# "7> : Km:"1 "ᩦ>> : Kx:"> "ᩆE> : Kn:H"` :<%>@ K`GridFatbitsSet Font Edit Pattern Edit Mask Edit Angles Custom Brush Custom Bucket Custom LassoCustom Spatula<9N(LR7l_n L TL  <<<"<*<"":" "᩸> : K :" "ᩘ> : K+:" "x> : K6:" "X> : KA:" "8#> : Kn:H"` :<7>@ K`InvertFillFlip Horizontal Flip VerticalRotate:H:H$" tGsuoqw (,NL RB N ] E>:"> <"^:"^ <"~:"~ <":" <":" <":" <" HH0"T"HH0"T"HH0"T"@0"T"`"w( _*)<+)+)Dsu<,:* w1*) *<+) <++) +DwIw V"`e搥e:`<h)I "h)" A(A"h)I " e""he" +(+&"(&0"HH"w ()F)y&u(wHH0"T" &q(sHH0"T"K&(HH0"T"#h)I "h)" ,,`k ]HH0"`h) "h)" ͱ`: su@0"T"- ": :$:: ::&  " ]`8 ;I`8;I`;0B=;050w;0< ;0x0.H G8` G`;-01ح;/03< G8`;;       ""`0`"wH (  h ("`H Gh"JJe""i "8mJJ"iJJ8">>>>>>>>>>>>>>>㍍؍؍؍؍؍؍؍،ȌȌȌȌȌȌȌȜɜɜɜɜɜɜɜLLLLLLLLLLLLLLLL{{{{{{{{{{{{{{{{kkkkkkkkkkkkkkkkjjjjjjjjjjjjjjjjggvvggvvggvvggvvggvvggvvggvvggvv66cc66cc66cc66cc66cc66cc66cc66ccEETTEETTEETTEETTEETTEETTEETTEETT&&bb&&bb&&bb&&bb&&bb&&bb&&bb&&bb________________nnnnnnnnnnnnnnnn................>>>>>>>>>>>>>>>>㍍؍؍؍؍؍؍؍،ȌȌȌȌȌȌȌȜɜɜɜɜɜɜɜLLLLLLLLLLLLLLLL{{{{{{{{{{{{{{{{kkkkkkkkkkkkkkkkjjjjjjjjjjjjjjjjggvvggvvggvvggvvggvvggvvggvvggvv66cc66cc66cc66cc66cc66cc66cc66ccEETTEETTEETTEETTEETTEETTEETTEETT&&bb&&bb&&bb&&bb&&bb&&bb&&bb&&bb________________kkkkkkkkkkkkkkkkjjjjjjjjjjjjjjjjggvvggvvggvvggvvggvvggvvggvvggvv66cc66cc66cc66cc66cc66cc66cc66ccEETTEETTEETTEETTEETTEETTEETTEETT&&bb&&bb&&bb&&bb&&bb&&bb&&bb&&bb________________****+!+A+a+++A)a)))))*!*A*a*(!(A(a((((()!)&&'!'A'a''''' ${,-UUUU""""""""DDDDDDDD333333333333333333333333,,,,,,,,,,,,{,,,, G"ᩀ'df<: YV :<<<e:᫫-fHdH m G"`SCREEN.0 G-fHdH m df - G`"᫫'\<:<\\\:\i\i qO"` $3:H:H$" zNxLTR LdB N"". .H.H.H.H:"". 01 b`=Z8/IZ/UZ/^Z0gZX0pZ0yZ0Z0Z1Z@1Z1Z1MLW/Paint Copyright (C) 1987 by Apple ComputerP by Art Cabral Version 1.0A1 - January 31, 1987?LW/Paint is a paint program in the tradition of Bill Atkinson's@MacPaint, written in order to test Quickdraw II and to provide a(tool for generation of 640 mode screens. >The toolkit can be toggled on and off with the space bar or by?clicking in the menu bar to the right of Options. If you click<: K`z3ڢJ ;^3b; G~333H~3H%"`bbbbbbbbbbbbbbbb3J ^3;b^3 譀3H~3H$"~33 :GHHh"`:301<:0, 4)")":`ŖL ŔD`$"e<Ɛe<Ɩx>?  ????  J  DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUffffffffffffffffffffffffffffffffwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww""""""""""""""""""""""""""""""""33333333333333333333333333333333(AHAhAA@@@A(@H@h@@???@005(K"LH *"hFBhHB(B "_TLStartup failed. Error was $ "LH *"hBhBB "_MMStartup failed. Error was $ h E"LH *"hBhBB "_MTStartup failed. Error was $  EH "bH *"h{Ch}CGC "_NewHandle failed fetching 6 zero pages. Error was $ ;[[ h hh E iHH" iH "᫢)04) 40 O O<"ᩀHH"" QP rc?"X0NLRB Nd<:"E" F0 iHH" E"LH *"hDhDD "_LoadTools failed. Error was $ ;\^\i\d@ K\\:>i@> K\\:>i@> K\\:>i@> K\\`Ri!\\\à@\\à\\ \\\\B\\\"\<\\!) >!@!) @!!) !") ""ᯀ) ) ^) ^`) "`a:;B;0`<<<<<<<<iھP<<0` :;a0`ھP>o>oos9t $4DTdt5G8L*d8t*d8*d8* e8*e8*emL,0emt,;em,Fem,Wem,bem,meThg StandardsLhg Set DeskTophjQuit4 k > ?l27i Color Panel:;|gg:H:H$" NLR LB N"" E," Uk:;0"4gT" E4gS"&g<<<< eg dfgghh&h6hFhVhfhvhhhg ]#i ] lj bk bb bj b`;,g00g;.g0 2g G` G` [j e df`;). Jm` Wd j`H<"h"lg ng< )"<<<"` M&g:;0"0;H.;Hz" fc ` [jd(g*gg ]`Bk bb b`k bb b` E,gT"Us\^k i(kk kikkkk|gkH)JJJ:\ȗ\)\h) :\ȗ\)\kпkШkЋ`h "hڅ$Je"|g$)H)xg#*g (g`(g*gg)"|g)"*g`(g) xg|gg)I)zg#*g (g`(g*gg)"|g)"*g`(g) zg|ggJJJJ)H E{iHƄƆƆT"|g0" >K/D2DIILI`KpTsTKffmmK{{K n:,K<LTLVM <<<"<*<2<  !K14HKX[oKKn:K<LTL < < < "< *< 2< :< B< J< R<A D X Kh k  K   K   K   K   K+  .  B KR # U # i Ky 1 | 1  K >  >  K n: KQ <m Lp TLs y <| < < "< *<   K   K   K ! 5 KE H \ K_ n: K : : tG s u o q w ( N   ] E           @@0w5_?ISZ]sbuwwwV A%AD+I+NQfjuwz(}uwqs "D,GJ,MQkTkZ]]a:su@@ "$& "  ]l o;;;;w;;GG;-1;/3<G ;; !$(.147: ?B GNQ TZ]fknqvyw((G "YV-0369<?BFwK(NVY;\_behlo;ru x{~bb(A(A""""""  }""W"""" &-4>BX\kr~ ;;jyy: &(=,047;:?DGLQVY\;_dilpuz};;  ;;;;6 ; ;6; ; ) ;6>LA;DG;J MQ\ `z}  ;;6X` N"q(* .2869<?DGLPSX [^hknruUxU   !L.;14;7 :>ILL6ORUY\pt , ,  ,(,7 AEPS],ad~ , ,; -1;/3 #;), /25:=B-EH/KN1QT3WZ*_deg-jm/ps1vy3|55J ;;; ;!; ; ;#; $;'+ 3;JM;S;V \;`f/inr/y3  3;--11J-1/3 !!#$;(--11;:1D#G-N-Y1\#_;c/h3l;u3#!//#3!-%/'1)3+#!-/1 3"%*2:GKWZ`cfk55--cegciecGe G:3=BG4KNcQTeWZg]`isw!{1AQey  ! 1 A U e u    l - !=e!M!](Aq(Au@(A(A@(A(A@"m"" # u#- #= %$M (Aa }$q $ -% % % 5&&?& &&&)+*+*+*+*+++!++A++a++++++A)+a)+)+)+)+),*,!* ,A* ,a*,(,!(,A(,a(!,(%,(),(-,(1,)5,!)9,&=,&A,'E,!'I,A'M,a'Q,'U,'Y,'],'u,{,y,-,,,,-,-, -,-,-,-,-,-,#-,'-,+-{,/-,3-,7-,?-Gi-YV-----m-G-G-----m---GN.qO\.$3_.:c.:n..L.N.............1.b.8/././.0.X0/0 /0/0/1$/@1,/14/11M13111121111112U22121262"262:21J21P21V21Y21c21i21l21r21u21{21~212121212121212:2:212121212121212131 31!3K'3333;63^393b<3;F3GI3~3L33O33S3~3^3b`3bb3bd3bf3bh3bj3bl3bn3bp3br3bt3bv3bx3bz3b|3b333^33;3b3^3333~33~3333:G34.44P4Gd4G4<5445(55(5%54e5Gq5G535A5G5J555!c565<525;E565;555556 6G6660;6.;6 6+6/6:6>6I6T6_6c6n6q6{666-6tG66666G666666666666 6K76b6X76b66b6b6A:6b66777o7q7:G.737;7:GL7R7A:U7bY7;\7_7d7Eh77n7q7w7]}7X77b7;7;7(7w777b7b7b7b7b7b7b777b7b7b767b7;7fc777]7(7fc8Y86888b8$88985: 8?:"8@:*8X.38<882;8<E81K8<T8Cix8<{8<8888888<8-9888888888<8-9888888888<8-98888888988989998 9< 9-99898989998$98'99*9899w9(9;-9(999w:(:- :(:::::: :#:&:):2:;;:bB:H:;S:(\:_:bb:::;b;b;b;b;b;b;b;b;b;b;b;b;b;b;b;b;b<<<=<><?A(AAHAAhAAAA@A@A@AAA(@AH@Ah@A@A?A?A?A@BFBBHBB(BB(BiBBnBBrBBuBBB EBBBBBBBB C E0C{C5C}C9CGCJFAJh:EJf:PJj:[Jl:fJn:rJ2JuJ;xJ;JHJHJ;J;J<J;J2IJ2IJ2IJQPJ:J:JqJJ0;J.;K:K: K:K:K0;K.;"K2;%K2;/K.;2K;5K0;8K;;KG>K.;AK0;DK:HK:LK;PK;TK0;XK.;cK;gK;rK2JuK:yK:K IK IKJKKKKKKKKKK%LL\LL%MLMKMKMKNKNTLNMNVMNMNNO:;OB;O<O<O<O<O<O<O<O<PP P< P<)P:;?PPBP<UP:;P O7VV9ViW;V6Z=V\?Vf\AV\CV]EVV^GV^^IVf^KVf^MVaOVsaQVaSVAbUVbWVbVGVYVV;V;VPVPVQVIQ3WVRWV_W'VeW'VtWWzWQW$XWGWQWQXYVX?R XYVc;Fc;Qc;Wc;\c;ac;gc;oc;-dN3dECdcFdcddddddddddddddddd<dgded<dhded<dhdee<e< e< e heee<e0hee e<#e@h&ee)e<,e<1e<4ePh7eel*gDl(gKlxgNl|gQlg^lzgcl*ghl(gnl(gql*gtlg|l|gl*gl(glzgl|glglEl|gl|gl/pro/demo/listings/lib.list echo "Assembling Paint..." assemble +l +s paint.asm >/pro/demo/listings/paint.list echo "Linking Paint and Lib..." alink paint.lnk echo "Paint built." echo "Assembling lib..." assemble +l +s lib >/pro/demo/listings/lib.list echo "Assembling Demo..." assemble +l +s demo.asm >/pro/demo/listings/demo.list echo "Linking Demo and Lib..." alink demo.lnk echo "Demo built." ]e]]mmmV^e]]mm]]]]]]n]]]]]em]feeffm]f]ef]ff]eefV]e]m]]]f^e]m]]efeefeeef]ffmef]fff]f]fefmf]feff]ffffffme]feemmmmV]]n]^e]mmee]mmf]f]ffef]ff]fmfefmfefmfffefmfeff]feffff]ffmmffV^m]mn^^]mn]^e mmmm]]em]m]f]ff]ef]f]efmf]f]ff]fffefffffeffffff]f]mfeemen]mm]ne]]mm]mmmf]emem]ff]efffmffefefmfef]feffffffmffffeffeffeefV^m^m]]mmne]m]]mmefm]efemff]eeef]ef]f]fefffmffffffff]ffffmff]ff]]mfem]m]ememnemem]mm]fm^fmf]f]memffmffmf]f^feffff]feff]ffff]ffffmfff]e]efmne]]mefmfmmfef]f]mmfmeffmffefmfff]ff]feffffffffmffmmefme]m]nVne]mmm]em]e]ee]ff]f]fmfmf]fmfeffmffff]fmf]feffffffeffffm]]^ff^me]m]n^]nemm]me]ef^effmf]f]f]f]ff]f]feffmfVfmfmfmfefeffff]ffefffmeeefme]emmm^ene]]me]em]e]^ef]mf]f]fefff]fmfffnfefefmfmfmffffff]ff]fm]m]^ff^^me]em^enem]]]efmmmf]mf]f]ffmefeeff]fffffefmfmffmfffefeffeffff]fefmme]mfnVnemmmmm]fmefe]mmf]f]ef]fmf]fmfmfefVf]fffefmff]fffmffmff]ffeefmnffV^]e]Vmfemmmm]e]e^m^ef]]fmeef]fef^f]ffff]fnfeffVfeffnff]ffff]ffffeffemm]fnmmeemnVfem^]mm]]eef^mmVmeef]fmfffefmfnfmfffff^feff^ffffffffeff]ffm]]]enff^]f^]]emm^]m]m^m^mefenefef]ffmeef]f]ffffff]fnffffVfffffeff]ffmfffmfff]fnnnnmmmfmm]emm]m]mef]feffef]ef]fmfmffefVfmfffmfnffffffefffmfefffff]ff]eemfnff]fm]emm]m^me^mne]f]]ff]effVf]fef]fefefffefefffffmffff]ffmffmfff]fff]eem]mfffVVV^^]mVVmen]m]m]efeVmmff]effef]ffVf]fffffff]ffffnfffefffffffffffmem]f]ffeeemmmmfVmen]]^mee^mfVmffemff]meefmffmfffefff]ffff]ffffVfffmffmff]ffffffeeemfmeVfVVfVVmen]mmmm^]eee^feeff]meff]fmfffffffmffff]ffffffff]ff]ffeffeffffffem]e]]efefnn^V]fn]nmen]mmm^]meVmff]mffef]f]mmffff]fefffmffefffmfffffffffeff]ffefff]fffeemfmffVfVmnmm]neen]n^]^^nmeenmef]ff]f]fmfnffeff]fffffffffmfffffffeffmffeffefffmffffmeenfemfffnVfemeefnVmV^ffVfmf]]f]f^fVffmfmefff]fff]fffmfffffffmffffffmfffeffff]fffe^ee]^fffen^VfeefV]mmmmnmeef]nfe]mf]f^fff^f^fmffeffmfffefffffff]ffmffmfffmffffffffffffmefefVemfeffffen^^feffVVVVVVVVVfeeffmmf^fVffffffffVffefffefffffffff]fffff]ffff]ffffmffffeff]efVm^e^ffffVmmfffVeeeffffmmf^feffefnfmffnfff]fffeffffffmffeffmfff]fff]ffff]fffffff]f]ef]f]fffVffen^ffVmmmnnfVVVfmVf^emf^ffffnfVffffffmffefffffff^ff]fffffffffmffffffff]ffff]fmfmeff]efnfffffVf^fVfen^]nVVeeffenfnfefVffffffffefffffeffffffffffffff]ffffffefffeffffmfffff]fmemeefneVffffn^fmf^fen^^VefVfff]ffefefVefffffff^ffffffffffffffffffmffeffeffffffffmffffefffffmfefeeffV]efffffemfef^feVnVefnfmfff^efVfffffffefffffVffffffffffffff]ffefff]ffffffffffffffffmf^feefeffffffefef^fenefffffffff^ffVfffffffnfffffnfff^fffffffffffeffmfffmfffeffffffffff]fffffnfVfefmfefffffVfnfefmfnffff^ffVnffffffffffffffefff^ffffffffffffffmfffeffffmffff]fffffeffffffmf]fmefnfefmf^ffffffVfnfmfn^efffffeffffffffffffnffffffff^ffffffffffmfff]ffffffff]ffffmfffffffffffeffffffVef]ffffffnfVnfnfVffffffffeffffffffffffffffffffffffffffܝfff]fffffffeffffefffffmffffffff]fefmffffVff]fefffffeffffnfefffffnfffffffffffffffffffffffffffffmffhfff]ffffmffffffffffeffffff]ffffff]fmffff^ffffffffffnfffffffffefffffffffffffffffffffffffffeԌf͌fffmffff]ffff]fffff]ffffffmfmffffffeff]f]fmfffnffefffffVffffenfffffffffffffffffffffffffffffff]ffhHHffffffffmfffffmffffffm]ffffffffffffmff]ffffffnffeffffffnfffVfVffffffffffffffffffffffffffffeffe܌d Ffmffffmfffffffffffef]fmf]mefffffeffffff^fefmffffffnfffffefffffffffffffffffffffffffffffff]ffmhHfffefffffmfffffffffffffeffffffmfff]ffffffffffeffmffVfmfVffffffffffffffeffffffffffffffffffffffffmffmfffm̌ ̝fffffeffffff]ffffffff]fffff]ffffmffffffffffeff]ffeffffff]ffffffffffffVfffnfffffffffffffffffffffffffmfffef`fd ffffffmffffffffmfffffffffmffeffmffffVffffffffffffffVfffffffffffffffffffmfff]ffflfffff`l ffmfffffffffffffffffffffffffffffffffe.ffffffffffmffeffffffffffffffffffffffffffffffffffffffff]ffffhffHfh ̀ffffffffffffffffffffffffeffnfbffnffffffffffffffefffffefffffffffffffffffffffffffffffnfffffffffflffLffl fffffffffffffffffffff]fffeffeneތn.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffHH ffffffffmfffffffff]fffebBffmffffffffffffffffffffff]fffffffffffffffffffffffffffffffffffffffd ffffffffffffffffmffdfffLh.dfffffffffffffffffffffffffffffffffffffffffffffffffffffffff Ȉ؈fffffffffffffffffffm]lɁHbȦffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffl ̀ HLfffffffffffffffffffffffffffeffffnldnL,Jeffffmfffmffffffffffffffffffffffffffffffffffffffffffffffffffffffh  Ȅffffffffffffffffffffffeeffbݎfȍfdffmffffffffffffffffffffffffffffffffffffffffffffffffffffffd@ @  ̀ LfFffffffffffffffffffffffffffe 숦. Ȏff,fffffffeffa&ffe ȑȈࠀffffee&ffa&fffe  . ,&RfafQfaffffffQfffaffffffafe&afRfa&ffffe&fff  n숐,&ee&fa%&!ffff" b숑- fffefQffffVff&ffe&ffe n-   - &fffa&&faffV&affa  fefQe QefeRQ&afQ &Qfa&QfRffRQUfQfaQ&ae      !afQaaQ%Q Q&%QQ%a&&e%  aQaaQQ   n%&%%%aQaQQ .na%e  n aQ%%-.a QQQQ-am Q%%n&n^  nmb  . -b- . -Z - 0 lш0.m-,h 0.l h̀0- ́8ȃ-n.   %m Ȍ ̌n    n ̘8 Ȉ0 n  3 8 ȈÈ3̈Ȁ0..Б Ȉ<Ȉ80.̉  ȁȈ03É0.nБ̍ <8 03. Ɂ ȀȀЈ8 0̈30 8؃ 30n  ȀȀ 0ɀ30ȑȌȌ̀00 <30. Ȉ03 < 30ð. Ȑ3̰ 30<<b   ȉ Ѓ ȁ080.<<ȁ   Ȁ38<-  0Ɉ;3  3 8;8 &33  3308?   3Ȑ<333 83 < ̃ 3   ΈȀ918?38< < 3;3  0Ȁ<< 38< 33-- ȁɀ3̀0838<30 03 <8030.188 138 .А 0  <?183< . 8Ȍ03 3 0<;1030 80 <3 <1<Ȍ 38 130   80 000 309033 0 8 8 0 0301 Љ 0=033     00 < 3 3 3<033   800̌ Ȍ<<<3 3 31 <333<   8000 0ȌȈ30 а310330 0303Ã< 30 83333  3̈8003 ` Ȱ3103  0880;3< 130