APPMAN is an OPL example program written in 1995 by Jezar that allows the creation of asynchronous menus and dialogs. It was originally written for the Series 3a, and it was assumed to work on the Workabout (and by default, the later 3c, 3mx and Siena machines).
A few months ago I started work on a program that would have to work on the Workabout, but until a couple of weeks ago I had only tested it on the 3a emulator, my real 3a and my real 3mx. (As an aside - I had also noticed that on my 3mx the Shift-Psion hotkeys wouldn't return the correct keycode when pressed in the menus - I fixed this by disabling the force-to-lowercase code in APPMAN - but I didn't like this solution).
When I tried my program on the Workabout emulator I was quite concerned to find that it crashed! Although I quickly traced the problem to the code freeing the memory allocated to the menu cards, I had no idea what was going on, so I made some postings to the comp.sys.psion.programmer newsgroup.
I would like to thank everybody who replied to my questions, both to the group and directly to me via email. I would have been unable to solve this problem without your help.
The problems with APPMAN are due to the DatGate
object being
changed after the Series 3a was released. This moved the locations in memory of
the menu cards and other things that APPMAN was trying to access.
The symptoms on some of the machines are quite subtle and may not have been noticed by users of APPMAN. Please note that these are my experiences only - your mileage may vary!
Machine | Description |
---|---|
Series 3a | None - works perfectly. |
Workabout | System panic when MENUs are closed (Esc/Help pressed or item selected). |
3c, 3mx, Siena | Memory allocated to menu cards is not freed. Shift-Psion hotkeys are returned as Psion hotkeys (no Shift modifier). |
To my knowledge, only the wsMenu%:
procedure has any
problems.
wsMenu%:
Code with CorrectionsThe corrections are highlighted below. Note that I haven't just added the
offset fix to the DatGate address because the changes to the DatGate object are
an extra 18 bytes somewhere between the start of the object and the items
wsMenu%:
is interested in (so the 18 byte offset correction would
come into effect at some point between offset 0 and offset 70 in DatGate).
Also, I've assumed that all Series 3a machines do not need to use a fixed offset. The code below works for my 3a and 3mx machines, and the 3a, Siena, and Workabout emulators. Could anybody who has access to a 1MB or 2MB Series 3a confirm that the fix works on them? If it doesn't, what is the ROM version of your machine?
The fixed APPMAN (renamed to AMFIXED.OPL) can be downloaded here: amfixed.zip.
PROC wsMenu%: REM Launch a menu REM This is the top-level function which REM you use to launch menus asynchronously LOCAL wmenu%,nmenus%,pmenu%,ret%,gate%,gatefix% wmenu%=PEEKW(UADD(PEEKW($12),32)) IF wmenu%=0 RAISE -85 ENDIF ret%=wsDoIt%:(wmenu%) REM The DatGate object changes depending on the machine, so get the REM ROM version and set the offset fix value (which defaults to zero). IF CALL($2a8b)<$3000 OR CALL($2a8b)>=$3560 REM need to adjust offset gatefix%=18 ENDIF REM Free menu cards gate%=PEEKW($38) nmenus%=UADD(gate%,72+gatefix%) WHILE PEEKW(nmenus%) POKEW nmenus%,PEEKW(nmenus%)-1 SEND(PEEKW(UADD(PEEKW(UADD(gate%,74+gatefix%)),2*PEEKW(nmenus%))),0) ENDWH IF PEEKW(UADD(gate%,70+gatefix%))=0 AND ret%>0 ret%=ASC(LOWER$(CHR$(ret%))) ENDIF RETURN ret% ENDP