ON ERROR REPORT:PRINT" at line ";ERL:END PROCassemble CALL code END : DEF PROCassemble DIM code 2048 REM Allocate buffers inside code, so we don't get problems with long ADRs in_file=code+128 out_file=code+256 code=code+384 : REM Example of two-pass assembly; on the first time around, we REM don't want errors reported, hence OPT 0 : FOR pass=0 TO 2 STEP 2 P%=code [OPT pass : MOV R12,R14 ; Keep BASIC return address in R12 : ADR R0,in_prompt ADR R1,in_file BL input_routine ; Get input filename : ADR R0,out_prompt ADR R1,out_file BL input_routine ; Get output filename : MOV R0,#&43 ADR R1,in_file SWI "OS_Find" ; Open input file CMP R0,#0 BEQ file_error ; Finish now if there's been an error MOV R6,R0 ; Otherwise store the file handle in R6 : MOV R0,#&83 ADR R1,out_file SWI "OS_Find" ; Create and open output file CMP R0,#0 BEQ file_error_close_input ; Finsh and close the input file if ; there's been an error MOV R7,R0 ; Otherwise store the file handle in R7 : .process_file ; Start of file processing loop MOV R1,R6 SWI "OS_BGet" ; Get next byte from input file into R0 BCS file_finished ; Check for end-of-file, and if we've ; reached it, jump out of the loop CMP R0,#65 ; } These four comparisons make sure BLT skip_byte ; } that a byte is changed only if it CMP R0,#90 ; } is less than 65 or greater than 90 BGT skip_byte ; } (i.e. it is a capital letter) ADD R0,R0,#32 ; Changes letter to lower case .skip_byte MOV R1,R7 ; } Put byte (altered or otherwise) SWI "OS_BPut" ; } to output file B process_file ; Loop round again : .file_finished MOV R0,#0 MOV R1,R6 SWI "OS_Find" ; Close input file MOV R1,R7 SWI "OS_Find" ; Close output file MOV R0,#18 ADR R1,out_file MOV R2,#&1000 ; } SUB R2,R2,#1 ; } &FFF is what we want (see magazine) SWI "OS_File" ; Set filetype of output to text : MOV PC,R12 ; Return to BASIC : .file_error_close_input ; Called when input file has been opened ; but the output file hasn't MOV R0,#0 MOV R1,R6 SWI "OS_Find" ; Close input file .file_error SWI "OS_WriteS" ; Display error message EQUS "Couldn't open files":EQUB 0 ALIGN SWI "OS_NewLine" MOV PC,R12 ; Return to BASIC : .input_routine ; BL here with R0 > prompt ; R1 > 128 byte buffer ; ARM chip does R14 > return address : SWI "OS_Write0" ; Display prompt passed in R0 MOV R0,R1 ; Move buffer to R0 for OS_ReadLine MOV R1,#128 ; 128 byte limit MOV R2,#33 ; No spaces / ctrl chars allowed MOV R3,#126 ; No top-bit set characters either SWI "OS_ReadLine" ; Call OS routine to get input MOVCS PC,R12 ; If Escape pressed, exit to BASIC... MOV PC,R14 ; ...otherwise return back to caller : .in_prompt EQUS " In filename: ":EQUB 0 .out_prompt EQUS "Out filename: ":EQUB 0 ]:NEXT ENDPROC