> SpecPatch 1.05  Patch Speculator to: > *** Can't seem to get *Spectrum to notify RESET properly (( * access separate Tapes directory 2 * display centred better <4 * Reset and OUT (nn),A passed to service call F * read standard tapefiles P5 * Ensure unused DD/ED/FD codes return silently Z) * Fixed RETN to actually pop to PC d* * OUT (BC),r passed to service call n! * Seperate &DDDD and &FDDD x To do: ) - IN A,(nn) passed to service call ) - IN r,(BC) passed to service call / - prevent it writing to protected memory # - display with MonitorType 4  - extra MOS interface? : ) Doesn't like just removing !8=value : 'ver0$="1.03": Patches version 1.03 ver1$="1.04 (23 Mar 1998)" #infile$=".Speculator" $outfile$=".Speculator" : %ș "OS_File",5,infile$ ,,,,len% B ver0% 20,ver1% 20,mem% len%+&200:"Load "+infile$+" "+~mem% $ver0%=ver0$:$ver1%=ver1$ "Z mem%!&266<>!ver0% mem%!&266<>!ver1%:"This program only patches Speculator 1.03": ,,$(mem%+&266)=ver1$:mem%?(&266+ ver1$)=0 6ScrCentre @ XYTape J RdTape T PROCWrTape ^ Reset h OUT_A r PROCIN_A | PROCSwiVector  NullOps : +"Save "+outfile$+" "+~mem%+"+"+~len% ""SetType "+outfile$+" Module" "Stamp "+outfile$  :  Poke(A%,B%,C%) U mem%!A%<>B% mem%!A%<>C%:"Unexpected word found at &";~A%;" (";~mem%!A%;")": mem%!A%=C%: : : 4 Move the displayed screen left about 4 columns  ScrCentre .Poke(&04E4,&8C140000,&8C0E8000): LHS psn .Poke(&04E8,&90340000,&902E8000): RHS psn &8 PROCPoke(&051C,&00000100,&000000FF):REM XWindLimit 08 PROCPoke(&0524,&000000C0,&000000BF):REM YWindLimit : D: N+ Seperate &DDDD and &FDDD instructions X XYTape b8Poke(&129F8,&EAFFC14C,&E51B0002): MOV R0,[R11,#-2] l3Poke(&129FC,&E1000090,&E35000FD): CMP R0,#&FD v1Poke(&12A00,&E1000090,&1AFFC14A): BNE &2F30 3Poke(&12A04,&E1000090,&E1A0F00E): MOV pc,link  : & Looks at SpecTape$Path for files  RdTape 3Poke(&3124,&E28F2048,&E28F201C): ADR R2,&3148 -Poke(&3148,&6570533C,&63657053): "Spec" -Poke(&314C,&69442463,&65706154): "Tape" *Poke(&3150,&502E3E72,&0000003A): ":" 2Poke(&31D8,&E24F0084,&E1A0F00E): MOV pc,link : . Read TAP files as well as SpecTape files HPoke(&2FB4,&E1800401,&EB000092): BL &3204 ; R0=R0|R1+2*TAP MPoke(&2FD0,&E50C4054,&EB000090): BL &3218 ; R4=R4+TAP; Store R4  MPoke(&306C,&E50C4054,&EB000069): BL &3218 ; R4=R4+TAP; Store R4 3Poke(&310C,&E3C11A0F,&E1A0600E): MOV R6,R14  HPoke(&3110,&E2211C07,&EB000027): BL &31B4 ; Check filetype *3Poke(&3114,&E2311001,&E1A0E006): MOV R14,R6 4:Poke(&3208,&6E697274,&E55C104C): LDRB R1,[R12,#-76] H5Poke(&320C,&6F742067,&E2111004): ANDS R1,R1,#4 R5Poke(&3210,&6F727020,&12400002): SUBNE R0,R0,#2 \4Poke(&3214,&6D617267,&E1A0F00E): MOV R15,R14 f:Poke(&3218,&72696420,&E51C004C): LDR R0,[R12,#-76] p5Poke(&321C,&6F746365,&E2100004): ANDS R0,R0,#4 z5Poke(&3220,&74207972,&12844001): ADDNE R4,R4,#1 :Poke(&3224,&6C206F6F,&E50C4054): STR R4,[R12,#-84] 4Poke(&3228,&00676E6F,&E1A0F00E): MOV R15,R14 : 9Poke(&31B4,&20646574,&E3C11A0F): BIC R1,R1,#&F000 :Poke(&31B8,&69727473,&E50C104C): STR R1,[R12,#-76] 5Poke(&31BC,&2020676E,&E3510C07): CMP R1,#&700 0Poke(&31C0,&20202020,&2A000002): BCS xx2 9Poke(&31C4,&20202020,&E2211C01): EOR R1,R1,#&0100 7Poke(&31C8,&20202020,&E231101D): EORS R1,R1,#&1d 4Poke(&31CC,&20202020,&E1A0F00E): MOV R15,R14 8Poke(&31D0,&20202020,&E2211C07): EOR R1,R1,#&700 5Poke(&31D4,&20202020,&E2311001): EORS R1,R1,#1 4Poke(&31D8,&E24F0084,&E1A0F00E): MOV R15,R14  :  Speculator TAP file is: $" {} . Standard TAP file is: 84 {} B: L: V) Notify emulated hardware of a Reset ` Reset j9 PROCPoke(&0994,&E1A0F00E,&EA000A11):REM B &31E0 t2Poke(&0A74,&E1A0B00C,&EB0009D8): BL &31DC ~1Poke(&3178,&70533A3A,&E24F4DC6): ADR R4,0 4Poke(&317C,&6C756365,&E1A0F00E): MOV pc,link DPoke(&31DC,&E24F1070,&E1A0B00C): MOV R11,R12 ; z80pc=z80mem 7Poke(&31E0,&E3A02064,&E92D4000): STMDB R13!,{R14} CPoke(&31E4,&EF000027,&EBFFFFE3): BL &3178 ; R4=ModuleBase 8Poke(&31E8,&31A0F00E,&E59F1010): LDR R1,[PC,#16] 2Poke(&31EC,&E28F0000,&E3A00000): MOV R0,#0 :Poke(&31F0,&EF00002B,&E54C0042): STR R0,[R12,#-66] 3Poke(&31F4,&00800006,&E1A0000C): MOV R0,R12 =Poke(&31F8,&676E654C,&EF020030): SWI "OS_ServiceCall" 6Poke(&31FC,&6F206874,&E8BD8000): LDMIA R13!,{PC} MPoke(&3200,&61702066,&00080AC2): EQUD &80AC2 ; Srv_Z80Reset  :  : + OUT (N),A extended to call Srv_Z80OUT  OUT_A ( OUT_A: 2GPoke(&3180,&726F7461,&E1802403): ORR R2,R0,R3,LSL #8 ; R2=port <:Poke(&3184,&212E242E,&E54C3100): STRB R3,[r12,#-256] F:Poke(&3188,&63657053,&E54C40FC): STRB R4,[r12,#-252] P2Poke(&318C,&6D757274,&E1A0000E): MOV R0,R14 ZOPoke(&3190,&6F72502E,&EBFFFFF8): BL &3178 ; Find ModuleBase d2Poke(&3194,&6D617267,&E1A0E000): MOV R14,R0 n7Poke(&3198,&68002E73,&E59F1010): LDR R1,[PC,#16] x2Poke(&319C,&63617261,&E1A0000C): MOV R0,R12 5)): MOV R3,reg ; Pass value to R3 "jPoke(&C324+A%*512,&E1000090,&EAFFDB97-128*A%) : B &3188 ; Jump to do srv_Z80OUT , 6 @: J: T? Ensure null EDxx and iDxx codes return silently, fix RETN ^ NullOps h:A%=&45 : Fix RETN r:Poke(&B2B8+64*A%+0,&E1000090,&E3A000FF): MOV R0,#&FF |APoke(&B2B8+64*A%+4,&E1000090,&E54C0041): STRB R0,[R12,#-65] 6Poke(&B2B8+64*A%+8,&E1000090,&EAFFE82A): B {ret} : :A%=&46 : Fix IM 0 8Poke(&B2B8+64*A%+0,&E1000090,&E3A00000): MOV R0,#0 @Poke(&B2B8+64*A%+4,&E1000090,&E50C005C): STR R0,[R12,#-92] 9Poke(&B2B8+64*A%+8,&E1000090,&E1A0F00E): MOV PC,R14 : 0 null(&B2B8,&63,&63): Should be LD (nn),HL 0 null(&B2B8,&6B,&6B): Should be LD HL,(nn) :  EDxx gaps: null(&B2B8,&00,&3F) null(&B2B8,&4C,&4C) null(&B2B8,&4E,&4E) null(&B2B8,&54,&55) null(&B2B8,&5C,&5D) &null(&B2B8,&64,&66) 0null(&B2B8,&6C,&6E) :null(&B2B8,&70,&71) Dnull(&B2B8,&74,&77) Nnull(&B2B8,&7C,&7F) Xnull(&B2B8,&80,&9F) bnull(&B2B8,&A4,&A7) lnull(&B2B8,&AC,&AF) vnull(&B2B8,&B4,&B7) null(&B2B8,&BC,&BF) null(&B2B8,&C0,&FF) :  xyxx gaps: null(&F2B8,&00,&08) null(&F2B8,&0A,&18) null(&F2B8,&1A,&20) null(&F2B8,&27,&28) null(&F2B8,&2F,&33) null(&F2B8,&37,&38) null(&F2B8,&3A,&3F)  B%=0 3 "null(&F2B8,&40+8*B%,&43+8*B%) "null(&F2B8,&47+8*B%,&47+8*B%)  P FOR A%=&40+8*B% TO &43+8*B%:PROCPoke(&F2B8+64*A%,&E1000090,&E1A0F00E):NEXT ; A%=&47+8*B%:PROCPoke(&F2B8+64*A%,&E1000090,&E1A0F00E)   *null(&F2B8,&78,&7B) 4null(&F2B8,&7F,&7F) > B%=0 7 H"null(&F2B8,&80+8*B%,&83+8*B%) R"null(&F2B8,&87+8*B%,&87+8*B%) \P FOR A%=&80+8*B% TO &83+8*B%:PROCPoke(&F2B8+64*A%,&E1000090,&E1A0F00E):NEXT f; A%=&87+8*B%:PROCPoke(&F2B8+64*A%,&E1000090,&E1A0F00E) p znull(&F2B8,&C0,&CA) null(&F2B8,&CC,&DC) null(&F2B8,&DE,&E0) null(&F2B8,&E2,&E2) null(&F2B8,&E4,&E4) null(&F2B8,&E6,&E8) null(&F2B8,&EA,&F8) null(&F2B8,&FA,&FC) null(&F2B8,&FE,&FF) :  Unimplemented xy codes: "null(&F2B8,&24,&24): INC XYH "null(&F2B8,&2D,&2D): DEC XYL "null(&F2B8,&76,&76): HALT XY (null(&F2B8,&84,&85): ADD A,XYH/XYL (null(&F2B8,&8C,&8D): ADC A,XYH/XYL &null(&F2B8,&94,&95): SUB XYH/XYL $&null(&F2B8,&9C,&9D): SBC XYH/XYL .&null(&F2B8,&A4,&A5): AND XYH/XYL 8%null(&F2B8,&B4,&B5): OR XYH/XYL B%null(&F2B8,&BC,&BD): CP XYH/XYL L: V `: jH null(B%,S%,E%): A%=S% E%:Poke(B%+64*A%,&E1000090,&E1A0F00E): t ~: : : :  SwiVector , There are three occurances of !8=value > 00A10 (drop out with error), 00AB0 (exit), 00D50 (setup) $Poke(&0A10,&E5810008,&F5810008) $Poke(&0AB0,&E5810008,&F5810008) $Poke(&0D50,&E5810008,&F5810008) - Also need to knock out SWI &C0000 calls $Poke(&0918,&EF0C0000,&FF0C0000) $Poke(&3040,&EF0C0000,&FF0C0000)  and 8 more Knock out !&3400000=x call $Poke(&0BDC,&E5810000,&F5810000) 0 Still ends up wanting direct screen access ( 2: <: F Test code: P4Poke(&30D8,&6AFFF63C,&EA000034): 30D8: B &31B0 Z6Poke(&31B0,&616C736E,&6AFFF606): 31C0: BVS &09D0 d