Unraveling some time code? - Page 1
Forum section: electronics / general

author: metertech58761
author_rank: Frequent Contributor
timestamp: November 15, 2023, 03:30:47 pm
content: Chipping away at some code and I think I have finally identified the segment that deals with correlating the unit and system clocks.However, I'm having a bit of difficulty visualizing how the time is calculated and stored. I'm not entirely sure if it is just a 7-day rollover or if it is some offset beyond 1/1/1980.I'm hoping that someone a bit more familiar with assembly-level math and 6801 / HC11 assembly can see what I cannot.If I can get a better understanding of what's going on here, it will help "unlock" some more of the code for me.Variables:NVR_46 - NVR_48: local time registerNVR_49 - NVR_4B: system time registerSRM_C0 - SRM_C2: likely a scratchpad areaSRM_D1 - SRM_D2: time difference temp register?timeDiff: Time difference (for setting time sync flag and calculating time on battery)Code:app_DABLDX #NVR_49JSR sub_687STD SRM_D1LDX #NVR_46JSR sub_687SUBD SRM_D1BCC app_DC0 ; higher or same?ADDD #$9D80app_DC0STD SRM_D1LDAA NVR_47CMPA NVR_4ABEQ app_DDELDX #$0008CPX SRM_D1BLT app_DDEBCS app_DDE ; lower?STAB timeDiff(continued)app_DDE(continued);Some type of time calculation;Accumulators A / B hold result (16-bit value in Accumulator D)sub_687LDAB $02,XLDAA #$90MULADDB $01,XADCA #$00STAA SRM_C0LDAA #$14MULSTD SRM_C1LDAA SRM_C0LDAB #$14MULTBACLRBADDD SRM_C1ADDB $00,XADCA #$00RTS

author: golden_labels
author_rank: Super Contributor
timestamp: November 16, 2023, 07:54:01 am
content: Disclaimer: AFAIK I have zero experience with this architecture.Proceduresub_687seems to be doing:Code:2880 * t + 20 * t + t… wheretis the i-th byte in anNVR_xtriplet. Yes, the order is “2, 0, 1”, not “2, 1, 0”. The operation is split into multiplying by 144 (8-bit · 8-bit → 16-bit) and then by 20 (16-bit · 8-bit → 16-bit). Doing 16-bit multiplication seems to be the cause of all the temporary values shuffling: it’s split into two 8-bit multiplications.Unless there is some deeper meaning behind these values,(1)it may be packing values into a single 16-bit number, so they can be cheaply compared in their lexicographical order. If that is true, the ranges would be limited to:[0, 19] for t[0, 143] for t[0, 22] for tThis way the above expression would fit the values into 16 bits without collisions. Does any number, which fits in these ranges (likely smaller than any of them) make any sense in the context of how these triplets are used elsewhere?The only thing, which pops up, is 2880, which is twice 1440 (the number of minutes in a day). So, hypothetically pair (t, t) may be storing half-minutes of a day in some convoluted little-endian format, and t counts days. t may be 10-minute periods of the day, and t half-minutes in the current 10-minute period.0x9D80 is exactly the number of half-minutes in 14 days. Also exactly the number of hours in 240 weeks, but that is less likely. I have no idea, why it would be added to local time in case system time is greater.0x0008 may be a number chosen to fit the alredy existing values, without any meaning by itself. But if the half-minutes hypothesis is right, it would indicate 4 minutes. Do 4 minutes manifest themselves anywhere?(1)Due to a mistake I already managed to discover subsequence (positions 54–68) of OEIS A025642 in your code. And 0x9D80 is 8!. So who knows?

author: metertech58761
author_rank: Frequent Contributor
timestamp: November 16, 2023, 01:29:53 pm
content: There's a counter elsewhere in the code that resets every 1800 counts, so you may be on to something there.I'll post that code later (it is one in a series of counters).Edit: I've read through it again and tbh, I think I can see a few more parts of the puzzle moving into place.There is definitely a need for a day of the week value, as the unit has a 7-day schedule.

author: golden_labels
author_rank: Super Contributor
timestamp: November 16, 2023, 03:19:54 pm
content: I missed one possibility that also includes 144 and 20. Quarter-minutes (15 s), 144 of which is 12 h. In this scenario 40320 neatly fits exactly one week.

author: metertech58761
author_rank: Frequent Contributor
timestamp: November 16, 2023, 04:39:07 pm
content: Pieces sliding together...As I went to clean up the definitions section of the source, I realized the very next variable after SRM_C2 (my temporary notation for the SRAM address $C2), is that counter that resets when it reaches 1800.So $C0 - $C2 may not be just a scratchpad... and are actually referenced throughout the code. So would it be safe to say that is the actual clock reference?

author: golden_labels
author_rank: Super Contributor
timestamp: November 16, 2023, 06:51:11 pm
content: SRM_C0…2are blindly overwritten bysub_687. Without caring about the previous contents. That happens twice for sys/local time comparison, one invocation destroying the results of the previous one. So I would say: it was your initial guess about these being scracthpad memory, that was right.

author: golden_labels
author_rank: Super Contributor
timestamp: November 18, 2023, 02:51:14 am
content: I inquired ChatGPT about the formula (2880 * t2 + 20 * t0 + t1) in multiple ways. It didn’t point to anything specific. But the responses were in a way peculiar. The smortnet was weirdly stuck with the idea, that variablestNrepresent days, hours and minutes. DHM is not the most popular date-time storage format. This gives a slight hint, that perhaps it seen it somewhere and we are on the right track about minutes (or half-minutes) being the basic unit and the topmost octet representing days.Going in reverse, in hope ChatGPT generates something from the original context, yielded nothing of value.

author: metertech58761
author_rank: Frequent Contributor
timestamp: November 20, 2023, 06:26:25 pm
content: Definitely on the right track... here's one routine that makes use of the above:; Subroutine; First call loads X register with the pointer to LMT time (previous NVR_46); Second call loads X register with the pointer to system time (previous NVR_49); Other variables:; SRM_D1 - 8-bit value; SRM_D2 - 8-bit value; Outside of this routine, SRM_D1 and SRM_D2 are handled as a single 16-bit value; SRM_D4 - 16 bit value - probably load profile-related (only other use is routine that works with load profile data); NVR_4F - may be schedule? Code below suggests addresses $0C4F - $0C56 is used for this; NVR_59 / NVR_5A - 16 bit value, no other calls from LMT ROM - is likely written by absent DCT ROM; There is a routine that wipes most of upper RAM ($0C28 to $0CFC aka NVR_28 to NVR_FC), so assume NVR_59 & NVR_5A are 0 for nowCode:sub_6A5LDAA flgTosSch ; is schedule flag clear (i.e., active)ORAA flgTmSync ; is time sync flag clear (i.e., LMT is synced to system time)BEQ sub_6B1CLR outBits ; No. Clear PIA output buffer and exitRTS;Unit is in sync with system time and schedule is active. Continue.sub_6B1LDAA $02,X ; Current dayPSHXINCAANDA #$0ESTAA SRM_D1LDD NVR_59DEC SRM_D1sub_6BFDEC SRM_D1BLE sub_6C7LSRDBRA sub_6BFsub_6C7LDAA #$00ANDB #$03BEQ sub_6D2CMPB #$01BNE sub_71DLDAA #$05sub_6D2STAA SRM_D2LDAB #$04STAB SRM_D1LDAB #$00PULXLDAA $02,X ; Current dayANDA #$01BEQ sub_6E2LDAB #$90sub_6E2LDAA #$00ADDD #$0090SUBB $01,X ; Minutes in current intervalSBCA #$00STD SRM_D4PSHXLDX #NVR_4FLDAB SRM_D2ABXLDD SRM_D4PSHAPSHBLDAA #$00LDAB $00,XSTD SRM_D4PULBPULASUBD SRM_D4BLT sub_722sub_6F7INXDEC SRM_D1BEQ sub_703STD SRM_D4LDD SRM_D4PSHAPSHBLDAA #$00LDAB $00,XSTD SRM_D4PULBPULASUBD SRM_D4BGE sub_6F7sub_703LDX #NVR_4FLDAB SRM_D2ADDB #$04ABXLDAA $00,XLDAB SRM_D1BEQ sub_716sub_711ASRAASRADECBBNE sub_711sub_716ANDA #$03CMPA #$03BNE sub_71DLDAA #$00sub_71DSTAA outBits ; Set TOU rate: 0 = base, 1 = lower peak, 2 = upper peakPULXRTSsub_722PULXLDAB $02,X ; Current dayINCBBITB #$01BNE sub_72BINCBsub_72BCMPB #$0FBNE sub_731LDAB #$01sub_731LDAA #$01STD tmSysMin ; B register: tmSysDayRTS