mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-06 14:11:48 -06:00
- Fixes to ZPMLDR to make it functional with RomWBW. - Incorporate fixes from the Jon Saxton disassembly in ZPM3 itself. - Credit to Lars Nelson for finding the ZPM3 source (disassembly).
187 lines
7.1 KiB
Plaintext
187 lines
7.1 KiB
Plaintext
PATCHES TO SIMEON CRAN'S ZPM3
|
||
=============================
|
||
|
||
ZPM3 is a CP/M 3 workalike written by Simeon Cran. It is readily available in
|
||
binary form; just look for archives like zpm3n10.arc and similar.
|
||
|
||
This patch contains updated BNKBDOS3.SPR and RESBDOS3.SPR files although it
|
||
is only the banked portion which has been modified.
|
||
|
||
Three changes have been implemented.
|
||
|
||
1. BDOS function 152 (Parse file name) password bug
|
||
===================================================
|
||
|
||
The first change was to fix a bug identified by Tilmann Reh in the file name
|
||
parser invoked by BDOS function 152. Unlike the parser in standard CP/M 3,
|
||
Simeon's version can deal with a user number. The FCB which is filled in by
|
||
the parser has the following structure where the field names are those shown
|
||
in the CP/M 3 Programmer's Reference Manual:
|
||
|
||
|
||
Offset Field Length
|
||
------ ----- ------
|
||
0 DR 1 Drive code (0 = current, 1 = A, ... 16 = P
|
||
1 NAME 8 File name
|
||
9 TYPE 3 File type (extension)
|
||
12 PM 1 Password mode
|
||
13 S1 1 Reserved
|
||
14 S2 1 Reserved
|
||
15 RC 1 Reserved (Result code)
|
||
16 PASSWORD 8 Password (encrypted)
|
||
24 RESERVED 8 Used by CP/M 3
|
||
|
||
Now the RC field gets set to FFh if an error occurs during the parse but S1
|
||
and S2 are not used at all by CP/M 3. Simeon's parser uses those fields to
|
||
store the user number (S1) and a copy of the DR field (S2) thus rendering the
|
||
parser far more useful in that it can now handle names like
|
||
|
||
K12:TESSER.CAT
|
||
|
||
and deliver a sensible result to a user program.
|
||
|
||
None of this is useful to other CP/M 3 implementations and so most programs do
|
||
their own parsing but the basic idea is commendable. However Tilmann noticed
|
||
that if a password is attached to a file then Simeon's parser puts it in the
|
||
wrong place, overwriting the four fields PM through RC.
|
||
|
||
It is probably not a critical issue; after all, how many CP/M 3 users bother
|
||
to password-protect files? Nevertheless it is clearly wrong and is fixed in
|
||
this version of BNKBDOS3.SPR.
|
||
|
||
2. BDOS function 152 (Parse file name) user/drive prefix
|
||
========================================================
|
||
|
||
A limitation of Simeon's parser is that it cannot handle the UD: (user, drive)
|
||
prefix, only the DU: form. That was annoying to me since I am just as likely
|
||
to type 7g:tesser.cat as g7:tesser.cat. My second patch was to fix ZPM3 to
|
||
handle both the UD: and DU: prefix forms.
|
||
|
||
I also put the drive number in the S2 field even when no drive was specified
|
||
in the input string. Assuming that the current drive is E and the current
|
||
user number is 8 then the following results are obtained with the inputs
|
||
shown:
|
||
|
||
Input string DR S1 S2
|
||
------------ -- -- --
|
||
FILE.EXT 0 8 5
|
||
E:FILE.EXT 5 8 5
|
||
12:FILE.EXT 0 12 5
|
||
G:FILE.EXT 7 8 7
|
||
G12:FILE.EXT 7 12 7
|
||
12G:FILE.EXT 7 12 7
|
||
|
||
The interesting cases shown above are the first and third. Setting DR to zero
|
||
is consistent with the way standard CP/M works and the setting of S2 is just
|
||
extra information which may be of use to the calling program but which can
|
||
be ignored. Unfortunately it is not possible to do the same thing with the
|
||
user number because standard CP/M does not have a field for that.
|
||
|
||
3. BDOS function 152 (Parse file name) Clear target FCB
|
||
=======================================================
|
||
|
||
On 2013-09-05 a contributor to comp.os.cpm known only as "Ed" pointed out that
|
||
there is yet another bug in BDOS 152 in that it does not clear the record
|
||
number fields in the last four bytes of the FCB populated by the function.
|
||
A program which uses the FCB for a read or write operation without first
|
||
explicitly setting the fields will have the I/O operation start at some
|
||
unexpected position in the file.
|
||
|
||
This problem has also been fixed.
|
||
|
||
4. Command line editing keys
|
||
============================
|
||
|
||
A couple of years ago I added code to yaze-ag (a Z80 emulator) to make it
|
||
possible to use the cursor and function keys on a modern PC keyboard to do
|
||
sensible things in CP/M. The keyboard translations are specified in external
|
||
text files and can be loaded dynamically from within CP/M.
|
||
|
||
By far the most useful translate table maps the arrow keys to WordStar
|
||
controls. For example, pressing the up arrow key generates a ^E, pressing
|
||
PgUp generates ^R and so on. This works really well in most cases but there
|
||
is one piece of software which gives problems, namely CP/M itself.
|
||
|
||
Yaze-ag uses Simeon Cran's ZPM3 as a replacement for the CP/M 3 BDOS. It was
|
||
a good choice because ZPM3 offers more features than standard CP/M 3 and in
|
||
particular, it provides a rich command history facility with decent recall and
|
||
edit capabilities.
|
||
|
||
As originally implemented, ZPM3 viewed the history as an upward-growing
|
||
stack, i.e. with new lines being added at the top. For example assume
|
||
that lines comprising the single words "one", "two", "three", "four" and
|
||
"five" are entered in sequence. The history looks like this:
|
||
|
||
-> (current line, blank)
|
||
five (newest)
|
||
four
|
||
three
|
||
two
|
||
one (oldest)
|
||
|
||
According to this view, the NEXT line in the history is the last one
|
||
entered. After ^W ^W ^W ^W (NEXT, NEXT, NEXT, NEXT) the view is like this:
|
||
|
||
two (line ready for editing)
|
||
five (newest)
|
||
four
|
||
three
|
||
-> two
|
||
one (oldest)
|
||
|
||
After ^E ^E (PREVIOUS, PREVIOUS) the view is:
|
||
|
||
four (line ready for editing)
|
||
five (newest)
|
||
-> four
|
||
three
|
||
two
|
||
one (oldest)
|
||
|
||
This is all very consistent. The problem is that it is utterly counter-
|
||
intuitive and the complete reverse of any recall and edit scheme in any
|
||
other operating system. For example, linux and Windows both view shell
|
||
command history as a stack, but one which grows downwards. The most
|
||
recently entered command is the one conceptually ABOVE the current line.
|
||
This view of the command history also corresponds to the way that we
|
||
compose text, where new lines are added below the most recently added
|
||
lines.
|
||
|
||
Using the same five-line example as above, the initial view would be:
|
||
|
||
one (oldest)
|
||
two
|
||
three
|
||
four
|
||
five (newest)
|
||
-> (current line, blank)
|
||
|
||
After UP, UP, UP, UP the view is:
|
||
|
||
one (oldest)
|
||
-> two
|
||
three
|
||
four
|
||
five (newest)
|
||
two (line ready for editing)
|
||
|
||
then DOWN, DOWN yields:
|
||
|
||
one (oldest)
|
||
two
|
||
three
|
||
-> four
|
||
five (newest)
|
||
four (line ready for editing)
|
||
|
||
Tilman Reh recognised this as a bug when he disassembled this ZPM3.
|
||
It was fixed by cross-renaming the two routines NextLine and PreviousLine
|
||
and for WordStar compatability the NextLine routine was moved to ^W.
|
||
That meant the previous occupant of the ^W position, DeleteToLeft had to
|
||
be moved also. For no particularly good reason I chose to use the just-
|
||
vacated ^X slot.
|
||
|
||
Although I cannot imagine why one would want to do so, the original ZPM3
|
||
behaviour can be recovered by setting the assembly-time switch "HistoryBug"
|
||
to some odd number, e.g. 0FFFFh.
|
||
|