Reflecting on yesterday's experience with ROM 4, I'm a little daunted by what lays ahead. That was a 2 KiB ROM. This is a 32 KiB ROM, so 16 x as much to cover. At the same time, the understandings I got from ROM 4 might provide context that speeds things along.
The PIO A is configured much like on the MCU2, with differences in bit 7 and 6. On the MCU2 b7 is the interrupt in, and b6 is unused. On the PCU they are both outputs. B7 does something. B6 seems unused so far.
PIO A does not provide an interrupt source as it does on MCU2, but there are plenty of timers, and in particular CTCb0 is configured free running. It prescales by 256 and has a time constant of 3fh, so that would imply a total division of 16384. I don't know its clock source. If it was the 4 MHz system clock, then that would be 244 per second, and if that were externally prescaled by 4, then that would be 61 per second. Again, I don't know if any of that is the case.
What I did negatively confirm is that there seems to be no systick as with the other board. There is a counter that is incremented, but it is 8 bits and it saturates rather than rolling over.
I was eager to find such a tick, because my assumption was that PIO Port B would be serviced similarly here -- and it is, except for the timeout. Had it been the case I might have been able to work out what the clock rate likely is. Oh well.
The PIO B ISR is freaky. It starts off sane:
3D48 isrPIOb_3D48:
3D48 FB ei ; allow nesting
3D49 F5 push af
3D4A C5 push bc
3D4B D5 push de
3D4C E5 push hl
3D4D CD 56 3D call impl_isrPIOb_3D56 ; XXX PIO B isr implementation; invoked after saving all regs
3D50 E1 pop hl
3D51 D1 pop de
3D52 C1 pop bc
3D53 F1 pop af
3D54 ED 4D reti
and then things get weird:
3D56 impl_isrPIOb_3D56:
3D56 4F ld c, a ; XXX freaky; where was A set? non-isr code? 'expect'?
3D57 DB 10 in a, (10h) ; XXX PIO A data; ostensibly 'state' (though we aren't masking off high bits for some reason)
3D59 B9 cp c
3D5A 20 FA jr nz, impl_isrPIOb_3D56 ; loop, there it is!
3D5C E6 07 and 7 ; mask only b2,b1,b0 ('state')
3D5E C2 68 3E jp nz, sub_3E68
So, two things:
- a spin-wait in an ISR for anything tweaks my spidey-sense
- we are checking for a value that is specified in A, but we never explicitly set A ourselves. A will be whatever it was in the pre-interrupt environment. All the more curious because Port B I/O is not synchronous to this system.
And I guess a minor thing is that we didn't mask off bits 7 and 6.
This is a head-scratcher. I'll have to come back to it later. (maybe some weird coordination with non-isr code: "wait for this and let me know". I'll keep an eye out for that pattern.)
Another treat:
7FA9 3E 4F ld a, 4Fh
7FAB D3 E3 out (0E3h), a ; XXX set PIO B mode 1 (input)
7FAD 3E 87 ld a, 87h
7FAF D3 E2 out (0E2h), a ; XXX wut? it's now an input port, so what is write doing?
Since [Nigel] was concerned about the port 30/38/39 stuff I took a little look at that. On cold boot, port 38h is read, and then jumps into the warm boot routine which immediately writes it out to port 39h. Warm boot ("boot_100") may be entered in other ways, and those ways a value left over from a previous write to both 30h and 38h is the one that is written to 39h.
And that is the end of the story for those ports. They don't affect code flow in direct way (conceivably they might indirectly by causing some unknown hardware to do something different). So looking into what the 'leftover value' is that comes in on the warm boot path led me to some RTC stuff.
02C3 sub_2C3:
02C3 3A 6D C0 ld a, (byte_C06D) ; a flag set in NMI
02C6 B7 or a
02C7 20 0D jr nz, loc_2D6 ; horror
02C9 3A 68 C0 ld a, (byte_C068) ; another flag that could cause us to reboot
02CC B7 or a
02CD C8 ret z
02CE F3 di
02CF CD A2 0E call sub_EA2 ; XXX RTC alarm stuff; leaves something in A
02D2 D3 38 out (38h), a ; hmm!
02D4 D3 30 out (30h), a ; hmm!
02D6 loc_2D6: ; horror; warm boot
02D6 CD AC 02 call sub_2AC ; a very long delay
02D9 C3 00 01 jp boot_100 ; bootilicious
The sub_EA2 sets the RTC alarm. The oddity is that it is setting down to the seconds, but the RTC data sheet explicitly says that the seconds are ignored. So why does it bother? Also, we only are writing out the 10's digit, not the 1s digit. Anyway, that is the last value that is in A before exiting the routine, and so is the value that is written to 38h and 30h. I'm suspecting that this is a bug of sorts, and that the value in the ostensible 'alarm seconds' is either something that is not really alarm seconds, or that it doesn't matter. Have to dig in more...
Anyway, it makes me suspect that the port 30h,38h,39h are somehow related to sleeping or power or something. But they do not directly guide the flow of execution.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.