How can PK$save be stopped from adding an extra byte 'FF'?

Be clear with the topic titles to help members find the answers
amenjet
Posts: 200
Joined: Tue Jan 03, 2023 7:54 pm

Re: How can PK$save be stopped from adding an extra byte 'FF'?

Post by amenjet »

Lostgallifreyan wrote: Mon Jan 29, 2024 3:03 pm
amenjet wrote: Mon Jan 29, 2024 2:43 pm To find a service routine we'd need to follow the SWI vector and find the table of routines that perform each function. I followed to the redirect vector in RAM, but need to find what is there to follow the rest of the code. There should then be a table or sequence f jumps.
That's weird.. I'd cut what might have been a longer reply thinking it's not relevant, and you'd already know. That 'rst_entry_point' thing you asked about once. You'll have seen the mention in the system variables list, bolded text "rst_entry_point 2174-76", which I recently saw better described than anywhere before, as a value changed by the Comms Link on install, to point to itself to give access to its own routines.

What's weird is that if the ROM's internal addresses go with it, and are effectively hardcoded, why jump via some location in RAM? The only reason I can think of was to help people who wanted to replace services with their own code while satisfying expectations of existing code that called for a service.
I wonder if these disassembly files could go on a wiki or something so several people could work on bits at once?
You traced it to RAM... Which address? I don't know if I can trace it from there but I can try if I can see what my Organiser puts at that address. If I have the routines located my own script will make a disassembly that is easier to read than Gidra's, but more primitive, unless I devise a way to convert branch jump sizes into a label-based notation. (Not that my script has any notion of how to tell code from data, but it usually works if it's definitely pointing at code!)
The SWI address vector is at FFFA, that jumps to 8291 and that jumps to the address in location 2052 (RAM). The reason for these jumps through RAM is indeed so that they can be patched or extended. I'm looking at adding some single stepping of machine code to my recreation so I can trace execution and get answers to these sorts of problems.
Lostgallifreyan
Posts: 83
Joined: Thu Jan 12, 2023 8:25 pm

Re: How can PK$save be stopped from adding an extra byte 'FF'?

Post by Lostgallifreyan »

amenjet wrote: Mon Jan 29, 2024 10:15 pm The SWI address vector is at FFFA, that jumps to 8291 and that jumps to the address in location 2052 (RAM). The reason for these jumps through RAM is indeed so that they can be patched or extended. I'm looking at adding some single stepping of machine code to my recreation so I can trace execution and get answers to these sorts of problems.
I wonder if it would yield an answer even then. I tried to trace this, and it's like crawling through the Grimpen Mire in the dark, in a fog.

It starts easily, at 7FFA, the next location is given, varied according to ROM version, at which point it gets the number at $2052 into X and by adding 0 as 'd' it jumps to an absolute address of 130 ($82) in the LA, v3.3 Organiser, assuming the value 130 got by PEEKB($2052) is valid, and I don't see how it can be because the location it indicates is a one-byte variable, not code!

At this point I can't trace this, and my suspicion is that any real value must be in address $2052 only in the instant it is needed, and that might need a full reverse engineering of the Organiser to figure out.

When I worked on the Comms Link code for ORG-Link I had the helpful presence of specific strings to help guide me to actual code to disassemble, but in this case I have nothing like that, and whatever it did would be specific to asserting hardware control lines and such, so I'd not recognise it even if I were looking directly at it!

At this point I have to admit I can't follow the trail, and likely never will.

EDIT:
I got something wrong, using PEEKB when it should be PEEKW, but then I get address $8242. That's just as meaningless, it's a PUL A instruction. It looked like it was mid-code in whatever, it seems extremely unlikely that a service would begin by pulling something off the stack unless yet more hidden complexity had put something there first!

I really am done, it would be easier to write explicit code to do a raw write directly to a RAM pack than to try to undo this horrible knot. At least, it would if the Psion docs hold enough info to enable this to be done.
amenjet
Posts: 200
Joined: Tue Jan 03, 2023 7:54 pm

Re: How can PK$save be stopped from adding an extra byte 'FF'?

Post by amenjet »

Lostgallifreyan wrote: Tue Jan 30, 2024 4:51 pm
amenjet wrote: Mon Jan 29, 2024 10:15 pm The SWI address vector is at FFFA, that jumps to 8291 and that jumps to the address in location 2052 (RAM). The reason for these jumps through RAM is indeed so that they can be patched or extended. I'm looking at adding some single stepping of machine code to my recreation so I can trace execution and get answers to these sorts of problems.
I wonder if it would yield an answer even then. I tried to trace this, and it's like crawling through the Grimpen Mire in the dark, in a fog.

It starts easily, at 7FFA, the next location is given, varied according to ROM version, at which point it gets the number at $2052 into X and by adding 0 as 'd' it jumps to an absolute address of 130 ($82) in the LA, v3.3 Organiser, assuming the value 130 got by PEEKB($2052) is valid, and I don't see how it can be because the location it indicates is a one-byte variable, not code!

At this point I can't trace this, and my suspicion is that any real value must be in address $2052 only in the instant it is needed, and that might need a full reverse engineering of the Organiser to figure out.

When I worked on the Comms Link code for ORG-Link I had the helpful presence of specific strings to help guide me to actual code to disassemble, but in this case I have nothing like that, and whatever it did would be specific to asserting hardware control lines and such, so I'd not recognise it even if I were looking directly at it!

At this point I have to admit I can't follow the trail, and likely never will.

EDIT:
I got something wrong, using PEEKB when it should be PEEKW, but then I get address $8242. That's just as meaningless, it's a PUL A instruction. It looked like it was mid-code in whatever, it seems extremely unlikely that a service would begin by pulling something off the stack unless yet more hidden complexity had put something there first!

I really am done, it would be easier to write explicit code to do a raw write directly to a RAM pack than to try to undo this horrible knot. At least, it would if the Psion docs hold enough info to enable this to be done.
I'm just about to put an XP ROm into my recreation here, I have added a USB CLI and so can dump the emulator memory. I'm going to add tracing as well, so I will be able to trace any code. I have an LZ64 ROM in the code at the moment which doesn't match what you have. I'm pretty sure the number at 2052 is 16 bit and JMP 0,X jumps to that address. I'll post here when I get some result.
Lostgallifreyan
Posts: 83
Joined: Thu Jan 12, 2023 8:25 pm

Re: How can PK$save be stopped from adding an extra byte 'FF'?

Post by Lostgallifreyan »

amenjet wrote: Tue Jan 30, 2024 8:32 pm I'm pretty sure the number at 2052 is 16 bit and JMP 0,X jumps to that address. I'll post here when I get some result.
I'll look closely at anythign you come up with and try to understand it, maybe even make it useful if I can. I agree about the jump, but two Organisers with different working history since first boot were giving -32190 ($8242) at address $2052, and that didn't look right, it made no sense as a starting point in a new routine.

I think my question is what I think the StackOverflow bods call an XY problem, insisting on solving for X when Y needs to be known.

If I knew how to write ONE byte at ONE location, on a RAM pack, I could solve this completely. The only reason to examine services is to see how Psion do this. I have failed to do that, and it's beginning to look as if raw byte-writing code might be by far the easier thing to do. I wouldn't need to worry about implications of writing to EPROM or Flash, because I can detect the pack type and prevent any code running if the wrong type of pack was fitted.

I have to ask this because I think my first question looks like the wrong one!
amenjet
Posts: 200
Joined: Tue Jan 03, 2023 7:54 pm

Re: How can PK$save be stopped from adding an extra byte 'FF'?

Post by amenjet »

I've added tracing and memory dump to the recreation, but am having problems running the 3.3 ROM for some reason. The more complicated, bank switched, LZ64 ROM runs fine, but that isn't what we are looking for here.

$8242 looks correct for the SWI vector address, the disassembly is here:

Code: Select all

            8242 32              PULA
            8243 b7 20 6f        STA        DAT_206f
            8246 33              PULB
            8247 32              PULA
            8248 fd 20 69        STD        DAT_2069
            824b 38              PULX
            824c ff 20 6b        STX        DAT_206b
            824f 38              PULX
            8250 e6 00           LDB        0x0,X
            8252 08              INX
            8253 3c              PSHX
            8254 fe 23 e7        LDX        DAT_23e7
            8257 3a              ABX
            8258 3a              ABX
            8259 ee 00           LDX        0x0,X
That is pulling the registers that SWI pushed on the stack and storing them in places like this:

Code: Select all

btb_4dontuse	206F		Used in SWI's to save flag register.
So that matches this being SWI handling code. It should be possible to find the correct code path from there for any system call.
amenjet
Posts: 200
Joined: Tue Jan 03, 2023 7:54 pm

Re: How can PK$save be stopped from adding an extra byte 'FF'?

Post by amenjet »

OK, I now have the 3.3 ROm working on my recreation, which has tracing etc on it now.

For those that are interested:
It was a problem that I should have remembered. The organisers when they are switched off and back on, don't check for cold start and reset or warm start and run the code without clearing RAM, rather, they actually suspend by storing the PC in RAM and reloading that when warm starting. The organiser actually suspends and resumes back to where it was when turned off. Of course, you can do a cold start by removing the battery as that clears the A: RAM. Also, if the ROM wrote the PC then it has to be the address of an instruction.

On the recreation the A: drive is in serial EEPROM, which has the advantage that it isn't cleared on battery removal. This makes the data securely stored. Too securely in some situations. If you take the LZ64 ROM out of an organiser and put an XP ROM in, on a real organiser (if you could do this and you can't as the hardware is different so the code won't run), then you can do a cold start by removing the battery. On the recreation, you can swap ROMs and it does work (because the emulator emulates the appropriate hardware for the ROM), but the PC stored in RAM is not a valid one for the new ROM because it was written by the old ROM. So the new ROM immediately crashes on warm start. Removing the battery doesn't clear this bad data, so you have to invalidate the EEPROM A: drive somehow (I added features to do this to the recreation code, but forgot to use them).

All, is now running, and I see the same value in $2052:

Code: Select all

2050: 81 F3 82 42 81 C5 80 AF 
2058: 80 3A 84 76 84 AA 85 8B 
2060: 55 55 01 C8 48 7E FF 7F 
2068: E0 FF 00 01 2C A5 2B C8 
2070: 46 49 4E 44 20 53 41 56 
2078: 45 20 44 49 41 52 59 20 
2080: 43 41 4C 43 20 50 52 4F 
2088: 47 20 45 52 41 53 45 20 

Here's a trace of the code executing from $8242:

Code: Select all

0000:8242      A:0C B:60 X:8242 SP:7FF3
0001:8243      A:F0 B:60 X:8242 SP:7FF4
0002:8246      A:F0 B:60 X:8242 SP:7FF4
0003:8247      A:F0 B:60 X:8242 SP:7FF5
0004:8248      A:0C B:60 X:8242 SP:7FF6
0005:824B      A:0C B:60 X:8242 SP:7FF6
0006:824C      A:0C B:60 X:82B9 SP:7FF8
0007:824F      A:0C B:60 X:82B9 SP:7FF8
0008:8250      A:0C B:60 X:AB55 SP:7FFA
0009:8252      A:0C B:10 X:AB55 SP:7FFA
000A:8253      A:0C B:10 X:AB56 SP:7FFA
000B:8254      A:0C B:10 X:AB56 SP:7FF8
000C:8257      A:0C B:10 X:82B9 SP:7FF8
000D:8258      A:0C B:10 X:82C9 SP:7FF8
000E:8259      A:0C B:10 X:82D9 SP:7FF8
000F:825B      A:0C B:10 X:AC04 SP:7FF8
0010:825C      A:0C B:10 X:AC04 SP:7FF6
0011:825F      A:0C B:10 X:82B9 SP:7FF6
0012:8262      A:0C B:60 X:82B9 SP:7FF6
0013:8263      A:0C B:60 X:82B9 SP:7FF5
0014:8266      A:F0 B:60 X:82B9 SP:7FF5
0015:8267      A:F0 B:60 X:82B9 SP:7FF5
0016:8268      A:0C B:60 X:82B9 SP:7FF6
0017:AC04      A:0C B:60 X:82B9 SP:7FF8
0018:AC05      A:0C B:60 X:82B9 SP:7FF6
0019:AC06      A:0C B:60 X:82B9 SP:7FF5
001A:AC07      A:0C B:60 X:82B9 SP:7FF4
001B:AC0D      A:0C B:60 X:82B9 SP:7FF2
001C:AC0F      A:0C B:60 X:82B9 SP:7FF2
001D:AC11      A:0C B:60 X:82B9 SP:7FF2
001E:AC13      A:0C B:60 X:82B9 SP:7FF2
001F:AC15      A:0C B:60 X:82B9 SP:7FF2
0020:AC18      A:0C B:60 X:AD8A SP:7FF2
0021:AC19      A:0C B:0C X:AD8A SP:7FF2
0022:8A80      A:0C B:0C X:AD8A SP:7FF2
0023:8A81      A:0C B:0C X:AD96 SP:7FF2
0024:8A82      A:0C B:0C X:ADA2 SP:7FF2
0025:8A84      A:0C B:0C X:AB2B SP:7FF2
0026:AB2B      A:0C B:0C X:AB2B SP:7FF2
0027:AB2C      A:0C B:00 X:AB2B SP:7FF2
0028:AB2E      A:0C B:00 X:AB2B SP:7FF2
0029:AB38      A:0C B:00 X:AB2B SP:7FF0
002A:AB3B      A:01 B:0C X:AB2B SP:7FF0
002B:AB1B      A:01 B:0C X:AB2B SP:7FF0
002C:AB1E      A:01 B:0C X:AB2B SP:7FEE
002D:AB21      A:01 B:0C X:AB2B SP:7FEE
002E:AB23      A:01 B:0C X:AB2B SP:7FEE
002F:AB26      A:01 B:0C X:AB2B SP:7FEE
0030:AB1D      A:01 B:0C X:AB2B SP:7FF0
0031:AB1E      A:0C B:0C X:AB2B SP:7FF0
0032:AB21      A:0C B:0C X:AB2B SP:7FF0
0033:AB23      A:0C B:0C X:AB2B SP:7FF0
0034:AB26      A:0C B:0C X:AB2B SP:7FF0
0035:AB30      A:0C B:0C X:AB2B SP:7FF2
0036:AB33      A:0C B:0C X:2070 SP:7FF2
0037:AB35      A:0C B:20 X:2070 SP:7FF2
0038:87B4      A:0C B:20 X:2070 SP:7FF2
0039:87B6      A:20 B:20 X:2070 SP:7FF2
003A:87B9      A:20 B:20 X:2070 SP:7FF2
003B:87BA      A:20 B:10 X:2070 SP:7FF2
003C:87C6      A:20 B:10 X:2070 SP:7FF2
003D:87BF      A:20 B:10 X:2070 SP:7FF2
003E:87C1      A:20 B:10 X:2070 SP:7FF2
003F:87C2      A:20 B:10 X:2071 SP:7FF2
0040:87C4      A:20 B:10 X:2071 SP:7FF2
0041:87C5      A:20 B:10 X:2072 SP:7FF2
0042:87C6      A:20 B:0F X:2072 SP:7FF2
0043:87BF      A:20 B:0F X:2072 SP:7FF2
0044:87C1      A:20 B:0F X:2072 SP:7FF2
0045:87C2      A:20 B:0F X:2073 SP:7FF2
0046:87C4      A:20 B:0F X:2073 SP:7FF2
0047:87C5      A:20 B:0F X:2074 SP:7FF2
0048:87C6      A:20 B:0E X:2074 SP:7FF2
0049:87BF      A:20 B:0E X:2074 SP:7FF2
004A:87C1      A:20 B:0E X:2074 SP:7FF2
004B:87C2      A:20 B:0E X:2075 SP:7FF2
004C:87C4      A:20 B:0E X:2075 SP:7FF2
004D:87C5      A:20 B:0E X:2076 SP:7FF2
004E:87C6      A:20 B:0D X:2076 SP:7FF2
004F:87BF      A:20 B:0D X:2076 SP:7FF2
0050:87C1      A:20 B:0D X:2076 SP:7FF2
0051:87C2      A:20 B:0D X:2077 SP:7FF2
0052:87C4      A:20 B:0D X:2077 SP:7FF2
0053:87C5      A:20 B:0D X:2078 SP:7FF2
0054:87C6      A:20 B:0C X:2078 SP:7FF2
0055:87BF      A:20 B:0C X:2078 SP:7FF2
0056:87C1      A:20 B:0C X:2078 SP:7FF2
0057:87C2      A:20 B:0C X:2079 SP:7FF2
0058:87C4      A:20 B:0C X:2079 SP:7FF2
0059:87C5      A:20 B:0C X:207A SP:7FF2
005A:87C6      A:20 B:0B X:207A SP:7FF2
005B:87BF      A:20 B:0B X:207A SP:7FF2
005C:87C1      A:20 B:0B X:207A SP:7FF2
005D:87C2      A:20 B:0B X:207B SP:7FF2
005E:87C4      A:20 B:0B X:207B SP:7FF2
005F:87C5      A:20 B:0B X:207C SP:7FF2
0060:87C6      A:20 B:0A X:207C SP:7FF2
0061:87BF      A:20 B:0A X:207C SP:7FF2
0062:87C1      A:20 B:0A X:207C SP:7FF2
0063:87C2      A:20 B:0A X:207D SP:7FF2
0064:87C4      A:20 B:0A X:207D SP:7FF2
0065:87C5      A:20 B:0A X:207E SP:7FF2
0066:87C6      A:20 B:09 X:207E SP:7FF2
0067:87BF      A:20 B:09 X:207E SP:7FF2
0068:87C1      A:20 B:09 X:207E SP:7FF2
0069:87C2      A:20 B:09 X:207F SP:7FF2
006A:87C4      A:20 B:09 X:207F SP:7FF2
006B:87C5      A:20 B:09 X:2080 SP:7FF2
006C:87C6      A:20 B:08 X:2080 SP:7FF2
006D:87BF      A:20 B:08 X:2080 SP:7FF2
006E:87C1      A:20 B:08 X:2080 SP:7FF2
006F:87C2      A:20 B:08 X:2081 SP:7FF2
0070:87C4      A:20 B:08 X:2081 SP:7FF2
0071:87C5      A:20 B:08 X:2082 SP:7FF2
0072:87C6      A:20 B:07 X:2082 SP:7FF2
0073:87BF      A:20 B:07 X:2082 SP:7FF2
0074:87C1      A:20 B:07 X:2082 SP:7FF2
0075:87C2      A:20 B:07 X:2083 SP:7FF2
0076:87C4      A:20 B:07 X:2083 SP:7FF2
0077:87C5      A:20 B:07 X:2084 SP:7FF2
0078:87C6      A:20 B:06 X:2084 SP:7FF2
0079:87BF      A:20 B:06 X:2084 SP:7FF2
007A:87C1      A:20 B:06 X:2084 SP:7FF2
007B:87C2      A:20 B:06 X:2085 SP:7FF2
007C:87C4      A:20 B:06 X:2085 SP:7FF2
007D:87C5      A:20 B:06 X:2086 SP:7FF2
007E:87C6      A:20 B:05 X:2086 SP:7FF2
007F:87BF      A:20 B:05 X:2086 SP:7FF2
0080:87C1      A:20 B:05 X:2086 SP:7FF2
0081:87C2      A:20 B:05 X:2087 SP:7FF2
0082:87C4      A:20 B:05 X:2087 SP:7FF2
0083:87C5      A:20 B:05 X:2088 SP:7FF2
0084:87C6      A:20 B:04 X:2088 SP:7FF2
0085:87BF      A:20 B:04 X:2088 SP:7FF2
0086:87C1      A:20 B:04 X:2088 SP:7FF2
0087:87C2      A:20 B:04 X:2089 SP:7FF2
0088:87C4      A:20 B:04 X:2089 SP:7FF2
0089:87C5      A:20 B:04 X:208A SP:7FF2
008A:87C6      A:20 B:03 X:208A SP:7FF2
008B:87BF      A:20 B:03 X:208A SP:7FF2
008C:87C1      A:20 B:03 X:208A SP:7FF2
008D:87C2      A:20 B:03 X:208B SP:7FF2
008E:87C4      A:20 B:03 X:208B SP:7FF2
008F:87C5      A:20 B:03 X:208C SP:7FF2
0090:87C6      A:20 B:02 X:208C SP:7FF2
0091:87BF      A:20 B:02 X:208C SP:7FF2
0092:87C1      A:20 B:02 X:208C SP:7FF2
0093:87C2      A:20 B:02 X:208D SP:7FF2
0094:87C4      A:20 B:02 X:208D SP:7FF2
0095:87C5      A:20 B:02 X:208E SP:7FF2
0096:87C6      A:20 B:01 X:208E SP:7FF2
0097:87BF      A:20 B:01 X:208E SP:7FF2
0098:87C1      A:20 B:01 X:208E SP:7FF2
0099:87C2      A:20 B:01 X:208F SP:7FF2
009A:87C4      A:20 B:01 X:208F SP:7FF2
009B:87C5      A:20 B:01 X:2090 SP:7FF2
009C:87C6      A:20 B:00 X:2090 SP:7FF2
009D:87C8      A:20 B:00 X:2090 SP:7FF2
009E:AC09      A:20 B:00 X:2090 SP:7FF4
009F:AC0A      A:0C B:00 X:2090 SP:7FF5
00A0:AC0B      A:0C B:60 X:2090 SP:7FF6
00A1:AC0C      A:0C B:60 X:82B9 SP:7FF8
00A2:AB56      A:0C B:60 X:82B9 SP:7FFA
00A3:8173      A:0C B:60 X:82B9 SP:7FFC
00A4:A166      A:0C B:60 X:82B9 SP:7FFA
00A5:A169      A:0C B:60 X:2000 SP:7FFA
00A6:A16A      A:0C B:60 X:2000 SP:7FF8
00A7:A16C      A:0C B:40 X:2000 SP:7FF8
00A8:87B8      A:0C B:40 X:2000 SP:7FF6
00A9:87B9      A:00 B:40 X:2000 SP:7FF6
00AA:87BA      A:00 B:20 X:2000 SP:7FF6
00AB:87C6      A:00 B:20 X:2000 SP:7FF6
00AC:87BF      A:00 B:20 X:2000 SP:7FF6
00AD:87C1      A:00 B:20 X:2000 SP:7FF6
00AE:87C2      A:00 B:20 X:2001 SP:7FF6
00AF:87C4      A:00 B:20 X:2001 SP:7FF6
00B0:87C5      A:00 B:20 X:2002 SP:7FF6
00B1:87C6      A:00 B:1F X:2002 SP:7FF6
00B2:87BF      A:00 B:1F X:2002 SP:7FF6
00B3:87C1      A:00 B:1F X:2002 SP:7FF6
00B4:87C2      A:00 B:1F X:2003 SP:7FF6
00B5:87C4      A:00 B:1F X:2003 SP:7FF6
00B6:87C5      A:00 B:1F X:2004 SP:7FF6
00B7:87C6      A:00 B:1E X:2004 SP:7FF6
00B8:87BF      A:00 B:1E X:2004 SP:7FF6
00B9:87C1      A:00 B:1E X:2004 SP:7FF6
00BA:87C2      A:00 B:1E X:2005 SP:7FF6
00BB:87C4      A:00 B:1E X:2005 SP:7FF6
00BC:87C5      A:00 B:1E X:2006 SP:7FF6
00BD:87C6      A:00 B:1D X:2006 SP:7FF6
00BE:87BF      A:00 B:1D X:2006 SP:7FF6
00BF:87C1      A:00 B:1D X:2006 SP:7FF6
00C0:87C2      A:00 B:1D X:2007 SP:7FF6
00C1:87C4      A:00 B:1D X:2007 SP:7FF6
00C2:87C5      A:00 B:1D X:2008 SP:7FF6
00C3:87C6      A:00 B:1C X:2008 SP:7FF6
00C4:87BF      A:00 B:1C X:2008 SP:7FF6
00C5:87C1      A:00 B:1C X:2008 SP:7FF6
00C6:87C2      A:00 B:1C X:2009 SP:7FF6
00C7:87C4      A:00 B:1C X:2009 SP:7FF6
00C8:87C5      A:00 B:1C X:200A SP:7FF6
00C9:87C6      A:00 B:1B X:200A SP:7FF6
00CA:87BF      A:00 B:1B X:200A SP:7FF6
00CB:87C1      A:00 B:1B X:200A SP:7FF6
00CC:87C2      A:00 B:1B X:200B SP:7FF6
00CD:87C4      A:00 B:1B X:200B SP:7FF6
00CE:87C5      A:00 B:1B X:200C SP:7FF6
00CF:87C6      A:00 B:1A X:200C SP:7FF6
00D0:87BF      A:00 B:1A X:200C SP:7FF6
00D1:87C1      A:00 B:1A X:200C SP:7FF6
00D2:87C2      A:00 B:1A X:200D SP:7FF6
00D3:87C4      A:00 B:1A X:200D SP:7FF6
00D4:87C5      A:00 B:1A X:200E SP:7FF6
00D5:87C6      A:00 B:19 X:200E SP:7FF6
00D6:87BF      A:00 B:19 X:200E SP:7FF6
00D7:87C1      A:00 B:19 X:200E SP:7FF6
00D8:87C2      A:00 B:19 X:200F SP:7FF6
00D9:87C4      A:00 B:19 X:200F SP:7FF6
00DA:87C5      A:00 B:19 X:2010 SP:7FF6
00DB:87C6      A:00 B:18 X:2010 SP:7FF6
00DC:87BF      A:00 B:18 X:2010 SP:7FF6
00DD:87C1      A:00 B:18 X:2010 SP:7FF6
00DE:87C2      A:00 B:18 X:2011 SP:7FF6
00DF:87C4      A:00 B:18 X:2011 SP:7FF6
00E0:87C5      A:00 B:18 X:2012 SP:7FF6
00E1:87C6      A:00 B:17 X:2012 SP:7FF6
00E2:87BF      A:00 B:17 X:2012 SP:7FF6
00E3:87C1      A:00 B:17 X:2012 SP:7FF6
00E4:87C2      A:00 B:17 X:2013 SP:7FF6
00E5:87C4      A:00 B:17 X:2013 SP:7FF6
00E6:87C5      A:00 B:17 X:2014 SP:7FF6
00E7:87C6      A:00 B:16 X:2014 SP:7FF6
00E8:87BF      A:00 B:16 X:2014 SP:7FF6
00E9:87C1      A:00 B:16 X:2014 SP:7FF6
00EA:87C2      A:00 B:16 X:2015 SP:7FF6
00EB:87C4      A:00 B:16 X:2015 SP:7FF6
00EC:87C5      A:00 B:16 X:2016 SP:7FF6
00ED:87C6      A:00 B:15 X:2016 SP:7FF6
00EE:87BF      A:00 B:15 X:2016 SP:7FF6
00EF:87C1      A:00 B:15 X:2016 SP:7FF6
00F0:87C2      A:00 B:15 X:2017 SP:7FF6
00F1:87C4      A:00 B:15 X:2017 SP:7FF6
00F2:87C5      A:00 B:15 X:2018 SP:7FF6
00F3:87C6      A:00 B:14 X:2018 SP:7FF6
00F4:87BF      A:00 B:14 X:2018 SP:7FF6
00F5:87C1      A:00 B:14 X:2018 SP:7FF6
00F6:87C2      A:00 B:14 X:2019 SP:7FF6
00F7:87C4      A:00 B:14 X:2019 SP:7FF6
00F8:87C5      A:00 B:14 X:201A SP:7FF6
00F9:87C6      A:00 B:13 X:201A SP:7FF6
00FA:87BF      A:00 B:13 X:201A SP:7FF6
00FB:87C1      A:00 B:13 X:201A SP:7FF6
00FC:87C2      A:00 B:13 X:201B SP:7FF6
00FD:87C4      A:00 B:13 X:201B SP:7FF6
00FE:87C5      A:00 B:13 X:201C SP:7FF6
00FF:87C6      A:00 B:12 X:201C SP:7FF6
0100:87BF      A:00 B:12 X:201C SP:7FF6
0101:87C1      A:00 B:12 X:201C SP:7FF6
0102:87C2      A:00 B:12 X:201D SP:7FF6
0103:87C4      A:00 B:12 X:201D SP:7FF6
0104:87C5      A:00 B:12 X:201E SP:7FF6
0105:87C6      A:00 B:11 X:201E SP:7FF6
0106:87BF      A:00 B:11 X:201E SP:7FF6
0107:87C1      A:00 B:11 X:201E SP:7FF6
0108:87C2      A:00 B:11 X:201F SP:7FF6
0109:87C4      A:00 B:11 X:201F SP:7FF6
010A:87C5      A:00 B:11 X:2020 SP:7FF6
010B:87C6      A:00 B:10 X:2020 SP:7FF6
010C:87BF      A:00 B:10 X:2020 SP:7FF6
010D:87C1      A:00 B:10 X:2020 SP:7FF6
010E:87C2      A:00 B:10 X:2021 SP:7FF6
010F:87C4      A:00 B:10 X:2021 SP:7FF6
0110:87C5      A:00 B:10 X:2022 SP:7FF6
0111:87C6      A:00 B:0F X:2022 SP:7FF6
0112:87BF      A:00 B:0F X:2022 SP:7FF6
0113:87C1      A:00 B:0F X:2022 SP:7FF6
0114:87C2      A:00 B:0F X:2023 SP:7FF6
0115:87C4      A:00 B:0F X:2023 SP:7FF6
0116:87C5      A:00 B:0F X:2024 SP:7FF6
0117:87C6      A:00 B:0E X:2024 SP:7FF6
0118:87BF      A:00 B:0E X:2024 SP:7FF6
0119:87C1      A:00 B:0E X:2024 SP:7FF6
011A:87C2      A:00 B:0E X:2025 SP:7FF6
011B:87C4      A:00 B:0E X:2025 SP:7FF6
011C:87C5      A:00 B:0E X:2026 SP:7FF6
011D:87C6      A:00 B:0D X:2026 SP:7FF6
011E:87BF      A:00 B:0D X:2026 SP:7FF6
011F:87C1      A:00 B:0D X:2026 SP:7FF6
0120:87C2      A:00 B:0D X:2027 SP:7FF6
0121:87C4      A:00 B:0D X:2027 SP:7FF6
0122:87C5      A:00 B:0D X:2028 SP:7FF6
0123:87C6      A:00 B:0C X:2028 SP:7FF6
0124:87BF      A:00 B:0C X:2028 SP:7FF6
0125:87C1      A:00 B:0C X:2028 SP:7FF6
0126:87C2      A:00 B:0C X:2029 SP:7FF6
0127:87C4      A:00 B:0C X:2029 SP:7FF6
0128:87C5      A:00 B:0C X:202A SP:7FF6
0129:87C6      A:00 B:0B X:202A SP:7FF6
012A:87BF      A:00 B:0B X:202A SP:7FF6
012B:87C1      A:00 B:0B X:202A SP:7FF6
I'm now going to trigger the tracing on specific values of the registers when the SWI occurs so I can trace the OS call we are interested in.
amenjet
Posts: 200
Joined: Tue Jan 03, 2023 7:54 pm

Re: How can PK$save be stopped from adding an extra byte 'FF'?

Post by amenjet »

Looking a the SWI code:

Code: Select all

            8242 32              PULA
            8243 b7 20 6f        STA        DAT_206f
            8246 33              PULB
            8247 32              PULA
            8248 fd 20 69        STD        DAT_2069
            824b 38              PULX
            824c ff 20 6b        STX        DAT_206b
            824f 38              PULX
            8250 e6 00           LDB        0x0,X
            8252 08              INX
            8253 3c              PSHX
            8254 fe 23 e7        LDX        DAT_23e7
            8257 3a              ABX
            8258 3a              ABX
            8259 ee 00           LDX        0x0,X
This pulls the registers off the stack and saves them then it pulls the return address (which points to the SWI function number) and indexes that off the value in 23e7, which is:

Code: Select all

bta_vect	23E7/E8		Pointer to SWI vector table.            
So that is the table of SWI system call functions. That has this value:

Code: Select all

23E0: 55 55 55 55 55 55 05 82 
23E8: B9 00 55 00 00 00 00 00 
And so the table is at $82B9. Service 61 is at $839b, if I've calculated correctly.

This looks like a table:

Code: Select all

            8395 88 c0           dw         88C0h
            8397 88 b7           dw         88B7h
            8399 86 0b           dw         860Bh
            839b 87 b9           dw         87B9h
            839d 87 c9           dw         87C9h
            839f 88 05           dw         8805h
            83a1 86 19           dw         8619h

So the PK$SAVE routine is at $87b9, I think.

Code: Select all

                             LAB_87b9                                        XREF[2]:     87b6(j), d2ff  
            87b9 54              LSRB
            87ba 24 0a           BCC        LAB_87c6
            87bc 5c              INCB
            87bd 20 03           BRA        LAB_87c2
                             LAB_87bf                                        XREF[1]:     87c6(j)  
            87bf a7 00           STA        0x0,X
            87c1 08              INX
                             LAB_87c2                                        XREF[1]:     87bd(j)  
            87c2 a7 00           STA        0x0,X
            87c4 08              INX
            87c5 5a              DECB
                             LAB_87c6                                        XREF[1]:     87ba(j)  
            87c6 26 f7           BNE        LAB_87bf
            87c8 39              RTS

That is a routine, but i don't think it's correct, so I must have got something wrong. Or is this just copying the bytes to a buffer that will be written to the pack later?
Lostgallifreyan
Posts: 83
Joined: Thu Jan 12, 2023 8:25 pm

Re: How can PK$save be stopped from adding an extra byte 'FF'?

Post by Lostgallifreyan »

One reply to three posts follows...
amenjet wrote: Wed Jan 31, 2024 7:54 am So the PK$SAVE routine is at $87b9, I think.

Code: Select all

                             LAB_87b9                                        XREF[2]:     87b6(j), d2ff  
            87b9 54              LSRB
            87ba 24 0a           BCC        LAB_87c6
            87bc 5c              INCB
            87bd 20 03           BRA        LAB_87c2
                             LAB_87bf                                        XREF[1]:     87c6(j)  
            87bf a7 00           STA        0x0,X
            87c1 08              INX
                             LAB_87c2                                        XREF[1]:     87bd(j)  
            87c2 a7 00           STA        0x0,X
            87c4 08              INX
            87c5 5a              DECB
                             LAB_87c6                                        XREF[1]:     87ba(j)  
            87c6 26 f7           BNE        LAB_87bf
            87c8 39              RTS

That is a routine, but i don't think it's correct, so I must have got something wrong. Or is this just copying the bytes to a buffer that will be written to the pack later?
Thanks, I never considered that they might pass arguments on the stack! For no particular reason I'd just assumed they populated global variables directly before calling code that wanted them. (Probably because I hoped I might find them there...)

Thanks also for doing the tracing. I'd have no way to figure out where it went to a particular routine without being able to examine stored arguments as it was happening.

Is PC meaning Program Counter? Like what is called Instruction Pointer in an Intel CPU?

That trace you have formatted as "0000:8242 A:0C B:60 X:8242 SP:7FF3" is nice, if that could be combined with the standard ASM listing it would be extremely useful on general principle. There can be too much info in a listing, but not in this case, the register detail is nice. Maybe adding flags too... That would leave very little unknown at any instant, and just scanning for stack pointer changes can make it easy to see how the stack changed, even from a static listing.

The last listing (before my post here) does look like a buffer storage iteration. I don't know what's in X but it might be a pointer to the runtime buffer(rtt_bf, 2188-2287). If it were writing to a pack, I'd expect to see hardcoded addressing for storage to RAM locations below $20, based on seeing a description of the ports for hardware access. I think you found a routine to fill the runtime buffer ready for more specific uses of it.
amenjet
Posts: 200
Joined: Tue Jan 03, 2023 7:54 pm

Re: How can PK$save be stopped from adding an extra byte 'FF'?

Post by amenjet »

Lostgallifreyan wrote: Wed Jan 31, 2024 3:52 pm One reply to three posts follows...
amenjet wrote: Wed Jan 31, 2024 7:54 am So the PK$SAVE routine is at $87b9, I think.

Code: Select all

                             LAB_87b9                                        XREF[2]:     87b6(j), d2ff  
            87b9 54              LSRB
            87ba 24 0a           BCC        LAB_87c6
            87bc 5c              INCB
            87bd 20 03           BRA        LAB_87c2
                             LAB_87bf                                        XREF[1]:     87c6(j)  
            87bf a7 00           STA        0x0,X
            87c1 08              INX
                             LAB_87c2                                        XREF[1]:     87bd(j)  
            87c2 a7 00           STA        0x0,X
            87c4 08              INX
            87c5 5a              DECB
                             LAB_87c6                                        XREF[1]:     87ba(j)  
            87c6 26 f7           BNE        LAB_87bf
            87c8 39              RTS

That is a routine, but i don't think it's correct, so I must have got something wrong. Or is this just copying the bytes to a buffer that will be written to the pack later?
Thanks, I never considered that they might pass arguments on the stack! For no particular reason I'd just assumed they populated global variables directly before calling code that wanted them. (Probably because I hoped I might find them there...)

Thanks also for doing the tracing. I'd have no way to figure out where it went to a particular routine without being able to examine stored arguments as it was happening.

Is PC meaning Program Counter? Like what is called Instruction Pointer in an Intel CPU?

That trace you have formatted as "0000:8242 A:0C B:60 X:8242 SP:7FF3" is nice, if that could be combined with the standard ASM listing it would be extremely useful on general principle. There can be too much info in a listing, but not in this case, the register detail is nice. Maybe adding flags too... That would leave very little unknown at any instant, and just scanning for stack pointer changes can make it easy to see how the stack changed, even from a static listing.

The last listing (before my post here) does look like a buffer storage iteration. I don't know what's in X but it might be a pointer to the runtime buffer(rtt_bf, 2188-2287). If it were writing to a pack, I'd expect to see hardcoded addressing for storage to RAM locations below $20, based on seeing a description of the ports for hardware access. I think you found a routine to fill the runtime buffer ready for more specific uses of it.
The SWI code pushes the registers on the stack and the serice code pops them off again, I think that's why. Yes, PC is program counter and yes, forgot to put the flags on there.

The trace comes directly out of the recreation hardware over USB. The asm listing is too big to put in the Pico, but maybe it could be combined with the trace on the PC. Maybe.
Maybe that routine is working with a concept like the OPL records? They are manipulated then written later, I think. The actual write must be done in some other call.
Lostgallifreyan
Posts: 83
Joined: Thu Jan 12, 2023 8:25 pm

Re: How can PK$save be stopped from adding an extra byte 'FF'?

Post by Lostgallifreyan »

amenjet wrote: Wed Jan 31, 2024 6:21 pm The trace comes directly out of the recreation hardware over USB. The asm listing is too big to put in the Pico, but maybe it could be combined with the trace on the PC. Maybe.
It did look like it might, there were addresses shared, and the gaps in the trace record at one point matched those in the ASM listing, based on instruction lengths. Given enough info between the two outputs, I think I can merge them in TextPad with a macro, then reduce major and obvious loops later by hand.
Maybe that routine is working with a concept like the OPL records? They are manipulated then written later, I think. The actual write must be done in some other call.
I think so too, the services might well match the order of events like EDIT and UPDATE, to do otherwise might be too inefficient once Psion decided on a method.

My aim is to use OPL where it's most efficient, e.g. it's great to OPEN a file by name in OPL, saves a lot of service calls, just doing that: sets pack, sets file, makes sure pack is switched on... Once I have code that can handle the port access to write one byte to a RAM pack at the current address without affecting any other byte, I'm in business. I'd arrange my own buffering, in fact, I'd just point to an OPL string as in the example I prepared near the start of this thread. That way I can optimise it. The hardest thing is always trying to understand complex inbuilt behaviour when we need to circumvent unwanted action. Defining it as new, MUCH easier...

EDIT: Well, it will be easier, once I know how to write that byte to a RAM pack. I never understood the hardware access, because things like timing to avoid trouble with NMI's and such made it difficult. At that level, the data is extremely dynamic, it never sits still, probably because so much hardware stuff is multiplexed constantly. We can imagine four 'packs' on an Organiser at once, but the Organiser can't.
Post Reply