heyrick1973 -at- yahoo -dot- co -dot uk

Tea in 90 seconds

It's so much simpler to use the Tassimo to make a cuppa, than to boil a kettle...


Zap rick-03 rick-04!

This gets really geeky - if you just want Zap, scroll to the bottom.

Well, since I have a buildable version of Zap set up, it was time to make two modifications that had bugged me for a long time.

  • The Code mode had a load of irrelevant options (for DebuggerPlus on 26 bit systems) and couldn't interact with the RISC OS Debugger's options.
  • Quick Print output to the Printer: device, which was usually set to Null: (and may or may not be 'owned' by !Printers when it is in use?).


The first job was to merge in previous bug fixes. That is to say, reapply the fixes to the ZapMJE module, then do the same for ZapObey.
While I was there, I applied two fixes by Jan de Boer - one to remove the SWP instruction from Zap (so it'll work on the Pi3 and other ARMv8 machines), and the other to cure a nasty bug in ZapRedraw where clicking a bitmap font size (such as "06x20") would stiff the machine.


Tweaking Quick print was easy. It simply redirects the print stream to Zap.Printout within !Scrap. That said, I wonder if this is the best approach. Maybe I should only do this if the current Printer: device is Null:? Or maybe anything less than 5 (Null, Parallel, Serial, User, Econet) on a modern machine? What do you think?


Code mode required a bit more work. And since DebuggerPlus never made it to 32 bit, I have simply yanked out all of the DebuggerPlus options and inserted two options for the default Debugger. This is a breaking change - namely that anything indended to happen with Debugger will not work correctly with DebuggerPlus. This doesn't bother me, as there is a perfectly functional version of Zap for the 26 bit systems. My concentration is on getting Zap working as best possible on 32 bit systems.

To that end, there are four combinations of register set - namely ARM or APCS with or without alternate naming, as shown here, with the parts in bold highlighting what may differ:
ARM       R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 PC
ARM alt.  R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 SP  LR  PC
APCS      a1 a2 a3 a4 v1 v2 v3 v4 v5 sb sl  fp  ip  sp  lr  pc
APCS alt. a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7  v8  ip  sp  lr  pc

Here is a disassembly as it normally looks:

And here it is using APCS naming:


I was pleased with this work. I set out to dump the updated stuff into an archive, and released that it was a lot of fiddling around to install it all. So I created an Obey file to perform the task automatically.


And that was supposed to be that. Only it never is, is it? ☺

The dust had barely settled when a bug report of the HidePointer module under RISC OS 5.25 rolled in. The OS' paranoid error checking was hitting the calls to OS_Byte saying that it was returning a duff error pointer. Now personally I think this is a fault in RISC OS (as any error messages coming back from OS_Byte really ought to have a valid error block), however this doesn't help when it makes stuff crash. And it also isn't helped by HidePointer being, as nemo tactfully put it "a bit odd in places, and archaic". The simplest "fix", since all it does is hide the pointer while one is typing (hardly a big crisis-making issue) is to simply disable the module so it doesn't get loaded. My update script pushes it out of the way by changing the filename.


Roll on to day two. Something I used to like about !Edit was the Tab mode which would simply move to align the cursor with whatever was on the previous line, like this:

This is some text.
     |  |    |
Pressing Tab would move the cursor as indicated by the vertical bars.

Zap can do this too, or at least, it should. Instead, Zap blows up.

Now let me take a moment here to say that the crash reports are a stack dump created by Debugger, so it looks like this:

0000871c : 2042872c : - 2042886c return to 2042872c?
         :          : | 2042886c = Zap +c778
         :          : | = do_command +0
         :          : | 2042872c = Zap +c638
         :          : | = command_primative +1c
Then I need to load Zap's executable into memory and find what's at Zap plus offset. Then this needs to be correlated with the source.

We're not done yet. The next job is to insert the command SWI 256+7 ; ##RICK## and rebuild. The SWI is a VDU7, or "make a beep". The "##RICK##" is so I can find it again easily.
Then I quit Zap, reload the rebuilt version, and see what happens first - the beep or the crash.
Then, keep moving the location of the beep instruction until the crash happens first. Don't fool yourself. This can lead to literally dozens of rebuilds and reloads. And maybe a couple of machine restarts if I start the Zap module without first quitting the previous incarnation... It's slow. And tedious. Did I mention tedious and slow?
At that end, I should have narrowed it down to a place where the instruction before beeps first and the one after crashes first. Then I'll know what's upsetting things and can look to see why.

I can't use DDT because Zap is an application in a module, and DDT is too braindead to cope with modules. So, it's the painful slow tedious way of debugging...

Let's face it - it's ironically comical that in 2018 I'm using basically the exact same method of debugging (a moving VDU7) that I used on the BBC Micro a third of a century ago!

Thankfully, the problem with Tab wasn't too onerous. Instead of locating the failing instruction, I went to the Command source and just worked my way through how the TAB command operates. After a bit of tracing, I worked out that most modes that have a text-like data entry (not Byte/Word/Disassembly) eventually revert back to "mode0" (the text mode) for handling of Tabs. This is useful as the same behaviour applies everywhere without the wheel being reinvented each time. It's also useful as there's only one thing to fix.

;E R0=phy line start R1=cur off R2=cur col R8-R10
;X R1,R2=new posn / R2<0 for specials #
        FNAME   mode0_splus
        _PUSH   "R2"
        LDR     R14,[R9,#f_ptr]          ; >>tim, protect against deleted file
        CMP     R14,#-1
        MOVEQ   R0,#0
        MOVEQ   R1,#0
        MOVEQ   R2,#0
        FNRTS   EQ
        LDR     R2,[R8,#w_format]       ; w_format
        TST     R2,#1 << 25
        _PULL   "R2"

And... The problem is right there staring us in the face. That added check to protect against a deleted file is trying not to interfere with anything by using R14 as a temporary register. However R14 has not been stacked! So the test sets R14 to some sort of value (which may be &FFFFFFFF). The function executes as is usual. Then the processor jumps to whatever was stored in R14 (which ought to be the return address, but isn't).

I stacked/unstacked R14 around the check, but the thing kept failing as the check kept reporting true. Weird. So I simply commented out that code (everything between the _PUSH and the second LDR) and now Edit-style "as above" tabbing works perfectly.


Zap is not perfect, nor is it bug free. Maybe not yet good enough for Steve Pampling ☺, but every bug less is a step further forward.



If you use Zap, and you find a repeatable crash situation, execute these commands in a TaskWindow:

Set Debugger$DumpOptions -file annotated
Set Debugger$AnnotatedFile $.ZapCrash

Then make Zap crash, and send me what the ZapCrash file says, along with a description of what to do to trigger the crash.

You can also send the crash dump, if you made one, for one-off crashes...however the chance of success for something I can't repeat is... very much smaller.


Finally, now you've read all of this rubbish, please enjoy the rick-04 release of Zap.

If you're interested, there is also the source code.



Your comments:

Please note that while I check this page every so often, I am not able to control what users write; therefore I disclaim all liability for unpleasant and/or infringing and/or defamatory material. Undesired content will be removed as soon as it is noticed. By leaving a comment, you agree not to post material that is illegal or in bad taste, and you should be aware that the time and your IP address are both recorded, should it be necessary to find out who you are. Oh, and don't bother trying to inline HTML. I'm not that stupid! ☺
You can now follow comment additions with the comment RSS feed. This is distinct from the b.log RSS feed, so you can subscribe to one or both as you wish.

David Pilling, 1st May 2018, 22:57
VDU7 debugging is good, I used to do that. Tab mode will be handy for Python programmers. I try to use print these days for debugging, but sometimes twiddle io lines and watch using 'scope. Which raises thought can you use ARM hardware debuggers JTAG for Pi - You Tube says yes.
Timo Hartong, 13th May 2018, 21:32
Thank you for this working version of Zap for the rasberri pi

Add a comment (v0.09) [help?] . . . try the comment feed!
Your name
Your email (optional)
Validation Are you real? Please type 06070 backwards.
Your comment
«   May 2018   

Japan - can you help?
Japanese Red Cross
日本 赤十字社

Earthquake relief donations have closed.

Read about the JRC
Make a general donation

Last 5 entries

List all b.log entries

Return to the site index


Search Rick's b.log!

PS: Don't try to be clever.
It's a simple substring match.


Thank you:
  • Fred
  • Bernard
  • Michael
  • David

Last read at 12:54 on 2018/05/21.

QR code

Valid HTML 4.01 Transitional
Valid CSS
Valid RSS 2.0


© 2018 Rick Murray
This web page is licenced for your personal, private, non-commercial use only. No automated processing by advertising systems is permitted.
RIPA notice: No consent is given for interception of page transmission.


Have you noticed the watermarks on pictures?
Next entry - 2018/05/07
Return to top of page