jamie from oz wrote: ↑Thu Jul 20, 2023 2:16 am
Yes i used your patch code for a template.
No worries.
0x1000 and the other R14 etc was referenced in the original bin i pulled with QH and BE and thought i would try that first to see if i had learned any thing about how it was relevant.
More below.
edit : looking at the reference to R3b i see that it makes sense as it is used more as table output and R34 / R30 probably make more sense also as function registers.
Yes R3B is used as the lookup result. If interrupts were not disabled, a foreground sub could do a lookup and the patch goes pear shaped. Logging a long payload list may take so much time that interrupts may need to be enabled, that would require greater care in selection of scratch registers. One would want to select scratch registers that are only used by background subroutines.
The goal is to select scratch registers for use by the patch code. The patch code requires three scratch registers.
We don't want the patch code to overwrite a scratch register in use by another subroutine.
We don't want another subroutine to overwrite the scratch registers used by patch code.
Looking at your current patch code;
R3B is the high byte of word R3A and also the address mode modifier for R3A.
By choosing to use R3A at 0x8482, 3B must be used at 0x8484.
Opcode 0x46 at 0x8483 is AD3W with address mode options of Indirect or Indirect Auto Increment.
By using the operand value of 0x3B at 0x8484, Indirect Auto Increment address mode is set for word R3A.
The address held by word R3A is increased by 0x02 on each loop.
Looking at the console code, it uses a few registers. It would be fair to say that using the registers the console sub uses, would be a fair bet for the patch code...to an extent.
R14 is being loaded with the contents of a console address. The console can't be plugged in while the QH is on the J3 port. Looking at R14's use throughout the bin it is obvious that it is a scratch register.
RA is a Special Function register, not a scratch register, leave that one alone.
R6 is a Special Function register, not a scratch register, leave that one alone.
R7A is being used with R6, lets leave that alone.
RD is a Special Function register, not a scratch register, leave that one alone.
RE is a Special Function register, not a scratch register, leave that one alone.
R30 is being used as a Rbase by the console sub. Looking at R30's use throughout the bin it is obvious that it is a scratch register.
R42 is being used for the result of the R30+offset by the console sub. Looking at R42 throughout the bin it appears to be a scratch, but is used with an SFR and some timing related code. Without complete disassembly of the bin, I'm not sold on this one.
R1A is being used for the number of data blocks by the console sub. Looking through the bin it is clearly a scratch register.
R1C is being used for the number of tunes by the console sub. Looking through the bin it is clearly a scratch register.
R14, R30, R1A & R1C all look good for use in the patch code, pick 3 out of the 4.
Looking at the console code, it uses two RAM ranges, 0xD00 and 0x1000.
I've seen bins using RAM just above 0x1000 to store parameter data. 3DBC is not disassembled well enough to know if it uses ~0x1000 up for other purposes. Payload offsetting to ~0x1000 as well as logging parameters at ~0x1000 up, just sounds like beta testing the QH and BE.
0xD00 is nominated for console use in the literature, the console can't be plugged in, so it's available to us for QH use as the payload offset.
Code: Select all
Sub_847e:
847e: fa di interrupts OFF;
847f: a3,01,00,0d,14 ldw R14,[R0+d00] Rcr14 = [d00]; # Scratch and RAM address
8484: 99,2a,15 cmpb R15,2a
8487: d7,3b jne 84c4 if (R15 = 2a) {
8489: 38,0a,1b jb B0,Ra,84a7 if (HSO_OVF = 0) { # SFR
848c: 47,01,0e,20,06,7c ad3w R7c,R6,[R0+200e] R7c = IO_Timer + [200e]; # SFR
8492: d7,02 jne 8496 if (R7c = 0) {
8494: 07,7c incw R7c R7c++; }
8496: a0,7c,0e ldw Re,R7c HSI_Time = R7c; # SFR
8499: b1,0f,0d ldb Rd,f HSO_Cmd = f; # SFR
849c: c9,a7,84 push 84a7 push(Sub_84a7);
849f: ad,00,30 ldzbw R30,0 wR30 = 0; # Scratch
84a2: cb,31,66,84 push [R30+8466] push([R30+8466]);
84a6: f0 ret return; }
Sub_84a7:
84a7: a3,01,80,0c,14 ldw R14,[R0+c80] Rcr14 = [c80];
84ac: ad,00,30 ldzbw R30,0 wR30 = 0;
84af: a3,31,78,84,42 ldw R42,[R30+8478] R42 = [R30+8478]; # Scratch, but?
84b4: c6,42,00 stb R0,[R42] [R42] = 0;
84b7: 36,14,0a jnb B6,R14,84c4 if (B6_Rcr14 = 1) {
84ba: ad,00,30 ldzbw R30,0 wR30 = 0;
84bd: a3,31,72,84,14 ldw R14,[R30+8472] Rcr14 = [R30+8472];
84c2: 20,04 sjmp 84c8 goto 84c8; } }
84c4: a1,22,20,14 ldw R14,2022 Rcr14 = 2022;
84c8: fb ei interrupts ON;
84c9: a1,f0,00,18 ldw R18,f0 R18 = f0;
84cd: b3,01,20,20,1a ldb R1a,[R0+2020] R1a = [2020]; # Scratch
84d2: a2,15,1c ldw R1c,[R14++] R1c = [Rcr14]; # Scratch
84d5: c2,19,1c stw R1c,[R18++] [R18++] = R1c;
84d8: e0,1a,f7 djnz R1a,84d2 R1a--;
if (R1a != 0) goto 84d2;
84db: a3,01,00,0d,14 ldw R14,[R0+d00] Rcr14 = [d00];
84e0: 99,3b,15 cmpb R15,3b
84e3: d7,03 jne 84e8 if (R15 = 3b) {
84e5: ef,18,8b call 1000 1000 (); } # RAM address, but?
84e8: f0 ret return;
I clearly dont understand the code yet and would like help sorting it please.
Ok.
The purpose of the patch code is to copy parameter data from Registers to the MBus.
Registers are inside the microprocessor, not on the MBus.
The QH connects to MBus at the J3 port.
When a register payload is selected for logging, BE must write the patch code to the QH so that the EEC microprocessor can copy the selected register to the datalog offset address.
The list of selected register payload addresses are written by BE to the QH at the payload list address. 0xA000 being chosen in this case. The EEC microprocessor executes the patch code as a background sub, copying the data for the register address stored at 0xA000, to the [register address+datalog offset]. It loops through the payload list until hitting 0x0000 (or 0xFFFF if opcode 0xDA is used at 0x8487).
payload goes further than what i had posted and didnt think that was required in the post.
Ok cool.
This is the patch I would try on 3DBC, with explanatory notes.
You need to edit it into a bin using 0xFF for addresses 0x8498 and 0x8499.
Use your hex editor to to edit addresses 0x8498 and 0x8499 until the file check sum is 0x0000.
Transfer those zero sum values to the definition QH tab patch code for 0x8498 and 0x8499.
Code: Select all
ADDRESS DATA
0x847E 0xFA Disable Interrupts
0x847F 0xA1 Load Word, Payload List Address 0xA000 into R30
0x8480 0x00
0x8481 0xA0
0x8482 0x30
0x8483 0x46 Load Payload Register Address from A000 into R14 with PSW Flags
0x8484 0x31
0x8485 0x00
0x8486 0x14 PSW Z Flag set if R14 = 0000. N Flag set if R14 = FFFF
0x8487 0xDA Jump if Z or N flags set
0x8488 0x0A
0x8489 0xA2 Load Current Payload Value into R1A from Current Payload Register Address
0x848A 0x14
0x848B 0x1A
0x848C 0xC3 Store the [R1A] Payload Value too address [0x0D00 + Payload Register Address] in [R14]
0x848D 0x15
0x848E 0x00
0x848F 0x0D
0x8490 0x1A
0x8491 0x27 Jump too Loop Start 0x8483
0x8492 0xF0
0x8493 0xFB Enable Interrupts
0x8494 0xF0 Return
0x8495 0xFF Fill
0x8496 0xFF
0x8497 0xFF
0x8498 0x?? Patch code
0x8499 0x?? Sum correction
0x849A 0xFF Fill
0x849B 0xFF
0x849C 0xFF
0x849D 0xFF
0x849E 0xFF
0x849F 0xFF
0x84A0 0xFF
0x84A1 0xFF
0x84A2 0xFF
0x84A3 0xFF
0x84A4 0xFF
0x84A5 0xFF
0x84A6 0xFF
0xA000 0000 Payload List
0xA001 0xFF Multiple
0xA002 0xFF Payload Slots
0xA003 0xFF In Pairs
0xA004 0xFF
… 0xFF
… 0xFF
Crickets on now...see ya
Back again
[edit]
Fixed a typo in the patch
The fill from 0x849A to 0x84A6 is not necessary for the patch to function. It just tidies up the remnants of the console sub. It would make much more sense if at some later time the bin with patch in place is uploaded and disassembled with fill there.