Mercurial > hg > Members > kono > nitros9-code
changeset 714:2e5433122a67
Fixed line ending problem
author | boisy |
---|---|
date | Sat, 04 Jan 2003 03:15:13 +0000 |
parents | e81574187272 |
children | 59a079eb1b0b |
files | level1/cmds/shellplus.asm |
diffstat | 1 files changed, 3624 insertions(+), 3624 deletions(-) [+] |
line wrap: on
line diff
--- a/level1/cmds/shellplus.asm Sat Jan 04 02:26:02 2003 +0000 +++ b/level1/cmds/shellplus.asm Sat Jan 04 03:15:13 2003 +0000 @@ -1,3624 +1,3624 @@ -******************************************************************** -* Shellplus - Enhanced shell for OS-9 Level Two -* -* Modified by L. Curtis Boyle from original 2.2 disassembly -* -* $Id$ -* -* Ed. Comments Who YY/MM/DD -* ------------------------------------------------------------------ -* 21 Original Tandy/Microware version -* 22a History and numerous features added - - nam Shell - ttl program module - -* Disassembled 93/04/15 14:58:18 by Disasm v1.6 (C) 1988 by RML -* Signals: Signals 2 & 3 are assigned new keys to handle forward/backward -* command history. Signal $B (11) is the signal sent out on a key being ready -* for normal command processing - - ifp1 - use defsfile - endc - -tylg set Prgrm+Objct -atrv set ReEnt+rev -rev set $02 - mod eom,name,tylg,atrv,start,size - -u0000 rmb 1 Path # for standard input -u0001 rmb 1 Path # for standard output -u0002 rmb 1 Path # for standard error -u0003 rmb 1 # of 256 byte pages of data mem for frked module -u0004 rmb 2 Temp ptr (current parse ptr, mem module ptr,etc) -u0006 rmb 2 Size of current group -u0008 rmb 2 Pointer to start of current group (past '(') -u000A rmb 2 -u000C rmb 1 Current char. being processed in command parser -u000D rmb 1 # of command groups [ '()' groupings ] -u000E rmb 1 unprocessed signal # (0=none waiting) -u000F rmb 1 ??? Flag of some sort -u0010 rmb 2 ??? (ptr to some module name) -u0012 rmb 1 Current working DIR path # -u0013 rmb 1 Flag to kill parent process (1=Kill parent) -u0014 rmb 1 Flag: If set, a result must not be 0 ??? -u0015 rmb 1 -u0016 rmb 1 -u0017 rmb 1 -u0018 rmb 1 Immortal shell (0=NO) -* A clearing routine only does u0000 to u0018 -u0019 rmb 1 -u001A rmb 2 -u001C rmb 1 Shell logging on flag (0=OFF) -u001D rmb 1 Shell prompting (0=ON) -u001E rmb 1 Echo input (0=OFF) -u001F rmb 1 Variable expansion (0=ON) -u0020 rmb 1 Kill shell on error (0=OFF) -u0021 rmb 1 Process # to set priority on -u0022 rmb 1 Priority to set (0=don't change) (ours or fork) -u0023 rmb 2 -u0025 rmb 2 End of data mem ptr (top of stack) -u0027 rmb 1 -u0028 rmb 1 -u0029 rmb 1 -u002A rmb 2 -u002C rmb 2 -u002E rmb 1 -u002F rmb 1 -u0030 rmb 1 -u0031 rmb 1 -u0032 rmb 2 -u0034 rmb 3 -u0037 rmb 1 Flag: 0=Data dir .PWD invalid, 1=valid -u0038 rmb 1 Flag: 0=Exec dir .PXD invalid, 1=valid -u0039 rmb 1 -u003A rmb 1 -u003B rmb 2 -u003D rmb 1 -u003E rmb 2 -u0040 rmb 2 Ptr to start of filename (vs. pathname) ('/') -* Shell prompt flag -u0042 rmb 1 Current working dir path already done flag -u0043 rmb 1 -u0044 rmb 1 -u0045 rmb 1 ??? <>0 means looking for GOTO label? -u0046 rmb 1 Flag: 1=GOTO label found? -u0047 rmb 1 Error code from ReadLn or signal -u0048 rmb 2 Ptr to 1st char after redirection symbols -u004A rmb 2 Ptr to text message -u004C rmb 2 Size of text message -u004E rmb 1 -u004F rmb 1 0=no pathname in parm line, else IS pathname -u0050 rmb 2 -u0052 rmb 2 Current expanded buffer size (max=2048) -u0054 rmb 2 Ptr to current char in wildcard filename we are -* checking -u0056 rmb 2 Ptr to current pos in expanded buffer -u0058 rmb 2 Pointer to end of GOTO label name -u005A rmb 2 User ID # from F$ID call -u005C rmb 1 -u005D rmb 1 -u005E rmb 1 Device type: 0=SCF (keyboard),1=RBF (Scriptfile) -u005F rmb 1 -u0060 rmb 1 Data module linked flag: 1= Yes -u0061 rmb 2 Ptr to data module name -u0063 rmb 2 Ptr to intercept routines data mem -u0065 rmb 2 Execution address of linked module -u0067 rmb 2 Start address of module -u0069 rmb 2 -u006B rmb 1 Flag: 0=No module to unlink, <>0 module to unlink -u006C rmb 1 -u006D rmb 1 Start of device name buffer (start with '/') -u006E rmb 71 Actual device name -u00B5 rmb 20 Start of another device name buffer ('/') -u00C9 rmb 13 -u00D6 rmb 13 Standard module header info (M$ID-M$Mem) -u00E3 rmb 5 Module name string (reserves 64 chars) -u00E8 rmb 3 -u00EB rmb 4 -u00EF rmb 10 Temp buffer (many uses) -u00F9 rmb 6 -u00FF rmb 37 Place to point SP when CHAINing -u0124 rmb 81 Temporary buffer (used for several things) -u0175 rmb 119 Part of temp buffer for ReadLn (200 chars total) -u01EC rmb 2 Least sig. 2 digits of process # (ASCII format) -u01EE rmb 1 -u01EF rmb 2 Holding area for 2 digit ASCII conversions -* Shell prompt parsing flags -u01F1 rmb 1 Process ID # already done flag -u01F2 rmb 1 Standard output device name already done flag -u01F3 rmb 1 Quoting on flag in shell prompt string parsing -u01F4 rmb 1 Date already done flag -u01F5 rmb 1 Time already done flag -u01F6 rmb 1 Date OR time already done flag -u01F7 rmb 2 Size of expanded shell prompt -u01F9 rmb 25 Current shell prompt string -u0212 rmb 1 Lead in Line feed for expanded shell prompt -u0213 rmb 199 Expanded shell prompt -u02DA rmb 6 Date/time packet -u02E0 rmb 8 Date string -u02E8 rmb 1 Space separating date & time (for shell init) -u02E9 rmb 9 Time string (and CR) -u02F2 rmb 131 -u0375 rmb 131 -u03F8 rmb 29 -u0415 rmb 2 -u0417 rmb 1 -u0418 rmb 400 Intercept routines memory area (not used) -u05A8 rmb 810 Shell variables (user?) -u08D2 rmb 810 Shell variables (shell sub?) -u0BFC rmb 80 -u0C4C rmb 81 Copy of GOTO label name -u0C9D rmb 32 DIR Entry buffer -u0CBD rmb 32 Shell logging filename (append mode '+') -u0CDD rmb 400 PATH=Buffer (each entry CR terminated) -u0E6D rmb 2048 Fully expanded filenames buffer (for wildcards) -* Actually,this next block appears to be generic buffers for various functions -u166D rmb 80 Process descriptor copies go here (512 bytes) -u16BD rmb 1 -u16BE rmb 80 -u170E rmb 238 -u17FC rmb 10 -u1806 rmb 2 ??? Ptr to end of shell history buffers -u1808 rmb 2 Ptr to where next history entry will go -u180A rmb 2 Ptr to start of shell history buffers -u180C rmb 1 # of lines in history buffer (1-(u180C)) -u180D rmb 1 Current line # in history buffer -u180E rmb 1 Original keyboard terminate char -u180F rmb 1 Original keyboard interrupt char -u1810 rmb 1 -u1811 rmb 1 Original end of line NUL count -u1812 rmb 1 Flag to indicate if we have to restore PD.OPT -u1813 rmb 2 -u1815 rmb 808 Shell history copies start here -u1B3D rmb 963 Local stack space, etc. -size equ . -name equ * -L000D fcs /Shell/ - fcb $16 -L0013 fcb Prgrm+PCode - fcs 'PascalS' - fcb Sbrtn+CblCode - fcs 'RunC' - fcb Sbrtn+ICode -L0021 fcs 'RunB' - fcb $00,$00,$00,$00,$00,$00,$00,$00,$00 -L002E fcb C$LF - fcc 'Shell+ v2.2a ' -L003C fcb $00 -L003D fcc '{@|#}$: ' -L0055 fcc '+++START+++' - fcb C$CR -L0061 fcc '+++END+++' - fcb C$CR -* Intercept routine -L006B stb <u000E Save signal code & return - rti - -start leas -5,s Make 5 byte buffer on stack - pshs y,x,d Save Top/bottom of param area, and size of area - leax >u1815,u Pointer to start of history buffer area - stx >u1808,u Save ptr to where next history entry goes - stx >u180A,u Save ptr to start of history buffers - leax >$0328,x Setup up another pointer (end of history area?) - stx >u1806,u Save it - clr >u1812,u Clear flag that we have to restore PD.OPT - clr >u180D,u Current line # of history buffer=0 - clr >u180C,u # lines in history buffer=0 - ldx 2,s Get back top of data area ptr - ldb #$FF 255 bytes to clear - lbsr L0412 Go clear direct page - sts <u0025 Save current stack ptr - stu <u0027 Save Data mem ptr (0) - leax >u0418,u Point to intercept routines memory area - stx <u0063 Save a copy of it - leax <L006B,pc Point to intercept routine - os9 F$Icpt Setup the intercept routine - lbsr L16A6 Get user #, and make 2 digit ASCII ver. @ 1EC - lbsr L1674 Make shell logging pathname @ CBD - leax <L003D,pc Point to default shell prompt string - lbsr L0A14 Go create shell prompt string & prompt itself - leax >u05A8,u Point to start of shell variables - ldd #C$CR*256+20 Carriage return (blank entries) & all 20 of them -L009C sta ,x Mark shell variable as blank - leax <81,x Point to next entry (81 bytes/entry) - decb Do until all 20 are done (user & shell sub) - bne L009C - sta >u0CDD,u Init 1st 2 entries of PATH= buffer to CR's - sta >u0CDD+1,u - puls x,d Get parameter ptr & parameter size - std <u0006 Save size of parameter area - beq L00BF If no parameters, skip ahead - lbsr L041B Pre-Parse parameters passed to this shell - lbcs L01FA Error, go handle it - tst <u000C Any char being processed in parser? - lbne L01F9 Yes, skip ahead -L00BF lbsr L0225 Release any keyboard/mouse signals & get PD.OPT - inc <u006C ??? Set flag - lds ,s++ Since parameters parsed, point SP to top of mem - sts <u0025 Save end of data mem ptr (top of stack) - stu <u0027 Save start of data mem ptr -L00CC leax >L002E,pc Point to Shellplus v2.2 message - tst <u001D Shell prompting turned on? - bne L00EA No, skip ahead - ldy #$000E Length of message - lda #$01 Standard out - os9 I$Write Write it - lbcs L0200 If error writing, terminate Shellplus - bsr L00FB Go create date & time strings - lbsr L021B Write out date & time - lbcs L0200 If error writing, terminate Shellplus -L00EA clra - sta <u005C - leax >L0055,pc Point to '+++START+++' for shell logging - lbsr L07E7 Go deal with logging if necessary - tst <u001D Shell prompting turn on? - bne L0120 No, skip ahead - bra L010D Yes, do something else first - -L00FB clr >u01F6,u Clear date or time done flag - lbsr L0B3B Create current date & time strings - lda #C$SPAC Put in a space to separate date & time - sta >u02E8,u - leax >u02E0,u Point to start of date buffer - rts - -* Shell just booted goes here -L010D lbsr L09F7 Update expanded shell prompt if needed - leax >u0212,u Point to expanded shell prompt - ldy >u01F7,u Get size of expanded shell prompt -L0119 tst <u001D Shell prompting on? - bne L0120 No, continue on - lbsr L021F Print shell prompt to standard error -* Shell already booted goes here -L0120 clra - leax >u0124,u Point to an input line of some sort - tst <u006B Any module linked? - beq L015B No, continue on - ldy <u0065 Yes, get Execution address of linked module - cmpy <u0069 ??? - lbhs L01F0 - ldb #200 LDW #200/PSHS X/TFM Y+,X+ - pshs x Copy temporary buffer to [<u0065] -L0137 lda ,y+ - sta ,x+ - decb - beq L014E Whole buffer copied, skip ahead - cmpy <u0069 But don't go past here - bhs L0147 - cmpa #C$CR Also, stop on carriage return - bne L0137 -L0147 sty <u0065 Save new start address - puls x Restore ptr to u0124 - bra L01B9 Skip ahead - -L014E lda ,y+ - cmpy <u0069 - bhs L0147 - cmpa #C$CR - bne L014E - bra L0147 - -L015B tst <u005E We reading from script file? - bne L017F Yes, skip ahead - ldd #SS.Relea Std input path/release keyboard+mouse signals - os9 I$SetStt Release any keyboard signals - lbsr L18DB Go modify signals 2&3 to use up/down arrows, -* set up to re-enable Kybd signals -L016A clr <u000E Clear out last signal received - os9 I$SetStt Re-set up SS.SSig -* NOTE: This BRA L0177 is required for type-ahead to work - bra L0177 Go check for history-related signals - -* DOESN'T SEEM TO GET BACK TO HERE WHEN ABORT BUG APPEARS -L0171 ldx #$0000 Sleep until signal is received - os9 F$Sleep -L0177 lbra L191C Go check for history signals (PD.QUT & PD.INT) -* Signal received is not PD.QUT or PD.INT goes here -L017B cmpb #$0B Key pressed signal? - bne L0171 No, ignore signal & go to sleep again -* Keyboard input received signal goes here -L017F leax >u0124,u Point to temp buffer to hold line - clra Std Input - ldy #200 Maximum 200 char. input - lbra L193E Go read the rest of line as ReadLn - -* Comes here after line or signal received & processed -* NOTE: IF LINE RECEIVED, PD.QUT & PD.INT ARE BACK TO NORMAL VALUES -L018B bcc L01B9 If no errors, skip ahead - cmpb #E$EOF <ESC> key in ReadLn? - beq L01F0 Yes, skip ahead - -L0191 lds <u0025 Get top of stack ptr - ldu <u0027 Get back ptr to DP - stb <u0047 Save error code - tst <u0046 GOTO label active? - bne L01A4 Yes, go print error message - tst <u0018 Is this shell immortal? - bne L01A4 Yes, go print error message - tst <u0020 Kill shell on error? - bne L01FA Yes, go do that - -L01A4 os9 F$PErr Print the error message - tst <u0046 GOTO label active? - lbeq L010D No, go print shell prompt/process next line - clr <u0046 Clear GOTO label flag - leax >u0C4C,u Point to copy of GOTO label name - lbsr L0FD0 Go process GOTO line - lbra L010D Go print shell prompt/process next line - -* No error received on line -L01B9 cmpy #$0001 Just 1 char read (just a CR)? - bhi L01CE No, go parse parameters - lbsr L09F7 Go update date/time & expanded shell prompt - leax >u0213,u Point to expanded shell prompt - ldy >u01F7,u Get size of expanded shell prompt - lbra L0119 Go print shell prompt & get next line from user - -* No errors-got input line, and there is something in it -L01CE lbsr L041B Go parse parameters? - pshs cc Save flags - tst <u0045 - bne L01D9 - clr <u0047 Clear error/signal code from ReadLn -L01D9 puls cc Restore flags - lbcc L010D If no error from parse, do prompts & read again - tstb If a 0 error, do prompts & read again - lbeq L010D - tst <u0045 ??? Do we care about errors? - bne L0191 No, go handle error - stb <u0047 Save error/signal code - bra L0191 Go handle error - -L01EC fcc 'eof' - fcb $0d - -* <ESC> received -L01F0 tst <u001D Shell prompting on? -L01F2 bne L01F9 No, skip printing 'eof' to screen - leax <L01EC,pc Point to 'eof' string - bsr L021B Write it out to std error -L01F9 clrb No error flag -* Possible shell error - Process -L01FA lda <u0018 Is this shell immortal? - lbne L0BDA Yes, go close or dupe paths -* Shell not immortal, exit routine in here -L0200 pshs u,b,cc Preserve regs - tst <u006B Shellsub module to unlink? - beq L020B No, skip ahead - ldu <u0067 Yes, get ptr to module - os9 F$UnLink Unlink it -L020B puls u,b,cc Restore U, error # & flags -* EX with no module name (or non-existant one) go here -L020D pshs b,cc Save error # & flags - leax >L0061,pc Point to '+++END+++' string - lbsr L07E7 Close log file if one is open, restore ID # - puls b,cc Restore error # & flags - os9 F$Exit Terminate shellplus - -L021B ldy #80 Write up to 80 chars or CR -L021F lda #$02 Std error path - os9 I$WritLn Write message out & return - rts - -L0225 pshs y,x,d Preserve regs - ldd #SS.Relea Std In & Release keyboard & mouse signals - os9 I$SetStt - bcc L0233 No error, continue - lda #$01 Couldn't release keyboard/mouse signals flag - bra L0241 - -L0233 leax >u0124,u Point to buffer for current path options - clra - clrb CHANGE TO CLRB - os9 I$GetStt Get std input path options - lda >u0124,u Get Device type (0 (SCF) usually) - -L0241 sta <u005E Save device type (1=SS.Relea failed) - puls pc,y,x,d Restore regs & return - -* R= command (redirect specific paths) -L0245 lda ,x Get char from input line - cmpa #'< Is it input path? - beq L0251 Yes, skip ahead - cmpa #'> Is it an output/error path? - lbne L0BCF No, print 'WHAT?' -L0251 pshs x Preserve ptr to 1st redirection symbol - leay >L03CF,pc Point to modifier symbol table - lbsr L092A Go to command line parser - lbcs L0BCF Error, print 'WHAT?' - ldd ,y Get table offset - jsr d,y Call appropriate subroutine - stx <u0048 Save ptr to source after redirection symbols - puls x Restore ptr to redirection symbols - lbcs L0B96 If error in subroutine, close paths & return - -L026A lda ,x+ Get 1st char again - cmpa #'< Input path? - beq L026A Yes, skip to next - cmpa #'> Output or Error path? - beq L026A Yes, skip to next - cmpa #'- Overwrite old file? - beq L026A Yes, skip to next - cmpa #'+ Append to old file? - beq L026A Yes, skip to next - leax -1,x Point to non-redirect char - bsr L02A3 Make name buffer, release signals,parse modifiers - clrb Start path # 0 -L0281 pshs b Save on stack - lda b,u Get special path # - beq L028A None, skip ahead - os9 I$Close Close the path -L028A puls b Get path # back - clr b,u Clear out entry - incb Next path # - cmpb #$03 Done the 3 standard paths yet? - blo L0281 No, keep doing until all done - ldx <u0048 Get ptr to redirected dev/file name & return - rts -* Z= command (immortal shell setting, but kill parent process) -L0296 inc <u0013 Flag we want to kill parent -* I= command (immortal shell setting) -L0298 lbsr L0CD2 - lbcs L0B96 - bsr L02A3 - bra L02D4 - -* Create device name buffer @ u006D, Write NUL to std out, parse special -* chars: # @ @+hibit $ ( ), Release any keyboard/mouse signals -L02A3 pshs x Prsrve ptr to file/dev name we're redirecting to - ldb #SS.DevNm Get device name call code - leax <u006D,u Point to buffer for path names - lda #'/ Preload '/' for device names - sta ,x+ - clra Standard input path - os9 I$GetStt Get the current device name - puls x Get back ptr to file/dev name for redirection - lbcs L0B96 Error on GetStt, shut down paths & exit - ldy #$0001 One char to write - pshs x Prsrve ptr to file/dev name we're redirecting to - leax >L003C,pc Point to a NUL - lda #1 Std out - os9 I$Write Write the NUL out - puls x Restore Devname ptr - lbcs L0B96 Error on Write, shut down paths & exit - lbsr L0A04 Do normal parsing - includes #,@,$e0,$,(,) - lbsr L0225 Release signals - rts - -L02D4 inc <u0018 Set 'immortal shell' flag - inc <u0019 ??? (flag used by L0B96 routine) - lbsr L0B96 - clr <u0019 - tst <u0013 Do we want to kill the parent process? - beq L02FC - os9 F$ID Get our process ID # into A - pshs x Preserve X - leax >u166D,u Point to process descriptor buffer - os9 F$GPrDsc Get our process descriptor - lda P$PID,x Get our parents process # - puls x Restore X - beq L02A3 If parent's process # is 0 (system), skip back - clrb S$Kill signal code - os9 F$Send Send it to parent - lbcs L0191 If error sending signal, go to error routine -L02FC clrb No error - stb <u0013 Clear 'kill parent' flag - rts - -* Command list -L0300 fdb L0B87-L0300 $0887 - fcs '*' -L0303 fdb L12D1-L0303 $0fce - fcs 'W' -L0306 fdb L09BD-L0306 $06b7 - fcs 'CHD' -L030B fdb L09B5-L030B $06aa - fcs 'CHX' -L0310 fdb L09BD-L0310 $06ad - fcs 'CD' -L0314 fdb L09B5-L0314 $06a1 - fcs 'CX' -L0318 fdb L0987-L0318 $066f - fcs 'EX' -L031C fdb L16DD-L031C $13c1 - fcs 'KILL' -L0322 fdb L09EF-L0322 $06cd - fcs 'X' -L0325 fdb L09F3-L0325 $06ce - fcs '-X' -L0329 fdb L0A14-L0329 $06eb - fcs 'P=' -L032D fdb L09D7-L032D $06aa - fcs 'P' -L0330 fdb L09DA-L0330 $06aa - fcs '-P' -L0334 fdb L09DF-L0334 $06ab - fcs 'T' -L0337 fdb L09E3-L0337 $06ac - fcs '-T' -L033B fdb L170D-L033B $13d2 - fcs 'SETPR' -L0342 fdb L0298-L0342 $ff56 - fcs 'I=' -L0346 fdb L0245-L0346 $feff - fcs 'R=' -L034A fdb L0296-L034A $ff4c - fcs 'Z=' -L034E fdb L0927-L034E $05d9 - fcs ';' -L0351 fdb L176B-L0351 $141a - fcs '.PWD' -L0357 fdb L177D-L0357 $1426 - fcs '.PXD' -L035D fdb L1029-L035D $0ccc - fcs 'M=' -L0361 fdb L105A-L0361 $0cf9 - fcs 'VAR.' -L0367 fdb L09E7-L0367 $0680 - fcs 'V' -L036A fdb L09EA-L036A $0680 - fcs '-V' -L036E fdb L1209-L036E $0e9b - fcs 'PATH=' -L0375 fdb L11CF-L0375 $0e5a - fcs 'PAUSE' -L037C fdb L1126-L037C $0daa - fcs 'INC.' -L0382 fdb L1131-L0382 $0daf - fcs 'DEC.' -L0388 fdb L0D62-L0388 $09da - fcs 'IF' -L038C fdb L0E0B-L038C $0a7f - fcs 'THEN' -L0392 fdb L0F8C-L0392 $0bfa - fcs 'ELSE' -L0398 fdb L0E0B-L0398 $0a73 - fcs 'FI' -L039C fdb L0E0B-L039C $0a6f - fcs 'ENDIF' -L03A3 fdb L0F3F-L03A3 $0b9c - fcs 'CLRIF' -L03AA fdb L0FD0-L03AA $0c26 -L03AC fcs 'GOTO' -L03B0 fdb L0F93-L03B0 $0be3 - fcs 'ONERR' -L03B7 fdb L09CF-L03B7 $0618 - fcs 'L' -L03BA fdb L09D3-L03BA $0619 - fcs '-L' -L03BE fdb L0969-L03BE $05ab - fcs 'S.T.A.R.T.U.P' - fdb $0000 -L03CF fdb L1634-L03CF $1265 - fcs '!' -L03D2 fdb L1634-L03D2 $1262 - fcs '|' -L03D5 fdb L12A0-L03D5 $0ecb - fcs ';' -L03D8 fdb L12C3-L03D8 $0eeb - fcs '&' -L03DB fdb L1299-L03DB $0ebe - fcb $8d CR -L03DE fdb L0CCE-L03DE $08f0 - fcs '<>>>' -L03E4 fdb L0CE5-L03E4 $0901 - fcs '<>>' -L03E9 fdb L0CD7-L03E9 $08ee - fcs '<>' -L03ED fdb L0CF3-L03ED $0906 - fcs '>>>' -L03F2 fdb L0C01-L03F2 $080f - fcs '>>' -L03F6 fdb L0BFA-L03F6 $0804 - fcs '<' -L03F9 fdb L0C08-L03F9 $080f - fcs '>' -L03FC fdb L1277-L03FC $0e7b - fcs '#' -L03FF fdb L1265-L03FF $0e66 - fcs '^' - fdb $0000 End of table marker - -L0404 fcb $0d - fcc '()' - fcb $ff -L0408 fcb $0d - fcc '!#&;<>^|' - fcb $ff - -* Subroutine: Clears B bytes of memory to NUL's starting @ U -L0412 pshs u Clear memory -L0414 clr ,u+ - decb -L0417 bne L0414 -L0419 puls pc,u - -* Pre-Parse parameters passed to this shell. Will copy from parm area to -* buffer area at u0166D, checking for raw mode access allowability if needed -* Will also -* Entry: X=ptr to parm area -L041B ldb #$18 # of bytes to clear in DP -L041D bsr L0412 Go clear from <u0000 to <u0018 (immortal off) - tst <u006C ??? (If shell is initing, it's 0) - lbeq L04CE Shell just initializing, skip ahead - leay >u17FC,u Point to end of buffer marker - pshs y Save ptr on stack - leay >u166D,u Point to buffer for process descriptor -L042F bsr L0486 Copy next char (check for '@', possibly eat) - cmpa #C$CR CR? - beq L04A8 Yes, force CR into ,y & process line from start - cmpy ,s At end of buffer? - beq L04A8 Yes, force CR, process line from start - tst <u001F Variable expansion on? - bne L042F No, check next char - cmpa #'% Is it a '%' (shell variable)? - bne L042F No, do next character - leay -1,y Back up destination ptr to where '%' is - pshs x Save current position in parms - lda ,x Get 1st char of shell variable nam - cmpa #'* Shell variable for last error code received? - beq L049D Yes,replace shell var with contents of shell var - leax >u05A8,u Point to user shell variable contents table - cmpa #'% 2nd '%'= shellsub variable - bne L0460 No, just user, go process - puls x Get back parm ptr - leax 1,x Skip over 2nd '%' - lda ,x Get shellsub variable # - pshs x Save parm ptr - leax >u08D2,u Point to shellsub variable contents table -* Entry: A=ASCII 0-9 for either shell or shellsub variable # -L0460 cmpa #'9 ASCII numeric? - bhi L0470 No, skip ahead - cmpa #'0 - blo L0470 - suba #$30 Yes, bump down to binary equivalent - ldb #81 Point to proper variable entry within var table - mul - leax d,x - incb ??? Used in TSTB below -L0470 bsr L0486 Copy char from var table to pre-parse buffer - cmpy 2,s Hit end of pre-parse buffer? - beq L04A6 Yes, force CR at end of it, do full parse - cmpa #C$CR End of variable? - bne L0470 No, keep copying characters - leay -1,y Knock ptr back one (to where CR is) - puls x Get current parm ptr back - tstb ??? flag to skip a byte in parm or not - beq L042F Don't skip -L0482 leax 1,x Skip to next byte in parm line - bra L042F Continue pre-parse - -* Copy char from parm area to command line buffer - if '@', eat if user is -* not super-user (#0) -* Entry: X=ptr to current pos. in original parm buffer -* Y=ptr to current pos. in new, pre-parsed buffer -L0486 lda ,x+ Get char from parms - cmpa #'@ Raw mode request? - bne L049A Skip ahead if not (SHOULD BE BNE) -L048C pshs y,a Preserve regs - os9 F$ID Get user ID # - cmpy #$0000 Is it 0 (superuser)? (should be leay ,y) - puls y,a Restore regs - beq L049A Yes, allow char thru - rts Otherwise eat it - -L049A sta ,y+ Save char & return - rts - -* Shell variable '%* (for last error code) requested -* Put contents of shell var. into pre-parsed command line buffer -L049D puls x Get back parm ptr - lbsr L168A Put error code into preparse buffer - leay 3,y Skip over error code space we just added - bra L0482 Skip over shell varname, continue preparse - -L04A6 leas 2,s Eat stack -L04A8 lda #C$CR Force CR as last char in buffer - sta ,y - puls y - leax >u166D,u Point to start of pre-parse buffer again -L04B2 bra L04CE Start real parse - -L04B4 fcb C$LF - fcc 'Expanded line too long' - fcb C$CR -L04CC fcc '.' -L04CD fcb C$CR - -* Parse command line buffer - already pre-parsed (user 0 RAW mode checks & -* shell/shellsub variable expansion is already done) -* Entry: X=Ptr to pre-parsed command line buffer -L04CE lda ,x Get 1st char from parameter area - cmpa #'* Is it a comment? - beq L04DE Yes, skip ahead - cmpa #': Is it a wildcard on/off? - bne L04DA No, skip ahead - leax 1,x Bump ptr past it -L04DA cmpa #': Is it a wildcard off? -* FOLLOWING LINE: BEQ means wildcarding default off, BNE = on - beq L04F0 No, go process wildcarding -* No wildcard processing -L04DE leay >u0E6D,u Point Y to expanded buffer - lbsr L1320 Copy param area to buffer area until 1st CR - leax >u0E6D,u Point X to expanded (wildcard) buffer - ldy #$0800 Max. size of expanded buffer (2048 bytes) - lbra L079B Process line without wildcards - -* Wild carding processor -* Entry: X=ptr to current position in pre-parsed parm line -* 1st, set up error msg for if buffer gets full -L04F0 leay >L04B4,pc Point to 'Expanded line too long' - sty <u004A Save it - ldy #$0018 Get size of text - sty <u004C Save it too - leay >L04CD,pc Point to CR - sty <u0048 Save ptr - sts <u0050 Save stack ptr - leay >u0E6D,u Point to fully expanded buffer (2k max) - sty <u0056 Save it - clra - clrb - sta <u0012 No current working DIR path - sta <u004F Flag no pathname in parm area - std <u0052 Expanded buffer size=0 bytes - bra L0520 Enter main loop for wildcards - -L051D lbsr L06FB Special shell chars handling -L0520 lbsr L0746 Check for special chars (wildcard or shell) - bcc L051D Special shell char process -* Wildcard char found - pshs x Save current pre-parsed parm ptr - bsr L0549 Check from that point for '/' or special char - ldx ,s Get previous parm ptr back - bcc L0557 No '/' found, open current dir '.' -* Found '/' (part of path) - keep looking for last '/' for filename (not -* pathname) portion -L052D bsr L0549 Check for special char or '/' again - bcc L0535 No '/', skip ahead - stx <u0040 Save latest ptr to '/' in parm line found so far - bra L052D See if any more sub-paths - -* Found one or more '/' path dividers in current parm line. -* Entry: <u0040 - contains the last '/' found -L0535 inc <u004F Flag that their IS a pathname from parm line -L0538 ldx <u0040 Get last level of path ptr - puls y Get original parm ptr - sty <u0040 Save it - pshs x Save filename ptr on stack - lda #C$SPAC Save space over '/' after pathname - sta -1,x (before filename) - tfr y,x Move original parm ptr to X - bra L055E Open dir path - -* Parse from current position in pre-parsed parm line until shell special -* char, or '/' found (path) -* Entry: X=ptr to current pos in pre-parsed parm line -* Exit: Carry clear if special shell char found -* Carry set if '/' found -* X=ptr to found char+1 -L0549 clrb - lda ,x+ Get next char - lbsr L05D3 See if shell special char - beq L0556 Yes, return - cmpa #'/ No, is it a slash (path start)? - bne L0549 No, Keep checking for / or special char - comb -L0556 rts - -* No '/' found in parm line at all -L0557 clr <u004F Flag no pathname from parm line - leax >L04CC,pc Point to '.' -* Entry: X=ptr to pathname to directory -* 0-1,s = Ptr to filename spec we are looking for in this directory -L055E lda #DIR.+READ. Open directory in READ mode - os9 I$Open - lbcs L0776 Error, skip ahead - sta <u0012 Save current DIR path - puls x Get back ptr to filename (not pathname) - lbsr L0746 Check for special shell char or wildcard - lbcc L06E3 Special shell char found, ?????? -L0572 lda ,x+ Get next char from filename - cmpa #C$CR End of user specified filename (CR)? - lbeq L0789 Yes, close DIR and proceed - cmpa #', Comma? - beq L0572 Yes, skip it - cmpa #C$SPAC Space? - beq L0572 Yes, skip it - leax -1,x Other char, point to it. - stx <u0054 Save ptr to it - lda <u0012 Get DIR path # - pshs u Preserve u - ldx #$0000 Skip '.' and '..' dir entries - ldu #$0040 - os9 I$Seek - lbcs L0776 Error, skip ahead - puls u Restore u -L0599 leax >u0C9D,u Point to dir entry buffer - pshs x Save ptr - lda <u0012 Get Current dir path # - ldy #$0020 Read 1 file entry - os9 I$Read - lbcs L06BD Error, skip ahead - puls y Restore pointer to dir filename buffer - lda ,y Get 1st char of entry - tsta Is it a deleted file? - beq L0599 Yes, skip it - ldx <u0054 Get ptr to current char in expanded filename bfr - bsr L05EF Check wildcard spec against this filename - bcs L0599 No match, skip to next file in DIR - tst <u004F Was a pathname specified? - beq L05CA No, skip ahead - ldx <u0040 Yes,get ptr to end of pathname/start of filename - lbsr L06FB Check for wildcard stuff there - ldx <u0056 Get current pos in expanded buffer - lda #'/ Save '/' there (to separate path & filename) - sta -1,x -L05CA leax >u0C9D,u Point to start of matched DIR entry filename - lbsr L06FB Copy filename over, handling quoted chars, etc. - bra L0599 On to next DIR entry - -* Check if shell 'special' char. (except wildcards & shell var) -* non-wildcard char in current byte of pre-parsed parm buffer -* Entry: X=ptr to next char in parms buffer -* A=current char in parms buffer -* Exit: BEQ if shell special char found, BNE if just regular char -* A=char we were checking -L05D3 pshs x Save parms buffer ptr - cmpa #'( Group start char? - beq L05ED Yes, skip ahead - cmpa #') Group end char? - beq L05ED Yes, skip ahead - cmpa #C$SPAC Space? - beq L05ED Yes, skip ahead - cmpa #', Comma? - beq L05ED Yes, skip ahead - leax >L0408,pc Table of other special chars -L05E9 cmpa ,x+ Found match or end of table? - bhi L05E9 No, keep checking (or fall through if not found) -L05ED puls pc,x Exit with BEQ/BNE flag set - -* IF wildcards were detected in preparsing, filename compares happen here -* Entry: X=ptr to current char in user's pre-parse parm line -* Y=ptr to start of current DIR entry filename -* Exit: Carry set if no match -* Carry clear if match -L05EF ldd ,x+ Get 2 chars (NOTE: PTR UP BY ONLY 1!) -L05F1 cmpa #'* 1st char a * (multi-char wildcard)? - beq L064C Yes, go handle it - cmpa #'? Question mark (single char wildcard)? - beq L0638 Yes, go handle it - cmpa #'[ Start of ranged wildcard? - lbeq L068B Yes, go handle it - bsr L05D3 Not wildcard, check for special shell chars - beq L062B It is a special shell char, skip ahead - bsr L0631 Just regular char, force uppercase - pshs a Save char - bsr L062D Force uppercase on DIR filename char - eora ,s+ Same char as last parm char? - bne L062B No, exit with carry set -L060D lda ,y+ Re-get char from DIR filename - bpl L05EF Not on last char yet, check next char from parm - ldd ,x At end of DIR filename, grab 2 chars from parm - bsr L05D3 Check 1st char against special shell chars - beq L0621 Found one, skip ahead - cmpa #'* Multi-char wildcard char? - bne L062B No, no match, exit with carry set - tfr b,a 1st char from parm is '*', check 2nd char for - bsr L05D3 special shell chars - bne L062B None found, no match, exit with carry set -L0621 lda -1,y Special char, get last char from DIR filename -L0623 anda #$7F Strip 'end of filename' bit flag - ldb #C$SPAC Space char - std -1,y Save 'fixed' last char & space - clrb Flag match - rts - -L062B comb Flag no match - rts - -* Force char to uppercase -L062D lda ,y Get char - anda #$7F Strip hi-bit -L0631 cmpa #'A Need to force uppercase? - blo L0637 No, exit - anda #$DF Yes, force to uppercase -L0637 rts - -* '?' single char wildcard found -L0638 cmpb #'* Is next char a multi-char wildcard? - beq L060D Yes, process as if just '*' - cmpb #', 2nd char '-' or greater? - bhi L060D Yes, process normally - lda ,y+ Get next char from DIR filename - bpl L062B Not end of filename, Flag no match - bra L0623 Save hibit stripped char & space, flag match - -L0646 lda ,y+ Get next char from DIR filename - bpl L0646 Hunt for end of DIR filename - bra L0623 Found it, fix hibit and add space to DIR entry - -* '*' multi-char wildcard found -L064C lda ,x+ Get next char after '*' from parm buffer - bsr L05D3 Check for shell special char - beq L0646 Found one, check if end of DIR filename - cmpa #'? Single char wildcard next? - beq L067F Yes, Process - cmpa #'[ Start of Ranged wildcard next? - beq L067F Yes, process - bsr L0631 Force char to uppercase - pshs a Save it -L065E bsr L062D Get next char from DIR filename, force uppercase - eora ,s+ Same char? - beq L066E Yes, possible resync after '*' -L0664 leas -1,s Make room on stack - lda ,y+ Re-get un-modified char from DIR filename - bpl L065E Not end of filename, try next char - leas 1,s Found end of filename, eat temp stack - bra L062B Flag no match -* Above loop @ L0664/L065E uses sneaky stack stuff - -* Found possible resync char match after '*' -L066E leas -1,s Make room on stack - pshs y,x Preserve both DIR & parm ptrs - bsr L060D Attempt normal matching using this resync - puls y,x Restore ptrs - leas 1,s Eat temp stack - bcs L0664 No, resync did not work, look for next resync - rts worked, exit with carry clear - -L067B lda ,y+ Get next char in DIR - bmi L062B Last char, flag no match -* '?' found after '*' in parm buffer -L067F pshs y,x Preserve both DIR and parm buffer ptrs - ldd -1,x Get previous & current parm chars - lbsr L05F1 Do normal sub-parsing from here - puls y,x Restore ptrs - bcs L067B No match, go to next char in DIR and attemp resync - rts Matched, exit with match - -* Ranged wildcard here -* Entry: X=ptr to 1st char in parm buffer AFTER '[' -L068B ldd ,x+ Get 1st 2 chars of range sub-string from parm bfr - bsr L0631 Force uppercase on 1st char - exg b,a Force uppercase on 2nd char - bsr L0631 - exg b,a - cmpa #'] Is 1st char a close range check char? - beq L062B Yes, flag no match for '[]' - cmpa #'- Range separator char? - beq L06A7 Yes, need to get end of range -* Special case for [x] - acts as if just normal char (no range or wildcard) - sta <u00EF No, save start of range char - bsr L062D Get char from DIR filename, force uppercase - eora <u00EF Match only range char? - beq L06B4 Yes, skip to next char now -* Special case for [xyz] - one of these chars must match - bra L068B No, see if more single chars to try matching - -* Actual range - need to get end of range char -* Entry: B=high char of range -* <u00EF - current char (within range) we are checking against -L06A7 inc <u00EF Bump up start char's ascii value - cmpb <u00EF Hit end of range yet? - beq L068B Yes, try next char - lbsr L062D Force char in A to uppercase - eora <u00EF equal to current range check char? - bne L06A7 No, try next char in range -L06B4 ldd ,x+ Get next 2 chars from pathname - cmpa #'] End of range? - bne L06B4 No, check next char - lbra L060D End of range specifier, process normally - -* Error reading from current DIR -L06BD cmpb #E$EOF End of file error? - lbne L0776 No, fatal error, leave - ldx <u0054 Get ptr to current char in wildcard filename - lda -1,x Get last char processed - bsr L0714 Add it to new expanded buffer -L06C9 lda ,x+ Get next char, inc ptr - stx <u0054 Save updated pointer - cmpa #C$CR CR? - lbeq L0789 Yes, append CR to expanded buffer, we are done - lbsr L05D3 See if special shell char - bne L06C9 Just regular char, go to next one - pshs x Save current ptr to wildcard filename - ldx <u0056 Get current ptr in expanded buffer - sta -1,x Save that char overtop last char written - puls x Get wildcard ptr back - bra L06EA Close dir path, go back into loop - -* If special shell char found right after OPEN of DIR path -* Entry: X=ptr to filename (not pathname) - but with special char -L06E3 bsr L06FB Process special shell char copying - bsr L072F Close DIR path - lbra L051D More processing - -L06EA bsr L072F Close DIR path - lbra L0520 Go back to main wildcard processing loop - -* This chunk (6EF-6F9) is for copying '\x' when x is NOT a wildcard char -L06EF lda ,x+ Get quoted char - bsr L0739 Check if it is [, * or ? - beq L06F9 Yes, add that char to expanded buffer by itself - leax -2,x No, bump ptr back to '\' - lda ,x+ Get '\' char -L06F9 bsr L0714 Append that to output buffer -* Special shell chars found goes here -* This part copies filename from [,x] to expanded buffer, handling quoted -* wildcard chars, and ending on CR or special shell char -L06FB lda ,x+ Get char - cmpa #'\ Backslash (for quoted char)? - beq L06EF Yes, go get quoted char - cmpa #C$CR Is it the end of the filename? - beq L0789 Yes, append CR to expanded line, we are done - bsr L073D Is it '?' or '*' - beq L0714 Yes, add that char to expanded buffer - lbsr L05D3 Check if shell special char - beq L0714 Yes, add to expanded buffer, return from there - bsr L0714 No, add to expanded buffer, stay in this loop - bra L06FB - -* Add char to expanded line buffer -* Entry: A=char to append to expanded line buffer -* <u0056=Current position in expanded line buffer -* <u0052=Current size of expanded line buffer -* Exit: <u0056 & <u0052 updated -L0714 pshs x,a Preserve regs - ldx <u0056 Get current pos in expanded buffer - sta ,x+ Save char - stx <u0056 Save updated expanded buffer ptr - ldd <u0052 Get expanded buffer size - addd #$0001 Increase by 1 - cmpd #2048 Is it full yet? - bhi L0773 Yes, exit with expanded line too long error - std <u0052 No, save new size - puls pc,x,a Restore regs & return - -* Close DIR path -L072F lda <u0012 Get DIR path # - beq L0738 If none, exit - os9 I$Close Close the path - clr <u0012 Clear DIR path # to none -L0738 rts - -* Wildcard checks -* Entry: A=char to check -* Exit: BEQ if any of the 3 wildcard chars, or BNE if not -L0739 cmpa #'[ Range wildcard? - beq L0745 -L073D cmpa #'? Single char wildcard? - beq L0745 - cmpa #'* Multi-char wildcard? - beq L0745 -L0745 rts - -* Parse for next wildcard or special shell char in pre-parsed parm line -* Entry: X=current pos in pre-parse parm line -* Exit: X=Same as entry -* IF WILDCARD CHAR FOUND: -* B=# chars to next wildcard/special char -* A=special char found -* Carry bit set -* IF SPECIAL SHELL CHAR FOUND -* B=0 -* Carry bit clear -* A=special char found: CR ( ) , space ! # & ; < > ^ | -L0746 pshs x Save current parm ptr - bra L0752 Parse for wildcard or special shell chars - -L074A lda ,x+ Get char from parms - bsr L0739 Do wildcard char check - beq L0752 If wildcard char, skip over it & continue - leax -1,x not wildcard char, bump back to char after \ -L0752 lda ,x+ Get char from parms - cmpa #'\ Wildcard quote char (do not expand next)? - beq L074A Yes, handle it - lbsr L05D3 No, check for other special shell chars - beq L0770 Found one, skip ahead - bsr L0739 Check for wildcard char - bne L0752 None, skip to next char -* One of the 3 wildcard chars found, process - pshs a Save char - tfr x,d Move parm ptr to D - subd 1,s Calc distance since last wildcard/special char - subd #$0001 -1 - puls a B=distance between wild/special chars - orcc #Carry Set Carry Flag - puls pc,x Exit with original parm ptr in X - -* Exit with B=0, Carry clear and A=special char found (which ends current -* 'chunk' being checked... can included CR) -L0770 clrb Clear carry, exit - puls pc,x - -* Expanded buffer full error -L0773 comb - ldb #E$BufSiz -L0776 pshs b,cc Preserve error code - bsr L072F Close DIR path (if we had one) - ldx <u004A Print text message (usually error msg) - ldy <u004C - lda #$02 - os9 I$WritLn - puls b,cc - lbra L0191 Exit with error - -L0789 lda #C$CR Append CR to expanded filenames buffer - bsr L0714 - ldy <u0052 Get expanded buffer size - leax >u0E6D,u Point to start of expanded buffer - bsr L072F Close DIR path - lds <u0050 Get back original stack ptr -* At this point, expanded buffer is complete and ready to go (either through -* wildcard routine, or by simply copying the original parm buffer from user) - -* Main entry point for non-wildcard filename search/match -* Entry: X=Ptr to start of expanded buffer -L079B tst <u001E Echo required? - beq L07A2 No, skip ahead - lbsr L021F Print out user entered parm line to std err -L07A2 tst <u0043 2=FALSE,0=TRUE, 1=??? (check current IF status, - beq L07B0 if any. If TRUE flag set, skip ahead) - lbsr L0F69 Do checks for IF type statements - tsta Find match? - lbpl L0F1D Yes, process IF type statement -L07AE clrb No error & return - rts - -* If current IF type statement has result TRUE -L07B0 tst <u0045 ??? (Are we looking for a label for GOTO?) - beq L07E3 No, skip ahead - lda ,x+ Get char from buffer - cmpa #'* Comment line? - bne L07AE No, exit without error - lbsr L091F Yes, get ptr to first non-space char into X - leay >u0124,u Point to temp buffer - lbsr L100B Copy label from X to Y - lda ,x Get 1st char of label - cmpa #'\ '*\'? (Which means cancel impending GOTO) - beq L07DB Yes, cancel GOTO - leax >u0BFC,u No, point to 80 byte buffer (GOTO label holder?) - clra default char to check against=NUL -L07CF cmpa #C$CR End of label? - beq L07DB Yes, cancel GOTO search - lda ,x+ Get next char from buffer - cmpa ,y+ Is it the label we are looking for? - beq L07CF Keep checking till done - bra L07AE No match, clear carry & return - -* Cancelling GOTO search -L07DB clr <u0045 Flag we are NOT looking for label for GOTO - clrb - leas 2,s Eat stack - lbra L010D Reprint shell prompt, process from scratch - -L07E3 bsr L07E7 - bra L083A - -L07E7 pshs x - tst <u006C - beq L0832 - tst <u005C - bne L07F5 - tst <u001C - beq L0832 -L07F5 lda ,x - cmpa #'* - beq L0832 - ldy #$0000 Force temporarily to super-user - os9 F$SUser - leax >u0CBD,u - ldd #$0203 - lbsr L0C79 - bcs L0832 - lbsr L00FB - lda #$20 - sta <$11,x - ldy #$0012 - lda <u0012 - os9 I$Write - bcs L082D - ldx ,s - ldy #$0800 - lda <u0012 - os9 I$WritLn -L082D lda <u0012 - os9 I$Close -L0832 ldy <u005A Get original user # back - os9 F$SUser Change user # to original - puls pc,x - -* Parse input line -* Entry : X=Ptr to current char in line buffer -L083A clra - sta <u0022 Flag we don't change priority for forked process - sta <u0003 Clear out # pages of data mem for forked process - sta <u000E Clear out signal code - leay >L0300,pc Point to main command list - lbsr L08D1 Parse keywords from list - bcs L08A0 Keyword found but generated error, done line - cmpa #C$CR Is 1st non-keyword char a carriage return? - beq L08A0 Yes, done line - sta <u000C Save non-keyword char - cmpa #'( Is it a 'start command group' char? - bne L087B No, try next - leay >L000D,pc Point to 'Shell' - sty <u0004 Save pointer to program to fork? - leax 1,x Bump ptr past '(' - stx <u0008 Save updated ptr -L0860 inc <u000D Bump up # of command groups -L0862 leay >L0404,pc Point to command group symbols to parse - lbsr L08E9 Hunt down EOL, or '(' or ')' (skip quoted text) - cmpa #'( Another group start? - beq L0860 Yes, bump up # of command groups & continue - cmpa #') Group end? - bne L0898 No, skip ahead (to print WHAT?) - dec <u000D Bump down # of command groups - bne L0862 Still more groups, continue parsing for them - lda #C$CR Append CR at end of command line - sta -1,x - bra L087F Check for modifiers - -L087B bsr L08A3 Check for valid path, do '<>', '#', '^' if needed - bcs L08A0 No valid path found, skip ahead -* Found valid pathname -L087F leay >L0408,pc Point to modifiers table - bsr L08E9 Go parse for them - tfr x,d Move ')' ptr to D for SUB - subd <u0008 Calculate size from 1st '(' to ')' - std <u0006 Save size of group (could also be pathname-modifier) - leax -1,x - leay >L03CF,pc Point to modifier branch table - bsr L08D1 Go execute modifier routine - bcs L08A0 If error in modifier routine, exit - ldy <u0004 Get ptr to first char we started at -L0898 lbne L0BCF Not proper, print 'WHAT?' - cmpa #C$CR Last char a carriage return? - bne L083A No, start parsing again at current position -L08A0 lbra L0B96 Done processing line, continue - -* Entry: X=Ptr to text to check for valid device name (including '.' & '..') -* Exit: Carry set if not a valid device name -* Carry clear if there was -* <u0004 = Ptr to first char where we started at -* <u0008 = Ptr to end of redirection/mem size/priority setting chars (if found) -L08A3 stx <u0004 Save ptr to current char in input line - bsr L08B6 Check for valid device name - bcs L08B5 None found, return -* Found valid device name -L08A9 bsr L08B6 Eat rest of valid pathlist - bcc L08A9 Keep going until we are done pathlist - leay >L03DE,pc Point to Command list starting at '<>>>' - bsr L08D1 Call any redirection, mem size or priority routines - stx <u0008 Save ptr to where we are now (end of current set) -L08B5 rts - -L08B6 os9 F$PrsNam Valid OS9 device name? - bcc L08C7 Yes, point X to it & return - lda ,x+ Not valid, get first char - cmpa #'. Is it a period? - bne L08CB No, bad path name - cmpa ,x+ Is it a double period? - beq L08C9 Yes, leave src ptr pointing to name after '..' - leay -1,x If single, bump ptr to name after '.' -L08C7 leax ,y Point X to pathname in source -L08C9 clra No error & return - rts - -L08CB comb Error flag - leax -1,x Bump source ptr back - ldb #E$BPNam Bad Path Name error & return - rts -* Entry: Y=ptr to command list (L0300) -L08D1 bsr L0907 Go find 1st non-space char - pshs y Save command list ptr - bsr L092A Parse for keyword or special char - bcs L08E2 If no keyword found, skip ahead - ldd ,y Keyword found, get offset - jsr d,y Go execute routine for command found - puls y Restore command list ptr - bcc L08D1 No error, continue parsing for keywords - rts Subroutine had error, return with it -L08E2 clra No error - lda ,x Get character (not in command list) - puls pc,y Restore command list ptr & return - -* Start searching at beginning of current command list -* For looking for single character modifiers -L08E7 puls y -L08E9 pshs y Preserve command list ptr - lda ,x+ Get next char from command line -L08ED tst ,y Check current char in command list - bmi L08E7 If done list, start over at beginning - cmpa #'" Is it quotes? - bne L0901 No, skip ahead -L08F5 lda ,x+ Get next char from command line - cmpa #C$CR EOL? - beq L0905 Yes, exit with A being CR - cmpa #'" Is it another set of quotes? - bne L08F5 No, keep looking for it (or EOL) - lda ,x+ Get char after 2nd quotes -L0901 cmpa ,y+ Is it the current command char we are checking? - bne L08ED No, try next -L0905 puls pc,y Yes, exit with A containing it - -* Entry: Y=ptr to command list -L0907 pshs x Preserve X - lda ,x+ Get char from line entered by user - cmpa #C$SPAC Is it a space? - beq L091D Yes, skip ahead - cmpa #', Is it a comma? - beq L091D Yes, skip ahead - leax >L0408,pc Point to single character modifiers -L0917 cmpa ,x+ Found a match? - bhi L0917 No, try next until list is done - puls pc,x Found it, restore X to point to it & return - -L091D leas 2,s Eat X off the stack -L091F lda #C$SPAC Get space character -L0921 cmpa ,x+ Keep searching until non-space char is found - beq L0921 - leax -1,x Point to 1st non-space char -* ; (1st pass) comes here -L0927 andcc #^Carry No carry & return - rts -* Command line parser -L092A pshs y,x Preserve command table ptr & input line ptr - leay 2,y Skip first offset -L092E ldx ,s Get input line ptr -L0930 lda ,x+ Get char from input line - lbsr L0F0C Convert char to uppercase if lowercases - eora ,y+ Check for a match - lsla - bne L0951 No match, skip to next keyword in table - bcc L0930 Keep checking until end of keyword (high bit set) - lda -$01,y Get command table char again - cmpa #'|+$80 '|' (with high bit set)? - beq L094E Yes, exit with carry clear - cmpa #'^+$80 '^' (with high bit set)? - beq L094E Yes, exit with carry clear - cmpa #'A+$80 Any of the other special modifiers with high bit? - blo L094E Yes, exit with carry clear - bsr L0907 Eat spaces until first non-space char - bcs L0951 If special char (!|#,etc.), skip ahead -L094E clra - puls pc,y,d - -L0951 leay -1,y Bump search ptr back -L0953 lda ,y+ Get char again - bpl L0953 Keep getting them until end of keyword - sty 2,s Save ptr to next offset on stack - ldd ,y++ Get offset - bne L092E If not at end of table, keep searching - comb End of table, command not found error - puls pc,y,x - -L0961 fcc 'startup' - fcb C$CR - -* Create child shell to run 'startup' file -L0969 pshs u,y,x Preserve regs - leax L000D,pc Point to 'shell' (module name) - leau L0961,pc Point to 'startup' (parameter for 'shell') - ldy #$0008 Size of 'startup<CR>' - ldd #$111F Program+Objct / 7.5K data area - os9 F$Fork Fork a shell to run the startup file - bcs L0983 Couldn't fork, exit - os9 F$Wait Wait until 'startup' is done -L0983 puls u,y,x Restore regs - clrb No error & return - rts - -* EX command -L0987 lbsr L08A3 Go check for valid device name (module) - bcs L09AB If none, exit - clra Std in path - bsr L09B0 Go close it - bsr L09AF Go close Std out - bsr L09AF Go close Std Err - lbsr L0B87 Go find the end of the input line - leax 1,x Bump ptr to 1 past CR - tfr x,d Move ptr to D - subd <u0008 Calculate size of current command group - std <u0006 Save it - lbsr L130A Point to module to chain&get its parm size, etc. - leas >u00FF,u Point stack to end of DP - os9 F$Chain Chain to the new program - lbra L01FA Couldn't, go here -L09AB clrb No error - lbra L020D Close logging file (if any) and exit ShellPlus - -L09AF inca Inc path # -L09B0 pshs a Save path # - lbra L0BBC close path if it is open -* CHX & CX commands -L09B5 clr <u0038 - lda #DIR.+EXEC. - os9 I$ChgDir - rts -* CHD & CD commands -L09BD lda #DIR.+READ. (bug fix, originally opened in UPDATE) - os9 I$ChgDir Change the directory - bcs L09CE Error, exit with it - clr <u0037 Flag .pwd entry as invalid - tst <u0042 WAS ,U - beq L09CE - bsr L0A04 Go update shell expanded prompt if needed -L09CE rts -* L command - Logging ON -L09CF lda #$01 - bra L09D4 -* -L command - Logging OFF -L09D3 clra -L09D4 sta <u001C - rts -* P command - Prompting ON -L09D7 clra - bra L09DC -* -P command - Prompting OFF -L09DA lda #$01 -L09DC sta <u001D - rts -* T command - Echo input ON -L09DF lda #$01 - bra L09E4 -* -T command - Echo input OFF -L09E3 clra -L09E4 sta <u001E - rts -* V command - Turn variable expansion ON -L09E7 clra - bra L09EC -* -V command - Turn variable expansion OFF -L09EA lda #$01 -L09EC sta <u001F - rts -* X command - Kill Shell when error occurs ON -L09EF lda #$01 - bra L09F4 -* -X command - Kill Shell when error occurs OFF -L09F3 clra -L09F4 sta <u0020 - rts - -L09F7 tst >u01F4,u Date already done? - bne L0A04 Yes, skip ahead - tst >u01F5,u Time already done? - bne L0A04 Yes, skip ahead - rts If neither, we don't need to change prompt? -L0A04 pshs y,x Preserve regs - bra L0A64 Go update shell expanded prompt if needed - -* Make shell prompt string the default one -L0A08 puls y Restore Y - pshs x Preserve X - leax >L003D,pc Point to default prompt string - bsr L0A14 Put that into working shell prompt string - puls pc,x Restore X & return - -* P= (prompt set) command -* Make shell prompt string (default or user-specified) -* Entry: X=ptr to source of new shell prompt string -L0A14 pshs y Preserve Y - leay >u01F9,u Point to working prompt text buffer - ldd #C$LF*256+22 Line feed & max count for prompt string+1 - sta ,y+ Save LF as first char - bsr L0A25 Go copy prompt string (& parse quotes) - bra L0A5E Go see if we need to override with default - -L0A25 clr >u01F3,u Clear quotes in progress flag -L0A29 lda ,x+ Get char from default shell prompt - cmpa #'" Is it a quotes? - bne L0A3F No, skip ahead - leax 1,x Yes, bump ptr up 2 past quotes - tst >u01F3,u We processing quotes already? - bne L0A59 Yes, we are done then - inc >u01F3,u Set processing quotes flag - leax -1,x Set ptr back to char just after quotes - bra L0A29 Check next char - -L0A3F cmpa #C$CR Carriage return? - beq L0A59 Yes, we are done then - cmpa #C$SPAC Space? - beq L0A4B Yes, skip ahead - cmpa #'; Semi-colon? - bne L0A51 No, skip ahead -* Semi-colon or space found -L0A4B tst >u01F3,u We quoting at the moment? - beq L0A59 No, we are done -L0A51 tstb Char count down to 0? - beq L0A29 Yes, continue parsing (but eating them) - decb Dec max char counter - sta ,y+ Save literal char into current copy - bra L0A29 continue parsing - -L0A59 clr ,y Append NUL to indicate end of string - leax -1,x Bump source ptr back to last char & return - rts - -L0A5E cmpb #22 Did the user do a no-length prompt? - beq L0A08 Yes, go override with default prompt - pshs x Preserve ptr to last char of source prompt - -* Create expanded shell prompt from shell prompt string -L0A64 leay >u01F9,u Point to shell prompt string - leax >u0212,u Point to expanded prompt buffer - pshs x Preserve it a moment - clr >u01F2,u Output device name done already = OFF - clr >u01F1,u Process ID # done already = OFF - clr >u01F4,u Date done already = OFF - clr >u01F5,u Time done already = OFF - clr >u01F6,u Date OR time already done once = OFF - clr >u0042,u Current working dir name done already = OFF -L0A86 lda ,y+ Get char from shell prompt string - lbeq L0B29 If end of string, exit - cmpa #'# Process ID # wanted? - bne L0AA2 No, try next -* Process ID # - tst >u01F1,u Done it already? - bne L0A86 Yes, skip doing it again - inc >u01F1,u No, flag it as being done now - ldd >u01EC,u Get process # (01-99) - std ,x++ Save in expanded prompt buffer - bra L0A86 Continue parsing -L0AA2 cmpa #'@ Standard output path device name wanted? - beq L0AAA Yes, go do it - cmpa #$E0 High bit version? - bne L0AC7 No, try next -* Standard output path device name -L0AAA tst >u01F2,u Done it already? - bne L0A86 Yes, skip doing it again - ldd #$01*256+SS.DevNm Standard out/get device name - os9 I$GetStt Get the device name - bcs L0A86 Error, skip doing device name - inc >u01F2,u Flag it as being done now -L0ABD lda ,x+ Get char from device name - bpl L0ABD Keep looking until last char (high bit set) - anda #$7F Mask out high bit - sta -1,x Save the normal char - bra L0A86 Continue parsing -L0AC7 cmpa #'$ Current working directory wanted? - bne L0AF2 No, check next -* Current working directory - tst <u0042 Done it already? (WAS ,U) - bne L0A86 Yes, skip doing it again - inc <u0042 Flag it as being done now (WAS ,U) - lda #$01 - sta <u003D - lbsr L176D Go figure out current working directory - tstb - bne L0AF2 - pshs y Save prompt string ptr - ldy <u002A Get pointer to current working directory -* Copy string: Y=source string ptr, X=prompt buffer ptr -L0AE4 lda ,y+ Get char - sta ,x+ Save as part of shell prompt text - cmpa #C$CR Was it the end? - bne L0AE4 No, keep copying - leax -1,x Bump ptr back CR - puls y Restore source string ptr - bra L0A86 Continue parsing - -L0AF2 cmpa #'( Current Date wanted? - bne L0B0A No, check next -* Current date - tst >u01F4,u Done it already? - bne L0A86 Yes, skip doing it again - inc >u01F4,u Flag as being done now - bsr L0B3B Go get date & time - pshs y Save shell prompt string ptr - leay >u02E0,u Point to date text - bra L0AE4 Copy into expanded prompt -L0B0A cmpa #') Current Time wanted? - bne L0B24 No, just store the raw ASCII char -* Current time - tst >u01F5,u Done Time already? - lbne L0A86 Yes, skip doing it again - inc >u01F5,u Flag as being done now - bsr L0B3B Go get date & time - pshs y Save shell prompt string ptr - leay >u02E9,u Point to time text - bra L0AE4 Copy into expanded prompt - -L0B24 sta ,x+ Save raw character - lbra L0A86 Continue parsing - -L0B29 sta ,x Save NUL to mark end of prompt - tfr x,d Move End of prompt ptr to D for subtract - subd ,s++ Subtract start of prompt ptr - std >u01F7,u Save size of expanded shell prompt - puls pc,y,x Restore regs & return - -* Separator table for date & time strings -L0B35 fcc '//' - fcb $0d - fcc '::' - fcb $0d - -* Get current date (2E0-2E8) & time (2E9-2EF) -L0B3B pshs y,x Preserve shell prompt string & shell prompt ptrs - tst >u01F6,u Have we already been here before? - bne L0B75 Yes, both date & time strings already done - inc >u01F6,u Flag we have been here now - leax >u02DA,u Point to date/time packet buffer - os9 F$Time Get the date/time packet - leay >u02E0,u Point to where date string goes - clrb Offset into separator table to first '/' -L0B54 lda ,x+ Get byte from time packet - bsr L0B77 Convert to ASCII - pshs b Preserve offset into separator table - ldd >u01EF,u Get ASCII version of byte - std ,y++ Save into date/string buffers - puls b Restore offset into separator table - pshs y Preserve date/string buffer ptr - leay >L0B35,pc Point to separator's table - lda b,y Get current separator - puls y Restore date/string buffer ptr - sta ,y+ Save separator into date/string buffer - incb Point to next separator - cmpb #6 On last one? - bne L0B54 No, continue converting -L0B75 puls pc,y,x Restore prompt & buffer ptrs & return - -L0B77 pshs y,x,d Preserve regs - leay >L0B80,pc Point to routine to copy ASCII digits - lbra L16B9 Go convert byte to ASCII equivalent - -L0B80 ldd $04,s Copy 2 digit ASCII # to 1EF - std >u01EF,u - rts - -* Searches for CR in string pointed to by X -* '*' Comment lines come here -L0B87 lda #C$CR We want to find the CR -L0B89 cmpa ,x+ Found it yet? - bne L0B89 No, keep looking - cmpa ,-x Set up flags & return - rts - -L0B90 pshs d,cc Preserve regs - lda #$01 Only do std in & out (not error) - bra L0B9A - -* Any errors from any of the L0300 subroutines go here -* If child process had error/status code it goes here (u005D cleared,B=Status -* code) -L0B96 pshs d,cc Preserve error code, flags & A - lda #$02 # of paths to do -L0B9A sta <u001A Save it - clra Start at path 0 -L0B9D bsr L0BA8 Go close (possibly dupe) paths - inca Next path # - cmpa <u001A Done up to last one yet? - bls L0B9D No, do next one -* POSSIBLY COULD BE PULS PC,D,CC - ror ,s+ Eat CC but shift Carry bit into Carry - puls pc,d Restore error code & A & return - -L0BA8 pshs a Save path # - tst <u0019 - bmi L0BC4 If high bit set, close path - bne L0BBC If 0<u0019<128, get changed path # & close - tst a,u Check 'real' path # from DP - beq L0BC7 If 0, return - os9 I$Close Otherwise, close current path # - lda a,u Get 'real' path # - os9 I$Dup Dupe it - -* Close path # on stack, if it is open -L0BBC ldb ,s Get path # from stack - lda b,u Get real path # from DP - beq L0BC7 If none, exit - clr b,u Clear out path # -L0BC4 os9 I$Close Close the path -L0BC7 puls pc,a Exit - -L0BC9 fcc 'WHAT?' - fcb C$CR - -L0BCF bsr L0B96 Close 3 std paths (possibly dupe) - leax <L0BC9,pc Point to 'WHAT?' - lbsr L021B Write it out std err - clrb - coma - rts - -L0BDA inc <u0019 ??? - bsr L0B96 Do path closings (possibly dupings) - lda #$FF Set flag to just close raw paths - sta <u0019 - bsr L0B90 Go close std in & std err - leax <u006D,u Point to device name buffer - lbsr L0CDB - lbcs L0200 - lda #$02 - bsr L0BA8 - lbsr L0CFF - clr <u0019 - lbra L00CC -* < processing -L0BFA ldd #$0001 - orb <u000F - bra L0C1A -* >> processing -L0C01 ldd #$020D - stb -$02,x - bra L0C0A -* > processing -L0C08 lda #$01 -L0C0A ldb #$02 - bra L0C1A -* if from z= or i=, A=0, B=3 -L0C0E tst a,u Test duped path? - bne L0BCF There is one, print 'WHAT' & close paths & return - pshs d Save path # & B - tst <u0019 - bmi L0C34 - bra L0C24 - -L0C1A tst a,u - bne L0BCF - pshs d - ldb #C$CR - stb -$01,x - -L0C24 os9 I$Dup Create duplicate of the standard path - lbcs L0CBE Couldn't create dupe, - ldb ,s - sta b,u - lda ,s - os9 I$Close - -L0C34 lda 1,s Get B - bmi L0C40 - ldb ,s - lbsr L0D05 - tsta - bpl L0C47 -L0C40 anda #$0F - os9 I$Dup - bra L0CBE -L0C47 ldb #$0B - bita #$02 - bne L0C7B - pshs a - ldd ,x - andb #$5F - cmpd #$2F57 Is it '/W' - puls a - bne L0C74 - ora #$02 - os9 I$Open - bcs L0CBE - pshs x - leax >L003C,pc - ldy #$0001 - clra - os9 I$Write - puls x - bra L0CBE -L0C74 os9 I$Open - bra L0CBE -L0C79 pshs d -L0C7B stb <u004E - ldb ,x - cmpb #$2B - bne L0C96 - leax $01,x - os9 I$Open - bcs L0CB1 - pshs u,x - ldb #SS.Size - os9 I$GetStt - os9 I$Seek - bra L0CA8 -L0C96 cmpb #'- - bne L0CB9 - leax 1,x - os9 I$Open - bcs L0CB1 Error opening - pshs u,x - ldx #$0000 - tfr x,u -L0CA8 ldb #SS.Size Init size of file to 0 bytes - os9 I$SetStt - puls u,x - bra L0CBE -L0CB1 cmpb #E$PNNF Error 216 (path name not found)? - beq L0CB9 Yes, create the file - orcc #Carry Otherwise, set error flag - bra L0CBE -L0CB9 ldb <u004E Get file attributes - os9 I$Create - -L0CBE sta <u0012 Save path # (or one we tried to duplicate?) - stb 1,s Save possible error code? - lda #$00 DO NOT CHANGE-NEED TO PRESERVE CARRY - sta <u000F - puls pc,d Restore regs & return -L0CC8 ldd #$0003 Std in & ??? - lbra L0C0E -* <>>> processing -L0CCE lda #C$CR - sta -$04,x -* i= & z= both come here right off the bat -L0CD2 bsr L0CDB - bcc L0CFF -L0CD6 rts -* <> processing -L0CD7 lda #C$CR - sta -$02,x - -L0CDB bsr L0CC8 - bcs L0CD6 - ldd #$0180 - lbra L0C0E -* <>> processing -L0CE5 lda #C$CR - sta -$03,x - bsr L0CC8 - bcs L0CD6 - ldd #$0280 - lbra L0C0E -* >>> processing -L0CF3 lda #C$CR - sta -$03,x - ldd #$0102 - lbsr L0C0E - bcs L0CD6 -L0CFF ldd #$0281 - lbra L0C0E -L0D05 pshs x,d - ldd ,x++ - cmpd #$2F30 - bcs L0D2F - cmpd #$2F32 - bhi L0D2F - pshs x,d - lbsr L0907 - puls x,d - bcs L0D2F - andb #$03 - cmpb 1,s - bne L0D31 - ldb b,u -L0D26 orb #$80 - stb ,s - puls d - leas 2,s - rts -L0D2F puls pc,x,d - -L0D31 tst $01,s - bne L0D26 - pshs x - tfr b,a - leax >u00B5,u Point to buffer for device name - ldb #'/ Put a slash in it - stb ,x+ - ldb #SS.DevNm Get the device name - os9 I$GetStt - bcs L0D4F Error, skip ahead - leax -1,x Reset ptr to include '/' - lda #UPDAT. - os9 I$Open -L0D4F puls x Restore ptr to beginning (including '/') - leas 6,s Eat stack - lbra L0CBE - -L0D56 fcc 'TRUE ' -L0D5B fcb $0d -L0D5C fcc 'FALSE' - fcb $0d - -L0D62 lda ,x+ - cmpa #'[ - bne L0D6B - lbsr L0E15 -L0D6B cmpa #'- - lbne L0E3E - ldb ,x+ - lbsr L0E15 - leax -$01,x - tfr b,a - lbsr L0F0C Convert char to uppercase if lower - cmpa #'Y - bne L0DBB -L0D81 pshs x Preserve X - leax >u0124,u Point to buffer - ldy #$0001 Read 1 byte from error path??? - lda #$02 - os9 I$Read - lbcs L0F17 - lda ,x Get the character read - puls x - lbsr L0F0C Convert char to uppercase if lower - cmpa #'Y Unless char is Y or N, re-read it - beq L0DA3 - cmpa #'N - bne L0D81 -L0DA3 pshs a Preserve char on stack - leax >L0D5B,pc Point to a Carriage return - lda #$02 Print it to std out - ldy #$0001 - os9 I$WritLn - puls a Restore char - clrb - cmpa #'Y - beq L0DF8 Print 'true' if it is a Y - bra L0DEE Print 'false' if it is a N - -L0DBB clrb - cmpa #'F - beq L0DE0 - cmpa #'E - bne L0DC8 - orb #%00000100 - bra L0DE0 - -L0DC8 cmpa #'R - bne L0DD0 - orb #%00000001 - bra L0DE0 - -L0DD0 cmpa #'W - bne L0DD8 - orb #%00000010 - bra L0DE0 - -L0DD8 cmpa #'D - lbne L0F17 - orb #%10000000 -L0DE0 tfr b,a - os9 I$Open - bcs L0DEE - os9 I$Close - bra L0DF8 - -L0DEE lda #$02 - sta <u0043 - leax >L0D5C,pc Point to 'FALSE' - bra L0DFE - -L0DF8 clr <u0043 - leax >L0D56,pc Point to 'TRUE' -L0DFE tst <u001E Command echo on? - beq L0E0B No, skip ahead - ldy #$0006 Print result of IF to std error - lda #$02 - os9 I$WritLn -L0E0B leax >u0124,u - lda #C$CR - sta ,x - clrb - rts - -L0E15 lda ,x+ - cmpa #C$SPAC - beq L0E15 - rts - -L0E1C cmpa #$3D - bne L0E26 - lda <u005F - ora #$01 - bra L0E38 - -L0E26 cmpa #'< - bne L0E30 - lda <u005F - ora #$02 - bra L0E38 - -L0E30 cmpa #'> - bne L0E3C -* X command - Kill Shell when error occurs ON - lda <u005F - ora #$04 -L0E38 sta <u005F - clra - rts - -L0E3C coma - rts - -L0E3E cmpa #'+ - bne L0E46 - inc <u0015 - bra L0E48 - -L0E46 leax -1,x -L0E48 clr <u005F - pshs u - leau >u0124,u - ldb #180 Clear out 180 bytes @ u0124 - lbsr L0412 - puls u - leay >u0124,u - ldb #81 -L0E5D lda ,x+ Copy buffer up to CR or 81 chars - lbsr L0F0C Convert char to uppercase if lower - sta ,y+ - cmpa #C$CR - lbeq L0F17 - bsr L0E1C - bcc L0E74 - decb - bne L0E5D - lbra L0F17 - -L0E74 negb - addb #81 - stb <u0016 - clra - sta -$01,y - lda ,x - bsr L0E1C - bcs L0E84 - leax $01,x -L0E84 leay >u0175,u - ldb #81 -L0E8A lda ,x+ - bsr L0F0C Convert char to uppercase if lower - sta ,y+ - cmpa #C$CR - beq L0E99 - decb - bne L0E8A - bra L0F17 - -L0E99 negb - addb #$51 - stb <u0017 - clra - sta -$01,y - tst <u0015 - beq L0EE0 - leax >u166D,u - ldd #$30b4 Store 180 ASCII 0's into buffer -L0EAD sta ,x+ - decb - bne L0EAD - leax >u0124,u - ldb <u0016 - leax b,x - leay >u16BD,u - bsr L0ED8 - leax >u0175,u - ldb <u0017 - leax b,x - leay >u170E,u - bsr L0ED8 - leax >u166D,u - leay >u16BE,u - bra L0EE8 - -L0ED8 lda ,-x - sta ,-y - decb - bne L0ED8 - rts - -L0EE0 leax >u0124,u - leay >u0175,u -L0EE8 ldb #80 -L0EEA lda ,x+ - cmpa ,y+ - blo L0EFB - bhi L0F01 - decb - bne L0EEA - lda <u005F - bita #$01 - bra L0F05 - -L0EFB lda <u005F - bita #$02 - bra L0F05 - -L0F01 lda <u005F - bita #$04 -L0F05 lbne L0DF8 - lbra L0DEE - -* Convert char to uppercase if it is a letter -L0F0C cmpa #'a Lower case letter? - blo L0F16 No, return - cmpa #'z Check high range - bhi L0F16 No, return - suba #$20 Yes, convert to uppercase -L0F16 rts - -L0F17 comb - ldb #$01 - lbra L0191 - -L0F1D cmpa #$03 - beq L0F3F - cmpa #$02 - bne L0F2B - dec <u0044 - blt L0F3F - bra L0F43 - -L0F2B cmpa #$01 - bne L0F3B - lda <u0043 - cmpa #$02 - bne L0F43 - tst <u0044 - beq L0F3F - bra L0F43 - -L0F3B inc <u0044 - bra L0F43 - -L0F3F clr <u0043 - clr <u0044 -L0F43 clrb - rts - -* Table: 7 bytes/entry: -* 1st 5 bytes is name, high bit set & NUL padded -* Byte 6 is # bytes actually used -L0F45 fcs 'IF' - fcb 0,0,0,2,0 - fcs 'ELSE' - fcb 0,4,1 - fcs 'ENDIF' - fcb 5,2 - fcs 'FI' - fcb 0,0,0,2,2 - fcs 'CLRIF' - fcb 5,3 - fcb $ff - -L0F69 leay <L0F45,pc Point to conditionals table -L0F6D ldb 5,y Get actual length of string we are checking - os9 F$CmpNam Compare with string pointed to by X - bcs L0F80 If they don't match, skip ahead - lda 6,y Get conditional token(?) number - ldb b,x Get char past end of matching string - cmpb #C$CR Is it a CR? - beq L0F8B Yes, return - cmpb #C$SPAC Is it a space? - beq L0F8B Yes, return -L0F80 leay 7,y Point to next command in table - lda ,y Get 1st char from this entry - cmpa #$FF End of table marker? - beq L0F8B Yes, return -* NOTE: THIS INCA SEEMS TO BE USELESS, AS F$CMPNAM DOESN'T USE A - inca No, ??? - bra L0F6D Process this one - -L0F8C lda #$01 - sta <u0043 - lbra L0E0B - -L0F93 lbsr L0907 Go find 1st non-space char or single char modifier - bne L0F9B - clr <u0046 -L0F8B rts - -L0F9B leay >L03AC,pc Point to 'GOTO' - ldb #4 4 chars to compare - os9 F$CmpNam Does it match? - lbcs L0BCF No, print 'WHAT?' - leax 4,x Yes, skip X past 'GOTO' - lbsr L091F Go find 1st non-space char past 'GOTO' - leay >u0C4C,u Point to some sort of buffer - lda ,x Get char from GOTO label - cmpa #'+ Is label after current pos. in script file? - bne L0FBB No, skip ahead - sta ,y+ Save '+' in buffer - leax 1,x Bump up source ptr past '+' -L0FBB bsr L100B Go copy label name into buffer - inc <u0046 Set flag that a GOTO was found -L0FBF lda ,x+ Get 1st char from user's label again - leay >L0408,pc Point to single char modifiers table -L0FC5 cmpa ,y+ Illegal modifier char in label name? - bhi L0FC5 Not yet, check other modifiers - blo L0FBF This char ok, check rest of label name - leax -1,x Point to last char (terminator) of label name - stx <u0058 Save it & return - rts - -L0FD0 lda ,x - cmpa #'+ - bne L0FDA - leax 1,x - bra L0FFB -L0FDA tst <u006B - beq L0FEA - ldy <u0067 - ldd $09,y - leay d,y - sty <u0065 - bra L0FFB -L0FEA pshs u,x - clra - ldx #$0000 Seek to beginning - tfr x,u - os9 I$Seek - puls u,x - lbcs L0191 -L0FFB lbsr L091F - leay >u0BFC,u - bsr L100B - lda #C$CR - sta ,x - inc <u0045 - rts - -* Copy label from X to buffer @ Y, terminate at 1st illegal char with CR -* Exit: X=ptr to start of label name from user's buffer -* Y=ptr to start of buffer entry copy of label name -L100B pshs y,x Preserve buffer & source ptrs - ldb #79 (78 bytes to check) -L100F decb Dec # chars left to check - beq L1022 If done max, skip ahead - lda ,x+ Get char for label - sta ,y+ Save in buffer - cmpa #'A Is it a letter or higher? - bhs L100F Yes, continue copying - cmpa #'0 Is it lower than a #? - blo L1022 Yes, not allowed, force end of label name - cmpa #'9 Is it a #? - bls L100F Yes, that is fine -L1022 lda #C$CR All others illegal, force CR in buffer copy - sta -1,y Save it - clrb No error - puls pc,y,x Restore regs & return - -* M= command (???) -L1029 ldb #C$CR - stb -$01,x - tst <u006B - bne L1057 - tst <u006C - bne L1057 - lda #Data Data module type - pshs u,y,x - os9 F$Link - bcs L1055 - stu <u0067 Save start address of module - sty <u0065 Save execution address of module - ldd 2,u - addd <u0067 - subd #$0003 - std <u0069 - inc <u006B - puls u,y,x - leax -$01,x - lbra L0907 - -L1055 puls u,y,x -L1057 lbra L0BCF - -* VAR. command -L105A leay >u05A8,u - lda ,x+ - cmpa #'? - beq L10C9 - cmpa #'= - beq L1096 - cmpa #C$SPAC - beq L1085 - cmpa #'; - beq L1085 - cmpa #'9 - bhi L1085 - cmpa #'0 - bcs L1085 - suba #$30 - ldb #$51 Multiply by 81 (size of each VAR entry) - mul - leay d,y - lda ,x+ - cmpa #'= - beq L1096 -L1085 leax -$01,x - pshs x - tfr y,x - ldy #$0051 - lda #$02 - os9 I$ReadLn - puls pc,x - -L1096 ldb #80 - lbsr L0A25 - lda #C$CR - sta ,y - rts - -L10A0 fcb C$LF - fcc 'User Variables :' - fcb C$CR - -L10B2 fcb C$LF - fcc 'Shell Sub Variables :' - fcb C$CR - -L10C9 pshs x - clrb - leax >L10A0,pc - bsr L10DF - leay >u08D2,u - clrb - leax >L10B2,pc - bsr L10DF - puls pc,x - -L10DF pshs y,b - lbsr L021B - puls y,b -L10E6 pshs y,b - lda #$51 - mul - leay d,y - leax >u0124,u - ldd #'V*256+'A - std ,x++ - ldd #'R*256+'. - std ,x++ - lda ,s -L10FD adda #$30 - ldb #'= - std ,x++ -L1103 lda ,y+ - sta ,x+ - cmpa #C$CR - bne L1103 - leax >u0124,u - ldy #$0057 - lda #$01 - os9 I$WritLn - puls y,b - bcs L1122 - incb - cmpb #C$LF - bcs L10E6 - rts - -L1122 puls y - puls pc,x - -* INC. command (increment shell variable by 1) -L1126 bsr L1144 - lbcs L0191 - addd #$0001 - bra L113A - -* DEC. command (decrement shell variable by 1) -L1131 bsr L1144 - lbcs L0191 - subd #$0001 -L113A bsr L11A7 - lda #C$CR - sta $05,y - ldx <u0048 - clrb - rts - -L1144 inc <u0014 - leay >u05A8,u - lda ,x+ - stx <u0048 - cmpa #'0 - bcs L1161 - cmpa #'9 - bhi L1161 - suba #$30 - ldb #81 - mul - leay d,y - tfr y,x - bra L1166 - -L1161 leas 2,s - lbra L0BCF - -L1166 pshs y - leas -$05,s - tfr s,y - clr $03,y - clr $04,y -L1170 clr $02,y - lda ,x+ - suba #$30 - cmpa #$09 - bhi L1195 - pshs a - lda #10 - ldb $03,y - mul - std ,y - lda $04,y - ldb #10 - mul - addd $01,y - std $01,y - clra - puls b - addd $01,y - std $03,y - bra L1170 - -L1195 ldd 3,y - leas 5,s - puls pc,y - -* 2 byte ASCII conversion table -L119B fdb 10000 - fdb 1000 - fdb 100 - fdb 10 - fdb 1 - fdb 0 - -L11A7 pshs y,x,d - pshs b - leax >L119B,pc -L11AF pshs d - ldb #'/ - stb 2,s - puls d -L11B7 inc ,s - subd ,x - bcc L11B7 - addd ,x++ - pshs d - ldb $02,s - stb ,y+ - lda $01,x - puls d - bne L11AF - puls b - puls pc,y,x,d - -* PAUSE command - may display text message, and then waits for key press or -* mouse button -L11CF ldy #394 Write up to 394 chars of pause string - lda #$02 To standard error - os9 I$WritLn - lbcs L0191 - tfr y,d Tfr # chars written to D - leax d,x Point X to next char after ones written - leax -1,x Point to last char written - pshs x Save ptr - ldd #$02*256+SS.SSig Std Err/Send signal when key pressed - ldx #$000A Signal $A is the one to send - os9 I$SetStt - lbcs L0191 Error, use main shell error handler - ldb #SS.MsSig Send signal on mouse button press - os9 I$SetStt - lbcs L0191 - ldx #$0000 Go to sleep until one of the 2 is received - os9 F$Sleep - ldb #SS.Relea Signal gotten, release all signals - os9 I$SetStt - clrb No error & return - puls pc,x - -* Parse PATH=, add paths to PATH buffer list -L1209 pshs x Preserve ptr to string after 'PATH=' - lda ,x Get 1st char - cmpa #'? User requesting current paths? - beq L1245 Yes, go do that - pshs u Preserve U - leau >u0CDD,u Point to PATH= buffer -L1217 lda ,x+ Get char from user-requested path - cmpa #C$SPAC Space? - beq L1217 Yes, eat spaces until 1st real char found - sta ,u+ No, save char -L121F leay >L0408,pc Point to command modifier list -L1223 cmpa ,y+ Match char? - bhi L1223 No, our char is higher, check next modifier - beq L1237 Found match, skip ahead - lda ,x+ No modifier found, get next char - sta ,u+ Save in PATH buffer - cmpa #C$SPAC Was it a space? - bne L121F No, check this char vs. modifier list - lda #C$CR Yes, change to CR - sta -1,u Save CR instead (terminate 1 path entry) - bra L1217 Do whole list - -* NOTE: ANY modifier (not just CR, but ! # & ; < > ^ |) stops PATH=parsing -L1237 leax -1,x Bump ptr back to last char from user - stx 2,s Save ptr on stack over original X - lda #C$CR Get CR - sta -1,u Save CR as current path end - sta ,u And 1 extra for parse routines - puls u Get U back - puls pc,x Restore new X & return - -L1245 leax >u0CDD,u Point to start of PATH=buffer -L1249 ldy #400 Write up to 400 chars to standard out - lda #$01 - os9 I$WritLn Print text of one path - lbcs L0191 Error, go process shell error - tfr y,d Tfr # bytes written to D - leax d,x Offset X to end of what was printed - lda ,x Get char from there - cmpa #C$CR CR (end of path list)? - bne L1249 No, go write next path out - puls x Restore ptr to next set of PATH= - leax 1,x Bump ptr up by 1 & return - rts - -* ^ (set priority on the fly) command -L1265 ldb #C$CR Plop a CR onto the end - stb -$01,x - ldb <u0022 Any priority already set? - lbne L0BCF Yes, print 'WHAT?' - lbsr L16EB Go calculate binary priority into B - stb <u0022 Save priority to fork module with - lbra L0907 Continue processing for modifiers - -* # (set data memory size) command -L1277 ldb #C$CR - stb -1,x - ldb <u0003 Already have a data mem size set? - lbne L0BCF Yes, print 'WHAT?' - lbsr L16EB - eora #'K - anda #$DF Force uppercase - bne L1294 No 'K', just save # of 256 byte pages - leax 1,x - lda #4 Multiply # of K by 4 to get # pages - mul - tsta - lbne L0BCF Ended up too big, print 'WHAT?' -L1294 stb <u0003 Save data mem size to use - lbra L0907 Continue processing command line - -* Carriage return processing -L1299 leax -1,x - lbsr L145D - bra L12A3 - -* ; (separator) command (also called by others) -L12A0 lbsr L1459 -L12A3 bcs L12BA - lbsr L0B96 Go do the path stuff - tst <u005D Is there a module that is unlinking? - bne L12AE Yes - bsr L12D2 Go wait for child process to die (A=process #) - -L12AE bcs L12BA If child exited with status/signal code,skip - lbsr L0907 Go parse for modifiers - cmpa #C$CR Was the next non-space/comma char a CR? - bne L12B9 No, skip ahead - leas 4,s Yes, eat stack -L12B9 clrb No error - -* Child process had a signal/status code -L12BA pshs cc Preserve error status - clr <u005D ??? - puls cc Restore carry - lbra L0B96 ??? Go close some paths & return? - -* & (background operation) command -L12C3 lbsr L1459 - bcs L12BA - bsr L12BA - ldb #$26 - lbsr L16B3 - bra L12AE - -* W command - Wait for a child to die -L12D1 clra Clear process ID # -* Entered here if commands are separated with ';' (or '()' groups) -L12D2 pshs a Save ID # of process? -L12D4 os9 F$Wait Wait for child to die or until signal received - tst <u000E Signal received (which would be in SHELL)? - beq L12EC No, child was exited (or got signal), go process -* Shell was interrupted by signal while Waiting - ldb <u000E Get signal that we received - cmpb #S$Abort Was it a PD.QUT (<CTRL>-<E>) (quit 'W'aiting?) - bne L1304 No, skip ahead - lda ,s Get process # - beq L1304 None, exit - os9 F$Send Send the signal to the child as well - clr ,s Clear process # - bra L12D4 Go Wait again (until child dies) - -* Child F$Exited or was aborted - eat should go here -* Entry: A=ID # of deceased child -* B=Exit (error) code from child -L12EC lbcs L1308 If F$Wait exited with error, return with it - cmpa ,s Same process # as one we were waiting for? - beq L1304 Yes, exit - tst ,s No, was there a specific process # we wanted? - beq L12F9 No, skip ahead -* Child died, but not the one we were waiting for - tstb Was there an error status? - beq L12D4 No, ignore dead child and wait for one we wanted -* Child died with error on exit -L12F9 pshs b Preserve child's exit status code - bsr L12BA ??? Go close & re-dupe paths? - ldb #'- Get a '-' (for a '-003' process finished msg) - lbsr L16B3 Print that out - puls b Get back exit status code - -L1304 tstb is there an Error/signal code? - beq L1308 No, exit - cmpb #S$Intrpt Yes, is it a keyboard interrupt signal? - beq eatchar Yes, eat the key - cmpb #S$Abort Keyboard abort signal? - bne errexit No, exit with unknown error/signal code - -* At this point, child died from signal 2 or 3 (CTRL-C or CTRL-E). The corres- -* ponding key is also sitting in this devices PD.BUF as the 1st char. We musts -* 1) Disable keyboard signal & eat the key from the buffer -* 2) Exit from here with Carry set & signal (2 or 3) in B -eatchar pshs b,x,y Preserve signal code & regs used - ldd #SS.Ready Std in, check for data ready on device - os9 I$GetStt Check it - bcs NotSCF No chars waiting on device, exit with signal - lda <u0018 Is the shell immortal? - beq NotSCF No, don't try to eat the char -eat clra Standard in path - leas -PD.OPT,s Make 32 byte buffer for OPT's - leax ,s Point X to it - clrb SS.Opt call - os9 I$GetStt Get current path options - lda ,x Get device type - beq Eatkey SCF (not script file) so go eat key -NoChar leas $20,s Eat temp buffer - bra NotSCF Exit with signal code (script file got signal) - -* Have to eat key: Shut echo off 1st -Eatkey clr 4,x PD.EKO flag off - os9 I$SetStt Shut echo off - ldd #SS.Relea Std In, Release keyboard/mouse signals - os9 I$SetStt Shut signals off so we don't get stuck - leax ,-s Make 1 byte buffer on stack - ldy #1 1 byte to read - os9 I$Read Eat the char - leas 1,s eat buffer - ldd #SS.SSig Std In, send signal on key ready - ldx #$B Signal to send - os9 I$SetStt Turn keyboard signal on again - leax ,s Point to temp buffer again - inc 4,x PD.EKO flag on - clra Std In - clrb Set Options - os9 I$SetStt Turn echo back on - leas $20,s Deallocate temp buffer - ldb u180D,u Get current history line # - cmpb #1 First one? - bhi Previous No, B=previous one - ldb u180C,u Was on first, so get last - incb Adjust for dec -Previous decb Point to previous one - lbsr L19D3 Go get ptr to history - lda ,y Get 1st char from previous line in history - sta ,x Save char there - ldd #SS.Fill Fill keyboard buffer call to Std In - ldy #$8001 1 char long, don't append CR - os9 I$SetStt Stick that key into the keyboard buffer -NotSCF puls b,x,y Restore regs (and exit status byte in B) -errexit coma Yes, set carry & exit -L1308 puls pc,a - -* If data area <4.25K, force up to 7.5K -* Exit: A=Type/language -* X=Current source line parsing ptr (module name to chain) -* Y=Size of parameter area -* U=Ptr to parameter area -* B=Size of data area -L130A lda #Prgrm+Objct Module type/language - ldb <u0003 Get # pages of data mem needed for forked module - cmpb #$11 Is it at least 17? - bhs L1316 Yes, skip ahead - ldb #$1F Otherwise, force to 7.5K minimum - stb <u0003 Save it -L1316 andcc #^Carry Clear carry - ldx <u0004 Get mem module ptr - ldy <u0006 Get size of current command group - ldu <u0008 Get ptr to start of current command group - rts - -* Copy string from X to Y until CR is hit -L1320 lda ,x+ Get char - sta ,y+ Save it - cmpa #C$CR Carriage return? - bne L1320 No, keep copying - rts Done, return - -* Attempt load in module to execute (it's not in memory) -* Entry: X=Ptr to module name -L1329 lda #EXEC. 1st, attempt to get it from current Exec DIR - os9 I$Open Attempt to open it - bcc L1362 Found it, continue -* Possible search thru PATH= settings - inc <u000F ??? Set flag to indicate using PATH= - leax >u0CDD,u Point to start of PATH= list -L1336 clrb - lda ,x Get 1st char from next PATH= line - cmpa #C$CR End of list? - lbeq L1564 Yes, ??? - leay >u0124,u No, point to temp buffer - bsr L1320 Copy path to temp buffer until CR - pshs x Preserve ptr to next possible path - lda #'/ Add slash since we want file from this path - sta -1,y Save at end of path in temp buffer - ldx <u0004 Get ptr to module/script name we are looking for - bsr L1320 Copy it into temp buffer up to CR - leax >u0124,u Point to start of full path list - lda #READ. Attempt to open file - os9 I$Open - puls x Restore ptr to next possible path - bcs L1336 Didn't find file there, try next path - leax >u0124,u Point to full pathlist again - stx <u0004 Replace ptr to module with full pathlist ptr -L1362 leax >u00D6,u Point to buffer to hold beginning of file - ldy #77 77 bytes to read - os9 I$Read Read it in - bcc L1373 No error, skip ahead - cmpb #E$EOF Just EOF error? - bne L13CE No, something more serious, skip ahead -L1373 tst <u000F - bne L137B - ldb #$04 - stb <u000F -L137B pshs a Save path # a sec - ldd M$ID,x Get possible module header bytes - cmpd #M$ID12 Legit module header? - puls a Restore path # - beq L1396 OS9 module, skip ahead -* Not module...possible shell script? - os9 I$Close Not OS9 module, close file - clrb - dec <u000F Dec flag - lbeq L1564 If 0, skip ahead - inc <u000F If not, inc & skip ahead - lbra L1564 - -* Seems to be OS9 module -L1396 clr <u000F Clear flag - ldy M$Name,x Get offset to module name - leax >u00E3,u Point X to offset $E in module - cmpy #$000D Does the name start at offset $D? - beq L13C0 Yes, skip ahead - pshs u Preserve U - tfr y,u Move name offset to U - ldx #$0000 MSW of file pos=0 - os9 I$Seek Go seek to that spot in file - puls u Restore U - bcs L13CE Error seeking, go handle - ldy #64 Go read up to 64 char filename - leax >u00E3,u Point to spot to hold filename - os9 I$Read Read it in - bcs L13CE Error reading, go handle -L13C0 pshs a Save path # - os9 F$PrsNam Parse module name - puls a Restore path # - bcs L13CE - cmpb #$40 - bhi L1422 - clrb -L13CE pshs b,cc Preserve error status - os9 I$Close Close file - puls b,cc Restore error status - lbcs L162B If error, exit with it (S/B L162C) - leax >u00D6,u Point to buffer holding 77 bytes of file - lda $06,x - ldy $0B,x - cmpa #$40 - bne L1407 - bsr L13EF - lbcs L162B - lbra L14AF -L13EF leax >u00E3,u - os9 F$NMLink - bcc L1400 - ldx <u0004 - os9 F$NMLoad - bcc L1400 - rts -L1400 leax >u00E3,u - stx <u0004 - rts -L1407 cmpa #$51 - bne L1413 - bsr L13EF - lbcs L162B - bra L1427 -L1413 cmpa #$11 - lbne L14D7 - leax >u00E3,u - stx <u0010 - lbra L15D7 -L1422 lbsr L08CB - bra L13CE - -* Call a shellsub module -L1427 clra Type/language byte to wildcard:any will match - ldx <u0004 Get ptr to module name - pshs u Preserve U - os9 F$Link Attempt to link it in - puls u Restore U - lbcs L162B If we couldn't link, Exit with error - ldx <u0004 Get ptr to module name again - os9 F$UnLoad Unlink it - lbcs L162B If we couldn't unlink exit with error - ldx <u0008 Get ptr to current group (param ptr for shellsub) - ldd <u0006 Get size of param area for shellsub - leau >u08D2,u Point to shellsub variable area - jsr ,y Execute shellsub module - pshs b,a,cc Preserve error status & A - clra - clrb - std <u0010 ? (originally pointing to E3 if type $11 module) - ldx <u0004 Get shellsub module ptr - os9 F$UnLoad Unlink it - std <u0004 Clear shellsub module ptr - inc <u005D Set flag that we should wait for module to exit? - puls pc,u,y,x,d,cc restore regs & return - -L1459 lda #C$CR - sta -1,x -L145D clr <u0060 - pshs u,y,x - ldx <u0004 Get ptr to name - ldd ,x Get 2 chars of name - andb #$5F Force 2nd one to uppercase - cmpd #$2F57 Is it a /W? - bne L1473 No, check for shellsub - comb Yes, exit with bad mode error - ldb #E$BMode - lbra L162B - -L1473 clra Wildcard NMLink - os9 F$NMLink Link to module - lbcs L1329 Error, do something - cmpa #ShellSub+Objct ShellSub module? - beq L1427 Yes, go set up for it - ldx <u0004 Get ptr to name back - os9 F$UnLoad Drop the link count back down - pshs y Save data area size - ldx <u0004 Get ptr to module name again - leay >L000D,pc Point to 'Shell' - ldb #$05 Size of 'Shell' - os9 F$CmpNam Is the module requested Shell? - puls y Restore data area size - bcs L14A3 Not shell, skip ahead - ldb 5,x Get char right after 'shell' - cmpb #C$CR Is 'shell' the only thing on the line? - lbeq L158D Yes, skip ahead - cmpb #C$SPAC Is it a space? - lbeq L158D Yes, skip ahead -* Not Shell or Shellsub module -L14A3 cmpa #Prgrm+Objct ML program? - lbeq L15D7 Yes, skip ahead - cmpa #Data Is it a data module? - bne L14D7 No, skip ahead - inc <u0060 Set flag - data module -L14AF inc <u0060 Bump it up - ldx <u0004 Get ptr to module name - os9 F$PrsNam Parse the name - ldy <u0063 Get ptr to Intercept routines data mem ($418) - leay $0A,y Bump up to $422 - sty <u0008 Save ptr to start of current group - sty <u0061 ??? Ptr to data modules name? - ldx #60 Max size of group - stx <u0006 Save it - ldx <u0004 Get ptr to module name -L14C8 lda ,x+ Copy it to buffer @ $422 - sta ,y+ - decb - bne L14C8 - lda #C$CR Append a CR to it - sta ,y+ - clrb - lbra L1564 -* Not 6809 object code or data module either -L14D7 sty <u000A Save data area size - leax >L0013,pc Point to alternate languages table -L14DE tst ,x Is this entry active? - lbeq L1629 No, exit with non-existing module error - cmpa ,x+ Same module type as we want? - beq L14EE Yes, skip ahead -L14E8 tst ,x+ No, eat module name - bpl L14E8 - bra L14DE Try next module -* Found run-time language match -L14EE ldd <u0008 Get ptr to start of current command group - subd <u0004 Calculate size of whole group - addd <u0006 Don't include size of current group - std <u0006 Save remainder size - ldd <u0004 Get ptr to start of sub-module - std <u0008 Save it - pshs y,x Preserve data area size & primary module ptr - leax >L0021,pc Point to 'RUNB' - cmpx ,s Is that the run-time module we want? - bne L1546 No, skip ahead -* RUNB needed - have to () & quote/commas between params - ldx <u0008 Yes, get sub-module ptr? - leay >u0418,u Point to before sub-module - bsr L154B Copy buffer up to next param (or end of line) - beq L1535 If it was end of line, add CR & continue - ldd ,x Get 2 param chars - cmpd #$2822 Is it '("' (RUNB variables ahead?) - beq L1546 Yes, skip ahead (we won't have to add them) - lda #C$SPAC No, add ' ("' - sta ,y+ - ldd #$2822 - std ,y++ -L151F bsr L154B Copy buffer up to next param (or end of line) - beq L152E If end of line, add '")' (close params) - ldd #$222C Add '","' (Basic09 param separators - std ,y++ - lda #$22 2nd quote of above - sta ,y+ - bra L151F Keep doing for all parameters - -L152E ldd #$2229 Add '")' to end parameter list - std ,y++ - lda #C$CR Add CR -L1535 sta ,y+ - tfr y,d Move end of param ptr to D - leay >u0418,u Point to start of param - sty <u0008 Save as start ptr - subd <u0008 Calculate param size - std <u0006 Save it -L1546 puls y,x Restore data area size & primary module ptr - lbra L15D5 - -* Copy from X to Y until either a CR or a space char is hit -* If it finds a space, it will eat them until the next non-space char is found -L154B lda ,x+ Get char - cmpa #C$SPAC Is it a space? -* Was L155B - beq L1559 yes, skip ahead - cmpa #C$CR Is it the end of the line? - beq L155F Yes, bump ptr back to CR & exit - sta ,y+ Save the char - bra L154B Keep doing it - -L1559 lda ,x+ Get char -L155B cmpa #C$SPAC Is it another space? - beq L1559 Yes, keep eating spaces -L155F leax -$01,x Bump ptr back to either non-space or CR - cmpa #C$CR Is it a CR? & return - rts - -* THIS CMPB / LBEQ SEEMS TO BE USELESS, AS B IS ALWAYS CLEAR COMING INTO THIS -* ROUTINE -L1564 cmpb #E$BMode - lbeq L162B - ldx <u0006 Get size of current group - leax 5,x Bump it up by 5??? - stx <u0006 Save new size - tst <u0060 Data module linked? - bne L1592 Yes, skip ahead - ldx <u0004 Get module name ptr - ldu 4,s - lbsr L0BFA Set up paths - lbcs L162B If error, exit with it - bra L1592 Start up shell with '-P X PATH=(current)' - -* L1581 is for sub-shells (?), L1586 for normal shells -L1581 fcc '-P X ' Prompting off/exit on error -L1586 fcc 'PATH= ' For inheriting parent shell's paths - fcb C$CR - -L158D leax <L1586,pc Point to 'path=' - bra L1595 Skip ahead - -L1592 leax <L1581,pc Point to '-p x ' -L1595 leay >u166D,u Point to about-to-be merged buffer - lbsr L1320 Copy up until CR - leay -1,y Point to CR - leax >u0CDD,u Point to copy of current path= -* Copy all paths to buffer, changing <CR> separated ones with Spaces -L15A2 lda ,x Get char - cmpa #C$CR CR? - beq L15B1 Yes, don't copy this buffer - lbsr L1320 Copy up until CR - lda #C$SPAC Replace CR with Space - sta -1,y - bra L15A2 Continue copying CR marked blocks until done -L15B1 lda #'; Replace final CR with ; (command separator) - sta -1,y - tst <u0060 - beq L15BE - ldd #'M*256+'= If flag set, append 'M=' - std ,y++ -L15BE ldx <u0008 Get ptr to start of current group - lbsr L1320 Copy up until CR - leax >u166D,u Point to merged buffer again - stx <u0008 Make it the new current group start - tfr y,d Move end buffer ptr to D - pshs x Push merged buffer ptr for SUBD - subd ,s++ Calculate size of merged buffer - std <u0006 Save merged buffer size - leax >L000D,pc Point to 'shell' - -L15D5 stx <u0004 Save ptr to module name to fork -L15D7 ldx <u0004 Get ptr to module name to fork - lda #Prgrm+Objct - os9 F$NMLink Get memory requirement stuff from it - bcc L15E5 Got it, continue - os9 F$NMLoad Couldn't get, try loading it - bcs L162B Still couldn't get, can't fork -L15E5 tst <u0003 Memory size specified? - bne L15F2 Yes, skip ahead - tfr y,d No, tfr modules mem size to D - addd <u000A ??? Add to something - addd #$00FF Round up to nearest page - sta <u0003 Save # of pages need for data mem -L15F2 clr ,-s Clear byte on stack to store original priority - ldb <u0022 Get priority we want to set new program at - beq DnePrior 0=Use inherited priority, skip ahead - leax >u166D,u Point to place to hold Process descriptor - os9 F$ID Get our process # - os9 F$GPrDsc Get our process descriptor - ldb P$Prior,x Get our priority - stb ,s Save it - ldb <u0022 Get priority for new process - os9 F$SPrior Set our priority so child will inherit it -DnePrior lbsr L130A Go setup Fork entry registers - os9 F$Fork Create the new process - pshs d,cc Preserve error (if any) & new process # - ldb 3,s Get original priority back - beq L1609 Priority didn't change, ignore it - os9 F$ID Get our process # into A - os9 F$SPrior Reset our priority back to normal -L1609 lda #Prgrm+Objct Std 6809 module - ldx <u0010 Get ptr to some other module name (?) - bne L1611 There is one, unlink it instead - ldx <u0004 Get ptr to command name -L1611 os9 F$UnLoad Bump link count down back to normal? - clra - clrb - std <u0010 Zero out other module name ptr - std <u0004 Clear out ptr to main command name - lda <u0060 Check if data module needs to be unlinked too - cmpa #$01 Just 1 link to it? - bne L1627 No, skip ahead - lda #Data Data module - ldx <u0061 Get ptr to name of data module - os9 F$UnLoad Bump link count down back to normal -L1627 puls cc,d Get back F$FORK error/process # - leas 1,s Eat priority byte - puls pc,u,y,x Restore regs & return - -L1629 ldb #E$NEMod Non-existing module error -L162B coma - puls pc,u,y,x - -L162E fcc '/pipe' - fcb C$CR - -L1634 pshs x - leax <L162E,pc Point to '/pipe' - ldd #$0103 - lbsr L0C0E - puls x - bcs L169E - lbsr L1459 - bcs L169E - lda ,u - bne L1653 - os9 I$Dup - bcs L169E - sta ,u -L1653 clra - os9 I$Close - lda #$01 - os9 I$Dup - lda #$01 - lbsr L0BA8 - lda #$02 - lbra L0BA8 - -* Filename for shell log-append mode because of leading '+' -L1666 fcc '+/dd/log/uxxx' - fcb $0d - -* Make shell logging filename @ u0CBD,u -L1674 leax <L1666,pc Point to log name string (append mode) - leay >u0CBD,u Point to buffer to hold shell log name - lbsr L1320 Copy name to buffer - leay -4,y Point to where 1st digit will go - lda <u005A+1 Get LSB of user #? - pshs y,x,d Preserve regs - leay <L1693,pc Point to routine - bra L16B9 Go convert digits & append to logname - -L168A lda <u0047 - pshs y,x,d - leay <L1693,pc - bra L16B9 - -L1693 ldy $0B,s Get ptr to where shell log # goes - ldd $03,s Get 1st 2 digits of # - std ,y++ Save in shell log pathname - lda $05,s Get last digit - sta ,y Save it too -L169E rts - -L169F ldd 4,s Get last 2 digits of process # (ASCII) - std >u01EC,u Save it & return - rts - -L16A6 pshs y,x,d Preserve End of parm ctr & others - os9 F$ID Get user's ID # - sty <u005A Save it - leay <L169F,pc Point to routine - bra L16B9 - -* Set up to write out process # when forked? -L16B3 pshs y,x,d - leay >L021B,pc - -* Entry: A=Process ID # -* Exit: L01EC=2 lower digits of process # in ASCII format - -L16B9 pshs y,x,b Preserve regs - leax 1,s Point X to X value on stack - ldb #$2F Init B to start @ '0' in loop -L16BF incb Bump ASCII # up - suba #100 Start with 100's digit - bhs L16BF More left, keep going - stb ,x+ Save digit - ldb #$3A Init so loop starts @ ASCII '9' -L16C8 decb Bump ASCII # down - adda #10 Do 10's digit - bhs L16C8 Still more, keep going - stb ,x+ Save 10's digit - adda #$30 Bump 1's digit up to ASCII equivalent - ldb #C$CR Add carriage return - std ,x Save overtop Y on the stack - leax ,s Point X to B on stack - jsr ,y - leas 5,s Eat stack - puls pc,y,x,d Restore other regs & return - -* KILL command -L16DD bsr L16EB Go get process # to kill - cmpb #2 Trying to kill the system process or 1st shell? - bls L170A Yes, print 'WHAT?' & ignore it - tfr b,a Move process # to proper reg -L16E5 clrb S$Kill signal - os9 F$Send Send it to the process & return - rts - -* Set priority - subroutine to calculate binary version of # -* (used for both process # & priority values) -L16EB clrb Initialize # for loop -L16EC lda ,x+ This loop will calculate the binary version - suba #$30 Of the ASCII # pointed to by X - cmpa #9 - bhi L16FD - pshs a - lda #10 - mul - addb ,s+ - bcc L16EC Keep going until overflows past 255 -L16FD lda ,-x Get last char done - bcs L1708 If #>255, eat RTS & exit with error - tst <u0014 If flag is set, return - bne L169E - tstb Otherwise, check if # is 0 - bne L169E No, return -L1708 leas 2,s Yes, eat RTS address & exit with error -L170A lbra L0BCF Print 'WHAT?' -* SETPR routine -L170D bsr L16EB Go calculate process # - stb <u0021 Save it - lbsr L0907 Find next field (after commas/spaces) - bsr L16EB Go calculate priority (into B) - lda <u0021 Get process # - os9 F$SPrior Set it's priority & return - rts - -L171C fcc 'pwd: bad name in path' - fcb C$CR -L1732 fcc '.......................................' -L1759 fcc '.' - fcb C$CR -L175B fcc 'pwd: read error' - fcb C$CR - -L176B clr <u003D -L176D pshs y,x - leay >u02F2,u - lda #$81 - tst <u0037 - beq L178F - ldx <u0039 - bra L17F7 -* .PXD command -L177D clr <u003D - pshs y,x - leay >u0375,u - lda #$85 - tst <u0038 - beq L178F - ldx <u003B - bra L17F7 -L178F sta <u0029 - sty <u003E -L1794 leax >$0080,y - lda #$0D - sta ,x - stx <u002A - leax <L1759,pc - stx <u0040 - bsr L1801 - lbsr L183C -L17A9 ldd <u002C - std <u0032 - lda <u002E - sta <u0034 - bsr L1828 - beq L17D3 - lda <u0012 - os9 I$Close - lbcs L188C - ldx <u0040 - leax -$01,x - stx <u0040 - bsr L1801 - bsr L183C - bsr L1817 - leax >u03F8,u - lbsr L1859 - bra L17A9 -L17D3 lda <u0012 - ldb #SS.DevNm - leax >u00B5,u - os9 I$GetStt Get device name - bsr L1859 -L17E0 lda <u0012 - os9 I$Close - ldx <u002A - lda <u0029 - bita #$04 - bne L17F3 - inc <u0037 - stx <u0039 - bra L17F7 -L17F3 inc <u0038 - stx <u003B -L17F7 ldy #$0083 - lda #$01 - clrb - lbra L18A0 -L1801 lda <u0029 - os9 I$Open - sta <u0012 - rts -L1809 lda <u0012 - leax >u03F8,u - ldy #$0020 - os9 I$Read - rts -L1817 bsr L1809 - bcs L1896 - leax >u0415,u - leay >u0032,u - bsr L1830 - bne L1817 - rts -L1828 leax >u002C,u - leay >u002F,u -L1830 ldd ,x++ - cmpd ,y++ - bne L183B - lda ,x - cmpa ,y -L183B rts -L183C bsr L1809 - ldd >u0415,u - std <u002F - lda >u0417,u - sta <u0031 - bsr L1809 - ldd >u0415,u - std <u002C - lda >u0417,u - sta <u002E - rts -L1859 os9 F$PrsNam - bcs L1890 - ldx <u002A - pshs b - incb - clra - std <u0032 - tfr x,d - subd <u0032 - cmpd <u003E - bls L1881 - puls b -L1871 lda ,-y - anda #$7F - sta ,-x - decb - bne L1871 - lda #$2F - sta ,-x - stx <u002A - rts - -L1881 lda #'* - sta ,-x - stx <u002A - leas 3,s - lbra L17E0 - -L188C pshs b,cc - bra L18AB - -L1890 leax >L171C,pc - bra L189A - -L1896 leax >L175B,pc -L189A leas $02,s - ldd #$02FF -L18A0 stx <u002A - pshs b,cc - tst <u003D - bne L18AB - os9 I$WritLn -L18AB puls b,cc - puls y,x,pc - -L18DB leax >u0124,u Point to PD.OPT work copy area - clrb Change to CLRB - os9 I$GetStt Get current PD.OPT settings - tst ,x Check device type - bne L1914 If not SCF, don't bother changing stuff - inc >u1812,u Set flag that we are changing key defs - ldd <$10,x Get PD.INT & PD.QUT chars (<CTRL>-<C> & <E>) - sta >u180F,u Save copy of PD.INT - stb >u180E,u Save copy of PD.QUT - ldd #$0A0C Reload with up & down arrows - std <$10,x Save 'em - lda $06,x Get PD.NUL count (normally 0) - sta >u1811,u Save copy - lda #$05 Replace with 5 - sta $06,x - clra - clrb Reset path options to new settings - os9 I$SetStt Do SS.OPT Setstat - -* Non-SCF devices go here (ex. a script file would be RBF) -L1914 ldb #SS.SSig Send signal on data ready - ldx #$000B Signal code to send is $B - rts Do SetStt, clear <E signal copy, and go to L191C - -* X still is $B from L1914 -* Called when F$Sleep @ L0171 is interrupted by keyboard/mouse signal -L191C ldb <u000E Get Signal code - clr <u000E Clear memory copy of signal code - cmpb #S$Abort Keyboard abort signal (<CTRL>-<E>)? - bne L1928 No, check next - bsr L1932 Write CR out if no history yet - bra L1967 Go backwards in history - -L1928 cmpb #S$Intrpt Keyboard interrupt signal (<CTRL>-<C>)? - lbne L017B No check for $B signal (ignore rest) - bsr L1932 Write CR out if no history yet - bra L1991 Go forwards in history - -* Keyboard abort or Keyboard interrupt signal -L1932 tst >u180D,u Any history entries yet? - bne L193D Yes, exit - bsr L1959 Otherwise, put CR into the buffer - os9 I$WritLn Write it out to standard out -L193D rts - -L193E os9 I$ReadLn Read in line - bcc L194E No error, skip ahead -* NOTE: WHEN THE ABORT A SUB-FORKED PROGRAM BUG OCCURS, THE ABOVE READLN -* EXITS WITH CARRY SET & B=0 (ERROR 0) - cmpb #$02 Go backward in history buffer signal? - beq L1967 Yes, go process - cmpb #$03 Go forward in history buffer signal? - beq L1991 Yes, go process - lbra L1AAA Go to parse routine with unknown error in B -L194E cmpy #$0001 Just 1 char. read? - lbeq L1AA3 Yes, go do normal parsing (no error) - lbra L1A37 Otherwise, change chars <$0D to spaces - -* Change A to be standard output??? -L1959 lda #C$CR Carriage return - leax >u0124,u ??? Point to a buffer - sta ,x Save CR there - clra Prepare to write the CR out to standard input - ldy #$0001 - rts -* PD.QUT (redefined to be go back 1 in history buffer) -L1967 tst >u180C,u Any lines in history buffer? - bne L1972 Yes, go move between them - bsr L1959 Otherwise, put CR into buffer - lbra L1AA3 Go to normal command parse routine (no error) - -L1972 ldb >u180D,u Get 'current' history buffer entry # - cmpb #$01 On the first one? - bls L1987 Yes, go wrap to end - cmpb >u180C,u Somehow point past last one? - bhi L1987 Yes, bump back to last one - decb Bump to previous one - stb >u180D,u Save it as 'current' history entry # - bra L19B3 - -L1987 ldb >u180C,u Get highest history entry # - stb >u180D,u Make it the current - bra L19B3 - -* PD.INT (redefined to be go forward 1 in history buffer) -L1991 tst >u180C,u Any lines in history buffer? - bne L199C Yes, go move between them - bsr L1959 Otherwise, put CR into buffer - lbra L1AA3 Go to normal command parse routine (no error) - -L199C ldb >u180D,u Get current history entry # - cmpb >u180C,u Higher or same as last one? - bhs L19AD Yes, wrap to beginning - incb Bump to next one - stb >u180D,u Save it as 'current' history entry # - bra L19B3 - -L19AD ldb #$01 Set history entry # to 1st one - stb >u180D,u Save as 'current' entry # -L19B3 bsr L19D3 Go get ptr to history entry buffer we want - sty >u1813,u Save 'current' history buffer ptr - leax >u0213,u Point to expanded shell prompt - ldy >u01F7,u Get size of expanded shell prompt - lda #$02 Std Err - os9 I$WritLn Write out shell prompt - bsr L19EA Go Pre-load Read buffer with history entry - bcc L1A0E No error, continue - lbra L1AAA Normal parse with error - -* Find history entry # we want -* Entry: B=history entry # (1-xx) -* Exit: Y=Ptr to history buffer entry we wanted -L19D3 ldy >u180A,u Get ptr to start of history buffers -L19D8 decb Bump down counter to find entry we want - beq L19E9 Found it, skip ahead -L19DB tst ,y+ Wrong one, search for end of one we are checking - beq L19E4 Found it, skip ahead - lbsr L1A97 Wrap buffer ptr if we hit end of all history - bra L19DB Keep searching for end of current entry - -L19E4 lbsr L1A97 Wrap buffer ptr if we hit end of all history - bra L19D8 Go into next entry in history buffers - -L19E9 rts Found it, leave - -L19EA leax >u0124,u Point to temp buffer - ldy >u1813,u Get ptr to current history buffer - clrb Set counter to 0 (size of buffer) -L19F4 lda ,y+ Get char from history buffer - beq L1A00 Found end, continue - sta ,x+ Put it in temp buffer - incb Bump up size counter - lbsr L1A97 Wrap buffer ptr if we hit end of all history - bra L19F4 Continue copying into temp buffer -L1A00 clra D=Size of history buffer - decb - tfr d,y Move to proper register - leax >u0124,u Point to buffer history copy - ldb #SS.Fill Fill it with current selected history command - os9 I$SetStt - rts - -* Successfull SS.Fill of history buffer goes here -L1A0E lda #$01 Write copy of history buffer to std out - os9 I$Write - leax >u0124,u Point to current history buffer again - tfr y,d Transfer # bytes written to D - lda #C$BSP Backspace char -L1A1B sta ,x+ Fill buffer with backspaces - decb - bne L1A1B - leax >u0124,u Write them to reset cursor to start of line - lda #$01 - os9 I$Write - ldd #SS.Relea Eat keyboard signal (SS.Fill cleared it out of - os9 I$SetStt the read buffer already) - ldb #SS.SSig Setup for re-enabling it - ldx #$000B Signal Code to send on keypress=$B - lbra L016A Go re-enable signal send on keyboard/mouse input - -* Put new entry into history buffers, adjusting # used, etc.) -* Entry: Y=# bytes read in ReadLn <>1 -L1A37 pshs y Preserve # bytes read - tfr y,d Move to D reg - ldy >u1808,u Get ptr to where next history entry will go - leax >u0124,u Point to line entered by user -L1A44 lda ,x+ Get char - cmpa #C$CR Control char <$0d? - bhs L1A4C No, save the character - lda #C$SPAC Replace with space char if it is -L1A4C sta ,y+ Save char into history buffer - bsr L1A97 Wrap to beginning if we hit end - cmpy >u180A,u Point to entry #1? - bne L1A59 No, continue - bsr L1A7B Yes, make new #1 entry & drop # of entries -L1A59 decb Drop # bytes left in new entry - bne L1A44 Not done, continue - clr ,y+ mark end with NUL - bsr L1A97 Wrap to beginning if at end - cmpy >u180A,u Pointing to entry #1? - bne L1A69 No, skip ahead - bsr L1A7B Yes, make new #1 entry & drop # of entries -L1A69 inc >u180C,u Increase # of entries - sty >u1808,u Save ptr to where next history entry will go - puls y Restore # bytes read - clra Point to temp buffer again - leax >u0124,u - bra L1AA3 Normal parse, no error - -* Reset ptr to new 1st entry in history buffer -L1A7B pshs y Preserve current location in history buffer - ldy >u180A,u Point to start of 1st entry -L1A82 tst ,y+ End of current entry? - beq L1A8A Yes, skip ahead - bsr L1A97 No, wrap if we need to - bra L1A82 Keep going until we find end -L1A8A bsr L1A97 Wrap if we need to - dec >u180C,u Dec # lines in history buffer - sty >u180A,u Save new 'start of history' ptr - puls pc,y Restore current location & return -* If we are at end of history buffers, wrap to beginning (raw, has nothing to -* do with entry #'s) -L1A97 cmpy >u1806,u Are we at end of buffer for history entries? - bne L1AA2 No, continue on - leay >u1815,u Yes, reset to beginning of history buffers -L1AA2 rts - -L1AA3 bsr L1AB1 Reset std paths to normal <CTRL>-<E>/<C> settings - andcc #^Carry No error - lbra L018B Normal command processing - -L1AAA bsr L1AB1 Reset std paths to normal <CTRL>-<E>/<C> settings - orcc #Carry Error - lbra L018B Normal command processing - -* Reset all 3 standard paths' NUL counts/Keyboard Interrupt/Terminate settings -L1AB1 pshs x,d Preserve regs - tst >u1812,u Check flag - beq L1AD6 If 0 skip ahead - leas <-PD.OPT,s Make 32 byte buffer on stack - leax ,s Point X to buffer - clrb CHANGE TO CLRB - clra Standard input path - bsr L1AD8 Restore NUL counts, Keyboard Intrpt/Terminate - lda #$01 Do same for Standard output path - bsr L1AD8 - lda #$02 Do same for Standard Error path - bsr L1AD8 - leas <$20,s Eat stack buffer - clr >u1812,u Reset PD.OPT flags to 0 - clr >u180D,u -L1AD6 puls pc,x,d Restore regs & return - -* Restore path options to preserved Keyboard terminate/interrupt & end of -* line NUL counts -L1AD8 pshs a Preserve path # - os9 I$GetStt Get current PD.OPT settings - lda >u180E,u Get copy of Keyboard terminate char - sta <PD.QUT-PD.OPT,x Save into buffered copy - lda >u180F,u Get copy of Keyboard interrupt char - sta <PD.INT-PD.OPT,x Save into buffered copy - lda >u1811,u Get copy of end of line NUL count - sta $6,x Save into buffered copy - puls a Get path # back - os9 I$SetStt Reset path options with restored values & return - rts - - emod -eom equ * - end - +******************************************************************** +* Shellplus - Enhanced shell for OS-9 Level Two +* +* Modified by L. Curtis Boyle from original 2.2 disassembly +* +* $Id$ +* +* Ed. Comments Who YY/MM/DD +* ------------------------------------------------------------------ +* 21 Original Tandy/Microware version +* 22a History and numerous features added + + nam Shell + ttl program module + +* Disassembled 93/04/15 14:58:18 by Disasm v1.6 (C) 1988 by RML +* Signals: Signals 2 & 3 are assigned new keys to handle forward/backward +* command history. Signal $B (11) is the signal sent out on a key being ready +* for normal command processing + + ifp1 + use defsfile + endc + +tylg set Prgrm+Objct +atrv set ReEnt+rev +rev set $02 + mod eom,name,tylg,atrv,start,size + +u0000 rmb 1 Path # for standard input +u0001 rmb 1 Path # for standard output +u0002 rmb 1 Path # for standard error +u0003 rmb 1 # of 256 byte pages of data mem for frked module +u0004 rmb 2 Temp ptr (current parse ptr, mem module ptr,etc) +u0006 rmb 2 Size of current group +u0008 rmb 2 Pointer to start of current group (past '(') +u000A rmb 2 +u000C rmb 1 Current char. being processed in command parser +u000D rmb 1 # of command groups [ '()' groupings ] +u000E rmb 1 unprocessed signal # (0=none waiting) +u000F rmb 1 ??? Flag of some sort +u0010 rmb 2 ??? (ptr to some module name) +u0012 rmb 1 Current working DIR path # +u0013 rmb 1 Flag to kill parent process (1=Kill parent) +u0014 rmb 1 Flag: If set, a result must not be 0 ??? +u0015 rmb 1 +u0016 rmb 1 +u0017 rmb 1 +u0018 rmb 1 Immortal shell (0=NO) +* A clearing routine only does u0000 to u0018 +u0019 rmb 1 +u001A rmb 2 +u001C rmb 1 Shell logging on flag (0=OFF) +u001D rmb 1 Shell prompting (0=ON) +u001E rmb 1 Echo input (0=OFF) +u001F rmb 1 Variable expansion (0=ON) +u0020 rmb 1 Kill shell on error (0=OFF) +u0021 rmb 1 Process # to set priority on +u0022 rmb 1 Priority to set (0=don't change) (ours or fork) +u0023 rmb 2 +u0025 rmb 2 End of data mem ptr (top of stack) +u0027 rmb 1 +u0028 rmb 1 +u0029 rmb 1 +u002A rmb 2 +u002C rmb 2 +u002E rmb 1 +u002F rmb 1 +u0030 rmb 1 +u0031 rmb 1 +u0032 rmb 2 +u0034 rmb 3 +u0037 rmb 1 Flag: 0=Data dir .PWD invalid, 1=valid +u0038 rmb 1 Flag: 0=Exec dir .PXD invalid, 1=valid +u0039 rmb 1 +u003A rmb 1 +u003B rmb 2 +u003D rmb 1 +u003E rmb 2 +u0040 rmb 2 Ptr to start of filename (vs. pathname) ('/') +* Shell prompt flag +u0042 rmb 1 Current working dir path already done flag +u0043 rmb 1 +u0044 rmb 1 +u0045 rmb 1 ??? <>0 means looking for GOTO label? +u0046 rmb 1 Flag: 1=GOTO label found? +u0047 rmb 1 Error code from ReadLn or signal +u0048 rmb 2 Ptr to 1st char after redirection symbols +u004A rmb 2 Ptr to text message +u004C rmb 2 Size of text message +u004E rmb 1 +u004F rmb 1 0=no pathname in parm line, else IS pathname +u0050 rmb 2 +u0052 rmb 2 Current expanded buffer size (max=2048) +u0054 rmb 2 Ptr to current char in wildcard filename we are +* checking +u0056 rmb 2 Ptr to current pos in expanded buffer +u0058 rmb 2 Pointer to end of GOTO label name +u005A rmb 2 User ID # from F$ID call +u005C rmb 1 +u005D rmb 1 +u005E rmb 1 Device type: 0=SCF (keyboard),1=RBF (Scriptfile) +u005F rmb 1 +u0060 rmb 1 Data module linked flag: 1= Yes +u0061 rmb 2 Ptr to data module name +u0063 rmb 2 Ptr to intercept routines data mem +u0065 rmb 2 Execution address of linked module +u0067 rmb 2 Start address of module +u0069 rmb 2 +u006B rmb 1 Flag: 0=No module to unlink, <>0 module to unlink +u006C rmb 1 +u006D rmb 1 Start of device name buffer (start with '/') +u006E rmb 71 Actual device name +u00B5 rmb 20 Start of another device name buffer ('/') +u00C9 rmb 13 +u00D6 rmb 13 Standard module header info (M$ID-M$Mem) +u00E3 rmb 5 Module name string (reserves 64 chars) +u00E8 rmb 3 +u00EB rmb 4 +u00EF rmb 10 Temp buffer (many uses) +u00F9 rmb 6 +u00FF rmb 37 Place to point SP when CHAINing +u0124 rmb 81 Temporary buffer (used for several things) +u0175 rmb 119 Part of temp buffer for ReadLn (200 chars total) +u01EC rmb 2 Least sig. 2 digits of process # (ASCII format) +u01EE rmb 1 +u01EF rmb 2 Holding area for 2 digit ASCII conversions +* Shell prompt parsing flags +u01F1 rmb 1 Process ID # already done flag +u01F2 rmb 1 Standard output device name already done flag +u01F3 rmb 1 Quoting on flag in shell prompt string parsing +u01F4 rmb 1 Date already done flag +u01F5 rmb 1 Time already done flag +u01F6 rmb 1 Date OR time already done flag +u01F7 rmb 2 Size of expanded shell prompt +u01F9 rmb 25 Current shell prompt string +u0212 rmb 1 Lead in Line feed for expanded shell prompt +u0213 rmb 199 Expanded shell prompt +u02DA rmb 6 Date/time packet +u02E0 rmb 8 Date string +u02E8 rmb 1 Space separating date & time (for shell init) +u02E9 rmb 9 Time string (and CR) +u02F2 rmb 131 +u0375 rmb 131 +u03F8 rmb 29 +u0415 rmb 2 +u0417 rmb 1 +u0418 rmb 400 Intercept routines memory area (not used) +u05A8 rmb 810 Shell variables (user?) +u08D2 rmb 810 Shell variables (shell sub?) +u0BFC rmb 80 +u0C4C rmb 81 Copy of GOTO label name +u0C9D rmb 32 DIR Entry buffer +u0CBD rmb 32 Shell logging filename (append mode '+') +u0CDD rmb 400 PATH=Buffer (each entry CR terminated) +u0E6D rmb 2048 Fully expanded filenames buffer (for wildcards) +* Actually,this next block appears to be generic buffers for various functions +u166D rmb 80 Process descriptor copies go here (512 bytes) +u16BD rmb 1 +u16BE rmb 80 +u170E rmb 238 +u17FC rmb 10 +u1806 rmb 2 ??? Ptr to end of shell history buffers +u1808 rmb 2 Ptr to where next history entry will go +u180A rmb 2 Ptr to start of shell history buffers +u180C rmb 1 # of lines in history buffer (1-(u180C)) +u180D rmb 1 Current line # in history buffer +u180E rmb 1 Original keyboard terminate char +u180F rmb 1 Original keyboard interrupt char +u1810 rmb 1 +u1811 rmb 1 Original end of line NUL count +u1812 rmb 1 Flag to indicate if we have to restore PD.OPT +u1813 rmb 2 +u1815 rmb 808 Shell history copies start here +u1B3D rmb 963 Local stack space, etc. +size equ . +name equ * +L000D fcs /Shell/ + fcb $16 +L0013 fcb Prgrm+PCode + fcs 'PascalS' + fcb Sbrtn+CblCode + fcs 'RunC' + fcb Sbrtn+ICode +L0021 fcs 'RunB' + fcb $00,$00,$00,$00,$00,$00,$00,$00,$00 +L002E fcb C$LF + fcc 'Shell+ v2.2a ' +L003C fcb $00 +L003D fcc '{@|#}$: ' +L0055 fcc '+++START+++' + fcb C$CR +L0061 fcc '+++END+++' + fcb C$CR +* Intercept routine +L006B stb <u000E Save signal code & return + rti + +start leas -5,s Make 5 byte buffer on stack + pshs y,x,d Save Top/bottom of param area, and size of area + leax >u1815,u Pointer to start of history buffer area + stx >u1808,u Save ptr to where next history entry goes + stx >u180A,u Save ptr to start of history buffers + leax >$0328,x Setup up another pointer (end of history area?) + stx >u1806,u Save it + clr >u1812,u Clear flag that we have to restore PD.OPT + clr >u180D,u Current line # of history buffer=0 + clr >u180C,u # lines in history buffer=0 + ldx 2,s Get back top of data area ptr + ldb #$FF 255 bytes to clear + lbsr L0412 Go clear direct page + sts <u0025 Save current stack ptr + stu <u0027 Save Data mem ptr (0) + leax >u0418,u Point to intercept routines memory area + stx <u0063 Save a copy of it + leax <L006B,pc Point to intercept routine + os9 F$Icpt Setup the intercept routine + lbsr L16A6 Get user #, and make 2 digit ASCII ver. @ 1EC + lbsr L1674 Make shell logging pathname @ CBD + leax <L003D,pc Point to default shell prompt string + lbsr L0A14 Go create shell prompt string & prompt itself + leax >u05A8,u Point to start of shell variables + ldd #C$CR*256+20 Carriage return (blank entries) & all 20 of them +L009C sta ,x Mark shell variable as blank + leax <81,x Point to next entry (81 bytes/entry) + decb Do until all 20 are done (user & shell sub) + bne L009C + sta >u0CDD,u Init 1st 2 entries of PATH= buffer to CR's + sta >u0CDD+1,u + puls x,d Get parameter ptr & parameter size + std <u0006 Save size of parameter area + beq L00BF If no parameters, skip ahead + lbsr L041B Pre-Parse parameters passed to this shell + lbcs L01FA Error, go handle it + tst <u000C Any char being processed in parser? + lbne L01F9 Yes, skip ahead +L00BF lbsr L0225 Release any keyboard/mouse signals & get PD.OPT + inc <u006C ??? Set flag + lds ,s++ Since parameters parsed, point SP to top of mem + sts <u0025 Save end of data mem ptr (top of stack) + stu <u0027 Save start of data mem ptr +L00CC leax >L002E,pc Point to Shellplus v2.2 message + tst <u001D Shell prompting turned on? + bne L00EA No, skip ahead + ldy #$000E Length of message + lda #$01 Standard out + os9 I$Write Write it + lbcs L0200 If error writing, terminate Shellplus + bsr L00FB Go create date & time strings + lbsr L021B Write out date & time + lbcs L0200 If error writing, terminate Shellplus +L00EA clra + sta <u005C + leax >L0055,pc Point to '+++START+++' for shell logging + lbsr L07E7 Go deal with logging if necessary + tst <u001D Shell prompting turn on? + bne L0120 No, skip ahead + bra L010D Yes, do something else first + +L00FB clr >u01F6,u Clear date or time done flag + lbsr L0B3B Create current date & time strings + lda #C$SPAC Put in a space to separate date & time + sta >u02E8,u + leax >u02E0,u Point to start of date buffer + rts + +* Shell just booted goes here +L010D lbsr L09F7 Update expanded shell prompt if needed + leax >u0212,u Point to expanded shell prompt + ldy >u01F7,u Get size of expanded shell prompt +L0119 tst <u001D Shell prompting on? + bne L0120 No, continue on + lbsr L021F Print shell prompt to standard error +* Shell already booted goes here +L0120 clra + leax >u0124,u Point to an input line of some sort + tst <u006B Any module linked? + beq L015B No, continue on + ldy <u0065 Yes, get Execution address of linked module + cmpy <u0069 ??? + lbhs L01F0 + ldb #200 LDW #200/PSHS X/TFM Y+,X+ + pshs x Copy temporary buffer to [<u0065] +L0137 lda ,y+ + sta ,x+ + decb + beq L014E Whole buffer copied, skip ahead + cmpy <u0069 But don't go past here + bhs L0147 + cmpa #C$CR Also, stop on carriage return + bne L0137 +L0147 sty <u0065 Save new start address + puls x Restore ptr to u0124 + bra L01B9 Skip ahead + +L014E lda ,y+ + cmpy <u0069 + bhs L0147 + cmpa #C$CR + bne L014E + bra L0147 + +L015B tst <u005E We reading from script file? + bne L017F Yes, skip ahead + ldd #SS.Relea Std input path/release keyboard+mouse signals + os9 I$SetStt Release any keyboard signals + lbsr L18DB Go modify signals 2&3 to use up/down arrows, +* set up to re-enable Kybd signals +L016A clr <u000E Clear out last signal received + os9 I$SetStt Re-set up SS.SSig +* NOTE: This BRA L0177 is required for type-ahead to work + bra L0177 Go check for history-related signals + +* DOESN'T SEEM TO GET BACK TO HERE WHEN ABORT BUG APPEARS +L0171 ldx #$0000 Sleep until signal is received + os9 F$Sleep +L0177 lbra L191C Go check for history signals (PD.QUT & PD.INT) +* Signal received is not PD.QUT or PD.INT goes here +L017B cmpb #$0B Key pressed signal? + bne L0171 No, ignore signal & go to sleep again +* Keyboard input received signal goes here +L017F leax >u0124,u Point to temp buffer to hold line + clra Std Input + ldy #200 Maximum 200 char. input + lbra L193E Go read the rest of line as ReadLn + +* Comes here after line or signal received & processed +* NOTE: IF LINE RECEIVED, PD.QUT & PD.INT ARE BACK TO NORMAL VALUES +L018B bcc L01B9 If no errors, skip ahead + cmpb #E$EOF <ESC> key in ReadLn? + beq L01F0 Yes, skip ahead + +L0191 lds <u0025 Get top of stack ptr + ldu <u0027 Get back ptr to DP + stb <u0047 Save error code + tst <u0046 GOTO label active? + bne L01A4 Yes, go print error message + tst <u0018 Is this shell immortal? + bne L01A4 Yes, go print error message + tst <u0020 Kill shell on error? + bne L01FA Yes, go do that + +L01A4 os9 F$PErr Print the error message + tst <u0046 GOTO label active? + lbeq L010D No, go print shell prompt/process next line + clr <u0046 Clear GOTO label flag + leax >u0C4C,u Point to copy of GOTO label name + lbsr L0FD0 Go process GOTO line + lbra L010D Go print shell prompt/process next line + +* No error received on line +L01B9 cmpy #$0001 Just 1 char read (just a CR)? + bhi L01CE No, go parse parameters + lbsr L09F7 Go update date/time & expanded shell prompt + leax >u0213,u Point to expanded shell prompt + ldy >u01F7,u Get size of expanded shell prompt + lbra L0119 Go print shell prompt & get next line from user + +* No errors-got input line, and there is something in it +L01CE lbsr L041B Go parse parameters? + pshs cc Save flags + tst <u0045 + bne L01D9 + clr <u0047 Clear error/signal code from ReadLn +L01D9 puls cc Restore flags + lbcc L010D If no error from parse, do prompts & read again + tstb If a 0 error, do prompts & read again + lbeq L010D + tst <u0045 ??? Do we care about errors? + bne L0191 No, go handle error + stb <u0047 Save error/signal code + bra L0191 Go handle error + +L01EC fcc 'eof' + fcb $0d + +* <ESC> received +L01F0 tst <u001D Shell prompting on? +L01F2 bne L01F9 No, skip printing 'eof' to screen + leax <L01EC,pc Point to 'eof' string + bsr L021B Write it out to std error +L01F9 clrb No error flag +* Possible shell error - Process +L01FA lda <u0018 Is this shell immortal? + lbne L0BDA Yes, go close or dupe paths +* Shell not immortal, exit routine in here +L0200 pshs u,b,cc Preserve regs + tst <u006B Shellsub module to unlink? + beq L020B No, skip ahead + ldu <u0067 Yes, get ptr to module + os9 F$UnLink Unlink it +L020B puls u,b,cc Restore U, error # & flags +* EX with no module name (or non-existant one) go here +L020D pshs b,cc Save error # & flags + leax >L0061,pc Point to '+++END+++' string + lbsr L07E7 Close log file if one is open, restore ID # + puls b,cc Restore error # & flags + os9 F$Exit Terminate shellplus + +L021B ldy #80 Write up to 80 chars or CR +L021F lda #$02 Std error path + os9 I$WritLn Write message out & return + rts + +L0225 pshs y,x,d Preserve regs + ldd #SS.Relea Std In & Release keyboard & mouse signals + os9 I$SetStt + bcc L0233 No error, continue + lda #$01 Couldn't release keyboard/mouse signals flag + bra L0241 + +L0233 leax >u0124,u Point to buffer for current path options + clra + clrb CHANGE TO CLRB + os9 I$GetStt Get std input path options + lda >u0124,u Get Device type (0 (SCF) usually) + +L0241 sta <u005E Save device type (1=SS.Relea failed) + puls pc,y,x,d Restore regs & return + +* R= command (redirect specific paths) +L0245 lda ,x Get char from input line + cmpa #'< Is it input path? + beq L0251 Yes, skip ahead + cmpa #'> Is it an output/error path? + lbne L0BCF No, print 'WHAT?' +L0251 pshs x Preserve ptr to 1st redirection symbol + leay >L03CF,pc Point to modifier symbol table + lbsr L092A Go to command line parser + lbcs L0BCF Error, print 'WHAT?' + ldd ,y Get table offset + jsr d,y Call appropriate subroutine + stx <u0048 Save ptr to source after redirection symbols + puls x Restore ptr to redirection symbols + lbcs L0B96 If error in subroutine, close paths & return + +L026A lda ,x+ Get 1st char again + cmpa #'< Input path? + beq L026A Yes, skip to next + cmpa #'> Output or Error path? + beq L026A Yes, skip to next + cmpa #'- Overwrite old file? + beq L026A Yes, skip to next + cmpa #'+ Append to old file? + beq L026A Yes, skip to next + leax -1,x Point to non-redirect char + bsr L02A3 Make name buffer, release signals,parse modifiers + clrb Start path # 0 +L0281 pshs b Save on stack + lda b,u Get special path # + beq L028A None, skip ahead + os9 I$Close Close the path +L028A puls b Get path # back + clr b,u Clear out entry + incb Next path # + cmpb #$03 Done the 3 standard paths yet? + blo L0281 No, keep doing until all done + ldx <u0048 Get ptr to redirected dev/file name & return + rts +* Z= command (immortal shell setting, but kill parent process) +L0296 inc <u0013 Flag we want to kill parent +* I= command (immortal shell setting) +L0298 lbsr L0CD2 + lbcs L0B96 + bsr L02A3 + bra L02D4 + +* Create device name buffer @ u006D, Write NUL to std out, parse special +* chars: # @ @+hibit $ ( ), Release any keyboard/mouse signals +L02A3 pshs x Prsrve ptr to file/dev name we're redirecting to + ldb #SS.DevNm Get device name call code + leax <u006D,u Point to buffer for path names + lda #'/ Preload '/' for device names + sta ,x+ + clra Standard input path + os9 I$GetStt Get the current device name + puls x Get back ptr to file/dev name for redirection + lbcs L0B96 Error on GetStt, shut down paths & exit + ldy #$0001 One char to write + pshs x Prsrve ptr to file/dev name we're redirecting to + leax >L003C,pc Point to a NUL + lda #1 Std out + os9 I$Write Write the NUL out + puls x Restore Devname ptr + lbcs L0B96 Error on Write, shut down paths & exit + lbsr L0A04 Do normal parsing - includes #,@,$e0,$,(,) + lbsr L0225 Release signals + rts + +L02D4 inc <u0018 Set 'immortal shell' flag + inc <u0019 ??? (flag used by L0B96 routine) + lbsr L0B96 + clr <u0019 + tst <u0013 Do we want to kill the parent process? + beq L02FC + os9 F$ID Get our process ID # into A + pshs x Preserve X + leax >u166D,u Point to process descriptor buffer + os9 F$GPrDsc Get our process descriptor + lda P$PID,x Get our parents process # + puls x Restore X + beq L02A3 If parent's process # is 0 (system), skip back + clrb S$Kill signal code + os9 F$Send Send it to parent + lbcs L0191 If error sending signal, go to error routine +L02FC clrb No error + stb <u0013 Clear 'kill parent' flag + rts + +* Command list +L0300 fdb L0B87-L0300 $0887 + fcs '*' +L0303 fdb L12D1-L0303 $0fce + fcs 'W' +L0306 fdb L09BD-L0306 $06b7 + fcs 'CHD' +L030B fdb L09B5-L030B $06aa + fcs 'CHX' +L0310 fdb L09BD-L0310 $06ad + fcs 'CD' +L0314 fdb L09B5-L0314 $06a1 + fcs 'CX' +L0318 fdb L0987-L0318 $066f + fcs 'EX' +L031C fdb L16DD-L031C $13c1 + fcs 'KILL' +L0322 fdb L09EF-L0322 $06cd + fcs 'X' +L0325 fdb L09F3-L0325 $06ce + fcs '-X' +L0329 fdb L0A14-L0329 $06eb + fcs 'P=' +L032D fdb L09D7-L032D $06aa + fcs 'P' +L0330 fdb L09DA-L0330 $06aa + fcs '-P' +L0334 fdb L09DF-L0334 $06ab + fcs 'T' +L0337 fdb L09E3-L0337 $06ac + fcs '-T' +L033B fdb L170D-L033B $13d2 + fcs 'SETPR' +L0342 fdb L0298-L0342 $ff56 + fcs 'I=' +L0346 fdb L0245-L0346 $feff + fcs 'R=' +L034A fdb L0296-L034A $ff4c + fcs 'Z=' +L034E fdb L0927-L034E $05d9 + fcs ';' +L0351 fdb L176B-L0351 $141a + fcs '.PWD' +L0357 fdb L177D-L0357 $1426 + fcs '.PXD' +L035D fdb L1029-L035D $0ccc + fcs 'M=' +L0361 fdb L105A-L0361 $0cf9 + fcs 'VAR.' +L0367 fdb L09E7-L0367 $0680 + fcs 'V' +L036A fdb L09EA-L036A $0680 + fcs '-V' +L036E fdb L1209-L036E $0e9b + fcs 'PATH=' +L0375 fdb L11CF-L0375 $0e5a + fcs 'PAUSE' +L037C fdb L1126-L037C $0daa + fcs 'INC.' +L0382 fdb L1131-L0382 $0daf + fcs 'DEC.' +L0388 fdb L0D62-L0388 $09da + fcs 'IF' +L038C fdb L0E0B-L038C $0a7f + fcs 'THEN' +L0392 fdb L0F8C-L0392 $0bfa + fcs 'ELSE' +L0398 fdb L0E0B-L0398 $0a73 + fcs 'FI' +L039C fdb L0E0B-L039C $0a6f + fcs 'ENDIF' +L03A3 fdb L0F3F-L03A3 $0b9c + fcs 'CLRIF' +L03AA fdb L0FD0-L03AA $0c26 +L03AC fcs 'GOTO' +L03B0 fdb L0F93-L03B0 $0be3 + fcs 'ONERR' +L03B7 fdb L09CF-L03B7 $0618 + fcs 'L' +L03BA fdb L09D3-L03BA $0619 + fcs '-L' +L03BE fdb L0969-L03BE $05ab + fcs 'S.T.A.R.T.U.P' + fdb $0000 +L03CF fdb L1634-L03CF $1265 + fcs '!' +L03D2 fdb L1634-L03D2 $1262 + fcs '|' +L03D5 fdb L12A0-L03D5 $0ecb + fcs ';' +L03D8 fdb L12C3-L03D8 $0eeb + fcs '&' +L03DB fdb L1299-L03DB $0ebe + fcb $8d CR +L03DE fdb L0CCE-L03DE $08f0 + fcs '<>>>' +L03E4 fdb L0CE5-L03E4 $0901 + fcs '<>>' +L03E9 fdb L0CD7-L03E9 $08ee + fcs '<>' +L03ED fdb L0CF3-L03ED $0906 + fcs '>>>' +L03F2 fdb L0C01-L03F2 $080f + fcs '>>' +L03F6 fdb L0BFA-L03F6 $0804 + fcs '<' +L03F9 fdb L0C08-L03F9 $080f + fcs '>' +L03FC fdb L1277-L03FC $0e7b + fcs '#' +L03FF fdb L1265-L03FF $0e66 + fcs '^' + fdb $0000 End of table marker + +L0404 fcb $0d + fcc '()' + fcb $ff +L0408 fcb $0d + fcc '!#&;<>^|' + fcb $ff + +* Subroutine: Clears B bytes of memory to NUL's starting @ U +L0412 pshs u Clear memory +L0414 clr ,u+ + decb +L0417 bne L0414 +L0419 puls pc,u + +* Pre-Parse parameters passed to this shell. Will copy from parm area to +* buffer area at u0166D, checking for raw mode access allowability if needed +* Will also +* Entry: X=ptr to parm area +L041B ldb #$18 # of bytes to clear in DP +L041D bsr L0412 Go clear from <u0000 to <u0018 (immortal off) + tst <u006C ??? (If shell is initing, it's 0) + lbeq L04CE Shell just initializing, skip ahead + leay >u17FC,u Point to end of buffer marker + pshs y Save ptr on stack + leay >u166D,u Point to buffer for process descriptor +L042F bsr L0486 Copy next char (check for '@', possibly eat) + cmpa #C$CR CR? + beq L04A8 Yes, force CR into ,y & process line from start + cmpy ,s At end of buffer? + beq L04A8 Yes, force CR, process line from start + tst <u001F Variable expansion on? + bne L042F No, check next char + cmpa #'% Is it a '%' (shell variable)? + bne L042F No, do next character + leay -1,y Back up destination ptr to where '%' is + pshs x Save current position in parms + lda ,x Get 1st char of shell variable nam + cmpa #'* Shell variable for last error code received? + beq L049D Yes,replace shell var with contents of shell var + leax >u05A8,u Point to user shell variable contents table + cmpa #'% 2nd '%'= shellsub variable + bne L0460 No, just user, go process + puls x Get back parm ptr + leax 1,x Skip over 2nd '%' + lda ,x Get shellsub variable # + pshs x Save parm ptr + leax >u08D2,u Point to shellsub variable contents table +* Entry: A=ASCII 0-9 for either shell or shellsub variable # +L0460 cmpa #'9 ASCII numeric? + bhi L0470 No, skip ahead + cmpa #'0 + blo L0470 + suba #$30 Yes, bump down to binary equivalent + ldb #81 Point to proper variable entry within var table + mul + leax d,x + incb ??? Used in TSTB below +L0470 bsr L0486 Copy char from var table to pre-parse buffer + cmpy 2,s Hit end of pre-parse buffer? + beq L04A6 Yes, force CR at end of it, do full parse + cmpa #C$CR End of variable? + bne L0470 No, keep copying characters + leay -1,y Knock ptr back one (to where CR is) + puls x Get current parm ptr back + tstb ??? flag to skip a byte in parm or not + beq L042F Don't skip +L0482 leax 1,x Skip to next byte in parm line + bra L042F Continue pre-parse + +* Copy char from parm area to command line buffer - if '@', eat if user is +* not super-user (#0) +* Entry: X=ptr to current pos. in original parm buffer +* Y=ptr to current pos. in new, pre-parsed buffer +L0486 lda ,x+ Get char from parms + cmpa #'@ Raw mode request? + bne L049A Skip ahead if not (SHOULD BE BNE) +L048C pshs y,a Preserve regs + os9 F$ID Get user ID # + cmpy #$0000 Is it 0 (superuser)? (should be leay ,y) + puls y,a Restore regs + beq L049A Yes, allow char thru + rts Otherwise eat it + +L049A sta ,y+ Save char & return + rts + +* Shell variable '%* (for last error code) requested +* Put contents of shell var. into pre-parsed command line buffer +L049D puls x Get back parm ptr + lbsr L168A Put error code into preparse buffer + leay 3,y Skip over error code space we just added + bra L0482 Skip over shell varname, continue preparse + +L04A6 leas 2,s Eat stack +L04A8 lda #C$CR Force CR as last char in buffer + sta ,y + puls y + leax >u166D,u Point to start of pre-parse buffer again +L04B2 bra L04CE Start real parse + +L04B4 fcb C$LF + fcc 'Expanded line too long' + fcb C$CR +L04CC fcc '.' +L04CD fcb C$CR + +* Parse command line buffer - already pre-parsed (user 0 RAW mode checks & +* shell/shellsub variable expansion is already done) +* Entry: X=Ptr to pre-parsed command line buffer +L04CE lda ,x Get 1st char from parameter area + cmpa #'* Is it a comment? + beq L04DE Yes, skip ahead + cmpa #': Is it a wildcard on/off? + bne L04DA No, skip ahead + leax 1,x Bump ptr past it +L04DA cmpa #': Is it a wildcard off? +* FOLLOWING LINE: BEQ means wildcarding default off, BNE = on + beq L04F0 No, go process wildcarding +* No wildcard processing +L04DE leay >u0E6D,u Point Y to expanded buffer + lbsr L1320 Copy param area to buffer area until 1st CR + leax >u0E6D,u Point X to expanded (wildcard) buffer + ldy #$0800 Max. size of expanded buffer (2048 bytes) + lbra L079B Process line without wildcards + +* Wild carding processor +* Entry: X=ptr to current position in pre-parsed parm line +* 1st, set up error msg for if buffer gets full +L04F0 leay >L04B4,pc Point to 'Expanded line too long' + sty <u004A Save it + ldy #$0018 Get size of text + sty <u004C Save it too + leay >L04CD,pc Point to CR + sty <u0048 Save ptr + sts <u0050 Save stack ptr + leay >u0E6D,u Point to fully expanded buffer (2k max) + sty <u0056 Save it + clra + clrb + sta <u0012 No current working DIR path + sta <u004F Flag no pathname in parm area + std <u0052 Expanded buffer size=0 bytes + bra L0520 Enter main loop for wildcards + +L051D lbsr L06FB Special shell chars handling +L0520 lbsr L0746 Check for special chars (wildcard or shell) + bcc L051D Special shell char process +* Wildcard char found + pshs x Save current pre-parsed parm ptr + bsr L0549 Check from that point for '/' or special char + ldx ,s Get previous parm ptr back + bcc L0557 No '/' found, open current dir '.' +* Found '/' (part of path) - keep looking for last '/' for filename (not +* pathname) portion +L052D bsr L0549 Check for special char or '/' again + bcc L0535 No '/', skip ahead + stx <u0040 Save latest ptr to '/' in parm line found so far + bra L052D See if any more sub-paths + +* Found one or more '/' path dividers in current parm line. +* Entry: <u0040 - contains the last '/' found +L0535 inc <u004F Flag that their IS a pathname from parm line +L0538 ldx <u0040 Get last level of path ptr + puls y Get original parm ptr + sty <u0040 Save it + pshs x Save filename ptr on stack + lda #C$SPAC Save space over '/' after pathname + sta -1,x (before filename) + tfr y,x Move original parm ptr to X + bra L055E Open dir path + +* Parse from current position in pre-parsed parm line until shell special +* char, or '/' found (path) +* Entry: X=ptr to current pos in pre-parsed parm line +* Exit: Carry clear if special shell char found +* Carry set if '/' found +* X=ptr to found char+1 +L0549 clrb + lda ,x+ Get next char + lbsr L05D3 See if shell special char + beq L0556 Yes, return + cmpa #'/ No, is it a slash (path start)? + bne L0549 No, Keep checking for / or special char + comb +L0556 rts + +* No '/' found in parm line at all +L0557 clr <u004F Flag no pathname from parm line + leax >L04CC,pc Point to '.' +* Entry: X=ptr to pathname to directory +* 0-1,s = Ptr to filename spec we are looking for in this directory +L055E lda #DIR.+READ. Open directory in READ mode + os9 I$Open + lbcs L0776 Error, skip ahead + sta <u0012 Save current DIR path + puls x Get back ptr to filename (not pathname) + lbsr L0746 Check for special shell char or wildcard + lbcc L06E3 Special shell char found, ?????? +L0572 lda ,x+ Get next char from filename + cmpa #C$CR End of user specified filename (CR)? + lbeq L0789 Yes, close DIR and proceed + cmpa #', Comma? + beq L0572 Yes, skip it + cmpa #C$SPAC Space? + beq L0572 Yes, skip it + leax -1,x Other char, point to it. + stx <u0054 Save ptr to it + lda <u0012 Get DIR path # + pshs u Preserve u + ldx #$0000 Skip '.' and '..' dir entries + ldu #$0040 + os9 I$Seek + lbcs L0776 Error, skip ahead + puls u Restore u +L0599 leax >u0C9D,u Point to dir entry buffer + pshs x Save ptr + lda <u0012 Get Current dir path # + ldy #$0020 Read 1 file entry + os9 I$Read + lbcs L06BD Error, skip ahead + puls y Restore pointer to dir filename buffer + lda ,y Get 1st char of entry + tsta Is it a deleted file? + beq L0599 Yes, skip it + ldx <u0054 Get ptr to current char in expanded filename bfr + bsr L05EF Check wildcard spec against this filename + bcs L0599 No match, skip to next file in DIR + tst <u004F Was a pathname specified? + beq L05CA No, skip ahead + ldx <u0040 Yes,get ptr to end of pathname/start of filename + lbsr L06FB Check for wildcard stuff there + ldx <u0056 Get current pos in expanded buffer + lda #'/ Save '/' there (to separate path & filename) + sta -1,x +L05CA leax >u0C9D,u Point to start of matched DIR entry filename + lbsr L06FB Copy filename over, handling quoted chars, etc. + bra L0599 On to next DIR entry + +* Check if shell 'special' char. (except wildcards & shell var) +* non-wildcard char in current byte of pre-parsed parm buffer +* Entry: X=ptr to next char in parms buffer +* A=current char in parms buffer +* Exit: BEQ if shell special char found, BNE if just regular char +* A=char we were checking +L05D3 pshs x Save parms buffer ptr + cmpa #'( Group start char? + beq L05ED Yes, skip ahead + cmpa #') Group end char? + beq L05ED Yes, skip ahead + cmpa #C$SPAC Space? + beq L05ED Yes, skip ahead + cmpa #', Comma? + beq L05ED Yes, skip ahead + leax >L0408,pc Table of other special chars +L05E9 cmpa ,x+ Found match or end of table? + bhi L05E9 No, keep checking (or fall through if not found) +L05ED puls pc,x Exit with BEQ/BNE flag set + +* IF wildcards were detected in preparsing, filename compares happen here +* Entry: X=ptr to current char in user's pre-parse parm line +* Y=ptr to start of current DIR entry filename +* Exit: Carry set if no match +* Carry clear if match +L05EF ldd ,x+ Get 2 chars (NOTE: PTR UP BY ONLY 1!) +L05F1 cmpa #'* 1st char a * (multi-char wildcard)? + beq L064C Yes, go handle it + cmpa #'? Question mark (single char wildcard)? + beq L0638 Yes, go handle it + cmpa #'[ Start of ranged wildcard? + lbeq L068B Yes, go handle it + bsr L05D3 Not wildcard, check for special shell chars + beq L062B It is a special shell char, skip ahead + bsr L0631 Just regular char, force uppercase + pshs a Save char + bsr L062D Force uppercase on DIR filename char + eora ,s+ Same char as last parm char? + bne L062B No, exit with carry set +L060D lda ,y+ Re-get char from DIR filename + bpl L05EF Not on last char yet, check next char from parm + ldd ,x At end of DIR filename, grab 2 chars from parm + bsr L05D3 Check 1st char against special shell chars + beq L0621 Found one, skip ahead + cmpa #'* Multi-char wildcard char? + bne L062B No, no match, exit with carry set + tfr b,a 1st char from parm is '*', check 2nd char for + bsr L05D3 special shell chars + bne L062B None found, no match, exit with carry set +L0621 lda -1,y Special char, get last char from DIR filename +L0623 anda #$7F Strip 'end of filename' bit flag + ldb #C$SPAC Space char + std -1,y Save 'fixed' last char & space + clrb Flag match + rts + +L062B comb Flag no match + rts + +* Force char to uppercase +L062D lda ,y Get char + anda #$7F Strip hi-bit +L0631 cmpa #'A Need to force uppercase? + blo L0637 No, exit + anda #$DF Yes, force to uppercase +L0637 rts + +* '?' single char wildcard found +L0638 cmpb #'* Is next char a multi-char wildcard? + beq L060D Yes, process as if just '*' + cmpb #', 2nd char '-' or greater? + bhi L060D Yes, process normally + lda ,y+ Get next char from DIR filename + bpl L062B Not end of filename, Flag no match + bra L0623 Save hibit stripped char & space, flag match + +L0646 lda ,y+ Get next char from DIR filename + bpl L0646 Hunt for end of DIR filename + bra L0623 Found it, fix hibit and add space to DIR entry + +* '*' multi-char wildcard found +L064C lda ,x+ Get next char after '*' from parm buffer + bsr L05D3 Check for shell special char + beq L0646 Found one, check if end of DIR filename + cmpa #'? Single char wildcard next? + beq L067F Yes, Process + cmpa #'[ Start of Ranged wildcard next? + beq L067F Yes, process + bsr L0631 Force char to uppercase + pshs a Save it +L065E bsr L062D Get next char from DIR filename, force uppercase + eora ,s+ Same char? + beq L066E Yes, possible resync after '*' +L0664 leas -1,s Make room on stack + lda ,y+ Re-get un-modified char from DIR filename + bpl L065E Not end of filename, try next char + leas 1,s Found end of filename, eat temp stack + bra L062B Flag no match +* Above loop @ L0664/L065E uses sneaky stack stuff + +* Found possible resync char match after '*' +L066E leas -1,s Make room on stack + pshs y,x Preserve both DIR & parm ptrs + bsr L060D Attempt normal matching using this resync + puls y,x Restore ptrs + leas 1,s Eat temp stack + bcs L0664 No, resync did not work, look for next resync + rts worked, exit with carry clear + +L067B lda ,y+ Get next char in DIR + bmi L062B Last char, flag no match +* '?' found after '*' in parm buffer +L067F pshs y,x Preserve both DIR and parm buffer ptrs + ldd -1,x Get previous & current parm chars + lbsr L05F1 Do normal sub-parsing from here + puls y,x Restore ptrs + bcs L067B No match, go to next char in DIR and attemp resync + rts Matched, exit with match + +* Ranged wildcard here +* Entry: X=ptr to 1st char in parm buffer AFTER '[' +L068B ldd ,x+ Get 1st 2 chars of range sub-string from parm bfr + bsr L0631 Force uppercase on 1st char + exg b,a Force uppercase on 2nd char + bsr L0631 + exg b,a + cmpa #'] Is 1st char a close range check char? + beq L062B Yes, flag no match for '[]' + cmpa #'- Range separator char? + beq L06A7 Yes, need to get end of range +* Special case for [x] - acts as if just normal char (no range or wildcard) + sta <u00EF No, save start of range char + bsr L062D Get char from DIR filename, force uppercase + eora <u00EF Match only range char? + beq L06B4 Yes, skip to next char now +* Special case for [xyz] - one of these chars must match + bra L068B No, see if more single chars to try matching + +* Actual range - need to get end of range char +* Entry: B=high char of range +* <u00EF - current char (within range) we are checking against +L06A7 inc <u00EF Bump up start char's ascii value + cmpb <u00EF Hit end of range yet? + beq L068B Yes, try next char + lbsr L062D Force char in A to uppercase + eora <u00EF equal to current range check char? + bne L06A7 No, try next char in range +L06B4 ldd ,x+ Get next 2 chars from pathname + cmpa #'] End of range? + bne L06B4 No, check next char + lbra L060D End of range specifier, process normally + +* Error reading from current DIR +L06BD cmpb #E$EOF End of file error? + lbne L0776 No, fatal error, leave + ldx <u0054 Get ptr to current char in wildcard filename + lda -1,x Get last char processed + bsr L0714 Add it to new expanded buffer +L06C9 lda ,x+ Get next char, inc ptr + stx <u0054 Save updated pointer + cmpa #C$CR CR? + lbeq L0789 Yes, append CR to expanded buffer, we are done + lbsr L05D3 See if special shell char + bne L06C9 Just regular char, go to next one + pshs x Save current ptr to wildcard filename + ldx <u0056 Get current ptr in expanded buffer + sta -1,x Save that char overtop last char written + puls x Get wildcard ptr back + bra L06EA Close dir path, go back into loop + +* If special shell char found right after OPEN of DIR path +* Entry: X=ptr to filename (not pathname) - but with special char +L06E3 bsr L06FB Process special shell char copying + bsr L072F Close DIR path + lbra L051D More processing + +L06EA bsr L072F Close DIR path + lbra L0520 Go back to main wildcard processing loop + +* This chunk (6EF-6F9) is for copying '\x' when x is NOT a wildcard char +L06EF lda ,x+ Get quoted char + bsr L0739 Check if it is [, * or ? + beq L06F9 Yes, add that char to expanded buffer by itself + leax -2,x No, bump ptr back to '\' + lda ,x+ Get '\' char +L06F9 bsr L0714 Append that to output buffer +* Special shell chars found goes here +* This part copies filename from [,x] to expanded buffer, handling quoted +* wildcard chars, and ending on CR or special shell char +L06FB lda ,x+ Get char + cmpa #'\ Backslash (for quoted char)? + beq L06EF Yes, go get quoted char + cmpa #C$CR Is it the end of the filename? + beq L0789 Yes, append CR to expanded line, we are done + bsr L073D Is it '?' or '*' + beq L0714 Yes, add that char to expanded buffer + lbsr L05D3 Check if shell special char + beq L0714 Yes, add to expanded buffer, return from there + bsr L0714 No, add to expanded buffer, stay in this loop + bra L06FB + +* Add char to expanded line buffer +* Entry: A=char to append to expanded line buffer +* <u0056=Current position in expanded line buffer +* <u0052=Current size of expanded line buffer +* Exit: <u0056 & <u0052 updated +L0714 pshs x,a Preserve regs + ldx <u0056 Get current pos in expanded buffer + sta ,x+ Save char + stx <u0056 Save updated expanded buffer ptr + ldd <u0052 Get expanded buffer size + addd #$0001 Increase by 1 + cmpd #2048 Is it full yet? + bhi L0773 Yes, exit with expanded line too long error + std <u0052 No, save new size + puls pc,x,a Restore regs & return + +* Close DIR path +L072F lda <u0012 Get DIR path # + beq L0738 If none, exit + os9 I$Close Close the path + clr <u0012 Clear DIR path # to none +L0738 rts + +* Wildcard checks +* Entry: A=char to check +* Exit: BEQ if any of the 3 wildcard chars, or BNE if not +L0739 cmpa #'[ Range wildcard? + beq L0745 +L073D cmpa #'? Single char wildcard? + beq L0745 + cmpa #'* Multi-char wildcard? + beq L0745 +L0745 rts + +* Parse for next wildcard or special shell char in pre-parsed parm line +* Entry: X=current pos in pre-parse parm line +* Exit: X=Same as entry +* IF WILDCARD CHAR FOUND: +* B=# chars to next wildcard/special char +* A=special char found +* Carry bit set +* IF SPECIAL SHELL CHAR FOUND +* B=0 +* Carry bit clear +* A=special char found: CR ( ) , space ! # & ; < > ^ | +L0746 pshs x Save current parm ptr + bra L0752 Parse for wildcard or special shell chars + +L074A lda ,x+ Get char from parms + bsr L0739 Do wildcard char check + beq L0752 If wildcard char, skip over it & continue + leax -1,x not wildcard char, bump back to char after \ +L0752 lda ,x+ Get char from parms + cmpa #'\ Wildcard quote char (do not expand next)? + beq L074A Yes, handle it + lbsr L05D3 No, check for other special shell chars + beq L0770 Found one, skip ahead + bsr L0739 Check for wildcard char + bne L0752 None, skip to next char +* One of the 3 wildcard chars found, process + pshs a Save char + tfr x,d Move parm ptr to D + subd 1,s Calc distance since last wildcard/special char + subd #$0001 -1 + puls a B=distance between wild/special chars + orcc #Carry Set Carry Flag + puls pc,x Exit with original parm ptr in X + +* Exit with B=0, Carry clear and A=special char found (which ends current +* 'chunk' being checked... can included CR) +L0770 clrb Clear carry, exit + puls pc,x + +* Expanded buffer full error +L0773 comb + ldb #E$BufSiz +L0776 pshs b,cc Preserve error code + bsr L072F Close DIR path (if we had one) + ldx <u004A Print text message (usually error msg) + ldy <u004C + lda #$02 + os9 I$WritLn + puls b,cc + lbra L0191 Exit with error + +L0789 lda #C$CR Append CR to expanded filenames buffer + bsr L0714 + ldy <u0052 Get expanded buffer size + leax >u0E6D,u Point to start of expanded buffer + bsr L072F Close DIR path + lds <u0050 Get back original stack ptr +* At this point, expanded buffer is complete and ready to go (either through +* wildcard routine, or by simply copying the original parm buffer from user) + +* Main entry point for non-wildcard filename search/match +* Entry: X=Ptr to start of expanded buffer +L079B tst <u001E Echo required? + beq L07A2 No, skip ahead + lbsr L021F Print out user entered parm line to std err +L07A2 tst <u0043 2=FALSE,0=TRUE, 1=??? (check current IF status, + beq L07B0 if any. If TRUE flag set, skip ahead) + lbsr L0F69 Do checks for IF type statements + tsta Find match? + lbpl L0F1D Yes, process IF type statement +L07AE clrb No error & return + rts + +* If current IF type statement has result TRUE +L07B0 tst <u0045 ??? (Are we looking for a label for GOTO?) + beq L07E3 No, skip ahead + lda ,x+ Get char from buffer + cmpa #'* Comment line? + bne L07AE No, exit without error + lbsr L091F Yes, get ptr to first non-space char into X + leay >u0124,u Point to temp buffer + lbsr L100B Copy label from X to Y + lda ,x Get 1st char of label + cmpa #'\ '*\'? (Which means cancel impending GOTO) + beq L07DB Yes, cancel GOTO + leax >u0BFC,u No, point to 80 byte buffer (GOTO label holder?) + clra default char to check against=NUL +L07CF cmpa #C$CR End of label? + beq L07DB Yes, cancel GOTO search + lda ,x+ Get next char from buffer + cmpa ,y+ Is it the label we are looking for? + beq L07CF Keep checking till done + bra L07AE No match, clear carry & return + +* Cancelling GOTO search +L07DB clr <u0045 Flag we are NOT looking for label for GOTO + clrb + leas 2,s Eat stack + lbra L010D Reprint shell prompt, process from scratch + +L07E3 bsr L07E7 + bra L083A + +L07E7 pshs x + tst <u006C + beq L0832 + tst <u005C + bne L07F5 + tst <u001C + beq L0832 +L07F5 lda ,x + cmpa #'* + beq L0832 + ldy #$0000 Force temporarily to super-user + os9 F$SUser + leax >u0CBD,u + ldd #$0203 + lbsr L0C79 + bcs L0832 + lbsr L00FB + lda #$20 + sta <$11,x + ldy #$0012 + lda <u0012 + os9 I$Write + bcs L082D + ldx ,s + ldy #$0800 + lda <u0012 + os9 I$WritLn +L082D lda <u0012 + os9 I$Close +L0832 ldy <u005A Get original user # back + os9 F$SUser Change user # to original + puls pc,x + +* Parse input line +* Entry : X=Ptr to current char in line buffer +L083A clra + sta <u0022 Flag we don't change priority for forked process + sta <u0003 Clear out # pages of data mem for forked process + sta <u000E Clear out signal code + leay >L0300,pc Point to main command list + lbsr L08D1 Parse keywords from list + bcs L08A0 Keyword found but generated error, done line + cmpa #C$CR Is 1st non-keyword char a carriage return? + beq L08A0 Yes, done line + sta <u000C Save non-keyword char + cmpa #'( Is it a 'start command group' char? + bne L087B No, try next + leay >L000D,pc Point to 'Shell' + sty <u0004 Save pointer to program to fork? + leax 1,x Bump ptr past '(' + stx <u0008 Save updated ptr +L0860 inc <u000D Bump up # of command groups +L0862 leay >L0404,pc Point to command group symbols to parse + lbsr L08E9 Hunt down EOL, or '(' or ')' (skip quoted text) + cmpa #'( Another group start? + beq L0860 Yes, bump up # of command groups & continue + cmpa #') Group end? + bne L0898 No, skip ahead (to print WHAT?) + dec <u000D Bump down # of command groups + bne L0862 Still more groups, continue parsing for them + lda #C$CR Append CR at end of command line + sta -1,x + bra L087F Check for modifiers + +L087B bsr L08A3 Check for valid path, do '<>', '#', '^' if needed + bcs L08A0 No valid path found, skip ahead +* Found valid pathname +L087F leay >L0408,pc Point to modifiers table + bsr L08E9 Go parse for them + tfr x,d Move ')' ptr to D for SUB + subd <u0008 Calculate size from 1st '(' to ')' + std <u0006 Save size of group (could also be pathname-modifier) + leax -1,x + leay >L03CF,pc Point to modifier branch table + bsr L08D1 Go execute modifier routine + bcs L08A0 If error in modifier routine, exit + ldy <u0004 Get ptr to first char we started at +L0898 lbne L0BCF Not proper, print 'WHAT?' + cmpa #C$CR Last char a carriage return? + bne L083A No, start parsing again at current position +L08A0 lbra L0B96 Done processing line, continue + +* Entry: X=Ptr to text to check for valid device name (including '.' & '..') +* Exit: Carry set if not a valid device name +* Carry clear if there was +* <u0004 = Ptr to first char where we started at +* <u0008 = Ptr to end of redirection/mem size/priority setting chars (if found) +L08A3 stx <u0004 Save ptr to current char in input line + bsr L08B6 Check for valid device name + bcs L08B5 None found, return +* Found valid device name +L08A9 bsr L08B6 Eat rest of valid pathlist + bcc L08A9 Keep going until we are done pathlist + leay >L03DE,pc Point to Command list starting at '<>>>' + bsr L08D1 Call any redirection, mem size or priority routines + stx <u0008 Save ptr to where we are now (end of current set) +L08B5 rts + +L08B6 os9 F$PrsNam Valid OS9 device name? + bcc L08C7 Yes, point X to it & return + lda ,x+ Not valid, get first char + cmpa #'. Is it a period? + bne L08CB No, bad path name + cmpa ,x+ Is it a double period? + beq L08C9 Yes, leave src ptr pointing to name after '..' + leay -1,x If single, bump ptr to name after '.' +L08C7 leax ,y Point X to pathname in source +L08C9 clra No error & return + rts + +L08CB comb Error flag + leax -1,x Bump source ptr back + ldb #E$BPNam Bad Path Name error & return + rts +* Entry: Y=ptr to command list (L0300) +L08D1 bsr L0907 Go find 1st non-space char + pshs y Save command list ptr + bsr L092A Parse for keyword or special char + bcs L08E2 If no keyword found, skip ahead + ldd ,y Keyword found, get offset + jsr d,y Go execute routine for command found + puls y Restore command list ptr + bcc L08D1 No error, continue parsing for keywords + rts Subroutine had error, return with it +L08E2 clra No error + lda ,x Get character (not in command list) + puls pc,y Restore command list ptr & return + +* Start searching at beginning of current command list +* For looking for single character modifiers +L08E7 puls y +L08E9 pshs y Preserve command list ptr + lda ,x+ Get next char from command line +L08ED tst ,y Check current char in command list + bmi L08E7 If done list, start over at beginning + cmpa #'" Is it quotes? + bne L0901 No, skip ahead +L08F5 lda ,x+ Get next char from command line + cmpa #C$CR EOL? + beq L0905 Yes, exit with A being CR + cmpa #'" Is it another set of quotes? + bne L08F5 No, keep looking for it (or EOL) + lda ,x+ Get char after 2nd quotes +L0901 cmpa ,y+ Is it the current command char we are checking? + bne L08ED No, try next +L0905 puls pc,y Yes, exit with A containing it + +* Entry: Y=ptr to command list +L0907 pshs x Preserve X + lda ,x+ Get char from line entered by user + cmpa #C$SPAC Is it a space? + beq L091D Yes, skip ahead + cmpa #', Is it a comma? + beq L091D Yes, skip ahead + leax >L0408,pc Point to single character modifiers +L0917 cmpa ,x+ Found a match? + bhi L0917 No, try next until list is done + puls pc,x Found it, restore X to point to it & return + +L091D leas 2,s Eat X off the stack +L091F lda #C$SPAC Get space character +L0921 cmpa ,x+ Keep searching until non-space char is found + beq L0921 + leax -1,x Point to 1st non-space char +* ; (1st pass) comes here +L0927 andcc #^Carry No carry & return + rts +* Command line parser +L092A pshs y,x Preserve command table ptr & input line ptr + leay 2,y Skip first offset +L092E ldx ,s Get input line ptr +L0930 lda ,x+ Get char from input line + lbsr L0F0C Convert char to uppercase if lowercases + eora ,y+ Check for a match + lsla + bne L0951 No match, skip to next keyword in table + bcc L0930 Keep checking until end of keyword (high bit set) + lda -$01,y Get command table char again + cmpa #'|+$80 '|' (with high bit set)? + beq L094E Yes, exit with carry clear + cmpa #'^+$80 '^' (with high bit set)? + beq L094E Yes, exit with carry clear + cmpa #'A+$80 Any of the other special modifiers with high bit? + blo L094E Yes, exit with carry clear + bsr L0907 Eat spaces until first non-space char + bcs L0951 If special char (!|#,etc.), skip ahead +L094E clra + puls pc,y,d + +L0951 leay -1,y Bump search ptr back +L0953 lda ,y+ Get char again + bpl L0953 Keep getting them until end of keyword + sty 2,s Save ptr to next offset on stack + ldd ,y++ Get offset + bne L092E If not at end of table, keep searching + comb End of table, command not found error + puls pc,y,x + +L0961 fcc 'startup' + fcb C$CR + +* Create child shell to run 'startup' file +L0969 pshs u,y,x Preserve regs + leax L000D,pc Point to 'shell' (module name) + leau L0961,pc Point to 'startup' (parameter for 'shell') + ldy #$0008 Size of 'startup<CR>' + ldd #$111F Program+Objct / 7.5K data area + os9 F$Fork Fork a shell to run the startup file + bcs L0983 Couldn't fork, exit + os9 F$Wait Wait until 'startup' is done +L0983 puls u,y,x Restore regs + clrb No error & return + rts + +* EX command +L0987 lbsr L08A3 Go check for valid device name (module) + bcs L09AB If none, exit + clra Std in path + bsr L09B0 Go close it + bsr L09AF Go close Std out + bsr L09AF Go close Std Err + lbsr L0B87 Go find the end of the input line + leax 1,x Bump ptr to 1 past CR + tfr x,d Move ptr to D + subd <u0008 Calculate size of current command group + std <u0006 Save it + lbsr L130A Point to module to chain&get its parm size, etc. + leas >u00FF,u Point stack to end of DP + os9 F$Chain Chain to the new program + lbra L01FA Couldn't, go here +L09AB clrb No error + lbra L020D Close logging file (if any) and exit ShellPlus + +L09AF inca Inc path # +L09B0 pshs a Save path # + lbra L0BBC close path if it is open +* CHX & CX commands +L09B5 clr <u0038 + lda #DIR.+EXEC. + os9 I$ChgDir + rts +* CHD & CD commands +L09BD lda #DIR.+READ. (bug fix, originally opened in UPDATE) + os9 I$ChgDir Change the directory + bcs L09CE Error, exit with it + clr <u0037 Flag .pwd entry as invalid + tst <u0042 WAS ,U + beq L09CE + bsr L0A04 Go update shell expanded prompt if needed +L09CE rts +* L command - Logging ON +L09CF lda #$01 + bra L09D4 +* -L command - Logging OFF +L09D3 clra +L09D4 sta <u001C + rts +* P command - Prompting ON +L09D7 clra + bra L09DC +* -P command - Prompting OFF +L09DA lda #$01 +L09DC sta <u001D + rts +* T command - Echo input ON +L09DF lda #$01 + bra L09E4 +* -T command - Echo input OFF +L09E3 clra +L09E4 sta <u001E + rts +* V command - Turn variable expansion ON +L09E7 clra + bra L09EC +* -V command - Turn variable expansion OFF +L09EA lda #$01 +L09EC sta <u001F + rts +* X command - Kill Shell when error occurs ON +L09EF lda #$01 + bra L09F4 +* -X command - Kill Shell when error occurs OFF +L09F3 clra +L09F4 sta <u0020 + rts + +L09F7 tst >u01F4,u Date already done? + bne L0A04 Yes, skip ahead + tst >u01F5,u Time already done? + bne L0A04 Yes, skip ahead + rts If neither, we don't need to change prompt? +L0A04 pshs y,x Preserve regs + bra L0A64 Go update shell expanded prompt if needed + +* Make shell prompt string the default one +L0A08 puls y Restore Y + pshs x Preserve X + leax >L003D,pc Point to default prompt string + bsr L0A14 Put that into working shell prompt string + puls pc,x Restore X & return + +* P= (prompt set) command +* Make shell prompt string (default or user-specified) +* Entry: X=ptr to source of new shell prompt string +L0A14 pshs y Preserve Y + leay >u01F9,u Point to working prompt text buffer + ldd #C$LF*256+22 Line feed & max count for prompt string+1 + sta ,y+ Save LF as first char + bsr L0A25 Go copy prompt string (& parse quotes) + bra L0A5E Go see if we need to override with default + +L0A25 clr >u01F3,u Clear quotes in progress flag +L0A29 lda ,x+ Get char from default shell prompt + cmpa #'" Is it a quotes? + bne L0A3F No, skip ahead + leax 1,x Yes, bump ptr up 2 past quotes + tst >u01F3,u We processing quotes already? + bne L0A59 Yes, we are done then + inc >u01F3,u Set processing quotes flag + leax -1,x Set ptr back to char just after quotes + bra L0A29 Check next char + +L0A3F cmpa #C$CR Carriage return? + beq L0A59 Yes, we are done then + cmpa #C$SPAC Space? + beq L0A4B Yes, skip ahead + cmpa #'; Semi-colon? + bne L0A51 No, skip ahead +* Semi-colon or space found +L0A4B tst >u01F3,u We quoting at the moment? + beq L0A59 No, we are done +L0A51 tstb Char count down to 0? + beq L0A29 Yes, continue parsing (but eating them) + decb Dec max char counter + sta ,y+ Save literal char into current copy + bra L0A29 continue parsing + +L0A59 clr ,y Append NUL to indicate end of string + leax -1,x Bump source ptr back to last char & return + rts + +L0A5E cmpb #22 Did the user do a no-length prompt? + beq L0A08 Yes, go override with default prompt + pshs x Preserve ptr to last char of source prompt + +* Create expanded shell prompt from shell prompt string +L0A64 leay >u01F9,u Point to shell prompt string + leax >u0212,u Point to expanded prompt buffer + pshs x Preserve it a moment + clr >u01F2,u Output device name done already = OFF + clr >u01F1,u Process ID # done already = OFF + clr >u01F4,u Date done already = OFF + clr >u01F5,u Time done already = OFF + clr >u01F6,u Date OR time already done once = OFF + clr >u0042,u Current working dir name done already = OFF +L0A86 lda ,y+ Get char from shell prompt string + lbeq L0B29 If end of string, exit + cmpa #'# Process ID # wanted? + bne L0AA2 No, try next +* Process ID # + tst >u01F1,u Done it already? + bne L0A86 Yes, skip doing it again + inc >u01F1,u No, flag it as being done now + ldd >u01EC,u Get process # (01-99) + std ,x++ Save in expanded prompt buffer + bra L0A86 Continue parsing +L0AA2 cmpa #'@ Standard output path device name wanted? + beq L0AAA Yes, go do it + cmpa #$E0 High bit version? + bne L0AC7 No, try next +* Standard output path device name +L0AAA tst >u01F2,u Done it already? + bne L0A86 Yes, skip doing it again + ldd #$01*256+SS.DevNm Standard out/get device name + os9 I$GetStt Get the device name + bcs L0A86 Error, skip doing device name + inc >u01F2,u Flag it as being done now +L0ABD lda ,x+ Get char from device name + bpl L0ABD Keep looking until last char (high bit set) + anda #$7F Mask out high bit + sta -1,x Save the normal char + bra L0A86 Continue parsing +L0AC7 cmpa #'$ Current working directory wanted? + bne L0AF2 No, check next +* Current working directory + tst <u0042 Done it already? (WAS ,U) + bne L0A86 Yes, skip doing it again + inc <u0042 Flag it as being done now (WAS ,U) + lda #$01 + sta <u003D + lbsr L176D Go figure out current working directory + tstb + bne L0AF2 + pshs y Save prompt string ptr + ldy <u002A Get pointer to current working directory +* Copy string: Y=source string ptr, X=prompt buffer ptr +L0AE4 lda ,y+ Get char + sta ,x+ Save as part of shell prompt text + cmpa #C$CR Was it the end? + bne L0AE4 No, keep copying + leax -1,x Bump ptr back CR + puls y Restore source string ptr + bra L0A86 Continue parsing + +L0AF2 cmpa #'( Current Date wanted? + bne L0B0A No, check next +* Current date + tst >u01F4,u Done it already? + bne L0A86 Yes, skip doing it again + inc >u01F4,u Flag as being done now + bsr L0B3B Go get date & time + pshs y Save shell prompt string ptr + leay >u02E0,u Point to date text + bra L0AE4 Copy into expanded prompt +L0B0A cmpa #') Current Time wanted? + bne L0B24 No, just store the raw ASCII char +* Current time + tst >u01F5,u Done Time already? + lbne L0A86 Yes, skip doing it again + inc >u01F5,u Flag as being done now + bsr L0B3B Go get date & time + pshs y Save shell prompt string ptr + leay >u02E9,u Point to time text + bra L0AE4 Copy into expanded prompt + +L0B24 sta ,x+ Save raw character + lbra L0A86 Continue parsing + +L0B29 sta ,x Save NUL to mark end of prompt + tfr x,d Move End of prompt ptr to D for subtract + subd ,s++ Subtract start of prompt ptr + std >u01F7,u Save size of expanded shell prompt + puls pc,y,x Restore regs & return + +* Separator table for date & time strings +L0B35 fcc '//' + fcb $0d + fcc '::' + fcb $0d + +* Get current date (2E0-2E8) & time (2E9-2EF) +L0B3B pshs y,x Preserve shell prompt string & shell prompt ptrs + tst >u01F6,u Have we already been here before? + bne L0B75 Yes, both date & time strings already done + inc >u01F6,u Flag we have been here now + leax >u02DA,u Point to date/time packet buffer + os9 F$Time Get the date/time packet + leay >u02E0,u Point to where date string goes + clrb Offset into separator table to first '/' +L0B54 lda ,x+ Get byte from time packet + bsr L0B77 Convert to ASCII + pshs b Preserve offset into separator table + ldd >u01EF,u Get ASCII version of byte + std ,y++ Save into date/string buffers + puls b Restore offset into separator table + pshs y Preserve date/string buffer ptr + leay >L0B35,pc Point to separator's table + lda b,y Get current separator + puls y Restore date/string buffer ptr + sta ,y+ Save separator into date/string buffer + incb Point to next separator + cmpb #6 On last one? + bne L0B54 No, continue converting +L0B75 puls pc,y,x Restore prompt & buffer ptrs & return + +L0B77 pshs y,x,d Preserve regs + leay >L0B80,pc Point to routine to copy ASCII digits + lbra L16B9 Go convert byte to ASCII equivalent + +L0B80 ldd $04,s Copy 2 digit ASCII # to 1EF + std >u01EF,u + rts + +* Searches for CR in string pointed to by X +* '*' Comment lines come here +L0B87 lda #C$CR We want to find the CR +L0B89 cmpa ,x+ Found it yet? + bne L0B89 No, keep looking + cmpa ,-x Set up flags & return + rts + +L0B90 pshs d,cc Preserve regs + lda #$01 Only do std in & out (not error) + bra L0B9A + +* Any errors from any of the L0300 subroutines go here +* If child process had error/status code it goes here (u005D cleared,B=Status +* code) +L0B96 pshs d,cc Preserve error code, flags & A + lda #$02 # of paths to do +L0B9A sta <u001A Save it + clra Start at path 0 +L0B9D bsr L0BA8 Go close (possibly dupe) paths + inca Next path # + cmpa <u001A Done up to last one yet? + bls L0B9D No, do next one +* POSSIBLY COULD BE PULS PC,D,CC + ror ,s+ Eat CC but shift Carry bit into Carry + puls pc,d Restore error code & A & return + +L0BA8 pshs a Save path # + tst <u0019 + bmi L0BC4 If high bit set, close path + bne L0BBC If 0<u0019<128, get changed path # & close + tst a,u Check 'real' path # from DP + beq L0BC7 If 0, return + os9 I$Close Otherwise, close current path # + lda a,u Get 'real' path # + os9 I$Dup Dupe it + +* Close path # on stack, if it is open +L0BBC ldb ,s Get path # from stack + lda b,u Get real path # from DP + beq L0BC7 If none, exit + clr b,u Clear out path # +L0BC4 os9 I$Close Close the path +L0BC7 puls pc,a Exit + +L0BC9 fcc 'WHAT?' + fcb C$CR + +L0BCF bsr L0B96 Close 3 std paths (possibly dupe) + leax <L0BC9,pc Point to 'WHAT?' + lbsr L021B Write it out std err + clrb + coma + rts + +L0BDA inc <u0019 ??? + bsr L0B96 Do path closings (possibly dupings) + lda #$FF Set flag to just close raw paths + sta <u0019 + bsr L0B90 Go close std in & std err + leax <u006D,u Point to device name buffer + lbsr L0CDB + lbcs L0200 + lda #$02 + bsr L0BA8 + lbsr L0CFF + clr <u0019 + lbra L00CC +* < processing +L0BFA ldd #$0001 + orb <u000F + bra L0C1A +* >> processing +L0C01 ldd #$020D + stb -$02,x + bra L0C0A +* > processing +L0C08 lda #$01 +L0C0A ldb #$02 + bra L0C1A +* if from z= or i=, A=0, B=3 +L0C0E tst a,u Test duped path? + bne L0BCF There is one, print 'WHAT' & close paths & return + pshs d Save path # & B + tst <u0019 + bmi L0C34 + bra L0C24 + +L0C1A tst a,u + bne L0BCF + pshs d + ldb #C$CR + stb -$01,x + +L0C24 os9 I$Dup Create duplicate of the standard path + lbcs L0CBE Couldn't create dupe, + ldb ,s + sta b,u + lda ,s + os9 I$Close + +L0C34 lda 1,s Get B + bmi L0C40 + ldb ,s + lbsr L0D05 + tsta + bpl L0C47 +L0C40 anda #$0F + os9 I$Dup + bra L0CBE +L0C47 ldb #$0B + bita #$02 + bne L0C7B + pshs a + ldd ,x + andb #$5F + cmpd #$2F57 Is it '/W' + puls a + bne L0C74 + ora #$02 + os9 I$Open + bcs L0CBE + pshs x + leax >L003C,pc + ldy #$0001 + clra + os9 I$Write + puls x + bra L0CBE +L0C74 os9 I$Open + bra L0CBE +L0C79 pshs d +L0C7B stb <u004E + ldb ,x + cmpb #$2B + bne L0C96 + leax $01,x + os9 I$Open + bcs L0CB1 + pshs u,x + ldb #SS.Size + os9 I$GetStt + os9 I$Seek + bra L0CA8 +L0C96 cmpb #'- + bne L0CB9 + leax 1,x + os9 I$Open + bcs L0CB1 Error opening + pshs u,x + ldx #$0000 + tfr x,u +L0CA8 ldb #SS.Size Init size of file to 0 bytes + os9 I$SetStt + puls u,x + bra L0CBE +L0CB1 cmpb #E$PNNF Error 216 (path name not found)? + beq L0CB9 Yes, create the file + orcc #Carry Otherwise, set error flag + bra L0CBE +L0CB9 ldb <u004E Get file attributes + os9 I$Create + +L0CBE sta <u0012 Save path # (or one we tried to duplicate?) + stb 1,s Save possible error code? + lda #$00 DO NOT CHANGE-NEED TO PRESERVE CARRY + sta <u000F + puls pc,d Restore regs & return +L0CC8 ldd #$0003 Std in & ??? + lbra L0C0E +* <>>> processing +L0CCE lda #C$CR + sta -$04,x +* i= & z= both come here right off the bat +L0CD2 bsr L0CDB + bcc L0CFF +L0CD6 rts +* <> processing +L0CD7 lda #C$CR + sta -$02,x + +L0CDB bsr L0CC8 + bcs L0CD6 + ldd #$0180 + lbra L0C0E +* <>> processing +L0CE5 lda #C$CR + sta -$03,x + bsr L0CC8 + bcs L0CD6 + ldd #$0280 + lbra L0C0E +* >>> processing +L0CF3 lda #C$CR + sta -$03,x + ldd #$0102 + lbsr L0C0E + bcs L0CD6 +L0CFF ldd #$0281 + lbra L0C0E +L0D05 pshs x,d + ldd ,x++ + cmpd #$2F30 + bcs L0D2F + cmpd #$2F32 + bhi L0D2F + pshs x,d + lbsr L0907 + puls x,d + bcs L0D2F + andb #$03 + cmpb 1,s + bne L0D31 + ldb b,u +L0D26 orb #$80 + stb ,s + puls d + leas 2,s + rts +L0D2F puls pc,x,d + +L0D31 tst $01,s + bne L0D26 + pshs x + tfr b,a + leax >u00B5,u Point to buffer for device name + ldb #'/ Put a slash in it + stb ,x+ + ldb #SS.DevNm Get the device name + os9 I$GetStt + bcs L0D4F Error, skip ahead + leax -1,x Reset ptr to include '/' + lda #UPDAT. + os9 I$Open +L0D4F puls x Restore ptr to beginning (including '/') + leas 6,s Eat stack + lbra L0CBE + +L0D56 fcc 'TRUE ' +L0D5B fcb $0d +L0D5C fcc 'FALSE' + fcb $0d + +L0D62 lda ,x+ + cmpa #'[ + bne L0D6B + lbsr L0E15 +L0D6B cmpa #'- + lbne L0E3E + ldb ,x+ + lbsr L0E15 + leax -$01,x + tfr b,a + lbsr L0F0C Convert char to uppercase if lower + cmpa #'Y + bne L0DBB +L0D81 pshs x Preserve X + leax >u0124,u Point to buffer + ldy #$0001 Read 1 byte from error path??? + lda #$02 + os9 I$Read + lbcs L0F17 + lda ,x Get the character read + puls x + lbsr L0F0C Convert char to uppercase if lower + cmpa #'Y Unless char is Y or N, re-read it + beq L0DA3 + cmpa #'N + bne L0D81 +L0DA3 pshs a Preserve char on stack + leax >L0D5B,pc Point to a Carriage return + lda #$02 Print it to std out + ldy #$0001 + os9 I$WritLn + puls a Restore char + clrb + cmpa #'Y + beq L0DF8 Print 'true' if it is a Y + bra L0DEE Print 'false' if it is a N + +L0DBB clrb + cmpa #'F + beq L0DE0 + cmpa #'E + bne L0DC8 + orb #%00000100 + bra L0DE0 + +L0DC8 cmpa #'R + bne L0DD0 + orb #%00000001 + bra L0DE0 + +L0DD0 cmpa #'W + bne L0DD8 + orb #%00000010 + bra L0DE0 + +L0DD8 cmpa #'D + lbne L0F17 + orb #%10000000 +L0DE0 tfr b,a + os9 I$Open + bcs L0DEE + os9 I$Close + bra L0DF8 + +L0DEE lda #$02 + sta <u0043 + leax >L0D5C,pc Point to 'FALSE' + bra L0DFE + +L0DF8 clr <u0043 + leax >L0D56,pc Point to 'TRUE' +L0DFE tst <u001E Command echo on? + beq L0E0B No, skip ahead + ldy #$0006 Print result of IF to std error + lda #$02 + os9 I$WritLn +L0E0B leax >u0124,u + lda #C$CR + sta ,x + clrb + rts + +L0E15 lda ,x+ + cmpa #C$SPAC + beq L0E15 + rts + +L0E1C cmpa #$3D + bne L0E26 + lda <u005F + ora #$01 + bra L0E38 + +L0E26 cmpa #'< + bne L0E30 + lda <u005F + ora #$02 + bra L0E38 + +L0E30 cmpa #'> + bne L0E3C +* X command - Kill Shell when error occurs ON + lda <u005F + ora #$04 +L0E38 sta <u005F + clra + rts + +L0E3C coma + rts + +L0E3E cmpa #'+ + bne L0E46 + inc <u0015 + bra L0E48 + +L0E46 leax -1,x +L0E48 clr <u005F + pshs u + leau >u0124,u + ldb #180 Clear out 180 bytes @ u0124 + lbsr L0412 + puls u + leay >u0124,u + ldb #81 +L0E5D lda ,x+ Copy buffer up to CR or 81 chars + lbsr L0F0C Convert char to uppercase if lower + sta ,y+ + cmpa #C$CR + lbeq L0F17 + bsr L0E1C + bcc L0E74 + decb + bne L0E5D + lbra L0F17 + +L0E74 negb + addb #81 + stb <u0016 + clra + sta -$01,y + lda ,x + bsr L0E1C + bcs L0E84 + leax $01,x +L0E84 leay >u0175,u + ldb #81 +L0E8A lda ,x+ + bsr L0F0C Convert char to uppercase if lower + sta ,y+ + cmpa #C$CR + beq L0E99 + decb + bne L0E8A + bra L0F17 + +L0E99 negb + addb #$51 + stb <u0017 + clra + sta -$01,y + tst <u0015 + beq L0EE0 + leax >u166D,u + ldd #$30b4 Store 180 ASCII 0's into buffer +L0EAD sta ,x+ + decb + bne L0EAD + leax >u0124,u + ldb <u0016 + leax b,x + leay >u16BD,u + bsr L0ED8 + leax >u0175,u + ldb <u0017 + leax b,x + leay >u170E,u + bsr L0ED8 + leax >u166D,u + leay >u16BE,u + bra L0EE8 + +L0ED8 lda ,-x + sta ,-y + decb + bne L0ED8 + rts + +L0EE0 leax >u0124,u + leay >u0175,u +L0EE8 ldb #80 +L0EEA lda ,x+ + cmpa ,y+ + blo L0EFB + bhi L0F01 + decb + bne L0EEA + lda <u005F + bita #$01 + bra L0F05 + +L0EFB lda <u005F + bita #$02 + bra L0F05 + +L0F01 lda <u005F + bita #$04 +L0F05 lbne L0DF8 + lbra L0DEE + +* Convert char to uppercase if it is a letter +L0F0C cmpa #'a Lower case letter? + blo L0F16 No, return + cmpa #'z Check high range + bhi L0F16 No, return + suba #$20 Yes, convert to uppercase +L0F16 rts + +L0F17 comb + ldb #$01 + lbra L0191 + +L0F1D cmpa #$03 + beq L0F3F + cmpa #$02 + bne L0F2B + dec <u0044 + blt L0F3F + bra L0F43 + +L0F2B cmpa #$01 + bne L0F3B + lda <u0043 + cmpa #$02 + bne L0F43 + tst <u0044 + beq L0F3F + bra L0F43 + +L0F3B inc <u0044 + bra L0F43 + +L0F3F clr <u0043 + clr <u0044 +L0F43 clrb + rts + +* Table: 7 bytes/entry: +* 1st 5 bytes is name, high bit set & NUL padded +* Byte 6 is # bytes actually used +L0F45 fcs 'IF' + fcb 0,0,0,2,0 + fcs 'ELSE' + fcb 0,4,1 + fcs 'ENDIF' + fcb 5,2 + fcs 'FI' + fcb 0,0,0,2,2 + fcs 'CLRIF' + fcb 5,3 + fcb $ff + +L0F69 leay <L0F45,pc Point to conditionals table +L0F6D ldb 5,y Get actual length of string we are checking + os9 F$CmpNam Compare with string pointed to by X + bcs L0F80 If they don't match, skip ahead + lda 6,y Get conditional token(?) number + ldb b,x Get char past end of matching string + cmpb #C$CR Is it a CR? + beq L0F8B Yes, return + cmpb #C$SPAC Is it a space? + beq L0F8B Yes, return +L0F80 leay 7,y Point to next command in table + lda ,y Get 1st char from this entry + cmpa #$FF End of table marker? + beq L0F8B Yes, return +* NOTE: THIS INCA SEEMS TO BE USELESS, AS F$CMPNAM DOESN'T USE A + inca No, ??? + bra L0F6D Process this one + +L0F8C lda #$01 + sta <u0043 + lbra L0E0B + +L0F93 lbsr L0907 Go find 1st non-space char or single char modifier + bne L0F9B + clr <u0046 +L0F8B rts + +L0F9B leay >L03AC,pc Point to 'GOTO' + ldb #4 4 chars to compare + os9 F$CmpNam Does it match? + lbcs L0BCF No, print 'WHAT?' + leax 4,x Yes, skip X past 'GOTO' + lbsr L091F Go find 1st non-space char past 'GOTO' + leay >u0C4C,u Point to some sort of buffer + lda ,x Get char from GOTO label + cmpa #'+ Is label after current pos. in script file? + bne L0FBB No, skip ahead + sta ,y+ Save '+' in buffer + leax 1,x Bump up source ptr past '+' +L0FBB bsr L100B Go copy label name into buffer + inc <u0046 Set flag that a GOTO was found +L0FBF lda ,x+ Get 1st char from user's label again + leay >L0408,pc Point to single char modifiers table +L0FC5 cmpa ,y+ Illegal modifier char in label name? + bhi L0FC5 Not yet, check other modifiers + blo L0FBF This char ok, check rest of label name + leax -1,x Point to last char (terminator) of label name + stx <u0058 Save it & return + rts + +L0FD0 lda ,x + cmpa #'+ + bne L0FDA + leax 1,x + bra L0FFB +L0FDA tst <u006B + beq L0FEA + ldy <u0067 + ldd $09,y + leay d,y + sty <u0065 + bra L0FFB +L0FEA pshs u,x + clra + ldx #$0000 Seek to beginning + tfr x,u + os9 I$Seek + puls u,x + lbcs L0191 +L0FFB lbsr L091F + leay >u0BFC,u + bsr L100B + lda #C$CR + sta ,x + inc <u0045 + rts + +* Copy label from X to buffer @ Y, terminate at 1st illegal char with CR +* Exit: X=ptr to start of label name from user's buffer +* Y=ptr to start of buffer entry copy of label name +L100B pshs y,x Preserve buffer & source ptrs + ldb #79 (78 bytes to check) +L100F decb Dec # chars left to check + beq L1022 If done max, skip ahead + lda ,x+ Get char for label + sta ,y+ Save in buffer + cmpa #'A Is it a letter or higher? + bhs L100F Yes, continue copying + cmpa #'0 Is it lower than a #? + blo L1022 Yes, not allowed, force end of label name + cmpa #'9 Is it a #? + bls L100F Yes, that is fine +L1022 lda #C$CR All others illegal, force CR in buffer copy + sta -1,y Save it + clrb No error + puls pc,y,x Restore regs & return + +* M= command (???) +L1029 ldb #C$CR + stb -$01,x + tst <u006B + bne L1057 + tst <u006C + bne L1057 + lda #Data Data module type + pshs u,y,x + os9 F$Link + bcs L1055 + stu <u0067 Save start address of module + sty <u0065 Save execution address of module + ldd 2,u + addd <u0067 + subd #$0003 + std <u0069 + inc <u006B + puls u,y,x + leax -$01,x + lbra L0907 + +L1055 puls u,y,x +L1057 lbra L0BCF + +* VAR. command +L105A leay >u05A8,u + lda ,x+ + cmpa #'? + beq L10C9 + cmpa #'= + beq L1096 + cmpa #C$SPAC + beq L1085 + cmpa #'; + beq L1085 + cmpa #'9 + bhi L1085 + cmpa #'0 + bcs L1085 + suba #$30 + ldb #$51 Multiply by 81 (size of each VAR entry) + mul + leay d,y + lda ,x+ + cmpa #'= + beq L1096 +L1085 leax -$01,x + pshs x + tfr y,x + ldy #$0051 + lda #$02 + os9 I$ReadLn + puls pc,x + +L1096 ldb #80 + lbsr L0A25 + lda #C$CR + sta ,y + rts + +L10A0 fcb C$LF + fcc 'User Variables :' + fcb C$CR + +L10B2 fcb C$LF + fcc 'Shell Sub Variables :' + fcb C$CR + +L10C9 pshs x + clrb + leax >L10A0,pc + bsr L10DF + leay >u08D2,u + clrb + leax >L10B2,pc + bsr L10DF + puls pc,x + +L10DF pshs y,b + lbsr L021B + puls y,b +L10E6 pshs y,b + lda #$51 + mul + leay d,y + leax >u0124,u + ldd #'V*256+'A + std ,x++ + ldd #'R*256+'. + std ,x++ + lda ,s +L10FD adda #$30 + ldb #'= + std ,x++ +L1103 lda ,y+ + sta ,x+ + cmpa #C$CR + bne L1103 + leax >u0124,u + ldy #$0057 + lda #$01 + os9 I$WritLn + puls y,b + bcs L1122 + incb + cmpb #C$LF + bcs L10E6 + rts + +L1122 puls y + puls pc,x + +* INC. command (increment shell variable by 1) +L1126 bsr L1144 + lbcs L0191 + addd #$0001 + bra L113A + +* DEC. command (decrement shell variable by 1) +L1131 bsr L1144 + lbcs L0191 + subd #$0001 +L113A bsr L11A7 + lda #C$CR + sta $05,y + ldx <u0048 + clrb + rts + +L1144 inc <u0014 + leay >u05A8,u + lda ,x+ + stx <u0048 + cmpa #'0 + bcs L1161 + cmpa #'9 + bhi L1161 + suba #$30 + ldb #81 + mul + leay d,y + tfr y,x + bra L1166 + +L1161 leas 2,s + lbra L0BCF + +L1166 pshs y + leas -$05,s + tfr s,y + clr $03,y + clr $04,y +L1170 clr $02,y + lda ,x+ + suba #$30 + cmpa #$09 + bhi L1195 + pshs a + lda #10 + ldb $03,y + mul + std ,y + lda $04,y + ldb #10 + mul + addd $01,y + std $01,y + clra + puls b + addd $01,y + std $03,y + bra L1170 + +L1195 ldd 3,y + leas 5,s + puls pc,y + +* 2 byte ASCII conversion table +L119B fdb 10000 + fdb 1000 + fdb 100 + fdb 10 + fdb 1 + fdb 0 + +L11A7 pshs y,x,d + pshs b + leax >L119B,pc +L11AF pshs d + ldb #'/ + stb 2,s + puls d +L11B7 inc ,s + subd ,x + bcc L11B7 + addd ,x++ + pshs d + ldb $02,s + stb ,y+ + lda $01,x + puls d + bne L11AF + puls b + puls pc,y,x,d + +* PAUSE command - may display text message, and then waits for key press or +* mouse button +L11CF ldy #394 Write up to 394 chars of pause string + lda #$02 To standard error + os9 I$WritLn + lbcs L0191 + tfr y,d Tfr # chars written to D + leax d,x Point X to next char after ones written + leax -1,x Point to last char written + pshs x Save ptr + ldd #$02*256+SS.SSig Std Err/Send signal when key pressed + ldx #$000A Signal $A is the one to send + os9 I$SetStt + lbcs L0191 Error, use main shell error handler + ldb #SS.MsSig Send signal on mouse button press + os9 I$SetStt + lbcs L0191 + ldx #$0000 Go to sleep until one of the 2 is received + os9 F$Sleep + ldb #SS.Relea Signal gotten, release all signals + os9 I$SetStt + clrb No error & return + puls pc,x + +* Parse PATH=, add paths to PATH buffer list +L1209 pshs x Preserve ptr to string after 'PATH=' + lda ,x Get 1st char + cmpa #'? User requesting current paths? + beq L1245 Yes, go do that + pshs u Preserve U + leau >u0CDD,u Point to PATH= buffer +L1217 lda ,x+ Get char from user-requested path + cmpa #C$SPAC Space? + beq L1217 Yes, eat spaces until 1st real char found + sta ,u+ No, save char +L121F leay >L0408,pc Point to command modifier list +L1223 cmpa ,y+ Match char? + bhi L1223 No, our char is higher, check next modifier + beq L1237 Found match, skip ahead + lda ,x+ No modifier found, get next char + sta ,u+ Save in PATH buffer + cmpa #C$SPAC Was it a space? + bne L121F No, check this char vs. modifier list + lda #C$CR Yes, change to CR + sta -1,u Save CR instead (terminate 1 path entry) + bra L1217 Do whole list + +* NOTE: ANY modifier (not just CR, but ! # & ; < > ^ |) stops PATH=parsing +L1237 leax -1,x Bump ptr back to last char from user + stx 2,s Save ptr on stack over original X + lda #C$CR Get CR + sta -1,u Save CR as current path end + sta ,u And 1 extra for parse routines + puls u Get U back + puls pc,x Restore new X & return + +L1245 leax >u0CDD,u Point to start of PATH=buffer +L1249 ldy #400 Write up to 400 chars to standard out + lda #$01 + os9 I$WritLn Print text of one path + lbcs L0191 Error, go process shell error + tfr y,d Tfr # bytes written to D + leax d,x Offset X to end of what was printed + lda ,x Get char from there + cmpa #C$CR CR (end of path list)? + bne L1249 No, go write next path out + puls x Restore ptr to next set of PATH= + leax 1,x Bump ptr up by 1 & return + rts + +* ^ (set priority on the fly) command +L1265 ldb #C$CR Plop a CR onto the end + stb -$01,x + ldb <u0022 Any priority already set? + lbne L0BCF Yes, print 'WHAT?' + lbsr L16EB Go calculate binary priority into B + stb <u0022 Save priority to fork module with + lbra L0907 Continue processing for modifiers + +* # (set data memory size) command +L1277 ldb #C$CR + stb -1,x + ldb <u0003 Already have a data mem size set? + lbne L0BCF Yes, print 'WHAT?' + lbsr L16EB + eora #'K + anda #$DF Force uppercase + bne L1294 No 'K', just save # of 256 byte pages + leax 1,x + lda #4 Multiply # of K by 4 to get # pages + mul + tsta + lbne L0BCF Ended up too big, print 'WHAT?' +L1294 stb <u0003 Save data mem size to use + lbra L0907 Continue processing command line + +* Carriage return processing +L1299 leax -1,x + lbsr L145D + bra L12A3 + +* ; (separator) command (also called by others) +L12A0 lbsr L1459 +L12A3 bcs L12BA + lbsr L0B96 Go do the path stuff + tst <u005D Is there a module that is unlinking? + bne L12AE Yes + bsr L12D2 Go wait for child process to die (A=process #) + +L12AE bcs L12BA If child exited with status/signal code,skip + lbsr L0907 Go parse for modifiers + cmpa #C$CR Was the next non-space/comma char a CR? + bne L12B9 No, skip ahead + leas 4,s Yes, eat stack +L12B9 clrb No error + +* Child process had a signal/status code +L12BA pshs cc Preserve error status + clr <u005D ??? + puls cc Restore carry + lbra L0B96 ??? Go close some paths & return? + +* & (background operation) command +L12C3 lbsr L1459 + bcs L12BA + bsr L12BA + ldb #$26 + lbsr L16B3 + bra L12AE + +* W command - Wait for a child to die +L12D1 clra Clear process ID # +* Entered here if commands are separated with ';' (or '()' groups) +L12D2 pshs a Save ID # of process? +L12D4 os9 F$Wait Wait for child to die or until signal received + tst <u000E Signal received (which would be in SHELL)? + beq L12EC No, child was exited (or got signal), go process +* Shell was interrupted by signal while Waiting + ldb <u000E Get signal that we received + cmpb #S$Abort Was it a PD.QUT (<CTRL>-<E>) (quit 'W'aiting?) + bne L1304 No, skip ahead + lda ,s Get process # + beq L1304 None, exit + os9 F$Send Send the signal to the child as well + clr ,s Clear process # + bra L12D4 Go Wait again (until child dies) + +* Child F$Exited or was aborted - eat should go here +* Entry: A=ID # of deceased child +* B=Exit (error) code from child +L12EC lbcs L1308 If F$Wait exited with error, return with it + cmpa ,s Same process # as one we were waiting for? + beq L1304 Yes, exit + tst ,s No, was there a specific process # we wanted? + beq L12F9 No, skip ahead +* Child died, but not the one we were waiting for + tstb Was there an error status? + beq L12D4 No, ignore dead child and wait for one we wanted +* Child died with error on exit +L12F9 pshs b Preserve child's exit status code + bsr L12BA ??? Go close & re-dupe paths? + ldb #'- Get a '-' (for a '-003' process finished msg) + lbsr L16B3 Print that out + puls b Get back exit status code + +L1304 tstb is there an Error/signal code? + beq L1308 No, exit + cmpb #S$Intrpt Yes, is it a keyboard interrupt signal? + beq eatchar Yes, eat the key + cmpb #S$Abort Keyboard abort signal? + bne errexit No, exit with unknown error/signal code + +* At this point, child died from signal 2 or 3 (CTRL-C or CTRL-E). The corres- +* ponding key is also sitting in this devices PD.BUF as the 1st char. We musts +* 1) Disable keyboard signal & eat the key from the buffer +* 2) Exit from here with Carry set & signal (2 or 3) in B +eatchar pshs b,x,y Preserve signal code & regs used + ldd #SS.Ready Std in, check for data ready on device + os9 I$GetStt Check it + bcs NotSCF No chars waiting on device, exit with signal + lda <u0018 Is the shell immortal? + beq NotSCF No, don't try to eat the char +eat clra Standard in path + leas -PD.OPT,s Make 32 byte buffer for OPT's + leax ,s Point X to it + clrb SS.Opt call + os9 I$GetStt Get current path options + lda ,x Get device type + beq Eatkey SCF (not script file) so go eat key +NoChar leas PD.OPT,s Eat temp buffer + bra NotSCF Exit with signal code (script file got signal) + +* Have to eat key: Shut echo off 1st +Eatkey clr 4,x PD.EKO flag off + os9 I$SetStt Shut echo off + ldd #SS.Relea Std In, Release keyboard/mouse signals + os9 I$SetStt Shut signals off so we don't get stuck + leax ,-s Make 1 byte buffer on stack + ldy #1 1 byte to read + os9 I$Read Eat the char + leas 1,s eat buffer + ldd #SS.SSig Std In, send signal on key ready + ldx #$B Signal to send + os9 I$SetStt Turn keyboard signal on again + leax ,s Point to temp buffer again + inc 4,x PD.EKO flag on + clra Std In + clrb Set Options + os9 I$SetStt Turn echo back on + leas PD.OPT,s Deallocate temp buffer + ldb u180D,u Get current history line # + cmpb #1 First one? + bhi Previous No, B=previous one + ldb u180C,u Was on first, so get last + incb Adjust for dec +Previous decb Point to previous one + lbsr L19D3 Go get ptr to history + lda ,y Get 1st char from previous line in history + sta ,x Save char there + ldd #SS.Fill Fill keyboard buffer call to Std In + ldy #$8001 1 char long, don't append CR + os9 I$SetStt Stick that key into the keyboard buffer +NotSCF puls b,x,y Restore regs (and exit status byte in B) +errexit coma Yes, set carry & exit +L1308 puls pc,a + +* If data area <4.25K, force up to 7.5K +* Exit: A=Type/language +* X=Current source line parsing ptr (module name to chain) +* Y=Size of parameter area +* U=Ptr to parameter area +* B=Size of data area +L130A lda #Prgrm+Objct Module type/language + ldb <u0003 Get # pages of data mem needed for forked module + cmpb #$11 Is it at least 17? + bhs L1316 Yes, skip ahead + ldb #$1F Otherwise, force to 7.5K minimum + stb <u0003 Save it +L1316 andcc #^Carry Clear carry + ldx <u0004 Get mem module ptr + ldy <u0006 Get size of current command group + ldu <u0008 Get ptr to start of current command group + rts + +* Copy string from X to Y until CR is hit +L1320 lda ,x+ Get char + sta ,y+ Save it + cmpa #C$CR Carriage return? + bne L1320 No, keep copying + rts Done, return + +* Attempt load in module to execute (it's not in memory) +* Entry: X=Ptr to module name +L1329 lda #EXEC. 1st, attempt to get it from current Exec DIR + os9 I$Open Attempt to open it + bcc L1362 Found it, continue +* Possible search thru PATH= settings + inc <u000F ??? Set flag to indicate using PATH= + leax >u0CDD,u Point to start of PATH= list +L1336 clrb + lda ,x Get 1st char from next PATH= line + cmpa #C$CR End of list? + lbeq L1564 Yes, ??? + leay >u0124,u No, point to temp buffer + bsr L1320 Copy path to temp buffer until CR + pshs x Preserve ptr to next possible path + lda #'/ Add slash since we want file from this path + sta -1,y Save at end of path in temp buffer + ldx <u0004 Get ptr to module/script name we are looking for + bsr L1320 Copy it into temp buffer up to CR + leax >u0124,u Point to start of full path list + lda #READ. Attempt to open file + os9 I$Open + puls x Restore ptr to next possible path + bcs L1336 Didn't find file there, try next path + leax >u0124,u Point to full pathlist again + stx <u0004 Replace ptr to module with full pathlist ptr +L1362 leax >u00D6,u Point to buffer to hold beginning of file + ldy #77 77 bytes to read + os9 I$Read Read it in + bcc L1373 No error, skip ahead + cmpb #E$EOF Just EOF error? + bne L13CE No, something more serious, skip ahead +L1373 tst <u000F + bne L137B + ldb #$04 + stb <u000F +L137B pshs a Save path # a sec + ldd M$ID,x Get possible module header bytes + cmpd #M$ID12 Legit module header? + puls a Restore path # + beq L1396 OS9 module, skip ahead +* Not module...possible shell script? + os9 I$Close Not OS9 module, close file + clrb + dec <u000F Dec flag + lbeq L1564 If 0, skip ahead + inc <u000F If not, inc & skip ahead + lbra L1564 + +* Seems to be OS9 module +L1396 clr <u000F Clear flag + ldy M$Name,x Get offset to module name + leax >u00E3,u Point X to offset $E in module + cmpy #$000D Does the name start at offset $D? + beq L13C0 Yes, skip ahead + pshs u Preserve U + tfr y,u Move name offset to U + ldx #$0000 MSW of file pos=0 + os9 I$Seek Go seek to that spot in file + puls u Restore U + bcs L13CE Error seeking, go handle + ldy #64 Go read up to 64 char filename + leax >u00E3,u Point to spot to hold filename + os9 I$Read Read it in + bcs L13CE Error reading, go handle +L13C0 pshs a Save path # + os9 F$PrsNam Parse module name + puls a Restore path # + bcs L13CE + cmpb #$40 + bhi L1422 + clrb +L13CE pshs b,cc Preserve error status + os9 I$Close Close file + puls b,cc Restore error status + lbcs L162B If error, exit with it (S/B L162C) + leax >u00D6,u Point to buffer holding 77 bytes of file + lda $06,x + ldy $0B,x + cmpa #$40 + bne L1407 + bsr L13EF + lbcs L162B + lbra L14AF +L13EF leax >u00E3,u + os9 F$NMLink + bcc L1400 + ldx <u0004 + os9 F$NMLoad + bcc L1400 + rts +L1400 leax >u00E3,u + stx <u0004 + rts +L1407 cmpa #$51 + bne L1413 + bsr L13EF + lbcs L162B + bra L1427 +L1413 cmpa #$11 + lbne L14D7 + leax >u00E3,u + stx <u0010 + lbra L15D7 +L1422 lbsr L08CB + bra L13CE + +* Call a shellsub module +L1427 clra Type/language byte to wildcard:any will match + ldx <u0004 Get ptr to module name + pshs u Preserve U + os9 F$Link Attempt to link it in + puls u Restore U + lbcs L162B If we couldn't link, Exit with error + ldx <u0004 Get ptr to module name again + os9 F$UnLoad Unlink it + lbcs L162B If we couldn't unlink exit with error + ldx <u0008 Get ptr to current group (param ptr for shellsub) + ldd <u0006 Get size of param area for shellsub + leau >u08D2,u Point to shellsub variable area + jsr ,y Execute shellsub module + pshs b,a,cc Preserve error status & A + clra + clrb + std <u0010 ? (originally pointing to E3 if type $11 module) + ldx <u0004 Get shellsub module ptr + os9 F$UnLoad Unlink it + std <u0004 Clear shellsub module ptr + inc <u005D Set flag that we should wait for module to exit? + puls pc,u,y,x,d,cc restore regs & return + +L1459 lda #C$CR + sta -1,x +L145D clr <u0060 + pshs u,y,x + ldx <u0004 Get ptr to name + ldd ,x Get 2 chars of name + andb #$5F Force 2nd one to uppercase + cmpd #$2F57 Is it a /W? + bne L1473 No, check for shellsub + comb Yes, exit with bad mode error + ldb #E$BMode + lbra L162B + +L1473 clra Wildcard NMLink + os9 F$NMLink Link to module + lbcs L1329 Error, do something + cmpa #ShellSub+Objct ShellSub module? + beq L1427 Yes, go set up for it + ldx <u0004 Get ptr to name back + os9 F$UnLoad Drop the link count back down + pshs y Save data area size + ldx <u0004 Get ptr to module name again + leay >L000D,pc Point to 'Shell' + ldb #$05 Size of 'Shell' + os9 F$CmpNam Is the module requested Shell? + puls y Restore data area size + bcs L14A3 Not shell, skip ahead + ldb 5,x Get char right after 'shell' + cmpb #C$CR Is 'shell' the only thing on the line? + lbeq L158D Yes, skip ahead + cmpb #C$SPAC Is it a space? + lbeq L158D Yes, skip ahead +* Not Shell or Shellsub module +L14A3 cmpa #Prgrm+Objct ML program? + lbeq L15D7 Yes, skip ahead + cmpa #Data Is it a data module? + bne L14D7 No, skip ahead + inc <u0060 Set flag - data module +L14AF inc <u0060 Bump it up + ldx <u0004 Get ptr to module name + os9 F$PrsNam Parse the name + ldy <u0063 Get ptr to Intercept routines data mem ($418) + leay $0A,y Bump up to $422 + sty <u0008 Save ptr to start of current group + sty <u0061 ??? Ptr to data modules name? + ldx #60 Max size of group + stx <u0006 Save it + ldx <u0004 Get ptr to module name +L14C8 lda ,x+ Copy it to buffer @ $422 + sta ,y+ + decb + bne L14C8 + lda #C$CR Append a CR to it + sta ,y+ + clrb + lbra L1564 +* Not 6809 object code or data module either +L14D7 sty <u000A Save data area size + leax >L0013,pc Point to alternate languages table +L14DE tst ,x Is this entry active? + lbeq L1629 No, exit with non-existing module error + cmpa ,x+ Same module type as we want? + beq L14EE Yes, skip ahead +L14E8 tst ,x+ No, eat module name + bpl L14E8 + bra L14DE Try next module +* Found run-time language match +L14EE ldd <u0008 Get ptr to start of current command group + subd <u0004 Calculate size of whole group + addd <u0006 Don't include size of current group + std <u0006 Save remainder size + ldd <u0004 Get ptr to start of sub-module + std <u0008 Save it + pshs y,x Preserve data area size & primary module ptr + leax >L0021,pc Point to 'RUNB' + cmpx ,s Is that the run-time module we want? + bne L1546 No, skip ahead +* RUNB needed - have to () & quote/commas between params + ldx <u0008 Yes, get sub-module ptr? + leay >u0418,u Point to before sub-module + bsr L154B Copy buffer up to next param (or end of line) + beq L1535 If it was end of line, add CR & continue + ldd ,x Get 2 param chars + cmpd #$2822 Is it '("' (RUNB variables ahead?) + beq L1546 Yes, skip ahead (we won't have to add them) + lda #C$SPAC No, add ' ("' + sta ,y+ + ldd #$2822 + std ,y++ +L151F bsr L154B Copy buffer up to next param (or end of line) + beq L152E If end of line, add '")' (close params) + ldd #$222C Add '","' (Basic09 param separators + std ,y++ + lda #$22 2nd quote of above + sta ,y+ + bra L151F Keep doing for all parameters + +L152E ldd #$2229 Add '")' to end parameter list + std ,y++ + lda #C$CR Add CR +L1535 sta ,y+ + tfr y,d Move end of param ptr to D + leay >u0418,u Point to start of param + sty <u0008 Save as start ptr + subd <u0008 Calculate param size + std <u0006 Save it +L1546 puls y,x Restore data area size & primary module ptr + lbra L15D5 + +* Copy from X to Y until either a CR or a space char is hit +* If it finds a space, it will eat them until the next non-space char is found +L154B lda ,x+ Get char + cmpa #C$SPAC Is it a space? +* Was L155B + beq L1559 yes, skip ahead + cmpa #C$CR Is it the end of the line? + beq L155F Yes, bump ptr back to CR & exit + sta ,y+ Save the char + bra L154B Keep doing it + +L1559 lda ,x+ Get char +L155B cmpa #C$SPAC Is it another space? + beq L1559 Yes, keep eating spaces +L155F leax -$01,x Bump ptr back to either non-space or CR + cmpa #C$CR Is it a CR? & return + rts + +* THIS CMPB / LBEQ SEEMS TO BE USELESS, AS B IS ALWAYS CLEAR COMING INTO THIS +* ROUTINE +L1564 cmpb #E$BMode + lbeq L162B + ldx <u0006 Get size of current group + leax 5,x Bump it up by 5??? + stx <u0006 Save new size + tst <u0060 Data module linked? + bne L1592 Yes, skip ahead + ldx <u0004 Get module name ptr + ldu 4,s + lbsr L0BFA Set up paths + lbcs L162B If error, exit with it + bra L1592 Start up shell with '-P X PATH=(current)' + +* L1581 is for sub-shells (?), L1586 for normal shells +L1581 fcc '-P X ' Prompting off/exit on error +L1586 fcc 'PATH= ' For inheriting parent shell's paths + fcb C$CR + +L158D leax <L1586,pc Point to 'path=' + bra L1595 Skip ahead + +L1592 leax <L1581,pc Point to '-p x ' +L1595 leay >u166D,u Point to about-to-be merged buffer + lbsr L1320 Copy up until CR + leay -1,y Point to CR + leax >u0CDD,u Point to copy of current path= +* Copy all paths to buffer, changing <CR> separated ones with Spaces +L15A2 lda ,x Get char + cmpa #C$CR CR? + beq L15B1 Yes, don't copy this buffer + lbsr L1320 Copy up until CR + lda #C$SPAC Replace CR with Space + sta -1,y + bra L15A2 Continue copying CR marked blocks until done +L15B1 lda #'; Replace final CR with ; (command separator) + sta -1,y + tst <u0060 + beq L15BE + ldd #'M*256+'= If flag set, append 'M=' + std ,y++ +L15BE ldx <u0008 Get ptr to start of current group + lbsr L1320 Copy up until CR + leax >u166D,u Point to merged buffer again + stx <u0008 Make it the new current group start + tfr y,d Move end buffer ptr to D + pshs x Push merged buffer ptr for SUBD + subd ,s++ Calculate size of merged buffer + std <u0006 Save merged buffer size + leax >L000D,pc Point to 'shell' + +L15D5 stx <u0004 Save ptr to module name to fork +L15D7 ldx <u0004 Get ptr to module name to fork + lda #Prgrm+Objct + os9 F$NMLink Get memory requirement stuff from it + bcc L15E5 Got it, continue + os9 F$NMLoad Couldn't get, try loading it + bcs L162B Still couldn't get, can't fork +L15E5 tst <u0003 Memory size specified? + bne L15F2 Yes, skip ahead + tfr y,d No, tfr modules mem size to D + addd <u000A ??? Add to something + addd #$00FF Round up to nearest page + sta <u0003 Save # of pages need for data mem +L15F2 clr ,-s Clear byte on stack to store original priority + ldb <u0022 Get priority we want to set new program at + beq DnePrior 0=Use inherited priority, skip ahead + leax >u166D,u Point to place to hold Process descriptor + os9 F$ID Get our process # + os9 F$GPrDsc Get our process descriptor + ldb P$Prior,x Get our priority + stb ,s Save it + ldb <u0022 Get priority for new process + os9 F$SPrior Set our priority so child will inherit it +DnePrior lbsr L130A Go setup Fork entry registers + os9 F$Fork Create the new process + pshs d,cc Preserve error (if any) & new process # + ldb 3,s Get original priority back + beq L1609 Priority didn't change, ignore it + os9 F$ID Get our process # into A + os9 F$SPrior Reset our priority back to normal +L1609 lda #Prgrm+Objct Std 6809 module + ldx <u0010 Get ptr to some other module name (?) + bne L1611 There is one, unlink it instead + ldx <u0004 Get ptr to command name +L1611 os9 F$UnLoad Bump link count down back to normal? + clra + clrb + std <u0010 Zero out other module name ptr + std <u0004 Clear out ptr to main command name + lda <u0060 Check if data module needs to be unlinked too + cmpa #$01 Just 1 link to it? + bne L1627 No, skip ahead + lda #Data Data module + ldx <u0061 Get ptr to name of data module + os9 F$UnLoad Bump link count down back to normal +L1627 puls cc,d Get back F$FORK error/process # + leas 1,s Eat priority byte + puls pc,u,y,x Restore regs & return + +L1629 ldb #E$NEMod Non-existing module error +L162B coma + puls pc,u,y,x + +L162E fcc '/pipe' + fcb C$CR + +L1634 pshs x + leax <L162E,pc Point to '/pipe' + ldd #$0103 + lbsr L0C0E + puls x + bcs L169E + lbsr L1459 + bcs L169E + lda ,u + bne L1653 + os9 I$Dup + bcs L169E + sta ,u +L1653 clra + os9 I$Close + lda #$01 + os9 I$Dup + lda #$01 + lbsr L0BA8 + lda #$02 + lbra L0BA8 + +* Filename for shell log-append mode because of leading '+' +L1666 fcc '+/dd/log/uxxx' + fcb $0d + +* Make shell logging filename @ u0CBD,u +L1674 leax <L1666,pc Point to log name string (append mode) + leay >u0CBD,u Point to buffer to hold shell log name + lbsr L1320 Copy name to buffer + leay -4,y Point to where 1st digit will go + lda <u005A+1 Get LSB of user #? + pshs y,x,d Preserve regs + leay <L1693,pc Point to routine + bra L16B9 Go convert digits & append to logname + +L168A lda <u0047 + pshs y,x,d + leay <L1693,pc + bra L16B9 + +L1693 ldy $0B,s Get ptr to where shell log # goes + ldd $03,s Get 1st 2 digits of # + std ,y++ Save in shell log pathname + lda $05,s Get last digit + sta ,y Save it too +L169E rts + +L169F ldd 4,s Get last 2 digits of process # (ASCII) + std >u01EC,u Save it & return + rts + +L16A6 pshs y,x,d Preserve End of parm ctr & others + os9 F$ID Get user's ID # + sty <u005A Save it + leay <L169F,pc Point to routine + bra L16B9 + +* Set up to write out process # when forked? +L16B3 pshs y,x,d + leay >L021B,pc + +* Entry: A=Process ID # +* Exit: L01EC=2 lower digits of process # in ASCII format + +L16B9 pshs y,x,b Preserve regs + leax 1,s Point X to X value on stack + ldb #$2F Init B to start @ '0' in loop +L16BF incb Bump ASCII # up + suba #100 Start with 100's digit + bhs L16BF More left, keep going + stb ,x+ Save digit + ldb #$3A Init so loop starts @ ASCII '9' +L16C8 decb Bump ASCII # down + adda #10 Do 10's digit + bhs L16C8 Still more, keep going + stb ,x+ Save 10's digit + adda #$30 Bump 1's digit up to ASCII equivalent + ldb #C$CR Add carriage return + std ,x Save overtop Y on the stack + leax ,s Point X to B on stack + jsr ,y + leas 5,s Eat stack + puls pc,y,x,d Restore other regs & return + +* KILL command +L16DD bsr L16EB Go get process # to kill + cmpb #2 Trying to kill the system process or 1st shell? + bls L170A Yes, print 'WHAT?' & ignore it + tfr b,a Move process # to proper reg +L16E5 clrb S$Kill signal + os9 F$Send Send it to the process & return + rts + +* Set priority - subroutine to calculate binary version of # +* (used for both process # & priority values) +L16EB clrb Initialize # for loop +L16EC lda ,x+ This loop will calculate the binary version + suba #$30 Of the ASCII # pointed to by X + cmpa #9 + bhi L16FD + pshs a + lda #10 + mul + addb ,s+ + bcc L16EC Keep going until overflows past 255 +L16FD lda ,-x Get last char done + bcs L1708 If #>255, eat RTS & exit with error + tst <u0014 If flag is set, return + bne L169E + tstb Otherwise, check if # is 0 + bne L169E No, return +L1708 leas 2,s Yes, eat RTS address & exit with error +L170A lbra L0BCF Print 'WHAT?' +* SETPR routine +L170D bsr L16EB Go calculate process # + stb <u0021 Save it + lbsr L0907 Find next field (after commas/spaces) + bsr L16EB Go calculate priority (into B) + lda <u0021 Get process # + os9 F$SPrior Set it's priority & return + rts + +L171C fcc 'pwd: bad name in path' + fcb C$CR +L1732 fcc '.......................................' +L1759 fcc '.' + fcb C$CR +L175B fcc 'pwd: read error' + fcb C$CR + +L176B clr <u003D +L176D pshs y,x + leay >u02F2,u + lda #$81 + tst <u0037 + beq L178F + ldx <u0039 + bra L17F7 +* .PXD command +L177D clr <u003D + pshs y,x + leay >u0375,u + lda #$85 + tst <u0038 + beq L178F + ldx <u003B + bra L17F7 +L178F sta <u0029 + sty <u003E +L1794 leax >$0080,y + lda #$0D + sta ,x + stx <u002A + leax <L1759,pc + stx <u0040 + bsr L1801 + lbsr L183C +L17A9 ldd <u002C + std <u0032 + lda <u002E + sta <u0034 + bsr L1828 + beq L17D3 + lda <u0012 + os9 I$Close + lbcs L188C + ldx <u0040 + leax -$01,x + stx <u0040 + bsr L1801 + bsr L183C + bsr L1817 + leax >u03F8,u + lbsr L1859 + bra L17A9 +L17D3 lda <u0012 + ldb #SS.DevNm + leax >u00B5,u + os9 I$GetStt Get device name + bsr L1859 +L17E0 lda <u0012 + os9 I$Close + ldx <u002A + lda <u0029 + bita #$04 + bne L17F3 + inc <u0037 + stx <u0039 + bra L17F7 +L17F3 inc <u0038 + stx <u003B +L17F7 ldy #$0083 + lda #$01 + clrb + lbra L18A0 +L1801 lda <u0029 + os9 I$Open + sta <u0012 + rts +L1809 lda <u0012 + leax >u03F8,u + ldy #$0020 + os9 I$Read + rts +L1817 bsr L1809 + bcs L1896 + leax >u0415,u + leay >u0032,u + bsr L1830 + bne L1817 + rts +L1828 leax >u002C,u + leay >u002F,u +L1830 ldd ,x++ + cmpd ,y++ + bne L183B + lda ,x + cmpa ,y +L183B rts +L183C bsr L1809 + ldd >u0415,u + std <u002F + lda >u0417,u + sta <u0031 + bsr L1809 + ldd >u0415,u + std <u002C + lda >u0417,u + sta <u002E + rts +L1859 os9 F$PrsNam + bcs L1890 + ldx <u002A + pshs b + incb + clra + std <u0032 + tfr x,d + subd <u0032 + cmpd <u003E + bls L1881 + puls b +L1871 lda ,-y + anda #$7F + sta ,-x + decb + bne L1871 + lda #$2F + sta ,-x + stx <u002A + rts + +L1881 lda #'* + sta ,-x + stx <u002A + leas 3,s + lbra L17E0 + +L188C pshs b,cc + bra L18AB + +L1890 leax >L171C,pc + bra L189A + +L1896 leax >L175B,pc +L189A leas $02,s + ldd #$02FF +L18A0 stx <u002A + pshs b,cc + tst <u003D + bne L18AB + os9 I$WritLn +L18AB puls b,cc + puls y,x,pc + +L18DB leax >u0124,u Point to PD.OPT work copy area + clrb Change to CLRB + os9 I$GetStt Get current PD.OPT settings + tst ,x Check device type + bne L1914 If not SCF, don't bother changing stuff + inc >u1812,u Set flag that we are changing key defs + ldd <$10,x Get PD.INT & PD.QUT chars (<CTRL>-<C> & <E>) + sta >u180F,u Save copy of PD.INT + stb >u180E,u Save copy of PD.QUT + ldd #$0A0C Reload with up & down arrows + std <$10,x Save 'em + lda $06,x Get PD.NUL count (normally 0) + sta >u1811,u Save copy + lda #$05 Replace with 5 + sta $06,x + clra + clrb Reset path options to new settings + os9 I$SetStt Do SS.OPT Setstat + +* Non-SCF devices go here (ex. a script file would be RBF) +L1914 ldb #SS.SSig Send signal on data ready + ldx #$000B Signal code to send is $B + rts Do SetStt, clear <E signal copy, and go to L191C + +* X still is $B from L1914 +* Called when F$Sleep @ L0171 is interrupted by keyboard/mouse signal +L191C ldb <u000E Get Signal code + clr <u000E Clear memory copy of signal code + cmpb #S$Abort Keyboard abort signal (<CTRL>-<E>)? + bne L1928 No, check next + bsr L1932 Write CR out if no history yet + bra L1967 Go backwards in history + +L1928 cmpb #S$Intrpt Keyboard interrupt signal (<CTRL>-<C>)? + lbne L017B No check for $B signal (ignore rest) + bsr L1932 Write CR out if no history yet + bra L1991 Go forwards in history + +* Keyboard abort or Keyboard interrupt signal +L1932 tst >u180D,u Any history entries yet? + bne L193D Yes, exit + bsr L1959 Otherwise, put CR into the buffer + os9 I$WritLn Write it out to standard out +L193D rts + +L193E os9 I$ReadLn Read in line + bcc L194E No error, skip ahead +* NOTE: WHEN THE ABORT A SUB-FORKED PROGRAM BUG OCCURS, THE ABOVE READLN +* EXITS WITH CARRY SET & B=0 (ERROR 0) + cmpb #$02 Go backward in history buffer signal? + beq L1967 Yes, go process + cmpb #$03 Go forward in history buffer signal? + beq L1991 Yes, go process + lbra L1AAA Go to parse routine with unknown error in B +L194E cmpy #$0001 Just 1 char. read? + lbeq L1AA3 Yes, go do normal parsing (no error) + lbra L1A37 Otherwise, change chars <$0D to spaces + +* Change A to be standard output??? +L1959 lda #C$CR Carriage return + leax >u0124,u ??? Point to a buffer + sta ,x Save CR there + clra Prepare to write the CR out to standard input + ldy #$0001 + rts +* PD.QUT (redefined to be go back 1 in history buffer) +L1967 tst >u180C,u Any lines in history buffer? + bne L1972 Yes, go move between them + bsr L1959 Otherwise, put CR into buffer + lbra L1AA3 Go to normal command parse routine (no error) + +L1972 ldb >u180D,u Get 'current' history buffer entry # + cmpb #$01 On the first one? + bls L1987 Yes, go wrap to end + cmpb >u180C,u Somehow point past last one? + bhi L1987 Yes, bump back to last one + decb Bump to previous one + stb >u180D,u Save it as 'current' history entry # + bra L19B3 + +L1987 ldb >u180C,u Get highest history entry # + stb >u180D,u Make it the current + bra L19B3 + +* PD.INT (redefined to be go forward 1 in history buffer) +L1991 tst >u180C,u Any lines in history buffer? + bne L199C Yes, go move between them + bsr L1959 Otherwise, put CR into buffer + lbra L1AA3 Go to normal command parse routine (no error) + +L199C ldb >u180D,u Get current history entry # + cmpb >u180C,u Higher or same as last one? + bhs L19AD Yes, wrap to beginning + incb Bump to next one + stb >u180D,u Save it as 'current' history entry # + bra L19B3 + +L19AD ldb #$01 Set history entry # to 1st one + stb >u180D,u Save as 'current' entry # +L19B3 bsr L19D3 Go get ptr to history entry buffer we want + sty >u1813,u Save 'current' history buffer ptr + leax >u0213,u Point to expanded shell prompt + ldy >u01F7,u Get size of expanded shell prompt + lda #$02 Std Err + os9 I$WritLn Write out shell prompt + bsr L19EA Go Pre-load Read buffer with history entry + bcc L1A0E No error, continue + lbra L1AAA Normal parse with error + +* Find history entry # we want +* Entry: B=history entry # (1-xx) +* Exit: Y=Ptr to history buffer entry we wanted +L19D3 ldy >u180A,u Get ptr to start of history buffers +L19D8 decb Bump down counter to find entry we want + beq L19E9 Found it, skip ahead +L19DB tst ,y+ Wrong one, search for end of one we are checking + beq L19E4 Found it, skip ahead + lbsr L1A97 Wrap buffer ptr if we hit end of all history + bra L19DB Keep searching for end of current entry + +L19E4 lbsr L1A97 Wrap buffer ptr if we hit end of all history + bra L19D8 Go into next entry in history buffers + +L19E9 rts Found it, leave + +L19EA leax >u0124,u Point to temp buffer + ldy >u1813,u Get ptr to current history buffer + clrb Set counter to 0 (size of buffer) +L19F4 lda ,y+ Get char from history buffer + beq L1A00 Found end, continue + sta ,x+ Put it in temp buffer + incb Bump up size counter + lbsr L1A97 Wrap buffer ptr if we hit end of all history + bra L19F4 Continue copying into temp buffer +L1A00 clra D=Size of history buffer + decb + tfr d,y Move to proper register + leax >u0124,u Point to buffer history copy + ldb #SS.Fill Fill it with current selected history command + os9 I$SetStt + rts + +* Successfull SS.Fill of history buffer goes here +L1A0E lda #$01 Write copy of history buffer to std out + os9 I$Write + leax >u0124,u Point to current history buffer again + tfr y,d Transfer # bytes written to D + lda #C$BSP Backspace char +L1A1B sta ,x+ Fill buffer with backspaces + decb + bne L1A1B + leax >u0124,u Write them to reset cursor to start of line + lda #$01 + os9 I$Write + ldd #SS.Relea Eat keyboard signal (SS.Fill cleared it out of + os9 I$SetStt the read buffer already) + ldb #SS.SSig Setup for re-enabling it + ldx #$000B Signal Code to send on keypress=$B + lbra L016A Go re-enable signal send on keyboard/mouse input + +* Put new entry into history buffers, adjusting # used, etc.) +* Entry: Y=# bytes read in ReadLn <>1 +L1A37 pshs y Preserve # bytes read + tfr y,d Move to D reg + ldy >u1808,u Get ptr to where next history entry will go + leax >u0124,u Point to line entered by user +L1A44 lda ,x+ Get char + cmpa #C$CR Control char <$0d? + bhs L1A4C No, save the character + lda #C$SPAC Replace with space char if it is +L1A4C sta ,y+ Save char into history buffer + bsr L1A97 Wrap to beginning if we hit end + cmpy >u180A,u Point to entry #1? + bne L1A59 No, continue + bsr L1A7B Yes, make new #1 entry & drop # of entries +L1A59 decb Drop # bytes left in new entry + bne L1A44 Not done, continue + clr ,y+ mark end with NUL + bsr L1A97 Wrap to beginning if at end + cmpy >u180A,u Pointing to entry #1? + bne L1A69 No, skip ahead + bsr L1A7B Yes, make new #1 entry & drop # of entries +L1A69 inc >u180C,u Increase # of entries + sty >u1808,u Save ptr to where next history entry will go + puls y Restore # bytes read + clra Point to temp buffer again + leax >u0124,u + bra L1AA3 Normal parse, no error + +* Reset ptr to new 1st entry in history buffer +L1A7B pshs y Preserve current location in history buffer + ldy >u180A,u Point to start of 1st entry +L1A82 tst ,y+ End of current entry? + beq L1A8A Yes, skip ahead + bsr L1A97 No, wrap if we need to + bra L1A82 Keep going until we find end +L1A8A bsr L1A97 Wrap if we need to + dec >u180C,u Dec # lines in history buffer + sty >u180A,u Save new 'start of history' ptr + puls pc,y Restore current location & return +* If we are at end of history buffers, wrap to beginning (raw, has nothing to +* do with entry #'s) +L1A97 cmpy >u1806,u Are we at end of buffer for history entries? + bne L1AA2 No, continue on + leay >u1815,u Yes, reset to beginning of history buffers +L1AA2 rts + +L1AA3 bsr L1AB1 Reset std paths to normal <CTRL>-<E>/<C> settings + andcc #^Carry No error + lbra L018B Normal command processing + +L1AAA bsr L1AB1 Reset std paths to normal <CTRL>-<E>/<C> settings + orcc #Carry Error + lbra L018B Normal command processing + +* Reset all 3 standard paths' NUL counts/Keyboard Interrupt/Terminate settings +L1AB1 pshs x,d Preserve regs + tst >u1812,u Check flag + beq L1AD6 If 0 skip ahead + leas <-PD.OPT,s Make 32 byte buffer on stack + leax ,s Point X to buffer + clrb CHANGE TO CLRB + clra Standard input path + bsr L1AD8 Restore NUL counts, Keyboard Intrpt/Terminate + lda #$01 Do same for Standard output path + bsr L1AD8 + lda #$02 Do same for Standard Error path + bsr L1AD8 + leas <PD.OPT,s Eat stack buffer + clr >u1812,u Reset PD.OPT flags to 0 + clr >u180D,u +L1AD6 puls pc,x,d Restore regs & return + +* Restore path options to preserved Keyboard terminate/interrupt & end of +* line NUL counts +L1AD8 pshs a Preserve path # + os9 I$GetStt Get current PD.OPT settings + lda >u180E,u Get copy of Keyboard terminate char + sta <PD.QUT-PD.OPT,x Save into buffered copy + lda >u180F,u Get copy of Keyboard interrupt char + sta <PD.INT-PD.OPT,x Save into buffered copy + lda >u1811,u Get copy of end of line NUL count + sta $6,x Save into buffered copy + puls a Get path # back + os9 I$SetStt Reset path options with restored values & return + rts + + emod +eom equ * + end +