home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
500-599
/
ff537.lzh
/
ZShell
/
ZShell.s.lzh
/
ZSH.s
Wrap
Text File
|
1991-08-26
|
109KB
|
5,215 lines
******** ZSHELL (C) 1990,91 Paul Hayter ********
* See my lharcs disk for log of previous versions
* ZSHELL V1.23 MAY 1991
* New readfile routine had to be created, and execscript and type had to be
* changed to accommodate this. New copy handles wildcards and ctrlC. Delete
* also supports the -r option.
*
* Changed comment specifier to * # or ;
* Changed delete so that it handles ctrl c better
*
* Altered type command so it is more like normal type. i.e. just continuously
* lists to the screen. CTRLC should break it.
*
* Added 'more' type text file viewer. Default clears screen and shows 23 lines
* (maximum allowed on original AmigaDOS window at startup). Space takes you
* forward 20 lines. Backspace takes you back 20 lines. Optional line count
* used for displaying more than 23 lines, ala PAL screens.
* Added <RETURN> to more; advances you one line.
* Added T and B to more. Take you to Top and Bottom.
*
* V1.24 900605
* Made it so that if you execute the last line in the history, it won't
* continually fill up the history. Can have 1 level of nested aliases I think.
* eg. set cls "echo ^L";set cdir "%1 cls;cd $1;diw"
* Fixed age old bug which made it so that anything printed with newprint had
* a null char at the end of it. Not anymore! Changed rpn so it uses less
* memory.
*
* V1.25 900630 start of July break.
* Added residentable command. Uses resi_list linked list created by
* resident command. All resident commands unloaded when shell is quit. Type
* RESIDENT [command1] [command2]...[command11] to make resident
*
* V1.26 900630
* Changed resident so that it auto replaces an entry in the resident list
* if it already exists. Fixed bug in search_res which failed to compare
* resident names to parm1 properly. Also changed search_sets so it is case
* independent.
*
* Changed sets so that defn has no size limitation. However shell line
* length is limited to 256 chars anyway
*
* V1.27 900704
* Changed packet sending so it is general purpose. There is now myArg1 thru
* myArg7 in memory block as well as packettype (the ACTION) and packettask
* which is the task you are sending it to. Added relabel and addbuffers
* commands which utilize the general purpose sendpacket.
* Changed m command so you can specify a start and end address.
*
* V1.28 900706
* Added IF ELSE ENDIF commands. Same as AmigaDOS so far. Support IF EXISTS,
* IF NOT EXISTS, IF WARN, IF ERROR, IF FAIL etc. Added ASK command for
* y n type responses. Changed get_parm so that TABs can precede parms.
* Is really only useful for TABs at start of line. It still looks for a space
* as the delimiter after a parameter.
*
* V1.29 900708
* Added LABEL and GOTO commands. Both of limited use considering the IF
* command constructs. Also added SLEEP command. NOTE Changed scflag from
* absolute to offset a5. Added RETURN command for exiting scripts midstream.
* Added join command. Added htype command. Added strings command. Changed
* help command so everything is printed pretty on window with border.
* Discovered strange bug which makes info show a different number of bytes
* free than is actually free on a particular disk. I dont know why?
* Changed prompt command so that \ character works in it. ie \%.
*
* V1.30 900722
* Changed path area size. Altered default path. Includes vd0: rad: etc.
* MADE shelline and clibuf bigger 384 bytes. Should allow for really long
* sets.
FIB equ 260 ;FileInfoBlock
ACCESS_READ equ -2
ACCESS_WRITE equ -1
MODE_OLDFILE equ 1005
MODE_NEWFILE equ 1006
;DOS LIBRARY
dl_A2 equ 42
SIGBREAKF_CTRL_C equ 1<<12
SIGBREAKB_CTRL_C equ $0C
;FILE INFO BLOCK
fib_DiskKey equ $0000
fib_DirEntryType equ $0004
fib_FileName equ $0008
fib_Protection equ $0074
fib_EntryType equ $0078
fib_Size equ $007c
fib_NumBlocks equ $0080
fib_Date equ $0084
fib_Comment equ $0090
fib_Reserved equ $00e0
;INFO DATA STRUCTURE
id_NumBlocks equ 12
id_NumBlocksUsed equ 16
id_BytesPerBlock equ 20
id_VolumeNode equ 28
;PROCESS
pr_ReturnAddr equ 176
pr_CLI equ 172
pr_CIS equ 156
pr_COS equ 160
pr_ConsoleTask equ 164
pr_StackSize equ 132
pr_Result2 equ 148
pr_WindowPtr equ 184
pr_TaskNum equ 140
pr_CurrentDir equ 152
;COMMAND LINE INTERFACE
cli_Module equ 60
cli_CommandName equ 16
cli_DefaultStack equ 52
cli_StandardInput equ 28
cli_StandardOutput equ 56
;FILE HANDLE
fh_Pos equ 16
fh_End equ 20
fh_Buf equ 12
*DATESTAMP
ds_Days equ 0
ds_Minute equ 4
ds_Tick equ 8
RETURN_OK EQU 0
RETURN_WARN EQU 5
RETURN_ERROR EQU 10
RETURN_FAIL EQU 20
;AVAIL STUFF
MEMF_PUBLIC equ 1
MEMF_CHIP equ 2
MEMF_FAST equ 4
MEMF_CLEAR equ $10000
MEMF_LARGEST equ $20000
* ACTIONS
ACTION_SCREEN_MODE EQU 994
ACTION_INHIBIT EQU 31
ACTION_MORE_CACHE EQU 18
ACTION_RENAME_DISK EQU 9
_LVOOpenLibrary equ -552
_LVOCloseLibrary equ -414
_LVOAllocMem equ -198
_LVOFreeMem equ -210
_LVORawDoFmt equ -522
_LVORawMayGetChar equ -510
_LVOFindTask equ -294
_LVOForbid equ -132
_LVOPermit equ -138
_LVOAvailMem equ -216
_LVOPutMsg equ -366
_LVOGetMsg equ -372
_LVOWaitPort equ -384
_LVOSetSignal equ -306
_LVOAllocSignal equ -330
_LVOFreeSignal equ -336
_LVOSetProtection equ -186
_LVOOutput equ -60
_LVOWrite equ -48
_LVOLock equ -84
_LVOUnLock equ -90
_LVODupLock equ -96
_LVOExamine equ -102
_LVOExNext equ -108
_LVOOpen equ -30
_LVOClose equ -36
_LVORead equ -42
_LVOInput equ -54
_LVODeleteFile equ -72
_LVORename equ -78
_LVOCreateDir equ -120
_LVOCurrentDir equ -126
_LVOIoErr equ -132
_LVOParentDir equ -210
_LVOLoadSeg equ -150
_LVOUnLoadSeg equ -156
_LVOInfo equ -114
_LVODateStamp equ -192
_LVOSeek equ -66
_LVODeviceProc equ -174
_LVODelay equ -198
_AbsExecBase equ 4
* NEED THESE 2 MACROS FOR A68K ASSEMBLER
blo macro
bcs \1
endm
bhs macro
bcc \1
endm
*SYSTEM0 stuff!!!!!!!!!!
REG_SysBase equr a6
callsys macro
jsr _LVO\1(REG_SysBase)
endm
* parameter offsets & stack
SAVED_REGS reg a2-a6/d2-d3
DELTA equ 7*4
ARG_NAME equ 4+DELTA
ARG_SEGLIST equ 8+DELTA
ARG_ARGS equ 12+DELTA
* additional return codes
NO_CLI equ -1
NO_MEM equ -2
* local constants
MAXBSTR equ 255
LF equ 10
* register usage
REG_Result equr d3
REG_Process equr a2 ;may not be A4, see below!
REG_CLI equr a3
REG_CIS equr a4 ;may not be A3, see below!
REG_PrevStack equr a5
* local stack frame
* STRUCTURE StackFrame,0
sf_CommandName equ 0
sf_CommandArgs equ MAXBSTR+1 ;BSTR, length byte!
sf_PrevStack equ sf_CommandArgs+MAXBSTR+1 ;not a BSTR, LF-terminated!
sf_SaveReturnAddr equ sf_PrevStack+4
sf_SaveModule equ sf_SaveReturnAddr+4
sf_SaveCommandName equ sf_SaveModule+4
sf_StackBase equ sf_SaveCommandName+4
sf_StackSize equ sf_StackBase+4
sf_PushSize equ sf_StackSize+4
sf_Process equ sf_PushSize+4
sf_CLI equ sf_Process+4
sf_CIS equ sf_CLI+4
sf_SCB_Buf equ sf_CIS+4
sf_SCB_Pos equ sf_SCB_Buf+4
sf_SCB_End equ sf_SCB_Pos+4
sf_SIZEOF equ sf_SCB_End+4
SHELLINE_SIZE equ 256+128 V1.30
CLIBUF_SIZE equ 256+128
PATH_SIZE equ 256 V1.30
HISTORY_SIZE equ 1024 MUST BE POWER OF 2
SEARCH_STRING_SIZE equ 60
DEST_LABEL_SIZE equ 60
* THE GENERAL MEMORY BLOCK
blockbase equ 0 ;the fib or info goes here
outhandle equ blockbase+260
inhandle equ outhandle+4
parm1 equ inhandle+4 ;addr of each parameter within shelline
parm2 equ parm1+4
parm3 equ parm2+4
parm4 equ parm3+4
parm5 equ parm4+4
parm6 equ parm5+4
parm7 equ parm6+4
parm8 equ parm7+4
parm9 equ parm8+4
parm10 equ parm9+4
parm11 equ parm10+4
parm12 equ parm11+4
parm13 equ parm12+4
parm14 equ parm13+4
parm15 equ parm14+4
endofparms equ parm15+4
shelline equ endofparms
endofshelline equ shelline+SHELLINE_SIZE
CLIbuf equ endofshelline
errorstack equ CLIbuf+CLIBUF_SIZE
temp1 equ errorstack+4
temp2 equ temp1+4
tempbuf equ temp2+4
dosbase equ tempbuf+SHELLINE_SIZE
temp2buf equ dosbase+4 ;80 char temp buffer
scsize equ temp2buf+80
scaddr equ scsize+4
scptr equ scaddr+4
scflag equ scptr+4 new v1.29
patharea equ scflag+2
now equ patharea+PATH_SIZE
nost equ now+4
then equ nost+4
past equ then+4 ;history buffer=1024 bytes
thistask equ past+HISTORY_SIZE
gather_ptr equ thistask+4
gather equ gather_ptr+4 ;CSI string=20 bytes
tempbytes equ gather+20
first_set_defn equ tempbytes+2
set_search_string equ first_set_defn+4
line_count equ set_search_string+SEARCH_STRING_SIZE
mem_addr equ line_count+2
wild_flag equ mem_addr+4
stat_mode_flag equ wild_flag+1
wild_string equ stat_mode_flag+1 allow 80 chars for wildcard
date_mark equ wild_string+80 3 lwords
mem_mark equ date_mark+12 3 lwords chip/fast/total
CD_string equ mem_mark+12 Allow 80 bytes.
prompt_string equ CD_string+80 Allow 80 bytes.
prompt_args equ prompt_string+80 Allow 40 bytes
nonstdin equ prompt_args+40 Allow 40 bytes
nonstdout equ nonstdin+40 Allow 40 bytes
stdout equ nonstdout+40
stdin equ stdout+4
mult_comm_flag equ stdin+4
next_comm_ptr equ mult_comm_flag+2
ctrl_c_flag equ next_comm_ptr+4
failat_level equ ctrl_c_flag+2 word size
cd_block equ failat_level+2
cd_volnode equ cd_block+4
recurs_flag equ cd_volnode+4
indent_count equ recurs_flag+2
resi_head equ indent_count+2
resi_flag equ resi_head+4
myArg1 equ resi_flag+2
myArg2 equ myArg1+4
myArg3 equ myArg2+4
myArg4 equ myArg3+4
myArg5 equ myArg4+4
myArg6 equ myArg5+4
myArg7 equ myArg6+4
packettype equ myArg7+4
packettask equ packettype+4
last_failcode equ packettask+4
if_flag equ last_failcode+4
if_condition_flag equ if_flag+1
goto_flag equ if_condition_flag+1
dest_label equ goto_flag+2
please_close_me equ dest_label+DEST_LABEL_SIZE
mem_offset_addr equ please_close_me+4
stackbot equ mem_offset_addr+4
sizeofblk equ stackbot
********************************************
SECTION MYSHELL,CODE
;Try to open dos then do the shell
start move.l a0,entryA0
move.l d0,entryD0
move.l _AbsExecBase,a6
move.l #sizeofblk,d0
moveq #0,d1
jsr _LVOAllocMem(a6) ;alloc general mem block
tst.l d0
beq.s blkfail
move.l d0,membase
move.l membase(pc),a5 ;A5=membase
* move.l _AbsExecBase,a6
moveq #0,d0
lea dosname(pc),a1
jsr _LVOOpenLibrary(a6)
tst.l d0
beq.s dosfail
move.l d0,a6 ;A6 = DOSBASE
move.l d0,dosbase(a5)
move.l d0,_DOSBase ;V1.02
bsr shell DO IT
bsr deallocate_sets v1.05
bsr deallocate_residents
bsr raw_off
move.l a6,a1
move.l _AbsExecBase,a6
jsr _LVOCloseLibrary(a6)
dosfail move.l a5,a1
move.l #sizeofblk,d0
* move.l _AbsExecBase,a6
jsr _LVOFreeMem(a6)
moveq #0,d0
rts
blkfail moveq #RETURN_ERROR,d0
rts
* SAVE THE CONSOLE HANDLERS
get_handles
jsr _LVOOutput(a6)
move.l d0,outhandle(a5)
move.l d0,stdout(a5) V1.13
jsr _LVOInput(a6)
move.l d0,inhandle(a5)
move.l d0,stdin(a5)
rts
initialise_default_paths
lea defpath1(pc),a0
lea patharea(a5),a1
moveq #10,d0 11 DEFAULT PATHS
idp_1 move.b (a0)+,(a1)+
bne.s idp_1
dbra d0,idp_1
clr.b (a1) MAKE SURE 2 ZERO BYTES AT END
rts
* PRINT DECIMAL print D0 as decimal
print10 movem.l d0/a0-a1,-(sp)
move.l d0,-(a7)
move.l a7,a1
lea format(pc),a0
bsr new_print
lea 4(sp),sp
movem.l (sp)+,d0/a0-a1
rts
*PRINT STRING at a1 ;saves some of the important low registers
pr_space lea space(pc),a1
bra.s pr_string
pr_tab lea tab(pc),a1
bra.s pr_string
pr_prompt lea prompt_string(a5),a1
bra.s pr_string
pr_lf lea lf(pc),a1
pr_string movem.l d0-d3/a0-a3,-(sp)
move.l a1,d2
moveq #-1,d3
ps1 addq.l #1,d3
tst.b (a1)+
bne.s ps1
move.l outhandle(a5),d1
jsr _LVOWrite(a6)
movem.l (sp)+,d0-d3/a0-a3
rts
*CHECK WHETHER A SCRIPT NAME WAS TYPED ON ENTRY TO ZSHELL
execscr move.l entryA0(pc),a0
cmpi.b #10,(a0)
bne.s execscr2
moveq #-1,d1 handle DEFAULT SCRIPT FILE login.z
bsr changeWindowPtr disable volume requesters
lea defscript1(pc),a2
move.l a2,d1
moveq #ACCESS_READ,d2
jsr _LVOLock(a6)
tst.l d0
bne.s 1$
lea defscript2(pc),a2
move.l a2,d1
moveq #ACCESS_READ,d2
jsr _LVOLock(a6)
tst.l d0
beq.s 2$
1$ move.l d0,d1
jsr _LVOUnLock(a6)
move.l a2,a0
moveq #0,d1
bsr changeWindowPtr
bra xz2
2$ moveq #0,d1
bsr changeWindowPtr
rts
execscr2 move.l a0,a1
execscr3 cmpi.b #10,(a1)+
bne.s execscr3
clr.b -1(a1) ;A0 pts to CLI residue.
bra xz2 ;NB this is OK, xz2 will pop the return addr and jump to chorus
*MAIN BIT
shell bsr get_task V0.15
bsr raw_on
clr.l first_set_defn(a5)
clr.b stat_mode_flag(a5) V1.09
clr.l resi_head(a5)
clr.b if_flag(a5) No IF
clr.l please_close_me(a5)
clr.b goto_flag(a5)
clr.b scflag(a5)
clr.l then(a5)
clr.l now(a5)
clr.l nost(a5)
MOVE.W #10,failat_level(a5)
move.b #$a,past(a5)
clr.b nonstdin(a5)
clr.b nonstdout(a5)
clr.b mult_comm_flag(a5)
bsr get_handles
bsr initialise_default_paths
bsr init_prompt
bsr eval_CD
* lea hello(pc),a1 V1.18 no hello
* bsr pr_string
move.l a7,errorstack(a5)
bsr execscr
chorus bsr raw_on MAKE SURE RAW MODE IS ON
bsr compose_prompt
bsr close_redirection
bsr get_line
move.l parm1(a5),a0
lea comtext(pc),a1
lea comoffs(pc),a2
bsr match
tst.l d0
beq.s notfound
lea start(pc),a0
move.l a7,errorstack(a5)
clr.b ctrl_c_flag(a5)
jsr 0(a0,d0.w) ;call internal command
tst.b ctrl_c_flag(a5)
bne.s com_fail
chkfail move.l d0,last_failcode(a5)
cmp.w failat_level(a5),d0 ;ALL COMMANDS MUST RETURN D0=0 unless failure
blo.s chorus
com_fail clr.b mult_comm_flag(a5)
* bsr print10
tst.b scflag(a5)
beq.s chorus
bsr kill_script
bra.s chorus
notfound bsr archie3 ;try disk NOTE V1.02
move.l d0,-(sp)
move.l thistask(a5),a0
move.l cd_volnode(a5),d0
move.l pr_CurrentDir(a0),a1
add.l a1,a1
add.l a1,a1
cmp.l fl_Volume(a1),d0 check volume node
bne.s 1$
move.l cd_block(a5),d0
cmp.l fl_Key(a1),d0 check disk block number
beq.s 2$
1$ bsr eval_CD If command changes cd then change prompt.
2$ move.l (sp)+,d0
* bsr print10
bra.s chkfail
*Match the string pointed to by A0 to one in a table pted to by a1
*The number of the matched string is linked to an offset table pted to by
*A2. return with
*D0 holding offset from 'start' so a jsr 0(a0,d0.w) can be done
*Entry A1 pts to Command text table A2 pts to command offset table
match moveq #0,d1 ;command count
move.l a0,a3 ;save command
mat2 move.b (a0)+,d0
cmp.b (a1),d0 ;V1.01
beq.s mat3
add.b #$20,d0 ;'A' -> 'a' handle commands typed in UCase
cmp.b (a1),d0
bne.s nextcom ;if any character wrong then check next
mat3 lea 1(a1),a1
tst.b -1(a0) ;check whether 0 was last compared
beq.s foundit ;if it was then success
bra.s mat2
nextcom tst.b (a1)+
bne.s nextcom
addq.l #2,d1 ;each offset is a word
move.l a3,a0
tst.b (a1) ;put 0,0 at end of com table
bne.s mat2
moveq #0,d0 ;D0 = 0 if command not found
rts
foundit move.w 0(a2,d1.l),d0 ;get offset
rts
get_one_char
read_kbd lea tempbytes(a5),a0 V0.15
move.l a0,d2
move.l inhandle(a5),d1
moveq #1,d3
jsr _LVORead(a6)
move.b tempbytes(a5),d6
rts
* A1 pts to past, d0=nost
gimme lea shelline(a5),a2
move.l d0,nost(a5)
cmp.l now(a5),d0
bne.s gimme2
moveq #0,d4 clear linmax
moveq #0,d5 clear linhere
lea delete_line(pc),a1
bsr pr_string
bsr pr_prompt
rts
gimme2 moveq #0,d5 linhere = 0
gimme5 addq.l #1,d0 copy to shelline
and.l #HISTORY_SIZE-1,d0
cmp.b #$a,0(a1,d0.l)
beq.s gimme4
move.b 0(a1,d0.l),0(a2,d5.l)
addq.l #1,d5
bra.s gimme5
gimme4 move.l d5,d4 linmax=linhere
gimme3 lea delete_line(pc),a1
bsr pr_string
bsr pr_prompt
clr.b 0(a2,d4.l) clear last
move.l a2,a1
bra pr_string
* READ TEXT LINE from keyboard or script into buffer pointed to by a0,
* and clear last byte. NOTE A0 is essentially ignored, and shelline is the assumed address
* Return with a0 same, and d0=length of text read
type_in tst.b scflag(a5) ;check whether we're doing a script
bne scr_in
type_in2 move.l a0,-(sp)
type_in3 moveq #0,d5 D5=linhere V0.15
moveq #0,d4 D4=linmax
next_ch bsr get_one_char
cmp.b #$9b,d6
bne not_csi
clr.l gather_ptr(a5)
fetch_csi bsr get_one_char
lea gather(a5),a0
move.l gather_ptr(a5),d0
move.b d6,0(a0,d0.l) ;save byte from CSI sequence.
addq.l #1,gather_ptr(a5)
cmp.b #'@',d6
blo.s fetch_csi ;keep gathering if char < @
cmp.b #'~',d6
bhi.s fetch_csi ;keep gathering if char > ~
cmp.b #'D',d6 CHECK LEFT ARROW <CSI>D
bne.s not_left
tst.l d5
beq.s not_left
subq.l #1,d5
lea left_cursor(pc),a1
bsr pr_string
bra next_ch
not_left cmp.b #'A',d6
bne.s not_sh_left
cmp.b #' ',gather(a5) CHECK SHIFT LEFT ARROW <CSI> A
bne.s not_sh_left
move_left tst.l d5
beq.s next_ch
subq.l #1,d5
lea left_cursor(pc),a1
bsr pr_string
lea shelline(a5),a0
cmp.b #' ',-1(a0,d5.w)
bne.s move_left
bra.s next_ch
not_sh_left
cmp.b #'C',d6 CHECK RIGHT ARROW <CSI>C
bne.s not_right
cmp.l d4,d5
bhs.s not_right
addq.l #1,d5
lea right_cursor(pc),a1
bsr pr_string
bra next_ch
not_right cmp.b #'@',d6
bne.s not_sh_right
cmp.b #' ',gather(a5) CHECK SHIFT RIGHT ARROW <CSI> @
bne.s not_sh_right
move_ryt cmp.l d4,d5
bhs next_ch
addq.l #1,d5
lea right_cursor(pc),a1
bsr pr_string
lea shelline(a5),a0
cmp.b #' ',-1(a0,d5.w)
bne.s move_ryt
bra next_ch
not_sh_right
cmp.b #'A',d6 CHECK UP ARROW
bne.s not_up
lea past(a5),a1
move.l nost(a5),d0
cmp.l then(a5),d0
beq.s no_srch_back
db1 subq.l #1,d0
and.l #HISTORY_SIZE-1,d0 WRAP AROUND
cmp.b #$a,0(a1,d0.l)
bne.s db1
no_srch_back
bsr gimme
bra next_ch
not_up cmp.b #'B',d6 CHECK DOWN ARROW
bne.s not_down
up_bit lea past(a5),a1 CALLED BY SHIFT DOWN BIT
move.l nost(a5),d0
cmp.l now(a5),d0
beq.s no_srch_fwd
ub1 addq.l #1,d0
and.l #HISTORY_SIZE-1,d0
cmp.b #$a,0(a1,d0.l)
bne.s ub1
no_srch_fwd
bsr gimme
bra next_ch
not_down cmp.b #'T',d6 CHECK SHIFT UP
bne.s not_sh_up
lea past(a5),a1
move.l then(a5),nost(a5) nost = then (the top)
move.l nost(a5),d0
bsr gimme
bra next_ch
not_sh_up cmp.b #'S',d6 CHECK SHIFT DOWN
bne.s not_sh_down
move.l now(a5),nost(a5) nost = now (the bottom)
bra.s up_bit
not_sh_down ;NOTE V1.05
cmp.b #'~',d6 CHECK FUNCTION KEYS AND HELP KEY
bne next_ch
cmp.b #'?',gather(a5)
bne.s process_the_func_key
lea help_ret(pc),a1
move.l d0,-(sp) need crap on stack to call print_def
bsr print_def will rip last 2 addrs off stack
* never gets to this line
process_the_func_key
bsr translate_func_key
bra next_ch
not_csi cmp.b #8,d6 CHECK BACKSPACE
bne.s not_bs
tst.l d5
beq.s not_bs
subq.l #1,d5
lea backspace_it(pc),a1
bsr pr_string
del_str lea shelline(a5),a4
lea SHELLINE_SIZE+shelline(a5),a1 NOTE SHELLINE SIZE!!!
lea 0(a4,d5.w),a0
lea 1(a0),a2
bs_1 move.b (a2)+,(a0)+
cmp.l a2,a1
bne.s bs_1
subq.l #1,d4
bra next_ch
not_bs cmp.b #$7f,d6 CHECK DELETE
bne.s not_del
cmp.l d4,d5
bhs.s not_del
lea delete_it(pc),a1
bsr pr_string
bra.s del_str
not_del cmp.b #$18,d6 CHECK CTRL X
bne.s not_ctrlx
moveq #0,d5
moveq #0,d4
lea delete_line2(pc),a1
bsr pr_string
bsr pr_prompt
bra next_ch
not_ctrlx cmp.b #$05,d6 CHECK CTRL E
bne.s not_ctrle
seek_ryt cmp.l d4,d5 send cursor to end of line
bhs next_ch
addq.l #1,d5
lea right_cursor(pc),a1
bsr pr_string
bra.s seek_ryt
not_ctrle cmp.b #$1a,d6 CHECK CTRL Z
bne.s not_ctrlz
seek_left tst.l d5 send cursor to start of line
beq next_ch
subq.l #1,d5
lea left_cursor(pc),a1
bsr pr_string
bra.s seek_left
not_ctrlz cmp.b #$d,d6 check CR
bne no_cr
do_cr lea return_it(pc),a1
bsr pr_string
lea shelline(a5),a4
move.b #10,0(a4,d4.w) HACK JOB (MUST END IN LF 0)
clr.b 1(a4,d4.w) FOR ALIAS STUFF
tst.l d4 CHECK IF NOTHING TYPED
bne.s history_it
bsr pr_prompt IF JUST HIT RETURN, THEN START AGAIN
bra type_in3
history_it
lea past(a5),a1 CHECK IF LAST ENTRY IS SAME AS CURRENT
move.l now(a5),d0
cmp.l then(a5),d0
beq.s 2$
move.l d0,nost(a5)
1$ subq.l #1,d0 FIND LAST
and.l #HISTORY_SIZE-1,d0 WRAP AROUND
cmp.b #$a,0(a1,d0.l)
bne.s 1$
lea (a4),a0
bra.s 3$
4$ cmp.b #$a,d1 COMPARE LAST TO SHELLINE
beq finland
3$ addq.l #1,d0
and.l #HISTORY_SIZE-1,d0
move.b (a0)+,d1
cmp.b 0(a1,d0.l),d1
beq.s 4$
2$ move.l a4,a3 lin COPY LINE TO HISTORY BUFFER
move.l now(a5),d3 pts to the last LF
5$ addq.l #1,d3
and.l #HISTORY_SIZE-1,d3 WRAP AROUND
move.b (a3)+,d0
move.b d0,0(a1,d3.l)
cmp.b #10,d0
bne.s 5$
dumped_hist
move.l d3,nost(a5) nost = now
move.l d3,now(a5)
move.l then(a5),d1
cmp.b #$a,0(a1,d1.l)
bne.s wxv1 BRANCH IF WRAPPED AROUND
cmp.l d3,d1
bne.s finland BRANCH IF THEN = (10) & THEN <> NOW
wxv1
* move.l d3,then(a5) then=now
wxv3 addq.l #1,d3 SEARCH FOR NEXT LF (NEW TOP OF HISTORY)
and.l #HISTORY_SIZE-1,d3 WRAP AROUND
move.b 0(a1,d3.l),d0
cmp.b #$a,d0
bne.s wxv3 ***
wxv2 move.l d3,then(a5) SET NEW THEN (TOP OF HISTORY)
*******
finland
move.l (sp)+,a0
rts
no_cr cmp.b #' ',d6
blo.s dunno_it
cmp.b #'~',d6
bhi.s dunno_it
cmp.w #SHELLINE_SIZE-2,d4 make sure line is not too long
bhi.s dunno_it
lea insert_it(pc),a1
move.b d6,2(a1) shove printable char after insert seq
bsr pr_string insert space for char
lea shelline(a5),a1 ethel
lea 1(a1,d4.w),a0 linmax
lea 1(a0),a2 A2=linmax+1
lea 0(a1,d5.w),a1 linhere
tc_1 move.b -(a0),-(a2) insert char into shelline
cmp.l a0,a1
bne.s tc_1
plop_ch lea shelline(a5),a4
move.b d6,0(a4,d5.w)
addq.l #1,d5
addq.l #1,d4
dunno_it
BRA next_ch
* TRANSLATE FUNC CODE TO F1,F2 ETC AND SET UP POINTERS
translate_func_key
lea gather(a5),a0
move.l gather_ptr(a5),d0
cmp.b #3,d0 CHECK IF TWO CODES EG '12'
beq process_shift_func
unshifted_func_key
cmp.b #2,d0
bne translate_func_fail
move.b (A0),d0
moveq #'f',d1
act_sh bsr convert_to_set_name
bsr search_sets returns D0 pointer to set
bsr print_func_defn
rts
process_shift_func
move.b 1(A0),d0
moveq #'F',d1
bra.s act_sh
translate_func_fail
rts
*d0=set ptr
print_func_defn
tst.l d0
beq do_not_print_func
move.l d0,a1
lea set_defn(a1),a1
print_def lea shelline(a5),a2
bra.s 2$
1$ addq.l #1,d5 copy defn to shelline
2$ move.b (a1)+,0(a2,d5.l)
bne.s 1$
cmp.b #'M',-1(a2,d5.l) check for auto return ^M
bne.s 3$
cmp.b #'^',-2(a2,d5.l)
bne.s 3$
subq.l #2,d5
move.l d5,d4
bsr gimme3 print it
movem.l (sp)+,d0-d1 get rid of last 2 return addresses
bra do_cr do a carriage return
3$ move.l d5,d4 linmax=linhere
bra gimme3 show prompt,new line
do_not_print_func
rts
convert_to_set_name
lea set_search_string(a5),a1
move.b d1,(a1)+
addq.b #1,d0
move.b d0,(a1)+
cmp.b #':',d0
bne not_func10
move.b #'1',-1(a1)
move.b #'0',(a1)+
not_func10
clr.b (a1)
rts
search_sets
* uses set_search_string, EXIT: D0 ptr to the associated set. D1 pts to prior set
* RETURN D0=0 IF NOT FOUND.
movem.l d2-d4/a1-a2,-(sp)
lea set_search_string(a5),a1
move.l a1,d2
lea first_set_defn(a5),a2
move.l a2,d4 NOTE PRIOR SET
move.l (a2),d3
search_next_set
beq 2$
move.l d3,a2
lea set_name(a2),a2 A2=current set name
move.l d2,a1 A1=name to match
bra.s 3$
1$ tst.b d0
beq.s 2$
3$ move.b (a1)+,d0
move.b (a2)+,d1
bsr compD1D0nocase
beq.s 1$
move.l d3,a2
move.l d3,d4
move.l (a2),d3
bra search_next_set
2$ move.l d3,d0
move.l d4,d1
movem.l (sp)+,d2-d4/a1-a2
rts
* DO SCRIPT FILE STUFF ENTRY A0 -> input line
scr_in bsr check_c
bne.s terminate_script
move.l scsize(a5),d0 ;read a line from the script file
add.l scaddr(a5),d0
cmp.l scptr(a5),d0
bgt.s scr_in2
terminate_script
bsr kill_script
bsr pr_prompt
bra type_in2
scr_in2 move.l a0,a2
moveq #0,d0
move.l scptr(a5),a1
1$ move.b (a1)+,(a2)+
addq.l #1,d0
cmp.b #10,(a1)
bne.s 1$
move.b (a1)+,(a2)+ LF
clr.b (a2) 0
move.l a1,scptr(a5)
rts
kill_script
move.l a0,-(sp)
clr.b scflag(a5) clean up if no more lines left
clr.b if_flag(a5) Make sure if structure ends
clr.b goto_flag(a5) Make sure goto is terminated
move.l scaddr(a5),a1
move.l scsize(a5),d0
bsr givemem
move.l (sp)+,a0
rts
** SAME AS compare_strings EXCEPT
** ALLOWS FOR A1 ENDING IN LF
lf_compare_strings
movem.l a0-a1/d0-d1,-(sp)
bra.s 1$
2$ tst.b d0
beq.s 3$ RETURN EQ
1$ move.b (a0)+,d0
move.b (a1)+,d1
bsr compD1D0nocase
beq.s 2$ return NE
tst.b d0
bne.s 3$
cmp.b #10,d1
3$ movem.l (sp)+,a0-a1/d0-d1
rts
** CASE INDEPENDENT STRING COMPARE. COMPARES (A0) TO (A1)
** RETURN EQ IF SAME
compare_strings
movem.l a0-a1/d0-d1,-(sp)
bra.s 1$
2$ tst.b d0
beq.s 3$ RETURN EQ
1$ move.b (a0)+,d0
move.b (a1)+,d1
bsr compD1D0nocase
beq.s 2$ return NE
3$ movem.l (sp)+,a0-a1/d0-d1
rts
* COPY STRING :copys null ending string from A0 to A1, Return with D0=length+1
cp_string movem.l a0-a1,-(sp)
moveq #0,d0
cp_str1 addq.l #1,d0
move.b (a0)+,(a1)+
bne.s cp_str1
movem.l (sp)+,a0-a1
rts
*Get line of text and seperate into up to 6 parameters
get_line bsr clr_parms
lea shelline(a5),a0
tst.b mult_comm_flag(a5) SKIP PROMPT IF SCRIPT OR MULT COMMANDS
bne.s 1$
tst.b scflag(a5)
bne.s 2$
bsr pr_prompt
2$ bsr type_in NOTE HISTORY STUFF ASSUMES SHELLINE HOLDS THE LINE
cmp.b #';',(a0) ;is 1st character a ';'
beq.s 3$
cmp.b #'*',(a0)
beq.s 3$
cmp.b #'#',(a0)
bne.s 1$
3$ move.l (sp)+,d0 ;kill return address
bra chorus ;do next line if comment
1$ bsr handle_mult_comms MAYBE ALTER A0
bsr handle_command_alias
* move.l a0,-(sp) TEST STUFF
* move.l a0,a1
* bsr pr_string
* move.l (sp)+,a0
bsr handle_redirection
gl16 lea parm1(a5),a2 ;do 1st parm seperate to establish CLI residue
bsr get_parm
move.l a0,d7
tst.l d2
beq.s gl3 if no parms at all
tst.b goto_flag(a5) CHECK IF IN GOTO SEARCH MODE
beq.s test_ifs
move.l a0,-(sp)
lea label_tx(pc),a0
bsr lf_compare_strings
bne skipline
move.l (sp)+,a0
test_ifs tst.b if_flag(a5) 0 if if encountered earlier
beq.s no_ifs
tst.b if_condition_flag(a5) 0 if condition TRUE
beq no_ifs
if_false move.l a0,-(sp) push ptr to next
lea else_tx(pc),a0
bsr lf_compare_strings
bne.s try_endif
not.b if_condition_flag(a5) flip condition flag
skipline movem.l (sp)+,d0-d1 get rid of last plus return address
bra chorus
try_endif lea endif_tx(pc),a0
bsr lf_compare_strings
bne.s skipline
clr.b if_flag(a5)
bra.s skipline
no_ifs move.l a1,(a2)+ save address of parm1
lea CLIbuf(a5),a1
bra.s 1$
2$ move.b d0,(a1)+
1$ move.b (a0)+,d0 copy sudoCLIresidue out
cmp.b #10,d0 only look for LF end
bne.s 2$
clr.b (a1) null end the copy
move.l d7,a0
lea endofparms(a5),a4 ;establish end of parms block
gl4 bsr get_parm
tst.l d2
beq.s gl3
move.l a1,(a2)+
cmp.l a2,a4 ;get out if more than 10 parms
bne.s gl4
clr.b (a0) ;make sure parm6 ends in 0
gl3 rts
endifz clr.b if_flag(a5)
moveq #RETURN_OK,d0
rts
elsez not.b if_condition_flag(a5)
moveq #RETURN_OK,d0
rts
*******************************
* GOTO COMMAND *
*******************************
gotoz move.l parm2(a5),d1
bne test_gs
goto_err lea goto_error_tx(pc),a1
bsr pr_string
moveq #RETURN_ERROR,d0
rts
test_gs tst.b scflag(a5) CAN ONLY GOTO FROM WITHIN SCRIPT
beq goto_err
move.l d1,a0
lea dest_label(a5),a1
2$ move.b (a0)+,(a1)+
bne.s 2$
move.l scaddr(a5),scptr(a5) RESET TO START OF SCRIPT
move.b #$ff,goto_flag(a5)
clr.b if_flag(a5) MAKE SURE IF IS TERMINATED
moveq #RETURN_OK,d0
rts
** LABEL COMMAND. DOES NOTHING IF NOT IN GOTO SEARCH MODE
labelz tst.b goto_flag(a5)
bne.s 1$
2$ moveq #RETURN_OK,D0
RTS
1$ move.l parm2(a5),d0
beq 2$
move.l d0,a0
lea dest_label(a5),a1
bsr compare_strings
bne 2$
clr.b goto_flag(a5)
bra 2$
*ENTRY A0=shelline ONLY HANDLES ALIASES OF FIRST KEYWORD.
handle_command_alias
movem.l a1-a4/d0-d2,-(sp)
cmp.b #10,(a0)
beq hca_nothing_typed
move.l a0,a1
lea tempbuf(a5),a3
move.b #10,(a3)
clr.b 1(a3) must be null end string
lea set_search_string(a5),a2 COPY PARM AT A0 TO SEARCH STR
2$ move.b (a1)+,(a2)+
cmp.b #10,(a1)
beq.s 4$ hca_one_parm
cmp.b #$20,(a1)
bne.s 2$
4$ move.b (a1)+,(a3)+ COPY FROM SPACE ONWARDS to tempbuf
bne.s 4$ WHOLE LINE ENDS IN NULL.
hca_one_parm
clr.b (a2) null end search string
hca_find_it
move.l a0,-(sp)
bsr search_sets
move.l (sp)+,a0
tst.l d0
beq hca_nothing_typed
move.l d0,a2
lea set_defn(a2),a2 A2=set defn
lea tempbuf(a5),a3 A3=line after alias
move.l a0,a1 A1=shelline ptr
moveq #7,d0
6$ clr.l -(sp) push down eight times 0=no entry.
dbra d0,6$
5$ move.b (a2)+,d0 handle %1...$1
beq not_much_of_an_alias
cmp.b #$20,d0 skip spaces
beq.s 5$
cmp.b #'%',d0
bne.s no_extra_parms
move.b (a2)+,d0
and.w #$0007,d0 only allow %0 --> %7
1$ move.b (a3)+,d1 find where the next param starts
cmp.b #10,d1
beq.s 3$ if no param then pt A3 to lf again
cmp.b #$20,d1
beq.s 1$
4$ lsl.w #2,d0 x 4
move.l a3,0(a7,d0.w)
subq.l #1,0(a7,d0.w) put address of param on stack
2$ move.b (a3)+,d1 get a3 to pt to next space
cmp.b #10,d1
beq 3$
cmp.b #$20,d1
bne.s 2$
3$ lea -1(a3),a3 a3 ts to space
bra.s 5$ do for more params
get_next_character
move.b (a2)+,d0
no_extra_parms
cmp.b #'$',d0
bne.s 1$
move.b (a2)+,d0 grab number after $
beq.s not_much_of_an_alias
and.w #$0007,d0
lsl.w #2,d0 x 4
move.l 0(a7,d0.w),d1
beq.s get_next_character
move.l d1,a4
2$ move.b (a4)+,(a1)+ copy param N
cmp.b #10,(a4)
beq.s 3$
cmp.b #$20,(a4)
bne.s 2$
3$ bra.s get_next_character
1$ move.b d0,(a1)+ copy DEFN -> SHELLINE
tst.b d0
bne.s get_next_character
lea -1(a1),a1
not_much_of_an_alias
lea 32(sp),sp ** NOTE STACK CHANGE
4$ move.b (a3)+,(a1)+ copy tempbuf onto end
bne.s 4$
clr.b mult_comm_flag(a5)
bsr handle_mult_comms
bsr handle_command_alias
clr.b mult_comm_flag(a5)
bsr handle_mult_comms put LF at end Allow for aliases with ;'s
hca_nothing_typed
movem.l (sp)+,a1-a4/d0-d2
rts
clr_parms movem.l a0-a1,-(sp)
lea parm1(a5),a0
lea endofparms(a5),a1
clr_loop1 clr.l (a0)+
cmp.l a0,a1
bne.s clr_loop1
movem.l (sp)+,a0-a1
rts
* GET PARM line pted to by A0
* LINE MUST END IN LF THEN 0
* returns A1 pointing to the address where the parm starts
* puts a 0 over the space or lf where it ends .A0 pts to next bit on end
* return d2=0 if got all possible commands from line
get_parm moveq #$20,d2 D2=delimiter
get_parm1 move.l a0,a1 ;make sure we can get the address before
move.b (a0)+,d1 ;skip spaces
cmp.b #$20,d1
beq.s get_parm1
cmp.b #$9,d1 skip tabs
beq.s get_parm1
cmp.b #$0a,d1 ;handle idiots who type spaces at end of line
beq.s last_parm
cmp.b #'"',d1 ;handle double quotes
bne.s gp2
lea 1(a1),a1
moveq #'"',d2 SET DELIMITER = "
gp4 move.b (a0)+,d1 ;make sure pts to after quotes d1 is dummy
gp2 move.b (a0)+,d1 ;a0 pts to after the space on exit
cmp.b #$0a,d1
beq.s gp3
cmp.b #'\',d1 allow for \" (nested quotes)
beq.s gp4
cmp.b d2,d1
bne.s gp2
clr.b -1(a0) ;make sure last byte is 0
rts
last_parm clr.b -1(a0)
moveq #0,d2 ;signify the end
rts
gp3 lea -1(a0),a0 if ends in LF then dont null end, catch that next time
rts
close_redirection
tst.b nonstdin(a5)
beq cls_outred
move.l thistask(a5),a0
move.l pr_CIS(a0),d1
move.l stdin(a5),pr_CIS(a0) restore old stdin
move.l stdin(a5),inhandle(a5)
jsr _LVOClose(a6)
clr.b nonstdin(a5)
cls_outred
tst.b nonstdout(a5)
beq cls_nothing
move.l thistask(a5),a0
move.l pr_COS(a0),d1
move.l stdout(a5),pr_COS(a0) restore old stdout
move.l stdout(a5),outhandle(a5)
jsr _LVOClose(a6)
clr.b nonstdout(a5)
cls_nothing
rts
* entry A0 pts to shelline
handle_redirection
movem.l a0-a2/d0,-(sp)
redir_2 move.b (a0)+,d0 CHECK FOR REDIRECTION CHARS < >
cmp.b #$0A,d0
beq redir_fin
cmp.b #'"',d0 HANDLE QUOTES
bne.s 1$
* bsr new_print
2$ move.b (a0)+,d0
cmp.b #10,d0
beq redir_fin
cmp.b #'"',d0
bne.s 2$
1$ cmp.b #$20,d0
bne.s redir_2
move.b (a0),d0 TEST CHAR AFTER SPACE.
cmp.b #'>',d0
beq.s redir_out
cmp.b #'<',d0
bne.s redir_2
redir_in lea nonstdin(a5),a2
move.l #MODE_OLDFILE,d2
bsr redir_open
move.l thistask(a5),a0
move.l d0,pr_CIS(a0) MAKE STDIN DIFFERENT.
move.l d0,inhandle(a5)
move.l a3,a0
bra redir_2 KEEP SEARCHING
redir_out cmp.b #'>',1(a0)
beq.s redir_append
lea nonstdout(a5),a2
move.l #MODE_NEWFILE,d2
bsr redir_open
move.l thistask(a5),a0
move.l d0,pr_COS(a0)
move.l d0,outhandle(a5)
move.l a3,a0
bra redir_2
redir_append
lea nonstdout(a5),a2
move.l #MODE_OLDFILE,d2
bsr redir_open
move.l thistask(a5),a0
move.l d0,pr_COS(a0)
move.l d0,outhandle(a5)
move.l d0,d1
moveq #0,d2 set position
moveq #1,d3 set mode
jsr _LVOSeek(a6)
move.l a3,a0
bra redir_2
redir_fin
movem.l (sp)+,a0-a2/d0
rts
redir_open
lea -1(a0),a3 ALIGN WITH SPACE
bsr copy_redirector
move.l a2,d1
jsr _LVOOpen(a6)
tst.l d0
bne.s redopefin
clr.b (a2)
bra DOSerr
redopefin rts
** ENTRY A0 pts redirection symbol. A2 pts to area to save redirection name
** EXIT A2 area holds null end string and redirection name is deleted from
** shelline
copy_redirector
movem.l a0-a2,-(sp)
move.l a0,a1 SAVE START OF REDIRECTION STRING
move.b (a0)+,d0 BUMP PAST '<' or '>'
cpred3 move.b (a0)+,d0
cmp.b #$20,d0
beq.s cpredsp
cmp.b #$0A,d0
beq.s cpredlf
cmp.b #'>',d0 HANDLE APPEND REDIRECTION PROPERLY
beq.s cpred3
move.b d0,(a2)+ COPY NEWSTDIN/OUT TO NONSTDIN/OUT
bra.s cpred3
cpredlf lea -1(a0),a0
lea -1(a1),a1
cpredsp clr.b (a2)+ A0 should point to after the space or lf
lea shelline+SHELLINE_SIZE(a5),a2
move.l a1,d0
sub.l a0,d0
add.l d0,next_comm_ptr(a5) offset next_comm_ptr
cpred5 move.b (a0)+,(a1)+ delete redirection string from shelline
cmp.l a0,a2
bhi.s cpred5
movem.l (sp)+,a0-a2
rts
** V1.14 multiple commands on command line. Delimit by ';'
* ENTRY A0 pts to shelline, EXIT A0 pts to start of next bit on line.
handle_mult_comms
movem.l a1/d0,-(sp)
tst.b mult_comm_flag(a5)
beq.s 1$
move.l next_comm_ptr(a5),a0
1$ move.l a0,a1
2$ move.b (a1)+,d0
cmp.b #'"',d0 ignore semi-colons between quotes
bne.s 3$
4$ move.b (a1)+,d0
beq.s endofline END OF LINE IS NULL.
cmp.b #10,d0
beq.s fndret
cmp.b #'"',d0
bne.s 4$
3$ cmp.b #';',d0
beq fndsemi
cmp.b #10,d0
bne.s 2$
fndret tst.b (a1) IF NULL FOLLOWS LF THEN AT END OF LINE
bne.s fndsemi
endofline clr.b mult_comm_flag(a5)
movem.l (sp)+,a1/d0
rts
fndsemi move.b #10,-1(a1) REPLACE ; or LF WITH LF
move.l a1,next_comm_ptr(a5)
move.b #1,mult_comm_flag(a5)
movem.l (sp)+,a1/d0
rts
*DOSERRor but Unlock first using D7 as the lock
DOSerrUL move.l d7,d1 ;Assume D7=lock
jsr _LVOUnLock(a6) ;NB the last DOS error may be destroyed
;DON'T PUT ANYTHING HERE
*DOSERRor handler D0=0 on entry
DOSerr jsr _LVOIoErr(a6)
cmp.l #232,d0
bne.s dse1
moveq #0,d0
rts ;Return if ERROR_NO_MORE_ENTRIES
dse1 bsr pr_DOSerr
galactic move.l errorstack(a5),a7 ;restore stack
moveq #RETURN_ERROR,d0
bra com_fail ;reenter shell loop
* ENTRY D0=dos error number
pr_DOSerr lea doserrtx(pc),a1
bsr pr_string
lea doserror_text(pc),a1 v1.21 handle textual errors
bra.s 3$
2$ tst.b (a1)+
bne.s 2$
3$ move.b (a1)+,d1
beq.s 1$
cmp.b d1,d0
bne.s 2$
bsr pr_string
1$ bsr print10
bra pr_lf
* fix up parameters that exist or not
fixpam32 move.l parm3(a5),d0
move.l d0,a1
bne.s fixpam2
lea null(pc),a1
fixpam2 move.l parm2(a5),d0
move.l d0,a0
bne.s fxpam
lea null(pc),a0
fxpam rts
renamez bsr fixpam32
;DON'T PUT ANYThING HERE
*RENAME A0-> oldname A1-> newname
rename move.l a0,d1
move.l a1,d2
jsr _LVORename(a6)
tst.l d0
beq DOSerr
moveq #RETURN_OK,d0
rts
mkdirz lea parm2(a5),a4
1$ move.l (a4)+,d1
beq.s 2$
bsr.s mkdir
bra.s 1$
2$ moveq #RETURN_OK,d0
rts
*MAKEDIR D1-> directory name
mkdir jsr _LVOCreateDir(a6)
tst.l d0
beq DOSerr
move.l d0,d1
jsr _LVOUnLock(a6)
* moveq #0,d0
rts
** CHECK DIRECTORY DESCRIPTION IN (A0) AND CONVERTS INTO DIRNAME[0] AND PUTS
** THE WILD CARD IN WILD_STRING. ALSO SETS WILD_FLAG
handle_wild_dirs
clr.b wild_flag(a5)
bsr check_wild
tst.b d0
bne.s 1$
lea wild_string(a5),a1
bsr split_wild
move.b #1,wild_flag(a5)
1$ rts
deletez lea parm2(a5),a4 v1.21 delete as many as you like.
move.l (a4),a0
bsr check_recurs
tst.b recurs_flag(a5)
beq.s 1$
move.l (a4)+,d1 dummy bump
1$ move.l (a4)+,d1
beq.s del_end
bsr.s delete2
bra.s 1$
del_end moveq #RETURN_OK,d0
rts
;DON'T PUT ANYTING HERE
*DELETE FILE D1-> filename
delete2 clr.w indent_count(a5)
move.l d1,-(sp) ;NOTE D1 is pushed
move.l d1,a0
bsr handle_wild_dirs
bsr fibexam LOCK DIRECTORY OR FILE
tst.l fib_DirEntryType(a5)
bpl.s delete_dir
move.l d7,d1
jsr _LVOUnLock(a6)
move.l (sp)+,d1 ;FIXED V1.05
move.l d1,a1
bsr prindent PRINT NAME OF SINGLE FILE TO GO
bra del1file
delete_dir
moveq #0,d6 ;init cd count
delete_dir2
move.l d7,d1
jsr _LVOCurrentDir(a6) CD to the directory
tst.l d6
bne.s this_is_a_sub_dir
move.l d0,temp2(a5) ;save original directory lock
bra.s dd3 DONT UNLOCK THE ORIGINAL LOCK (YET)
this_is_a_sub_dir
move.l d0,d1 ;unlock old entry dir.
jsr _LVOUnLock(a6)
dd3 bsr check_c
bne del_die_safely
bsr fibexnx
tst.l d0
beq del_dir_finished
tst.b wild_flag(a5)
beq.s ddx500
lea fib_FileName(a5),a0
lea wild_string(a5),a1
bsr wildmatch
tst.b d0
bne.s dd3
ddx500 lea fib_FileName(a5),a0
lea tempbuf(a5),a1
bsr cp_string ;copy filename to tempbuf
move.l fib_DirEntryType(a5),temp1(a5) ;save type
delete_d2 bsr check_c
bne del_die_safely
bsr fibexnx ;get next entry
tst.l d0
beq.s ddx501
tst.b wild_flag(a5)
beq.s ddx501
move.l d0,d4
lea fib_FileName(a5),a0
lea wild_string(a5),a1
bsr wildmatch
tst.b d0
bne.s delete_d2
move.l d4,d0
ddx501 move.l d0,-(sp) push exnext result
lea -84(sp),sp ;alloc 84 bytes on stack
lea fib_FileName(a5),a0
lea 4(sp),a1
bsr cp_string ;copy filename to stack
move.l fib_DirEntryType(a5),(sp)
bsr del_filet DELETE PRIOR ENTRY
move.l (sp),temp1(a5) grab dirtype
lea 4(sp),a0
lea tempbuf(a5),a1
bsr cp_string ;copy stack to temp
lea 84(sp),sp ;dealloc 84 bytes on stack
move.l (sp)+,d0
tst.l d0
beq.s del_dir_finished
bra delete_d2
del_filet lea tempbuf(a5),a1 delete file (in tempbuf) or enter new dir
tst.l temp1(a5)
bmi.s del_print_file
tst.b recurs_flag(a5)
bne.s 1$
rts
1$ lea newcol(pc),a1
bsr pr_string
lea tempbuf(a5),a1
del_print_file
bsr prindent PRINT FILE OR DIR NAME
lea tempbuf(a5),a1
move.l a1,d1
tst.l temp1(a5) ;check dir type
bmi.s dft2
del_new_dir
bsr pr_tab
lea dirtext(pc),a1 PRINT "DIR"
bsr pr_string
bsr pr_lf
addq.w #1,indent_count(a5)
addq.l #1,d6
lea tempbuf(a5),a0 A0=tempbuf
bsr fibexam
lea -80(sp),sp
lea (sp),a1
lea fib_FileName(a5),a0
bsr cp_string ;copy dirname to stack
bra delete_dir2 recurs
dft2 bra del1file
* IF CTRLC CHECKING CALLS HERE IT WELL ONLY BREAK THE DELETION IN THE CURRENT DIR
del_dir_finished
tst.l d6
bne.s not_back_enough
move.l temp2(a5),d1
jsr _LVOCurrentDir(a6)
move.l d0,d1 ;unlock old.
jsr _LVOUnLock(a6)
move.l (sp)+,d1
jsr _LVODeleteFile(a6) ;delete directory name
bra pr_lf
not_back_enough
subq.l #1,d6
subq.w #1,indent_count(a5)
lea backslash(pc),a0
bsr fibexam
move.l d7,d1
jsr _LVOCurrentDir(a6)
move.l d0,d1 ;unlock old.
jsr _LVOUnLock(a6)
lea (sp),a1
move.l a1,d1
jsr _LVODeleteFile(a6) ;delete directory name
lea 80(sp),sp
move.l d7,d0
bsr fibexam2
bra fibexnx
del1file jsr _LVODeleteFile(a6)
tst.l d0
beq.s 1$
lea deletedtx(pc),a1 PRINT "...DELETED"
bsr pr_string
rts
1$ jsr _LVOIoErr(a6) IF FILE IS PROTECTED OR SOMETHING
bsr pr_DOSerr THEN GET OUT TO OLD DIRECTLY LEVEL
del_die_safely
3$ tst.l d6 CLEANLY.
bne.s 2$
move.l temp2(a5),d1
jsr _LVOCurrentDir(a6)
move.l d0,d1 ;unlock old.
jsr _LVOUnLock(a6)
bsr pr_lf
bra galactic GET BACK TO ORIGINAL STACK LEVEL
* AND GET TO MAIN LOOP
2$ subq.l #1,d6
lea backslash(pc),a0
bsr fibexam
move.l d7,d1
jsr _LVOCurrentDir(a6)
move.l d0,d1 ;unlock old.
jsr _LVOUnLock(a6)
bra.s 3$
init_prompt
lea prompt_args_tx(pc),a0
lea prompt_args(a5),a1
init_pr2 move.b (a0)+,(a1)+
bne.s init_pr2
rts
compose_prompt
lea prompt_string(a5),a1
lea newcol(pc),a0
cpro4 move.b (a0)+,(a1)+ copy highlight colour
bne.s cpro4
lea -1(a1),a1
lea prompt_args(a5),a0
cpro3 move.b (a0)+,d0
beq composer3
cmp.b #'\',d0
bne.s 1$
move.b (a0)+,d0
bra.s composer2
1$ cmp.b #'%',d0
bne.s composer2
move.b (a0)+,d0
cmp.b #'p',d0 check if %p
bne.s try_task_num
lea CD_string(a5),a2
cpro2 move.b (a2)+,(a1)+ copy cd_string to prompt_string
bne.s cpro2
lea -1(a1),a1
bra cpro3
try_task_num
cmp.b #'n',d0
bne.s composer2
move.l thistask(a5),a2
move.l pr_TaskNum(a2),d0
add.b #$30,d0
composer2 move.b d0,(a1)+
bra cpro3
composer3 lea oldcol(pc),a0
cpro5 move.b (a0)+,(a1)+
bne.s cpro5
rts
*** PROMPT COMMAND
promptz tst.l parm2(a5)
beq.s promptz2
move.l parm2(a5),a0
lea prompt_args(a5),a1
promptz3 move.b (a0)+,(a1)+
bne.s promptz3
MOVEQ #RETURN_OK,D0
rts
promptz2 lea prompt_args(a5),a1
bsr pr_string
moveq #RETURN_OK,d0
bra pr_lf
*FILL FIB WITH EXAMINE A0-> directory name ,D7=filelock on return
fibexam move.l a0,-(sp)
moveq #ACCESS_READ,d2
fibexam3 move.l a0,d1
jsr _LVOLock(a6)
tst.l d0
beq DOSerr
bsr fibexam2
move.l (sp)+,a0
rts
fibexam2 move.l d0,d7
move.l d0,d1
move.l a5,d2
jsr _LVOExamine(a6)
tst.l d0
beq DOSerrUL
rts
chdirz tst.l parm2(a5)
beq querycd
move.l parm2(a5),a0
;DON'T PUT ANYTHING HERE
*CHANGE DIRECTORY A0-> new current directory
chdir bsr fibexam
tst.l fib_DirEntryType(a5) ;check entry OK
bpl.s cd123
lea cderrtx(pc),a1
bsr pr_string
bsr unlockOK
moveq #RETURN_ERROR,d0
rts
cd123 move.l d7,d1
jsr _LVOCurrentDir(a6)
move.l d0,d1 ;unlock the old directory
jsr _LVOUnLock(a6)
bsr eval_CD ;update cd string
moveq #RETURN_OK,d0
rts
querycd bsr eval_CD
lea CD_string(a5),a0
bsr new_print
moveq #RETURN_OK,d0
bra pr_lf
** Evaluate entire name of current directory and put in CD_string
eval_CD clr.b CD_string(a5)
lea null(pc),a0
move.l a0,d1
moveq #ACCESS_READ,d2
jsr _LVOLock(a6)
tst.l d0
beq.s 1$
move.l d0,a0
add.l a0,a0
add.l a0,a0
move.l fl_Key(a0),cd_block(a5)
move.l fl_Volume(a0),cd_volnode(a5)
lea CD_string(a5),a0
bsr eval_full_path
jsr _LVOUnLock(a6)
1$ rts
** evaluate entire name associated with lock in D0, store string in A0
** Return D1 = last lock to unlock
** Reg usage:a0,d0,d1,d2,a3 (must not use A2)
eval_full_path
lea -88(sp),sp
move.l a0,4(sp) save address of string
move.l d0,(sp) save original lock on stack
move.l d0,d1
move.l a5,d2
jsr _LVOExamine(a6)
move.l 4(sp),a1
lea fib_FileName(a5),a0
evx1 move.b (a0)+,(a1)+ COPY FILENAME TO deststring
bne.s evx1
lea -1(a1),a3
evcd2 move.l (sp),d1 get lock
jsr _LVOParentDir(a6)
tst.l d0
beq.s root_found
move.l (sp),d1
move.l d0,(sp)
jsr _LVOUnLock(a6) unlock last
move.l (sp),d1
move.l a5,d2
jsr _LVOExamine(a6)
lea fib_FileName(a5),a0
lea 8(sp),a1
evx2 move.b (a0)+,(a1)+ stackbuf = filename
bne.s evx2
move.b #'/',-1(a1)
move.l 4(sp),a0
evx3 move.b (a0)+,(a1)+ stackbuf = filename/CD_string
bne.s evx3
move.l 4(sp),a1
lea 8(sp),a0
evx4 move.b (a0)+,d0
move.b d0,(a1)+
cmp.b #'/',d0
bne.s evx4
lea -1(a1),a3
evx5 move.b (a0)+,(a1)+ dest string = stackbuf
bne.s evx5
bra evcd2
root_found
move.l (sp),d1
tst.b (a3)
bne.s root2
clr.b 1(a3)
root2 move.b #':',(a3)
lea 88(sp),sp
rts
*ADDPATH A0-> path A1-> parameter A2-> destination for string
** eg. (A0)='df0:libs',0 (A1)='arp.library',0 (A2)='df0:libs/arp.library',0
addpath movem.l a0-a2,-(sp)
move.b (a0),d0
beq.s addp4
addp1 move.b (a0)+,d0
beq.s addp2
move.b d0,(a2)+
bra.s addp1
addp2 move.b -2(a0),d0
cmp.b #':',d0
beq.s addp4
cmp.b #'/',d0
beq.s addp4
move.b #'/',(a2)+
addp4 move.l a1,a0
move.l a2,a1
bsr cp_string
movem.l (sp)+,a0-a2
rts
* path(a0) + parm1 -> tempbuf
loadmep move.l a4,a1
lea tempbuf(a5),a2 ;use temp buffer
bsr addpath
move.l a2,d1
rts
* Search Resident list for command
* RETURN D0= seglist OR 0 if not found
* A0= addr of node
** Resi list structure -->[ lword link ][ lword seg ptr ][ 32 char name ]
search_res
move.l parm1(a5),a4
search_res2
move.l resi_head(a5),d2
beq.s 4$
1$ move.l a4,a1
move.l d2,a0
move.l d2,d4 D4=addr of current node
move.l (a0)+,d2 get link
move.l (a0)+,d3 get seglist
bsr compare_strings
beq 3$
tst.l d2
bne.s 1$
4$ moveq #0,d0
rts
3$ move.l d3,d0
move.l d4,a0
rts
*Search paths for command
spaths MOVE.L parm1(a5),a4 A4=parm1
spaths2 moveq #-1,d1
bsr changeWindowPtr
move.l a4,d1 ;search current
jsr _LVOLoadSeg(a6)
tst.l d0
bne.s gotit
lea patharea(a5),a0
spa_3 tst.b (a0)
beq.s no_more_paths CHECK IF PATH LIST IS EMPTY
spa_2 move.l a0,d4
bsr loadmep
jsr _LVOLoadSeg(a6)
tst.l d0
bne.s gotit
move.l d4,a0
spa_1 tst.b (a0)+
bne.s spa_1
bra.s spa_3
no_more_paths
moveq #0,d0
gotit moveq #0,d1
bra changeWindowPtr
* ARCHIE 3 calls system0 to execute non internal commands
archie3 tst.l parm1(a5) ;exit if nothing typed
beq noarch31
bsr save_mem
clr.b resi_flag(a5) =0 if resident
bsr search_res search resident list first
tst.l d0
bne.s 1$
addq.b #1,resi_flag(a5) =1 if not resident
bsr spaths ;load the command
tst.l d0
beq noarch32 ;could not load
1$ move.l d0,temp1(a5) ;save the segment
bsr raw_off
bsr save_time
lea CLIbuf(a5),a0
move.l a0,-(sp) ;push arg_args ptr.
move.l d0,-(sp) ;push seglist
move.l parm1(a5),d0
move.l d0,-(sp) ;push arg_name
bsr _System0 TAKES 3 PARMS(ARG_NAME,SEGLIST,ARGS)
lea 12(sp),sp
move.l d0,-(sp)
tst.b resi_flag(a5)
beq.s 2$
move.l better_seglist(pc),d1
jsr _LVOUnLoadSeg(a6)
2$ tst.b stat_mode_flag(a5)
beq.s no_status_disp
bsr show_status
no_status_disp
bsr raw_on
move.l (sp)+,d0 RESULT IN D0
noarch31 rts
noarch32 lea badcomm(pc),a1
moveq #RETURN_ERROR,d0 return d0 bad V1.30
bra pr_string
*SYSTEM0 execute command from disk from Sozobon C distribution.
_System0
movem.l SAVED_REGS,-(sp)
moveq #NO_CLI,REG_Result ;ERROR - not a CLI task
movea.l _AbsExecBase,REG_SysBase
move.l thistask(a5),REG_Process V1.03
move.l pr_CLI(REG_Process),d0
beq quit0
* build local stack frame & save some values
lsl.l #2,d0 ;BPTR to machine pointer
movea.l d0,REG_CLI
movea.l sp,REG_PrevStack ;save old stack pointer
move.l sp,d0
andi.b #$fc,d0 ;make SP longword-aligned for BPTRs
movea.l d0,sp
suba.l #sf_SIZEOF,sp <<<***************
move.l REG_PrevStack,sf_PrevStack(sp)
move.l REG_Process,sf_Process(sp)
move.l REG_CLI,sf_CLI(sp)
move.l pr_ReturnAddr(REG_Process),sf_SaveReturnAddr(sp)
* allocate space for stack
moveq #NO_MEM,REG_Result ;ERROR - no memory for STACK
move.l cli_DefaultStack(REG_CLI),d0 ;in longwords for "VEC"
lsl.l #2,d0
move.l d0,sf_PushSize(sp)
addq.l #4,d0 ;one additional longword
move.l d0,sf_StackSize(sp)
moveq #0,d1 ;intentionally NOT "MEMF_PUBLIC"!
callsys AllocMem
tst.l d0
beq quit1
move.l d0,sf_StackBase(sp) ;save result
* save old command pointer, build new BCPL command name
move.l cli_CommandName(REG_CLI),sf_SaveCommandName(sp)
movea.l ARG_NAME(REG_PrevStack),a0 ;first parameter to "System0()"
lea sf_CommandName+1(sp),a1 ;first char location for BSTR
move.l a1,d0
lsr.l #2,d0 ;will ignore (+1), BPTR as result
move.l d0,cli_CommandName(REG_CLI)
move.w #MAXBSTR,d0
bra.s 2$
1$ move.b d1,(a1)+
2$ move.b (a0)+,d1
dbeq d0,1$
suba.l ARG_NAME(REG_PrevStack),a0 ;subtract original source
move.l a0,d0
subq.l #1,d0 ;terminating null-byte
move.b d0,sf_CommandName(sp) ;to first location in BSTR
* save contents of Current Input Stream
move.l pr_CIS(REG_Process),d0
lsl.l #2,d0
movea.l d0,REG_CIS ;contains APTR to CIS
move.l REG_CIS,sf_CIS(sp)
move.l fh_Buf(REG_CIS),sf_SCB_Buf(sp)
move.l fh_Pos(REG_CIS),sf_SCB_Pos(sp)
move.l fh_End(REG_CIS),sf_SCB_End(sp)
* convert argument to LF-terminated string
movea.l ARG_ARGS(REG_PrevStack),a0 ;third argument to "System0()"
lea sf_CommandArgs(sp),a1 ;first buffer location
move.l a1,d0
lsr.l #2,d0 ;make buffer pointer a BPTR
move.l d0,fh_Buf(REG_CIS)
move.w #MAXBSTR,d0 ;leave some room for terminating LF
bra.s 4$
3$ move.b d1,(a1)+
4$ move.b (a0)+,d1
dbeq d0,3$
move.b #LF,(a1)
suba.l ARG_ARGS(REG_PrevStack),a0 ;subtract first position
move.l a0,d0 ;do NOT subtract, LF need this byte
* setup start/end indices in Stream Control Block
clr.l fh_Pos(REG_CIS)
move.l d0,fh_End(REG_CIS)
* misc setup
clr.l pr_Result2(REG_Process) ;clear secondary result
moveq #0,d0
move.l #SIGBREAKF_CTRL_C,d1
callsys SetSignal ;clear CTRL-C flag
* handle seglist and start address
move.l cli_Module(REG_CLI),sf_SaveModule(sp)
move.l ARG_SEGLIST(REG_PrevStack),d0 ;second argument to "System0()"
move.l d0,cli_Module(REG_CLI)
lsl.l #2,d0
movea.l d0,a3 ;make it a machine pointer in A3
* setup processor registers & C-interface
lea sf_CommandArgs(sp),a0
move.l fh_End(REG_CIS),d0
* setup processor registers, BCPL-interface, stack & return address for "Exit()"
movea.l sf_StackBase(sp),a1 ;BCPL stack, low end
move.l sf_PushSize(sp),d2
lea 4(a1,d2.l),a4 ;must not destroy REG_Process!
move.l sp,-(a4) ;previous stack frame
move.l d2,-(a4) ;stack size in bytes
move.l a4,pr_ReturnAddr(REG_Process)
movea.l a4,sp
movea.l _DOSBase,a4 ;large data memory model!
movem.l dl_A2(a4),a2/a5/a6
* now call the command at its entry point
jsr 4(a3) ;code starts one longword behind segment pointer
move.l d0,REG_Result ;save return code
* get old stackframe & reload old register contents
movea.l 4(sp),sp ;old stack frame
movea.l sf_Process(sp),a0
move.l sf_SaveReturnAddr(sp),pr_ReturnAddr(a0)
movea.l sf_CLI(sp),a0
move.l sf_SaveCommandName(sp),cli_CommandName(a0)
* Next line makes powerpacker programs deallocate memory properly
move.l cli_Module(a0),better_seglist NEW V1.05
move.l sf_SaveModule(sp),cli_Module(a0)
* restore original contents of Current Input Stream
movea.l sf_CIS(sp),a0
lea sf_CommandArgs(sp),a1
move.l a1,d0
lsr.l #2,d0
cmp.l fh_Buf(a0),d0 ;still the same?
bne.s 5$ ;no: don't restore
move.l sf_SCB_Buf(sp),fh_Buf(a0)
5$ move.l sf_SCB_Pos(sp),fh_Pos(a0)
tst.l fh_End(a0) ;end index set?
beq.s 6$ ;no: don't restore
move.l sf_SCB_End(sp),fh_End(a0)
* free temporary stack
6$ movea.l _AbsExecBase,REG_SysBase
movea.l sf_StackBase(sp),a1
move.l sf_StackSize(sp),d0
callsys FreeMem
quit1 movea.l sf_PrevStack(sp),sp ;UNLINK local variables
quit0 move.l REG_Result,d0
movem.l (sp)+,SAVED_REGS
quitx rts
*******************************
* HELP COMMAND *
*******************************
helpmez lea comtext(pc),a4
lea tempbuf(a5),a3
4$ moveq #5,d3
3$ move.l a3,a2
tst.b (a4)
beq help_fin
moveq #12,d2
2$ subq.l #1,d2
move.b (a4)+,(a2)+
bne.s 2$
tst.b -(a2) bump back
1$ move.b #$20,(a2)+
dbra d2,1$
clr.b (a2)
move.l a3,a1
bsr pr_string
dbra d3,3$
bsr pr_lf
bra 4$
help_fin bsr pr_lf
moveq #RETURN_OK,D0
rts
* PRINT A STRING BUT PUT A TAB AFTER IT
showittab bsr pr_string
bra pr_tab
showpath lea patharea(a5),a1
sh_p3 tst.b (a1)
beq.s sh_p1
move.l a1,d4
bsr showittab
move.l d4,a1
sh_p2 tst.b (a1)+
bne.s sh_p2
bra.s sh_p3
sh_p1 moveq #RETURN_OK,d0
bra pr_lf
*PATH COMMAND Assign path or show it.
pathcomz tst.l parm2(a5) ;see whether any parameters
beq.s showpath
move.l parm2(a5),a0
bsr return_dash_option
lea parm2(a5),a0
lea patharea(a5),a1
cmp.b #'A',d0
bne.s pc_x2
1$ tst.b (a1)+
bne.s 1$
tst.b (a1) test if 2 nulls
bne.s 1$
tst.l (a0)+ dummy bump
pc_x2 move.l (a0),a2 go through each additional parameter
tst.l (a0)+
beq.s pc_x3
pc_x1 move.b (a2)+,(a1)+
bne.s pc_x1
bra.s pc_x2
pc_x3 clr.b (a1)
moveq #RETURN_OK,d0
rts
*INFO COMMAND prints out no. of bytes free
infoz moveq #ACCESS_READ,d2
bsr fixpam2
move.l a0,d1
jsr _LVOLock(a6)
tst.l d0
beq DOSerr
move.l d0,-(sp) ;push the lock
move.l d0,d1
move.l a5,d2
jsr _LVOInfo(a6)
tst.l d0
beq DOSerrUL
bsr do_forbid
move.l id_NumBlocks(a5),d0
sub.l id_NumBlocksUsed(a5),d0 ;work out blocks free
moveq #0,d1
hammy subq.l #1,d0 ;work out bytes free
bmi.s johnny
add.l id_BytesPerBlock(a5),d1
bra.s hammy
johnny move.l d1,d7 ;D7= no. of bytes
move.l id_VolumeNode(a5),a0
add.l a0,a0
add.l a0,a0
move.l 40(a0),a0
add.l a0,a0
add.l a0,a0
moveq #0,d0
move.b (a0)+,d0
wilma lea tempbuf(a5),a1
Ifo2 move.b (a0)+,(a1)+
dbra d0,Ifo2
clr.b (a1)
bsr do_permit
move.l d7,-(sp)
pea tempbuf(a5)
lea (a7),a1
lea volytx(pc),a0
bsr new_print
movem.l (sp)+,d0-d1
move.l (sp)+,d7
bra unlockOK
*EXIT FROM ZSHELL TO CLI. IF WE EXIT FROM SCRIPT THEN FREE SCRIPT MEMORY
exitz tst.b scflag(a5)
beq.s byebye
bsr kill_script
byebye move.l (sp)+,d0 ;kill return address on stack
rts
** SPLIT STRING(A0) INTO DIRECTORY PATH AND WILDCARD DESCRIPTION
** NULL END THE PATH, AND MOVE THE WILDCARD TO (A1)
* eg. ram:c/*.info -> ram:c0 + *.info0
split_wild
movem.l a0-a2/d0-d1,-(sp)
move.l a0,d1
sp_w2 move.l a0,a2 a2=temp
sp_w3 move.b (a0)+,d0
beq.s sp_w4
cmp.b #':',d0
beq.s sp_w2 A0= 1 after :
cmp.b #'/',d0
beq.s sp_w2
bra.s sp_w3
sp_w4 cmp.l a2,d1
beq.s sp_mis
cmp.b #':',-1(a2)
bne.s sp_w5
sp_mis move.l a2,d1 SAVE POSITION
sp_w6 move.b (a2)+,(a1)+
bne.s sp_w6
move.l d1,a2
clr.b (a2)
movem.l (sp)+,a0-a2/d0-d1
rts
sp_w5 clr.b -1(a2)
sp_w7 move.b (a2)+,(a1)+
bne.s sp_w7
movem.l (sp)+,a0-a2/d0-d1
rts
** CHECK STRING(A0) IF IT CONTAINS WILDCARD SPECIFIC CHARS
** RETURN D0=0 IF WILDS FOUND
check_wild
move.l a0,-(sp)
chk_w3 move.b (a0)+,d0
beq.s chk_w2
cmp.b #'*',d0
beq.s chk_w4
cmp.b #'~',d0 special not char
beq.s chk_w4
cmp.b #'[',d0
beq.s chk_w4
cmp.b #']',d0
beq.s chk_w4
cmp.b #'?',d0
bne.s chk_w3
chk_w4 moveq #0,d0
move.l (sp)+,a0
rts
chk_w2 moveq #1,d0
move.l (sp)+,a0
rts
* NOTE this wildmatcher only handles cases where the wildcard has one * in it.
** WILDCARD MATCHER. CHECK IF STRING(A0) MATCHES WILDCARD(A1)
** RETURN D0=0 IF MATCH
wildmatch cmp.b #'~',(a1) check for NOT specifier
bne.s wm_1
move.b (a1)+,d0
bsr.s wm_1
subq.l #1,d0 0 --> -1 1 --> 0
rts
wm_1 move.b (a0)+,d0
beq source_fin1
move.b (a1)+,d1
cmp.b #'*',d1
beq.s wild_run
cmp.b #'[',d1 handle character classes
bne.s 1$
2$ move.b (a1)+,d1
beq.s wild_fail
cmp.b #']',d1
beq.s wild_fail
bsr compD1D0nocase
bne.s 2$
3$ move.b (a1)+,d1
beq.s wild_fail
cmp.b #']',d1
bne.s 3$
bra.s wm_1
1$ cmp.b #'?',d1
beq.s wm_1
bsr compD1D0nocase
beq.s wm_1
wild_fail moveq #1,d0
rts
wild_run
wr_3 tst.b (a0)+ GOTO END OF STRING
bne.s wr_3
wr_4 tst.b (a1)+ GOTO END OF WILDCARD
bne.s wr_4
wr_5 move.b -(a1),d0 get tail of wildcard (1st should be null)
move.b -(a0),d1
cmp.b #'*',d0
beq.s source_fin2
cmp.b #']',d0 handle class [xyz]
bne.s 1$
2$ move.b -(a1),d0
cmp.b #'*',d0
beq.s wild_fail
cmp.b #'[',d0
beq.s wild_fail
bsr compD1D0nocase
bne.s 2$
3$ move.b -(a1),d0
beq.s wild_fail should never happen but should leave in
cmp.b #'[',d0
bne.s 3$
bra.s wr_5
1$ cmp.b #'?',d0
beq.s wr_5
bsr compD1D0nocase
beq.s wr_5
bra.s wild_fail
source_fin1
tst.b (a1)
beq.s source_fin2
cmp.b #'*',(a1)
bne.s wild_fail
source_fin2
moveq #0,d0
rts
compD1D0nocase
cmp.b #'a',d1
blo.s D1_OK
cmp.b #'z',d1
bhi.s D1_OK
sub.b #$20,d1
D1_OK cmp.b #'a',d0
blo.s D0_OK
cmp.b #'z',d0
bhi.s D0_OK
sub.b #$20,d0
D0_OK cmp.b d1,d0
rts
fibexnx move.l d7,d1
move.l a5,d2
jmp _LVOExNext(a6)
*WIDE DIRECTORY LISTER
dirwz bsr fixpam2
moveq #1,d0
move.l d0,temp2(a5)
bsr raw_off V0.15
bra.s directory
dirz bsr fixpam2
clr.l temp2(a5) ;clear wide flag
bsr raw_off
;DON'T PUT ANYTHING HERE
*PRINT DIRECTORY A0-> name of directory
directory clr.l temp1(a5) ;init total size
bsr handle_wild_dirs
bsr pr_dir ;print the dir
bsr pr_size ;show total size
moveq #RETURN_OK,d0
rts
pr_dir bsr fibexam
tst.l fib_DirEntryType(a5) ;check entry OK
bpl.s prd20 ;Directory V1.05
lea fib_FileName(a5),a1 V1.05 EXTRAS FOR 'DIR FILENAME'
bsr pr_string ;print filename
lea seq(pc),a1
bsr pr_string ;print some tabs
move.l fib_Size(a5),d0
add.l d0,temp1(a5) ;increase total size
bsr print10 ;print file size
bra unlock ;make sure to unlock
prd20 lea dirof(pc),a1
bsr pr_string
lea fib_FileName(a5),a1
bsr pr_string ;print dircetory's name
bsr pr_lf
prd2
bsr check_c
bne unlock
bsr fibexnx
tst.l d0
beq unlock
tst.b wild_flag(a5)
beq.s zelma
lea fib_FileName(a5),a0
lea wild_string(a5),a1
bsr wildmatch
tst.b d0
bne.s prd2
zelma tst.l fib_DirEntryType(a5) ;check whether is dir
bmi.s paulx ;if plus,is directory
lea newcol(pc),a1 ;change foregnd colour
bsr pr_string
paulx move.l fib_Size(a5),d0
add.l d0,temp1(a5) ;increase total size
lea fib_FileName(a5),a1
paul1 bsr pr_string ;print filename
move.l temp2(a5),d0
beq.s paul5
btst.l #0,d0
bne.s paul5
lea seqwide(pc),a1
bra.s paul17
paul5 lea seq(pc),a1
paul17 bsr pr_string ;print some tabs
tst.l fib_DirEntryType(a5) ;check whether is dir
bmi.s paul2 ;if plus,is directory
lea dirtext(pc),a1 ;print '(dir)'
bsr pr_string
bra.s paul3
paul2 move.l fib_Size(a5),d0
bsr print10 ;print file size
paul3 tst.l temp2(a5) ;are we printing wide
beq.s paul6
addq.l #1,temp2(a5)
move.l temp2(a5),d0
btst.l #0,d0
bne.s paul6
lea widetx(pc),a1
bsr pr_string
bra prd2
paul6 bsr pr_lf ;send return
bra prd2
unlock move.l d7,d1
jsr _LVOUnLock(a6)
move.l temp1(a5),d0
getoutd rts
unlockOK move.l d7,d1
jsr _LVOUnLock(a6)
moveq #RETURN_OK,d0
rts
pr_size lea totfiles(pc),a1
bsr pr_string
bsr print10 ;expects no. in D0
bra pr_lf
*** CHECK CTRL_C
** RETURN NE if ctrl c, EQ if not
check_c movem.l d0-d1/a0-a1/a6,-(sp) checks if CTRL_C pressed
moveq #0,d0
moveq #0,d1
move.l _AbsExecBase,a6
jsr _LVOSetSignal(a6)
btst #SIGBREAKB_CTRL_C,d0
beq.s ck_nostop
moveq #0,d0
moveq #0,d1
bset #SIGBREAKB_CTRL_C,d1
jsr _LVOSetSignal(a6)
move.l dosbase(a5),a6
lea breaktx(pc),a0
bsr new_print
moveq #1,d0 NE: STOP!!!
move.b d0,ctrl_c_flag(a5)
movem.l (sp)+,d0-d1/a0-a1/a6
rts
ck_nostop
clr.b ctrl_c_flag(a5)
moveq #0,d0 EQ: no stop
movem.l (sp)+,d0-d1/a0-a1/a6
rts
*ALLOCATE MEMORY D0=size D1=type
iwantmem movem.l a0-a1/d1,-(sp)
move.l _AbsExecBase,a6
jsr _LVOAllocMem(a6)
move.l dosbase(a5),a6
movem.l (sp)+,a0-a1/d1
rts
*FREEMEM A1=ptr to mem block D0=size
givemem move.l _AbsExecBase,a6
jsr _LVOFreeMem(a6)
move.l dosbase(a5),a6
rts
*REMOVE PATH A0-> source A1->destination
rempath movem.l a0-a2/d0,-(sp)
rempath1 move.l a0,a2
rempath2 move.b (a0)+,d0
cmp.b #'/',d0
beq.s rempath1
cmp.b #':',d0
beq.s rempath1
tst.b d0
bne.s rempath2
move.l a2,a0
bsr cp_string
movem.l (sp)+,a0-a2/d0
rts
** PRINT STRING (A1) USING indent_count(a5) AS A SPACE INDENT COUNT
prindent movem.l d7/a0-a1,-(sp)
move.w indent_count(a5),d7
move.l a1,a0
and.w #$3f,d7
beq.s 1$
bra.s 2$
3$ bsr pr_space print d7 spaces
2$ dbra d7,3$
move.l a0,a1
1$ bsr pr_string
movem.l (sp)+,d7/a0-a1
rts
** ENTRY A0 pts to parameter.
** EXIT D0=lower case char after dash OR 0 if no dash command.
return_dash_option
moveq #0,d0
cmp.b #'-',(a0)
bne.s 2$
1$ move.b 1(a0),d0
cmp.b #'a',d0
blo.s 2$
cmp.b #'z',d0
bhi.s 2$
sub.b #$20,d0
2$ rts
** ENTRY A0 pts to parameter. If it is -r then set recurs_flag, otherwise clr it
check_recurs
move.l d0,-(sp)
clr.b recurs_flag(a5)
bsr return_dash_option
cmp.b #'R',d0
bne.s 1$
move.b #1,recurs_flag(a5)
1$ move.l (sp)+,d0
rts
*THE COPY COMMAND
** V1.23 major alterations to allow recursive file copying
copyz lea parm2(a5),a2
tst.l 4(a2) check if only 2 parameters
beq.s copy_fail
move.l (a2),a0
bsr check_recurs
tst.b recurs_flag(a5)
beq.s 1$
move.l (a2)+,d0 bump the pointer
1$ tst.l 8(a2) CHECK PARM4 IF DOING MULTIPLE FILE COPY
beq.s 2$
4$ move.l (a2)+,a3 multiple files to directory copy
lea -4(a2),a1
3$ move.l (a1)+,d0 search for end
bne.s 3$
move.l -8(a1),a4 grab dest directory
cmp.l a4,a3
beq copy_fin
move.l a2,-(sp)
bsr.s 5$ do one copy
move.l (sp)+,a2
tst.l d0
bne.s copy_fail
bra.s 4$
2$ move.l (a2)+,a3 SOURCE
move.l (a2),a4 DEST
5$ moveq #0,d6
clr.w indent_count(a5)
bsr perform_copy
tst.l d6
bne.s copy_fail
copy_fin moveq #RETURN_OK,D0
rts
copy_fail moveq #RETURN_ERROR,D0
rts
*** SUPPLEMENTARY COPY ROUTINES ***
** ENTRY A2=fib, RETURN D0=address
alloc_file_space
move.l fib_Size(a2),d0
move.l d0,4+cp_filesize(sp)
moveq #0,d1
bsr iwantmem ALLOCATE SPACE FOR FILE
move.l d0,4+cp_fileaddr(sp) save 0 if failure
rts
** ENTRY D1=name, RETURN D0=handle
open_read_file
move.l #MODE_OLDFILE,d2
jsr _LVOOpen(a6) OPEN FILE
move.l d0,4+cp_ropen(sp) save the handle
rts
**ENTRY D0=handle
read_to_mem
move.l d0,d1
move.l 4+cp_fileaddr(sp),d2
move.l 4+cp_filesize(sp),d3
jsr _LVORead(a6) READ FILE returns -1 if error
rts
close_read_file
move.l 4+cp_ropen(sp),d1
jsr _LVOClose(a6) CLOSE FILE
clr.l 4+cp_ropen(sp) null it incase later dos errs
rts
**ENTRY D1=name, RETURN D0=handle
open_write_file
move.l #MODE_NEWFILE,d2
jsr _LVOOpen(a6) OPEN FILE
move.l d0,4+cp_wopen(sp) save the handle
rts
**ENTRY D0=handle
write_from_mem
move.l d0,d1
move.l 4+cp_fileaddr(sp),d2
move.l 4+cp_filesize(sp),d3
jsr _LVOWrite(a6) WRITE FILE returns -1 if error
rts
close_write_file
move.l 4+cp_wopen(sp),d1
jsr _LVOClose(a6) CLOSE FILE
clr.l 4+cp_wopen(sp)
rts
dealloc_file_space
move.l 4+cp_fileaddr(sp),a1
move.l 4+cp_filesize(sp),d0
bsr givemem DEALLOCATE FILE SPACE
clr.l 4+cp_fileaddr(sp)
rts
print_copyOK
lea copyOK(pc),a1
bsr pr_string ;print '...copied'
rts
*STACK STUFF
cp_fibaddr equ 0
cp_srclock equ cp_fibaddr+4
cp_fileaddr equ cp_srclock+4
cp_filesize equ cp_fileaddr+4
cp_ropen equ cp_filesize+4
cp_wopen equ cp_ropen+4
cp_fname equ cp_wopen+4 allow 128 bytes
cp_size equ cp_fname+128
** RECURSIVE STACK FRAME
nth_srcname equ 0
nth_destname equ 128
nth_size equ 256
** ENTRY A3 = source A4 = destination D6=0 no errors yet, NE just exit
** indent_count(a5) is used
perform_copy
tst.l d6
beq.s 1$ exit if D6<>0
rts
1$ lea -cp_size(sp),sp ALLOCATE STACK SPACE
move.l sp,a0
lea cp_fname(sp),a1
2$ clr.b (a0)+ clear all parameters on stack
cmp.l a1,a0
blo.s 2$
move.l a3,a0
bsr handle_wild_dirs
move.l a3,d1
moveq #ACCESS_READ,d2
jsr _LVOLock(a6)
move.l d0,cp_srclock(sp) store 0 if failure
tst.l d0
beq kill_copyDOS
* ALLOCATE FILEINFOBLOCK
move.l #FIB,D0
moveq #0,d1
bsr iwantmem
move.l d0,cp_fibaddr(sp) store 0 if failure ,save fib addr
tst.l d0
beq kill_copy
* EXAMINE SOURCE
move.l cp_srclock(sp),d1
move.l cp_fibaddr(sp),d2
move.l d2,a2 A2=fibaddr
jsr _LVOExamine(a6) EXAMINE SOURCE
tst.l d0
beq kill_copyDOS
lea fib_FileName(a2),a1
* bsr pr_string
tst.l fib_DirEntryType(a2)
bpl next_dir_entry if source is dir then attempt dir to dir
* HANDLE FILE TO FILE or FILE TO DIR
move.l a3,a1
bsr prindent PRINT NAME OF FILE BEING COPIED
move.l cp_fibaddr(sp),a2 reset a2 to fibaddr
bsr alloc_file_space
tst.l d0
beq kill_copy
move.l a3,d1
bsr open_read_file
tst.l d0
beq kill_copyDOS
bsr read_to_mem
tst.l d0
bmi kill_copyDOS
bsr close_read_file
move.l a3,a0
lea cp_fname(sp),a1
bsr rempath REMOVE PATH FROM SRC NAME
move.l a4,d1
moveq #ACCESS_READ,d2
jsr _LVOLock(a6) LOCK DEST
tst.l d0
beq do_file_to_file
move.l d0,d1
move.l d0,d5 D5=lock temporary
move.l cp_fibaddr(sp),d2
move.l d2,a2 A2=fibaddr
jsr _LVOExamine(a6) EXAMINE SOURCE assume does not fail
move.l fib_DirEntryType(a2),d4
move.l d5,d1
jsr _LVOUnLock(a6)
tst.l d4
bmi do_file_to_file
move.l a4,a0 DO ONLY IF FILE TO DIR
lea cp_fname(sp),a1
lea fib_FileName(a2),a2 !!!! USING FIB AS TEMPORARY FOR NEW FNAME
bsr addpath
move.l a2,d1
bra.s go_open
do_file_to_file
move.l a4,d1 destination = new filename
go_open bsr open_write_file
tst.l d0
beq kill_copyDOS
move.l cp_fibaddr(sp),a2 reset a2 to fibaddr
bsr write_from_mem
tst.l d0
bmi kill_copyDOS
bsr close_write_file
bsr dealloc_file_space
bsr print_copyOK
bra exit_cp
** MAIN LOOP FOR DIR TO DIR COPYING STARTS HERE
next_dir_entry
bsr check_c
bne kill_copy
move.l cp_srclock(sp),d1
move.l cp_fibaddr(sp),d2
move.l d2,a2 guarantee a2=fibaddr
jsr _LVOExNext(a6) get next entry
tst.l d0
beq.s exit_cp
tst.b wild_flag(a5)
beq test_if_file
lea fib_FileName(a2),a0
lea wild_string(a5),a1
bsr wildmatch
tst.b d0
bne.s next_dir_entry
bra test_if_file
exit_cp move.l cp_srclock(sp),d1 if no more entries then exit
jsr _LVOUnLock(a6)
move.l cp_fibaddr(sp),a1
move.l #FIB,d0
bsr givemem
lea cp_size(sp),sp
rts EXIT BACK
test_if_file
tst.l fib_DirEntryType(a2)
bpl must_be_dir
move.l a3,a0 *** COPY A FILE ***
lea fib_FileName(a2),a1
lea cp_fname(sp),a2
bsr addpath add src dir path to filename
move.l a2,a1
bsr prindent PRINT NAME OF FILE BEING COPIED
move.l cp_fibaddr(sp),a2 reset a2 to fibaddr
bsr alloc_file_space
tst.l d0
beq kill_copy
lea cp_fname(sp),a0
move.l a0,d1
bsr open_read_file
tst.l d0
beq kill_copyDOS
bsr read_to_mem
tst.l d0
bmi kill_copyDOS
bsr close_read_file
move.l a4,a0 dest name
lea fib_FileName(a2),a1
lea cp_fname(sp),a2
bsr addpath add dest dir path to filename
move.l a2,d1
bsr open_write_file
tst.l d0
beq kill_copyDOS
move.l cp_fibaddr(sp),a2 reset a2 to fibaddr
bsr write_from_mem
tst.l d0
bmi kill_copyDOS
bsr close_write_file
bsr dealloc_file_space
bsr print_copyOK
BRA next_dir_entry
must_be_dir
tst.b recurs_flag(a5)
beq next_dir_entry
lea -nth_size(sp),sp
move.l a4,a0
lea fib_FileName(a2),a1
lea nth_destname(sp),a2 NEW DESTINATION DIRECTORY
bsr addpath add dest dir path to filename
move.l a2,d1
jsr _LVOCreateDir(a6) dont care if error is reported (will be picked up later)
move.l d0,d1
beq.s 1$
jsr _LVOUnLock(a6)
1$ move.l cp_fibaddr+nth_size(sp),a2
move.l a3,a0
lea fib_FileName(a2),a1
lea nth_srcname(sp),a2 NEW SOURCE DIRECTORY
bsr addpath
move.l a2,a1
bsr prindent PRINT NAME OF NEW DIR
bsr pr_lf
addq.w #1,indent_count(a5)
MOVEM.L a3-a4,-(sp) save old source and dest
lea 8+nth_srcname(sp),a3
lea 8+nth_destname(sp),a4
bsr perform_copy RECURSION!!!!
MOVEM.L (SP)+,A3-A4
lea nth_size(sp),sp
subq.w #1,indent_count(a5)
tst.l d6
bne kill_copy
bra next_dir_entry
*** SAFELY HANDLE ERRORS
kill_copyDOS
jsr _LVOIoErr(a6)
bsr pr_DOSerr print error
kill_copy move.l cp_fibaddr(sp),d0
beq.s 1$
move.l d0,a1
move.l #FIB,d0
bsr givemem
1$ move.l cp_srclock(sp),d1
beq.s 2$
jsr _LVOUnLock(a6)
2$ move.l cp_fileaddr(sp),d0
beq.s 3$
move.l d0,a1
move.l cp_filesize(sp),d0
bsr givemem
3$ move.l cp_ropen(sp),d1
beq.s 4$ open return D0=0 if failure
jsr _LVOClose(a6)
4$ move.l cp_wopen(sp),d1
beq.s 5$
jsr _LVOClose(a6)
5$ MOVEQ #1,D6 SET THE ERROR FLAG!!!!!
lea cp_size(sp),sp
rts EXIT BACK
** ENTRY A0=name
** EXIT D0=address, D1=size
readfile movem.l a0/d2-d6,-(sp)
move.l a0,d1
move.l #MODE_OLDFILE,d2
jsr _LVOOpen(a6) OPEN FILE
move.l d0,d4 d4=handle
beq readerr
moveq #1,d3
moveq #0,d2
move.l d4,d1
jsr _LVOSeek(a6)
moveq #-1,d3
moveq #0,d2
move.l d4,d1
jsr _LVOSeek(a6)
move.l d0,d5 d5=size
moveq #0,d1
bsr iwantmem
tst.l d0
beq readerr2
move.l d0,d6 d6=addr
move.l d6,d2
move.l d5,d3
move.l d4,d1
jsr _LVORead(a6)
tst.l d0
bmi readerr3
move.l d4,d1
jsr _LVOClose(a6)
move.l d6,d0
move.l d5,d1
movem.l (sp)+,a0/d2-d6
rts
readerr3 move.l d6,a1
move.l d5,d0
bsr givemem NB won't work correctly if memory fail occurs. Will try to print DOS error for this
readerr2 move.l d4,d1
jsr _LVOClose(a6)
readerr move.l please_close_me(a5),d1 V1.29 Allows for additional
beq.s 1$ file closure. Needed for
jsr _LVOClose(a6) JOIN command
clr.l please_close_me(a5)
1$ bra DOSerr
** MORE TYPE COMMAND
morez tst.l parm2(a5)
bne.s 1$
moveq #RETURN_ERROR,d0
rts
1$ moveq #23,d4
tst.l parm3(a5)
beq 3$
move.l parm3(a5),a1
bsr convert_ASCII_to_num
tst.b d1
beq 3$
cmp.w #20,d0
blo.s 3$
move.l d0,d4
3$ subq.w #1,d4
move.w d4,line_count(a5)
move.l parm2(a5),a0
bsr readfile
move.l d0,-(sp) push address
move.l d1,-(sp) push size
moveq #1,d4
move.l d0,d5 d5=start
move.l d0,a4 a4=ptr
move.l d0,d6
add.l d1,d6 d6=end addr
2$ bsr make_screen
tst.l d4
bne.s 2$
move.l (sp)+,d0
move.l (sp)+,a1
bsr givemem
bsr pr_lf
moveq #RETURN_OK,D0
RTS
make_screen
lea clstx(pc),a1
bsr pr_string
move.w line_count(a5),d1
move.w d1,d2
sub.w #19,d2
move.l a4,-(sp)
bra.s 1$
3$ bsr pr_lf PRINT SCREEN FULL OF LINES
1$ bsr pr_line
2$ cmp.l d6,a4 check against end
beq.s 9$
move.b (a4)+,d0
cmp.b #10,d0
bne.s 2$
cmp.w d2,d1
bne.s 8$
move.l a4,a3 A3 points to end of page marker
8$ dbra d1,3$
9$ move.l a4,d7 D7 points to end
move.l (sp)+,a4
waitabit move.l inhandle(a5),d1
lea tempbytes(a5),a0
move.l a0,d2
moveq #1,d3
jsr _LVORead(a6) wait for space key
moveq #0,d0 ;clear top bytes
move.b tempbytes(a5),d0 ;test byte of input line
cmp.b #'a',d0
blo.s go_upper
sub.b #$20,d0
go_upper cmp.b #13,d0 IS THIS A CARRIAGE RETURN?
bne.s ck_space
lea scroll_up_tx(pc),a1
bsr pr_string SCROLL UP ONE LINE
lea carriage_tx(pc),a1
bsr pr_string SEND CURSOR TO START OF LINE
2$ cmp.l d6,a4 advance one line
beq.s 3$
move.b (a4)+,d0
cmp.b #10,d0
bne.s 2$
3$ cmp.l d6,a3 move a3 down one line too
beq.s 4$
move.b (a3)+,d0
cmp.b #10,d0
bne.s 3$
4$ move.l a4,-(sp)
move.l d7,a4
cmp.l d7,d6
beq.s 1$
bsr pr_line print line from d7
1$ cmp.l d6,a4 advance D7 one line
beq.s 5$
move.b (a4)+,d0
cmp.b #10,d0
bne.s 1$
5$ move.l a4,d7
move.l (sp)+,a4
bra.s waitabit
ck_space cmp.b #32,d0
bne.s ck_top
move.l a3,a4
moveq #1,d4
rts
ck_top cmp.b #'T',d0
bne.s ck_bot
move.l d5,a4
moveq #1,d4
rts
ck_bot cmp.b #'B',d0
bne.s ck_back
move.l d6,a4
bra.s look_back
ck_back cmp.b #8,d0
bne.s unknown_key
look_back move.w #20,d1
6$ cmp.l d5,a4 check against start
beq.s 5$
move.b -(a4),d0
cmp.b #10,d0
bne.s 6$
dbra d1,6$
lea 1(a4),a4
5$ moveq #-1,d4
rts
unknown_key
moveq #0,d4
rts
find_end_of_line
2$ cmp.l d6,a0 check against end
beq.s 1$
move.b (a0)+,d0
cmp.b #10,d0
bne.s 2$
lea -1(a0),a0
1$ rts
** PRINT STRING AT A4 ENDING IN LF
pr_line movem.l d0-d3/a0,-(sp)
move.l a4,d2
move.l outhandle(a5),d1
move.l a4,a0
bsr find_end_of_line
sub.l a4,a0
move.l a0,d3
beq.s 3$ don't print if 0
jsr _LVOWrite(a6)
3$ movem.l (sp)+,d0-d3/a0
rts
** ENTRY D6=end of file A4=current pos
pr_screen bsr check_c
bne type_break
bsr pr_line
bsr pr_lf
2$ cmp.l d6,a4 check against end
beq.s type_break
move.b (a4)+,d0
cmp.b #10,d0
bne.s 2$
bra.s pr_screen
type_break
rts
*Type out ASCII file command
typez tst.l parm2(a5)
bne.s 1$
rts
1$ move.l parm2(a5),a0
bsr readfile
bsr raw_off MAKE SURE YOU CAN PRESS SPACE TO HOLD IT
move.l d0,-(sp) push address
move.l d1,-(sp) push size
move.l d0,a4 a4=ptr
move.l d0,d6
add.l d1,d6 d6=end addr
next_scr bsr pr_screen
bsr raw_on
freef1 move.l (sp)+,d0
move.l (sp)+,a1
bsr givemem
moveq #RETURN_OK,D0
RTS
*EXECUTE SCRIPT FILE COMMAND
xz tst.l parm2(a5)
bne.s xz_oh
rts
xz_oh bsr fixpam2
xz2 bsr readfile ;A0 pts to filename
move.l d1,scsize(a5)
move.l d0,scaddr(a5)
move.l d0,scptr(a5)
move.b #1,scflag(a5) ;make shell think text lines are in memory
move.l (sp)+,d0 ;kill return address
clr.b mult_comm_flag(a5)
bra chorus
echo_parm bsr fixpam2
move.l a0,a1
move.l a0,a2
bra.s 3$
2$ move.b d0,(a2)+
3$ move.b (a0)+,d0
beq.s 1$
cmp.b #'\',d0
bne.s 4$
move.b (a0)+,d0
bra.s 2$
4$ cmp.b #'^',d0
bne.s 2$
move.b (a0)+,d0
and.b #$3f,d0
bra.s 2$
1$ clr.b (a2)+
bsr pr_string
rts
*ECHO COMMAND
echoz bsr echo_parm
bsr pr_lf
moveq #RETURN_OK,d0
rts
** MEM INFO :RETURN 3 LONGWORDS AT A0 -> FREE CHIP,FAST,TOTAL
memory_info
move.l _AbsExecBase,a6
jsr _LVOForbid(a6) ; don't let 'em change while we ask
move.l #MEMF_CHIP,d1 ; ok, check free chip
jsr _LVOAvailMem(a6) ; ask system how much there is
move.l d0,(A0)
move.l #MEMF_FAST,d1 ; check fast mem avail
jsr _LVOAvailMem(a6)
move.l d0,4(a0)
move.l #MEMF_PUBLIC,d1 ; get all available memory
jsr _LVOAvailMem(a6)
move.l d0,8(a0)
jsr _LVOPermit(a6)
move.l dosbase(a5),a6 ;restore dosbase
rts
*AVAIL COMMAND
availz lea -12(sp),sp
lea (a7),a0
bsr memory_info
move.l a0,a1
lea memess(pc),a0
bsr new_print
lea 12(sp),sp
moveq #RETURN_OK,d0
rts
* ALTER WINDOW PTR FOR THIS PROCESS. USE TO DISABLE REQUESTERS POPPING UP.
* ENTRY D1=0 (NORMAL) D1=-1 (SUBNORMAL).
changeWindowPtr
movem.l d1/a0,-(sp)
move.l thistask(a5),a0
move.l d1,pr_WindowPtr(a0)
movem.l (sp)+,d1/a0
rts
get_task
sub.l a1,a1
move.l _AbsExecBase,a6
jsr _LVOFindTask(a6)
move.l d0,thistask(a5) ;save this task address
move.l dosbase(a5),a6 ;restore dosbase
rts
dp_Link EQU $00 ;DosPacket Structure
dp_Port EQU $04
dp_Type EQU $08
dp_Arg1 EQU $14
dp_SIZEOF EQU $30
sp_Msg EQU $00 ;StandardPacket Structure
sp_Pkt EQU $14
sp_SIZEOF EQU $44
LH_TAIL EQU $04
LN_PRED EQU $04
LN_TYPE EQU $08
LN_NAME EQU $0A
NT_MSGPORT EQU 4
MP_FLAGS EQU $0E ;Message Port Structure
MP_SIGBIT EQU $0F ;Signal bit number
MP_SIGTASK EQU $10 ;Task to be signalled
MP_MSGLIST EQU $14 ;Message linked list
MP_SIZE EQU $22
PA_SIGNAL EQU 0 ;PutAction messages
clearArgs
movem.l a0/d0,-(sp)
lea myArg1(a5),a0
moveq #6,d0
1$ clr.l (a0)+
dbra d0,1$
movem.l (sp)+,a0/d0
rts
raw_on
moveq #-1,d6
bra.s raw_switch
raw_off
moveq #0,d6
bra.s raw_switch
nop
*WINDOW TYPE CHANGER
raw_switch
move.l a1,-(sp)
move.l thistask(a5),a1
move.l pr_ConsoleTask(a1),packettask(a5)
bsr clearArgs
move.l #ACTION_SCREEN_MODE,packettype(a5)
move.l d6,myArg1(a5)
bsr sendpacket
move.l (sp)+,a1
rts
** ENTRY Uses myArg1-myArg7, and packettask, packettype
sendpacket
movem.l d0-d1/a0-a3,-(sp)
move.l _AbsExecBase,a6
moveq #MP_SIZE+sp_SIZEOF+1,d0
lea myport,a2
move.l a2,a0
1$ clr.b (a0)+ clear bss section
dbra d0,1$
moveq #-1,d0
jsr _LVOAllocSignal(a6)
move.b d0,MP_SIGBIT(a2)
bmi.s creaporte -> no sigbit
move.l thistask(a5),MP_SIGTASK(a2)
move.b #NT_MSGPORT,LN_TYPE(a2)
move.b #PA_SIGNAL,MP_FLAGS(a2)
lea MP_MSGLIST(a2),a0
*newlist
move.l a0,(a0)
addq.l #LH_TAIL,(a0)
clr.l LH_TAIL(a0)
move.l a0,(LH_TAIL+LN_PRED)(a0)
packetstuff
lea mypacket,a3 A3=packet
lea dp_Arg1+sp_Pkt(a3),a0
lea myArg1(a5),a1
moveq #6,d0
1$ move.l (a1)+,(a0)+
dbra d0,1$
* move.l d6,dp_Arg1+sp_Pkt(a3) 1
* move.l thistask(a5),a1
* move.l pr_ConsoleTask(a1),d6 D6=pid
lea sp_Msg(a3),a1
move.l a1,sp_Pkt(a3) 2
lea sp_Pkt(a3),a1
move.l a1,LN_NAME(a3) 3
move.l a2,dp_Port+sp_Pkt(a3) 4
move.l packettype(a5),dp_Type+sp_Pkt(a3)
* move.l #994,dp_Type+sp_Pkt(a3) 5
* move.l d6,a0
move.l packettask(a5),a0
move.l a3,a1
jsr _LVOPutMsg(a6) EXEC
move.l a2,a0
jsr _LVOWaitPort(a6) EXEC
move.l a2,a0
jsr _LVOGetMsg(a6) EXEC
delportnpacket
moveq #0,d0
move.b MP_SIGBIT(a2),d0
bmi.s creaporte -> no sigbit to free
jsr _LVOFreeSignal(a6)
creaporte move.l dosbase(a5),a6 ;restore dosbase
movem.l (sp)+,d0-d1/a0-a3
rts
*****************************************
* RELABEL COMMAND *
*****************************************
relabelz tst.l parm3(a5)
bne.s 2$
5$ moveq #RETURN_ERROR,D0
rts
2$ move.l parm2(a5),a0
bsr check_for_colon
beq.s 4$
lea no_colon_tx(pc),a1
bsr pr_string
bra 5$
4$ move.l parm2(a5),d1 PARM2=DF0: etc
jsr _LVODeviceProc(a6)
tst.l d0
beq DOSerr
move.l d0,packettask(a5)
move.l #256,d0
moveq #0,d1
bsr iwantmem ASSUME GETS 256 BYTES
move.l d0,a2 A2=destination
lsr.l #2,d0
bsr clearArgs
move.l d0,myArg1(a5) BPTR to my string
move.l parm3(a5),a0 NewName
lea 1(a2),a1 A1=after count
moveq #0,d0
1$ move.b (a0)+,(a1)+
addq.l #1,d0
cmp.b #':',(a0) ALLOW FOR IDIOTS WHO PUT : ON END
beq.s 3$
tst.b (a0)
bne.s 1$
3$ move.b d0,(a2)
move.l #ACTION_RENAME_DISK,packettype(a5) TYPE=RENAME_DISK
bsr sendpacket
move.l a2,a1
move.l #256,d0
bsr givemem
bsr changedisk
* bsr eval_CD -IS MORE ELEGANT IF I LEAVE OUT.
moveq #RETURN_OK,d0 USER WILL HAVE TO TYPE CD TO CHANGE
rts PROPER.
** USes task in packettask
changedisk
bsr clearArgs
move.l #ACTION_INHIBIT,packettype(a5)
move.l #1,myArg1(a5)
bsr sendpacket
clr.l myArg1(a5)
bsr sendpacket
rts
*****************************************
* ADDBUFFERS COMMAND *
*****************************************
addbuffersz
tst.l parm3(a5)
bne.s 1$
moveq #RETURN_ERROR,d0
rts
1$ bsr clearArgs
move.l parm3(a5),a1
bsr convert_ASCII_to_num
tst.b d1
beq bad_number_error
cmp.l #32767,d0
bhi bad_number_error
move.l d0,myArg1(a5)
move.l parm2(a5),d1 PARM2=DF0: etc
jsr _LVODeviceProc(a6)
tst.l d0
beq DOSerr
move.l d0,packettask(a5)
move.l #ACTION_MORE_CACHE,packettype(A5)
bsr sendpacket
moveq #RETURN_OK,d0
rts
*****************************************
* VERSION COMMAND *
*****************************************
versionz lea hello(pc),a1
moveq #RETURN_OK,d0
bra pr_string
*****************************************
* UNSET VARIABLE COMMAND *
*****************************************
unsetz lea parm2(a5),a3
1$ tst.l (a3)
beq no_more_unsets
move.l (a3)+,a0
bsr check_if_set_already_there
tst.l d0
beq unset_failure
move.l d0,a1
move.l (a1),d2 GRAB NEXT SET POINTER
move.l set_size(a1),d0
move.l d1,a0 D1=prior set
move.l d2,(a0) SKIP OVER SET TO DELETE
bsr givemem
bra 1$
no_more_unsets
moveq #RETURN_OK,d0
rts
unset_failure
lea set_search_string(a5),a1
bsr pr_string
lea bad_unset_tx(pc),a1
bsr pr_string
moveq #RETURN_ERROR,d0
rts
*****************************************
* SET VARIABLE KEY COMMAND *
*****************************************
set_funcz tst.l parm2(a5) SEE IF ANY PARAMETERS TYPED
beq show_current_sets
bsr fixpam32 A0=parm2 A1=parm3
bsr check_if_set_already_there
tst.l d0
beq create_new_set
bra update_old_set
create_new_set
bsr allocate_temp_space GET BIG BLOCK
tst.l d0
beq.s end_set_func
bsr copy_func_defn_to_space
move.l a1,d4 D4=after end
sub.l a3,a1 WORK OUT HOW BIG IS ACTUALLY
move.l a1,d0
moveq #0,d1
bsr iwantmem allocate block big enough for everything
tst.l d0
beq.s 1$
move.l d0,a2
move.l a1,set_size(a2)
bsr insert_new_set
lea set_name(a2),a1 new block
lea set_name(a3),a0 temp block
2$ move.b (a0)+,(a1)+
cmp.l a0,d4
bne.s 2$
1$ move.l a3,a1
move.l #temp_set_size,d0
bsr givemem
end_set_func
moveq #RETURN_OK,d0
rts
check_if_set_already_there
* A0= set name
movem.l a0-a1,-(sp)
lea set_search_string(a5),a1
bsr cp_string
bsr search_sets
movem.l (sp)+,a0-a1
rts
update_old_set
* first delete old one
movem.l a0-a1,-(sp)
move.l d0,a1
move.l (a1),d2 GRAB NEXT SET POINTER
move.l set_size(a1),d0
move.l d1,a0 D1=prior set
move.l d2,(a0) SKIP OVER SET TO DELETE
bsr givemem
movem.l (sp)+,a0-a1
* and replace with new set
bra create_new_set
temp_set_size equ SHELLINE_SIZE+$60
allocate_temp_space
move.l #temp_set_size,d0
moveq #0,d1
bra iwantmem
deallocate_sets
move.l first_set_defn(a5),d3
beq no_sets_to_lose
lose_next_set
move.l d3,a1
move.l (a1),-(sp)
move.l set_size(a1),d0
bsr givemem
move.l (sp)+,d3
bne lose_next_set
no_sets_to_lose
rts
insert_new_set
move.l a3,-(sp)
move.l d0,a3 A3=new space
move.l first_set_defn(a5),d1
move.l d1,(a3) new pts to old
move.l a3,first_set_defn(a5)
move.l (sp)+,a3
rts
set_size equ 4
set_name equ 8
set_defn equ 24
** ENTRY D0=space, A0=name, A1=defn
** EXIT A1=after zero in dest, A3=space
copy_func_defn_to_space
move.l d0,a3
move.l a1,-(sp)
lea set_name(a3),a1
bsr cp_string COPY SET NAME TO SPACE
move.l (sp)+,a0
lea set_defn(a3),a1
bra cp_string_special COPY SET DEFN TO SPACE
* THIS STRING COPY COPYS A0->A1 BUT CONVERTS ALL \n to n
* RETURN A0 = after zero in src, A1 = after zero in dest
cp_string_special
move.l d0,-(sp)
bra.s 2$
1$ cmp.b #'\',d0
beq.s 2$
move.b d0,(a1)+
2$ move.b (a0)+,d0
bne.s 1$
move.b d0,(a1)+
move.l (sp)+,d0
rts
show_current_sets
move.l first_set_defn(a5),d0
beq no_sets_to_show
show_next_set
move.l d0,a3
lea set_name(a3),a1
bsr pr_string
bsr pr_tab
lea set_defn(a3),a1
bsr pr_string
bsr pr_lf
move.l (a3),d0 CHECK NEXT SET ADDRESS
bne show_next_set
no_sets_to_show
moveq #RETURN_OK,d0
rts
*****************************************
* RESIDENT COMMAND *
*****************************************
residentz move.l parm2(a5),d0 SEE IF ANY PARAMETERS TYPED
beq show_current_residents
lea parm2(a5),a3
next_resi move.l (a3)+,d0
beq resi_no_more
move.l d0,a4 A4=parmN
make_resi bsr spaths2 SEARCH PATHS FOR THE COMMAND!
tst.l d0
beq resi_not_found
move.l d0,-(sp) push seglist
move.l a4,a0
move.l a4,a1
bsr rempath SRC = DEST is OK
bsr search_res2 find if same name is on resi list
move.l (sp)+,d3
tst.l d0
beq create_new_resident
move.l d0,d1
move.l d3,resi_seglist(a0) new seglist
jsr _LVOUnLoadSeg(a6) Unload old one with same name
bra.s next_resi
create_new_resident
bsr allocate_resi_space
tst.l d0 D0=addr of resi_list_node
beq resi_no_mem
bsr insert_new_resi
bra.s next_resi
resi_no_more
moveq #RETURN_OK,d0
rts
resi_not_found
lea resi_not_found_tx(pc),a1
bsr pr_string
resi_error
moveq #RETURN_ERROR,d0
rts
resi_no_mem
lea resi_no_mem_tx(pc),a1
bsr pr_string
bra resi_error
insert_new_resi
move.l d0,a1
move.l resi_head(a5),d1
move.l d1,(a1) new pts to old
move.l a1,resi_head(a5)
move.l d3,resi_seglist(a1)
lea resi_name(a1),a1
move.l a4,a0
bsr cp_string
rts
deallocate_residents
move.l resi_head(a5),d3
beq no_resis_to_lose
1$ move.l d3,a1
move.l (a1),-(sp)
move.l resi_seglist(a1),d4 get seglist
move.l #resi_list_length,d0
bsr givemem
move.l d4,d1
jsr _LVOUnLoadSeg(a6)
move.l (sp)+,d3
bne 1$
no_resis_to_lose
rts
show_current_residents
move.l resi_head(a5),d0
beq no_resis_to_show
1$ move.l d0,a3
lea resi_name(a3),a1
bsr showittab
move.l (a3),d0 CHECK NEXT SET ADDRESS
bne 1$
bsr pr_lf
no_resis_to_show
moveq #RETURN_OK,d0
rts
resi_list_length equ 4+4+32
resi_link equ 0
resi_seglist equ 4
resi_name equ 8
allocate_resi_space
move.l #resi_list_length,d0
moveq #0,d1
bra iwantmem
*****************************************
* SET PROTECTION COMMAND *
*****************************************
setprotz bsr fixpam32
tst.b (a1)
beq check_existing_protection
bsr get_protection_bits
bsr alter_protection_bits
moveq #RETURN_OK,d0
rts
alter_protection_bits
* A1-> rwed etc. A2-> prot table A0-> filename D3=old prot bits.
lea prot_bits_table(pc),a2
tst.b (a1)
beq set_the_protection
apb_loop move.b (a2)+,d1 get letter from table
bne.s 1$
lea bad_prot_bits_tx(pc),a1
bsr pr_string
moveq #RETURN_ERROR,D0
RTS
1$ move.b (a2)+,d2 get code from table
move.b (a1),d0
bsr compD1D0nocase
bne.s apb_loop
eor.b d2,d3
move.b (a1)+,d1 dummy,bump ptr
bra alter_protection_bits
set_the_protection
move.l d3,d2
move.l a0,d1
jmp _LVOSetProtection(a6)
check_existing_protection
bsr get_protection_bits
bsr translate_prot_bits
moveq #RETURN_OK,d0
rts
get_protection_bits
movem.l a0-a1,-(sp)
bsr fibexam
move.l fib_Protection(a5),d3
bsr unlock
movem.l (sp)+,a0-a1
rts
translate_prot_bits
lea prot_bits_table(pc),a2
lea tempbuf(a5),a3
eor.b #$0F,d3
check_next_bit
move.b (a2)+,d0 get letter
beq exhausted_bits
move.b #'-',(a3)+
move.l d3,d2 get protection bits
and.b (a2)+,d2
beq check_next_bit
move.b d0,-1(a3)
bra check_next_bit
exhausted_bits
move.b #10,(a3)+
clr.b (a3)
* bsr pr_tab
lea fib_FileName(a5),a1
bsr pr_string
bsr pr_tab
lea tempbuf(a5),a1
bra pr_string
prot_bits_table
dc.b 'h',$80
dc.b 's',$40
dc.b 'p',$20
dc.b 'a',$10
dc.b 'r',$08
dc.b 'w',$04
dc.b 'e',$02
dc.b 'd',$01
dc.w 0
*****************************************
* RPN CALCULATOR COMMAND *
*****************************************
rpnz lea parm2(a5),a4
move.l a7,d5 remember the stack ptr
rpn_loop1 move.l (a4)+,d1
beq show_rpn_result
lea endofparms(a5),a1
cmp.l a1,a4
bhi show_rpn_result
move.l d1,a1
lea 8(sp),a0
cmp.l a0,d5
blo not_poke32
cmp.b #'+',(a1)
bne.s not_add
move.l (sp)+,d0 DO ADD
add.l d0,(sp)
bra rpn_loop1
not_add cmp.b #'-',(a1)
bne.s not_sub
move.l (sp)+,d0
sub.l d0,(sp)
bra rpn_loop1
not_sub cmp.b #'*',(a1)
bne.s not_mult
move.l (sp)+,d0 last DO MULT
move.l (sp)+,d1 2nd last
bsr mult_32x32
move.l d0,-(sp)
bra rpn_loop1
not_mult cmp.b #'/',(a1)
bne.s not_div
move.l (sp)+,d1 last DO DIVIDE
move.l (sp)+,d0 2nd last
tst.l d1
beq rpn_error NO DIVIDE BY ZERO
bsr div_32
move.l d0,-(sp)
bra rpn_loop1
not_div cmp.b #'&',(a1)
bne.s not_and
move.l (sp)+,d0
and.l d0,(sp)
bra rpn_loop1
not_and cmp.b #'|',(a1)
bne.s not_or
move.l (sp)+,d0
or.l d0,(sp)
bra rpn_loop1
not_or cmp.b #'!',(a1)
bne.s not_poke32
move.l (sp)+,d0 GET ADDR DO POKE 32
move.l (sp)+,d1 GET VALUE
and.b #$fe,d0
move.l d0,a0
move.l d1,(a0)
bra rpn_loop1
not_poke32
cmp.b #'@',(a1)
bne.s not_peek32
move.l (sp)+,d0 ADDR DO PEEK 32
cmp.l a7,d5
blo rpn_error
and.b #$fe,d0
move.l d0,a0
move.l (a0),-(sp)
bra rpn_loop1
not_peek32
bsr convert_ASCII_to_num
tst.b d1
beq rpn_error
move.l d0,-(sp)
bra rpn_loop1
rpn_error move.l d5,a7
rts
show_rpn_result
move.l (sp),-(sp)
lea (a7),a1
lea rpn_result_tx(pc),a0
bsr new_print
move.l d5,a7
moveq #RETURN_OK,d0
rts
div_32 movem.l d2-d4,-(sp)
moveq #0,d2
moveq #31,d4
_divu1 roxl.l #1,d0 ; divident
roxl.l #1,d2 ; work accum
cmp.l d1,d2 ; cmp with divisor
blo.s _divu2
sub.l d1,d2
ori #16,ccr ;setx
_divu2 roxl.l #1,d3 ; result
dbf d4,_divu1
move.l d3,d0
move.l d2,d1
movem.l (sp)+,d2-d4
rts
mult_32x32
* D1 = 32 bit, D0 = 32 bit (result)
movem.l d1-d3,-(sp)
move.l d0,d2
move.l d0,d3
mulu d1,d0 save intermediate result
swap d3
mulu d1,d3
swap d3
clr.w d3
add.l d3,d0
swap d1
mulu d1,d2
swap d2
clr.w d2
add.l d2,d0
movem.l (sp)+,d1-d3
rts
* Convert null ending ASCII number(A1) to 32bit number in D0
* REturn D1=0 if bad number
convert_ASCII_to_num
moveq #0,d0 RESET RESULT
moveq #10,d1 SET THE BASE
cmp.b #'$',(a1)
bne.s other_base
move.b (a1)+,d2 DUMMY BUMP
moveq #16,d1 SET RADIX16
bra same_base
other_base
cmp.b #'%',(a1)
bne.s same_base
move.b (a1)+,d2
moveq #2,d1 SET RADIX2
same_base moveq #0,d2
move.b (a1)+,d2
beq conversion_finished
bsr convert_D2_to_num
bsr mult_32x32
add.l d2,d0
bra same_base
conversion_finished
rts
convert_D2_to_num
cmp.b #'0',d2
blo.s bad_number
cmp.b #'9',d2
bhi.s check_hex
sub.b #'0',d2
rts
check_hex cmp.b #16,d1
bne.s bad_number
cmp.b #'f',d2
bhi.s bad_number
cmp.b #'A',d2
blo.s bad_number
cmp.b #'F',d2
bhi.s check_upper_hex
sub.b #55,d2
rts
check_upper_hex
cmp.b #'a',d2
blo.s bad_number
sub.b #87,d2
rts
bad_number
moveq #0,d1 FLAG ERROR thru silly base
rts
*****************************************
* MEMORY EXAMINE COMMAND *
*****************************************
memexamz clr.l mem_offset_addr(a5)
moveq #0,d7
tst.l parm2(a5) CHECK IF NO ADDRESS.
bne.s 5$
moveq #20,d7
bra show_mempage
5$ bsr fixpam32
tst.b (a1)
beq.s 1$
move.l a0,-(sp)
bsr convert_ASCII_to_num convert 2nd num
move.l (sp)+,a0
tst.b d1
beq bad_number_error
move.l d0,d7 D7=2nd num
1$ move.l a0,a1
bsr convert_ASCII_to_num convert 1st num
tst.b d1
beq bad_number_error
3$ tst.l d7
bne.s 4$
moveq #20,d7
bra.s memex2
4$ sub.l d0,d7
lsr.l #4,d7
addq.l #1,d7
memex2 move.l d0,mem_addr(a5)
show_mempage
and.b #$fe,mem_addr+3(a5) MAKE SURE EVEN ADDRESS
* moveq #19,d7 D7=count
shmem2 bsr check_c
bne 1$
bsr show_16_locs
subq.l #1,d7
bne.s shmem2
1$ moveq #RETURN_OK,d0
rts
show_16_locs
move.l mem_addr(a5),a1
lea CLIbuf(a5),a3
move.l a3,a0
moveq #15,d0
sh_16_1 move.b (a1)+,d1
move.b #'.',(a0)+
move.b d1,d2
bclr #7,d2
cmp.b #' ',d2
blo.s sh_16_2
move.b d1,-1(a0)
sh_16_2 dbra d0,sh_16_1
clr.b (a0)
move.l a3,-(sp) PUSH STRING ADDR
move.l -(a1),-(sp) PUSH LAST BYTES
move.l -(a1),-(sp)
move.l -(a1),-(sp)
move.l -(a1),-(sp) PUSH FIRST BYTES
move.l mem_addr(a5),d0
sub.l mem_offset_addr(a5),d0
move.l d0,-(sp)
lea mem_line(pc),a0
lea (sp),a1
bsr new_print
movem.l (sp)+,d0-d5 DUMMY
add.l #16,mem_addr(a5)
rts
* ENTRY A0=FORMATSTRING A1=DATASTREAM.
new_print
movem.l d0-d7/a0-a6,-(sp)
lea -200(sp),sp
move.l sp,a3
lea KPutChar(pc),a2
clr.l char_count
move.l _AbsExecBase,a6
jsr _LVORawDoFmt(a6)
move.l dosbase(a5),a6
move.l outhandle(a5),d1
lea (sp),a0
move.l a0,d2
move.l char_count,d3
subq.l #1,d3
jsr _LVOWrite(a6)
lea 200(sp),sp
movem.l (sp)+,d0-d7/a0-a6
rts
KPutChar move.b d0,(a3)+
addq.l #1,char_count
rts
resetz move.l (4).w,a6
clr.l $0026(A6)
move.l #$00FC00D2,$0080
trap #$00
eb_CoolCapture equ 46
eb_ColdCapture equ 42
eb_WarmCapture equ 50
eb_KickMemPtr equ 546
eb_KickTagPtr equ 550
eb_KickCheckSum equ 554
vecz move.l _AbsExecBase,a0
move.l eb_KickCheckSum(a0),-(sp)
move.l eb_KickMemPtr(a0),-(sp)
move.l eb_KickTagPtr(a0),-(sp)
move.l eb_ColdCapture(a0),-(sp)
move.l eb_CoolCapture(a0),-(sp)
move.l eb_WarmCapture(a0),-(sp)
lea (a7),a1
lea vec_line(pc),a0
bsr new_print
movem.l (sp)+,d0-d5 get rid of trash
moveq #RETURN_OK,d0
rts
** SAVE STATS store current time in date mark, and current memory use in mem mark
save_time
movem.l a0/d0-d1,-(sp)
lea date_mark(a5),a0
bsr get_time
movem.l (sp)+,a0/d0-d1
rts
save_mem movem.l a0/d0-d1,-(sp)
lea mem_mark(a5),a0
bsr memory_info
movem.l (sp)+,a0/d0-d1
rts
** DISPLAY TIME ELAPSED SINCE LAST CALL TO SAVE TIME AND
** ALSO CHANGE IN MEMORY AVAILABLE. EXPECTS RETURN CODE TO BE ABOVE RETURN
** ADDRESS ON STACK ie 4(sp)
show_status
move.l 4(sp),d0
lea -28(sp),sp
lea (a7),a0 A0=time area
move.l d0,(a0)+
bsr get_time
lea date_mark(a5),a1
move.l ds_Tick(a0),d0
sub.l ds_Tick(a1),d0
bpl.s no_tick_carry
add.l #3000,d0
subq.l #1,ds_Minute(a0)
no_tick_carry
move.l d0,ds_Tick(a1) store in datemark
move.l ds_Minute(a0),d0
sub.l ds_Minute(a1),d0
move.l d0,ds_Minute(a1)
bsr convert_time A0=4 words of time
do_mem_deltas
lea 8(a0),a0
bsr memory_info
lea mem_mark(a5),a1
move.l (a1),d0
sub.l d0,(a0) subtract old from new
move.l 4(a1),d0
sub.l d0,4(a0)
move.l 8(a1),d0
sub.l d0,8(a0)
lea -12(a0),a1
lea stat_text(pc),a0
bsr new_print
lea 28(sp),sp
rts
* TIME command
timez lea date_mark(a5),a2
move.l a2,a0
bsr get_time
move.l a2,a1
lea -8(sp),sp
lea (a7),a0
bsr convert_time
lea (a7),a1
lea time_text(pc),a0
bsr new_print
lea 8(sp),sp
moveq #RETURN_OK,d0
rts
** GET TIME STORE DAYS,MINUTES,TICKS AT A0
get_time move.l a0,-(sp)
move.l a0,d1
jsr _LVODateStamp(a6)
move.l (sp)+,a0
rts
** ENTRY A0 pts to 4 words of storage, A1 pts to date stamp
** send time to A0 --> 7(A0)
convert_time
move.l ds_Tick(a1),d0
divu #50,d0
move.w d0,4(a0) seconds
swap d0
asl.w #1,d0
move.w d0,6(a0) hundredths
move.l ds_Minute(a1),d0
divu #60,d0
move.w d0,(a0) hours
swap d0
move.w d0,2(a0) minutes
rts
** STATUS COMMAND ALLOWS DIS/ENABLING OF STATUS DISPLAY
statusz tst.l parm2(a5)
beq.s help_status
move.l parm2(a5),a0
clr.b stat_mode_flag(a5) =00
bsr return_dash_option
cmp.b #'Y',d0
bne.s say_OK
stat_yes not.b stat_mode_flag(a5) =FF
say_OK lea OK_text(pc),a0
bsr new_print
moveq #RETURN_OK,d0
rts
help_status
lea status_help_text(pc),a0
bsr new_print
moveq #RETURN_OK,d0
rts
** STACK COMMAND
stackz move.l thistask(a5),a0
move.l pr_CLI(a0),a4
add.l a4,a4
add.l a4,a4 A4=cli ptr
move.l cli_DefaultStack(a4),d7
asl.l #2,d7
tst.l parm2(a5)
beq.s show_stack
move.l parm2(a5),a1
bsr convert_ASCII_to_num
tst.b d1
beq bad_number_error
stk_num_OK
move.l d0,d6
cmpi.l #1600,d6
blt.s stoosmall
move.l d6,d0
moveq #1,d1
bsr iwantmem
tst.l d0
beq.s stoobig
move.l d0,a1
move.l d6,d0
bsr givemem
asr.l #2,d6
move.l d6,cli_DefaultStack(a4)
moveq #RETURN_OK,d0
rts
stoosmall lea stk_too_small_tx(pc),a0
moveq #RETURN_ERROR,d0
bra new_print
stoobig lea stk_too_big_tx(pc),a0
moveq #RETURN_ERROR,d0
bra new_print
show_stack
move.l d7,-(a7)
lea (a7),a1
lea stk_size_tx(pc),a0
bsr new_print
move.l (a7)+,d0
moveq #RETURN_OK,d0
rts
** CHECK STRING A0 IF ENDING IN :
** RETURN EQ IF DOES END IN COLON
check_for_colon
1$ tst.b (a0)+ MAKE SURE ENDS IN :
bne.s 1$
move.b -2(a0),d0
cmp.b #':',d0
rts
do_forbid move.l _AbsExecBase,a6
jsr _LVOForbid(a6)
move.l dosbase(a5),a6
rts
do_permit move.l _AbsExecBase,a6
jsr _LVOPermit(a6)
move.l dosbase(a5),a6
rts
*******************************
* ASSIGN COMMAND *
*******************************
dl_Root equ 34 APTR
rn_Info equ 24 BPTR
di_DevInfo equ 4 BPTR
dvi_Next equ 0 BPTR
dvi_Type equ 4 LONG
dvi_Task equ 8 APTR
dvi_Lock equ 12 BPTR
dvi_Handler equ 16
dvi_StackSize equ 20
dvi_Priority equ 24
dvi_Startup equ 28
dvi_SegList equ 32
dvi_GlobVec equ 36
dvi_Name equ 40 BSTR
dt_device equ 0 <-- contents of dvi_Type
dt_dir equ 1
dt_volume equ 2
fl_Volume equ 16
fl_Task equ 12
fl_Key equ 4
*pr_StackSize equ 132
pr_SegList equ 128
pr_GlobVec equ 136
assignz bsr do_forbid FORBID
bsr get_first_devinfo
tst.l parm2(a5)
beq show_assigns
tst.l parm3(a5)
beq exit_assignf ONLY TWO PARMS TYPED (NEED 3)
move.l parm2(a5),a0
bsr check_for_colon
beq 2$
bsr do_permit
lea no_colon_tx(pc),a1
bsr pr_string
moveq #RETURN_ERROR,d0
rts
2$ moveq #dt_dir,d1 CREATE/MODIFY ASSIGN ******
bsr find_next_assign
tst.l d0
bne no_more_dir_assigns
move.l a0,d5
move.l parm2(a5),a0 A0=assigned name[0]
moveq #0,d2
move.b (a1)+,d2 get char count
1$ move.b (a1)+,d0
move.b (a0)+,d1
beq.s 2$
subq.l #1,d2
bmi.s 3$
bsr compD1D0nocase
beq.s 1$
4$ bra.s 2$
3$ cmp.b #':',d1 CHANGE EXISTING
bne.s 4$
bsr do_permit PERMIT
move.l d5,a2 GOT A MATCH
moveq #ACCESS_READ,d2
move.l parm3(a5),d1
jsr _LVOLock(a6)
tst.l d0
beq exit_assignp
move.l d0,a3
bsr do_forbid FORBID
move.l dvi_Lock(a2),d4
move.l a3,dvi_Lock(a2) new lock
add.l a3,a3
add.l a3,a3
move.l fl_Task(a3),dvi_Task(a2)
clr.l dvi_Handler(a2)
clr.l dvi_StackSize(a2)
clr.l dvi_Priority(a2)
clr.l dvi_Startup(a2)
clr.l dvi_SegList(a2)
clr.l dvi_GlobVec(a2)
bsr do_permit
move.l d4,d1
jsr _LVOUnLock(a6)
bra exit_assignp
no_more_dir_assigns
bsr do_permit CREATE NEW ASSIGN
moveq #48,d0
move.l #MEMF_CLEAR,d1
bsr iwantmem
tst.l d0
beq exit_assignp
move.l d0,a4
move.l #48,(a4)+ save size byte
move.l parm2(a5),a0
moveq #3,d0 4 extra bytes for dos(nb: : is ignored)
1$ addq.l #1,d0
tst.b (a0)+
bne.s 1$
move.l d0,d3 D3=size+5 (block size|char_count|chars)
moveq #0,d1
bsr iwantmem
tst.l d0
beq rem_dvi
move.l d0,a3
move.l d0,d4 D4=string ptr
move.l d3,(a3)+ save size byte
subq.l #5,d3
move.b d3,(a3)+ save char_count
move.l parm2(a5),a0
bra.s 3$
2$ move.b d1,(a3)+ copy string to NAME
3$ move.b (a0)+,d1
cmp.b #':',d1
bne.s 2$
addq.l #4,d0
lsr.l #2,d0 convert to bstr
move.l d0,dvi_Name(a4)
move.l #dt_dir,dvi_Type(a4)
moveq #ACCESS_READ,d2
move.l parm3(a5),d1
jsr _LVOLock(a6)
tst.l d0
beq rem_str
move.l d0,dvi_Lock(a4)
asl.l #2,d0 x 4
move.l d0,a0
move.l fl_Task(a0),dvi_Task(a4)
bsr do_forbid
bsr get_first_devinfo RETURNS A1 pts info substr, A2 pts 1st devinfo
move.l a2,dvi_Next(a4)
move.l a4,d0
lsr.l #2,d0
move.l d0,di_DevInfo(a1) Insert new top of chain
bsr do_permit
bra.s exit_assignp
rem_str move.l d4,a1
move.l (a1),d0
bsr givemem
rem_dvi lea -4(a4),a1
moveq #48,d0
bsr givemem
exit_assignp
moveq #RETURN_OK,d0
rts
exit_assignf
bsr do_permit
moveq #RETURN_OK,d0
rts
* SHOW ASSIGNS ALREADY IN FORBID STATE
show_assigns
lea -8(sp),sp
move.l a2,(sp) 0(sp)= BPTR of first devinfo
move.l #1024,d0
moveq #0,d1
bsr iwantmem allocate big block
tst.l d0
beq asg_fail
move.l d0,a4 A4 = string block
move.l d0,4(sp) 4(sp) = string block
lea volume_tx(pc),a0 PRINT VOLUMES:
bsr copy_name
moveq #dt_volume,d1
do_volumes
5$ bsr find_next_assign COPY ALL DEVICES THAT MATCH TYPE IN D1
tst.l d0 TO THE BIG STRING
bne.s do_devices
bsr copy_bstr
move.b #$20,(a4)+ seperate with spaces
tst.l dvi_Task(a0)
beq.s 7$
lea mounted_tx(pc),a0
bsr copy_name
7$ move.b #$0a,(a4)+
bra.s 5$
do_devices
move.l (sp),a2 restart at first devinfo
lea device_tx(pc),a0 PRINT DEVICES:
bsr copy_name
moveq #dt_device,d1
bsr store_mult_entries
move.l (sp),a2
do_dirs
lea directory_tx(pc),a0 PRINT DIRECTORIES
bsr copy_name
move.l #-1,-(sp) PUSH NEGATIVE ON STACK
2$ moveq #dt_dir,d1
bsr find_next_assign COPY ALL DEVICES THAT MATCH TYPE IN D1
tst.l d0 TO THE BIG STRING
bne.s get_nxt_lock
lea -38(sp),sp ALLOW 38 BYTES FOR STRING
move.l dvi_Lock(a0),-(sp) push lock
lea 4(sp),a0
move.b (a1)+,d0
bra.s 8$
7$ move.b (a1)+,(a0)+ copy name onto stack
8$ dbra d0,7$
clr.b (a0)+
bra.s 2$
get_nxt_lock
move.l (sp)+,d1 get lock
bmi 1$
lea (sp),a0
6$ move.b (a0)+,(a4)+ copy name to store
bne.s 6$
lea 38(sp),sp
move.b #$9,-1(a4)
tst.l d1
beq 3$ no lock
move.l d1,a0
add.l a0,a0
add.l a0,a0
move.l fl_Volume(a0),a0
add.l a0,a0
add.l a0,a0
tst.l dvi_Task(a0)
bne.s 5$
lea unmounted_tx(pc),a0
bsr copy_name
bra.s get_nxt_lock
5$ bsr do_permit
jsr _LVODupLock(a6) copy lock(D1) --> (D0)
move.l a4,a0
bsr eval_full_path
jsr _LVOUnLock(a6)
bsr do_forbid
4$ tst.b (a4)+
bne.s 4$
3$ move.b #$0a,-1(a4) overwrite null or tab
bra.s get_nxt_lock
1$ move.b #$0a,(a4)+ linefeed at end
clr.b (a4)+
bsr do_permit
move.l 4(sp),a1
bsr pr_string
move.l 4(sp),a1
move.l #1024,d0
bsr givemem
bra.s asg_fail2
asg_fail bsr do_permit
asg_fail2 lea 8(sp),sp
moveq #RETURN_OK,d0
rts
store_mult_entries
2$ bsr find_next_assign COPY ALL DEVICES THAT MATCH TYPE IN D1
tst.l d0 TO THE BIG STRING
bne.s 1$
bsr copy_bstr
move.b #$20,(a4)+ seperate with spaces
move.b #$20,(a4)+
bra.s 2$
1$ move.b #$0a,(a4)+ linefeed at end
rts
get_first_devinfo
move.l dl_Root(a6),a1
move.l rn_Info(a1),a1
add.l a1,a1
add.l a1,a1
move.l di_DevInfo(a1),a2 A2=BPTR to first devinfo
rts
copy_name move.b (a0)+,(a4)+
bne.s copy_name
lea -1(a4),a4
rts
**COPY BSTR FROM A1 TO A4, DONT NULL END
copy_bstr move.b (a1)+,d0
bra.s 3$
2$ move.b (a1)+,(a4)+
3$ dbra d0,2$
rts
**ENTRY: D1=type ,A2=Bptr of devinfo, EXIT: A2=Bptr to next ,D0=0 if found
**EXIT: D2=lock, D1=type, A1 pts to string, A0 pts devinfo struct
find_next_assign
1$ add.l a2,a2 FIND NEXT DEVINFO THAT MATCHES THE TYPE (D1)
add.l a2,a2 A2 pts to first devinfo structure
move.l a2,d0 tst.l (a2)
beq.s 2$
move.l a2,a0
move.l dvi_Name(a2),a1
move.l dvi_Lock(a2),d2
move.l dvi_Type(a2),d0
move.l (a2),a2
cmp.l d0,d1
bne.s 1$
add.l a1,a1
add.l a1,a1
moveq #0,d0
rts
2$ moveq #1,d0
rts
bad_number_error
move.l a1,-(sp)
lea bad_number_tx(pc),a1
bsr pr_string
move.l (sp)+,a1
moveq #RETURN_ERROR,D0
rts
*******************************
* FAILAT COMMAND *
*******************************
failatz tst.l parm2(a5)
beq.s show_failat
move.l parm2(a5),a1
bsr convert_ASCII_to_num
tst.b d1
bne.s failat_OK
bra bad_number_error
failat_OK move.w d0,failat_level(a5)
moveq #RETURN_OK,d0
RTS
show_failat
lea failat_level(a5),a1
lea failat_tx(pc),a0
bsr new_print
moveq #RETURN_OK,d0
rts
*******************************
* IF COMMAND *
*******************************
ifz move.b #$ff,if_flag(a5)
move.b #$ff,if_condition_flag(a5) set FALSE
lea parm2(a5),a4
moveq #0,d4 not state
3$ move.l (a4)+,d0
beq if_fail
move.l d0,a0
lea not_tx(pc),a1
bsr compare_strings
bne.s 2$
not.b d4 set D4=FF if not
bra 3$
2$ lea exists_tx(pc),a1
bsr compare_strings
bne.s try_warn IF NOT AN EXISTS TYPE COMPARE
move.l (a4)+,d1
beq if_fail
moveq #0,d3 d3=0 doesnt exist
moveq #ACCESS_READ,d2
jsr _LVOLock(a6)
tst.l d0
beq.s save_state
move.l d0,d1
jsr _LVOUnLock(a6)
not.b d3 d3=ff exists
save_state
not.b d3 d3=0 true
eor.b d4,d3
move.b d3,if_condition_flag(a5)
moveq #RETURN_OK,D0
RTS
try_warn move.l last_failcode(a5),d5
moveq #RETURN_WARN,d6
lea warn_tx(pc),a1 CHECK IF 'IF WARN'
bsr compare_strings
bne try_error
set_error_state
moveq #0,d3
cmp.l d6,d5
bne save_state
not.b d3
bra save_state
try_error lea error_tx(pc),a1
bsr compare_strings
bne try_fail
moveq #RETURN_ERROR,d6
bra set_error_state
try_fail lea fail_tx(pc),a1
bsr compare_strings
bne if_fail
moveq #RETURN_FAIL,d6
bra set_error_state
if_fail not.b if_flag(a5) clear it
lea if_error_tx(pc),a1
bsr pr_string
MOVEQ #RETURN_ERROR,D0
RTS
*******************************
* ASK COMMAND *
*******************************
askz bsr echo_parm print the parm same as echo does
bsr raw_off
move.l inhandle(a5),d1
lea tempbuf(a5),a4
clr.b (a4)
move.l a4,d2
move.l #SHELLINE_SIZE,d3 MAKE SURE READ ANY EXCESS CRAP TOO
jsr _LVORead(a6)
bsr raw_on
moveq #RETURN_WARN,d0
cmp.b #'y',(a4)
beq 1$
cmp.b #'Y',(a4)
beq 1$
moveq #RETURN_OK,D0
1$ RTS
*******************************
* SLEEP COMMAND *
*******************************
sleepz move.l parm2(a5),d0
bne 1$
2$ moveq #RETURN_ERROR,D0
RTS
1$ move.l d0,a1
bsr convert_ASCII_to_num
tst.b d1
beq bad_number_error
move.l d0,d4
3$ bsr check_c
bne.s 5$
moveq #50,d1 one second
jsr _LVODelay(a6)
subq.l #1,d4
bne.s 3$
5$ moveq #RETURN_OK,D0
RTS
*******************************
* RETURN COMMAND *
*******************************
* only returns from script files.
returnz tst.b scflag(a5)
bne.s 1$
moveq #RETURN_OK,D0
RTS
1$ move.l parm2(a5),d0
beq 2$
move.l d0,a1
bsr convert_ASCII_to_num
tst.b d1
bne 2$
bsr bad_number_error
2$ move.l d0,-(sp)
bsr kill_script guarantee that script is dead
move.l (sp)+,d0
rts
*******************************
* JOIN COMMAND *
*******************************
joinz lea parm2(a5),a4
move.l a4,a3
tst.l 4(a3) must have at least 2 parameters
beq join_failure
1$ tst.l (a3)+ FIND LAST PARAMETER
bne.s 1$
lea -8(a3),a3 A3=last parm ie the write file
move.l (a3),d1
move.l #MODE_NEWFILE,D2
jsr _LVOOpen(a6)
tst.l d0
beq DOSjoin_failure
move.l d0,please_close_me(a5) write handle
2$ cmp.l a4,a3
beq finish_join
move.l (a4)+,a0
bsr readfile
move.l d0,d2
move.l d0,d5 D5=addr
move.l d1,d3
move.l d1,d6 D6=size
move.l please_close_me(a5),d1
jsr _LVOWrite(a6)
tst.l d0
bmi DOSjoin_failure3
bsr free_joiner
bra 2$
finish_join
bsr close_the_joined
moveq #RETURN_OK,D0
RTS
DOSjoin_failure3
bsr free_joiner dealloc readfile
bsr close_the_joined
DOSjoin_failure
bra DOSerr
join_failure
lea join_error_tx(pc),a1
bsr pr_string
moveq #RETURN_ERROR,D0
RTS
free_joiner
move.l d5,a1
move.l d6,d0
bra givemem dealloc readfile
close_the_joined
move.l please_close_me(a5),d1
jsr _LVOClose(a6) close write file
clr.l please_close_me(a5)
rts
*******************************
* HTYPE COMMAND *
*******************************
htypez move.l parm2(a5),d1
bne.s 1$
moveq #RETURN_ERROR,d0
rts
1$ move.l d1,a0
bsr readfile
move.l d0,mem_addr(a5)
move.l d0,mem_offset_addr(a5)
move.l d1,temp1(a5)
add.l d0,d1
move.l d1,d7 end marker
bsr raw_off
2$ bsr check_c
bne htype_end
bsr show_16_locs
cmp.l mem_addr(a5),d7
bhi 2$
htype_end move.l mem_offset_addr(a5),a1
move.l temp1(a5),d0
bsr givemem
bsr raw_on
moveq #RETURN_OK,D0
RTS
*******************************
* STRINGS COMMAND *
*******************************
stringsz move.l parm2(a5),d0
bne 1$
3$ moveq #RETURN_ERROR,D0
RTS
1$ moveq #10,d7 default 10
move.l parm3(a5),d0
beq.s 2$
move.l d0,a1
bsr convert_ASCII_to_num
tst.b d1
beq bad_number_error
move.l d0,d7 D7=min_string
2$ move.l parm2(a5),a0
bsr readfile
move.l d0,a4 A4=addr of file
move.l a4,a3
move.l d1,d6 D6=size of file
add.l d0,d1
move.l d1,d4 D4=max addr
movem.l d4-d7/a3-a4,-(sp)
bsr raw_off
movem.l (sp)+,d4-d7/a3-a4
str_next bsr check_c
bne kill_string_file
moveq #0,d5 D5=current string size
move.l a3,a2
valid_ch cmp.l a3,d4
beq string_fin
move.b (a3)+,d0
cmp.b #' ',d0
blo.s not_valid_char
cmp.b #$7f,d0
bhi.s not_valid_char
addq.l #1,d5
bra valid_ch
not_valid_char
cmp.l d7,d5
blo str_next
bsr write_my_string
bra str_next
string_fin
cmp.l d7,d5
blo kill_string_file
bsr write_my_string
kill_string_file
move.l a4,a1
move.l d6,d0
bsr givemem
bsr raw_on
moveq #RETURN_OK,D0
RTS
write_my_string
move.l outhandle(a5),d1
move.l a2,d2
move.l d5,d3
jsr _LVOWrite(a6)
bra pr_lf
_DOSBase dc.l 0
char_count dc.l 0
oldstack dc.l 0
membase dc.l 0
entryA0 dc.l 0
entryD0 dc.l 0
better_seglist dc.l 0
doserror_text
dc.b 103,'NO FREE STORE',0
dc.b 121,'FILE NOT OBJECT',0
dc.b 202,'OBJECT IN USE',0
dc.b 203,'OBJECT EXISTS',0
dc.b 205,'OBJECT NOT FOUND',0
dc.b 210,'INVALID COMPONENT NAME',0
dc.b 211,'INVALID LOCK',0
dc.b 212,'OBJECT WRONG TYPE',0
dc.b 213,'DISK NOT VALIDATED',0
dc.b 214,'DISK WRITE PROTECTED',0
dc.b 215,'RENAME ACROSS DEVICES',0
dc.b 216,'DIRECTORY NOT EMPTY',0
dc.b 218,'DEVICE NOT MOUNTED',0
dc.b 219,'SEEK ERROR',0
dc.b 221,'DISK FULL',0
dc.b 222,'DELETE PROTECTED',0
dc.b 223,'WRITE PROTECTED',0
dc.b 224,'READ PROTECTED',0
dc.b 225,'NOT A DOS DISK',0
dc.b 226,'NO DISK',0
dc.b 0
bad_number_tx dc.b 'Cannot understand number!',10,0
join_error_tx dc.b 'Not enough parameters',10,0
goto_error_tx dc.b 'GOTO statement error!',10,0
if_error_tx dc.b 'IF statement error!',10,0
warn_tx dc.b 'warn',0
error_tx dc.b 'error',0
fail_tx dc.b 'fail',0
not_tx dc.b 'not',0
exists_tx dc.b 'exists',0
bad_prot_bits_tx dc.b 'Unknown protection bit',10,0
no_colon_tx dc.b 'Name MUST end in :',10,0
resi_not_found_tx dc.b 'Could not find resident!',10,0
resi_no_mem_tx dc.b 'Not enough memory for resident list',10,0
rpn_result_tx dc.b 'RESULT: Dec %ld Hex $%08lx',10,0
failat_tx dc.b 'Failat: %d',10,0
defscript1 dc.b 's:' DONT SEPERATE FROM NEXT LINE -,
defscript2 dc.b 'login.z',0 <----"
unmounted_tx dc.b '[UnMounted]',10,0
mounted_tx dc.b '[Mounted]',0
directory_tx dc.b 10,'Directories:',10,0
volume_tx dc.b 'Volumes:',10,0
device_tx dc.b 10,'Devices:',10,0
bad_unset_tx dc.b ' could not be unset!!',10,0
breaktx dc.b 10,'*** BREAK ***',10,0
prompt_args_tx dc.b '%p> ',0
stk_too_small_tx dc.b 'Too Small!',10,0
stk_too_big_tx dc.b 'Too Big!',10,0
stk_size_tx dc.b 'Current Stack = %ld bytes',10,0
OK_text dc.b "O.K..",10,0
status_help_text
dc.b "Usage: status [-y|-n]",10,0
time_text dc.b "TIME = %02d:%02d:%02d.%02d",10,0
stat_text dc.b 27,"[33mRETURN = %ld time = %02d:%02d:%02d.%02d"
dc.b " changes ->chip :%ld fast :%ld total :%ld",27,"[31m",10,0
mem_line dc.b "%08lx: %08lx %08lx %08lx %08lx '%s'",10,0
vec_line dc.b "WarmCapture $%08lx",10,"CoolCapture $%08lx",10
dc.b "ColdCapture $%08lx",10,"KickTagPtr $%08lx",10
dc.b "KickMemPtr $%08lx",10,"KickCheckSum $%08lx",10,0
format dc.b '%8ld',0 ;print a longw right justified
totfiles dc.b 10,'Total bytes = ',0
lf dc.b 10,0
seq dc.b $0d,$9b,'25C',0
seqwide dc.b $0d,$9b,'65C',0
widetx dc.b $0d,$9b,'40C',0
dosname dc.b 'dos.library',0
newcol dc.b 27,'[33m',0
oldcol dc.b 27,'[31m',0
dirtext dc.b 'Dir',27,'[31m',0
cderrtx dc.b 'Where?',10,0
dirof dc.b 27,'[33mDirectory of -> ',27,'[31m',0
defpath1 dc.b 'vd0:',0
dc.b 'vd0:c',0
dc.b 'rad:',0
dc.b 'rad:c',0
dc.b 'ram:',0
dc.b 'ram:c',0
dc.b 'df0:',0
dc.b 'df0:c',0
dc.b 'c:',0
dc.b 'df1:',0
dc.b 'df1:c',0
hello dc.b 10,'ZShell V1.30 '
dc.b '(C)1990,91 Paul Hayter',10,10,0
tab dc.b ' ',0
badcomm dc.b 'Command not found!',10,0
volytx dc.b 'Volume "%s:" has %ld bytes free.',10,0
copyOK dc.b '...copied!',10,0
deletedtx dc.b '...deleted!',10,0
memess dc.b "CHIP = %ld FAST = %ld TOTAL FREE = %ld",10,0
backspace_it dc.b 8 DON'T SEPERATE
delete_it dc.b $9b,'P',0 THESE LINES
return_it dc.b $d,$a,0
insert_it dc.b $9b,'@',0,0 3rd char is char to be inserted
left_cursor dc.b $9b,'D',0
right_cursor dc.b $9b,'C',0
delete_line dc.b $0d,$9b,'M',0
delete_line2 dc.b $9b,'M',$0d,0
backslash dc.b '/',0
help_ret dc.b 'help^M',0
clstx dc.b $0c,0
scroll_up_tx dc.b $9b,'S',0
carriage_tx dc.b 13,0
doserrtx dc.b 'ERROR:' ;DON'T SEPERATE
space dc.b ' '
null dc.b 0 ;THESE 3 LINES
*********************************************
comtext dc.b 'addbuffers',0 V1.27
dc.b 'ask',0 V1.28
dc.b 'assign',0
dc.b 'cd',0
dc.b 'copy',0
dc.b 'delete',0
dc.b 'dir',0
dc.b 'diw',0
dc.b 'echo',0
else_tx dc.b 'else',0 V1.28
endif_tx dc.b 'endif',0 V1.28
dc.b 'exec',0
dc.b 'exit',0
dc.b 'failat',0
dc.b 'goto',0 V1.29
dc.b 'help',0
dc.b 'htype',0 V1.29
dc.b 'if',0 V1.28
dc.b 'info',0
dc.b 'join',0 V1.29
label_tx dc.b 'label',0 V1.29
dc.b 'm',0
dc.b 'mem',0
dc.b 'mkdir',0
dc.b 'more',0 V1.23
dc.b 'path',0
dc.b 'prompt',0
dc.b 'relabel',0 V1.27
dc.b 'rename',0
dc.b 'reset',0
dc.b 'resident',0 V1.25
dc.b 'return',0 V1.29
dc.b 'rpn',0
dc.b 'set',0
dc.b 'setprot',0
dc.b 'sleep',0 V1.29
dc.b 'stack',0
dc.b 'status',0
dc.b 'strings',0 V1.29
dc.b 'time',0
dc.b 'type',0
dc.b 'unset',0
dc.b 'vec',0
dc.b 'version',0
dc.b 0
cnop 0,2
comoffs
dc.w addbuffersz-start
dc.w askz-start
dc.w assignz-start
dc.w chdirz-start
dc.w copyz-start
dc.w deletez-start
dc.w dirz-start
dc.w dirwz-start
dc.w echoz-start
dc.w elsez-start V1.28
dc.w endifz-start V1.28
dc.w xz-start
dc.w exitz-start
dc.w failatz-start
dc.w gotoz-start
dc.w helpmez-start
dc.w htypez-start V1.29
dc.w ifz-start V1.28
dc.w infoz-start
dc.w joinz-start V1.29
dc.w labelz-start
dc.w memexamz-start
dc.w availz-start
dc.w mkdirz-start
dc.w morez-start
dc.w pathcomz-start
dc.w promptz-start
dc.w relabelz-start
dc.w renamez-start
dc.w resetz-start
dc.w residentz-start
dc.w returnz-start
dc.w rpnz-start
dc.w set_funcz-start
dc.w setprotz-start
dc.w sleepz-start
dc.w stackz-start
dc.w statusz-start
dc.w stringsz-start
dc.w timez-start
dc.w typez-start
dc.w unsetz-start
dc.w vecz-start
dc.w versionz-start
section raw_stuff,bss
myport ds.b MP_SIZE
here ds.b 2 MAKE SURE MYPACKET IS LONGWORD ALIGNED.
mypacket ds.b sp_SIZEOF
end