# HG changeset patch # User boisy # Date 1032707198 0 # Node ID 5d138adbc9fe9e514c805f3fdd9052d204161ada # Parent 2cf4b593cebfd922919ddb79ece4fce0096ae75c Adding gshell to Multi-Vue diff -r 2cf4b593cebf -r 5d138adbc9fe 3rdparty/packages/multivue/cmds_6809/gshell.asm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/multivue/cmds_6809/gshell.asm Sun Sep 22 15:06:38 2002 +0000 @@ -0,0 +1,8062 @@ +* Signal handlers will have to handle new RBF call for directory updates +* DIR has to be open (uses path #), but can be in READ+DIR mode +* Renames, etc. will have to close DIR 1st, do function, re-open. + + nam GShell Graphics Shell + ttl Source derived by Kent D. Meyers. + +* Compressed Version. Started February 7, 1988. Completed February 29. +* Upgraded Version. Started March 2, 1988. Finished by KDM Feb 13, 1994 +* NITROS9 ONLY VERSION. Started August 8,1998 by LCB +* NOTE: When GSHPAL added, got rid of DEVICSET, and 2 other SETS from env.file +* check in DP (3 DP bytes back) +* NOTE: HAVE TRIED 5 ROWS OF ICONS (ICONYMAX=143, ICONROWH=32, ICONSCR=20), & +* IT FITS, BUT LOOKS REALLY CROWDED +* Killed all calls to F.SLEEP, embedded (shorter & faster) +* Should do F$CpyMem of <$40-43 in direct page to get real RAM size - both +* 6809 and NitrOS9. Then we can eliminate RAM= from the Env.fil entirely! + +* NOTE (6309 ONLY): ALL STD -2,S TO CHECK THE D FLAG CAN BE CHANGED TO TSTD +*(SAME SIZE, FASTER) + +BTEXT mod MODSIZE,MODNAME,$11,$81,CSTART,DATASIZE + +* COMPLETE DEFS FOR THIS ASSEMBLY. + +ICNONSCR equ 16 # icons on screen in 40 column mode + +* System call defs +F$FORK equ $03 +F$WAIT equ $04 +F$CHAIN equ $05 +F$EXIT equ $06 +F$MEM equ $07 +F$SEND equ $08 +F$ICPT equ $09 +F$SLEEP equ $0A +F$ID equ $0C +F$GPRDSC equ $18 +F$UNLOAD equ $1D +F$NMLINK equ $21 +F$NMLOAD equ $22 +I$DUP equ $82 +I$OPEN equ $84 +I$MAKDIR equ $85 +I$CHGDIR equ $86 +I$DELETE equ $87 +I$READ equ $89 +I$WRITE equ $8A +I$READLN equ $8B +I$WRITLN equ $8C +I$GETSTT equ $8D +I$SETSTT equ $8E +I$CLOSE equ $8F + +* Standard character defs +NUL equ $00 +BEL equ $07 +HT equ $09 +LF equ $0A +FF equ $0C +CR equ $0D +SPACE equ $20 + +* Standard RBF access mode defs +READ. equ $0001 +UPDAT. equ $0003 +EXEC. equ $0004 +PREAD. equ $0008 +PEXEC. equ $0020 +DIR. equ $0080 + +* Standard condition code register defs +CARRY equ $0001 +NCARRY equ $00FE + +* Error message defs +E$MEMFUL equ $00CF +E$EOF equ $00D3 +E$PNNF equ $00D8 + +* GShell specific Data Structures. + + org 0 +* File info - linked list for each icon +FL.XSTRT rmb 2 X start position of icon \ These are for determining if +FL.YSTRT rmb 2 Y start position of icon \ mouse clicks are on a particular +FL.XEND rmb 2 X end position of icon / icon or not. +FL.YEND rmb 2 Y end position of icon / +FL.ICONO rmb 1 Icon type (IC.*) +FL.AIFNO rmb 1 AIF # (entry # to look in ID.* table) +FL.LINK rmb 2 Link to next FL.* entry +FL.FNAME rmb 2 Ptr to filename +FL.SIZE equ . + + org 0 +* Structure for table entries for executable programs to fork into new +* windows - called process tables here (see PTBL* vars) +GD.MNAME rmb 2 Module name ptr? +GD.INDVC rmb 2 ??? Ptr to ? +GD.PRCID rmb 2 Process ID # for new process +GD.STATS rmb 2 Last status of forked program (errors, etc.) +GD.MTYPE rmb 1 Module type +GD.MLANG rmb 1 Module language +GD.MEMSZ rmb 2 Mem size required +GD.WPATH rmb 2 Path to window +GD.DW.OW rmb 2 Process running in overlay window flag: 1=Yes, else NO +GD.XSTRT rmb 2 Start X,Y coords of window +GD.YSTRT rmb 2 +GD.XEND rmb 2 End X,Y coords of window +GD.YEND rmb 2 +GD.SCRNO rmb 2 Screen # +GD.LINK rmb 2 Link to next GD.* entry +GD.SIZE equ . + +* Defs for table entries of AIF data +* NOTE: all ID.NUMBR's below IC.XTRNL ($14) are for internal AIF structures, +* not from actual read in AIF files ($f-$13 are currently unused?) + org 0 +ID.NUMBR rmb 2 Entry # in ID.* structure (only 2nd byte is used) +ID.WTYPE rmb 2 Window type for AIF program +ID.XSIZE rmb 2 Minimum window X size for AIF program +ID.YSIZE rmb 2 Minimum window Y size for AIF program +ID.FRGND rmb 2 Window foreground color for AIF program +ID.BKGND rmb 2 Window background color for AIF program +ID.MEMSZ rmb 2 Data area size for AIF program +ID.MNAME rmb 2 Ptr to module name for AIF program +ID.XXXPT rmb 2 ??? Ptr to AIF 3 letter extension? +ID.PARAM rmb 2 Ptr to parameters for AIF program +ID.LINK rmb 2 Ptr to next ID.* structure in linked list +ID.SIZE equ . + +* Structure for screens used table (maximum of 8) + org 0 +SC.PTHNO rmb 1 Path number to screen +SC.WTYPE rmb 1 Full screen background window type +SC.USERS rmb 1 # of users (programs) active on screen + rmb 1 ??? reserved space? +SC.SIZE equ . + +* Icon descriptor identifiers (reserved ones). For programs, they will have +* there own entry for running in a new window (?) +* These are stored in Fl.ICONO +* NOTE: WE SHOULD ADD A PRINTER ICON, AND HAVE IT CALL THE FILE/PRINT ROUTINE +* ALSO, A NEW VERSION OF COCOPR SHOULD BE WRITTEN TO HANDLE GRAPHIC SCREEN +* DUMPS OF VEF'S. IT SHOULD ALSO ALLOW -F (FORMFEED AFTER TRAILER) AS AN +* OPTION FROM THE ENV.FILE +IC.TEXT equ $0001 Text file identifier +IC.FOLDR equ $0002 Folder (directory) identifier +IC.PRGRM equ $0003 Program (executable) identifier +IC.CLOSE equ $0004 Close box +IC.DRIVE equ $0005 Drive icon +IC.AIF.F equ $0006 ??? AIF for a single program +IC.F.XXX equ $0007 ??? AIF for an extension already allocated +IC.DRBAR equ $0008 Drive bar (top of current dir window) +IC.TRASH equ $0009 Trash can (delete from file menu) +IC.GCALC equ $000A Calculator off of Tandy menu +IC.GCLOK equ $000B Clock off of Tandy menu +IC.GCAL equ $000C Calendar off of Tandy menu +IC.SHELL equ $000D Shell off of Tandy menu +IC.QUERY equ $000E '?' Help off of Tandy menu +IC.PRNTR equ $000F Printer (print from file menu) +* Looks like we have room to insert 5 entries here... like PRINTER +IC.XTRNL equ $0014 Start of external entries (from AIF files) + +* Menu ID #'s +MID.CLS equ $0002 +MID.SUP equ $0004 +MID.SDN equ $0005 +MID.SRT equ $0006 +MID.SLT equ $0007 +MID.TDY equ $0014 +MID.FIL equ $0017 +MID.VEW equ $0018 +MID.DSK equ $0019 +MID.KDM equ $001A + +* Mouse packet variables (see manual) +PT.VALID equ $0000 +PT.CBSA equ $0008 +PT.CBSB equ $0009 +PT.STAT equ $0016 +PT.ACX equ $0018 +PT.ACY equ $001A +PT.WRX equ $001C +PT.WRY equ $001E + +*Get/Setstat calls +SS.READY equ $0001 +SS.SSIG equ $001A +SS.RELEA equ $001B +SS.FDINF equ $0020 +SS.SCSIZ equ $0026 +SS.FSIG equ $002C Signal on dir change Setstat +SS.WNSET equ $0086 +SS.MNSEL equ $0087 +SS.SBAR equ $0088 +SS.MOUSE equ $0089 +SS.MSSIG equ $008A +SS.SCTYP equ $0093 +SS.UMBAR equ $0095 + +STDOUT equ $0001 +STDERR equ $0002 + +OBJCT equ $0001 +ICODE equ $0002 +PCODE equ $0003 +CBLCODE equ $0005 + +WT.FSWIN equ $0002 +WT.DBOX equ $0004 +WN.NMNS equ $0014 +WN.SYNC equ $0017 +WN.BAR equ $0020 +WINSYNC equ $C0C0 + +S$WAKE equ $0001 +S$ABORT equ $0002 +S$INTRPT equ $0003 +DIR.FD equ $001D +DIR.SZ equ $0020 + +PTR.ARR equ $0001 +FNT.S8X8 equ $0001 +FNT.S6X8 equ $0002 +FNT.G8X8 equ $0003 +PTR.SLP equ $0004 +PTR.ILL equ $0005 +MOUSIGNL equ $000A +KYBDSGNL equ $000B +DIRSIG equ $000C New signal for SS.FSig +MI.SIZ equ $0015 +MI.ENBL equ $000F +MN.ENBL equ $0012 +MN.SIZ equ $0017 +WN.SIZ equ $0022 +GRP.FNT equ $00C8 +GRP.PTR equ $00CA + +* OS-9 DATA AREA DEFINITIONS + + org 0 +WIPED rmb 1 Icons wiped flag (0=no need to redraw) +DEFWTYPE rmb 2 GShell's current window type (default for GCalc, GClock, etc.) +ICONCOLW rmb 2 Width of icon column. (in pixels) +STRTYPOS rmb 2 Starting Y position for the first icon on screen. +ICONYMAX rmb 2 Maximum Y value for displayed icons. +ICONROWH rmb 2 Height of icon row. (in pixels) +WINDWSZY rmb 2 Y size of GShell window path. +PTBLNEXT rmb 2 Pointer to next available process descriptor link. +FNAMEPTR rmb 2 Pointer to file name buffer. (null terminated) +IDSCSPTR rmb 2 Pointer to start of icon descriptor table. +IDSCNEXT rmb 2 Pointer to next available icon descriptor link +DEVICNTR rmb 1 Current device count. (maximum 5) +DRIVYPOS rmb 1 Starting Y position for first drive icon. + +* The preceding are loaded at startup with default values. + +STRTXPOS rmb 2 Starting X position for the first icon on screen. +PIXELSWD rmb 2 Width of GShell window in pixels. +FLAG640W rmb 1 640 pixels wide flag +RECDSGNL rmb 2 Current received signal from intercept routine. +MAXICONS rmb 2 Maximum number of icons per screen. (12/24) +RAMSIZE rmb 2 Computer's memory size. (128/512) +WNDWPATH rmb 2 GShell window I/O path number. +WINDWSZX rmb 2 X size of GShell window path. +PRCIDNUM rmb 2 GShell process ID number. (for GPLOAD) +SCREENOW rmb 2 Number of current display icon screen. (0 to n-1) +NSCREENS rmb 2 Number of available icon screens. +STRTICON rmb 2 Pointer to file icon descriptor for first icon on current screen. +FILESCTR rmb 2 Number of files in current data directory. +FTBLSPTR rmb 2 Pointer to start of file icon descriptor table. +FTBLNEXT rmb 2 Pointer to next available link in file icon descriptor table. +SELECTED rmb 2 Pointer to file icon descriptor for currently selected icon. +DEVICNOW rmb 2 Pointer to file icon descriptor for currently selected drive. +PTBLSPTR rmb 2 Pointer to start of process descriptor table. +DIRPTR rmb 2 Pointer to next directory entry in directory read buffer. +XFD.ATT rmb 1 Buffer for FD.ATT (attributes) of current directory entry. +NEXTXPOS rmb 2 Next X position for file icon on this screen. +NEXTYPOS rmb 4 Next Y position for file icon on this screen. +ACTVSCRN rmb 2 Number of the active process screen. (for window setup) +PROCXSIZ rmb 2 Minimum X size for this process. +PROCYSIZ rmb 2 Minimum Y size for this process. +PROCWTYP rmb 2 Default window type for this process. +WPOSGOOD rmb 2 Window OK flag. (for window setup) +DWSETSTY rmb 2 Actual STY byte for process window. (for window setup) + +* Additions to handle GSHPALx=r,g,b commands (removed *SET ones) +CURPAL rmb 1 Current GSHPAL palette # being worked on +CURCOLOR rmb 1 Current palette value +CURGFXSZ rmb 1 Size of GFXBUF to write for GSHPAL values +GIPMSRES rmb 1 0=low res, 1=high res, $ff=not set (default=0) +GIPMSPRT rmb 1 1=right, 2=left, $ff=not set (default=1) +GIPKYST rmb 1 keyboard repeat start ($ff=not set) +GIPKYSPD rmb 1 keyboard repeat speed ($ff=not set) +DRTBLPTR rmb 2 Pointer to start of drive table. +SUREYPOS rmb 2 Y position for "Sure" box. +SUREXPOS rmb 1 X position for "Sure" box. +BXOFFSET rmb 2 X size for selection box. +WD48FLAG rmb 1 $80 if on type 7 windown. +TNDYITMS rmb MI.SIZ*8 Tandy Menu items array. + +DISKITMS rmb 0 Disk Menu items array. +ITM.FREE rmb MI.SIZ Free +ITM.FLDR rmb MI.SIZ Folder +ITM.FMAT rmb MI.SIZ*4 Format + +FILSITMS rmb 0 Files menu items array. +ITM.OPEN rmb MI.SIZ Open +ITM.LIST rmb MI.SIZ List +ITM.COPY rmb MI.SIZ Copy +ITM.STAT rmb MI.SIZ Stat +ITM.PRNT rmb MI.SIZ Print +ITM.RNAM rmb MI.SIZ Rename +ITM.DELT rmb MI.SIZ Delete +ITM.SORT rmb MI.SIZ*2 Sort + +VIEWITMS rmb 0 View Menu items array. +ITM.LRES rmb MI.SIZ*3 Low Res 4 Color + +KDMITMS rmb MI.SIZ*2 KDM Menu items array. + +TNDYDESC rmb MN.SIZ Tandy Menu descriptor. +FILSDESC rmb MN.SIZ Files Menu descriptor. +DISKDESC rmb MN.SIZ Disk Menu descriptor. +VIEWDESC rmb MN.SIZ View Menu descriptor. +KDMDESC rmb MN.SIZ KDM Menu descriptor. + +SHELLNAM rmb 6 "shell" +LISTNAM rmb 5 "list" +GCALCNAM rmb 6 "gcalc" +GCLOCKNM rmb 7 "gclock" +GCALNAM rmb 5 "gcal" +CONTRLNM rmb 8 "control" +GPRINTNM rmb 7 "gprint" +GPORTNAM rmb 6 "gport" +HELPNAM rmb 5 "help" +COCPRNM rmb 7 "cocopr" + +DBOXDESC rmb FL.SIZE Directory Close Box descriptor. (file icon descriptor format) +DBARDESC rmb FL.SIZE Directory Bar descriptor. (file icon descriptor format) +QURYDESC rmb FL.SIZE ? descriptor. (file icon descriptor format) +TRSHDESC rmb FL.SIZE Trash Can descriptor. (file icon descriptor format) +PRTRDESC rmb FL.SIZE Printer descriptor (file icon descriptor format) + +CALCDESC rmb ID.SIZE Icon descriptor for gcalc. +CLOKDESC rmb ID.SIZE icon descriptor for gclock +CALDESC rmb ID.SIZE icon descriptor for gcal. +SHELDESC rmb ID.LINK icon descriptor for shell. +ENDLINK rmb 2 Terminating link for internal icon descriptors. +NXTICONO rmb 2 Next available external icon number. +PRESSMSG rmb 14 "press any key" +NEWNMSG rmb 18 "new name:" +SLASHW rmb 3 "/w" +ALLOCP rmb 3 "C" Variable. +STTOP rmb 2 "C" Variable. +MEMEND rmb 10 "C" Variable. 1st 2 is current upper boundary of data memory +MTOP rmb 2 "C" Variable. +STBOT rmb 2 "C" Variable. +ERRNO rmb 2 "C" Variable. +WINDDESC rmb WN.SIZ GShell window descriptor. +DDIRNAME rmb 256 Full path name to current data directory. +XDIRNAME rmb 256 Full path name to current execution directory. +MOUSPCKT rmb 32 Mouse packet buffer. +FNAMBUFR rmb 30 File name (null terminated) for file icon descriptor setup. +DIRBUFER rmb 2048 Read buffer for current directory information. +ICONBUFR rmb 144 Icon read/build buffer. (for GPLOAD) +MULTIBFR rmb 256 Shared buffer. +LINEBUFR rmb 80 80 character line input buffer. +ASCIINUM rmb 8 ASCII number from binary/ASCII conversion routine. +ASCIITMP rmb 8 Binary/ASCII temp buffer. (reversed) +PARMSBFR rmb 256 Command/parameters build build buffer. +AIFNMBFR rmb 8 AIF.xxx file name build buffer. +DNAMBUFR rmb 32 Directory name input buffer. +SCRNTABL rmb SC.SIZE*8 Process screen table. +ENVFLBFR rmb 80 80 character line buffer for ENV.FILE input. +GFXBUF2 rmb 4 Graphics command build buffer. (small) +SSOPTBFR rmb 34 Buffer for SS.OPT information. +DRIVETBL rmb FL.SIZE*5 Device/Drive table. +DRVNMTBL rmb 32*5 Device/Drive name table. +BASE rmb 4 "C" Variable. +SPARE rmb 2 "C" Variable. +GFXBUF rmb 16 Graphics command build buffer. (large) +* Added for mode changing palette support +GSHBUF rmb 16 GSHPAL0 to 3 display code buffer. +DIRPATH rmb 1 Path # to current dir. (added for dir monitoring) +Dirup rmb 1 Copy of signal code (if it was new DIR signal) +RenFlag rmb 1 Flag used by rename - whether to reset DIRSIG or not +SIGN rmb 1 "C" Variable. +HANDLER rmb 2 "C" Variable. +END rmb 896 "C" Variable. +DATASIZE equ . + +MODNAME fcs "gshell" + fcb 2 + +* Will change to not bother preserving U, assume data area always @ 0 +CSTART pshs Y Save ptr to end of parm area + pshs U Save ptr to start of data area + clr ,-s Init all of direct page to 0's + ldw #256 + tfm s,u+ + leas 1,s Eat 0 byte + ldx ,S Get ptr to start of data area again + leau ,X Point U to it again + leax END,X Point to End of GSHELL data area + pshs X Save it + leay ETEXT,PC Point to a table of initialized data (includes screen height) + ldw ,y++ Get size of data block + tfm y+,u+ Block copy initialized data + ldu 2,S Get ptr to start of data area again + leau MEMEND Save as end of data memory ptr + leay ,U Point Y to start of data area + bsr MAIN Call main GSHELL routine + clrd No error & exit + std ,--s + lbra EXIT + +* Signal intercept trap +SAVESGNL clra Save signal as D & return + std RECDSGNL,U + cmpb #DIRSIG Dir update signal? + bne DoneSig + stb Dirup,u Save copy (in case in middle of dir update, or stuck elsewhere) +DoneSig rti + +MAIN pshs U,y Save U + lbsr SETUPENV Setup drive tables, and read in ENV.FIL stuff + puls y + leax ERRNO Save 16 bit error # + lda #UPDAT. Attempt to open path to 'w/' + ldx #SLASHW + lbsr I.OPEN D=path for window +DoneFix std + std WINDDESC+WN.SYNC,Y + leax 128k RAM? + bne FINLINIX Yes, skip ahead + clr VIEWDESC+MN.ENBL No, disable the view menu (only allow 16k 320x200x4) + clr ITM.FMAT+MI.ENBL Disable the FORMAT command + lda WNDWPATH+1 Get window path + ldb #SS.UMBAR Update the menu bar (to enforce above changes) + os9 I$SETSTT + +FINLINIX lbsr STDICONS Preload built in icons (regular & expanded for some) + lbsr MOUSENOW Turn on auto-follow mouse + rts + +* Shut cursor & scaling off +CURSCLOF clrd + pshs d + ldb 5,S + pshs d + lbsr SCALESW Shut scaling off + lbsr CURSROFF Shut cursor off + bra CURSCLOX + +* Clear out signal code, reset up Mouse/keyboard signals +* CHANGED: will copy Dirup signal flag to RECDSGNL +SETSGNLS clra Clear out last received signal + ldb Dirup Get Saved Dir updated signal (0 means none) + std RECDSGNL Clear or set saved DIR signal + ldb WNDWPATH+1 D=window path to receive mouse signal from + ldx #MOUSIGNL Mouse signal # + pshs d,X Save for routine call (both only s/b 8 bit) + lbsr ST.RELEA Release the mouse signal + lbsr ST.MSSIG Set the mouse signal + inc 3,S Bump up signal number (to keyboard signal) + lbsr ST.SSIG Set keyboard signal +CURSCLOX leas 4,S Eat temp stack & return + rts + +GSHSTART pshs U Preserve U + leas -3,S Make room on stack + ldu #MOUSPCKT Point to mouse packet buffer + lbsr INITSCRN +WAITLOOP bsr SETSGNLS Set signals for keyboard & mouse + ldd RECDSGNL Get signal + bne SGNLRECD Got one, process it + pshs d Preserve 0 + lbsr HNDLWAIT Go sleep, check for signals + std ,S++ Save child's signal code + bne SGNLRECD Got one, process as if local signal + bsr SETSGNLS Set signals again + ldx RECDSGNL Get any new signal + bne SGNLRECD Got one, process it + os9 F$SLEEP Sleep until signal received +SGNLRECD ldd RECDSGNL Get signal code (only need B portion) + subb #DIRSIG Dir update signal? + lbeq EQULSIGN Yes, go do + incb Keyboard signal? + lbeq CHKKEYBD yes, handle + incb Mouse signal? + bne WAITLOOP No, wait some more +* Mouse signal handling here +CHKMOUSE ldd WNDWPATH Get window path + pshs d,U + lbsr GT.MOUSE Get mouse packet + leas 4,S + ldb PT.VALID,U Mouse on current window? + beq WAITLOOP No, continue waiting + ldb PT.CBSA,U Is button A pressed? + beq WAITLOOP No, continue waiting + ldb PT.STAT,U Is mouse in control region or off window? + bne CHEKMENU Yes, go check if menu select made + pshs U + lbsr CHEKSCRN No, check if user selected something not on menu bar +SLCTRTRN leas 2,S Eat stack, poll keyboard/mouse + bra WAITLOOP + +CHEKMENU lda WNDWPATH+1 Get window path + ldb #SS.MNSEL Menu select call + os9 I$GETSTT Do call (ignore errors... original does) +* Error code added to see if we get errors when GSHELL "freezes" + bcc NoError + os9 F$EXIT +NoError cmpa #MID.CLS Close box? + beq CLOSEBOX + cmpa #MID.SUP Scroll up arrow? + beq SCRLLUPL + cmpa #MID.SLT Scroll left arrow? + beq SCRLLUPL + cmpa #MID.SDN Scroll down arrow? + beq SCRLLDNR + cmpa #MID.SRT Scroll right arrow? + beq SCRLLDNR + cmpa #MID.TDY Tandy menu? + beq TNDYMENU + cmpa #MID.FIL File menu? + beq FILEMENU + cmpa #MID.DSK Disk menu? + beq DISKMENU + cmpa #MID.VEW View menu? + beq VIEWMENU +WAITRTRN bra WAITLOOP Continue waiting (About.. menu will never return item) + +* Called by hitting 'q' or clicking on close box +CLOSEBOX lbsr SUREQUIT Do 'are you sure' box + bra WAITRTRN Obviously hit 'no', continue + +SCRLLUPL ldd DEVICNOW Drive selected? + beq WAITRTRN No, continue polling keyboard/mouse + lbsr SCRLLUP1 Scroll up on current drive + bra WAITRTRN Continue polling keyboard/mouse + +SCRLLDNR ldd DEVICNOW If drive selected, scroll down + beq WAITRTRN continue polling keyboard/mouse + lbsr SCRLLDN1 + bra WAITRTRN + +* Entry for all 4 ????MENU calls is B=item # selected +TNDYMENU clra + pshs d + lbsr TNDYSLCT Go handle Tandy menu + bra SLCTRTRN Eat stack, continue polling + +FILEMENU clra + pshs d + lbsr FILESLCT Do File menu + bra SLCTRTRN Eat stack, continue polling + +DISKMENU clra + pshs d + lbsr DISKSLCT Do Disk menu + bra SLCTRTRN Eat stack, continue polling + +VIEWMENU clra + pshs d + lbsr VIEWSLCT Do View menu + bra SLCTRTRN Eat stack, continue polling + +* Poll keyboard +CHKKEYBD ldd #1 1 byte length/std in? + pshs d + leax 2,S Point to 1 byte buffer + ldd WNDWPATH Get window path + pshs d,X + lbsr I.READ Read key + leas 6,S + std -2,S save byte + ble WAITRTN2 No key(?), continue polling + ldb ,S Get key press + cmpb #'= + beq EQULSIGN '=' - go refresh current drive/dir selection + cmpb #'$ + beq DOLRSIGN '$' - go set up new resizable shell window + cmpb #28 (Pageup) + beq SCRLLUPL Scroll up current dir + cmpb #26 (PageDown) + beq SCRLLDNR Scroll down current dir + cmpb #63 '?' - call Help routine + beq ICONQUR1 + andb #$5F + cmpb #'Q 'Q'uit Gshell + beq CLOSEBOX + cmpb #'S 'S'ame screen overlay shell + beq LETTERS + ldd WNDWPATH Illegal key, beep at user + pshs d + lbsr RINGBELL + leas 2,S + bra WAITRTN2 Continue polling + +* Resizable shell +DOLRSIGN ldb #IC.SHELL We want the structure for the SHELL entry + pshs d + lbsr FNDIDESC (Returns D=ptr to proper ID structure) - may change screen type + std ,S Save ptr + ldd #1 ? Save flag that we want a double box window for the program + pshs d + ldx #SHELLNAM Point to shell name for F$Fork + pshs X + lbsr EXCICOND Execute shell in resizable window + leas 6,S + bra WAITRTN2 + +* Refresh current drive/dir (NEW RBF CALL, IF FULLY WORKING, MAY OBSOLETE THIS +* ROUTINE FROM BEING CALLED BY A KEYPRESS) +EQULSIGN ldd DEVICNOW If no drive selected, don't bother + beq WAITRTN2 + lbsr DONEWDIR Go refresh current drive stuff +WAITRTN2 lbra WAITLOOP + +* Same screen overlay shell +LETTERS clrd + pshs d + pshs d No parameter for calling program + incb + pshs d Flag that we want overlay window to run in + ldx #SHELLNAM Point to 'shell' + pshs X + lbsr EXECPRGM Execute program in overlay window (MAYBE ALLOW RESIZE?) + leas 8,S + bra WAITRTN2 Continue polling after shell exited + +* Printer click +ICONPRTR ldd SELECTED Is there a file/dir selected? + beq ICONTRS1 No, don't do printer + ldb #5 Print menu item # from FILES menu + std ,S + lbsr FILESLCT + bra ICONTRS1 + +* Trash can click +ICONTRSH ldd SELECTED Is there a file/dir selected? + beq ICONTRS1 No, don't do trash stuff + ldb #10 Trash delete option from FILES menu structure (no sure prompt) + std ,S + lbsr FILESLCT +ICONTRS1 lbra ICONEXIT + +* ? in upper right corner - hot key +ICONQUR1 pshs d Just so it exits properly + ldb #7 + pshs d + lbsr TNDYSLCT + bra WAITRTN2 + +ICONQURY ldb #7 '?' selected, call 'Help' (menu item 7) from Tandy menu + pshs d + lbsr TNDYSLCT + lbra ICONEXT1 + +* Not menu bar selection, try other stuff on screen +CHEKSCRN pshs U + ldd 8-4,S + pshs d,X + lbsr ISITICON Check if drive or icon + tfr D,U + stu -2,S Set CC based on ptr to icon info + lbeq DSLCTALL Empty spot clicked, clear any currently highlighted stuff + ldb FL.ICONO,U Get selected icon buffer # + cmpb #IC.TRASH Is it the trash can? + beq ICONTRSH Yes, go handle + cmpb #IC.PRNTR Is it the printer? + beq ICONPRTR Yes, go do it + cmpb #IC.QUERY Is it the question mark? + beq ICONQURY Yes, go do help + lbsr ENBLSOFF Disable any menu items that deal with specific file + ldb #1 + std ,S + ldd SELECTED Get current selected icon + beq CHEKSCR2 None, skip ahead + cmpu SELECTED Same as previously selected icon? + bne CHEKSCR1 No, unselect previous icon + inc 1,S + bra CHEKSCR2 + +CHEKSCR1 pshs d Unselect previously selected icon + lbsr UNSLICON + leas 2,S +CHEKSCR2 stu SELECTED Save newly selected icon + ldb FL.ICONO,U Get icon # (also type?) + decb + lbeq ICONTEXT 1=Text file icon + decb + beq ICONFLDR 2=Folder (dir) icon + decb + lbeq ICONPRGM 3=Program (executable) icon + decb + beq ICONCLOS 4=Close box for current device title bar + decb + beq ICONDRIV 5=Disk drive icon + decb + lbeq ICONAIF 6=AIF file icon + decb + lbeq ICON.XXX 7=file with extension already defined by AIF + decb + bne ICONEXT2 >8, exit icon check routine + ldd DEVICNOW 8=current device title bar (to refresh current dir) + beq ICONEXT2 + lbsr DONEWDIR Refresh current dir + bra ICONEXT2 + +* Select new drive icon +ICONDRIV ldd DEVICNOW Get current device + std 2,S + pshs d + lbsr UNSLICON Unselect current device + stu ,S + lbsr SELCICON Select new icon + ldd FL.FNAME,U Get ptr to drive name + std ,S + lbsr NEWDDIR Get new drive dir + std ,S++ + bne ICONDROK Legit, continue + pshs U + lbsr UNSLICON Bad dir, unselect drive + leas 2,S + clrd + std SELECTED Current device=none + ldd 2,S Did user have a different drive selected before? + beq ICONEXT2 No, exit + pshs d + lbsr SELCICON Re-select the old drive instead +ICONEXT1 leas 2,S +ICONEXT2 lbra ICONEXIT + +* User selected new, legitimate drive +ICONDROK ldb #1 Enable menu items flag + pshs d + lbsr ENFREFLD Enable drive specific menu items (NOT FILE ONES!) + leas 2,S + stu DEVICNOW Save new current device + bra ICONEXT2 + +* Selected current path close box (go up a directory) +ICONCLOS lbsr PARENTDR Change to parent directory or drive + bra ICONEXT2 + +* Selected a folder (directory) +ICONFLDR ldd ,S ??? Get # times mouse clicked + decb + beq ONECLIKF Once, skip ahead + ldd FL.FNAME,U Twice, get ptr to folder name + pshs d + lbsr OPENFLDR Open the folder & return + bra ICONEXT1 + +ONECLIKF pshs U + lbsr SELCICON Highlight (select) the folder + ldb #1 + std ,S + lbsr ENBLOPEN Enable OPEN item on files menu + lbsr ENSTRNDL Enable STAT, RENAME & DELETE on files menu + bra ICONEXT1 Exit + +* Text file icon selected +ICONTEXT ldb #1 Enable LIST & PRINT on Files menu + pshs d + lbsr ENLSTPRT + ldd 2,S Get # of mouse clicks + decb + bne TWOCLIKT double click, skip ahead + stu ,S Select the icon + lbsr SELCICON + bra ICONTEX1 + +TWOCLIKT ldx #1 Double clicked text file: try executing as shell script + stx ,S + ldd FL.FNAME,U Save ptr to filename + pshs d + ldd #SHELLNAM Save ptr to 'shell' and 'use overlay window' flag + pshs d,X + lbsr EXECPRGM Execute shell in overlay window + leas 6,S + bra ICONTEX1 + +* File with previously found AIF extension clicked on +ICON.XXX ldd ,S Get # of clicks + decb + beq ICONAIF1 1 click, skip ahead + pshs U + lbsr EXEC.XXX Double click, execute the program related to icon + bra ICONAIF2 + +* AIF file clicked on +ICONAIF ldb #1 Enable LIST & PRINT on FILE menu + pshs d + lbsr ENLSTPRT + leas 2,S + ldd ,S Get # of clicks + decb + beq ICONAIF1 1 click, skip ahead + pshs U + lbsr EXECAIF 2 clicks, execute program AIF file refers to + bra ICONAIF2 + +* Executable program clicked on +ICONPRGM ldd ,S Get # of clicks + decb + beq ICONAIF1 1 click, skip ahead + pshs d + lbsr FILESLCT 2 clicks, Go to file select menu, option 1 (OPEN) + leas 2,S + bra ICONPRG1 + +ICONAIF1 pshs U + lbsr SELCICON Do select icon on screen +ICONAIF2 leas 2,S +ICONPRG1 ldb #1 Enable OPEN item on FILES menu + pshs d + lbsr ENBLOPEN +ICONTEX1 ldb #1 + std ,S + lbsr ENBLCOPY Enable COPY item on FILES menu + lbra ICONEXT1 + +DSLCTALL ldd SELECTED Get ptr to current selected icon + pshs d + lbsr UNSLICON Unselect icon + lbsr ENBLSOFF Shut all FILES menu items off + leas 2,S + clrd + std SELECTED Set selected file/device to none +ICONEXIT leas 4,S + puls U,PC + +* Pop up overlay window to ask user for parameters for file we are about to +* execute. +GETPARMS pshs U + ldd 4,S + leas -48-10,S Make room on stack for string copy + leax TENSPACE,PC + pshs d,X Save ptr to 10 spaces & ptr to module name we are executing + leax =256K, skip ahead + lbsr CLRSCRN on 128k, clear GSHELL screen 1st + bra KILPDS12 + +*Process killed was on different path than GSHELL itself is on +KILPDES7 ldd GD.DW.OW,U Process running in overlay window? + beq KILPDES8 No, skip ahead +* NOTE: WHY DO SELECT TWO DIFFERENT WINDOWS IN A ROW??? +* Something to do with overlay window vs. parent device window? + ldd GD.WPATH,U Get path to window process was on + pshs d Make it the active window + lbsr SELECT + ldd WNDWPATH Get GSHELL window path + std ,S Select it + lbsr SELECT Select window + ldd GD.WPATH,U Get process' window path again + std ,S End process' window + lbsr DWEND + bra KILPDES9 + +KILPDES8 ldd WNDWPATH Get path to GSHELL window + pshs d Make it the active window + lbsr SELECT +KILPDES9 leas 2,S Eat temp stack + ldd GD.WPATH,U Get path to process' window + pshs d Close path to window + lbsr I.CLOSE + bra KILPDS11 + +KILPDS10 ldd WNDWPATH Get path to GSHELL window + pshs d + lbsr SELECT Make it the active window +KILPDS11 leas 2,S Eat stack +KILPDS12 ldd GD.SCRNO,U Get screen # + ble KILPDS13 If negative or 0, skip ahead + pshs d Save screen # + lbsr UNLKWNDW Unlink window from active window/screen list + leas 2,S +KILPDS13 ldd GD.INDVC,U Get ptr to ??? + beq KILPDS14 None, skip ahead + pshs d + lbsr FREE ??? Free memory of some sort? + leas 2,S +KILPDS14 ldd GD.MNAME,U Get ptr to process module name + beq KILPDS15 None, skip ahead + pshs d ??? Free mem for that? + lbsr FREE + leas 2,S +KILPDS15 pshs U + lbsr FREE + leas 2,S +KILPDS16 leas 2,S + puls U,PC + +* Allocate & setup process entry for our table of forked proceses +SETPDESC pshs U + ldd #GD.SIZE Size we want to allocate + pshs d + lbsr MEMSPACE Allocate the memory + tfr D,U Save ptr to allocated memory into U + std [PTBLNEXT,Y] Save ptr to next available spot for process descriptor + leax GD.LINK,U Point to next link + stx PTBLNEXT Save ptr to next available + ldd 4+2,S + std ,S + lbsr PUTSTRNG + leas 2,S + std GD.MNAME,U Save ptr to module name + clrd + std GD.MTYPE,U Default stuff to zeros + std GD.INDVC,U ??? to 0 + std GD.PRCID,U Process ID # to 0 + std GD.MEMSZ,U memory size to 0 + std GD.DW.OW,U Default to running on separate device window + leax GD.LINK,U Point to next link ptr + std ,X Set next link to empty + ldd #-1 + std GD.STATS,U + std GD.WPATH,U No window path done yet + std ,--X + std ,--X + std ,--X + std ,--X + std ,--X + tfr U,D + puls U,PC + +DONEWDIR lbsr KILLFTBL Kill current file table in memory + lbsr RSTXYPTR Reset x/y pointers for icon starts + lbsr NEWDIREC Redraw current dir screen + bra DONEWDR1 Redraw screen & return + +SCRLLDN1 ldb SCREENOW+1 + cmpb NSCREENS+1 + bge SCRLLUDX + incb + bra SCRLLDN2 + +SCRLLUP1 ldb SCREENOW+1 + beq SCRLLUDX + decb +SCRLLDN2 stb SCREENOW+1 +DONEWDR1 bsr DRAWSCRN +SCRLLUDX rts + +* Update screen: does 1) update directory bar, 2) update icons, 3) update +* scroll bar marker. +DRAWSCRN pshs U + lbsr ENBLSOFF Disable any menu items that deal with a specific file + ldd WNDWPATH Get GSHELL path + pshs d,X + lbsr GCSETOFF Shut graphics cursor off + lbsr MOUSOFF Shut mouse off + lbsr WIPICONS Wipe icons off screen (should not touch dir bar) + clrd + std SELECTED 0 out currently selected icon ptr + ldd MAXICONS Get # icons/screen + muld SCREENOW Multiply by screen set # + stw 2,s Save result + ldu FTBLSPTR Get ptr to file icon descriptor table + bra DRAWSCR2 + +DRAWSCR1 ldu FL.LINK,U +DRAWSCR2 ldd 2,S Get screen set # we want to print + decd Base 0 + std 2,S Save it back + bge DRAWSCR1 If not 1st, skip ahead + stu STRTICON Save ptr to 1st icon on current screen + clrd + bra DRAWSCR4 + +DRAWSCR3 pshs U + lbsr WRITICON + leas 2,S + ldu FL.LINK,U + ldd 2,S + incd +DRAWSCR4 std 2,S + stu -2,S + beq DRAWSCR5 + cmpd MAXICONS + blt DRAWSCR3 + +DRAWSCR5 ldd NSCREENS Get # of icon screens + cmpd SCREENOW On last one? + bne SCROLBAR No, skip ahead + ldd #20 Yes, use Y pos 20 (for 200 line screen) + bra DRAWSCR6 + +* Calculate position of vertical scroll bar (based on current screen #, and +* how many screens of icons there is in current dir) +SCROLBAR ldd NSCREENS Get # of screens of icons + beq DRAWSCR6 If 0, just put in position 0 + lda SCREENOW+1 Get current screen# + beq Force0 If 0, that is Y position + leas -3,s make room on stack for temp vars + incb Base 1 for divide + stb 3,s Save # of screens + ldd #21 Maximum # of screens + divd 3,s B= # of Y positions per screen + std 1,s Save remainder & answer + lda SCREENOW+1 Get current screen # + inca Base 1 + mul Multiply by answer (rough Y pos) + stb ,s Save that result + lda SCREENOW+1 Get current screen # + inca Base 1 + ldb 1,s Get original remainder + mul Calculate 2ndary offset + divd 3,s Divide by # screens total (Y pos=B) + addb ,s Add 2ndary to primary Y pos calc + leas 3,s Eat stack + decb Base 0 for scroll bar SETSTAT call + bge NotNeg not negative, skip ahead +Force0 clrd Force to 0 +NotNeg cmpb #20 Past end? + bls DRAWSCR6 No, good, so update scroll bars + ldb #20 Force to 20 +* Actually update the scrollbar (Y only one used) +* Entry: D=Y position wanted (0-20) +DRAWSCR6 std ,S Save Y pos + pshs d And again + ldx #77 Default to X position 77 + tst FLAG640W 80 or 40 column? + bne DRAWSCR8 80, continue + ldx #37 X position to 37 for 40 column +DRAWSCR8 ldd WNDWPATH Get GSHELL window path + pshs d,X Save path & x position + lbsr ST.SBAR Set scroll bar positions + lbsr MOUSENOW Turn auto-follow mouse back on + leas 6,S eat stack + lbra GENLEXIT Fix stack & return + +* Wipe interior window, & redraw directory bar (latter done by call to +* WRITDBAR). Change so it doesn't redraw directory bar unless directory has +* changed +WIPICONS pshs U + ldb #21 Window Y size to clear - NOTE: WE HAVE TO ELIMINATE THE + pshs d EXTRA BOX LINE IT CURRENTLY DRAWS + ldx WINDWSZX Get window X size + leax -7,X Subtract 7 (leaves scroll bars & drive icons alone) + ldb #2 Start Y at 2 (skip menu bar and current path line) + pshs d,X + ldx #6 Start X (skip left border & drive icons) + ldd WNDWPATH Get GSHELL path + pshs d,X + lbsr CWAREA Change working area + lbsr CLRSCRN Clear screen (Send CHR$(12)) + leas 10,S Eat stack + lbsr FULLSCRN Change working area to whole window except border stuff + lbsr WRITDBAR Do initial drawing of "inside" screen REDOES DIR STUFF + clr WIPED Flag that icons need not be redrawn + puls U,PC Exit + +* Wipe interior window, except drive icons (but including box around dir +* contents) +CLRDSCRN pshs U + ldb #22 Y size + pshs d + ldx WINDWSZX X size -6 (includes box around dir contents) + leax -6,X + ldb #1 Y start=1 (includes dir bar) + pshs d,X + ldx #5 X start=5 (includes box around dir) + ldd WNDWPATH + pshs d,X + lbsr CWAREA Clear out interior window + lbsr CLRSCRN + lbsr FULLSCRN Full interior window size (except border) + clrd Redo scroll bars at 0,0 + std 4,S + std 2,S + lbsr ST.SBAR + leas 10,S + puls U,PC + +* new dir - read in and print 1st screen +NEWDIREC pshs U + ldb #$ff Flag that we have to redo icons + stb WIPED + bsr WIPICONS Wipe icons off screen (leave current dir border) + clrd + std FILESCTR # files in current dir=0 + ldb #PTR.SLP Hourglass ptr + pshs d,X,Y + ldx #GRP.PTR + ldd WNDWPATH + pshs d,X + lbsr GCSET + lbsr MOUSOFF Shut mouse off - Change later to slow sampling? + +* New DIR check code here + lda DIRPATH Get current DIR path # + beq SkipClos None, don't try closing + os9 I$Close Close dir path 1st +* New label here +SkipClos ldb #DIR.+READ. + std 2,S + leax ONEDOT,PC Point to '.' + stx ,S + lbsr I.OPEN2 Open current dir + leas 6,S + std 2,S Save path # to stack + lblt BAD.DIR Couldn't read current dir + stb DIRPATH Successfull open; Save current dir path +* NOTE: Done this early so if opening a large directory, and updates are done +* during read, they will get caught too + clr Dirup Clear out Directory update flag (saved signal) +* New DIR code here - We want a signal if DIR changes +* Moved here so will detect changes even on dir we are doing + lda DIRPATH path in A + ldx #DIRSIG Signal code to send on dir update + ldb #SS.FSIG Send signal on file update setstat + os9 I$SetStt Enable call + + ldd #DIR.SZ*2 Flag to read 2 entries (. & ..) - NOTE IF ONE OR BOTH OF THESE + pshs d IS NOT PRESENT, THEN GSHELL WILL SKIP ENTRIES! + ldx #DIRBUFER + ldd 6-2,S + pshs d,X + lbsr I.READ Read . & .. + leas 6,S + bra READ.DIR Go read rest of dir + +DIRVALID ldd ,S Get # of bytes of dir entries + pshs d Save # to divide by + ldb #5 + lbsr CCASR divide by 32 (2^5) (size of dir entry) + std ,S + ldx #DIRBUFER Point to start of DIR buffer + stx DIRPTR Save it + bra CLASTEST Check which kind of file + +CLASSIFY ldb [DIRPTR,Y] Get 1st byte of dir entry + beq CLASSIF4 NUL (Deleted file, skip to next) + ldx DIRPTR Get ptr to filename + ldd FNAMEPTR Get ptr to current filename buffer + pshs d,X + lbsr STRHCPY Copy filename, including fixing hi-bit marker + lbsr UPDTIPTR Update icon/file table ptrs + leas 4,S + tfr D,U + stu -2,S + beq CLASSIF4 + bsr GTFD.ATT Get file attributes + ldb #IC.FOLDR Default to folder (dir) + bita #DIR. If it is dir, done + bne CLASSIF3 + ldb #IC.PRGRM + bita #EXEC. If executable, program type + bne CLASSIF3 + pshs U + lbsr ISIT.XXX Check if an AIF type we know about + leas 2,S +CLASSIF3 stb FL.ICONO,U Save icon type +CLASSIF4 ldd DIRPTR Go onto next dir entry + addd #DIR.SZ + std DIRPTR + +CLASTEST ldd ,S Get # of dir entries in this 2k block + decd Subtract 1 + std ,S + bge CLASSIFY Still going, classify file type, otherwise, get next 2k block + +READ.DIR ldd #2048 Size of read buffer (64 dir entries @ once) + pshs d + ldx #DIRBUFER + ldd 6-2,S + pshs d,X + lbsr I.READ Read in 2K of directory + leas 6,S + std ,S + bgt DIRVALID Good read, continue + +* New DIR code here +* We want a signal if DIR changes + lda DIRPATH path in A + ldx #DIRSIG Signal code to send on dir update + ldb #SS.FSIG Send signal on file update setstat + os9 I$SetStt Enable call + bra READDIR2 + +BAD.DIR leax 0 if box AND dark grey invert shadow +* U=ptr to FL.* structure +* Uses F +DRAIFBOX ldd FL.YSTRT,U Get Y start coord for icon, subtract 2 for box + subb #2 A little above top of icon + pshs d + ldx FL.XSTRT,U Get X pos of icon + ldf FL.ICONO,u Get icon type + subf #IC.DRIVE Drive? (special case) + bne NormIcon No, do normal box + leax -3,x Yes, smaller box + bra Minus9 Go save X pos + +NormIcon leax -9,X -9 to include text + tst WD48FLAG If 40 column, bump down by another 14 + bne Minus9 + leax -16,x + ldd FL.XSTRT,u Get original icon start again + lsld Put column # in A + lsld +AdjLoop leax 2,x 2 pixels per column + deca + bne AdjLoop +Minus9 ldd WNDWPATH Save X start & window path + pshs d,X + lbsr SETDPTR Set draw ptr to upper left corner of box +* include text below icon as well + ldd #36 Box height 36 pixels (2 above & below) + tstf + bne NormIco2 + ldd #24 Unless drive, then 24 +NormIco2 std 4,S + tstf Drive? + bne NormIco3 No, determine width + ldb #29 Special width for drive + bra DRAIFBO1 + +NormIco3 ldb #68 80 columns defaults to 68 pixel width + tst WD48FLAG If 80 column skip ahead + bne DRAIFBO1 + ldb #62 Box width 62 pixels for 40 column +DRAIFBO1 std 2,S Save box width + lbsr RBOX Draw box & return +* use entry flag to flag whether + tste Do we want shadow too? + beq DoneAIFB No, exit + ldb #1 Dark Grey color + std 2,s + lbsr FCOLOR + clrb Set X offset to 0 + std 2,s + lbsr RLINE Draw vertical line + clrb Set Y offset to 0 + std 4,s + tstf Drive? + bne NormIco4 No + ldb #28 + bra Do40Shdw + +NormIco4 ldb #61 61 pixel width for 40 column + tst WD48FLAG + beq Do40Shdw + ldb #67 67 pixel width for 80 column +Do40Shdw std 2,s X offset + lbsr RLINE Draw horizontal dark grey line +DoneAIFB leas 6,S Eat stack & return + rts + +UPDTDEVC pshs U + ldu #DRIVETBL + ldx #21 + ldb #4 + pshs d,X + ldx #1 + pshs X + ldb WNDWPATH+1 + pshs d,X + lbsr CWAREA + lbsr MOUSOFF + lbsr CLRSCRN + lbsr FULLSCRN + bra UPDTDEV2 + +UPDTDEV1 lbsr WRITICON Print icon on screen + ldu FL.LINK,U Get next device in linked list +UPDTDEV2 stu ,S Save it + bne UPDTDEV1 Still more drives, do next one + ldx #TRSHDESC Now, do trash can + stx ,S + lbsr WRITICON + ldx #PRTRDESC And printer + stx ,s + lbsr WRITICON + ldd DEVICNOW Get current drive (if any) + std ,S + lbsr SELCICON Select it on screen + ldd WNDWPATH + std ,S + lbsr INITMOUS Set mouse parms + leas 10,S + puls U,PC + +* Get ptr to root path (not including drive name) +* Exit: X=ptr to either end of pathname (if on root), or ptr to root path +* D=1 if on root +* D=0 if found path +FNDSLASH ldx #DDIRNAME+1 Point to full path of current dir (skip 1st '/') +FNDSLAS1 ldb ,X+ Get char + beq FNDSLAS2 End of path, exit with D=1 + cmpb #'/ Find slash? + bne FNDSLAS1 No, keep looking + clrb Exit with D=0 + bra FNDSLAS3 + +FNDSLAS2 incb +FNDSLAS3 clra + rts + +* Check if icon (or clickable option) +* Exit: D=0 if no icon selected +* else D=ptr to FL.* structure for icon selected +ISITICON pshs U + ldx 4,S Get ptr to mouse packet + ldd PT.ACY,X Get Y coord + subd #8 + pshs d,X Save modified Y coord & room for X coord + ldd PT.ACX,X Get X coord + tst FLAG640W 640 wide screen? + bne ISITICO1 No, skip ahead + asrd Divide by 2 (scale to 320) +ISITICO1 subd #8 + std 2,S Save modified X coord + cmpd #32 Is X coord within 32 pixels of left side (no border)? + ble ISITDEVC Yes, check for device (NOTE: WHERE PRINTER SHOULD GO) + ldd ,S Get Y adjusted coord + cmpd #8 Is it in the current directory bar area? + bgt ISITDISP No, skip ahead + ldu #DBOXDESC Point to icon info table entry for CLOSE box in current dir bar + bra ISITICO4 Go check that + +ISITDISP ldu STRTICON Get ptr to icon descriptor for 1st icon on current scrn + bra ISITICO4 Check it + +ISITDEVC ldu #DRIVETBL Point to start of device/drive table + ldd ,S Get adjusted Y coord (NOTE: LDB 1,S BOTH 6809/6309) + cmpb #128 From 0-128 (drives themselves)? + blo ISITICO4 Yes, check with drive table entries + cmpb #160 Trash? + blo TryPrntr No, try printer + ldu #TRSHDESC Try the trash can descriptor + bra ISITICO4 + +TryPrntr ldu #PRTRDESC Try printer descriptor + bra ISITICO4 + +ISITICO2 ldd 2,S Get X coord + cmpd FL.XSTRT,U Within X start coord of current file table entry? + blt ISITICO3 No, check next file entry + cmpd FL.XEND,U Within X end coord of current entry? + bgt ISITICO3 No, check next file entry + ldd ,S Get Y coord + cmpd FL.YSTRT,U Within Y start coord of current entry? + blt ISITICO3 No, check next + cmpd FL.YEND,U Within Y end coord of current entry + bgt ISITICO3 No, check next + tfr U,D Found, move table entry ptr to D & exit + bra ISITICO5 + +* Go to next file table entry +ISITICO3 ldu FL.LINK,U Get next file table ptr +ISITICO4 stu -2,S Is this a legit ptr? + bne ISITICO2 Yes, go check it + clra No match, return with 0 (done, & no icon clicked) + clrb +ISITICO5 leas 4,S Eat stack & return + puls U,PC + +SET48X24 ldd #288 + std 14,S + ldx #MULTIBFR Point to general purpose buffer + stx 16,S + ldb #7 + stb 9,S + ldd #48 + std 10,S + ldb 7,S + orb #$80 + stb 7,S + rts + +SET24X24 ldd #144 + std 14,S + ldx #ICONBUFR Point to icon build buffer + stx 16,S + ldb #6 + stb 9,S + ldd #24 + std 10,S + rts + +* Load standard icons +STDICONS leas -12,S Make temp buffer on stack + ldx PRCIDNUM Get GSHELL's process id # (for group) + ldd WNDWPATH Get GSHELL's window path + pshs d,X Save them + ldb #24 Save ??? (height in pixels?) + std 10,S + leax txticon,pc Point to new 4 color image of text + ldb #144 + lbsr CopyIcon + lbsr ICN48X24 + ldd #IC.TEXT + std 4,S + bsr SET24X24 + lbsr GPLOAD + bsr SET48X24 + lbsr GPLOAD + + leax foldricn,pc Point to new 4 color image of folder + ldb #144 + lbsr CopyIcon + lbsr ICN48X24 + ldb #IC.FOLDR + std 4,S + bsr SET24X24 + lbsr GPLOAD + bsr SET48X24 + lbsr GPLOAD + + leax execicon,pc Point to new 4 color image of executable + ldb #144 + lbsr CopyIcon + lbsr ICN48X24 Make double width version for 80 column screen + ldb #IC.PRGRM + std 4,S + bsr SET24X24 + lbsr GPLOAD + lbsr SET48X24 + lbsr GPLOAD + + leax trashicn,pc Point to new 4 color image of trashcan + ldb #144 + lbsr CopyIcon + ldb #IC.TRASH + std 4,S + bsr SET24X24 + lbsr GPLOAD + ldb #7 + stb 7,S + ldb #IC.TRASH+$80 + stb 5,S + lbsr GPLOAD + lbsr SET24X24 + + leax driveicn,pc Point to new 4 color image of drive + ldb #72 + lbsr CopyIcon + ldd #72 72 bytes to load + std 12,S + ldb #12 12 lines high + std 10,S + ldb #IC.DRIVE Buffer # + std 4,S + lbsr GPLOAD Load it in + ldb #7 Screen type 7 + stb 7,S + ldb #IC.DRIVE+$80 Buffer #+$80 for type 7 version (useless, same as type 6) + stb 5,S + lbsr GPLOAD Load the type 7 version (eliminate later!) + + leax prntricn,pc Point to new 4 color image of printer + ldb #90 90 bytes to load/copy + lbsr CopyIcon + ldd #90 72 bytes to load + std 12,S + ldb #15 12 lines high + std 10,S + ldb #IC.PRNTR Buffer # + std 4,S + lbsr GPLOAD Load it in + ldb #7 Screen type 7 + stb 7,S + ldb #IC.PRNTR+$80 Buffer #+$80 for type 7 version (useless, same as type 6) + stb 5,S + lbsr GPLOAD Load the type 7 version (eliminate later!) + + leas 16,S + rts + +* NOTE: XPNDICONS ROUTINE ORIGINALLY HERE...NO LONGER NEEDED + +* duplicate a 24x12 4 color buffer to a 48x12 +ICN48X24 ldb #144 Counter for # of bytes in 4 color icon + pshs B,U Save it + ldx #ICONBUFR Point to 4 color icon buffer + ldu #MULTIBFR Point to bigger buffer to expand into (could expand into LINEBUFR) +IC48X24L ldb ,X+ Get 4 color byte + bsr SR48X24 Expand 2 pixels (a nibble) into 4 pixels (a byte) + bsr SR48X24 Do next last half of byte + dec ,S Are we done all 144 source bytes? + bne IC48X24L No, continue + puls B,U,PC Restore & return + +SR48X24 clra Zero out hi byte + lslb Shift 1st color into B (2 bits) + rola + lslb + rola + lsla Now, shift that over 1 pixel + lsla + lslb Shift in the next pixel from the source byte + rola + lslb + rola + pshs A Save that byte (2 source pixels, now separated by a pixel) + lsla Shift it left by a pixel + lsla + ora ,S+ Merge with original (effectively doubling each pixel) + sta ,U+ Save doubled up byte + rts + +AIF.NAME fcc "aif" + +ONEDOT fcb '. + fcb NUL + +* Entry: 0-1,s=RTS address +* 2-3,s=Ptr to file table entry +FILE.XXX pshs U + ldu 4,S Get ptr to file table entry + leas -64,S Make large buffer on stack + clrd + std 28,S + ldd FL.FNAME,U Get ptr to filename + pshs d + lbsr ISIT.AIF + std 28+2,S + ldd 70+2,S + std ,S + lbsr MTCH.XXX + leas 2,S + std 22,S + lbne FILEXXX3 + ldd 70,S + pshs d + leax module name + leas 2,S Eat stack + ldd 10,S Get ptr to name of primary program + bra FORKPRC3 + +FORKPRC2 ldd GD.MNAME,U Get ptr to module to run +FORKPRC3 std 6,S Save it + ldx #PARMSBFR Point to temp buffer + pshs X Save it + lbsr STRLEN Get length of command line to run + leas 2,S Eat stack + std 2,S Save length + beq FORKPRC4 If 0, just put a CR in it + addd #-1 Dec length by 1 (space on end?) + ldx #PARMSBFR Point to start of command line + leax D,X Point to end of it + ldd #CR*256 Append a CR/NUL to it + std ,X + bra FORKPRC5 + +FORKPRC4 ldd #CR*256 Nothing in command buffer, just put CR/NUL in + std PARMSBFR,Y +FORKPRC5 ldd 2,S Get length of command line to run + addd #1 bump up by 1 & save it again + std 2,S + pshs U + lbsr NEWSTDIO Change I/O paths (all 3) to window path in current GD.* ptr + std ,S++ Were we successful? + beq FORKPRC7 No, skip ahead + clra Select std IN path as current window (in other words, + clrb select GD.* path as new window + pshs d + lbsr SELECT + ldd GD.MEMSZ,U Get memory size required + std ,S Save it + clra + clrb + pshs d + pshs d + ldx #PARMSBFR Point to parms buffer + ldd 8,S + pshs d,X + ldd 16,S + pshs d + lbsr F.FORK Fork the program + std 16,S + ble FORKPR51 + leas 12,S + bra FORKPRC6 + +FORKPR51 ldd 20,S + bne FORKPR52 + leas 12,S + bra FORKPRC7 + +FORKPR52 std ,S + lbsr F.FORK + leas 12,S + std 4,S + ble FORKPRC7 + +FORKPRC6 ldd 4,S + std GD.PRCID,U + ldd #1 + std ,S + +* Couldn't change std paths to new window +FORKPRC7 ldd GD.MNAME,U Get ptr to module name + pshs d Save it + lbsr F.UNLOAD Unload the module + leas 2,S Eat stack + ldd ,S ??? + bne FORKPRC8 But don't print FORK ERROR if it is<>0 + ldd ERRNO,Y Get error code + std GD.STATS,U Save as last status for forked program + leax , abort copy + std ,S Save ptr to string we are inserting in front of + lbsr STPREFIX Insert original filename to copy (?) + clra + clrb + std ,S + pshs U + lbsr GETFLPTR Get ptr to filename we want to copy + std ,S + clra No overlay window for COPY command + clrb + pshs d + leax , abort rename + std ,S + lbsr STPREFIX + clra + clrb + std ,S + pshs U + bsr GETFLPTR Get ptr to filename of original filename to rename + std ,S +* If Dirup <>0, leave RECDSGNL/Dirup alone (another process has updated DIR) +* If Dirup=0, we want to wipe out RECDSGNL & Dirup right after Fork comes back +* before we exit this routine. + lda Dirup Any directory update signal? + sta RenFlag Save it (irregardless) + clra No overlay window for RENAME + clrb + pshs d + leax , exit + leax , exit + cmpu 2,S Same as source drive? + beq SNGLDRIV Yes, doing single drive backup + pshs d + lbsr STPREFIX Append + leas 2,S + clra No overlay window (since will be automatic) + clrb + bra TWODRIVE + +* Single drive backup +SNGLDRIV ldd #1 Need overlay window for disk swap prompts +TWODRIVE std ,S + pshs U + lbsr STPREFIX + ldd #1 + std ,S + ldd 2,S + beq TWODRIV1 + leax 128k, skip ahead + ldd 8,S 128k + pshs D + pshs U + lbsr ISCR128K Do special 128k processing for new window + leas 4,S Eat stack + std -2,S Check if new window create successful + beq EXCICON1 Yes, continue + bgt EXCICON6 Screen type of 7 or 8, can't create in 128k + lbsr SETHLRES Reinit main window, then print 'can't create' error + bra EXCICON6 + +EXCICON1 ldd 6,S ??? + beq EXCICON2 + ldx #WT.DBOX Double box border + ldb WNDWPATH+1 Window path + pshs D,X Save for routine + lbsr ST.WNSET Set window to double box + leas 4,S Eat temp stack + std -2,S Error on Window Set? + bne EXCICON3 Yes, reset window (?) and exit +EXCICON2 pshs D Save regs + pshs D + pshs U ?? Save ptr to process to fork + lbsr FORKWAIT Go fork process + leas 6,S +EXCICON3 lbsr SETHLRES Change current window type & exit + bra EXCICN10 + +* >128k RAM for forking IC.* program +EXCICON4 ldd 8,S + pshs D + pshs U + lbsr ISCR512K Go set up new window to fork program into + leas 4,S Eat temp stack + std -2,S Successful window create? + blt EXCICN11 No, report error + ldd 6,S Get double box window flag + beq EXCICON5 Not set, go straight to program fork + ldx #WT.DBOX Draw Double box window + ldd GD.WPATH,U Get path # to window program is/will be running on + pshs D,X + lbsr ST.WNSET + leas 4,S + std -2,S + bne EXCICON6 Couldn't create double box window, report error +EXCICON5 pshs U Save ptr to GD.* variables + lbsr FORKPROC Fork program + std ,S++ + bne EXCICN10 Successful fork, exit +EXCICON6 ldd WNDWPATH Print error on main window that we could not + pshs D make a new window + lbsr SELECT + leas 2,S + leax 0 = no overlay window +* 6-7,s = Ptr to parameter to send? +EXECPRGM pshs U + ldd 4,S Get ptr to primary module to execute + pshs D + lbsr SETPDESC Allocate a process table entry + std ,S + beq EXECPRG5 If primary module ptr empty, exit + ldu ,S Get ptr to primary module name + lbsr LINKLOAD Attempt to link or load it + std ,S++ Eat stack + beq EXECPRG4 Could not load/link, return process tbl mem & exit + ldd 6,S Get overlay window flag + beq EXECPRG1 If flag=0, don't do overlay window + pshs U + lbsr OLAYBLWT + bsr NOMOUSE + leas 2,S +EXECPRG1 ldd 8,S + beq EXECPRG2 + pshs D + lbsr STPREFIX + leas 2,S + +EXECPRG2 ldd 10,S + pshs D + ldd 8,S + +EXECPRG3 pshs d + pshs U + bsr FORKWAIT + pshs d + bsr MOUSENOW + puls d + leas 6,S + lbsr ResetPal Reset palettes to GSHPAL in case CONTROL was called. + puls U,PC + +EXECPRG4 pshs U + lbsr KILPDESC Kill the process table entry we had allocated +EXECPRG5 leas 2,S Exit with error flag set + ldd #-1 + puls U,PC + +NOMOUSE ldd WNDWPATH + pshs d + lbsr GCSETOFF + lbsr MOUSOFF + puls d,PC + +MOUSENOW ldd WNDWPATH Get path to gshell window + pshs d Save it + lbsr CRSRAROW Set gfx cursor to arrow + lbsr INITMOUS Set mouse parms + puls d,PC + +FORKWAIT pshs U + ldu 4,S + pshs U,PC + lbsr FORKPROC Fork process + std ,S++ Successful? + beq FORKWAI3 No, flag error & kill process descriptor entry +FORKWAI1 clra Succesful - clear received signal + clrb + std RECDSGNL + pshs U + lbsr HNDLWAIT Handle waiting while forked process runs + leas 2,S + ldd GD.STATS,U Get child's exit signal + cmpd #-1 If -1, try waiting again + beq FORKWAI1 + std ,S Save signal + ldd 8,S + beq FORKWAI5 + ldd 10,S + beq FORKWAI4 + ldd ,S + bne FORKWAI4 + ldx #PRESSMSG "Press any key" message + pshs X + lbsr WRLNWCR + leas 2,S + bsr WAITPSIG Wait for signal + bra FORKWAI4 + +FORKWAI3 ldd #-1 Flag error + std ,S +FORKWAI4 pshs U + lbsr KILPDESC Kill process descriptor entry + leas 2,S + tst RAMSIZE Only 128k? + bne FORKWAI5 No, exit + lbsr INITSCRN Yes, reinit screen before exiting +FORKWAI5 puls d,U,PC + +WAITPSIG lbsr SETSGNLS Reset mouse & keyboard signals + ldd RECDSGNL Get current signal (could be dirupdate from SETSGNLS) + beq WAITPSLP None, sleep for one. + cmpb #DIRSIG Queued Dir update signal? + beq WAITPSL2 Yes, sleep till next signal + bsr FORKWTST Check for key press, abort or interrupt signal + bne WAITPSIG Different signal, wait for a different one + bsr FORKWSUB Go read a key from current window + bra WAITPSIG Now wait for signal again + +WAITPSL2 clrb +WAITPSLP tfr d,x Sleep till we receive a signal + os9 F$SLEEP + bsr FORKWTST Have signal, check it out + bne WAITPRSX Not key, abort or interrupt, skip ahead + bsr FORKWSUB If one of those, eat key from kybd buffer 1st +WAITPRSX ldd 128k RAM, try to make new window??? +ISCR512K pshs U + ldu 4,S Get ptr to current GD (forked process table) structure + clrd + std ACTVSCRN Current active screen to none + std DWSETSTY New window type to none + ldx 6,S + lbsr GFXSIZXY Set window type & minimum X/Y sizes + ldd ID.MEMSZ,X Get mem size need for new program + std GD.MEMSZ,U Save it in forked process table + ldd PROCWTYP Get default window type new program + pshs d,X,Y Save window type, ID.* tbl ptr & room for 2 bytes(?) + bsr COLS4080 Figure it if 40 or 80 column screen + stb 5,S Save 40/80 flag (0=80 column) + puls d Get window type back + decb + beq ISC512K3 H/W text handler (type 1) - Just create new window + decb + beq ISC512K3 H/W text handler (type 2) - Just create new window + ldb #40 Default to 40 column screen + tst 3,S Was process window type 40 or 80 column + bne ISC512K2 40, skip ahead + ldb #80 It was 80 +ISC512K2 cmpb ID.XSIZE+1,X If min width<>full width window, go to window + bne ISC512K6 sizing routine + lda ID.YSIZE+1,X If min height<>full height window, go to window sizing + cmpa #25 routine + bne ISC512K6 +* New window is full size goes here +ISC512K3 clrd Default window x,y start to 0,0 + std GD.XSTRT,U + std GD.YSTRT,U + ldd #319 Default to 320 X pixel size + tst 3,S Was it 40 column window? + bne ISC512K5 Yes, 320 is fine + ldd #639 80 column, so 640 X pixel size +ISC512K5 std GD.XEND,U Save X size for new process + ldd #199 Y end is 199 (NitrOS9 only) + std GD.YEND,U + ldd #-1 Flag active screen with -1 (?) + std ACTVSCRN + ldd PROCWTYP Get process' requested type + std DWSETSTY Save as screen type to use to create new window + bra ISC512K7 + +* New window is sized by user - do positioning/sizing +ISC512K6 lbsr GETPSCRN ???Activate screen we will be putting new window on + std ,S Save flag + lblt IS512K13 If -2 or -1, eat stack & exit (Either scrn tbl full, or deleted old screen) + pshs d,U + lbsr SETSTOP Position & size window with mouse + leas 4,S + std ,S Save flag + lblt IS512K13 + pshs d,U + lbsr SETSBOTM + ldd 4,S + std ,S + lbsr GCSETOFF + leas 4,S + ldx #0 + ldd ,S + pshs d,X + lbsr LSET + leas 4,S +* Create new window (?) +ISC512K7 ldd ACTVSCRN + std GD.SCRNO,U + blt ISC512K8 + lbsr LINKWNDW +ISC512K8 lda #UPDAT. Open path to next available window + ldx #SLASHW + lbsr I.OPEN + std 2,S Save path # + blt IS512K13 negative (error), skip ahead + std GD.WPATH,U Save as path # to window for program to fork + ldx 10,S + bne ISC512K9 + clra + clrb + ldx #1 + bra IS512K10 + +ISC512K9 ldd ID.FRGND,X Get foreground color + ldx ID.BKGND,X Get background color +IS512K10 pshs X Save border color (Background copy) + pshs d,X Save background & foreground colors + leas -12,S Make room on stack for rest of DWSET + ldd GD.YSTRT,U + bsr DIVDX8 + std 6,S Save Y start of window + ldd GD.YEND,U + incb + bsr DIVDX8 + subd 6,S Save Y window size + std 10,S + ldd GD.XSTRT,U Save X start of window + bsr DIVDX8 + std 4,S + ldd GD.XEND,U Save X window size + incd + bsr DIVDX8 + subd 4,S + std 8,S + ldd DWSETSTY Save screen type + std 2,S + ldd 20,S Save path to new window + std ,S + lbsr DWSET + leas 18,S + std -2,S + bne IS512K12 + ldd DWSETSTY + beq IS512K11 + ldd 2,S + pshs D + lbsr SELECT + puls D + +IS512K11 ldd #2 + std GD.DW.OW,U + decb + bra IS512K13 + +IS512K12 ldd #-1 + +IS512K13 leas 4,S + puls U,PC + +*D=D/8 +DIVDX8 asra + rorb + asra + rorb + asra + rorb + rts + +*D=D*8 +MULDX8 aslb + rola + aslb + rola + aslb + rola + rts + +* ??? +* NOTE: BOTH CPUS: SINCE MAX=8, LDB ACTVSCRN+1 WOULD BE FINE +* Exit: D=-1 : screen table full, could not create new screen +* D=-2 : Closed existing screen table, did not create new screen +GETPSCRN pshs U Preserve U + leas -2,S Make room on stack + ldu #SCRNTABL Point to start of screens used table + ldd ACTVSCRN Get active screen # + aslb x4 (size of each entry) + aslb + leau D,U Point to active screen entry + ldb ACTVSCRN+1 Get active screen # again + beq GETPSCR3 1st entry, skip ahead (?) + leax SC.SIZE,U Point to next entry + lda SC.USERS,X Any paths already open to this next screen? + bne GETPSCR3 Yes, skip ahead +* Cleanup? seems to close screen path if no programs on screen + ldd WNDWPATH No programs on this screen, get GSHELL window path + pshs D,X + lbsr SELECT Go select GSHELL window + puls D,X + lbsr CLOSE.X Close screen entry path + ldd #-2 Exit flag + bra GETPSCR6 + +* NOTE: IN ADDITION TO ADDING SUPPORT FOR VDG SCREENS, AND WINDOW TYPES +* WITH GSHELL PALETTES (INSTEAD OF STANDARD), WE SHOULD PUT IN A WILDCARD +* ONE FOR PROGRAMS THAT DON'T CARE (EX. ZONE RUNNER, ROGUE, ETC.) THAT CAN +* RUN ON ANY TYPE AS LONG AS THERE IS ROOM, BASED ON MINIMUM X/Y SIZES. +* (AND IT HAS TO BE ON A GRAPHICS WINDOW) +* SC.USERS count will be at least 1 (for the underlying size select window) + +* This chunk checks against window types for screens in active use... +GETPSCR1 lda SC.WTYPE,U Get screen type + cmpa PROCWTYP+1 Same as window type needed for process? + bne GETPSCR2 No, try next screen + lda SC.USERS,U Screen initialized already? + bne GETPSCR8 Yes, skip ahead +GETPSCR2 incb Set active screen to next one + stb ACTVSCRN+1 + leau SC.SIZE,U Bump to next screen table +GETPSCR3 cmpb #8 On last possible active screen? + blt GETPSCR1 No, check this screen +* No current screen entry of correct type + ldu #SCRNTABL IF on last screen, point to start of screen table + clrb Next routine starts @ screen 0 again + bra GETPSCR5 See if we can add new screen to list + +* This chunk checks to see if we can add a new screen to the screen table +GETPSCR4 lda SC.USERS,U Is this screen initialized already? + beq GETPSCR7 No, use it + incb Yes, try next one + leau SC.SIZE,U +GETPSCR5 stb ACTVSCRN+1 Save screen # + cmpb #8 On last one? + blt GETPSCR4 No, check next + ldd #-1 ERROR - no room for new screen +GETPSCR6 std ,S Save flag as to what happened + bra GETPSCR9 Restore regs & exit + +* Empty screen table entry - add new entry (Screen) for process +GETPSCR7 ldd PROCWTYP Get process window type + stb SC.WTYPE,U Save as screen table screen type + pshs D Save it + bsr OPNSLSHW Open new window (/w) + leas 2,S Eat stack + stb SC.PTHNO,U Save new window path # +GETPSCR8 ldb SC.PTHNO,U Get path # to screen + sex Save it as D for subroutines + std ,S + blt GETPSCR9 If new window failed, exit + inc ACTVSCRN+1 Bump up active screen # + bsr INITPSCR Select new window, LSET to XOR, set up mouse +GETPSCR9 puls D,U,PC + +* Select new window, prepare for sizing/etc. +INITPSCR pshs D Save new window path # + pshs D & again + lbsr INITMOUS Set mouse parms & turn auto follow on + lbsr CURSCLOF Cursor & scaling off + lbsr SELECT Select new window as interactive one + ldd #3 gfx logic set to XOR + std 2,S + lbsr LSET + clr 3,S + lbsr PAUSECHO Shut echo & pause off + leas 4,S Eat stack & return + rts + +* Create new window - GSHPAL window stuff & VDGINT stuff should go here! +* Called from GETPSCR7 only. Should be able to sneak GSHPAL flag as 1st byte +* of window type (0=not gshpal, <>0=gshpal), so window type needs no +* massaging here (or, do masks here) +* Entry: 0-1,s = RTS address +* 2-3,s = window type +* Exit: D=New window path # +* <0 means failure on OPEN +OPNSLSHW pshs U + ldx #SLASHW + lda #UPDAT. + lbsr I.OPEN Open /w + tfr D,U Copy path # to U + std -2,S + blt OPNSLSHX Error opening path, exit + ldb #80 + lda 5,S Get window type (could put GSHPAL flag at 4,s) +* beq SetupVDG Add this in for when we do VDG window support + anda #1 See if 40 or 80 column window + bne OPNSLSH2 + ldb #40 +OPNSLSH2 pshs d Save window width for DWSET + ldb #2 Border color=2 + pshs d + clrb Background color=0 + pshs d + incb Foreground color=1 + pshs d + ldb #25 Window height=25 + pshs d + ldx 8,S Get window width + clrb + pshs d,X Save Y start & window width + pshs d Save X start + ldd 20,S Get window type + pshs d Save for DWSET + pshs U Save path # to new window (new screen) + lbsr DWSET Set the window + clrb + std 2,S + lbsr DWPROTSW + leas 20,S Eat temp stack +OPNSLSHX tfr U,D Transfer new window path # to D & exit + puls U,PC + +SRWINDOW decb - Note, if B does not need to be signed, change + ldx #SCRNTABL LEAX d,x to abx + aslb + aslb + leax D,X + rts + +LINKWNDW bsr SRWINDOW + inc SC.USERS,X + rts + +* Unlink window from active screen list +UNLKWNDW ldd 2,S + bsr SRWINDOW + dec SC.USERS,X Dec # users on current screen + bne UNLKWND1 Still some left, exit +* Close current SC.* entry path +* Entry: X=ptr to current entry in used screen table +CLOSE.X lda SC.PTHNO,X Get path to window + os9 I$CLOSE Close it + clra Flag as no path anymore & return + sta SC.PTHNO,X +UNLKWND1 rts + +* Calc highest pixel values allowed for AIF entry (X&Y), and window type +* Saves PROCYSIZ, PROCXSIZ, PROCWTYP +* Entry: X=ptr to ID.* structure +GFXSIZXY ldd ID.XSIZE,X Get min. X size for AIF entry + lbsr MULDX8 *8 for pixels + subd #1 -1 for far right pixel base 0 + std PROCXSIZ Save as min. X size for process + ldd ID.YSIZE,X Do pixel Y calc + lbsr MULDX8 + subd #1 + std PROCYSIZ Save as min. Y size for process + ldd ID.WTYPE,X Save AIF window type too. + std PROCWTYP + rts + +ENV.FILE fcc "/dd/sys/env.file" + fcb NUL + +GET.ENV pshs U + ldu #ENVFLBFR Point U to 80 char buffer for enviornment file lines + ldd #$ffff Defaults for keyboard & mouse stuff + std ' for help box + stb 5,S + leax " + +ONESPACE fcc " " + +* memory allocation ala K&R +* functionally identical to the C stuff from MicroWare +* but 75% as much code and faster +* calloc split out to save size +* Allocates memory in multiples of 256 bytes (pages) +* Exit:D=-1 If could not get the memory requested + +MORECORE ldd 2,S get nu (Get # 4 byte units requested) + addd #255 nu + NALLOC - 1 Round up to even 256 byte page + clrb divided by NALLOC + pshs D rnu = result Save # of 256 byte pages needed + aslb * sizeof(HEADER) (Multiply by 4) + rola + aslb + rola + pshs D Save # + lbsr SBRK Go allocate more data mem & clear it + leas 2,S Eat temp + puls U get rnu into U (U=# 256 byte pages requested) + cmpd #-1 Did we get our requested data memory? + beq ANRTS No, return with D=-1 + exg D,U Swap # 256 byte pages & ptr to start of free data mem + std 2,U Save # 256 byte pages at 2, + leau 4,U up += 1 (Point to next entry after free data header)?? + pshs U Save ptr + bsr FREE + leas 2,S waste up + ldu ALLOCP,Y return allocp (never 0) +ANRTS rts + +* Allocate memory within our data area +MALLOC pshs D,U Preserve regs + ldd 6,S Get # bytes to be allocated + addd #3 nbytes + sizeof(HEADER) - 1 + lsrd div by sizeof(HEADER) (4 bytes) + lsrd + incd result+1 + std ,S nunits = result (units allocated seems to be 4 byte chunks) + ldx ALLOCP,Y q = allocp (Get current value) + bne MALLOC1 if not 0 (If not zero, it has been initialized) + ldx #BASE q = &base (Initialize it to BASE) + stx ALLOCP,Y allocp = q = &base + stx BASE,Y base.ptr = .... = &base (BASE points to itself) + clrd + std BASE+2,Y base.size = 0 (it's size=0) +MALLOC1 ldu ,X p = q->ptr (Get ptr to current allocp (last mem entry?) + bra MALLOC3 + +MALLOC2 tfr U,X q = p + ldu ,U p = p->ptr +MALLOC3 ldd 2,U Get size of last block allocated + cmpd ,S Compare with # 4 byte blocks requested + blo MALLOC6 if (p->size >= nunits) + bne MALLOC4 if (p->size == nunits) + ldd ,U + std ,X q->ptr = p->ptr + bra MALLOC5 + +MALLOC4 ldd 2,U p->size -= nunits + subd 0,S + std 2,U + aslb (char) p->size + rola + aslb + rola + leau D,U p += (char) p->size + ldd ,S p->size = nunits + std 2,U + +MALLOC5 stx ALLOCP,Y allocp = q + leau 4,U p += 1 (header) + tfr U,D set up for return + bra MALLOC7 + +MALLOC6 cmpu ALLOCP,Y if (p == allocp) + bne MALLOC2 + lbsr MORECORE nunits above return addr (Get more data mem) + bne MALLOC2 if (p = .... == 0) (Get mem failed?) + clrd set up zero for return +MALLOC7 leas 2,S + puls U,PC + +* Entry: 0-1,s RTS address +* 2-3,s Ptr of some sort (to data area after 4 byte header?) +* D=# 256 byte pages requested +* U=Ptr to header+4 +FREE pshs D,U Save ??? ptr & #256 byte pages + ldu 6,S Get ptr to data start of allocated chunk? + leau -4,U p = ap - 1 (Point to star of chunk header?) + ldx ALLOCP,Y q = allocp ??? + bra FREE3 + +FREE1 cmpx ,X if (q >= q->ptr) + blo FREE2 + cmpu ,S && (p > q + bhi FREE4 + cmpu ,X || p < q->ptr) + blo FREE4 break +FREE2 ldx ,X q >= q->ptr +FREE3 stx ,S q' = q Save ??? (chunk header?) + cmpu ,S if (p > q) Is + bls FREE1 + cmpu ,X && (p < q->ptr) + bhs FREE1 +FREE4 pshs U stack p + ldd 2,U t$1 = p->size + aslb scale it + rola + aslb + rola + addd ,S++ t$1 = p + p->size + cmpd ,X if (p + p->size == q->ptr) + bne FREE5 + pshs X save q + ldx ,X q = q->ptr + ldd 2,X t$1 = q->ptr->size + puls X recover q + addd 2,U t$1 = p->size + p->ptr->size + std 2,U p->size = t$1 + ldd [,X] t$1 = q->ptr->ptr + bra FREE6 + +FREE5 ldd ,X t$1 = q->ptr +FREE6 std ,U p->ptr = t$1 + ldd 2,X t$1 = q->size + aslb scale it + rola + aslb + rola + addd ,S t$1 = q + q->size +*NOTE 6309:CMPR D,U + pshs D + cmpu ,S++ if (q + q->size == p) + bne FREE7 + ldd 2,X t$1 = q->size + addd 2,U t$1 += p->size + std 2,X q->size = t$1 + ldd ,U t$1 = p->ptr + std ,X q->ptr = t$1 + bra FREE8 + +FREE7 stu ,X q->ptr = p +FREE8 stx ALLOCP,Y allocp = q + bra MALLOC7 + +NMLNKLOD pshs U + leas -4,S + leax ,S + leau 2,S + pshs X,U + ldu 12,S + ldd GD.MNAME,U + pshs D + bsr F.NMLINK + std -2,S + bne LINLOA1 + bsr F.NMLOAD + std -2,S + bne LINLOA1 + leas 6,S + bra LINLOA3 + +LINLOA1 leas 6,S + ldb 1,S + andb #$F0 + lsrb + lsrb + lsrb + lsrb + stb GD.MTYPE,U + ldb 1,S + andb #$0F + stb GD.MLANG,U + ldd GD.MEMSZ,U + bne LINLOA3 + ldd 2,S + tstb + beq LINLOA2 + inca +LINLOA2 tfr A,B + clra + std GD.MEMSZ,U + ldb #1 +LINLOA3 leas 4,S + puls U,PC + +F.NMLOAD pshs X,Y + ldx 6,S + clra + os9 F$NMLOAD + bra F.NML1 + +F.NMLINK pshs X,Y + ldx 6,S + bsr SKPSLASH + clra + os9 F$NMLINK +F.NML1 bcc F.NML2 + puls X,Y + stb ERRNO+1,Y + clrd + rts + +F.NML2 sty [10,S] + tfr A,B + clra + std [8,S] + ldb #1 + puls X,Y,PC + +F.UNLOAD ldx 2,S + bsr SKPSLASH + clra + os9 F$UNLOAD + rts + +SKPSLASH pshs X + lbsr STREND1 +SKPSLAS1 cmpx ,S + ble SKPSLAS2 + ldb ,-X + cmpb #'/ + bne SKPSLAS1 + leax 1,X + stx ,S +SKPSLAS2 puls X + rts + +KILLPBUF clrb + pshs D + ldx PRCIDNUM + ldd WNDWPATH + pshs D,X + lbsr KILBUF + leas 6,S + rts + +* NOTE: ONLY CALLED FROM +* Wait for forked program to die (or wait for signal) +* Entry: [,x] is a ptr to a 16 bit area to save the child's exit code +* Exit: [,x] child's exit code +* D=0 - if [,x] ptr was 0 +* else D= Child's proces # +F.WAIT clrd Wait for signal + os9 F$WAIT + bcs OS9ERR2 Error, save error code & return (no child process) + ldx 2,S Get ptr to ??? + beq F.WAITX If 0, exit with child ID process #=0 + stb 1,X Save child's exit code in pointed to area + clr ,X +F.WAITX tfr A,B D=Deceased child process's ID # + clra + rts + +F.FORK pshs Y,U + ldx 6,S + ldy 8,S + ldu 10,S + lda 13,S + ora 15,S + ldb 17,S + os9 F$FORK + puls Y,U + bcs OS9ERR2 + tfr A,B + clra + rts + +* Raw read +I.READ pshs Y Save Y + ldx 6,S Get ptr to buffer to read into + lda 5,S Get file path + ldy 8,S Get size of read + os9 I$READ Read data +READ1 bcc WRITE10 + cmpb #E$EOF EOF error? + bne WRITERR No, report error + clrd If EOF error, report 0 bytes read + puls Y,PC + +* Read line: Exits with D=# bytes read +I.READLN pshs Y + lda 5,S + ldx 6,S + ldy 8,S + os9 I$READLN + bra READ1 + +I.WRITE pshs Y + ldy 8,S + beq WRITE10 + lda 5,S + ldx 6,S + os9 I$WRITE +WRITE1 bcc WRITE10 +WRITERR puls Y +OS9ERR2 lbra OS9ERR + +WRITE10 tfr Y,D + puls Y,PC + +* Perform WritLn call +* Entry: 0-1,s =RTS address +* 2-3,s =Path to write to (use only B) +* 4-5,s =Ptr to text to write +* 6-7,s =Length to write +I.WRITLN pshs Y + ldy 8,S + beq WRITE10 + lda 5,S + ldx 6,S + os9 I$WRITLN + bra WRITE1 + +I.DUP os9 I$DUP + bra ERRTEST + +I.OPEN2 ldx 2,S + lda 5,S +I.OPEN os9 I$OPEN +ERRTEST bcs OS9ERR2 + tfr A,B + clra + rts + +I.CLOSE lda 3,S + os9 I$CLOSE + bra I.SYSRET + +I.MAKDIR ldx 2,S + ldb 5,S + os9 I$MAKDIR + bra I.SYSRET + +I.DELETE ldx 2,S + os9 I$DELETE +I.SYSRET lbra SYSRET + +* Get String length - terminated by NUL (CHR$(0)) char +* Entry: 0-1,s is RTS address +* 2-3,s is the ptr to the string to check +* Exit: X=Ptr to end of string (not including NUL) +* D=Length of string +STRLEN ldx 2,S Get ptr to string we are checking length of +STRLEN1 ldb ,X+ Get char + bne STRLEN1 Not end of string, keep checking + leax -1,X Found it, point to last char + tfr X,D + subd 2,S D=length of string + rts + +* Get string end - terminated by NUL char +* Entry: [,s] is the ptr to the string to check +* Exit: D=Ptr to end of string (not including NUL) +STREND ldx 2,S +STREND1 ldb ,X+ + bne STREND1 + leax -1,X + tfr X,D + rts + +STRCPY pshs X,U + ldu 6,S +STRCAT2 ldx 8,S +STRCPY1 ldb ,X+ + stb ,U+ + bne STRCPY1 + ldd 6,S + puls X,U,PC + +STRCAT pshs X,U + ldu 6,S +STRCAT1 ldb ,U+ + bne STRCAT1 + leau -1,U + bra STRCAT2 + +* Compare two strings +* Exit: D=0 if they are the same +* D=-1 if they are not the same +STRCMP pshs X,U Save regs + ldu 6,S Get ptr to 1st string + beq STRCMP2 No string, exit with <> + ldx 8,S Get ptr to 2nd string + beq STRCMP2 No string, exit with <> +STRCMP1 ldb ,U+ Get char from 1st string + cmpb ,X+ Same as char from 2nd string? + bne STRCMP2 No, exit with <> + tstb Same, is it an end of string marker? + bne STRCMP1 No, continue comparing + clra Exit with '=' + puls X,U,PC + +* Flag not equal strings +STRCMP2 ldd #-1 + puls X,U,PC + +* String compare with maximum length of strings +* Exit: D=-1 if they are <> +* D=0 if they are = +STRNCMP pshs X,U + ldu 6,S Get ptr to string 1 + beq STRNCMP4 + ldx 8,S Get ptr to string 2 + beq STRNCMP4 + lda 11,S Get maximum size to compare + beq STRNCMP2 If 0, exit with = +STRNCMP1 deca Done max length? + blt STRNCMP3 Yes, process + ldb ,U+ Get char + cmpb ,X+ Same as in 2nd string? + bne STRNCMP4 No, exit with <> + tstb End of string early? + bne STRNCMP1 No, continue comparing +STRNCMP2 clrd Exit with = + puls X,U,PC + +* If done up to max length, compare last chars of each string +* NOTE: THIS LOOKS LIKE THE LDB/CMPB/BEQ IS USELESS??? SHOULD JUST EXIT +* WITH D=0??? +STRNCMP3 ldb ,-U If last 2 chars matched, exit with = + cmpb ,-X + beq STRNCMP2 +STRNCMP4 ldd #-1 Exit with <> +STRNCMPX puls X,U,PC + +STRHCPY pshs U + ldu 4,S + ldx 6,S +STRHCPY1 ldb ,X+ + stb ,U+ + bgt STRHCPY1 + andb #$7F + stb -1,U + clrb + stb ,U + ldd 4,S + puls U,PC + +* Copy B bytes from X to Y +* NOTE: CHANGE TO TFM! +STRNCPY pshs X,U + ldu 6,S + ldx 8,S + ldb 11,S +STRNCPY1 lda ,X+ + sta ,U+ + decb + bne STRNCPY1 + puls X,U,PC + +* Allocate more memory from our remainding data memory, or get more data mem- +* ory and allocate from that +* Exit:D=-1 if could not get memory +* or D=Ptr to start of free data memory +SBRK ldd MEMEND,Y Get end of data memory ptr + pshs D Save it + ldd 4,S Get # bytes requested + cmpd SPARE,Y Will that fit in what we have left right now? +* following should be BLO + bcs SBRK20 Yes, skip ahead + addd MEMEND,Y Calculate what total data area size should now be + bcs SBRK05 >64k, too big to fit in process space, exit with error + pshs Y Preserve Y + os9 F$MEM Attempt to change data area size to D bytes + tfr Y,D Move new end of data mem address to D + puls Y Restore Y + bcc SBRK10 No error on F$MEM call, continue +SBRK05 ldd #-1 Eat stack & exit with error flag set + leas 2,S + rts + +* Extra memory requested was succesful +SBRK10 std MEMEND,Y Save new end of data mem ptr + addd SPARE,Y Add to amount of free data mem before request came in + subd ,S Subtract original end of data mem ptr + std SPARE,Y Save new amount of spare data mem +SBRK20 leas 2,S + ldd SPARE,Y Get amount of spare data mem + pshs D + subd 4,S Subtract the amount of mem requested + std SPARE,Y Save new amount of spare data mem + ldd MEMEND,Y Get end of data mem ptr +* NOTE 6309:SUBR, AND KEEP SIZE OF SPARE MEM. CHANGE LOOP BELOW TO TFM + subd ,S++ Calculate start address of free data mem + pshs D Save it + clra Zero byte + ldx ,S X=start of free data mem +SBRK30 sta ,X+ Clear out all free data mem + cmpx MEMEND,Y + bcs SBRK30 + puls D,PC Get ptr to start of data mem & return with it + +GT.READY lda 3,S + ldb #SS.READY + os9 I$GETSTT + bcs OS9ERR3 + clra + rts + +* setup mouse parms - NOTE: should embed elsewhere - only called once. +* In routine: 0-1,s = Preserved Y +* 2-3,s = RTS address +* 4-5,s = Path to window to read mouse from +* 6-7,s = Mouse sampling rate +* 8-9,s = Mouse button timeout +* 10-11,s= Auto follow mouse flag +ST.MOUSE pshs Y Preserve Y + lda 7,S Get # clock ticks between mouse reads + ldb 9,S Get mouse button timeout value + tfr D,X + clra Get auto-follow flag + ldb 11,S + tfr D,Y + lda 5,S Get path for window mouse is on + ldb #SS.MOUSE Setup mouse parms + os9 I$SETSTT + puls Y Restore Y & return + bra SYSRET2 + +GT.MOUSE lda 3,S + ldb #SS.MOUSE + ldx 4,S + pshs Y + ldy #0 + os9 I$GETSTT + puls Y + bra SYSRET2 + +ST.SSIG lda 3,S + ldb #SS.SSIG + ldx 4,S + os9 I$SETSTT + bra SYSRET2 + +ST.RELEA lda 3,S + ldb #SS.RELEA + os9 I$SETSTT +SYSRET2 lbra SYSRET + +OS9ERR3 lbcs OS9ERR + pshs A + sex + std [5,S] + puls B + clra + rts + +* Get current screen size in 8x8 text chars +* Entry: 0-1,s = RTS address +* 2-3,s = 16 bit path # (only use 3,s) +* 4-5,s = Ptr to where to store X size +* 6-7,s = Ptr to where to store Y size +GT.SCSIZ lda 3,S Get path to screen + ldb #SS.SCSIZ + pshs X,Y Preserve regs + os9 I$GETSTT + bcs SCSIZERR + stx [8,S] Save X size (by pointer) + sty [10,S] Save Y size (by pointer) + clrd + bra SCSIZEXT + +SCSIZERR ldy 2,S Get data area pointer back + clra + std ERRNO,Y Save error code + ldd #-1 Flag error & return +SCSIZEXT puls X,Y + rts + +ST.SBAR lda 3,S + ldb #SS.SBAR + ldx 4,S + pshs Y + ldy 8,S + os9 I$SETSTT + puls Y + bra SYSRET2 + +ST.MSSIG lda 3,S + ldb #SS.MSSIG + ldx 4,S + os9 I$SETSTT + bra SYSRET2 + +* Do WINDINT window style +* Entry: 0-1,s =RTS address +* 2-3,s =Window path (only use B) +* 4-5,s =window type (WT.*) +* 6-7,s =Ptr to window/menu data (for framed windows only) +ST.WNSET lda 3,S Get path + ldb #SS.WNSET + pshs Y + ldy 6,S Get window type + ldx 8,S Get ptr for framed window data + os9 I$SETSTT Convert current window + puls Y + bra SYSRET2 + +* Entry: all parms for DWSET are on stack, in order-but with 2 bytes/parm +* whether it needs it or not! +* 0-1,s: RTS address +* 2-3,s: path # to window +* 4-5,s: screen type +* etc. for other DWSET parms +DWSET ldd #$1B20 Device window Set + bsr DW.OWSET Set up GFXBUF to contain full display code sequence for DWSET + ldb #9 # of bytes to write in DWSET sequence + tst 5,S Check low byte of window type (actual type) + ble DOWSETX If current displayed or current processes screen, don't bother with border + incb If positive, bump # bytes up to 10 (to cover border color) +DOWSETX bra GFXWR3 Go write it out and return from there + +OWSET ldd #$1B22 + bsr DW.OWSET + ldb #9 + bra DOWSETX + +DW.OWSET ldx #GFXBUF Place to put actual command bytes for DWSET + std ,X++ Save command sequence + lda 7,S Get screen type (low byte only) + ldb 9,S + std ,X++ Get start, end ,etc. parms & append them + lda 11,S + ldb 13,S + std ,X++ + lda 15,S + ldb 17,S + std ,X++ + lda 19,S + ldb 21,S Get border color (may not be used) + std ,X + rts + +DWEND ldd #$1B24 + bra OUT2 + +OWEND ldd #$1B23 + bra OUT2 + +SELECT ldd #$1B21 + +OUT2 std GFXBUF,Y + ldb #2 + bra GFXWR3 + +CWAREA ldd #$1B25 + ldx #GFXBUF + std ,X++ + lda 5,S + ldb 7,S + std ,X++ + lda 9,S + ldb 11,S + std ,X + ldb #6 + bra GFXWR3 + +GCSET ldd #$1B39 + bra OUT4 + +FONT ldd #$1B3A + bra OUT4 + +KILBUF ldd #$1B2A +OUT4 ldx #GFXBUF + std ,X++ + lda 5,S + ldb 7,S + std ,X + ldb #4 +GFXWR3 lbra GFXWR + +SCALESW ldb #$35 + bra OUT3 + +DWPROTSW ldb #$36 + bra OUT3 + +FCOLOR ldb #$32 + bra OUT3 + +LSET ldb #$2F +OUT3 lda #$1B + std GFXBUF,Y + ldb 5,S + stb GFXBUF+2,Y + ldb #3 + bra GFXWR3 + +LINE ldb #$44 + bra OUT6 + +LINEM ldb #$46 + bra OUT6 + +RLINE ldb #$45 + bra OUT6 + +BOX ldb #$48 + bra OUT6 + +RBOX ldb #$49 + bra OUT6 + +SETDPTR ldb #$40 +OUT6 lda #$1B + ldx #GFXBUF + std ,X++ + ldd 4,S + std ,X++ + ldd 6,S + std ,X + ldb #6 + bra GFXWR + +PUTBLK ldx #GFXBUF + ldd #$1B2D + std ,X++ + lda 5,S + ldb 7,S + std ,X++ + ldd 8,S + std ,X++ + ldd 10,S + std ,X + ldb #8 + bra GFXWR + +FFILL ldd #$1B4F + std GFXBUF,Y + ldb #2 + bra GFXWR + +GPLOAD ldx #GFXBUF + ldd #$1B2B + std ,X++ + lda 5,S + ldb 7,S + std ,X++ + lda 9,S + sta ,X+ + ldd 10,S + std ,X++ + ldd 12,S + std ,X++ + ldd 14,S + std ,X + ldd 2,S + pshs D + ldb #11 + bsr GFXWR + leas 2,S + ldx 16,S + pshs Y + ldy 16,S + lda 5,S + os9 I$WRITE + bcs GFXERR + puls Y,PC + + +* Entry:B= # bytes to write +GFXWR clra D=B + ldx #GFXBUF Point to buffer that holds graphics commands to execute + pshs Y + tfr D,Y Length of command sequence to write + lda 5,S Get path # to write to + os9 I$WRITE Send gfx command + puls Y + bcs GFXERR + clra + clrb + rts + +GFXERR clra + std ERRNO,Y + ldd #-1 + rts + +* Convert ASCII # to 16 bit signed integer +* NOTE:WILL DO WEIRD THINGS IF RESULT IS >65535 (WRAPS AT 16 BIT) +* Works by saving neg/pos flag, and then going from left to right, multiplying +* cumulative result by 10 each time a new digit is found, until non-digit +* found. Also eats leading spaces & tabs. +* Entry: ptr to ASCII buffer on stack +* Exit: D=signed 16 bit value +ATOI pshs U Preserve U + ldu 4,S Get ptr to text to convert + clrd Clear carry, and default # to 0 + pshs CC,d,dp CC=storage for current ASC char, dp=sign, D=current result +ATOI1 ldb ,U+ Get 1st ascii character + stb ,S Save it + cmpb #SPACE Is it a space? + beq ATOI1 Yes, skip that char + cmpb #HT Is it a TAB char? + beq ATOI1 Yes, skip that char + cmpb #'- Is it a negative sign? + bne ATOI2 No, process character + ldb #1 Flag that we are working with a negative # + bra ATOI3 + +ATOI2 clrb Flag that it is a positive # +ATOI3 stb 3,S Save positive/negative flag + ldb ,S Get char again + cmpb #'- Was it a negative sign? + beq ATOI5 Yes, go onto next character + cmpb #'+ Was it a plus sign? + bne ATOI6 No, go check if it was a numeric char + bra ATOI5 +, skip to next char +* CHANGE MAIN LOOP TO PRE SUBTRACT #$30 INSTEAD OF CMP 1ST WHEN CHECKING +* RANGE (?) + +ATOI4 ldd 1,S Get current result (so far) + muld #10 Bump up by one order of magnitude (Since on next digit) + ldb ,S Get original numeric char + sex make 16 bit (note: still ascii version!) + addr w,d Add to current base digit value (1,10,100,1000,10000) + std 1,S Save current result +ATOI5 ldb ,U+ Get next char from ASCII buffer +ATOI6 subb #$30 Convert to binary + stb ,S Save it + blt ATOI65 Below '0', stop conversion + cmpb #9 Above '9'? + bls ATOI4 No, numeric, go process + cmpb #'0 Below a numeric char? + blo ATOI65 Yes, skip ahead + cmpb #'9 Above a numeric char? + bls ATOI4 No, a numeric, go process +* Non numeric char stops conversion +ATOI65 ldd 1,S Get current result + tst 3,S Was there a negative sign? + beq ATOI8 No, done + negd +ATOI8 leas 4,S Eat temp vars + puls U,PC Restore U & exit + +CCMOD leax " + fcb NUL,NUL,NUL,NUL,NUL,NUL + fcb 0,0,0,0 + fcb 0,0 + + fcc "V#1.26" + fcb NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL + fcb 0,0,0,0 + fcb 0,0 + +* TNDYDESC + + fcc "Tandy" + fcb NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL + fcb NUL,NUL + fcb MID.TDY + fcb 8,8,1 + fdb $0000 + fdb TNDYITMS + +* FILSDESC + + fcc "Files" + fcb NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL + fcb NUL,NUL + fcb MID.FIL + fcb 6,9,1 + fdb $0000 + fdb FILSITMS + +* DISKDESC + + fcc "Disk" + fcb NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL + fcb NUL,NUL,NUL + fcb MID.DSK + fcb 12,6,1 + fdb $0000 + fdb DISKITMS + +* VIEWDESC + + fcc "View" + fcb NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL + fcb NUL,NUL,NUL + fcb MID.VEW + fcb 13,3,1 + fdb $0000 + fdb VIEWITMS + +* KDMDESC + + fcc "About.." + fcb NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL + fcb MID.KDM + fcb 9,2,1 + fdb $0000 + fdb KDMITMS + +* SHELLNAM + + fcc "shell" + fcb NUL + +* LISTNAM + + fcc "list" + fcb NUL + +* GCALCNAM + + fcc "gcalc" + fcb NUL + +* GCLOCKNM + + fcc "gclock" + fcb NUL + +* GCALNAM + + fcc "gcal" + fcb NUL + +* CONTROLNM + + fcc "control" + fcb NUL + +* GPRINTNM + + fcc "gprint" + fcb NUL + +* GPORTNAM + + fcc "gport" + fcb NUL + +* HELPNAM + + fcc "help" + fcb NUL + +* COCPRNM + + fcc "cocopr" + fcb NUL + +* SCRLPTRS table of pointers was here + +* DBOXDESC + + fdb 48,0,56,8 + fcb IC.CLOSE + fcb 0 + fdb DBARDESC + fdb $0000 + +* DBARDESC + + fdb 58,0,600,8 + fcb IC.DRBAR + fcb 0 + fdb QURYDESC + fdb $0000 + +* QURYDESC + + fdb 600,0,623,8 + fcb IC.QUERY + fcb 0 + fdb $0000,$0000 + +* TRSHDESC - moved down to make room for printer + fdb 8,160,32,184 Was 8,144,32,168 + fcb IC.TRASH + fcb 0 + fdb $0000,$0000 + +* PRTRDESC - NEW + fdb 8,133,32,148 + fcb IC.PRNTR + fcb 0 + fdb $0000,$0000 + +* CALCDESC + + fdb IC.GCALC + fdb 6,20,12,1 + fdb 0,0 + fdb GCALCNAM + fdb $0000,$0000 + fdb CLOKDESC + +* CLOKDESC + + fdb IC.GCLOK + fdb 6,20,10,1 + fdb 0,0 + fdb GCLOCKNM + fdb $0000,$0000 + fdb CALDESC + +* CALDESC + + fdb IC.GCAL + fdb 6,40,25,1 + fdb 0,0 + fdb GCALNAM + fdb $0000,$0000 + fdb SHELDESC + +* SHELDESC + + fdb IC.SHELL + fdb 6,10,5,1 + fdb 0,0 + fdb SHELLNAM + fdb $0000,$0000 + +* ENDLINK + + fdb $0000 + +* NXTICONO + + fdb IC.XTRNL + +* PRESSMSG + + fcc "Press any key" + fcb NUL + +* NEWNMSG + + fcc "New name: " + fcb NUL + +* SLASHW + + fcc "/w" + fcb NUL + +* ALLOCP + + fcb 0,0,0 + +DTXCOUNT + + + emod + +MODSIZE equ * + + end +