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

Be clear with the topic titles to help members find the answers
Lostgallifreyan
Posts: 87
Joined: Thu Jan 12, 2023 8:25 pm
Contact:

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

Post by Lostgallifreyan »

amenjet wrote: Sat Jan 27, 2024 2:50 pm Looking at PK$SAVE in Jaap's documentation, it says it leaves the counter pointing to the byte after the last one written. That might be a clue.
Hi, I tried adding machine code to call PK$skip to go forward a byte, then back one byte in a second attempt. I did this immediately after calling PK$save and before the RTS that follows it. The same byte was written as 'FF', no change under any circumstances.

If you can make a disassembly of the PK$save routine, please can I have it? I don't know how a pack is deselected, but even just knowing when it happens might help. I'd hoped it might happen on RTS to OPL, or even only when something later compels it to change to another pack, and that an immediate call to PK$skip after PK$save would not cause such deselection. The documentation seems to imply that it could not, in which case the PK$save service is directly implicated in this, even though the difference in outcome between Jape and a hardware Organiser is caused when using the exact same code.

The deeper I look at this, the weirder it gets. There is clearly some consistent behaviour that has so far resisted all reductionist attempts to get at it.

Jaap has gone silent after some discussion of this, so either he's busy with other stuff, or he's equally perplexed and isn't going to say anything until he's beaten it.
amenjet
Posts: 301
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: Sat Jan 27, 2024 7:22 pm
amenjet wrote: Sat Jan 27, 2024 2:50 pm Looking at PK$SAVE in Jaap's documentation, it says it leaves the counter pointing to the byte after the last one written. That might be a clue.
Hi, I tried adding machine code to call PK$skip to go forward a byte, then back one byte in a second attempt. I did this immediately after calling PK$save and before the RTS that follows it. The same byte was written as 'FF', no change under any circumstances.

If you can make a disassembly of the PK$save routine, please can I have it? I don't know how a pack is deselected, but even just knowing when it happens might help. I'd hoped it might happen on RTS to OPL, or even only when something later compels it to change to another pack, and that an immediate call to PK$skip after PK$save would not cause such deselection. The documentation seems to imply that it could not, in which case the PK$save service is directly implicated in this, even though the difference in outcome between Jape and a hardware Organiser is caused when using the exact same code.

The deeper I look at this, the weirder it gets. There is clearly some consistent behaviour that has so far resisted all reductionist attempts to get at it.

Jaap has gone silent after some discussion of this, so either he's busy with other stuff, or he's equally perplexed and isn't going to say anything until he's beaten it.
Have you tried a PK$PKOF after the PK$SAVE? That turns off the slots and should stop any access once issued.

Andrew
Lostgallifreyan
Posts: 87
Joined: Thu Jan 12, 2023 8:25 pm
Contact:

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

Post by Lostgallifreyan »

amenjet wrote: Sun Jan 28, 2024 5:16 am Have you tried a PK$PKOF after the PK$SAVE? That turns off the slots and should stop any access once issued.
It makes no difference. I also tried stacking B and X after preparing them for PK$sadd, so I could recall them for a second use of PK$sadd immediately after PK$save, to 'rewind' to the first written byte, in case PK$skip wasn't doing enough. Nothing has ever prevented PK$save forcing that extra 'FF' in hardware tests. If it had, it still may not have explained why Jape and hardware act differently with the same ROM code.

Do you know the exact ROM addresses for these routines? My OPL script will make a good disassembly listing if I know where to do it. I can't use it on the entire ROM because bytes that cannot be interpreted as valid code will break it.
amenjet
Posts: 301
Joined: Tue Jan 03, 2023 7:54 pm

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

Post by amenjet »

It might be something to do with the SOE line, as I think that is used as a WR, if I remember correctly. If you take that high while the CE is still valid then you will write to the device. You need to take CE (SS on the connector) high then write high. Maybe it's something like that.

I'll have a hunt for a ROM disassembly. I did use Ghidra to disassemble a ROM I think, but I don't know the ROM addresses.
amenjet
Posts: 301
Joined: Tue Jan 03, 2023 7:54 pm

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

Post by amenjet »

This file is a quick disassembly of a ROM.
I can disassemble areas if need be..
You do not have the required permissions to view the files attached to this post.
Lostgallifreyan
Posts: 87
Joined: Thu Jan 12, 2023 8:25 pm
Contact:

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

Post by Lostgallifreyan »

amenjet wrote: Sun Jan 28, 2024 3:29 pm This file is a quick disassembly of a ROM.
I can disassemble areas if need be..
Thanks, that's useful already. Just before Jaap went silent, he mentioned an address D955 as program entry point, when I asked where it was. I didn't think of the ROM starting at address 8000, I'd been assuming that addresses would be based on the offsets in a 32K binary file! Your post clears that up, he must have meant that the RAM occupies 0000~7FFF, then ROM hardware addresses were what he meant when citing D955 (for that same 33-la.rom, fortunately, which reduces risk of error).

About the RW, CS, SOE detail, that is beyond my knowledge, but it does seem that there is an answer to my literal question: "No, it is impossible". While there may be things that can be done to the hardware which would prevent the extra 'FF' byte, it seems that it is proven that ONLY hardware changes can do it, therefore it's impossible. Whatever solution is applied, it MUST work on all Organisers, and we can never modify them all.

I hate ugly solutions, but there IS only one solution: allow an extra byte inside the single field in every record in the relevant file, so the 'FF' will always be written, but harmlessly, after the real data. In turn, this means that for efficient reading, a machine code routine must be used to capture those bytes because OPL would be inefficient, having to get length, use LEFT$(), etc..

Even though the solution is going to be ugly, it may still be very efficient for speed, even though it wastes some space. Given the size of RAM packs that make the method most useful, that space loss may not matter much either.

It is still possible that knowing what the routine does in deepest detail might give a way to write a new routine that works equally well in Jape and in hardware, to write arbitrary bytes with no effect on any not indicated for action, but at this point I have no idea about that. It may be diminishing returns even if there is, though a minimal form that writes one byte the way PK$rbyt can read it, might be a way to augment PK$save in a len-1+1 write, where the +1 is written directly after the main data. This would be less ugly than it looks because the pack address would already be correct for that final byte of real data.
amenjet
Posts: 301
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: Sun Jan 28, 2024 4:00 pm
amenjet wrote: Sun Jan 28, 2024 3:29 pm This file is a quick disassembly of a ROM.
I can disassemble areas if need be..
Thanks, that's useful already. Just before Jaap went silent, he mentioned an address D955 as program entry point, when I asked where it was. I didn't think of the ROM starting at address 8000, I'd been assuming that addresses would be based on the offsets in a 32K binary file! Your post clears that up, he must have meant that the RAM occupies 0000~7FFF, then ROM hardware addresses were what he meant when citing D955 (for that same 33-la.rom, fortunately, which reduces risk of error).

That address (D955) doesn't seem to be an instruction.
I've attached a more complete disassembly from Ghidra, I modified Ghidra so it understands the OS calls.

Andrew
You do not have the required permissions to view the files attached to this post.
Lostgallifreyan
Posts: 87
Joined: Thu Jan 12, 2023 8:25 pm
Contact:

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

Post by Lostgallifreyan »

amenjet wrote: Mon Jan 29, 2024 7:53 am
That address (D955) doesn't seem to be an instruction.
I noticed that too, it's maybe an off-by-one error and should have pointed to one byte earlier ('00' is the first data byte for a three-byte instruction.) Jaap said he was using 33-LA.rom at the time, but it's possible he'd tried a few and that offset belongs to another one.
I've attached a more complete disassembly from Ghidra, I modified Ghidra so it understands the OS calls.

Andrew
Thankyou. I've seen a lot in there I don't understand though.. How would I interpret that to locate the start of a named service routine? Knowing where it's called is one thing, knowing exactly where the called code is, is quite another. :)
amenjet
Posts: 301
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 2:06 pm
amenjet wrote: Mon Jan 29, 2024 7:53 am
That address (D955) doesn't seem to be an instruction.
I noticed that too, it's maybe an off-by-one error and should have pointed to one byte earlier ('00' is the first data byte for a three-byte instruction.) Jaap said he was using 33-LA.rom at the time, but it's possible he'd tried a few and that offset belongs to another one.
I've attached a more complete disassembly from Ghidra, I modified Ghidra so it understands the OS calls.

Andrew
Thankyou. I've seen a lot in there I don't understand though.. How would I interpret that to locate the start of a named service routine? Knowing where it's called is one thing, knowing exactly where the called code is, is quite another. :)
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.
I wonder if these disassembly files could go on a wiki or something so several people could work on bits at once?
Lostgallifreyan
Posts: 87
Joined: Thu Jan 12, 2023 8:25 pm
Contact:

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

Post by Lostgallifreyan »

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!)
Post Reply