>Basic6809   (2 Patches BASIC V module to assemble 6809 code 2 < F Version 1.00 (05 Nov 2009) P( by John Kortink, (c) Zeridajh 2009 Z d# Version 1.0-jgh (21 Nov 2010) nO J.G.Harston - Also patches BASIC v1.05, corrected assembler error numbers x    ! "Error: ";$;" at ";:   Patch_Off(100)  Data_Size% = 256 * 1024   Data% Data_Size% + 4  Source% = which_source  Ȏ Source%   105 : doing_105 " 116 : doing_116 , 119 : doing_119 6 120 : doing_120 @ 920 : doing_120x J 128 : doing_128 T 129 : doing_129 ^ h r |patch_code  " "Total size ";Size%;" bytes"   out_file$ = "6809_" + Which$  <ș "OS_File", 10, out_file$, &FFA,, Data%, Data% + Size%   '"Saved to ";out_file$'      ݤwhich_source   choice% & source% 0 : D N "Possible sources:"' X "1. Local RISC OS ROM" b! "2. RISC OS ROM image file" l" "3. BASIC module image file" v  '"Your source: ";  ș "OS_Byte", 15, 0  8 choice% = - ("0"): choice% >= 1 choice% <= 3   ;choice%'  - A% = Data% Data% + Data_Size% - 1 4   !A% = 0     Ȏ choice%    1 : src_local * 2 : src_riscos 4 3 : src_module > H R \source% = 0 f pG source% = 0 test_module(52308, &70AD) source% = 105 : JGH z@ source% = 0 test_module(52628, &5EF2) source% = 116 @ source% = 0 test_module(55392, &58E4) source% = 119 @ source% = 0 test_module(55440, &71CA) source% = 120 @ source% = 0 test_module(55532, &45DF) source% = 920 @ source% = 0 test_module(55632, &EB77) source% = 128 @ source% = 0 test_module(55636, &8A16) source% = 129  7 source% = 0 64, "BASIC module not recognized"   = source%    src_local   base%  $+ș "OS_Module", 18, "Basic" ,,, base% . 8Size% = base%!-4 - 4 B L A% = 0 Size% - 1 4 V ` Data%!A% = base%!A% j t ~     src_riscos   in  riscos%  file_name$   "Filename: " file_name$'  "Size% = file_size(file_name$)   in = (file_name$)  (riscos% = 0 2  1 214, "File not found"   = size%    %ݤtest_riscos(in, offset%, word%) & 0*ș "OS_GBPB", 3, in, Data%, 4, offset% : D= (!Data% = word%) N X b l,ݤtest_module(actual_size%, actual_crc%) v  crc%  9ș "OS_CRC", 0, Data%, Data% + actual_size%, 1 crc%   crc% <> actual_crc% =  Size% = actual_size%  =    patch_code   token_AND = &80 token_EOR = &82  token_OR = &84 * 4Size% = (Size% + 3) 3 > H R Change module name \ f p A%=Data% Data%+Size%-1 z" !A%=&49534142 A%?4=&43 C A%!-4<>&20434242 A%?5<>"$" A%?5<>"T" A%?5<>"." ! A%!1=&39303836: "6809"    A%   `P = %0000 %0010 %0010   0 On TEXTLOAD, RENUMBER 1,1 instead of 10,10   prime(1, &E3A0400A)   [OPT `P ; $ MOV r4,#1 . MOV r5,#1 8; B] L V ` 6809 assembler j t ~K Source% = 105 Source% = 116 word% = &E28F1014 word% = &E28F103C prime(2, word%)  [OPT `P ;  BL patch_6809_1 ; ]  prim4(3, &E202140F)  [OPT `P ;  B patch_6809_2 ; ]  (% Source% = 105 Source% = 116 2 < Source%=105 Dest%=&A864 F Source%=116 Dest%=&A9A4 P ZP% -= 6 * 4 d n [OPT `P x; # SUB r2,r2,#&F0000000-&C0000000  BCS Data%+Dest%  ADD r11,r11,#2  CMP r2,#&F0000000  BCS P% - 4 * 4 ; ]  prime(5, &E200000F)  [OPT `P ;  r0,r0,#%11111 ; ]  " , 6K Source% = 105 Source% = 116 word% = &E35A0080 word% = &E35A007F @prime(4, word%) J T [OPT `P ^; h B patch_6809_0 r; |]    Other code points   prim4(50, &E51830C0) prime(51, &E92D4002) prime(52, &E1A00400)    Extra code   P% = Data% + Size%   [OPT `P & 0 : D.patch_6809_0 N; XF TEQ r10,#token_OR ; 'Expand' tokenised mnemonics b BNE mnem_notOR l LDRB r1,[r11] v BIC r1,r1,#&20  TEQ r1,#"A"  TEQNE r1,#"B"  TEQNE r1,#"C"  BNE mnem_notOR  SUB r11,r11,#1  CMP r1,#"B"  LDRLO r0,mnem_ORA  LDREQ r0,mnem_ORB  LDRHI r0,mnem_ORC  B Data%+Patch_Off(52) ; .mnem_notOR ;  TEQ r10,#token_AND  SUBEQ r11,r11,#2  LDREQ r0,mnem_AND  BEQ Data%+Patch_Off(52) *; 4 TEQ r10,#token_EOR > SUBEQ r11,r11,#2 H LDREQ r0,mnem_EOR R BEQ Data%+Patch_Off(52) \; fA BIC r0,r10,#&20 ; Skip 'L' for all 'LBxx' p TEQ r0,#"L" z LDREQB r0,[r11,#0]  BICEQ r0,r0,#&20  TEQEQ r0,#"B"  LDREQB r10,[r11],#1 ; ? BIC r0,r10,#&20 ; Build 'mnemonic word' ;  LDRB r1,[r11,#0]  BIC r1,r1,#&20  R r0,r0,r1,LSL#8 ;  LDRB r1,[r11,#1]  BIC r1,r1,#&20  R r0,r0,r1,LSL#16 ;  B Data%+Patch_Off(52) ; $ .mnem_ORA .; 8 EQUS "ORA " B; L .mnem_ORB V; ` EQUS "ORB " j; t .mnem_ORC ~;  EQUS "ORC " ;  .mnem_AND ;  EQUS "AND " ;  .mnem_EOR ;  EQUS "EOR "    .patch_6809_1  ; T ADR r1,table_mnem_6809 ; Use 6809 mnemonic table instead of ARM one ; (0 MOV pc,r14 ; Return 2 < F P.table_mnem_6809 Z; d EQUS "ADC":EQUB &00 n EQUS "ADD":EQUB &01 x EQUS "AND":EQUB &02  EQUS "BIT":EQUB &03  EQUS "CMP":EQUB &04  EQUS "EOR":EQUB &05  EQUS "SBC":EQUB &06  EQUS "SUB":EQUB &07  EQUS "JMP":EQUB &08  EQUS "JSR":EQUB &09  EQUS "LEA":EQUB &0A  EQUS "CWA":EQUB &0B ;  EQUS "ASL":EQUB &10  EQUS "ASR":EQUB &11  EQUS "CLR":EQUB &12  EQUS "COM":EQUB &13  EQUS "DEC":EQUB &14  EQUS "INC":EQUB &15 " EQUS "LSL":EQUB &16 , EQUS "LSR":EQUB &17 6 EQUS "NEG":EQUB &18 @ EQUS "ROL":EQUB &19 J EQUS "ROR":EQUB &1A T EQUS "TST":EQUB &1B ^; h EQUS "ORA":EQUB &2D r EQUS "ORB":EQUB &2D | EQUS "ORC":EQUB &2D ;  EQUS "LDA":EQUB &2E  EQUS "LDB":EQUB &2E  EQUS "LDD":EQUB &2E  EQUS "LDS":EQUB &2E  EQUS "LDU":EQUB &2E  EQUS "LDX":EQUB &2E  EQUS "LDY":EQUB &2E ;  EQUS "STA":EQUB &2F  EQUS "STB":EQUB &2F  EQUS "STD":EQUB &2F  EQUS "STS":EQUB &2F  EQUS "STU":EQUB &2F  EQUS "STX":EQUB &2F  EQUS "STY":EQUB &2F &; 0 EQUS "BCC":EQUB &40 : EQUS "BCS":EQUB &41 D EQUS "BEQ":EQUB &42 N EQUS "BGE":EQUB &43 X EQUS "BGT":EQUB &44 b EQUS "BHI":EQUB &45 l EQUS "BHS":EQUB &46 v EQUS "BLE":EQUB &47  EQUS "BLO":EQUB &48  EQUS "BLS":EQUB &49  EQUS "BLT":EQUB &4A  EQUS "BMI":EQUB &4B  EQUS "BNE":EQUB &4C  EQUS "BPL":EQUB &4D  EQUS "BRA":EQUB &4E  EQUS "BRN":EQUB &4F  EQUS "BSR":EQUB &50  EQUS "BVC":EQUB &51  EQUS "BVS":EQUB &52 ;  EQUS "EXG":EQUB &70  EQUS "TFR":EQUB &71  ;  EQUS "PSH":EQUB &80   EQUS "PUL":EQUB &81 *; 4 EQUS "ABX":EQUB &A0 > EQUS "DAA":EQUB &A1 H EQUS "MUL":EQUB &A2 R EQUS "NOP":EQUB &A3 \ EQUS "RTI":EQUB &A4 f EQUS "RTS":EQUB &A5 p EQUS "SEX":EQUB &A6 z EQUS "SYN":EQUB &A7 ;  EQUS "SWI":EQUB &B0 ; J EQUS "DCB":EQUB &E0 ; (make DCx directives big-endian)  EQUS "DCW":EQUB &E1  EQUS "DCD":EQUB &E2 ; H EQUS "OPT":EQUB &F0 ; (pass the other relevant ones)  EQUS "EQU":EQUB &F1 ; 8 EQUD 0 ; (end of table)    .patch_6809_2 ; $E MOV r3,r2,LSR#24 ; Initialise processing flags .; 8; LDRB r10,[r11],#1 ; To next character B; LD r0,r3,#&F0 ; Possibly a 4-char mnemonic ? V TEQ r0,#&00 ` TEQNE r0,#&10 j TEQNE r0,#&20 t TEQNE r0,#&40 ~ TEQNE r0,#&50  TEQNE r0,#&80  TEQNE r3,#&A7  TEQNE r0,#&B0 @ BEQ class_nobn ; Yes, don't skip spaces ; 5 BL skip_spaces ; Skip spaces ; .class_nobn ; @ SUB r2,r8,#-basoff_stracc% ; Buffer for instruction ; 1 MOV r0,#0 ; Wipe it  STR r0,[r2,#0]   STR r0,[r2,#4] ; > ADR r14,class_done ; Call 'class' handler ( STMFD r13!,{r14} 2 r0,r3,#%11110000 < ADD pc,pc,r0,LSR#4-2 F MOV r0,r0 P; Z B class_ADC d B class_ASL n B class_ORA x EQUD 0  B class_BCC  B class_BCC  EQUD 0  B class_EXG  B class_PSH  EQUD 0  B class_ABX  B class_SWI  EQUD 0  EQUD 0  B class_DCx  EQUD 0 ; .class_done ; 5 BL skip_spaces ; Skip spaces "; ,? B Data%+Patch_Off(50) ; Join 'n>4 bytes' code 6; @; J; T.eval_expr_back ^; hA SUB r11,r11,#1 ; Step back one character r LDRB r10,[r11,#-1] |; .eval_expr ; = STMFD r13!,{r1-r3,r14} ; Evaluate expression ;  BL Data%+Patch_Off(51) ;  LDMFD r13!,{r1-r3,pc}^ ; ; ; .hop_skip_spaces ; 8 LDRB r10,[r11],#1 ; Skip character ; .skip_spaces ; &9 TEQ r10,#" " ; Scan to non-space 0 LDREQB r10,[r11],#1 : BEQ skip_spaces D; N MOVS pc,r14 X; b; l; v.not_a_variable ;  STMFD r13!,{r14} ;  LDRB r14,[r11] ;  CMP r14,#"A"  BLO notav_chelo  CMP r14,#"Z"  BLS notav_isvar ; .notav_chelo ;  CMP r14,#"a"  BLO notav_chedi   CMP r14,#"z"  BLS notav_isvar  ; *.notav_chedi 4; > CMP r14,#"0" H BLO notav_cheot R CMP r14,#"9" \ BLS notav_isvar f; p.notav_cheot z;  TEQ r14,#"`"  TEQNE r14,#"_"  TEQNE r14,#"$"  TEQNE r14,#"%"  TEQNE r14,#"("  BEQ notav_isvar ;  TEQ r14,r14 ;  LDMFD r13!,{pc} ; .notav_isvar ;  CMN r14,#1 ;  LDMFD r13!,{pc} $; .; 8; B .opt_2 L; V STMFD r13!,{r0,r14} `; j LDRB r0,[r8,#basoff_opt%] t TST r0,#2 ~;  LDMFD r13!,{r0,pc} ; ; ; .error_bad_mnemonic ;  ADR r0,ermsg_bad_mnemonic ;  B error_generate ; .ermsg_bad_mnemonic ; * error_message(4, "No such mnemonic")  ; ; ; (.error_constoverflow 2; <3 STMFD r13!,{r14} ; Save link F; P8 BL opt_2 ; Errors fatal ? Z; d6 LDMFD r13!,{r14} ; Restore link n; x1 QS pc,r14 ; No, return ;  TST r1,#&FF00 # ADREQ r0,ermsg_constoverflow_b # ADRNE r0,ermsg_constoverflow_s ;  B error_generate ; .ermsg_constoverflow_b ; ? error_message(2, "Immediate value out of range [0..255]") ; .ermsg_constoverflow_s ; A error_message(2, "Immediate value out of range [0..65535]") ; ; "; ,.error_offsetoutofrange 6; @3 STMFD r13!,{r14} ; Save link J; T8 BL opt_2 ; Errors fatal ? ^; h6 LDMFD r13!,{r14} ; Restore link r; |1 QS pc,r14 ; No, return ;  MOV r0,r3,LSR#24  CMP r0,#5 ' ADRLO r0,ermsg_offsetoutofrange_l4 ' ADRHS r0,ermsg_offsetoutofrange_l5 ;  B error_generate ; .ermsg_offsetoutofrange_l4 ; H error_message(1, "Offset target out of range [P%-32764,P%+32771]") ; .ermsg_offsetoutofrange_l5 ; H error_message(1, "Offset target out of range [P%-32763,P%+32772]") ; &; 0; :.error_branchoutofrange D; N3 STMFD r13!,{r14} ; Save link X; b8 BL opt_2 ; Errors fatal ? l; v6 LDMFD r13!,{r14} ; Restore link ; 1 QS pc,r14 ; No, return ;  MOV r0,r3,LSR#28  CMP r0,#3 & ADRLO r0,ermsg_branchoutofrange_n ' ADREQ r0,ermsg_branchoutofrange_l3 ' ADRHI r0,ermsg_branchoutofrange_l4 ;  B error_generate ; .ermsg_branchoutofrange_n ; D error_message(1, "Branch target out of range [P%-126,P%+129]")  ; .ermsg_branchoutofrange_l3  ; *H error_message(1, "Branch target out of range [P%-32765,P%+32770]") 4; >.ermsg_branchoutofrange_l4 H; RH error_message(1, "Branch target out of range [P%-32764,P%+32771]") \; f; p; z.error_R_register ; 3 STMFD r13!,{r14} ; Save link ; M BIC r14,r10,#&20 ; 'X', 'Y', 'U' or 'S', as expected ?  TEQ r14,#"X"  TEQNE r14,#"Y"  TEQNE r14,#"U"  TEQNE r14,#"S" 5 LDMEQFD r13!,{pc}^ ; Yes, return ;  ADR r0,ermsg_R_register ;  B error_generate ; .ermsg_R_register ; $C error_message(3, "Indexed addressing: expected X, Y, U or S") .; 8; B; L.error_R_PCR_register V; `3 STMFD r13!,{r14} ; Save link j; tT BIC r14,r10,#&20 ; 'X', 'Y', 'U', 'S' or 'PCR', as expected ? ~ TEQ r14,#"X"  TEQNE r14,#"Y"  TEQNE r14,#"U"  TEQNE r14,#"S" 5 LDMEQFD r13!,{pc}^ ; Yes, return ;  TEQ r14,#"P"  LDREQB r14,[r11,#0]  BICEQ r14,r14,#&20  TEQEQ r14,#"C"  LDREQB r14,[r11,#1]  BICEQ r14,r14,#&20  TEQEQ r14,#"R" 5 LDMEQFD r13!,{pc}^ ; Yes, return  ;  ADR r0,ermsg_R_PCR_register ; ( B error_generate 2; <.ermsg_R_PCR_register F; PH error_message(3, "Indexed addressing: expected X, Y, U, S or PCR") Z; d; n; x.error_all_register ; = STMFD r13!,{r10,r14} ; Save used registers ; m BIC r14,r10,#&20 ; 'A', 'B', 'D', 'X', 'Y', 'U', 'S', 'CC', 'DP' or 'PC' as expected ?  TEQ r14,#"A"  TEQNE r14,#"B"  TEQNE r14,#"D"  TEQNE r14,#"X"  TEQNE r14,#"Y"  TEQNE r14,#"U"  TEQNE r14,#"S" 5 LDMEQFD r13!,{r10,pc}^ ; Yes, return ;  LDRB r10,[r11,#0]  BIC r10,r10,#&20 ; " TEQ r14,#"C" , TEQEQ r10,#"C" 65 LDMEQFD r13!,{r10,pc}^ ; Yes, return @; J TEQ r14,#"D" T TEQEQ r10,#"P" ^5 LDMEQFD r13!,{r10,pc}^ ; Yes, return h; r TEQ r14,#"P" | TEQEQ r10,#"C" 5 LDMEQFD r13!,{r10,pc}^ ; Yes, return ;  ADR r0,ermsg_all_register ;  B error_generate ; .ermsg_all_register ; D error_message(3, "Expected A, B, D, X, Y, U, S, CC, DP or PC") ; ; ; .error_bad_addressing ;  ADR r0,ermsg_bad_addressing ; & B error_generate 0; :.ermsg_bad_addressing D; NJ error_message(3, "Addressing mode not allowed for this instruction") X; b; l; v.error_bad_ifnotalpha ; 3 STMFD r13!,{r14} ; Save link ; E r14,r10,r0 ; Alpha character as expected ?  BICS r14,r14,#&20 F BNE error_bad_mnemonic ; No, error 'no such mnemonic' ; C BL hop_skip_spaces ; Skip character and spaces ; 0 LDMFD r13!,{pc} ; Return ; ; ; !.error_indexed_c ! ; !: TEQ r10,#"," ; ',', as expected ? ! 2 QS pc,r14 ; Yes, return !*; !4 ADR r0,ermsg_indexed_c !>; !H B error_generate !R; !\.ermsg_indexed_c !f; !p8 error_message(3, "Indexed addressing: expected ,") !z; !; !; !.error_indexed_i !; !: TEQ r10,#"]" ; ']', as expected ? !2 QS pc,r14 ; Yes, return !; ! ADR r0,ermsg_indexed_i !; ! B error_generate !; !.ermsg_indexed_i !; "A error_message(3, "Indirect indexed addressing: expected ]") "; "; "$; "..error_transfer_c "8; "B: TEQ r10,#"," ; ',', as expected ? "L2 QS pc,r14 ; Yes, return "V; "` ADR r0,ermsg_transfer_c "j; "t B error_generate "~; ".ermsg_transfer_c "; ". error_message(3, "TFR/EXG : expected ,") "; "; "; ".error_transfer_x "; " ADR r0,ermsg_transfer_x "; " B error_generate "; #.ermsg_transfer_x # ; #? error_message(3, "TFR/EXG: registers are different size") #; #(; #2; #<.error_bad_pushpull #F; #P ADR r0,ermsg_bad_pushpull #Z; #d B error_generate #n; #x.ermsg_bad_pushpull #; #= error_message(3, "PSH/PUL: register cannot be stacked") #; #; #; #.error_bad_autostep #; # ADR r0,ermsg_bad_autostep #; # B error_generate #; #.ermsg_bad_autostep #; $\ error_message(3, "Indirect indexed addressing: auto-increment/decrement must be by 2") $; $; $"; $,.error_generate $6; $@ SWI "OS_GenerateError" $J; $T; $^; $h.do_R_register $r; $|3 STMFD r13!,{r14} ; Save link $; $< BL error_R_register ; Match 'R' register $; $G BIC r10,r10,#&20 ; Return specified 'R' register $ TEQ r10,#"X" $ Q r14,#%00 $ TEQ r10,#"Y" $ Q r14,#%01 $ TEQ r10,#"U" $ Q r14,#%10 $ TEQ r10,#"S" $ Q r14,#%11 $; %8 LDRB r10,[r11],#1 ; Next character %; % LDMFD r13!,{pc} %&; %0; %:; %D.do_R_PCR_register %N; %X3 STMFD r13!,{r14} ; Save link %b; %lE BL error_R_PCR_register ; Match 'R' register or 'PCR' %v; %G BIC r10,r10,#&20 ; Return specified 'R' register % TEQ r10,#"X" % Q r14,#%00 % TEQ r10,#"Y" % Q r14,#%01 % TEQ r10,#"U" % Q r14,#%10 % TEQ r10,#"S" % Q r14,#%11 %; %6 TEQ r10,#"P" ; Next character %: ADDEQ r11,r11,#2 ; (and flag 'PCR') % LDRB r10,[r11],#1 &; &  LDMFD r13!,{pc} &; & ; &*; &4.do_T_register &>; &H= STMFD r13!,{r0,r14} ; Save used registers &R; &\< BL error_all_register ; Match 'T' register &f; &pG BIC r10,r10,#&20 ; Return specified 'T' register &z LDRB r14,[r11,#0] & BIC r14,r14,#&20 &; & TEQ r10,#"A" & Q r0,#%10000 & TEQ r10,#"B" & Q r0,#%10010 & TEQ r10,#"D" & Q r0,#%00000 & TEQEQ r14,#"P" & Q r0,#%10111 & TEQ r10,#"X" & Q r0,#%00010 & TEQ r10,#"Y" ' Q r0,#%00100 ' TEQ r10,#"U" ' Q r0,#%00110 '$ TEQ r10,#"S" '. Q r0,#%01000 '8 TEQ r10,#"C" 'B Q r0,#%10101 'L TEQ r10,#"P" 'V Q r0,#%01011 '`; 'j8 MOVS r14,r0,LSR#1 ; Next character 't ADDCS r11,r11,#1 '~ LDRB r10,[r11],#1 '; ' LDMFD r13!,{r0,pc} '; '; '; '.do_P_register '; '= STMFD r13!,{r0,r14} ; Save used registers '; '< BL do_T_register ; Match 'P' register '; 'G ADR r0,do_P_register_map ; Return specified 'P' register ( LDRB r14,[r0,r14] ( ; ( LDMFD r13!,{r0,pc} (; ((.do_P_register_map (2; (< EQUB 0 << 0: D (F EQUB 1 << 4: X (P EQUB 1 << 5: Y (Z EQUB 1 << 6: U (d EQUB 1 << 6: S (n EQUB 1 << 7: PC (x EQUB 0 << 0: - ( EQUB 0 << 0: - ( EQUB 1 << 1: A ( EQUB 1 << 2: B ( EQUB 1 << 0: CC ( EQUB 1 << 3: DP ( EQUB 0 << 0: - ( EQUB 0 << 0: - ( EQUB 0 << 0: - ( EQUB 0 << 0: - (; (; (; (.do_dieximin ); )= STMFD r13!,{r1-r2,r14} ; Save used registers ); )"? MOV r3,r3,LSL#24 ; Move instruction info ),; )6> MOV r0,#1<<1 ; 8- or 16-bit force ? )@ TEQ r10,#"<" )J Q r0,#1<<0 )T TEQNE r10,#">" )^E REQ r3,r3,r0,LSL#4 ; Yes, flag it (and which one) )hH BLEQ hop_skip_spaces ; And skip '<' or '>' and spaces )r; )|3 TEQ r10,#"#" ; Immediate ? )6 BNE do_dieximin_noimm ; No, continue ); )9 BL eval_expr ; Immediate value ); )= R r3,r3,#2<<0 ; Indicate 'immediate' ); )0 B do_dieximin_rtarg ; Finish ); ).do_dieximin_noimm ); )5 TEQ r10,#"[" ; Indirection ? )5 REQ r3,r3,#1<<7 ; Yes, flag it )A BLEQ hop_skip_spaces ; And skip '[' and spaces *; *< TEQ r10,#"," ; Indexed, no offset ? *= BEQ do_dieximin_ixnul ; Yes, handle as such *&; *0? BIC r0,r10,#&20 ; Indexed, accu based ? *: TEQ r0,#"A" *D TEQNE r0,#"B" *N TEQNE r0,#"D" *X BLEQ not_a_variable *b= BEQ do_dieximin_ixacc ; Yes, handle as such *l; *v; BL eval_expr_back ; Address or offset *; *> TEQ r10,#"," ; Indexed, with offset ? *= BEQ do_dieximin_ixoff ; Yes, handle as such *; *7 TST r3,#1<<7 ; Indirection ? *? RNE r3,r3,#%10011111<<8 ; Yes, extended indirect *A BNE do_dieximin_ixfin ; And finish as 'indexed' *; *I TST r3,#1<<4 ; Indicate 'direct' or 'extended' * RNE r3,r3,#0<<0 * REQ r3,r3,#1<<0 *; *0 B do_dieximin_rtarg ; Finish +; + .do_dieximin_ixfin +; + ; R r3,r3,#3<<0 ; Indicate 'indexed' +*; +47 TST r3,#1<<7 ; Indirection ? +>A BEQ do_dieximin_rtarg ; No, don't check for ']' +H; +RB R r3,r3,#%00010000<<8 ; Make post-byte 'indirect' +\; +f5 BL skip_spaces ; Skip spaces +p; +z3 BL error_indexed_i ; Match ']' +; +8 LDRB r10,[r11],#1 ; Next character +; +.do_dieximin_rtarg +; +0 LDMFD r13!,{r1-r2,pc} ; Return +; +.do_dieximin_ixnul +; += BL hop_skip_spaces ; Skip ',' and spaces +; +> MOV r0,#%10000100 ; Initialise post-byte +; ,7 TEQ r10,#"-" ; Pre-decrement ? ,= Q r0,#%10000010 ; Yes, note and skip '-' , LDREQB r10,[r11],#1 ,$: TEQEQ r10,#"-" ; Double decrement ? ,.= Q r0,#%10000011 ; Yes, note and skip '-' ,8 LDREQB r10,[r11],#1 ,B; ,L; BL do_R_register ; Note 'R' register ,V R r3,r3,r14,LSL#13 ,`; ,j@ TEQ r0,#%10000100 ; Have a pre-decrement ? ,t@ BNE do_dieximin_noinc ; Yes, no post-increment ,~; ,8 TEQ r10,#"+" ; Post-increment ? ,= Q r0,#%10000000 ; Yes, note and skip '+' , LDREQB r10,[r11],#1 ,: TEQEQ r10,#"+" ; Double increment ? ,= Q r0,#%10000001 ; Yes, note and skip '+' , LDREQB r10,[r11],#1 ,; ,.do_dieximin_noinc ,; ,@ R r3,r3,r0,LSL#8 ; Note required post-byte ,; ,G TST r3,#1<<7 ; Fault single-inc/dec indirect - TEQNE r0,#%10000100 -  TEQNE r0,#%10000011 - TEQNE r0,#%10000001 - BNE error_bad_autostep -(; -2: B do_dieximin_ixfin ; Finish 'indexed' -<; -F.do_dieximin_ixacc -P; -ZB CMP r0,#"B" ; Note specified accumulator -d RLO r3,r3,#%10000110<<8 -n REQ r3,r3,#%10000101<<8 -x RHI r3,r3,#%10001011<<8 -; -J BL hop_skip_spaces ; Skip accumulator name and spaces -; -3 BL error_indexed_c ; Match ',' -; -= BL hop_skip_spaces ; Skip ',' and spaces -; -; BL do_R_register ; Note 'R' register - R r3,r3,r14,LSL#13 -; -: B do_dieximin_ixfin ; Finish 'indexed' -; -.do_dieximin_ixoff .; .= BL hop_skip_spaces ; Skip ',' and spaces .; ."M BL do_R_PCR_register ; Note 'R' register (or detect 'PCR') .,P BEQ do_dieximin_ixopc ; (if 'PCR' detected, handle seperately) .6 R r3,r3,r14,LSL#13 .@; .J7 TST r3,#1<<4 ; 8-bit force ? .T3 RNE r3,r3,#%10001000<<8 ; Yes, do it .^> BNE do_dieximin_ixfin ; And finish 'indexed' .h; .r8 TST r3,#1<<5 ; 16-bit force ? .|3 RNE r3,r3,#%10001001<<8 ; Yes, do it .> BNE do_dieximin_ixfin ; And finish 'indexed' .; .B TST r3,#1<<7 ; No 5-bit offset indirect . BNE do_dieximin_ixoby .; .A ADD r14,r0,#&10 ; Offset fits in 5 bits ? . CMP r14,#&20 .= BHS do_dieximin_ixoby ; No, try next larger .; .@ S r14,r0,#%11111 ; Note offset in post-byte . RNE r3,r3,r14,LSL#8 .B REQ r3,r3,#%10000100<<8 ; (replace '0,R' with ',R') .; /: B do_dieximin_ixfin ; Finish 'indexed' /; /.do_dieximin_ixoby /&; /0F ADD r14,r0,#&80 ; Fit offset in 8 or 16 bits ? /: CMP r14,#&100 /D* RLO r3,r3,#%10001000<<8 ; 8 /N+ RHS r3,r3,#%10001001<<8 ; 16 /X; /b: B do_dieximin_ixfin ; Finish 'indexed' /l; /v.do_dieximin_ixopc /; /J LDR r14,[r8,#basoff_p%] ; Calculate offset relative to PCR /M ADD r3,r3,#2<<24 ; (assuming 16-bit offset -> 2 bytes) / ADD r14,r14,r3,LSR#24 / SUB r0,r0,r14 /; /4 ADD r14,r0,#&8000 ; In range ? / CMP r14,#&10000 /P BLHS error_offsetoutofrange ; No, error 'offset target out of range' /; /7 ADD r0,r0,#1 ; 8-bit force ? / TST r3,#1<<4 /3 RNE r3,r3,#%10001100<<8 ; Yes, do it 0> BNE do_dieximin_ixfin ; And finish 'indexed' 0 ; 08 SUB r0,r0,#1 ; 16-bit force ? 0  TST r3,#1<<5 0*3 RNE r3,r3,#%10001101<<8 ; Yes, do it 04> BNE do_dieximin_ixfin ; And finish 'indexed' 0>; 0HF ADD r0,r0,#1 ; Fit offset in 8 or 16 bits ? 0R ADD r14,r0,#&80 0\ CMP r14,#&100 0f* RLO r3,r3,#%10001100<<8 ; 8 0p SUBHS r0,r0,#1 0z+ RHS r3,r3,#%10001101<<8 ; 16 0; 0: B do_dieximin_ixfin ; Finish 'indexed' 0; 0; 0; 0.finish_hop_byte 0; 0= LDRB r10,[r11],#1 ; Skip last character 0; 0.finish_byte 0; 0@ STRB r0,[r2],#1 ; Buffer opcode argument 0; 1 LDMFD r13!,{pc} 1; 1; 1$; 1..finish_hop_word 18; 1B= LDRB r10,[r11],#1 ; Skip last character 1L; 1V.finish_word 1`; 1j@ MOV r0,r0,ROR#8 ; Buffer opcode argument 1t STRB r0,[r2],#1 1~ MOV r0,r0,ROR#24 1 STRB r0,[r2],#1 1; 1 LDMFD r13!,{pc} 1; 1; 1; 1.finish_hop_dble 1; 1= LDRB r10,[r11],#1 ; Skip last character 1; 1.finish_dble 1; 2@ MOV r0,r0,ROR#24 ; Buffer opcode argument 2  STRB r0,[r2],#1 2 MOV r0,r0,ROR#24 2 STRB r0,[r2],#1 2( MOV r0,r0,ROR#24 22 STRB r0,[r2],#1 2< MOV r0,r0,ROR#24 2F STRB r0,[r2],#1 2P; 2Z LDMFD r13!,{pc} 2d; 2n; 2x; 2.finish_hop_implied 2; 2= LDRB r10,[r11],#1 ; Skip last character 2; 2.finish_implied 2; 2 LDMFD r13!,{pc} 2; 2; 2; 2.class_ABX 2; 2O TEQ r3,#&A7 ; Check 4th mnemonic character (if any) 3 Q r0,#"C" 3 BLEQ error_bad_ifnotalpha 3; 3"7 ADR r1,table_implieds_ABX-&A0 ; Output opcode 3, LDRB r1,[r1,r3] 36 STRB r1,[r2],#1 3@; 3JC B finish_implied ; End with 0 argument bytes 3T; 3^; 3h; 3r.table_implieds_ABX 3|; 3 EQUB &3A 3 EQUB &19 3 EQUB &3D 3 EQUB &12 3 EQUB &3B 3 EQUB &39 3 EQUB &1D 3 EQUB &13 3; 3 ALIGN 3; 3; 3; 4.class_EXG 4; 47 TEQ r3,#&70 ; Output opcode 4& Q r1,#&1E 40 MOVNE r1,#&1F 4: STRB r1,[r2],#1 4D; 4NA BL do_T_register ; Determine argument byte 4X R r0,r14,r0,LSL#4 4b; 4l BL skip_spaces 4v; 4 BL error_transfer_c 4; 4 BL hop_skip_spaces 4; 4 BL do_T_register 4 R r0,r14,r0,LSL#4 4; 4@ r14,r0,r0,LSR#4 ; Fault incompatible sizes 4 TST r14,#%1000 4 BNE error_transfer_x 4; 4B B finish_byte ; End with 1 argument byte 4; 5; 5 ; 5.class_PSH 5 ; 5*F BIC r0,r10,#&20 ; Check 4th mnemonic character 54 TEQ r0,#"S" 5> TEQNE r0,#"U" 5H MVNNE r0,r0 5R BL error_bad_ifnotalpha 5\; 5f7 TEQ r3,#&80 ; Output opcode 5p Q r1,#&34 5z MOVNE r1,#&35 5 TEQ r0,#"U" 5 ADDEQ r1,r1,#&02 5 STRB r1,[r2],#1 5; 5A MOV r0,#%00000000 ; Determine argument byte 5; 5.class_PSH_reg 5; 5 BL do_P_register 5; 5 TEQ r14,#0 5 BEQ error_bad_pushpull 5; 6 R r0,r0,r14 6; 6 BL skip_spaces 6$; 6. TEQ r10,#"," 68 BNE class_PSH_regd 6B; 6L BL hop_skip_spaces 6V; 6` B class_PSH_reg 6j; 6t.class_PSH_regd 6~; 6B B finish_byte ; End with 1 argument byte 6; 6; 6; 6.class_BCC 6; 6: LDRB r0,[r11,#-5] ; 'Long' version ? 6 BIC r0,r0,#&20 6 TEQ r0,#"L" 65 REQ r3,r3,#1<<16 ; Yes, flag it 6; 6: ADR r1,table_branches-&40*4 ; Determine opcode 7 r14,r3,#%11111111 7  LDR r1,[r1,r14,LSL#2] 7 TST r3,#1<<16 7 MOVNE r1,r1,ROR#16 7( ADDNE r3,r3,#1<<28 72; 7<5 S r14,r1,#&FF00 ; Output opcode 7F MOVNE r14,r14,LSR#8 7P STRNEB r14,[r2],#1 7Z ADDNE r3,r3,#1<<28 7d STRB r1,[r2],#1 7n; 7xA BL eval_expr_back ; Calculate branch offset 7 LDR r1,[r8,#basoff_p%] 7 ADD r3,r3,#2<<28 7 ADD r1,r1,r3,LSR#28 7 SUB r0,r0,r1 7; 74 TST r3,#1<<16 ; In range ? 7 Q r1,#&0080 7 MOVNE r1,#&8000 7 ADD r14,r0,r1 7 CMP r14,r1,LSL#1 7P BLHS error_branchoutofrange ; No, error 'branch target out of range' 7; 7K TST r3,#1<<16 ; Finish with 1 or 2 argument bytes 8 BEQ finish_byte 8 BNE finish_word 8; 8"; 8,; 86.table_branches 8@; 8J EQUW &0024:EQUW &1024 8T EQUW &0025:EQUW &1025 8^ EQUW &0027:EQUW &1027 8h EQUW &002C:EQUW &102C 8r EQUW &002E:EQUW &102E 8| EQUW &0022:EQUW &1022 8 EQUW &0024:EQUW &1024 8 EQUW &002F:EQUW &102F 8 EQUW &0025:EQUW &1025 8 EQUW &0023:EQUW &1023 8 EQUW &002D:EQUW &102D 8 EQUW &002B:EQUW &102B 8 EQUW &0026:EQUW &1026 8 EQUW &002A:EQUW &102A 8 EQUW &0020:EQUW &0016 8 EQUW &0021:EQUW &1021 8 EQUW &008D:EQUW &0017 8 EQUW &0028:EQUW &1028 8 EQUW &0029:EQUW &1029 9; 9; 9; 9&.class_SWI 90; 9:< TEQ r10,#"2" ; SWI number postfix ? 9D TEQNE r10,#"3" 9N; BNE class_SWI_nonum ; No, not 'special' 9X; 9b< SUB r1,r10,#"2"-&10 ; Output opcode prefix 9l STRB r1,[r2],#1 9v; 99 LDRB r10,[r11],#1 ; Skip SWI number 9; 9.class_SWI_nonum 9; 97 MOV r1,#%00111111 ; Output opcode 9 STRB r1,[r2],#1 9; 9C B finish_implied ; End with 0 argument bytes 9; 9; 9; 9.class_ADC 9; :5 TEQ r3,#&02 ; CC / CC ? :  TEQNE r3,#&0D : BICEQ r0,r10,#&20 :  TEQEQ r0,#"C" :* LDREQB r0,[r11,#0] :4 BICEQ r0,r0,#&20 :> TEQEQ r0,#"C" :H? ADDEQ r11,r11,#1 ; Yes, 'forget' first C :R; Q r10,#&03 ; And 're-code' second :\; :f.class_ASL_noacc :p; :z? ADR r0,table_deii_instns ; Mnemonic's info table : LDR r3,[r0,r3,LSL#2] : ADD r3,r0,r3 :; :E BIC r0,r10,#&20 ; Match register name postfix :; : SUB r1,r3,#1 :; :.class_ADC_pocha :; : LDRB r14,[r1,#1]! : TEQ r14,#0 : BEQ error_bad_mnemonic : TEQ r14,#" " ; BEQ class_ADC_ponot ; TEQ r14,r0 ; BNE class_ADC_pocha ;$; ;..class_ADC_ponot ;8; ;B? SUB r0,r1,r3 ; Mnemonic's info entry ;L ADD r1,r3,#8 ;V ADD r1,r1,r0,LSL#3 ;`; ;jC TEQ r14,#" " ; Skip register name (if any) ;t LDRNEB r10,[r11],#1 ;~; ;5 BL skip_spaces ; Skip spaces ;; ;O MOV r3,#2<<0 ; Minimum number of bytes for 'indexed' ; LDR r14,[r1,#3<<1] ; TST r14,#&1F00 ; ADDNE r3,r3,#1<<0 ;; ;Q BL do_dieximin ; Parse direct/extended/immediate/indexed ;; ;5 r14,r3,#%11 ; Output opcode ; LDR r1,[r1,r14,LSL#1] ; S r14,r1,#&1F00 < MOVNE r14,r14,LSR#8 <  STRNEB r14,[r2],#1 < STRB r1,[r2],#1 <; <(C TST r1,#1<<15 ; Addressing mode allowed ? <2> BNE error_bad_addressing ; No, abort with error <<; ; DH.table_deii_COM DR; D\ EQUS null_pad_8(" ") Df0 EQUW &0003:EQUW &0073:EQUW &FFFF:EQUW &0063 Dp; Dz.table_deii_DEC D; D EQUS null_pad_8(" ") D0 EQUW &000A:EQUW &007A:EQUW &FFFF:EQUW &006A D; D.table_deii_INC D; D EQUS null_pad_8(" ") D0 EQUW &000C:EQUW &007C:EQUW &FFFF:EQUW &006C D; D.table_deii_LSL D; D EQUS null_pad_8(" ") D0 EQUW &0008:EQUW &0078:EQUW &FFFF:EQUW &0068 E; E.table_deii_LSR E; E$ EQUS null_pad_8(" ") E.0 EQUW &0004:EQUW &0074:EQUW &FFFF:EQUW &0064 E8; EB.table_deii_NEG EL; EV EQUS null_pad_8(" ") E`0 EQUW &0000:EQUW &0070:EQUW &FFFF:EQUW &0060 Ej; Et.table_deii_ROL E~; E EQUS null_pad_8(" ") E0 EQUW &0009:EQUW &0079:EQUW &FFFF:EQUW &0069 E; E.table_deii_ROR E; E EQUS null_pad_8(" ") E0 EQUW &0006:EQUW &0076:EQUW &FFFF:EQUW &0066 E; E.table_deii_TST E; E EQUS null_pad_8(" ") E0 EQUW &000D:EQUW &007D:EQUW &FFFF:EQUW &006D F; F ; F; F.class_ASL F(; F2D BIC r0,r10,#&20 ; Accumulator name postfix ? F< TEQ r0,#"A" FF TEQNE r0,#"B" FP BLEQ not_a_variable FZ9 BNE class_ASL_noacc ; No, not implied Fd; Fn7 ADR r1,table_implieds_ASL-&10 ; Output opcode Fx LDRB r1,[r1,r3] F SUB r0,r0,#"A" F R r1,r1,r0,LSL#4 F STRB r1,[r2],#1 F; F] B finish_hop_implied ; Skip accumulator name and end with 0 argument bytes F; F; F; F.table_implieds_ASL F; F EQUB &48 F EQUB &47 F EQUB &4F G EQUB &43 G EQUB &4A G EQUB &4C G" EQUB &48 G, EQUB &44 G6 EQUB &40 G@ EQUB &49 GJ EQUB &46 GT EQUB &4D G^; Gh ALIGN Gr; G|; G; G.class_ORA G; G? SUB r11,r11,#2 ; Step back to 3rd char G LDRB r10,[r11],#1 G; G; r3,r3,#&20 &00 ; Change to 'ADC' class G; G B class_ADC G; G; G; G.class_DCx H; H< BL eval_expr_back ; Calculate argument H; H&N CMP r3,#&E1 ; Finish with 1, 2 or 4 argument bytes H0 BLO finish_byte H: BEQ finish_word HD BHI finish_dble HN HX Hb Hl] Hv H H HSize% = P% - Data% H H H H H Hݤnull_pad_8(string$) H H= string$ + 8, (0)), 8) H H I I -ݤerror_message(asm_err%, error_message$) I I [OPT `P I*; I4 EQUD asm_err% I> EQUS error_message$ IH EQUB 0 IR; I\ ALIGN If; Ip] Iz I= 0 I I I Idoing_105 I I RISC OS 3.1x BASIC 1.05 I1 Address data for v1.05 added by J.G.Harston I I0Patch_Off(1) = &B994: TEXTLOAD renumber 1,1 I2Patch_Off(2) = &A044: Point to mnemonic table I)Patch_Off(3) = &A0E8: B patch_6809_2 I)Patch_Off(4) = &9FE8: B patch_6809_0 J2Patch_Off(5) = &A87C: AND R0,R0,#15; mask OPT J JPatch_Off(50) = &A668 J$Patch_Off(51) = &AA18 J.1Patch_Off(52) = &A040: Search mnemonic table J8 JBbasoff_p% = -&C0 JLbasoff_opt% = -&26 JVbasoff_stracc% = -&600 J` JjWhich$ = "BASIC105" Jt J~ J J J Jdoing_116 J J RISC OS 3.70 BASIC 1.16 J JPatch_Off(1) = &BAD4 JPatch_Off(2) = &A184 JPatch_Off(3) = &A228 JPatch_Off(4) = &A128 JPatch_Off(5) = &A9BC K K Patch_Off(50) = &A7A8 KPatch_Off(51) = &AB58 KPatch_Off(52) = &A180 K( K2basoff_p% = -&C0 K<basoff_opt% = -&1E KFbasoff_stracc% = -&600 KP KZWhich$ = "BASIC116" Kd Kn Kx K K Kdoing_119 K K RISC OS 4.02 BASIC 1.19 K KPatch_Off(1) = &C588 KPatch_Off(2) = &A198 KPatch_Off(3) = &A35C KPatch_Off(4) = &A14C KPatch_Off(5) = &B204 K KPatch_Off(50) = &AFF0 LPatch_Off(51) = &B498 LPatch_Off(52) = &A194 L L"basoff_p% = -&C0 L,basoff_opt% = -&1E L6basoff_stracc% = -&600 L@ LJWhich$ = "BASIC119" LT L^ Lh Lr L| Ldoing_120 L L RISC OS 4.03 BASIC 1.20 L LPatch_Off(1) = &C5B8 LPatch_Off(2) = &A1CC LPatch_Off(3) = &A390 LPatch_Off(4) = &A180 LPatch_Off(5) = &B238 L LPatch_Off(50) = &B024 LPatch_Off(51) = &B4CC LPatch_Off(52) = &A1C8 M Mbasoff_p% = -&C0 Mbasoff_opt% = -&1E M&basoff_stracc% = -&600 M0 M:Which$ = "BASIC120" MD MN MX Mb Ml Mvdoing_120x M M' RISC OS 4.02 'mystery' BASIC 1.20 M MPatch_Off(1) = &C5D4 MPatch_Off(2) = &A1E0 MPatch_Off(3) = &A3A4 MPatch_Off(4) = &A194 MPatch_Off(5) = &B24C M MPatch_Off(50) = &B038 MPatch_Off(51) = &B4E0 MPatch_Off(52) = &A1DC M Nbasoff_p% = -&C0 N basoff_opt% = -&1E Nbasoff_stracc% = -&600 N  N*Which$ = "BASIC120X" N4 N> NH NR N\ Nfdoing_128 Np Nz RISC OS 4.37 BASIC 1.28 N NPatch_Off(1) = &C678 NPatch_Off(2) = &A244 NPatch_Off(3) = &A408 NPatch_Off(4) = &A1F8 NPatch_Off(5) = &B300 N NPatch_Off(50) = &B0EC NPatch_Off(51) = &B594 NPatch_Off(52) = &A240 N Nbasoff_p% = -&C0 Nbasoff_opt% = -&1A Obasoff_stracc% = -&600 O OWhich$ = "BASIC128" O$ O. O8 OB OL OVdoing_129 O` Oj RISC OS 4.39 BASIC 1.29 Ot O~Patch_Off(1) = &C678 OPatch_Off(2) = &A244 OPatch_Off(3) = &A408 OPatch_Off(4) = &A1F8 OPatch_Off(5) = &B300 O OPatch_Off(50) = &B0EC OPatch_Off(51) = &B594 OPatch_Off(52) = &A240 O Obasoff_p% = -&C0 Obasoff_opt% = -&1A Obasoff_stracc% = -&600 P P Which$ = "BASIC129" P P P( P2 P< PFprime(code%, old%) PP PZcheck(code%, old%, 0) Pd Pn Px P P Pprim4(code%, old%) P Pcheck(code%, old%, 4) P P P P P P check(code%, old%, choff%) P P!P% = Data% + Patch_Off(code%) Q Q `P = %0000 Q Q"K P%!choff% <> old% 66, "Old doesn't match (code " + (code%) + ")" Q, Q6