; Copyright 1996 Acorn Computers Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; TTL => SysComms , the system commands file: Load save dump etc. TAB * 9 FSUTtemp RN r10 GBLS UtilRegs ; Save the same set so we can common up exits UtilRegs SETS "r7-r10" ; Sam will preserve r0-r6 on module star entry AnyNoParms * &FF0000 ; Between 0 and 255 parameters: all flags clear SysCommsModule ROUT Module_BaseAddr SETA SysCommsModule & 0 ; No Start entry & 0 ; Not initialised & 0 & 0 & 0 & SysTitle-SysCommsModule & SCHCTab-SysCommsModule & 0 & 0 & 0 & 0 [ International_Help <> 0 & MessageFileName-SysCommsModule | & 0 ] SysTitle = "$SystemName", 9 [ :LEN: "$SystemName" < 8 = 9 ] = "$VersionNo", 0 [ Oscli_HashedCommands ; ;***WARNING*** if commands are added or changed, SysCoHashedCmdTab MUST be updated correspondingly ; ] SCHCTab ; Alphabetically ordered so it's easier to find stuff Command Append, 1, 1, International_Help Command Build, 1, 1, International_Help Command Close, 0, 0, International_Help Command Create, 4, 1, International_Help Command Delete, 1, 1, International_Help Command Dump, 3, 1, International_Help Command Exec, 1, 0, International_Help Command FX, 5, 1, International_Help ; 1-3 parms, but up to 2 commas may be there Command GO, 255, 0, International_Help HelpText Command Help, 255, 0, International_Help Command Key, 255, 1, International_Help Command Load, 2, 1, International_Help ; Fudge order for compatibility (*L.) Command List, 3, 1, International_Help Command Opt, 2, 0, International_Help Command Print, 1, 1, International_Help Command Quit, 0, 0, International_Help Command Remove, 1, 1, International_Help Command Save, 6, 2, International_Help ; *SAVE Fn St + Le Ex Lo (compatibility) Command Shadow, 1, 0, International_Help Command Spool, 1, 0, International_Help Command SpoolOn, 1, 0, International_Help Command TV, 3, 0, International_Help Command Type, 3, 1, International_Help ; -file fred -tabexpand = 0 [ Oscli_HashedCommands ; ; - Hashing table is 32 wide ; - Hashing function is: ; ; hash = (sum of all chars of command, each upper-cased) & 0x1f ; ; - Order of commands in each hashed list is alphabetical ; Table MUST be reorganised if hashing function changed, or command set altered ; ALIGN SysCoHashedCmdTab ; ; ! 0,"SysCoHashedCmdTab at ":CC::STR:(SysCoHashedCmdTab) ; ;First, 1 word per table entry, giving offset to hashed list on each hash value ; DCD SHC_hash00 - SysCommsModule DCD 0 ;null list on this hash value DCD SHC_hash02 - SysCommsModule DCD SHC_hash03 - SysCommsModule DCD 0 DCD SHC_hash05 - SysCommsModule DCD SHC_hash06 - SysCommsModule DCD 0 DCD 0 DCD SHC_hash09 - SysCommsModule DCD SHC_hash0A - SysCommsModule DCD 0 DCD 0 DCD SHC_hash0D - SysCommsModule DCD SHC_hash0E - SysCommsModule DCD SHC_hash0F - SysCommsModule DCD SHC_hash10 - SysCommsModule DCD 0 DCD 0 DCD SHC_hash13 - SysCommsModule DCD SHC_hash14 - SysCommsModule DCD 0 DCD SHC_hash16 - SysCommsModule DCD 0 DCD SHC_hash18 - SysCommsModule DCD 0 DCD 0 DCD 0 DCD SHC_hash1C - SysCommsModule DCD 0 DCD SHC_hash1E - SysCommsModule DCD 0 ; ; Now the hashed lists ; SHC_hash00 Command Load, 2, 1, International_Help ; Fudge order for compatibility (*L.) = 0 ALIGN SHC_hash02 Command Type, 3, 1, International_Help ; -file fred -tabexpand = 0 ALIGN SHC_hash03 Command Quit, 0, 0, International_Help = 0 ALIGN SHC_hash05 Command Exec, 1, 0, International_Help = 0 ALIGN SHC_hash06 Command Shadow, 1, 0, International_Help = 0 ALIGN SHC_hash09 Command Help, 255, 0, International_Help Command Key, 255, 1, International_Help = 0 ALIGN SHC_hash0A Command SpoolOn, 1, 0, International_Help Command TV, 3, 0, International_Help = 0 ALIGN SHC_hash0D Command Print, 1, 1, International_Help Command Spool, 1, 0, International_Help = 0 ALIGN SHC_hash0E Command Remove, 1, 1, International_Help = 0 ALIGN SHC_hash0F Command Save, 6, 2, International_Help ; *SAVE Fn St + Le Ex Lo (compatibility) = 0 ALIGN SHC_hash10 Command Build, 1, 1, International_Help = 0 ALIGN SHC_hash13 Command Delete, 1, 1, International_Help Command Opt, 2, 0, International_Help = 0 ALIGN SHC_hash14 Command Create, 4, 1, International_Help = 0 ALIGN SHC_hash16 Command Close, 0, 0, International_Help Command Dump, 3, 1, International_Help Command GO, 255, 0, International_Help = 0 ALIGN SHC_hash18 Command Append, 1, 1, International_Help = 0 ALIGN SHC_hash1C Command List, 3, 1, International_Help = 0 ALIGN SHC_hash1E Command FX, 5, 1, International_Help ; 1-3 parms, but up to 2 commas may be there = 0 ALIGN ;now a small table to fudge around need for old syntax for *fx etc (ie. ;allow zero spaces between command and first, numeric, parameter) ; SHC_fudgeulike Command FX, 5, 1, International_Help ; 1-3 parms, but up to 2 commas may be there Command Key, 255, 1, International_Help Command Opt, 2, 0, International_Help Command TV, 3, 0, International_Help = 0 ALIGN ] ;Oscli_HashedCommands ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Most help and syntax messages go together to save ALIGNing wastage GET s.MosDict GET s.TokHelpSrc GO_Syntax * Module_BaseAddr Help_Syntax * Module_BaseAddr ALIGN ; Just the one, please ! ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ HelpBufferSize * 512 Help_Code ROUT ; got R0 ptr to commtail, R1 no parameters Push "r7, lr" ; first pass round a service call to let wally user code do things. MOV r2, r1 MOV r1, #Service_Help BL Issue_Service CMP r1, #0 Pull "r7, pc", EQ CMP r2, #0 MOVNE r6, r0 addr r6, HelpText, EQ MOV r0, #117 ; Read current VDU status SWI XOS_Byte ; Won't fail SWI XOS_WriteI+14 ; paged mode on. Pull "r7, pc", VS ; Wrch can fail Push "r1" ; Save page mode state MOV r0, r6 MOV r7, #0 ; anyhelpdoneyet flag DoHelpOnNextKeyWord ; now look at syscomms module. addr r1, SysCommsModule BL ShowHelpInModule BVS %FT67 ; now try looking round the modules. LDR R2, =ZeroPage+Module_List 11 LDR R2, [R2] CMP R2, #0 BEQ tryagainstmodulename LDR R1, [R2, #Module_code_pointer] LDR R12, [R2, #Module_incarnation_list] ADD R12, R12, #Incarnation_Workspace BL ShowHelpInModule BVS %FT67 B %BT11 tryagainstmodulename Push "r0" MOV r1, #0 MOV r2, #0 tamn_loop MOV r0, #ModHandReason_GetNames SWI XOS_Module Pull r0, VS BVS %FT02 LDR r0, [stack] ; kword ptr Push "r1, r2" LDR r4, [r3, #Module_TitleStr] CMP r4, #0 BEQ tamn_notit ADD r4, r4, r3 MOV R5, #0 ; offset tamn_chk LDRB R1, [R0, R5] LDRB R2, [R4, R5] CMP R1, #32 CMPLE R2, #32 BLE tamn_dojacko ; matched at terminator UpperCase R1, R6 UpperCase R2, R6 CMP R1, R2 ADDEQ R5, R5, #1 BEQ tamn_chk RSBS R2, R2, #33 ; only if not terminated CMPLE R1, #"." ; success if abbreviation BNE tamn_notit tamn_dojacko BL ModuleJackanory STRVS r0, [stack, #2*4] tamn_notit Pull "r1, r2" Pull r0, VS BVS %FT67 CMP r2, #0 ADDNE r1, r1, #1 MOVNE r2, #0 B tamn_loop 02 LDRB R1, [R0], #1 CMP R1, #"." CMPNE R1, #" " BGT %BT02 CMP R1, #" " BLT %FT67 66 LDRB R1, [R0], #1 CMP R1, #" " BEQ %BT66 SUBGT R0, R0, #1 BGT DoHelpOnNextKeyWord 67 BLVC testnohelpdone Pull "R1" MRS r6, CPSR TST R1, #5 SWIEQ XOS_WriteI+15 ; paged mode off MSR CPSR_f, r6 ; restore V state Pull "r7, PC" testnohelpdone CMP r7, #0 MOVNE pc, lr MOV r7, lr [ International BL WriteS_Translated = "NoHelp:No help found.",10,13,0 ALIGN | SWI XOS_WriteS = "No help found.",10,13,0 ALIGN ] MOV pc, r7 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ModuleJackanory ROUT ; give summary of info in module @ r3 Push "r0, lr" CheckSpaceOnStack HelpBufferSize+256, modjack_noroom, r6 SUB stack, stack, #HelpBufferSize MOV r2, r3 LDR r3, [r2, #Module_TitleStr] CMP r3, #0 ADDNE r3, r3, r2 ADREQL r3, NoRIT BL PrintMatch BVS %FT99 LDR r3, [r2, #Module_HelpStr] CMP r3, #0 BEQ nohstring STMDB sp!, {r2, r3} LDR r2, =ZeroPage ; Try our message file before Global. LDR r0, [r2, #KernelMessagesBlock] TEQ r0, #0 ADDNE r0, r2, #KernelMessagesBlock+4 ADRL r1, modjack_hstr [ ZeroPage <> 0 MOV r2, #0 ] SWI XMessageTrans_Lookup SWIVC XMessageTrans_Dictionary MOVVC r1, r0 MOVVC r0, r2 SWIVC XOS_PrettyPrint SWIVC XOS_WriteI + 32 LDMIA sp!, {r2, r3} ADDVC r0, r2, r3 SWIVC XOS_PrettyPrint BVS %FT99 nohstring MOV r3, stack ; buffer address MOV r1, #0 ; flags for commands ADRL r0, modjack_comms BL OneModuleK_Lookup MOVVC r1, #FS_Command_Flag ADRVCL r0, modjack_filecomms BLVC OneModuleK_Lookup MOVVC r1, #Status_Keyword_Flag ADRVCL r0, modjack_confs BLVC OneModuleK_Lookup MOVVC r1, #-1 ADRVCL r0, modjack_aob BLVC OneModuleK_Lookup 99 ADD stack, stack, #HelpBufferSize SWIVC XOS_NewLine 98 STRVS r0, [stack] Pull "r0, PC" modjack_noroom ADRL r0, ErrorBlock_StackFull [ International BL TranslateError | SETV ] B %BT98 OneModuleK_Lookup STMDB sp!, {r1-r3, lr} MOV r1, r0 LDR r2, =ZeroPage ; Try our message file before Global. LDR r0, [r2, #KernelMessagesBlock] TEQ r0, #0 ADDNE r0, r2, #KernelMessagesBlock+4 [ ZeroPage <> 0 MOV r2, #0 ] SWI XMessageTrans_Lookup MOVVC r0, r2 LDMIA sp!, {r1-r3, lr} MOVVS pc, lr B OneModuleK ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Print match header, keyword @ r3 PrintMatch ROUT [ International Push "r0-r4, lr" SWI XOS_ReadEscapeState BLCS AckEscape BVS %FT99 SWI XOS_WriteI+CR MOVVC r4,r3 BL WriteS_Translated_UseR4 = "HelpFound:==> Help on keyword %0",0 ALIGN SWIVC XOS_NewLine 99 STRVS R0, [stack] MOV R7, #1 Pull "r0-r4, PC" | Push "r0-r2, lr" SWI XOS_ReadEscapeState BLCS AckEscape ADRVC r0, HelpMatchString MOV r2, r3 SWIVC XOS_PrettyPrint ; print matched keyword SWIVC XOS_NewLine STRVS R0, [stack] MOV R7, #1 Pull "r0-r2, PC" HelpMatchString = CR, "==> Help on keyword ",TokenEscapeChar,Token0, 0 ALIGN ] ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ShowHelpInModule ROUT ; take module ptr in R1, give relevant help. Push "R2-R6, lr" LDR R2, [R1, #Module_HC_Table] CMP R2, #0 Pull "R2-R6, PC", EQ ADD R2, R1, R2 ; point at table fujjnulltables LDRB R5, [R2] CMP R5, #0 BNE %FT21 Pull "R2-R6, PC" ; finished 21 MOV R3, #0 ; offset 22 LDRB R4, [R0, R3] LDRB R5, [R2, R3] CMP R4, #32 CMPLE R5, #32 BLE %FT25 ; matched at terminator UpperCase R4, R6 UpperCase R5, R6 CMP R4, R5 ADDEQ R3, R3, #1 BEQ %BT22 RSBS R5, R5, #33 ; only if not terminated CMPLE R4, #"." ; success if abbreviation BEQ %FT25 ADD R2, R2, R3 23 LDRB R5, [R2], #1 CMP R5, #32 BGT %BT23 ; skip to terminator ADD R2, R2, #3 BIC R2, R2, #3 ; ALIGN 24 ADD R2, R2, #16 B fujjnulltables 25 ADD R2, R2, R3 SUB R3, R2, R3 ; hang on to keyword ptr 28 LDRB R5, [R2], #1 CMP R5, #0 BNE %BT28 ; demand null terminator ADD R2, R2, #3 BIC R2, R2, #3 ; ALIGN LDR R5, [R2, #12] ; get help offset CMP R5, #0 BEQ %BT24 ; no help. BL PrintMatch ; r3 -> keyword Pull "R2-R6, PC", VS LDR R6, [R2, #4] ; get info word TST R6, #Help_Is_Code_Flag BNE CallHelpKeywordCode Push "R0-r3" TST R6, #International_Help BEQ %FT35 SUB sp, sp, #16 LDR r2, [r1, #-4] LDR r0, [r1, #Module_MsgFile] TST r0, #12,2 CMPEQ r0, #1 CMPCS r2, r0 MOVLS r0, #0 BLS %FT29 ADD r1, r1, r0 MOV r2, #0 MOV r0, sp SWI XMessageTrans_OpenFile MOVVS r0, #0 29 MOV r6, r0 LDR r1, [sp, #16 + 1 * 4] ADD r1, r5, r1 MOV r2, #0 SWI XMessageTrans_Lookup ADDVS r2, r0, #4 SWI XMessageTrans_Dictionary MOVVS r0, #0 MOV r1, r0 MOV r0, r2 LDR r2, [sp, #16 + 3 * 4] SWI XOS_PrettyPrint ; Error check not done yet SWI XOS_NewLine MOV r0, r6 LDR r2, [sp, #16 + 2 * 4] LDR R5, [r2, #8] CMP R5, #0 BEQ %FT30 ; Should print default message? LDR r1, [sp, #16 + 1 * 4] ADD r1, r5, r1 MOV r2, #0 SWI XMessageTrans_Lookup ADDVS r2, r0, #4 SWI XMessageTrans_Dictionary MOVVS r0, #0 MOV r1, r0 MOV r0, r2 LDR r2, [sp, #16 + 3 * 4] SWI XOS_PrettyPrint ; No Error check!!! SWI XOS_NewLine 30 MOVS r0, r6 SWINE XMessageTrans_CloseFile ADD sp, sp, #16 Pull "R0-R3" B %BT24 35 ADD R0, R5, R1 MOV r1, #0 MOV r2, r3 SWI XOS_PrettyPrint SWIVC XOS_NewLine STRVS R0, [stack] Pull "R0-r3" Pull "R2-R6, PC", VS B %BT24 helpnostack ADRL R0, ErrorBlock_StackFull [ International BL TranslateError | SETV ] Pull "R2-R6, pc" CallHelpKeywordCode CheckSpaceOnStack HelpBufferSize+256, helpnostack, R6 SUB stack, stack, #HelpBufferSize Push "R0-R2, R12" ; code allowed to corrupt R1-R6, R12 MOV R2, R1 ADD R0, stack, #4*4 MOV R1, #HelpBufferSize MOV lr, PC ; R12 set by our caller ADD PC, R5, R2 BVS hkc_threwawobbly CMP R0, #0 MOVNE r1, #0 SWINE XOS_PrettyPrint SWIVC XOS_NewLine hkc_threwawobbly STRVS R0, [stack] Pull "R0-R2, R12" ADD stack, stack, #HelpBufferSize BVC %BT24 Pull "R2-R6, PC" ;************************************************************************** GO_Code ROUT Push "R7, lr" MOV R4, R0 BL SPACES CMP R5, #13 TEQNE R5, #";" MOVLS R7, #AppSpaceStart BCC GOEX BEQ GOEX0 BL ReadHex MOVVS R7, #AppSpaceStart BL SPACES GOEX0 TEQ R5, #";" BLEQ SPACES GOEX SUB R1, R4, #1 MOV R0, #FSControl_StartApplication MOV R2, R7 ADR R3, GOSMUDGE SWI XOS_FSControl Pull "R7, PC", VS LDR sp_svc, =SVCSTK ; remove supervisor stuff WritePSRc 0, R14 ; in to user mode MOV PC, R7 GOSMUDGE = "GO ", 0 ALIGN ReadHex Push "R0-R2, lr" MOV R0, #16 SUB R1, R4, #1 SWI XOS_ReadUnsigned MOV R4, R1 MOV R7, R2 Pull "R0-R2, PC" SPACES LDRB R5, [R4], #1 TEQ R5, #" " BEQ SPACES MOV PC, R14 ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Close_Code Entry MOV R0, #0 MOV R1, #0 SWI XOS_Find EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FX_Code Entry MOV R1, #0 MOV R2, #0 Push "R1-R2" ; Put optional parms (default 0, 0) on stack MOV R1, R0 MOV R0, #10 SWI XOS_ReadUnsigned Push "R2" ; Pulled as R0 when OSByte called BVS %FT90 BL %FT10 TV_EntryPoint MOV R0, #10 SWI XOS_ReadUnsigned BVS %FT90 STR R2, [stack, #4] BL %FT10 MOV R0, #10 SWI XOS_ReadUnsigned BVS %FT90 STR R2, [stack, #8] BL %FT10 ; check for EOL: goes to 05 if end ADR R0, ErrorBlock_TooManyParms [ International BL TranslateError | SETV ] 90 ADD sp, sp, #12 ; Error before we'd pulled r0-r2 for osbyte EXIT MakeErrorBlock TooManyParms 05 Pull "R0-R2" SWI XOS_Byte EXIT ; Skip leading spaces and optional comma 10 LDRB R2, [R1], #1 CMP R2, #" " BEQ %BT10 CMP R2, #"," MOVEQ PC, lr ; Let ReadUnsigned strip leading spaces. CMP R2, #CR CMPNE R2, #LF CMPNE R2, #0 BEQ %BT05 ; Terminated command, so execute the osbyte SUB R1, R1, #1 ; Back to first char MOV PC, lr TV_Code ALTENTRY ; must be same as FX_Code ! MOV R1, #144 ; OSBYTE number MOV R2, #0 MOV R14, #0 Push "R1, R2, lr" MOV R1, R0 B TV_EntryPoint Shadow_Code Entry CMP R1, #0 MOV R1, R0 MOV R0, #10 + (1:SHL:30) SWINE XOS_ReadUnsigned MOVEQ R2, #0 EXIT VS BL CheckEOL BNE ShadowNaff MOV R0, #114 MOV R1, R2 SWI XOS_Byte EXIT ShadowNaff ADRL R0, ErrorBlock_BadNumb [ International BL TranslateError | SETV ] EXIT CheckEOL LDRB R0, [R1], #1 CMP R0, #" " CMPNE R0, #13 CMPNE R0, #10 CMPNE R0, #0 MOV PC, lr ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Key_Code Entry SUB sp, sp, #32 MOV R1, R0 MOV r6, sp LDR R2, %FT02 ; Load 'Key$' STR R2, [R6], #4 MOV R0, #10 + (1 :SHL: 29) ; default base MOV R2, #15 ; maximum key SWI XOS_ReadUnsigned BVS %FT90 CMP R2, #10 MOVGE R4, #"1" STRGEB R4, [R6], #1 SUBGE R2, R2, #10 ADD R2, R2, #"0" STRB R2, [R6] MOV R2, #0 STRB R2, [R6, #1] MOV R0, sp MOV R3, #0 MOV R4, #VarType_String SWI XOS_SetVarVal 80 ADD sp, sp, #32 EXIT 90 ADR r0, ErrorBlock_BadKey [ International BL TranslateError | SETV ; It needs setting here ! ] B %BT80 MakeErrorBlock BadKey 02 DCB "Key$" ; Must be aligned ALIGN LTORG ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Exec, Spool and SpoolOn share a common body Exec_Code Entry "$UtilRegs" MOV r3, #&40 ; OPENIN exec MOV r4, #198 ; r0b for osbyte exec B %FT01 Spool_Code ALTENTRY MOV r3, #&80 ; OPENOUT spool B %FT00 SpoolOn_Code ALTENTRY MOV r3, #&C0 ; OPENUP spoolon 00 MOV r4, #199 ; r0b for osbyte spool/spoolon 01 MOV r5, r0 ; Save filename^ MOV r6, r1 ; Save n parms MOV r0, r4 ; Read old exec/spool handle MOV r1, #0 ; Write 0 as handle; we may be just closing MOV r2, #0 ; and keep zero if open error (cf. RUN) SWI XOS_Byte ; Won't cause error BL CloseR1 EXIT VS CMP r6, #0 ; No filename present ? EXIT EQ ; ie. just closing down exec/spool ? MOV r1, r5 ; -> filename MOV r0, r3 ; OPENIN exec/OPENUP spoolon/OPENOUT spool BL OpenFileWithWinge EXIT VS CMP r3, #&C0 ; Doing SPOOLON ? VClear BLEQ MoveToEOF ; PTR#r1:= EXT#r1 MOV r0, r4 ; Write new exec/spool handle (r1) MOV r2, #0 SWIVC XOS_Byte ; May have got error in moving to EOF EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; List, Print and Type share a common body listopt RN r2 lastchar RN r3 linecount RN r4 charcount RN r5 lnum * 2_01 ; Line numbers type * 2_10 ; GSREAD format ? filterprinting * 2_10000000 ; Bits controlling printing linenumbering * 2_01000000 expandtabs * 2_00100000 forcetbsrange * 2_00001000 allowtbschar * 2_00000100 unprintangle * 2_00000010 unprinthex * 2_00000001 unprintdot * 2_00000001 Print_Code Entry "$UtilRegs" MOV listopt, #0 ; No line numbers, raw ASCII B %FT01 List_Code ALTENTRY MOV listopt, #(filterprinting + linenumbering) MOV linecount, #0 B %FT00 TypeArgs = "File/A,TabExpand/S",0 ALIGN Type_Code ALTENTRY MOV listopt, #filterprinting 00 MOV r6, r1 ; no. params BL ReadGSFormat ; Read configured GSFormat bits EXIT VS ; I2C could be faulty ! File not open ORR listopt, listopt, r1 CMP r6, #1 BEQ %FT01 Push "R2, R3" MOV R1, R0 ; args given ADR R0, TypeArgs LDR R2, =ArgumentBuffer MOV R3, #LongCLISize SWI XOS_ReadArgs Pull "R2, R3", VS EXIT VS LDR R0, [R2, #4] ; tabflag CMP R0, #0 LDR R0, [R2, #0] ; filename ptr Pull "R2, R3" ORRNE listopt, listopt, #expandtabs 01 MOV lastchar, #0 ; Reset NewLine indicator MOV r1, r0 ; Point to filename MOV r0, #&40 ; han := OPENIN <filename> BL OpenFileWithWinge EXIT VS 10 SWI XOS_ReadEscapeState ; Won't cause error BCS CloseThenAckEscape MOV charcount, #0 ; No characters printed this line SWI XOS_BGet ; Get first character of line BVS UtilityExitCloseR1 BCS UtilityExitCloseR1 ; EOF ? TST listopt, #linenumbering ; Do we want to print the line number ? BLNE LineNumberPrint BVS UtilityExitCloseR1 ; Doing ASCII (print) or GSREAD (type, list) ? 30 TST listopt, #filterprinting BEQ %FT35 ; GSREAD format printing CMP r0, #CR ; CR and LF both line terminators CMPNE r0, #LF BEQ %FT70 CMP r0, #TAB BNE %FT31 TST listopt, #expandtabs BEQ %FT31 ; simple tab expansion: 8 spaces SWI XOS_WriteS = " ",0 ALIGN B %FT32 31 MOV lastchar, r0 CMP r0, #"""" ; Don't display quotes in GSREAD though CMPNE r0, #"<" ; Or left angle BEQ %FT35 BL PrintCharInGSFormat 32 BVC %FT40 35 SWIVC XOS_WriteC BVS UtilityExitCloseR1 ADD charcount, charcount, #1 40 SWI XOS_ReadEscapeState ; Won't cause error BCS CloseThenAckEscape SWI XOS_BGet ; Get another character on this line BVS UtilityExitCloseR1 BCC %BT30 ; Loop if not EOF 50 TST listopt, #filterprinting SWINE XOS_NewLine ; Terminate with NewLine if not *Print B UtilityExitCloseR1 ; Hit LF or CR in GSFormat mode, decide whether to give a NewLine or not 70 CMP r0, lastchar ; NewLine if same as last time eg LF,LF SWIEQ XOS_NewLine BVS UtilityExitCloseR1 BEQ %BT10 ; Loop back and do another line CMP lastchar, #CR ; Don't give another NewLine if we've CMPNE lastchar, #LF ; had CR, LF or LF, CR MOVEQ lastchar, #0 ; Reset NewLine indicator so more will BEQ %BT40 ; Loop and do more chars in this line MOV lastchar, r0 ; Save char forcing this NewLine SWI XOS_NewLine ; Do NewLine then another line BVC %BT10 B UtilityExitCloseR1 ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Dump_Code Entry "$UtilRegs" MOV r7, r1 ; Remember nparms MOV r8, r0 ; Remember filename^ for below MOV r1, r0 ; -> filename MOV r0, #&40 ; han := OPENIN <filename> BL OpenFileWithWinge EXIT VS ; File not yet open MOV r9, r1 ; Save handle MOV r0, #OSFile_ReadWithType MOV r1, r8 ; Restore filename^ SWI XOS_File ; Must exist and be a file now MOVVS r1, r9 ; Restore handle in case of error/exit BVS UtilityExitCloseR1 TEQ r0, #object_nothing ; It opened a moment ago, assume stream ; like file (or broken FS). Rely on EOF. MOVEQ r6, #0 MOVEQ r4, #-1 MOV r5, r9 ; Standard place for handle below ; Default display at load addr of file (r2) unless special BL ReadGSFormat ; Only interested in some bits MOVVS r1, r5 BVS UtilityExitCloseR1 AND r10, r1, #forcetbsrange + allowtbschar CMP r6, #-1 ; Unstamped file ? MOVNE r2, #0 ; Display start = 0 MOV r3, #0 ; Default PTR# = 0 ; Funny order 'cos of ReadOptionalLoadAndExec CMP r7, #1 ; Only filename specified ? BEQ %FA10 ; If so, use loadaddr and ptr=0 MOV r1, r8 ; Get back filename^ BL SkipToSpace ; Over the filename BL ReadOptionalLoadAndExec ; Abuse ! r3 := start, r2 := disp start MOVVS r1, r5 BVS UtilityExitCloseR1 ADD r2, r3, r2 ; Display offset = disparm/loadaddr+ptr 10 Swap r2, r3 ; r2 := start, r3 := disp start CMP r2, r4 ; Is ptr > ext ? MOV r1, r5 BLS %FT11 BL SetErrorOutsideFile BVS UtilityExitCloseR1 11 MOV r0, #OSArgs_SetPTR SWI XOS_Args ; PTR#r1 := start offset MOVVC r7, #0 BLVC ReadWindowWidth BVS UtilityExitCloseR1 SUB r9, r0, #12+1 ; -ExtraFields (address and separators) MOV r9, r9, LSR #2 ; Two nibbles, one space and one char per byte Push r10 ; Save format bits MOV r10, #(1 :SHL: 31) ; Move 1 bit down until not zero 12 MOVS r10, r10, LSR #1 MOVEQ r9, #1 ; Always 1 byte per line at least BEQ %FT15 TST r10, r9 ; Mask against r9 (byte count) BEQ %BT12 ; Not hit yet ? AND r9, r9, r10, LSR #1 ; Take the bit one lower down ORR r9, r9, r10 ; And the bit we matched. Yowzay ! 15 MOV r1, r5 ; Get handle back Pull r10 ; Get format back SUB sp, sp, #256 ; Need temp frame now ; Main Dump loop 30 SWI XOS_ReadEscapeState ; Won't cause error ADDCS sp, sp, #256 BCS CloseThenAckEscape ; Get line of data (r9 bytes). Keep track of how many bytes were read in r4 MOV r2, sp ; Temp buffer MOV r4, #0 35 SWI XOS_BGet ; Fall out of loop if EOF BVS UtilityExitCloseR1_256 STRCCB r0, [r2, r4] ADDCC r4, r4, #1 CMPCC r4, r9 BCC %BT35 CMP r4, #0 ; No bytes to do this line ? BEQ UtilityExitCloseR1_256 ; Must preserve r4 till end for testing ANDS r7, r7, #15 ; Print title every 16 lines of data BNE %FT54 [ International SWI XOS_NewLine BL WriteS_Translated DCB "Address:Address :",0 ALIGN | SWI XOS_WriteS ; Print title start DCB LF, CR DCB "Address :", 0 ALIGN ] BVS UtilityExitCloseR1_256 MOV r8, #0 50 ADD r0, r3, r8 ; Print byte == LSB of SWI XOS_WriteI+" " ; display across page BLVC HexR0Byte BVS UtilityExitCloseR1_256 ADD r8, r8, #1 CMP r8, r9 BNE %BT50 CMP r9, #11 ; No room to print title end ? BLO %FT52 ; VClear SWI XOS_WriteS DCB " : ", 0 ALIGN BVS UtilityExitCloseR1_256 SUB r8, r9, #10 ; Centre 'ASCII data' over data MOVS r8, r8, LSR #1 51 SUBS r8, r8,#1 ; VClear SWI XOS_WriteI+" " BVS UtilityExitCloseR1_256 BPL %BT51 [ International BL WriteS_Translated DCB "ASCII:ASCII data",0 ALIGN | SWI XOS_WriteS DCB "ASCII data", 0 ALIGN ] 52 SWIVC XOS_NewLine SWIVC XOS_NewLine 54 MOVVC r0, r3 ; Print start of line address BLVC HexR0LongWord SWIVC XOS_WriteI+" " SWIVC XOS_WriteI+":" BVS UtilityExitCloseR1_256 ; Print line of data in hex MOV r5, #0 55 LDRB r0, [r2, r5] SWI XOS_WriteI+" " BVS UtilityExitCloseR1_256 CMP r5, r4 ; Byte valid ? SWICS XOS_WriteI+" " BVS UtilityExitCloseR1_256 SWICS XOS_WriteI+" " BVS UtilityExitCloseR1_256 BLCC HexR0Byte ; Alters C, so do last BVS UtilityExitCloseR1_256 ADD r5, r5, #1 CMP r5, r9 BCC %BT55 SWI XOS_WriteS DCB " : ", 0 ALIGN BVS UtilityExitCloseR1_256 ; Print line of data in ASCII MOV r5, #0 65 LDRB r0, [r2, r5] TST r10, #forcetbsrange ; Forcing into 00..7F ? BICNE r0, r0, #&80 TST r10, #allowtbschar BEQ %FT66 CMP r0, #&80 ; Print tbs unmolested BHS %FT67 66 CMP r0, #" " ; Space through twiddle are valid RSBGES r14, r0, #&7E MOVLT r0, #"." 67 SWI XOS_WriteC BVS UtilityExitCloseR1_256 ADD r5, r5, #1 CMP r5, r4 BCC %BT65 SWI XOS_NewLine BVS UtilityExitCloseR1_256 ADD r7, r7, #1 ; Increment line count ADD r3, r3, r9 ; Increment display address by r9 bytes CMP r4, r9 ; Loop till we couldn't fill a line BEQ %BT30 ; ............................................................................. UtilityExitCloseR1_256 ADD sp, sp, #256 ; Kill temp frame ; ............................................................................. UtilityExitCloseR1 BL CloseR1 ; Accumulates V Pull "$UtilRegs, pc" ; Back to *Command handler ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Append and Build share a common body Append_Code Entry "$UtilRegs" MOV r1, r0 ; -> filename MOV r0, #&C0 ; OPENUP B %FT01 Build_Code ALTENTRY MOV r1, r0 ; -> filename MOV r0, #&80 ; OPENOUT 01 BL OpenFileWithWinge EXIT VS SUB sp, sp, #256 MOV r5, r1 ; Save handle for later BL MoveToEOF ; Can do this anyhow as ext#(openout)=0 MOV linecount, #0 10 BLVC LineNumberPrint ; Escape is tested for on OS_ReadLine.Err below BVS UtilityExitCloseR1_256 MOV r0, sp ; Get a line from Joe Punter MOV r1, #256-1 ; -1 for terminator MOV r2, #" " MOV r3, #&FF SWI XOS_ReadLine32 MOVVS r1, r5 BVS UtilityExitCloseR1_256 MOV r3, #CR ; Terminate source string STRB r3, [r0, r1] MOVCC FSUTtemp, #0 ; Ended with ESCAPE ? MOVCS FSUTtemp, #-1 MOVCS r0, #&7E ; Ack. ESCAPE, not error SWICS XOS_Byte BVS UtilityExitCloseR1_256 MOV r2, sp ; r2 -> buffer to translate MOV r1, r5 ; Get handle back 18 LDRB r0, [r2], #1 ; Put all the spaces out ourselves ! CMP r0, #" " ; VClear SWIEQ XOS_BPut BVS UtilityExitCloseR1_256 BEQ %BT18 SUB r0, r2, #1 ; r0 -> past spaces, rest to translate MOV r2, #(1 :SHL: 31) ; No quote funnies, don't end on space, do | SWI XOS_GSInit 20 SWIVC XOS_GSRead ; Get a char MOVVS R1, R5 BVS UtilityExitCloseR1_256 BCS %FT30 ; End of string ? MOV r3, r0 ; Save GSState MOV r0, r1 ; Char from GSRead MOV r1, r5 ; Get handle back SWI XOS_BPut BVS UtilityExitCloseR1_256 MOV r0, r3 ; Restore GSState B %BT20 ; And loop 30 CMP FSUTtemp, #0 ; Did we read ESCAPE ? VClear MOV r1, r5 ; In any case, we want r1 handle MOV r0, #CR ; If not, stick a CR on eoln SWIEQ XOS_BPut BEQ %BT10 ; Finished if ESCAPE was pressed ; Catch error back there too SWIVC XOS_NewLine B UtilityExitCloseR1_256 ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; OSFile routines: Load, Save, Create, Delete and Remove Load_Code Entry "$UtilRegs" MOV r7, r0 ; -> filename CMP r1, #1 ; Just filename (1 parm) ? MOVEQ r3, #&FF ; Load at its own address if so BEQ %FT90 BL SkipNameAndReadAddr EXIT VS BLCS SetErrorBadAddress ; Must check for trailing junk MOVVC r3, #0 ; Got load address from command line 90 MOVVC r0, #OSFile_Load ORRVC r3, r3, #1<<31 ; Do OS_SynchroniseCodeAreas after load MOVVC r1, r7 ; Get filename^ back SWIVC XOS_File EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Save_Error DCD ErrorNumber_Syntax [ International DCB "BadSav:Bad parameters for *Save", 0 ] ALIGN Save_Code Entry "$UtilRegs" BL SkipNameAndReadAddr EXIT VS MOV r4, r2 ; Got start address BL SkipSpaces MOV r5, r0 ; Preserve state CMP r0, #"+" ; Is it a +<length> parm ? ADDEQ r1, r1, #1 ; Skip '+' then BLEQ SkipSpaces ; And any trailing spaces BL ReadAtMost8Hex ; Read a word anyway EXIT VS CMP r5, #"+" MOVNE r5, r2 ; <end addr> ? ADDEQ r5, r2, r4 ; Form <end addr> := <start addr> + <length> MOV r2, r4 ; r2, r3 := both r4 by default MOV r3, r4 BL ReadOptionalLoadAndExec SETV CS ADRVS R0, Save_Error ; If there's anything on the end, it's an error [ International BLVS TranslateError ] MOVVC r0, #OSFile_Save MOVVC r1, r7 ; Get filename^ back SWIVC XOS_File EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Create_Code Entry "r1, $UtilRegs" CMP r1, #1 ; Filename only -> length 0, dated MOVEQ r7, r0 ; Filename^ MOVEQ r2, #0 ; Will be copied to r5 in a bit BLNE SkipNameAndReadAddr EXIT VS MOV r5, r2 ; Got length, put in as end address MOV r4, #0 ; So start addr shall be .. 0 ! LDR r14, [sp] ; No load, exec -> datestamp FFD CMP r14, #3 MOVLO r0, #OSFile_CreateStamp LDRLO r2, =&FFFFFFFD ; Only bottom 12 bits are of interest MOVHS r0, #OSFile_Create ; Makes it an immediate constant MOVHS r2, #0 ; Load/Exec default to 0 MOVHS r3, #0 BLHS ReadOptionalLoadAndExec MOVVC r1, r7 ; Get filename^ back SWIVC XOS_File EXIT LTORG ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Delete and Remove share a common body Delete_Code Entry MOV r6, #0 ; Give error if file doesn't exist B %FT01 ; Use a reg. not affected by OSFile ! Remove_Code ALTENTRY MOV r6, #-1 ; Don't winge 01 MOV r1, r0 ; -> filename MOV r0, #OSFile_Delete SWI XOS_File EXIT VS ASSERT object_nothing = 0 CMP r0, r6 ; Are we going to winge ? MOVEQ r0, #OSFile_MakeError ; Give pretty error now, says Tutu MOVEQ r2, #object_nothing SWIEQ XOS_File EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Gosh, doesn't use UtilRegs !!! Opt_Code Entry MOV r3, #0 ; Default parms are 0, 0 MOV r4, #0 CMP r1, #0 ; No parms ? VClear BEQ %FT50 MOV r1, r0 MOV r0, #10 ; Default base 10, allow naff term ',' SWI XOS_ReadUnsigned ; Read first parm EXIT VS MOV r3, r2 BL FS_SkipSpaces ; Try getting another parm anyway BCC %FT50 ; End of the line TEQ r0, #"," ; commas too ! ADDEQ r1, r1, #1 BLEQ FS_SkipSpaces CMP r0, #space ; Anything here ? BEQ %FT99 MOV r0, #(1 :SHL: 31) + 10 ; Default base 10, no bad terms SWI XOS_ReadUnsigned ; Read second parm MOVVC r4, r2 50 MOVVC r0, #FSControl_Opt MOVVC r1, r3 MOVVC r2, r4 SWIVC XOS_FSControl EXIT 99 ADR r0, SyntaxError_StarOpt [ International BL TranslateError | SETV ] EXIT SyntaxError_StarOpt DCD ErrorNumber_Syntax DCB "OptErr:Syntax: *Opt [<x> [[,] <y>]]", 0 ALIGN ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; H o r r i b l e l i t t l e s u b r o u t i n e s ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Variegated output routines HexR0LongWord Entry "r0" MOV r0, r0, ROR #16 BL HexR0Word MOVVC r0, r0, ROR #32-16 BLVC HexR0Word STRVS r0, [sp] EXIT HexR0Word Entry "r0" MOV r0, r0, ROR #8 BL HexR0Byte MOVVC r0, r0, ROR #32-8 BLVC HexR0Byte STRVS r0, [sp] EXIT HexR0Byte Entry "r0" MOV r0, r0, ROR #4 BL HexR0Nibble MOVVC r0, r0, ROR #32-4 BLVC HexR0Nibble STRVS r0, [sp] EXIT HexR0Nibble Entry "r0" AND r0, r0, #15 CMP r0, #10 ADDCC r0, r0, #"0" ADDCS r0, r0, #"A"-10 SWI XOS_WriteC STRVS r0, [sp] EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SkipSpaces ROUT 10 LDRB r0, [r1], #1 CMP r0, #" " ; Leave r1 -> ~space BEQ %BT10 SUB r1, r1, #1 CLRV MOV pc, lr ; r0 = first ~space. Can't really fail SkipToSpace Entry 10 LDRB lr, [r1], #1 CMP lr, #&7F CMPNE lr, #" " ; Leave r1 -> space or CtrlChar BHI %BT10 SUB r1, r1, #1 CLRV EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; In r1 -> string ; Out flags from CMP r0, #space for eol detection FS_SkipSpaces ROUT 10 LDRB r0, [r1], #1 CMP r0, #space ; Leave r1 -> ~space BEQ %BT10 SUB r1, r1, #1 MOV pc, lr ; r0 = first ~space ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; In r0 = open mode ; r1 -> filename ; Out VC: r0 = r1 = handle ; VS: r0 -> error (FilingSystemError or 'NotFound') OpenFileWithWinge Entry ORR r0, r0, #(open_mustopen :OR: open_nodir) ; Saves us code here SWI XOS_Find MOVVC r1, r0 EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; PTR#handle := EXT#handle ; In r1 = handle to use ; Out VC: PTR moved ; VS: r0 -> Filing System Error MoveToEOF Entry "r0, r2" MOV r0, #OSArgs_ReadEXT SWI XOS_Args MOVVC r0, #OSArgs_SetPTR SWIVC XOS_Args STRVS r0, [sp] EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CloseThenAckEscape BL CloseR1 BL AckEscape Pull "$UtilRegs, pc" ; Common exit - back to MOS ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; In r1 = handle to close, or 0 means don't do anything ; Out VC: file closed, or nothing done ; VS: r0 -> Filing System Error, or VSet on entry CloseR1 EntryS "r0" CMP r1, #0 ; Is there a handle to close ? VClear MOVNE r0, #0 ; CLOSE#han SWINE XOS_Find EXITS VC ; Accumulate V STR r0, [sp] EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Increment then print a line number in decimal LineNumberPrint Entry "r0-r1" ADD linecount, linecount, #1 ; r0 := ++linecount MOV r0, linecount MOV r1, #1 ; Print leading spaces BL PrintR0Decimal SWIVC XOS_WriteI+" " STRVS r0, [sp] EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; In r0 = number to print ; r1 = 0 -> strip spaces ; 1 -> print leading spaces ; Number gets printed RJ in a field of 4 if possible, or more as necessary PrintR0Decimal Entry "r0-r3" SUB sp, sp, #32 MOV r3, r1 ; Save flag MOV r1, sp MOV r2, #32 SWI XOS_BinaryToDecimal ; No errors from this CMP r3, #0 ; If not doing spaces or >= 4 chars CMPNE r2, #4 ; in the number, son't print any ADRLT r0, %FT98-1 ; Point to right amount of spaces ADDLT r0, r0, r2 SWILT XOS_Write0 10 LDRVCB r0, [r1], #1 SWIVC XOS_WriteC BVS %FT99 SUBS r2, r2, #1 BNE %BT10 99 ADD sp, sp, #32 STRVS r0, [sp] EXIT 98 DCB " ", 0 ; Three spaces, null ALIGN ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Read configured GS string format ; ; Out r1 = bits read from CMOS ram ReadGSFormat Entry "r0, r2" MOV r0, #ReadCMOS MOV r1, #PrintSoundCMOS SWI XOS_Byte ANDVC r1, r2, #2_1111 ; Mask out all but my bits STRVS r0, [sp] EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; In r0b = char to print using current listopt ; Out r0 corrupt PrintCharInGSFormat Entry "r1, listopt" AND r0, r0, #&FF ; Just in case TST listopt, #forcetbsrange ; Forcing tbs into 00..7F ? BIC listopt, listopt, #forcetbsrange BICNE r0, r0, #&80 ; Take top bit out if so CMP r0, #" " ; Do we need to do this at all ? RSBGES r14, r0, #&7E BLT %FT10 ; LT if not in range &20-&7E CMP r0, #"|" ; Solidus ? VClear CMPNE r0, #"""" ; Quote ? CMPNE r0, #"<" ; Left angle ? SWINE XOS_WriteC ; Nope, so let's print the char and exit EXIT VS EXIT NE 10 TST listopt, #allowtbschar ; International format bit ? BIC listopt, listopt, #allowtbschar BEQ %FT15 CMP r0, #&80 BHS %FT45 ; Print tbs char and exit 15 TST listopt, #unprintangle ; Angle bracket format ? BNE %FT50 TST listopt, #unprintdot ; Doing unprintable dot format (2_01) ? BEQ %FT16 CMP r0, #" " ; Only space to twiddle are printable RSBGES r14, r0, #&7E MOVLT r0, #"." ; All others are dot B %FT45 ; Print char and exit ; Normal BBC GSREAD format (2_00) 16 CMP r0, #&80 ; Deal with tbs first BIC r0, r0, #&80 BLO %FT17 SWI XOS_WriteI+"|" SWIVC XOS_WriteI+"!" EXIT VS 17 CMP r0, #&7F ; Delete ? -> |?. VClear MOVEQ r0, #"?" CMPNE r0, #"""" ; Quote ? -> |" CMPNE r0, #"|" ; Solidus ? -> || SWIEQ XOS_WriteI+"|" EXIT VS CMP r0, #&1F ; CtrlChar ? -> |<char+@>. VClear ADDLS r0, r0, #"@" SWILS XOS_WriteI+"|" 45 SWI XOS_WriteC ; Used from above EXIT 50 ; Angle bracket format, either hex (2_11) or decimal (2_10) SWI XOS_WriteI+"<" TST listopt, #unprinthex BNE %FT60 MOV r1, #0 ; Strip leading spaces BLVC PrintR0Decimal SWIVC XOS_WriteI+">" EXIT 60 SWIVC XOS_WriteI+"&" BLVC HexR0Byte SWIVC XOS_WriteI+">" EXIT ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; In r0 -> filename. Used by most MOS OSFile routines for initial decoding ; Out r1 -> past address read ; r2 = address read ; r7 = initial filename^ ; VS : failed to read address, r0 -> error ; CS : text present comes immediately after address SkipNameAndReadAddr Entry MOV r7, r0 ; Save filename^ MOV r1, r0 ; -> filename BL SkipToSpace ; Over the filename BL SkipSpaces ; To the address BL ReadAtMost8Hex ; Go read it Floyd ! LDRVCB r0, [r1] ; Anything on the end ? CMPVC r0, #" "+1 ; CtrlChar + space ok EXIT ; VC/VS from readhex or VC, CC/CS from CMP ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; In r2, r3 = load/exec addresses to use if none provided. r1 -> string ; Out r2, r3 conditionally updated, r1 updated, past any trailing spaces ; VS if failed, error ('Bad Address' or whatever) set ; CS if something comes afterwards ... ReadOptionalLoadAndExec Entry "r0, FSUTtemp" MOV FSUTtemp, r2 ; Save initial value BL SkipSpaces CMP r0, #" " ; No more parms ? EXIT LO ; VClear, r2, r3 unaffected BL ReadAtMost8Hex BVS %FT99 MOV r3, r2 MOV r2, FSUTtemp BL SkipSpaces CMP r0, #" " ; No more parms ? EXIT LO ; VClear, r2 unaffected, r3 updated BL ReadAtMost8Hex BLVC SkipSpaces ; Anything on the end ? CMPVC r0, #" " 99 STRVS r0, [sp] EXIT ; VC/VS from readhex or VC, CC/CS from CMP ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Read a hex (default) address from a string ; In r1 -> string ; Out VC: r1 -> first char not used in building number, r2 = number ; VS: error ('Bad Address') set ReadAtMost8Hex Entry "r0, r3-r4" MOV R0, #16 ; default base, don't trap bad terms SWI XOS_ReadUnsigned STRVS r0, [sp] EXIT ; VClear -> good hex number / VSet -> bad ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Set various errors: VSet always on exit SetErrorBadAddress ADR r0, ErrorBlock_BadAddress [ International Push "lr" BL TranslateError Pull "lr" ] RETURNVS MakeErrorBlock BadAddress SetErrorOutsideFile ADR r0, ErrorBlock_OutsideFile [ International Push "lr" BL TranslateError Pull "lr" ] RETURNVS MakeErrorBlock OutsideFile SetErrorEscape ADR r0, ErrorBlock_Escape [ International Push "lr" BL TranslateError Pull "lr" ] RETURNVS MakeErrorBlock Escape ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ AckEscape Push "r1-r2, lr" MOV r0, #&7E SWI XOS_Byte BLVC SetErrorEscape ; Only set ESCAPE error if no override Pull "r1-r2, pc" ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ END