home *** CD-ROM | disk | FTP | other *** search
RISC OS BBC BASIC V Source | 1994-01-04 | 25.3 KB | 840 lines |
- E-Template
- Template program for creating Zap modes.
- The module will be saved to work_directory$
- You should run Zap first to ensure Zap$Dir and ZapWork$Dir
- are set up.
- directory to save module
- "work_directory$="<ZapMod$Dir>"
- name of mode
- mode_name$="Utils"
- authors name
- mode_author$="Paul Moore"
- version number of module
- ver$="0.03"
- mode number you want to be
- you MUST not hard wire this in as I may have allocated it
- to someone else!
- mode_number=15
- mode to base this mode on (text)
- mode_basemode=0
- define a proc error to print line number even if running
- under wimp.
- error
- reserve space for code / workspace
- default of 64k
- code_size%=&10000
- code% code_size%
- L%=code%+code_size%
- load the library defining zap's variables
- "<ZapWork$Dir>.Docs.E-Library"
- define zaps constants (call E-Library)
- define_zap_variables
- define any variables in our workspace
- set_up_variables
- assemble the code
- assemble_code
- save the module
- "OS_File",&0A,work_directory$+".Zap"+mode_name$,&FFA,0,code%,code%+length%
- "Zap";mode_name$+" module created and saved"
- define any variables we want to store in the module workspace
- set_up_variables
- buflen% = length of OS command buffer
- parmct% = number of argsub parameters
- buflen% = 255
- pass=%1100
- %1110
- 2:P%=0:O%=code%:[OPTpass
- .search_parm EQUD 0
- C%.cmd_buf
- res(buflen%)
- variable_size%=P%
- assemble the main code
- assemble_code
- define flags
- Iflag%=1<<27
- Vflag%=1<<28
- Cflag%=1<<29
- define register numbers (for macros)
- U<R0=0:R1=1:R2=2:R3=3:R4=4:R5=5:R6=6:R7=7:R8=8:R9=9:R10=10
- V,R11=11:R12=12:R13=13:R14=14:R15=15:PC=15
- pass=%1100
- %1110
- 2:P%=0:O%=code%
- [OPTpass
- .Module_header
- \ .Start_code EQUD 0
- ]..Initialisation_code EQUD initialise_code
- ^,.Finalisation_code EQUD finalise_code
- _ .Service_call_handler EQUD 0
- `+.Title_string EQUD title_string
- a*.Help_string EQUD help_string
- b .Command_keyword_tab EQUD 0
- c .SWI_chunk_number EQUD 0
- d .SWI_handler_code EQUD 0
- e .SWI_decoding_table EQUD 0
- f .SWI_decoding_code EQUD 0
- hD\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- iB\ TITLES
- COMMAND TABLES \
- jD\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .help_string
- S("Zap"+mode_name$+
- 9+ver$+" ("+
- date+")
- "+mode_author$)
- .title_string
- S("Zap"+mode_name$)
- rD\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- sB\ INITIALISE
- FINALISE \
- tD\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .initialise_code
- MOV R0,#6
- LDR R3,var_size
- z;SWI "XOS_Module" \ claim varable workspace
- RTSVS
- |CMOV R11,R2 \ claimed block (R11 from now on)
- }@STR R11,[R12] \ save as my workspace pointer
- ~=STR R11,workspace_address \ save it in the module for
- 7MOV R0,#18 \ accessing commands.
- ADR R1,zap_title
- ,SWI "XOS_Module" \ find zap
- RTSVS \ not found
- 1MOV R12,R4 \ zap workspace
- 9ADR R0,key_command_table \ add table of commands
- call(Zap_AddCommands)
- RTSVS
- MOV R1,#0
- MOV R2,R11
- LDR R3,var_size
- call(Zap_FillWords) \ clear workspace to zeros
- .var_size
- EQUD variable_size%
- .zap_title
- S("Zap")
- .workspace_address
- EQUD 0
- \X R11=module workspace |
- .get_workspace
- LDR R11,workspace_address
- MOV PC,R14
- .finalise_code
- MOV R0,#7
- LDR R2,[R12]
- 2SWI "XOS_Module" \ free workspace
- RTSVS
- MOV R0,#0
- 5STR R0,[R12] \ null private word
- A\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- A\ Command table \
- A\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .key_command_table
- EQUD key_command_table
- 5EQUD 0 \ service call code
- com("FILTERSEL",filtersel)
- com("WINLEFT",winleft)
- com("WINRIGHT",winright)
- com("WINUP",winup)
- com("WINDOWN",windown)
- com("DELWORDLEFT",delwordleft)
- com("DELWORDRIGHT",delwordright)
- com("SEARCHWORD",searchword)
- com("FW",fw)
- com("BW",bw)
- 'EQUD 0 \ end
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- D\ Word movement commands \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- EQUD (1<<12)
- STMFD R13!,{R14}
- LDR R0,[R10,#c_off]
- TEQ R1,#0
- .fw01
- BLNE fwd_word
- SUBNES R1,R1,#1
- BNE fw01
- call(Zap_JumptoOffset)
- LDMFD R13!,{PC}
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- EQUD (1<<12)
- STMFD R13!,{R14}
- LDR R0,[R10,#c_off]
- TEQ R1,#0
- .bw01
- BLNE back_word
- SUBNES R1,R1,#1
- BNE bw01
- call(Zap_JumptoOffset)
- LDMFD R13!,{PC}
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- D\ Word deletion commands \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- EQUD 0
- .delwordleft
- STMFD R13!,{R14}
- LDR R3,[R10,#c_off]
- MOV R0,R3
- TEQ R1,#0
- .dwl01
- BLNE back_word
- SUBNES R1,R1,#1
- BNE dwl01
- .\\\ R0 = start of block, R3 = end of block
- MOV R1,R0
- SUB R2,R3,R0
- call(Zap_StartOp)
- BVS dwl02
- MOV R0,#2
- call(Zap_Command)
- BVS dwl02
- call(Zap_StopOp)
- .dwl02
- LDMFD R13!,{PC}
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- EQUD (1<<12)
- .delwordright
- STMFD R13!,{R14}
- LDR R3,[R10,#c_off]
- MOV R0,R3
- TEQ R1,#0
- .dwr01
- BLNE fwd_word
- SUBNES R1,R1,#1
- BNE dwr01
- .\\\ R3 = start of block, R0 = end of block
- MOV R1,R3
- SUB R2,R0,R3
- call(Zap_StartOp)
- BVS dwr02
- MOV R0,#2
- call(Zap_Command)
- BVS dwr02
- call(Zap_StopOp)
- .dwr02
- LDMFD R13!,{PC}
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- D\ Word search commands \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- EQUD (2<<3)+(1<<12)
- .searchword
- STMFD R13!,{R14}
- BL get_workspace
- MOV R2,R0
- TEQ R1,#0
- BEQ sw02
- ! .sw01
- LDR R0,[R2],#4
- STR(R0,search_parm)
- BL search_rtn
- BVS sw02
- SUBS R1,R1,#1
- BNE sw01
- ) .sw02
- LDMFD R13!,{PC}
- ,D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .search_rtn
- STMFD R13!,{R1-R7,R14}
- 08LDR R7,[R10,#c_off] \ R7 = current cursor offset
- MOV R0,R7
- BL getc_off
- BL wordchar
- BCC sr_err
- 7 .sr01
- TEQ R0,#0
- BEQ sr02
- SUB R0,R0,#1
- BL getc_off
- BL wordchar
- BCS sr01
- ADD R0,R0,#1
- ? .sr02
- A0MOV R5,R0 \ R5 = start of word
- C.LDR R2,[R9,#f_len] \ R2 = file length
- MOV R0,R7
- E .sr03
- CMP R0,R2
- MOVHS R0,R2
- BHS sr04
- ADD R0,R0,#1
- BL getc_off
- BL wordchar
- BCS sr03
- M .sr04
- O2MOV R6,R0 \ R6 = end of word + 1
- P1SUB R4,R6,R5 \ R4 = length of word
- ADD R0,R4,#1
- call(Zap_Claim)
- LDMVSFD R13!,{R1-R7,PC}
- U-MOV R7,R0 \ R7 = heap block
- LDR R0,[R9,#f_splito]
- CMP R5,R0
- CMPLT R0,R6
- BLT sr05
- \ Word is in one part
- LDR R1,[R9,#f_ptr]
- ADD R1,R1,R5
- MOV R2,R7
- MOV R3,R4
- call(Zap_MoveBytes)
- BVS err_free
- B sr06
- \ Word is in two parts
- f .sr05
- LDR R1,[R9,#f_ptr]
- ADD R1,R1,R5
- MOV R2,R7
- SUB R3,R0,R5
- STMFD R13!,{R1-R3}
- call(Zap_MoveBytes)
- BVS err_free
- LDMFD R13!,{R1-R3}
- LDR R0,[R9,#f_splits]
- ADD R1,R1,R0
- ADD R1,R1,R3
- ADD R2,R2,R3
- SUB R3,R4,R3
- call(Zap_MoveBytes)
- BVS err_free
- w .sr06
- y,\ Word is now on heap. Zero-terminate it
- MOV R0,#0
- STRB R0,[R7,R4]
- }*\ Work out what type of search we want
- \ 0 = to buffer
- 3\ +1 = from here, forward ie, next match
- 7\ -1 = from here, backward ie, previous match
- 4\ +2 = from start, forward ie, first match
- 3\ -2 = from start, backward ie, last match
- \ others are errors
- LDR(R0,search_parm)
- CMP R0,#0
- Q R1,#1 \ To buffer for type 0
- @MOVNE R1,#2 \ Otherwise, get file offset in R0
- 9MOVPL R4,#1 \ Forwards, unless type < 0
- .MOVMI R4,#0 \ when backwards
- EMOVPL R3,R6 \ For forward search, start at word end
- HMOVMI R3,R5 \ For backward search, start at word start
- BRSBMI R0,R0,#0 \ Get the absolute value of the type
- CMP R0,#1
- @MOVNE R3,#0 \ From start, unless abs(type) = 1
- \ Do the search
- MOV R0,R7
- MOV R5,#0
- call(Zap_Search)
- BVS err_free
- ,\ If we got a throwback buffer, stop now
- CMP R1,#1
- LDMEQFD R13!,{R1-R7,PC}
- CMP R0,#0
- BMI sr_notfound
- call(Zap_GotoOffset)
- BVS err_free
- MOV R0,R7
- call(Zap_Free)
- LDMFD R13!,{R1-R7,PC}
- .err_free
- MOV R1,R0
- MOV R0,R7
- call(Zap_Free)
- MOV R0,R1
- LDMFD R13!,{R1-R7,R14}
- RS PC,R14,#Vflag%
- .sr_notfound
- MOV R0,R7
- call(Zap_Free)
- ADR R0,sr_no
- LDMFD R13!,{R1-R7,R14}
- RS PC,R14,#Vflag%
- .sr_err
- ADR R0,sr_error
- LDMFD R13!,{R1-R7,R14}
- RS PC,R14,#Vflag%
- .sr_error
- EQUD 0
- S("Not in a word")
- .sr_no
- EQUD 0
- S("Not found")
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- D\ Subroutines \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- #\ Move one word forward in file
- 7\ (In) R0 = file offset, (Out) R0 = new file offset
- .fwd_word
- STMFD R13!,{R1-R2,R14}
- LDR R2,[R9,#f_len]
- CMP R0,R2
- MOVHS R0,R2
- BHS fw_eof
- .fw01
- BL getc_off
- BL wordchar
- BCC fw02
- ADD R0,R0,#1
- CMP R0,R2
- BHS fw_eof
- B fw01
- .fw02
- ADD R0,R0,#1
- CMP R0,R2
- BHS fw_eof
- BL getc_off
- BL wordchar
- BCC fw02
- .fw_eof
- LDMFD R13!,{R1-R2,PC}^
- $\ Move one word backward in file
- 7\ (In) R0 = file offset, (Out) R0 = new file offset
- .back_word
- STMFD R13!,{R1,R14}
- .bw01
- SUBS R0,R0,#1
- BMI bw_eof
- BL getc_off
- BL wordchar
- BCC bw01
- .bw02
- SUBS R0,R0,#1
- BMI bw_eof
- BL getc_off
- BL wordchar
- BCS bw02
- .bw_eof
- ADD R0,R0,#1
- LDMFD R13!,{R1,PC}^
- (\ Get a character from a file buffer
- '\ (In) R0=file offset (Out) R1=char
- .getc_off
- STMFD R13!,{R0,R14}
- LDR R1,[R9,#f_splito]
- CMP R0,R1
- LDRCS R1,[R9,#f_splits]
- ADDCS R0,R0,R1
- LDR R1,[R9,#f_ptr]
- LDRB R1,[R1,R0]
- LDMFD R13!,{R0,PC}^
- 5\ Check whether a character is a word constituent
- ,\ (In) R1=char (Out) CS=Word, CC=NonWord
- .wordchar
- STMFD R13!,{R0-R2,R14}
- ADR R0,wordtab
- MOV R2,R1,LSR #5
- LDR R0,[R0,R2,ASL #2]
- R1,R1,#&1F
- ADD R1,R1,#1
- MOVS R0,R0,LSR R1
- LDMFD R13!,{R0-R2,PC}
- %\ Word characters (A-Z,a-z,0-9,_)
- .wordtab
- #EQUD &00000000 \ &00-&1F
- )EQUD &03FF0000 \ &20-&3F (0-9)
- /EQUD &87FFFFFE \ &40-&5F (A-Z and _)
- )EQUD &07FFFFFE \ &60-&7F (a-z)
- #EQUD &00000000 \ &80-&9F
- #EQUD &00000000 \ &A0-&BF
- !#EQUD &00000000 \ &C0-&DF
- "#EQUD &00000000 \ &E0-&FF
- $D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- %D\ Window Movement Commands \
- &D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- EQUD (2<<3)+(1<<12)
- .winleft
- STMFD R13!,{R14}
- BL getarg
- LDR R0,[R8,#w_minx]
- SUB R0,R0,R2
- STR R0,[R8,#w_minx]
- LDR R0,[R8,#w_maxx]
- SUB R0,R0,R2
- STR R0,[R8,#w_maxx]
- MOV R0,#1
- MOV R1,R8
- call(Zap_OpenWindow)
- LDMFD R13!,{PC}
- <D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- EQUD (2<<3)+(1<<12)
- .winright
- STMFD R13!,{R14}
- BL getarg
- LDR R0,[R8,#w_minx]
- ADD R0,R0,R2
- STR R0,[R8,#w_minx]
- LDR R0,[R8,#w_maxx]
- ADD R0,R0,R2
- STR R0,[R8,#w_maxx]
- MOV R0,#1
- MOV R1,R8
- call(Zap_OpenWindow)
- LDMFD R13!,{PC}
- RD\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- EQUD (2<<3)+(1<<12)
- .winup
- STMFD R13!,{R14}
- BL getarg
- LDR R0,[R8,#w_miny]
- ADD R0,R0,R2
- STR R0,[R8,#w_miny]
- LDR R0,[R8,#w_maxy]
- ADD R0,R0,R2
- STR R0,[R8,#w_maxy]
- MOV R0,#1
- MOV R1,R8
- call(Zap_OpenWindow)
- LDMFD R13!,{PC}
- hD\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- EQUD (2<<3)+(1<<12)
- .windown
- STMFD R13!,{R14}
- BL getarg
- LDR R0,[R8,#w_miny]
- SUB R0,R0,R2
- STR R0,[R8,#w_miny]
- LDR R0,[R8,#w_maxy]
- SUB R0,R0,R2
- STR R0,[R8,#w_maxy]
- MOV R0,#1
- MOV R1,R8
- call(Zap_OpenWindow)
- LDMFD R13!,{PC}
- ~D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- /\ (In) R0=list of words, R1=number in list
- .\ (Out) R2=sum of list, R0,R1,R3 corrupted
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .getarg
- MOV R2,#0
- SUBS R1,R1,#1
- LDRPL R3,[R0],#4
- ADDPL R2,R2,R3
- BPL L01
- MOVS PC,R14
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- D\ Filter Selection Command \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- EQUD 1+(3<<3)+(1<<6)
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- -\ (Uses) R7=command string, R6=heap block
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .filtersel
- .\\ Are we being asked for a prompt string?
- TEQ R2,#6
- BEQ add_prompt
- 1\\ Remember the minibuffer contents for later
- MOV R7,R0
- ,\\ Get the selected area to a heap block
- call(Zap_ReadSel) \ (Out) R2=len, R3=block
- BVS error_ret
- TEQ R3,#0
- <BEQ error_nosel \ Error if there isn't one
- 1\\ Save the selected area to a temporary file
- ADR R1,file_in
- FBL save \ (In) R1=filename, R2=len, R3=block
- BVS error_ret
- \\ Free the heap block
- MOV R0,R3
- call(Zap_Free) \ (In) R0=block
- BVS error_ret
- \\ Filter the file
- MOV R0,R7
- ADR R1,file_in
- ADR R2,file_out
- HBL filter_file \ (In) R0=command, R1=input, R2=output
- BVS error_ret
- .\\ Find the length of the replacement file
- ADR R1,file_out
- =BL get_len \ (In) R1=file (Out) R0=len
- BVS error_ret
- AMOV R4,R0 \ Save filesize in R4 for later
- ,\\ Get the necessary space on Zap's heap
- call(Zap_Claim) \ (In) R0=size (Out) R0=block
- BVS error_ret
- CMOV R3,R0 \ Save block addr in R3 for later
- \\ Load the replacement file
- ADR R1,file_out
- :BL load_file \ (In) R0=block, R1=file
- BVS error_ret
- 6\\ Get the file offset and length of the selection
- call(Zap_GetSel) \ (Out) CC, R1=offset, R2=len
- LBCS error_nosel \ Error if there isn't one - cannot happen
- BVS error_ret
- 2\\ Replace the selection with the changed text
- call(Zap_StartOp)
- BVS error_ret
- call(Zap_ReplaceArea) \ (In) R1=offset, R2=len, R3=block, R4=blklen
- BVS error_ret
- call(Zap_StopOp)
- BVS error_ret
- :\\ Free the heap block, and delete the temporary files
- MOV R0,R3
- call(Zap_Free) \ (In) R0=block
- BVS error_ret
- 0ADR R1,file_in \ (In) R1=file
- BL delete
- 0ADR R1,file_out \ (In) R1=file
- BL delete
- \\ Finished
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- D\ Error returns \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .error_nosel
- ADR R0,error_noselection
- \ Fall through!
- .error_ret
- .error_noselection
- EQUD 0
- S("No selection")
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- D\ Input and output filenames for command \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .file_in
- S("<Wimp$ScrapDir>.Zap-In")
- .file_out
- S("<Wimp$ScrapDir>.Zap-Out")
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- D\ Add a prompt to the minibuffer (tail called from command) \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .add_prompt
- ADR R0,prompt_string
- call(Zap_MiniPrompt)
- .prompt_string
- S("Filter: ")
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- D\ Save data to a file \
- D\ (In) R1 = filename, R2 = len, R3 = addr \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .save
- STMFD R13!,{R1-R5,R14}
- #MOV R4,R3 \ start addr
- !ADD R5,R3,R2 \ end addr
- "MOV R0,#10 \ save file
- !LDR R2,file_txt \ filetype
- SWI "XOS_File"
- LDMFD R13!,{R1-R5,PC}
- .file_txt
- EQUD &FFF
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- D\ Get the length of a file \
- D\ (In) R1 = file (Out) R0 = length \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .get_len
- STMFD R13!,{R1-R6,R14}
- MOV R0,#17
- SWI "XOS_File"
- MOVVC R0,R4
- LDMFD R13!,{R1-R6,PC}
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- !D\ Delete a file \
- "D\ (In) R1 = file \
- #D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .delete
- STMFD R13!,{R1-R5,R14}
- MOV R0,#6
- SWI "XOS_File"
- LDMFD R13!,{R1-R5,PC}
- +D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- ,D\ Load a file \
- -D\ (In) R0 = address, R1 = file \
- .D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .load_file
- STMFD R13!,{R1-R7,R14}
- 2,MOV R2,R0 \ address to load to
- 3#MOV R0,#16 \ load file
- 4/MOV R3,#0 \ load to given address
- SWI "XOS_File"
- LDMFD R13!,{R1-R7,PC}
- 8D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- 9D\ Filter file_in to file_out \
- :D\ (In) R0=command, R1=input, R2=output \
- ;D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .filter_file
- STMFD R13!,{R0-R2,R14}
- @(\ The parameter list is on the stack
- MOV R3,R13
- C6\ Claim some space for the command buffer from Zap
- MOV R0,#buflen%
- call(Zap_Claim)
- FGADDVS R13,R13,#4 \ On an error, we don't restore R0!
- LDMVSFD R13!,{R1-R2,PC}
- MOV R2,#buflen%
- MOV R1,R0
- ADR R0,cmd_template
- BL argsub
- N(\ Save the address of the heap block
- MOV R2,R0
- Q8\ Drop R0 from the stack, as we intend to corrupt it
- ADD R13,R13,#4
- \ Start the child task
- SWI "XWimp_StartTask"
- BVS error_starttask
- TEQ R0,#0
- ADRNE R0,error_livetask
- BNE error_starttask
- \ Free the heap block
- MOV R0,R2
- call(Zap_Free)
- LDMFD R13!,{R1-R2,PC}
- a&\ Error in starting the child task
- .error_starttask
- c@MOV R1,R0 \ Preserve the error pointer
- MOV R0,R2
- call(Zap_Free) \ Free the heap block (ignore errors here)
- MOV R0,R1
- LDMFD R13!,{R1-R2,R14}
- RS PC,R14,#Vflag%
- lD\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .error_livetask
- EQUD 0
- S("Filter task has not completed")
- qD\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .cmd_template
- S("%0 < %1 > %2 2> Null:")
- vD\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- wD\ Substitute args into a string \
- xD\ (In) R0 = template, R1 = output buffer, R2 = output buffer \
- yD\ length, R3 = parameter list \
- zD\ (Out) R0 = output buffer, R1 = null at end of output \
- {D\ \
- |D\ Copies the template into the output buffer, replacing %n by \
- }D\ the contents of the nth parameter in the list at R3. %% is \
- ~D\ replaced by a single % \
- D\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- .argsub
- STMFD R13!,{R1-R5,R14}
- &\ Main loop - load and store bytes
- \ Buffer overflow?
- TEQ R2,#0
- BEQ Lerr_overflow
- LDRB R4,[R0]
- \ Argument substitution?
- TEQ R4,#
- BEQ Lpct
- '\ Basic case - add to output string
- .Lbas
- STRB R4,[R1],#1
- ADD R0,R0,#1
- SUB R2,R2,#1
- \ At end?
- TEQ R4,#0
- BNE L11
- 9SUB R1,R1,#1 \ Back up to the null
- ILDMFD R13!,{R0,R2-R5,PC} \ Restore, but restore saved R1 to R0
- \ Argument substitution
- .Lpct
- LDRB R4,[R0,#1]!
- +TEQ R4,#
- "%" \ %% => %
- BEQ Lbas
- \ Check that we have %0 - %9
- CMP R4,#
- BLT Lerr_invalid
- CMP R4,#
- BGT Lerr_invalid
- EADD R0,R0,#1 \ R0 -> next unread template char
- SUB R4,R4,#
- LDR R5,[R3,R4,LSL #2]
- \ Copy [R5] into [R1]
- LDRB R4,[R5],#1
- TEQ R4,#0
- ABEQ L11 \ Done - go back to main loop
- TEQ R2,#0
- BEQ Lerr_overflow
- STRB R4,[R1],#1
- SUB R2,R2,#1
- B L12
- .Lerr_overflow
- ADR R0,error_overflow
- LDMFD R13!,{R1-R5,R14}
- RS PC,R14,#Vflag%
- .Lerr_invalid
- ADR R0,error_invalid
- LDMFD R13!,{R1-R5,R14}
- RS PC,R14,#Vflag%
- .error_overflow
- EQUD 0
- S("Overflow")
- .error_invalid
- EQUD 0
- S("Invalid template")
- @\\\\\\\\\\ End Of Assembly \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
- pass
- length%=P%
- S(A$) :[OPTpass:EQUS A$+
- 0:ALIGN:]:=""
- RES(n%) :[OPTpass:EQUS
- 0):ALIGN:]:=""
- SS(A$) :[OPTpass:SWI "XOS_WriteS":EQUS A$+
- 0:ALIGN:]:=""
- JSR :[OPTpass:STMFD R13!,{R14}:]:=""
- RTV :[OPTpass:LDMFD R13!,{R14}:
- RS PC,R14,#Vflag%:]:=""
- RTC :[OPTpass:LDMFD R13!,{R14}:BICS PC,R14,#Vflag%:]:=""
- RTS :[OPTpass:LDMFD R13!,{PC} :]:=""
- RTSNE :[OPTpass:LDMNEFD R13!,{PC}:]:=""
- RTSEQ :[OPTpass:LDMEQFD R13!,{PC}:]:=""
- RTSCS :[OPTpass:LDMCSFD R13!,{PC}:]:=""
- RTSCC :[OPTpass:LDMCCFD R13!,{PC}:]:=""
- RTSVS :[OPTpass:LDMVSFD R13!,{PC}:]:=""
- RTSVC :[OPTpass:LDMVCFD R13!,{PC}:]:=""
- RTSLS :[OPTpass:LDMLSFD R13!,{PC}:]:=""
- RTSHI :[OPTpass:LDMHIFD R13!,{PC}:]:=""
- RTSMI :[OPTpass:LDMMIFD R13!,{PC}:]:=""
- RTSLE :[OPTpass:LDMLEFD R13!,{PC}:]:=""
- RTSGE :[OPTpass:LDMGEFD R13!,{PC}:]:=""
- RTSLT :[OPTpass:LDMLTFD R13!,{PC}:]:=""
- RTSS :[OPTpass:LDMFD R13!,{PC}^:]:=""
- RTSSNE :[OPTpass:LDMNEFD R13!,{PC}^:]:=""
- RTSSEQ :[OPTpass:LDMEQFD R13!,{PC}^:]:=""
- RTSSCC :[OPTpass:LDMCCFD R13!,{PC}^:]:=""
- RTSSCS :[OPTpass:LDMCSFD R13!,{PC}^:]:=""
- mem(x%) :w%=O%-code%:P%=P%+x%:O%=O%+x%:[OPTpass:ALIGN:]:=w%
- res(x%) :P%=P%+x%:O%=O%+x%:[OPTpass:ALIGN:]:=""
- newl :[OPTpass:SWI "XOS_NewLine":]:=""
- date
- date% 64:?date%=3:
- "OS_Word",&0E,date%
- "OS_ConvertDateAndTime",date%,date%+16,32,"%DY %M3 19%YR"
- A%,B%
- ?B%=13:=$A%
- This modules workspace is at R11!!
- ADR(s%,x%) :[OPTpass:ADD s%,R11,#x%:]:=""
- LDR(s%,x%) :[OPTpass:LDR s%,[R11,#x%]:]:=""
- LDREQ(s%,x%):[OPTpass:LDREQ s%,[R11,#x%]:]:=""
- LDRNE(s%,x%):[OPTpass:LDRNE s%,[R11,#x%]:]:=""
- LDRCS(s%,x%):[OPTpass:LDRCS s%,[R11,#x%]:]:=""
- LDRCC(s%,x%):[OPTpass:LDRCC s%,[R11,#x%]:]:=""
- STR(s%,x%) :[OPTpass:STR s%,[R11,#x%]:]:=""
- STREQ(s%,x%):[OPTpass:STREQ s%,[R11,#x%]:]:=""
- STRNE(s%,x%):[OPTpass:STRNE s%,[R11,#x%]:]:=""
- STRVS(s%,x%):[OPTpass:STRVS s%,[R11,#x%]:]:=""
- MOV(s%,x%)
- perform MOV s%,#x% on second pass only (variable may not exist)
- (pass
- 2)<>0
- [OPTpass:MOV s%,#x%:]
- [OPTpass:MOV s%,#0:]
- TEQ(s%,x%)
- perform TEQ s%,#x% on second pass only (variable may not exist)
- (pass
- 2)<>0
- [OPTpass:TEQ s%,#x%:]
- [OPTpass:TEQ s%,#0:]
- error
- " at line ";
- err(a%,T$)
- A[OPTpass:ADD R0,PC,#0:
- RS PC,R14,#Vflag%:EQUD a%:
- S(T$):]:=""
- com(T$,a%)
- [OPTpass:EQUS T$:EQUB 0:]
- %!O%=0 :
- zero next four bytes
- [OPTpass:ALIGN:EQUD a%:]:=""
- Call zap at entry offset a% Entry R0-R11=args R12=zap workspace
- call(a%)
- [OPTpass
- %:LDR R14,[R12] \ get start of zap table
- &6ADD R14,R14,#a% \ get address of sub
- '9STMFD R13!,{R14} \ save address on stack
- (?MOV R14,PC \ return address (with flags)
- )0LDMFD R13!,{PC} \ call the sub
- * ]:=""
-