* for Emacs: -*- mode:indented-text; mode:outline-minor -*-

            ZCN v1.2 - (c) 1994-1999 Russell Marks

       A free CP/M-like operating system for the Amstrad NC100.


* License

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

[The GNU GPL is in the file `COPYING'.]


* About ZCN

ZCN is an alternative operating system for the NC100. Features
include:

- a high level of CP/M compatibility
- fast switching between ZCN and the ROM software, and file transfer
  between the two
- can run BBC Basic (from ROM) as if it were a native ZCN program
- command processor (shell) with many internal commands
- many external commands and third-party programs
- optional online help (using `man')
- 46k free for programs to run in
- terminal emulator with 120x10 text resolution
- keyboard handler with 128-char keyboard buffer
- context saving while power is off
- support for the serial port at speeds up to 19200 baud
- printer (i.e. parallel port) support
- auto power-off after a given idle time
- warnings when main, backup, or memory card batteries are low
- console redirection to serial port or printer
- washes whiter than other powders

ZCN is modelled quite closely on the CP/M operating system common on
8080 and Z80 machines in the late 70s and early 80s. (It is most
common in the UK today on Amstrad PCWs.) I decided to do this as there
is a great deal of public domain and other zero cost software for
CP/M, including text editors, simple C compilers, Z80 assemblers, a
few games, etc. CP/M is also, in my opinion, well suited to running on
small Z80 systems. ZCN's CP/M compatibility is sufficient to run most
CP/M 2.2 programs.


** Should I use ZCN?

You should probably consider using ZCN if you like the idea of a
portable CP/M box, or want to use the NC100 as something a bit closer
to a `real computer'. These are the two reasons I originally started
writing ZCN.


** Warning!

If you want to still be able to use the built-in ROM software without
losing any of your current data, you *MUST* transfer and run the
`rrinit' program before trying to run ZCN. If you don't, you'll lose
any data held in the 64k of internal memory! (This means losing not
only any files in both the upper and lower memory, but also any
configuration.)

If you don't care about the ROM software, or don't care about losing
currently-held data, you shouldn't bother with `rrinit'.

(There's more on `rrinit' at the appropriate point below.)


** Requirements

ZCN needs the following to install and run successfully:

- An Amstrad NC100 Notepad

- At least one PCMCIA memory card, which will need to be reformatted
  in ZCN's format

- A computer with a serial link to the NC100, and the
  capability to send files using the XMODEM protocol

If you want to save the data currently in the internal memory, the
memory card must be at least 128k (64k of it will be used to save the
memory).

You will also need a basic knowledge of using CP/M, though a
reasonably capable MS-DOS and/or Unix user should be able to get along
ok. (Hey, it worked for me... :-))


* Installing ZCN

The installation guide below assumes you are installing from a Unix or
MS-DOS machine. It should be clear what to do on other machines
though; you just need to know how to XMODEM a file across, and how to
send a plain ASCII file. Normally the easiest way is to use a serial
comms program of some sort.

** Getting ZCN up and running for the first time

*** Saving your existing data

[If you don't care about using the ROM software, or don't mind losing
all the data in the internal memory, skip ahead to the next section,
`Booting ZCN via a Serial Link'.]

ZCN uses the NC100's 64k of RAM as more normal computers generally use
RAM - as an area to load programs into, and an area to use for
temporary workspace, etc. Unfortunately, this is not compatible with
the way the built-in software works, so you'll lose all your existing
data in memory unless you save it first. `rrinit' is a program which
lets you save your data like this. (You'll be able to restore it later
using `runrom'. More on that later on.)

To run `rrinit', you'll need a memory card of at least 128k in size.
It should probably be the card you intend to copy ZCN onto, but it
doesn't have to be. Bear in mind that the card will be reformatted in
ZCN's format, and any data currently on it will be lost!

You must also have at least one file stored in memory on your NC100,
as the ROM software doesn't let you do serial file transfers
otherwise. (If you haven't got any files in memory, just create a
small file with the word processor. It doesn't matter what's in it or
what it's called, just that it's there.)

First you need to setup the serial link. You should set the baud rate
to 2400 baud on the `remote' computer, as transfers seem to be a bit
hairy (for the ROM software at least) at higher speeds.

After that, *make sure there isn't any memory card in the NC100's
slot*, then do the following:

Key                     Reason
---                     ------

Function + S                  go to terminal program
Menu, down*3, left*2, Stop    use 2400 baud
                        (you may need more or less lefts,
                        depending on the current setting)
<type a few characters on the NC100 and `remote' computer to check
 the link is working ok>
<start XMODEM send (or `upload') of `rrinit.bin' on `remote' computer>
Stop                    quit terminal program
Function + L                  load document
Menu, T, M, rrinit, return    XMODEM receive `rrinit'
<wait for transfer to finish>
Stop                    return to file selector
<now insert the memory card>
Menu, F, <possibly Y>, Stop   format card (answer `Y' if it prompts you)
<make sure the `rrinit' file is the currently-highlighted one>
Menu, T, P, Stop        write rrinit to memory card
Stop                    exit file selector
Function + X                  run rrinit

[NB: `rrinit.bin' is in the `bin' subdirectory.]

Almost immediately after you do the function-X, rrinit should say
"Snapshot written - press Stop". Pressing Stop then returns you to the
NC100's main menu.

Now you should be ready to run ZCN, so here goes...


*** Booting ZCN via a Serial Link

[If you are upgrading an existing version of ZCN, skip ahead to
`Installing a new version using an old one', which will be rather more
appropriate.]

First you need to setup the serial link. You should set the baud rate
to 2400 baud on the `remote' computer, as transfers seem to be a bit
hairy at higher speeds. (ZCN itself can cope with file transfers at up
to 19200, but the ROM software seems to be more picky. So for this
transfer, it's best to stick with 2400.)

Now you should cold-boot the NC100. Do this by turning it off and,
while holding down Function, Stop and `<-Del', turning it back on.

Next you should do the following:

Key                     Reason
---                     ------
Function + S                  go to terminal program
Menu, down*3, left*2, Stop    set speed to 2400 baud
<type a few characters on the NC100 and `remote' computer to check
 the link is working ok>
<start XMODEM send (or `upload') of `zcn.bin' on `remote' computer>
Stop                    quit terminal program
Function + N, x, return       create junk document
x                       put junk in it
Function + L                  load document
Menu, T, M, tmp, return       XMODEM receive `tmp'
<wait for transfer to finish>
Function + B                  enter basic
"*LOAD TMP 6000"        load system (omit the quotes :-))
"CALL &6000"                  start ZCN   (ditto)

[NB: `zcn.bin' is in the `bin' subdirectory.]

(It was necessary to create the junk file above so that Function-L
would work; there's no way to get the menu which lets you XMODEM
receive a file without any files in memory. Yuck.)

(Also, note that you will need a reasonably complete serial lead for
the ROM software's XMODEM transfer to work (this doesn't apply to ZCN
itself, which needs only the minimal out/in/gnd connection (plus CTS
if serial output is to work, though that can just be soldered to
RTS)). Any lead you *buy* should be fine, but if you've knocked up
your own only-three-pins-connected job you'll need to borrow a better
lead from someone for this transfer. :-) However, for an alternative
approach, see `badlead.txt'.)


You should then end up with a screen looking something like:

      ZCN v1.2 (1999-03-03 16:20) ROM v1.06

      A>
      A>

(The version numbers and date/time of assembly may vary - don't worry,
that's because I don't often update the above `screenshot'. :-))

The `A>' is the ZCN command processor's prompt. It'll probably be
there twice because you pressed enter at the end of "CALL &6000" and
it was still pressed the first time ZCN prompted for a command line,
so it just prompted again. (ZCN didn't know that it was pressed before
- it wasn't running then.)

If you ran `rrinit' before booting ZCN, skip the next paragraph. Let
me put that another way - IF YOU RAN `rrinit', DO *NOT* DO `format a:'
OR YOU WILL LOSE THE DATA IT SAVED. (`format b:' etc. is fine,
though.)

Those of you who didn't run `rrinit' should now make sure you have
your PCMCIA card in the card slot, and type `format a:'. If it prompts
you asking if you want to reformat it, press `y'. You should see the
message `Formatting complete' almost immediately (formatting memory
cards is a very simple operation).

If the card you're using is 512k or 1024k, type `format b:', which
formats the 2nd logical drive (the 2nd 256k of the card).

If the card is 1024k, follow this by typing `format c:' and finally
`format d:'.

If the card is larger than 1024k, you've got more money than sense, as
the NC100 can't access the rest. :-)

Now you can make a bootable ZCN drive on your card. Do this by typing
`sys a:'.

Since this is the first time you've added the system to this card,
you'll get lots of `addblk..' messages. This means that ZCN is moving
the whole logical drive up 1k (one block). This is necessary to ensure
that you can add a new version of ZCN to a card without having to
reformat it. If you ever want to add a new version of ZCN to the card,
you can just boot it via the serial link as you did here and then do
`sys a:' again. In fact, you can also do it without ever leaving ZCN -
see the section `Installing a new version using an old one' below.

When the message `copying...done.' appears, the card is bootable.

You may have noticed, while the system was being copied, there was a
rather curious small black bar at the bottom-left of the screen. This
is the `drive light' for logical drive A:. Whenever this bar appears,
part of the card's memory is paged in that belongs to that logical
drive, i.e. the `disk' is being accessed. The `drive light' for
logical drive B: is to the right of that, C:'s is to the right of
that, as is D:'s. It won't usually be `on' as much in general as it
was for the `sys a:' command; don't worry about this, it's perfectly
normal.

You should now check that the system is bootable. This gives you an
opportunity to learn the booting procedure. As the NC100 remembers
what you were doing when you turn it off, you should only ever need to
reboot the system from scratch like this to: 1. check bootable cards,
2. reboot after a crash, or 3. reboot after changing the lithium
backup battery. (When you change normal batteries, there's no need to
reboot - the backup battery takes over until the new batteries are
in.)


*** Rebooting to test a bootable card, or after a crash

Going from when the NC100 is still on, you should:

1. Press the on/off switch to turn the computer off. If it didn't turn
off, remove the main batteries (not the lithium one) and disconnect
from the mains adaptor, and then reinstall/reconnect. (The on/off
switch will work fine usually, but sometimes when the NC100 crashes it
stops working because of memory corruption.)

2. Hold down the Function, Stop and `<-Del' keys and press the on/off
switch. This restarts the machine from scratch.

Assuming you're now at the `enter time' screen or the main menu, it
doesn't matter which:

3. Make sure your bootable ZCN card is in the slot, and press
`Function' and `X'. This should boot ZCN and leave you at the `A>'
prompt.

An alternative method (for testing a bootable card) is to use the
`cboot' command.


**** Ye Olde Boot Method

Just for hysterical raisins, I've left in the instructions detailing
how you *used* to have to reboot. Not much fun. :-)

Skip this unless you're interested.

Steps 1 and 2 were as above, and then...

3. Press `Function' and `B'.

4. Make sure you have a bootable ZCN card in the card slot.

5. Type in any one of the following lines, whichever is most
convenient. (Type only one of them, and type them exactly as shown.)

P%=102:[:LD A,128:OUT (16),A:]
!102=&10D3803E
!102=282296382

6. Press the on/off switch.

ZCN should now boot from logical drive A: on the card. If it doesn't,
PANIC. :-)

(You'll probably have to transfer ZCN via serial link again to get it
to boot, if it really won't boot off the card.)

As to the choice of which lines to type in in step 5... The latter two
aren't too bad to write down if your memory isn't really up to
remembering any of them. The first one is probably fairly memorable if
you've done much Z80 programming.

That said, I've managed to memorise the last one, so it might be worth
trying that if you can.


Now, aren't you glad you don't have to do that any more? :-)


*** Getting the first program across

So you've got your shiny new operating system across, and it's there,
and... it's not doing very much really, is it? To fix that, you'll
need to get some interesting programs across to your ZCN system. But
in order to do that, you first need to get a reasonable comms program
across which will make serial transfer easier.

This implies that getting the first program across is hard. :-)

Well, it's harder, at any rate. ZCN has a simple `internal command' (a
program already in memory, which doesn't need to be loaded off the
card) called `rexec' which reads a uuencoded file from the serial port
and writes it to the memory card under the filename given. Now, a
uuencoded file is a binary file, such as a program, converted to
`normal' readable ASCII characters by a program called, reasonably
enough, `uuencode'. :-)

On a Unix machine, `uuencode' will usually be part of the system - it
was originally written to help with transferring binary files across
7-bit links between Unix machines. For example, from my Linux box I
could do:

uuencode wibble.com wibble.com >/dev/ttyS1

...to send the program `wibble.com' to my NC100, which is connected to
my second serial port.

One of the best `first programs' in my experience is QTERM. A version
patched for use under ZCN is in the `support' directory. There is also
a copy of this already uuencoded, called `qterm.uue'.

What you should do to send the program is to first type `rexec
qterm.com' on the NC100, then start the uuencode (if Unix) or `ASCII
upload' the `qterm.uue' file (if MS-DOS). (It's easiest to again do
this transfer at 2400 baud on your `remote' computer, as ZCN defaults
to 2400 baud - but that's a bit slow, and you can use `stty' to change
speed if you want, e.g. `stty 19200' sets the speed to 19200 baud.)

If it works, you should get a dot printed as each line is processed,
then a short delay at the end while the file is written.

(If it doesn't work, try pressing both ctrl and C (i.e. ^C) to abort
the `rexec' and start again.)

(If you're using MS-DOS and your comms program doesn't have any `ASCII
upload' facility: 1. do something like `copy qterm.uue com2:' from the
DOS prompt, and 2. get a new comms program.)

Once you get QTERM across, you can run it by giving the command
`qterm'. You'll need to read the QTERM documentation in
`support/qterm' to learn about all its features, but here's the bare
minimum for transferring things to/from the NC100:

You can type Control+\ followed by Q to quit QTERM. More usefully, you
can type Control+\ then R to receive a file (this is what you'll want
first off) and type something like `x wibble.com' in answer to the
prompt `Mode?'. Control+\ then S sends a file and works the same way.

(If you used `rrinit' to save your data, now would be a good time to
make a backup copy of the `runrom.ram' file it created, by sending it
to your main machine using QTERM.)

You can find many free CP/M programs on the oak.oakland.edu ftp site
under /pub/cpm. That's where I got QTERM from, for example. Note that
some of the programs there, particularly those that use the BIOS disk
routines, may not work under ZCN. Since many of the programs there are
stored in .LBR format, you'll probably want to use the `lar' program
in the `support' directory. Look at the README there for more info.


** Installing a new version using an old one

I noted earlier that you could actually install a new version of ZCN
using an old one - i.e. without ever leaving ZCN. Here's how to do
that.

First, you need to get the `zcn.bin' file across. You can do this with
`rexec' or (better) `qterm', as described above. At the NC100 end you
should give it a filename ending in `.com', as it acts just like a
normal executable program. `zcn.com' is a good name, for example.

Then after getting `zcn.com' (or whatever) across, you simply run it,
in this case by typing `zcn'. When the new version boots, test it out
a bit to make sure it's working ok; you can then delete the `.com'
file and install it on the card with `era zcn.com' and `sys a:'.


** Installation epilogue

By now, you should have a running ZCN system with a bootable card and
some file transfer program. You may now want to transfer other
programs in the `bin' and `support' directories, which together make
what I would consider a fully functional ZCN system. None of the
programs are necessary, but you're likely to find many useful:

- Programs you should transfer if at all possible are `ls', `optdir',
  `zde', `pipe', `submit', `pmarc', `pmext', `bbcbas', `runrom', and
  `rrxfer'.

- If you want online help, and it's better than you might think,
  you'll want `man' (be sure to transfer `manpages.pma' too, or it
  won't work - see the `MAN' section under `External Commands' for
  details).

- `spell' may be useful if yu kant spel wurth a dam. :-)

- `calc' runs the ROM calculator program under ZCN, and since
  floating-point calculators for CP/M are few and far between, this
  can be quite handy.

- `nswp' is a file manager which may be worth a look; alternatively,
  `zselx' is a simpler file manager which is somewhat like nswp but
  full-screen, and also has the advantage that the .com file is less
  than half the size.

- `rogue' can be a nice time-waster - oh sorry, "game" - especially
  for AD&D fans. :-)

- `cpmtris' is a reasonable tetris clone.

- If you own a microsoft-compatible serial mouse, you might want to
  take a look at `zcnpaint', a mouse-based paint program I wrote a
  while back. Documentation is in the `External Commands' section,
  later on.

- If you like the idea of a graphical front-end which works a bit like
  the ROM software's menus (but which is hugely more flexible), you
  may want to try `zap' (but be sure to transfer `zapdesc.bin' too -
  see the `ZAP' section under `External Commands' for details).

- And somewhat inevitably, there are many more. :-)

Frankly, it might be a good idea to simply transfer the lot, if you
have room. The programs in `bin' are described later on in `External
Commands'; the programs in `support' are described in the README
there.

The rest of the documentation in this file covers using ZCN and
programming for it, as well as details of some of the internals.

As such, while I've tried to assume little previous experience or
knowledge throughout this section of the documentation, the rest of
this file will assume varying amounts. It should be possible for
anyone with experience of CP/M to follow most of the ZCN Manual, but
some is intended for programmers or simply for whoever is interested.

Those of you who ran `rrinit' to save your data and are now beginning
to panic because I've said so little about how you get it back into
memory :-) should probably skip ahead to the section `Running the ROM
software from ZCN' and read that before reading the manual proper.

If you're a Z80 programmer new to CP/M and/or ZCN, you may want to
look at `zcnprog.txt', my guide to programming CP/M and ZCN. It
documents all the CP/M 2.2 BDOS calls, and all the `zcnlib' routines.

If you have any problems, feel free to write/email (addresses are at
the end of this file), and I'll do my best to help. If you're writing,
please include an SAE if you can, it saves me time and trouble.


* The ZCN Manual

** Rationale

The ZCN Manual tends to concentrate on differences from normal CP/M in
everyday use. I've tried to cover some of how CP/M works, but not all
that much. Parts of it may be in a rather confusing and messed-up
order, as to a certain extent I've just scrawled down documentation
for commands etc. as I've added them.

I recommend that you read at least up until the `ZCN for hackers'
section. I know it's a lot to read, but it will almost certainly be
worth it, as ZCN is quite an oddball mix of ideas and programs, and
there will almost certainly be something there that's new to you.

Also be sure to read the `Q&A' section below.

The manual is more than a little informal, as you may already have
noticed. In my humble opinion, far too many manuals are stuffy and
unreadable. In stark contrast, the ZCN manual is chatty and
unreadable. Much better. :-)


** Q&A

This section attempts to cover some of the more astonishing things ZCN
does. As for what I mean by `astonishing':

"A program should follow the `Law of Least Astonishment'. What is this
law? It is simply that the program should always respond to the user
in the way that astonishes him least."
      -- James Geoffrey, "The Tao of Programming"

ZCN, ah, bends this law at times. :-)

*** Why do some programs show the file FOO.TXT as FOO.TwT?

This is to do with, and yes I know this sounds bizarre, ZCN's support
for the power on/off switch. Turning the machine off is actually done
under software control, and the way it needs to work, combined with
the way CP/M works, means that with some programs you may see
filenames with `w' as the second character of the extension. A few
programs may even force the actual files to have a `w' there (this is
very unlikely, but there might be one or two programs that do it).

For technical reasons, there's little I can do to prevent either of
the problems. The NC100 simply wasn't designed to run CP/M, and ZCN
just does the best it can with what it's got. For a more technical
explanation of why this happens, see the section `The Power On/off
Switch' near the end of this file.

*** Why do I get rubbish from the serial port?

Whenever you turn on the NC100 under ZCN, the serial port is enabled.
During this process, a spurious `serial input' interrupt is generated
which is difficult to filter out for various reasons. This usually
ends up putting a random character in the serial input buffer. This is
harmless and can be ignored.

If you get a whole load of rubbish chars, you probably either have
parity enabled at the other end or are using the wrong baud rate.

*** Why are the letters so SMALL!?

I wanted to get as many lines as possible. I think it's worth the
smaller characters to get 10 lines rather than 8 with the ROM
software. I hope the characters are readable; I think they are, but
I'm obviously rather biased. They're narrow to keep the aspect ratio
as `normal' as possible, and because 4-bit wide characters are much
easier and faster to draw than 6-bit wide ones such as the ROM
software uses.

*** Why does zero look round, and O rectangular?

Before ZCN v1.1, you simply couldn't tell zero and O apart in ZCN's
font (both were round). Since, unfortunately, the characters were too
small to:

- put a slash through the zero;
- put a dot in the centre of the zero (it makes it look like an 8!);
- make the zero more diamond-like;
- make the zero narrower;

...I decided to make the O rectangular instead. (This is an unusual
approach, but isn't entirely without precedent.) It's not ideal, but
at least you can tell which is which.

If you really can't stand this, and you'd rather they were both round,
do this, but be careful to type it in correctly!

      poke ebda 44
      poke ebde 44

(Note that this causes problems with the copy cursor in `bbcbas'
though - it'll think both 0 and O are zeroes. And it'll affect
`dmp2txt' in much the same way.)

You could put these commands in your `autoexec.sub' if you wanted this
all the time (more on SUB files later), or you could just rewrite ZCN
with the altered font using `sys a:'.

*** Why do some characters look like random blotches?

ZCN only has character bitmaps for characters in the range 32-126, the
so-called `printable characters'. If a character outside this range is
printed which is not a control code, an effectively random collection
of pixels is printed.

This usually happens when a character was printed which had the high
bit set. If the offending character was received from the serial port,
try disabling parity on the other machine.

*** It says `Disk Full', but I've got plenty of room left!

This probably means that the drive's directory table is full. Usually
under ZCN there's a maximum of 64 files per drive (but see below).
When you run out of directory space, it's often interpreted by
programs as `disk full'. It does have the same effect, as in order to
write any more you'll have to move or delete one or more files.

You may, in fact, be allowed less than 64 files. If a file is larger
than 16k, it will take up more than one directory space - it'll use
one for each 16k of the file.

*** Why is QTERM's display when sending/receiving files messed up?

QTERM's file transfer display is designed for a terminal with 12 lines
or more. ZCN only has 10, so the line which shows the number of errors
sometimes overprints the line showing the number of packets done so
far. I'm afraid there isn't much that can be done about this without
patching QTERM - but hopefully it's not that much of a problem.

*** How can I patch programs without DDT/SID?

Unfortunately, the (possibly unusual, since they were for fairly `odd'
machines and may have been modified) copies of DDT and SID I've tried
didn't work on ZCN; or rather, they worked to a certain extent, but
they seemed to overwrite the call at 0030h, which is a Bad Thing on
ZCN.

Personally, I don't think this is that much of a problem. I use `wade'
instead (look in the `support' directory for a copy) which is, dare I
say it, rather nicer than DDT and SID. :-)

*** Why does the ROM ask me to set the time when I turn the NC on?

NC100s with ROM v1.00 seem to be quite pedantic about having the time
set. If the time *isn't* set, the ROM demands you set it, which loses
you any saved context - and if ZCN was running, it resets the machine
into the bargain. :-( This is a bug in the original ROM, and although
it was fixed in the later v1.06 (which is in my NC100, for example),
this doesn't help you if you have machine with the earlier ROM (you
can check which ROM you have with ZCN's `ver' command).

The only way to `fix' it is to set the time, as you might imagine.
(You can do this either with the ROM's time setting screen or with
ZCN's `timeset' command.) Fortunately, once the time is set it tends
to stay that way. :-)


** Running the ROM software from ZCN

[This is deliberately early on in the manual (earlier than it might
otherwise make sense for it to be) so that it isn't too hard to find
for anyone skipping ahead from `Installation epilogue'.]

*** About `runrom'

To run the ROM software from ZCN, just use the `runrom' program - i.e.
do `runrom' and it boots the ROM software. If you have an existing
`runrom.ram' file - this file is a snapshot of an already-booted
machine, usually with files in memory etc. - be sure to start with
that in the current drive and user area. If no `runrom.ram' file is
found in the current drive/user, the memory is zeroed and the ROM
booted from scratch.

Note that you can only run `runrom' from a bootable card. (It'll exit
with an error if you try to run it on one which isn't.) It's
complicated to fully explain why, but the basic reason it's necessary
is so that there's a safe way back to ZCN from the ROM software.

You also need either an existing `runrom.ram' snapshot file, or 64k
free on the current drive in order to create one. The reason for this
latter requirement is much easier to explain - a snapshot is always
saved when you return to ZCN, and the disk space for it is allocated
in advance.

When the ROM software is started, you can use it exactly as you
normally would.

(If you used `rrinit' to save your existing memory, the `rrinit' file
will still be there when you do `runrom'. Feel free to delete it; it's
not needed any more.)

When you want to return to ZCN, *make sure the card you ran `runrom'
from is in the card slot*, then press `Function' and `X'. (It's
probably best to leave this card in the slot throughout so you don't
need to worry about whether it's in or not - but you may find this
inconvenient. It's up to you.)

When you return to ZCN (in fact just before), a snapshot of the memory
is saved in `runrom.ram'. After that, ZCN is rebooted.

So in summary, it's:

- `runrom' on a bootable card to go from ZCN to the ROM s/w.

- Function-X *with the same card in the slot* to return to ZCN.

By the way, you may notice that the screen is corrupted for a (very)
short while when switching between ZCN and the ROM or vice versa. This
is meant to happen, and is nothing to worry about.

There is one extra detail to cover. Imagine this situation - when
using the ROM software, something terrible happens and you manage to
make it crash. (This isn't that difficult if you're messing about with
machine code in BBC Basic; also, there are one or two bugs in the ROM
which can lead to crashes in certain obscure situations.) The only way
out, as usual with a crash, is to reboot. Obviously, in this situation
you're not going to want a snapshot to be saved when you do
function-X! No problem. Just make sure you're holding both shift keys
when you do function-X - i.e. while holding down both shifts and the
function key, press X - and no snapshot will be saved. So the next
time you do `runrom', your previous data will still be intact.


Now you know how to switch between ZCN and the ROM software, you may
be wondering how useful this really is without the ability to copy
files between the two. That's where `rrxfer' comes in.


*** About `rrxfer'

`rrxfer' lets you copy files to/from a `runrom.ram' snapshot file, and
thus to effectively copy files to/from your ROM software setup.

Rrxfer uses an 80-column-friendly layout and no inverse video if the
console output is going to the serial port or printer.

**** How to use it

The program is relatively straightforward to use. You start it up with
plain `rrxfer', then when the menu line comes up (it'll take a little
while as it has to load most of the snapshot first), press one of
these keys:

- `r' to list the ROM files (i.e. the files in the snapshot). Files in
both the ROM's `upper' and `lower' memory areas are listed.

- `z' to list the ZCN files (i.e. the files in the current
drive/user). I'm afraid there's no way to transfer files to/from a
different drive or user area than the one the snapshot is in. (You can
probably get around this, though, by copying files or using `umv'
before/after running rrxfer, as appropriate.)

- `g' to get a file - to copy a ROM file to ZCN. Note that any
existing ZCN file with the same name will be overwritten. The filename
you type must exactly match the ROM file's name - case is significant
in ROM filenames. The copy made is automatically given a reasonable
ZCN name; non-printable ASCII chars, spaces, colons, asterisks and
question marks are all converted to underscores. If you choose `g'
then change your mind, just type in an empty filename (that is, just
press enter) to abort.

If the ROM file isn't found, or there isn't enough room on the ZCN
drive to write the copy, you'll get an error message saying so.

- `p' to put a file - to copy a ZCN file to the ROM's file area. Note
that any existing ROM file with the same name will be overwritten
(more precisely, the existing file is deleted first, whether in upper
or lower memory). The copy is always written in lower memory. (Again,
you can enter an empty filename to abort.) The copy made is given a
ROM filename which matches how you typed the ZCN file's name, which
means you have a degree of control over the ROM file's name.

Here's an example of what that means - say you have a file `foo.txt'.
If you type the name as `foo.txt', the ROM file written is `foo.txt'.
Simple enough. But you could also type it as `Foo.txt', as that still
refers to the same ZCN file, and the ROM file will then be called
that. (As I mentioned above, case is significant for ROM files.)
`FOO.TXT', `fOo.TxT', and `foo     .txt' are other possibilities.

If the NC100's real-time clock has been set (either via the ROM or
with ZCN's `timeset'), the file is written with the current time/date.
If the clock isn't set, however, they're written with a `zero'
time/date. The ROM interprets this as midnight on "90-00-00" [sic].

If the ZCN file isn't found, or there isn't enough room in the
snapshot's lower memory to write the copy, you'll get an error message
saying so.

- finally, `q' quits rrxfer. This may take a little while if you wrote
any files to the lower memory (i.e. used `put'), as the lower memory
part of the snapshot has to be rewritten.

The menu line lists these keys with a (very) brief description of what
they do.

**** Problems

There's one main problem when transferring files between the ROM
software and ZCN - the ROM software stores file sizes exactly, while
ZCN (being CP/M-like) only stores them to the nearest 128-byte
`record'.

For file tranfers in the ROM -> ZCN direction, this is usually not a
problem. Rrxfer always makes sure an extra ^Z is added to end of any
files transferred, so text files are ok. (This can cause some
difficulties for binary files assumed to be of a given size though -
screen dumps are probably the main example, and how to deal with those
is covered in the `Hints and tips' section below.)

The problem is in the ZCN -> ROM direction. Now, if you think about
it, this doesn't seem like it should be a problem for the ROM stuff -
XMODEM file transfers work with 128-byte records too, and it has no
problems dealing with those! Unfortunately, it seems to be the XMODEM
receive routine which deals with them (probably by stripping trailing
^Z's), rather than being some general capacity of the file I/O.

This means that we need to check each of the ROM software's programs
in turn to see how it copes with it. Now, the only ones with which you
can get at files written by rrxfer are the word processor and BBC
Basic. The word processor shows any trailing ^Z's literally, as a
series of little right-arrows. These are then easily deleted. As for
BBC Basic, it seems to simply ignore junk at the end of its Basic
files. If you *EXEC a file, it'll leave right-arrows on the screen,
but as with the word processor these are easy enough to delete (in
Basic pressing Stop is probably easiest). Note also that BBC Basic can
be run natively on ZCN (and is 10% faster), so running it under the
ROM software probably isn't that attractive anyway.

Text files written by some CP/M programs may cause more problems than
others. For example, since you need only one ^Z to end a CP/M text
file, some programs only write one, and don't worry about whatever
junk may be in the rest of the record. If you have this problem, and
the junk causes difficulties, there's an easy solution - just load the
file up into ZDE and save it before transferring with rrxfer. (ZDE
always fills up the remainder of the last record with ^Z's. By the
way, it'll prompt you because the file is unchanged - just press `Y'.)

**** An example session

Here's an example of an rrxfer session:

rus@amnesia:/b/0>rrxfer
Reading lower memory from snapshot...
 [R]OM files, [Z]CN files, [G]et (ROM->ZCN), [P]ut (ZCN->ROM), [Q]uit
ADDRESS BOOK   1k  foobar         1k  new2           1k  new6           1k
autoexec.sub   1k  HELLO.BAS      1k  new3           1k  new7           1k
COPY.BAS       1k  hello.bas      1k  new4           1k  sw.txt         2k
FILLER         9k  new1           1k  new5           1k  TRY.BAS        1k
 36k free in lower memory
 [R]OM files, [Z]CN files, [G]et (ROM->ZCN), [P]ut (ZCN->ROM), [Q]uit
radfreq.txt    1k  runrom.ram    64k  sw.txt         2k
 13k free on drive
 [R]OM files, [Z]CN files, [G]et (ROM->ZCN), [P]ut (ZCN->ROM), [Q]uit
Get which ROM file? hello.bas
File copied OK.
 [R]OM files, [Z]CN files, [G]et (ROM->ZCN), [P]ut (ZCN->ROM), [Q]uit
Get which ROM file? flurgle
Error writing ZCN file! (ROM file not found, or ZCN disk full)
 [R]OM files, [Z]CN files, [G]et (ROM->ZCN), [P]ut (ZCN->ROM), [Q]uit
Put which ZCN file? radfreq.txt
File copied OK.
 [R]OM files, [Z]CN files, [G]et (ROM->ZCN), [P]ut (ZCN->ROM), [Q]uit
Put which ZCN file? wibble
Error writing file! (ZCN file not found, or not enough low memory)
 [R]OM files, [Z]CN files, [G]et (ROM->ZCN), [P]ut (ZCN->ROM), [Q]uit
ADDRESS BOOK   1k  HELLO.BAS      1k  new4           1k  sw.txt         2k
autoexec.sub   1k  hello.bas      1k  new5           1k  TRY.BAS        1k
COPY.BAS       1k  new1           1k  new6           1k
FILLER         9k  new2           1k  new7           1k
foobar         1k  new3           1k  radfreq.txt    1k
 35k free in lower memory
 [R]OM files, [Z]CN files, [G]et (ROM->ZCN), [P]ut (ZCN->ROM), [Q]uit
hello.bas      1k  radfreq.txt    1k  runrom.ram    64k  sw.txt         2k
 12k free on drive
 [R]OM files, [Z]CN files, [G]et (ROM->ZCN), [P]ut (ZCN->ROM), [Q]uit
Writing lower memory to snapshot...
done.


**** Bugs

There's one bug in rrxfer that I'm aware of:

- You can't `put' an address book (due to the filename required). This
probably isn't that big a deal, as address books are in a funny format
anyway.


*** Hints and tips

`runrom.ram' is just a normal file. If you make a backup of this file,
you're backing up your ROM software setup and all the files it has in
memory. Backing up all your files has rarely been *this* easy... :-)

Equally, because it's a normal file, you can save space if (like me)
you don't use the ROM software much by compressing the snapshot with
pmarc (using something like `pmarc snap runrom.ram'). You'll have to
decompress it again (with pmext) before using `runrom', of course, but
it could save you quite a bit of disk space in the meantime.

ROM software screen dumps can't be viewed as-is on ZCN, because rrxfer
adds an extra record to the ZCN copy to allow for the ^Z it always
adds. (This means that trying to view it the usual `get f000' way will
crash the machine!) So the full sequence for getting a ROM s/w screen
dump and loading it on ZCN goes like this:

- Make sure you have at least 9k free on the ZCN drive with
  `runrom.ram' on.
- On ZCN, do `runrom' to start the ROM stuff.
- Make sure there's at least 4608 bytes free in the upper memory.
- Do whatever it is you need to, to get the screen right for the dump.
- Do Ctrl-Shift-S. This saves `s.a' and `s.b'.
- Do Function-X to return to ZCN.
- Start up rrxfer.
- Get `s.b', and quit. (`s.a' isn't of interest.)
- Do `get 100 s.b', then `save 16 dump'.
- `get f000 dump' now loads the screen dump.
- Delete `s.b' if you want, you don't need it any more.


** Command Prompt

When ZCN is waiting for you to issue a command, it gives a short
prompt ending in `>'. This prompt tells you which drive is the default
drive; the drive which files are assumed to be on unless you
explicitly specify another.

If drive A is current the prompt would normally be `A>'. This may not
always be the case however - there may be a number or `*' displayed
between the drive letter and the `>'. See `User Numbers' for more
details.

If you like, you can redefine the prompt ZCN uses to suit your own
tastes. See the description of the `%' command (listed as
`%prompt_string') in the `Internal Commands' section for details.


** Wildcards

Wildcards in ZCN (and CP/M, and even MS-DOS) have a curious quirk that
you may not be aware of. When you specify part of a filename or
extension then use a wildcard, it matches even files that have no more
characters after the part you specified.

This is fine for wildcards like `foo*.txt', which matches `foo.txt',
`foo2.txt' and `foobar.txt'. Where it gets weird is for `foo?.txt',
which obviously matches `foo2.txt' but (perhaps unexpectedly) also
matches `foo.txt'! The reason for this is that the file isn't really
called `foo.txt' as far as the system is concerned; it sees it as
`foo_____txt' (I'm using underscores to represent spaces for clarity).
The wildcard `foo?.txt', or `foo?____txt', matches this as the `?' by
definition matches any character.

Rational or not, having `foo?.txt' match `foo.txt' is bound to confuse
anyone who's used to Unix, where it wouldn't match, and might even
confuse some MS-DOS or CP/M users who haven't noticed it before. I
thought it was a bug the first time I noticed it. :-)


** The Keyboard

The NC100's keyboard is, shall we say, a little odd. Certainly some
keys are in the `wrong' place.

The way ZCN fixes this and maps the non-obvious keys is shown below:

Key         Acts like   ASCII code  Reason
---         ---------   ----------  ------

Function    Control           <none>            Nice big key
Stop        Escape            27          In the right place
<-Del       Delete            127         In the right place
Del->       ^G          7           WordStar-like
Menu        `           96          No real backquote key
Cursor Up   ^E          5           WordStar-like
Cursor Left ^S          19          WordStar-like
Cursor Right      ^D          4           WordStar-like
Cursor Down ^X          24          WordStar-like


The `symbol' key acts as a Meta key - it sets bit 7 of any key
pressed. (PC folks should think of it as analogous to `Alt', but
different.)

Ctrl+Space returns ASCII 0 (i.e. NUL). Note that this may not be sent
by some terminal programs (though QTERM seems to be ok). The built-in
command `sertest' does send it, so you could always use that.

It is possible to make the `Caps Lock' key act like a control key, if
you like that - see `CAPSCTRL' in the `Internal Commands' section for
details.

You cannot stop a program's output by using ^S. However, you can pause
a program's output at any time by holding both the `control' and
`symbol' keys simultaneously. The output starts again when you let go.

You can get a dump of the current screen at any time by pressing
Control-LeftShift-S (you must use the real Control key for this). The
middle 60 pixel lines of the screen memory are simply saved to the
file `screen.dmp', including the `wasted' bytes, giving 64 bytes per
line. The top two and the last-but-one pixel lines are used as
temporary storage during the screen dump, so don't worry if they
appear corrupted for a second or two. You'll get a screen flash (or
beep) when the dump has been written, and you can then carry on with
whatever you were doing.

On a Unix box with the `netpbm' or `pbmplus' utilities installed, you
can convert a `screen.dmp' file to a PBM file with something like this:

(echo P4;echo 512 60;cat screen.dmp) | pnmcut 0 0 480 60 >foo.pbm

You can then convert to other formats with things like ppmtogif, etc.


** The Screen

The NC100's screen has a pixel resolution of 480x64. ZCN provides a
character screen of 120x10 with 4x6 character cells, leaving two pixel
lines at the top and bottom free. The leftmost 32 pixels on the bottom
pixel line are used by the `drive lights' (see `Logical Drives').


** The Terminal Driver

*** Control Codes

Programs often have patch areas (or installation programs) which need
to know which sequences to send to do cursor movement, etc. For that
reason, and for programmers of course :-), the console control codes
are listed here. Those listed as `(reserved)' have no effect.

Code  Hex   Dec   Description

^@    00    0    (ignored)
^A    01    1    clear screen, home cursor
^B    02    2    bold off
^C    03    3    cursor on
^D    04    4    cursor off
^E    05    5    bold on
^F    06    6    clear to end of screen
^G    07    7    bell (by default, this flashes the screen)
^H    08    8    backspace
^I    09    9    tab (8 chars wide, i.e. 1,9,17,25,33,...)
^J    0A    10    linefeed
^K    0B    11    (reserved)
^L    0C    12    (ignored)
^M    0D    13    carriage return
^N    0E    14    italics ("underline") off
^O    0F    15    italics ("underline") on
^P    10    16    move cursor - 10h, then 20h+y, then 20h+x (see below)
^Q    11    17    (ignored)
^R    12    18    insert line
^S    13    19    (ignored)
^T    14    20    delete line
^U    15    21    scroll up
^V    16    22    (reserved)
^W    17    23    scroll down
^X    18    24    true video (i.e. turn off reverse video)
^Y    19    25    reverse video
^Z    1A    26    move cursor right one column
^[    1B    27    VT52 escape code prefix (see below)
^\    1C    28    (reserved)
^]    1D    29    move cursor up one line
^^    1E    30    home cursor without clearing screen
^_    1F    31    clear to end of line

In pre-v1.2 versions of ZCN, the y location for ^P was 46h+y. This is
still supported, but is deprecated and may not be supported by a
future version of ZCN - you should switch to using 20h+y instead.

Some VT52-like escape codes are supported, mostly so that Mallard
Basic will work comfortably on ZCN. These all start with ^[ (ESC).
Those supported are ESC-D to backspace, ESC-C to move the cursor right
one column, and ESC-K to clear to the end of the current line. (In
fact, at the moment, ESC followed by anything other than `D' or `C'
acts like ESC-K.) No other VT52 escape codes are implemented.

However, one extra feature of ESC is that it counteracts any CR/LF
output immediately after. So if you're writing a program where you
want to avoid the CR/LF which ZCN normally outputs when a program
exits, you can easily do this by just outputting an ESC before you
exit. (Be warned that this doesn't work on ZCN versions earlier than
v1.2, though, and obviously it won't work if console output is
redirected to the serial port.)

While I'm on the subject, here's another brief aside for programmery
types. :-) If for some reason you need to know the current cursor
location, you can use this bit of Z80 to read it (it reads the x
position into B and the y pos. into C):

      ld ix,(1)
      ld b,(ix-5)
      ld c,(ix-4)

Using this is a Bad Idea in general, and it won't work on old
(pre-v1.1) versions of ZCN, but it's there if you need it.


*** Unix termcap/terminfo entries

Skip this if you don't use any version of Unix.

Since the NC100 can be used as a convenient and portable terminal to
Unix systems, it's a good idea to have a termcap/terminfo entry to
hand so you can run full-screen programs on it. Note that they will
have to be able to cope with using such a small number of lines -
Emacs and Nethack can, for example (though Nethack isn't too happy
about it).

Here's a termcap entry for an NC100 running ZCN:

zcn|amstrad nc100 running zcn:\
      :cl=^A:co#120:li#10:cm=^P%+ %+ :le=^H:bs:am:sf=^U:sb=^W:sr=^W:\
      :ce=^_:so=^Y:mr=^Y:se=^X:us=^O:ue=^N:me=^X^N:al=^R:dl=^T:it#8:\
      :cr=^M:do=^J:nl=^J:ms:vi=^D:ve=^C:ta=^I:up=^]:nd=^Z:cd=^F:

However, termcap is rapidly falling into disuse these days, so most
people will probably want a terminfo entry instead. Here's the one I
use:

zcn|amstrad nc100 running zcn,
      cols#120, lines#10, am, clear=^A, cr=^M, bel=^G,
      cub1=^H, cuf1=^Z, cuu1=^], cud1=^J, ind=^U, ri=^W,
      cup=^P%p1%' '%+%c%p2%' '%+%c, home=^^,
      el=^_, ed=^F, il1=^R, dl1=^T,
      smso=^Y, rmso=^X, smul=^O, rmul=^N, bold=^E, rev=^Y,
      sgr0=^B^N^X, msgr, civis=^D, cnorm=^C,
      ht=^I, it#8, km,

You may have problems using Emacs, for a couple of reasons. The common
problem with XON/XOFF flow control doesn't apply since ZCN avoids it
like the plague; instead, there are two other problems.

Because of the way the direct console I/O BDOS function works, some
CP/M terminal programs may not send ^@ (ASCII 0, or NUL). This'd be a
real pain when using Emacs. The simplest solution is to use the
built-in command `sertest', which has the added advantage of being
faster than most other terminal programs since it really is very
simple indeed, and can call functions in ZCN directly rather than
having to use the BDOS entry point. (My tests indicate that `sertest'
is nearly twice as fast as QTERM.)

You may also have problems getting the `Symbol' key to work as a Meta
key. There shouldn't be a problem if Emacs is using terminfo - the
terminfo entry above specifies `km' which should get it working
properly. (Certainly that works for me.) But if for whatever reason it
doesn't work, you might want to try putting this in your ~/.emacs file
to fix it:

      (if (equal (getenv "TERM") "nc100")
          (set-input-mode nil nil t))

(If that doesn't work, it could be down to the stty settings `cs8'
and/or `-istrip' not being set.)


** Rebooting

There are two main rebooting possiblities available when switching on
the NC100 running ZCN. They are:

1. Cold boot of the ROM software. Do this by holding down Function,
Stop and `<-Del' while turning the computer on. You should only need
to do this if a program crashes, etc. You should then use Function-X
to boot ZCN from your bootable card.

2. Cold boot of ZCN. (This isn't fully `cold', as it just restarts the
copy of ZCN in memory.) Do this by holding down both shift keys while
turning the computer on. Use this to clear any random wedgitude that
may have occurred, or to test your `autoexec.sub' (see later).

You can also, from the ZCN command-line, use `cboot' to do a fully
`cold' boot of ZCN from the memory card.


** CP/M Compatibility

ZCN aims at close CP/M compatibility - enough to get the majority of
freely available programs running. Most programs work. This section
describes what facilities are provided, and lists programs which are
known to not work under ZCN.

*** BDOS Functions

The following BDOS functions are provided, and are believed to be
working correctly:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 29, 32, 33, 34, 36, 37.

These ones work but have known problems:

35 - gives incorrect results for files with holes.
40 - the same as function 34, i.e. it doesn't actually do the zero
     fill.

These not done:

27, 28, 31.


There are some additional (ZCN-specific) functions; some are mentioned
later. Full descriptions are given in `zcnprog.txt', but the ultimate
reference is `zcnfunc.z' in the `src' directory. So, in other words,
RTFS. :-)


*** BIOS Functions

ZCN has a rather sparse BIOS jumptable which omits all the
disk-related functions. I am very reluctant to add them as it would
take a fair chunk of memory to implement. (ZCN's internals work
differently to CP/M, which would make writing them tricky, too.)
Still, the existing BIOS is enough for most programs.


*** Zero Page etc.

ZCN uses the memory at addresses 0000h-00FFh as follows:

address(es) description

00h-02h           jump to warm boot routine
03h         ZCN does not implement CP/M's IOBYTE; instead, this
            byte contains the contents of 80h when the last
            program finished (this lets you check the exit status
            of a Hitech C program)
04h-04h           unused (but set to zero by warm boot)
05h-07h           jump to BDOS
08h-2Fh           usable by user programs (as on CP/M)
30h-32h           jump to NMI poweroff routine (see note 1)
33h-37h           part of NMI poweroff routine
38h-3Ah           unused jump to maskable interrupt routine (see note 2);
            usable by user programs
3Bh-5Bh           reserved (actually unused)
5Ch-6Bh           initialised part of FCB 1 (see note 1)
6Ch-7Bh           initialised part of FCB 2
7Ch-7Fh           remainder of FCB 1
80h         size of command tail at 0081h
81h-FFh           command tail (command line minus command name)

Note to programmers: Please do not *depend* on any of the `unused'
sections above being available for your use (unless your program is
taking over control of the machine completely).

Note 1:

Pressing the on/off switch when the NC100 is on causes a non-maskable
interrupt - that is, it disables interrupts, puts pc on the stack, and
jumps to 0066h. This is the 2nd char. of the filename extension in FCB
1 - there's some ad hackery in ZCN to try and deal with the problems
this causes. As far as I know it's successful, except that sometimes
you will see a filename printed with the 2nd char. of the extension
appearing as a lowercase `w'. I don't think there's anything I can do
about that. Anyway, the value that's actually stored at 0066h is F7h -
`rst 30h'. The maskable interrupt routine and BDOS both fix this byte
if it's been changed.


Note 2:

The maskable interrupt routine is responsible for the following:

- Fixing 0066h if it's been changed (see note 1 for details).
- Keyboard input/buffering.
- Serial port input/buffering.
- Auto poweroff timeout and the actual auto poweroff itself.
- Updating `drive lights'.

See `Tight Interrupts' (in the hacker's guide section) for what
happens when minimal interrupts are in use.

The reason there's still a jump to the interrupt handler at 0038h is
in case there's some program out there which explicitly selects IM1
for some reason and expects ZCN to cope with this.


Note 3:

Although 0008h-002Fh is available for use by user programs, ZCN puts a
jump instruction at 0028h (which it's ok to overwrite). The jump at
0028h is to allow ZCN's internal commands to use `rst 28h' as an
indirect call to a inline string output routine, thus saving a few
bytes. It's not a good idea to call this yourself - it doesn't exist
on other CP/Ms, and didn't even exist on ZCN until v1.1. However, if
you're really determined to ignore my advice on this :-), look at
`ilprint' in `src/misc.z' for how to call it.


Unusually for a CP/M system, the BDOS entry point (the address at
0006h) is the very start of system code; all addresses from that one
upwards are used by ZCN, except for the screen memory which starts at
F000h. Programs which leave space for a CCP will still work, as will
those which don't - all parts of ZCN interact directly with each
other, and should never be overwritten. Note that this monolithic
approach means you will presumably never be able to run any version of
ZCPR on a ZCN system unless someone's prepared to hack up both
programs.


*** Non-working Programs

Essentially, programs which need disk BIOS functions don't work. This
included (the last time I tested) superdir, `dr24.com', and zx 3.1.

Another possible problem is the whole 66h thing (more on this
elsewhere) - usually this just results in the odd spurious `w' being
printed :-), but it can cause real problems with some odd programs.
The ones I've found so far that are affected are nulu and kermit.


** Tips on using certain programs with ZCN

*** Hitech C

**** Getting Hitech C

Native CP/M Hitech C is free. It's very slow and memory/disk hungry
and Z80-specific and the optimisation is quite awful, but it's very
ANSI-compatible (well, for a CP/M C compiler ;-)) and excellent for
compiling short (<2000 line) C programs. It's available from
oak.oakland.edu in /pub/cpm/hitech-c, and probably also available from
any decent CP/M PD distributor.

**** How to run it on ZCN

Programs compiled with Hitech C (which fit in memory!) work on ZCN
just fine, though any use of any exec() or system() call will fail. A
few of the programs in the `support' dir were compiled with Hitech C
using the excellent `cpm' CP/M emulator on my Linux box.

As for the compiler, things are more problematic. The compiler driver
`c.com' doesn't seem to work on ZCN for some reason, so you have to
run the passes by hand. Even then, most of the passes need a LOT of
memory to run. You'll need to use `bigrun' to run them. (Be sure to
read the warnings in the `bigrun' section first!) Here's an example
SUB file `hc.sub', designed to run on drive B: with `libc.lib' on
drive A:, which acts as a simple replacement for `c.com':

--------------------------- cut here ----------------------------
submit hc.sub *
defrag -q b:
'cpp:
cpp -DCPM -Dz80 -I $1 hctemp1
ifnpeek 3 0 quitsub era hctemp?
'p1:
bigrun p1 hctemp1 hctemp2 hctemp3
ifnpeek 3 0 quitsub era hctemp?
era hctemp3
'cgen:
bigrun cgen hctemp2 hctemp1
ifnpeek 3 0 quitsub era hctemp?
era hctemp2
'zas:
bigrun zas -N hctemp1
ifnpeek 3 0 quitsub ; era hctemp?;era hctemp1.obj
era hctemp1
'link:
link -Z -C100H -o$1om crtcpm.obj hctemp1.obj $2 $3 $4 a:libc.lib
ifnpeek 3 0 quitsub ; era hctemp1.obj;era $1om
era hctemp1.obj
"compiled ok.
--------------------------- cut here ----------------------------

All the `ifnpeek's make sure it quits and cleans up temporary files if
any pass fails. The last two `ifnpeek..quitsub' commands need `semi'
to be on your machine as `;.com' - failing that, you could replace
them respectively with `ifnpeek 3 0 quitsub era hctemp?' and `ifnpeek
3 0 quitsub era $1om' at the cost of possibly leaving a hctemp1.obj
file lying around.

For the SUB file to work, you'll also need much of Hitech C on your
machine (unsurprisingly :-)). Specifically, you need `cgen.com',
`cpp.com', `crtcpm.obj', `link.com', `p1.com', and `zas.com'. You'll
also need `libc.lib' on drive A:, as I mentioned above, and you'll
need any headers you want to use - certainly you'll want `stdio.h',
and probably `stdlib.h' and `string.h'. It may be a good idea to make
a .pma archive of all the header files, so you can get at any you
need. (Such an archive is 9k rather than the 30k the headers take
uncompressed.)

To compile with floating-point support, you'll also need `libf.lib',
and will need to compile with something like `hc foo.c libf.lib'.

You need an awful lot of disk space to run Hitech C. You can't
realistically run it on anything less than a 512k card, and a 1024k
card might be preferable if you want to have enough disk space free to
do other things too. When I last tried it on my 512k card, on the A:
drive I had `headers.pma' and `libc.lib' taking up 69k, and on B: I
had the various required COM files and headers taking up roughly 190k.
Total disk space required, 259k - and that didn't include the 32k
needed for `bigrun' to work, nor did it include the space needed for
Hitech C's temporary files. (Which can be 30 or 40k.) So it
effectively took about 330k.

Oh, and another point - as I've said, it's not exactly fast. On ZCN,
it takes 50 seconds to compile a "hello world" program!

Personally, I dumped it and use `bbcbas' instead when I want to
program on the NC100 itself. It's about 50 times smaller ;-), and
there's no waiting for things to compile.

**** Realistic System Requirements for Hitech C

For serious use, I personally wouldn't run the compiler itself on a
CP/M box of less than around 20MHz clock speed, 60k TPA, 1 Mb disk -
to run it with less than that you'd have to be pretty patient. A good
CP/M/Z80 emulator on a 486 or better is a perfect environment.
(Consider `zsim' for MS-DOS, `cpm' for Linux and presumably other
386-based Unix; others I'm not sure of (`cpm' uses 386 assembly to get
the high speed, and isn't CPU-portable). Some sort of emulation is
probably your only option - I don't know of any *real* CP/M system
which could run it at a reasonable speed.)

**** Bugs in the library

There's one bug I've noticed in Hitech C's libc library - fgets() will
not read lines longer than the buffer size correctly. I suspect it's
implemented as gets() from a stream, which is not ANSI at all. This
may not worry you, but if it does, here's something you could put
right at the end of stdio.h as a workaround (minus the `cut' lines of
course :-)):

--------------------------- cut here ----------------------------
char *myfgets(char *s,int size,FILE *stream)
{
char *ptr=s;
int f,c;

for(f=0;f<size-1;f++)
  {
  c=fgetc(stream);
  if(c==EOF) break;
  *ptr++=c;
  if(c=='\n') break;
  }

 *ptr=0;
if(c==EOF) return(NULL);
return(s);
}

#define fgets myfgets
--------------------------- cut here ----------------------------

I think this fits the ANSI standard. Certainly it's a lot better than
the Hitech C implementation, 'cos it works. :-)

If you're feeling adventurous, you could fix the library itself (not
too hard if you use `libr'), but this is left as an exercise for the
reader. :-)


*** Mallard Basic

Mallard Basic is, if nothing else, the first commercial program I've
got to run under ZCN. (Though it's a bit painful compared to BBC
Basic. :-))

I added a couple of extra control codes to the terminal driver to cope
with MB's expectation of a VT52 - namely, ESC-C, ESC-D and ESC-K. (I'm
surprised it uses them, really. You can implement all it needs with
straight ascii codes like BS and CR. It'd be slower, but would work on
everything.)

If you want basic to use the full width of the screen and correctly
wrap long lines, do `width 120,120' after starting up.

My +3 CP/M manual only describes the keys MB uses in terms of the
unusual +3 keyboard - in case the PCW manual does something similar,
I'll describe what the keys are on the NC100 here:

Key       Function

^A        Move back along line being written/edited
^F        Move forward along line
^_        Move up on multi-line line (if you see what I mean)
^^        Move down on multi-line line
<-Del     Delete char to left of cursor
^G        Delete char under cursor (NB: Del-> also sends ^G)
^W <char> Moves forward to specified character
^S <char> Delete all between cursor and specified character
^S enter  To delete to end of line
^I        Toggle between insert and overstrike (NB: Tab also sends ^I)
Stop      Abandon changes to program line

Basic (my copy at least) only has around 16k available on startup.
This is unfortunate, but there isn't much I can do about that with
only 64k total! (Note that MB *does not* work with `bigrun', it
crashes the machine, so don't even think about trying that!)


*** QTERM

Assuming you have QTERM 4.3f patched for ZCN (there's a copy in the
`support' directory), an easy way to take backups is using YMODEM
batch transfers.

For example, when logged into my Linux box I would run `rb' - a YMODEM
batch receive program - then do ^\ s to send, then `xy *.*' to send
all the files on the current drive. At 19200 baud on a full (256k)
drive this takes between 3 and 5 minutes.

You may want to do `user 255' before running QTERM if you have files
on the drive in other user areas - this will make sure you backup all
files in all user areas. Be sure to see `User Numbers' for more about
user area 255, as there are some potential problems associated with
using it, particularly if two different files exist on the same drive
in different user areas with the same filename.


** Logical Drives

Cards of 256k or less have only one drive, drive A:. 512k cards have
two - A: and B:. 1024k cards, the largest allowed, have four, A:, B:,
C: and D:. These logical drives are completely independent of one
another, but drive A: must be formatted for drives B:, C: and D: to be
readable.

You make a drive current by typing its name, e.g. `b:'.


** User Numbers

[Note that I use `user', `user number' and `user area' pretty much
interchangeably. Sorry if this makes it sound more confusing than it
need be. :-)]

ZCN supports CP/M user numbers 0 to 15. You can change user numbers
with the `user' command, but not (yet) in the `0a:', `a0:' or `0:'
manner. This gives you a little more than a flat filesystem (or disk);
you might describe it as a segmented filesystem, but that sounds like
the partitioning scheme used on PCs, which it definitely isn't
anything like. It's more like having 16 different directories - all at
the same level - rather than one, and having them numbered rather than
named. 0 is the default `directory', or user area.

For the uninitiated - user numbers were in CP/M to allow different
users of a CP/M machine to keep their files separate. The way it
worked meant that they would have to keep not just data files, but
also any programs they wanted to run, in that single user area.

It gets worse; the way the feature was used in practice meant that you
had a single user wanting to move files across user areas, run
programs from other user areas, etc.

I'll admit now that ZCN doesn't handle user areas very well at all.
However, this section tells you what it does different from generic
CP/M.

(Note that user numbers are separate from drives - i.e. if you do
`a:', `user 1', `dir b:' it will show all files in user area 1 of
drive B:.)

*** Prompt

The `A>'-style prompt is actually only used in the default user area
0. In user areas 1 to 15, the user area is printed before the `>', as
in `A1>'. In user area 255, it becomes `A*>', with the `*' meant to
indicate the wildcard-like action of user 255 (see below for more on
this user area).

*** Execution

When running a COM or SUB file, ZCN tries the following things:

1. Try current/specified drive and current user.
2. Try current/specified drive and user 0.
3. If no drive was specified, try drive A: and user 0.

This means that user area 0 (and especially user 0 on A:, if you're
using a card larger than 256k) is a good place to put programs.

*** User Area 255

In addition to the usual 0-15, ZCN allows you to use user area 255.
This isn't a user area as such, but acts like all the files on the
drive are in the current user.

User area 255 is mostly read-only, though it does allow `umv' (see
below), and file deletion. The reasoning behind it being read-only is
that files in different user areas are allowed to have the same name.
If the file is written to, it's not clear which file should be changed
or added to. Having two files with the same name also causes problems
when reading from user area 255. You would get (effectively)
randomly-chosen 16k chunks from any files with the same name.

In general, you should only read files in user area 255 if they only
appear in the directory listing once. The `ls' program, which you
should probably be using in preference to `dir' anyway, will report
`*** WARNING: duplicate files found! ***' if two or more files share
the same filename. (The warning will only appear once, no matter how
many filename conflicts there are.)

This probably all sounds rather worrying, but the situation's not
really that bad. If you make sure no filenames occur more than once
across all user areas, you have absolutely nothing to worry about.
Even if you don't, you just have to be sure to not read the offending
files from user area 255. (You couldn't do this and get meaningful
results in any case - how could ZCN tell which file you're referring
to?)

*** UMV internal command

This command allows you to move files matching a given filespec from
the current user area to another, e.g. `umv *.com 0' would move all
COM files in the current area to user area 0. An easy way to put all
files in user area 0 is `user 255' then `umv *.* 0'.


** Warning about using the Serial and Parallel ports

There is no timeout when, say, the printer is busy or serial data
cannot be sent. ZCN will simply keep trying. To interrupt this if it
happens, I'm afraid you'll have to do a cold boot - turn the machine
off, then hold down both shift keys while turning it back on.
Apologies for the inconvenience. :-(


** Using the Serial Port or Printer as the Console

Under ZCN it's possible to use the serial port (instead of the
keyboard/screen) for console input and/or output. To use the serial
port for console output you should use the command `>s'. For serial
input do `<s'. To use the serial port for both input and output, use
`|s' (that's a pipe character, as given by shift-\, then an `s').

To redirect console input/output back to the NC100 itself, just use
the above without the trailing `s', e.g. use `|' (pipe) alone to
restore normality. You can also use `<' and `>' to only restore normal
input or output respectively.

As well as serial redirection, you can direct console output to a
printer connected to the parallel port. This is *as well as* output to
the screen though, so you can see what you're doing. :-) For printer
output of this kind do `>p'. You can also use `|p', which has the same
effect as doing `|' then `>p'. (`<p' is also accepted, but simply does
the same as `<'.) Again, you should use `|' to return to normal.

A brief note in case it's not obvious - redirecting to the printer
won't have the desired effect if you're printing to a PostScript
printer. (ZCN's console output doesn't make much sense at the best of
times, but it makes far less sense as a PostScript program, trust
me...) Then again, if you're using a PS printer with an NC100 you're
probably completely insane, so maybe it won't matter to you. :-)

Using the `semi' external command described later, a crude but
effective way to print a text file is:

      semi >p; cat file.txt; |

(The `semi' should be replaced with a semicolon if you rename the
command as I do; see the description of `semi' for details.)

ZCN makes the following demands of a terminal (or terminal emulator,
or printer):

- It must use ASCII encoding for characters 32-126 inclusive.
- When a CR (13) is sent, it must move the cursor to the leftmost
column.
- When an LF (10) is sent, it must move the cursor to the next line.
Preferably it should do this without moving the cursor to the leftmost
column, but ZCN itself does not require this.
- For the `buffered line input' function to work (as used for the
command-line and by many programs), BS (8) must move the cursor back
one character non-destructively and space (32) must erase any
character previously shown.

These are pretty minimal requirements. However, the last requirement
means that a printer can't properly implement the BS/space/BS ZCN uses
to backspace destructively - usually the new characters will simply be
printed over the old.

You should also note that the `cls' internal command works by simply
clearing the screen memory and homing the cursor, so it can't clear
the screen of a terminal.


** The Command Shell (CCP)

[CCP really stands for Console Command Processor, lest you think I'm
incredibly dim or some such... :-)]

*** Command Line Editing

The only command line editing available is delete-previous-char, and
there is no way to recall previous commands. Sorry.

You can abort the entered command line without executing it by
pressing ^C.

*** Battery level warnings

The low battery level warnings are part of the CCP - if any of the
batteries are low, you get a warning printed before each CCP prompt.
For example, if the main batteries are low, you get something like:

      *** Main batteries low ***
      A>

You can keep using the NC100 under ZCN while batteries are low, but
you run the risk of losing data etc. in memory should the battery
level get too low.

If you do keep using the NC100 when batteries are low, you should note
that if you need to use any of the builtin software (to reboot from a
memory card after a crash, for example), it will demand that you
replace the main/backup batteries (whichever is low) before
continuing. (You could just run it off the mains adaptor for a while
instead.)

For some sorts of batteries this may happen even if you're not using
the ROM - what seems to happen is that the voltage goes too low for
the NC to work, so the power flickers off, in response to which the
voltage goes up slightly, enough for the NC to come back on (into the
ROM OS, as it had effectively crashed). This can happen several times.

As far as I know, the ROM software does not check for low memory card
batteries as ZCN does. I suspect that this feature of the NC100, while
documented, was not correctly implemented, and you should not rely on
the NC100 to report when a memory card's battery is low. Instead, you
should replace memory card batteries at the interval suggested by the
manufacturer (often once a year). In my case, my card started randomly
losing data about 6 months after I should have changed the battery.

[The documentation for my 512k memory card says this:

  The battery condition is output from the card as a signal that some
  computers can read. This signal will indicate one of three states:-

  1. Battery good.
  2. Battery low, should be changed as soon as possible. Data
    maintained.
  3. Battery discharged, data LOST.

I strongly suspect that the NC100 treats states 1 and 2 above as
`battery ok' and treats state 3 as `battery low'! (Experimentation
seems to support this theory.)]

No battery level warnings occur at any other time than when displaying
the CCP prompt. If you have been using a program continuously for a
long time and suspect that batteries may be low, you should quit to
the CCP to check.

You can disable battery warning messages by doing `batwarn 0'.

By the way, the tests I've tried suggest that rechargeable batteries
give roughly 8 hours use between rechargings (possibly more, depending
on the type). It's more difficult to tell how long you generally have
between the `batteries low' warning and effectively dead batteries,
but it seems to be something like 30 minutes for `conventional'
rechargeables. It's much shorter and more variable for the
chargeable-in-two-hours kind - anything between 1 and 5 minutes.


*** Internal Commands

ZCN has several of the normal internal commands provided by CP/M's
CCP, such as `dir'. It also provides many extra commands which I found
useful, and modifies the behaviour of others. This section lists the
internal commands (in alphabetical order), what they do, and how to
use them.

Note that a few internal commands which require args (a filename, for
example), such as `note' and `ren', will just say "Args?" if they're
used without any.


**** !! [command args]

Jump to 100h, effectively running the previous command again with new
arguments. You must *only* do this if you know the command is
re-entrant, or if you like living dangerously. It can also be used to
run a command previously loaded with `get' (see below).

**** "any text

Echo the text after the double quote (") exactly as it appears (except
that the `$' character will terminate the line, if it arises). This
one of the very few commands that does not have its command tail
uppercased before it sees it (the others being ' and `%'). It's
intended for use in SUB files (see `SUB files' below).

A variant of this command is similar but starts with a single quote
('). This also echoes the text exactly, but omits the CCP's CR/LF
after echoing it, meaning that the cursor stays on the same line.

**** %prompt_string

Set the CCP's prompt. (While you can use this command anywhere, it's
really intended to be used in `autoexec.sub' so that ZCN uses the
specified prompt all the time.) The maximum allowed prompt size is 25
chars - if you try to specify one larger than that, it is silently
truncated.

The text after the initial `%' is printed verbatim apart from these
codes:

Code  Translates as...

%a    current user area
%b    current user area, if non-zero (otherwise, prints nothing)
%c    space left on current drive
%d    current drive letter
%e    current drive letter in lowercase
%%    a literal percent sign

(The `%c' number takes a little time to appear, so may not be such a
good thing to put into the prompt as you might initially think.
Personally, I find the slight delay distracting.)

Other two-char combinations starting with `%' don't output anything
(though you shouldn't depend on this). A `%' right at the end of the
prompt string is printed as a literal percent sign.

The default prompt string is `%d%b>' (which could be defined with the
command `%%d%b>'). Here's another example prompt string, the prompt I
use on my machine - `rus@amnesia:/%e/%a>'. It gives a prompt not
dissimilar from the prompt I use on my Linux box, and shows one way
you can get something which looks a bit like a `path' into the prompt.
(MS-DOS users might like to try `%d:\%a>' or `%d:\%b>' for a similar
effect.)


**** BATWARN <0 or 1>

Disables/re-enable low battery warnings. You should use this like
`batwarn 0' to disable battery warnings if you appreciate that the
main batteries are low (for example), but want to carry on without
getting `*** Main batteries are low ***' in your face all the time. Be
careful when doing this, because it's an inherently dangerous thing to
do, and be sure to change the relevant batteries as soon as possible.

**** BDOSDBUG <0 or 1>

Enable (or disable) display of which BDOS function is being called as
it is called. The function number is displayed in hex - for example,
`[0A]' would indicate that the program is reading a line of text from
the console. Enabling this output can be useful when debugging
programs. For various reasons, functions 2 (console output) and 46
(get disk free space) are treated slightly differently from other BDOS
functions, and as a result are not reported on.

**** CAT filename

Display a ^Z-terminated text file from beginning to end, without
pausing. (^C quits.)

(This means it's not a true `cat' command - that is, it doesn't
concatenate files - but simply a synonym for `type'. Still, it's handy
for Unix fans like me. :-))

**** CAPSCTRL <0 or 1>

Disable/enable swapping the functions of the `Caps Lock' and `Control'
keys. (It's off by default - i.e. the keys do what they say they do.)
This option may be useful if you like having a control key above the
left shift key (rather than below it). That said, the `Function' key
always acts like a control key no matter what.

Note that this swaps the functions of the keys at quite a low level -
if you've enabled the key-swapping, then whenever ZCN requires you to
press the physical `Control' key (for screen dumps and for pausing
output) you will *have* to use the `Caps Lock' key instead.

**** CBOOT

Cold boot ZCN from the memory card. If the card is not bootable, or
there's no card in the slot, ZCN will say "Bad crd/drv/format" rather
than booting.

**** CD n

Set current user area to number `n', or to number 255 if `n' is an
asterisk. If `n' is omitted, acts like `cd 0'. This alias for `user'
should make slightly more sense to MS-DOS and Unix users, though the
flat `directory' structure in CP/M makes their `cd' commands a poor
analogy, to be honest. Still, at least it's easier to type, right? :-)

**** CRLF <0 or 1>

Disable (or re-enable) the line-break (CR/LF) after a program exits.
Generally you'll always want this on, but it can be useful to turn it
off temporarily in a SUB file. (An easy way to get a CR/LF should you
need one after `crlf 0' is to use `"' or `vdu 13 10'.) Just make sure
you remember to re-enable it afterwards, or it'll all be a bit
confusing. :-)

Note that this doesn't affect the CR/LF always output after you type
in a command, so the effects of a `crlf 0' may not be immediately
obvious. Doing `ver' should clarify matters.

**** CLS

This clears the screen. (NB: this clears the entire screen, including
the top two and bottom two pixel lines.)

**** DF

Report how much space is free on all available drives. An example of
what the output's like: `A:=2k B:=43k'. (The values will probably be
different for your card.) Only drives which exist on the card are
reported on.

**** DIR [filespec]

List the files in the current drive/user. If a filespec is given, it
only shows files matching the filespec. The wildcards `*' and `?' can
be used. If no file is found/matches, then the error `No file'
results.

`dir' exists primarily for CP/M compatiblity, and so that there's some
internal command to list files - see the `LS' external command for how
to get a much better (sorted, and optionally with file sizes)
directory listing.

**** DUMP filename

Give a hex and ASCII dump of the specified file, pausing after every
128 bytes. Bugs: if the file position is greater than 65535, it'll be
shown incorrectly.

**** ERA (or RM) filespec

The CP/M-style delete command. (ERASE and DELETE are not recognised.)
Delete all files matching the filespec. Bugs: does not prompt when
deleting multiple files, which it should really.

**** FORMAT d:

Format the given drive. Cards of 256k or less are formatted as a
single A: drive. Cards larger than that (512k and 1024k) are formatted
as two 256k logical drives A:/B: or four drives A:/B:/C:/D:
respectively. On these larger cards, the A: drive must formatted in
order to format and use any of the others. (The logical drives are
formatted on an individual basis.) You can reformat one of the logical
drives without harming any others.

So to fully format a card of 256k or less, use `format a:'.

For a 512k card, do `format a:' then `format b:'.

And for 1024k cards, do `format a:', `format b:', `format c:', and
`format d:' in turn.

If the drive is already formatted in ZCN format, you will be asked
whether to reformat it. (It should if the drive is already formatted
in the ROM software's format too, but I haven't tested this.)

**** GET hex_address filename

Load a file in at the specified address (in hex). This is useful for a
variety of things:

- Loading a COM file off one card, then executing it with another in
the slot, e.g. `get 100 foo.com', change cards, then `!!'.

- Patching a COM file after it's loaded. You normally do this by
loading the COM file, then loading a small patch over some part of it.

- Loading a previously saved screen dump, e.g. `get f080 screen.dmp'.

This command makes it easy to crash the machine if you don't know what
you're doing, so be careful, and check your typing. If you miss out
the `1' in `get 100 foo.com', you'll soon know about it. :-)

**** IFNPEEK addr val command [args]

If byte at (hex) `addr' *does not* equal (hex) `val', run command,
otherwise do nothing. This is primarily of use in SUB files.

See `ifpeek' below for details.

**** IFPEEK addr val command [args]

If byte at (hex) `addr' equals (hex) `val', run command, otherwise do
nothing. This is primarily of use in SUB files.

Note that using a print command (' or ") will result in all-caps text,
since ZCN didn't see the command until after the `ifpeek' took place.
This is unfortunate, but there's nothing I can do about it. (It also
applies to the `%' prompt-setting command, but you're much less likely
to want to use that as the command in an `ifpeek'.)

To abort a SUB file if some command goes wrong, use `ifpeek ...
quitsub'. Obviously there has to be a byte in memory which indicates
if the command worked or not!

To check the value of 80h after the last command finished, use 3 as
the `addr'. This is primarily intended to be used to check the exit
status of programs compiled with Hitech C; however, there's no reason
you couldn't use it to return an exit status from your own programs.
If you want to check if a Hitech C command returned a non-zero exit
status - for C programs this usually means it failed somehow - then
use ifnpeek instead, like this: `ifnpeek 3 0 ...'.

The only command which does not have 80h copied after it exits is
`rem'. (The same applies to a blank command-line, of course, but
that's not really a command as such.) *ALL* other commands and
programs have it copied when they exit, whether they change it or not.

**** K3

Show how many K are free. :-) In other words, show the amount of
memory available for running programs in, or the transient program
area (TPA) as CP/M calls it. At the time of writing, this will be 46k.

For any techies out there who may be interested, the number given is
int((bdos_address-512)/1024). 256 of the 512 subtracted is to discount
the zero page, and the other 256 is to allow for stack space. So it's
a realistic estimate of the maximum program size.

**** MEMDUMP address

Show 128 bytes of memory, in hex and ascii, from the address given.
The address should be given in hex.

I consider this command to eliminate the need for a `peek' command,
which you might otherwise expect as a counterpart to `poke'.

**** MORE filename

Essentially, this is `cat' but pausing after every ten lines. In order
to show as much at a time as possible, you aren't prompted to press a
key to continue, as such; instead the cursor is moved to the
bottom-right hand corner of the screen to indicate that there is more
text waiting to be shown. There is no way of moving back through the
file. (^C quits.)

**** NOTE filename

This command lets you type text into a file. (Any existing file will
be overwritten.) There's no editing, and no prompt - it's quite crude,
but being an internal command it is at least always there. You just
keep typing text until you're done, then type in a line consisting
solely of a single `.' (full stop).

Mainly this is handy for those awkward situations where you for some
reason don't have a text editor like ZDE handy, but need to make a
quick note or something like that.

Don't do a ^C to exit - if you do, the text isn't saved (`note' builds
the text up in memory, and saves when you're finished). If you should
do this, though, you could salvage the text with `save', as the text
starts at 0100h.

**** POKE addr val

Set the byte at address `addr' to value `val'. The address and value
must be in hex.

I said this in the description of `get', but it applies equally to
`poke', so I'll repeat it: This command makes it easy to crash the
machine if you don't know what you're doing, so be careful, and check
your typing.

Using the internal commands `get', `poke', `memdump', and `save' is a
bearable way to patch programs and other files if you haven't got a
better way of doing it. (And of course, Real Programmers write all
their programs using `poke'. :-)) However, I recommend using `wade'
for patching programs/files if at all possible.

**** QUITSUB [command [args]]

Abort any currently-running SUB file. This is only useful in SUB
files (of course :-)), and usually only useful in combination with
`ifpeek' or `ifnpeek'. If a command is specified, that command is run
afterwards.

**** REALBEEP <0 or 1>

This disables/enables a real (noisy) beep in place of the `visual'
one. If you like having a real beep you could put `realbeep 1' in
`autoexec.sub' to have it automatically enabled.

**** REM (or #) [any text]

This command does exactly nothing. It allows you to put comments in
SUB files.

**** REN file1 file2

Rename file from file1 to file2. Wildcards are not permitted.

Note that this is *not* the way the command works in CP/M - on that,
the syntax is rather strange, effectively `REN file2=file1' [sic].

**** REXEC filename

This reads a uuencoded file from the serial port, decodes it, and
writes the resulting binary file under the filename given. (It outputs
a `.' for each line received.) The name stands for `Remote EXECute',
as the command used to just execute the (command) file after it was
transferred. That dates back to the time when I was running ZCN with a
16k TPA, a 32k ramdisk, no PCMCIA card and my fingers crossed. :-)
After ZCN stabilised a bit, I changed `rexec' to work as it does now,
which is almost certainly more useful. (In any case, you could get the
old behaviour if you really needed it by removing the card, doing
`rexec foo' (it'll say "No file" but the copy in memory is fine), then
doing `!!'.)

It's intended for getting a real serial transfer program across, such
as QTERM (which I recommend). It won't work (will probably crash!) if
files bigger than TPA are transferred.

**** SAVE n filename

Save `n' pages of memory, starting from 0100h, to file specified. A
page, in the context of this command, is 256 bytes. This is
traditionally used to save COM files after patching, but can be useful
for other things too.

**** SERTEST

A very simple terminal program. It just echoes serial input, and sends
keyboard input to the serial port. This can actually be very, very
useful if you're using your NC100 as a terminal to a Unix box with a
suitable termcap/terminfo entry as given earlier. You can use ^\ then
q (or ^\ then ^C) to quit; ^\ then ^\ sends a literal ^\.

**** SETBAUD [digit] (removed in ZCN v1.2)

In versions of ZCN prior to v1.2, `setbaud' set the baud rate the
serial port ran at, using a single digit (`4' for 2400, `5' for 4800,
`6' for 9600, etc.). It was replaced with the rather less inscrutable
`stty', but for masochists, an emulation of the old `setbaud' is
available in the `utils' directory, as `setbaud.sub'.

**** STAT (removed in ZCN v1.1)

In versions of ZCN prior to v1.1, `stat' gave a few bits of useful
information, for example:

Sys upgrd spc: 15 bytes
Max prog size: 45k
Free on drivs: A:=2k B:=43k

As you may already realise, the second line was replaced by `k3', and
the last line by `df'. (Most people won't miss the first line. :-))

In case there's anyone who misses `stat', or thinks it sounds useful,
I knocked up an external command `stat' (i.e. stat.com) which emulates
it.

(Note for those who want to hack ZCN: `Sys upgrd spc' reported the
amount of unused space between the ZCN system code and the ZCN static
data area (starting at E600h) allowed for upgrading before the origin
(in main.z) has to be moved down. You *can* still get at this number -
it's stored at start+15 (see main.z) - but it's more tricky now. Do
`memdump 7', then do memdump for 256 times the byte displayed there
plus 15; so e.g. for BBh, you'd do `memdump bb0f'. The word there
(though the high byte should always be zero) is the number you want.
It's probably easier to just use stat.com instead... :-))

**** STTY baud_rate

Set baud rate of serial port. The default is 2400 baud. Supported
speeds are 150, 300, 600, 1200, 2400, 4800, 9600, and 19200 baud.

Which baud rate is best to use depends on what equipment you're using,
what you'll be doing, etc. Assuming the `other end' is capable of
anything up to 19200 baud, here are some guidelines:

If you want to do file transfers, you should be able to do so without
losing any packets even at 19200 baud. (If you get too many errors,
use 9600 baud instead - that should definitely work. But I've never
had any problems with 19200.)

If you want to use the `other end' interactively, i.e. if you want to
use a terminal emulator, then you may need to use a lower speed to
avoid losing characters.

Now, consider these facts:

- ZCN has a 768-byte serial input buffer.

- The screen driver can only write characters at a speed of between
  about 110 and 800 chars/sec, depending on line length (i.e. how
  often it needs to scroll). (This is as tested with the built-in
  `sertest' program; with an external program like QTERM there is
  system call overhead, etc.)

- ZCN uses one start bit, 8 data bits and 1 stop bit which means that
  the maximum number of chars/sec you can transfer at a given baud
  rate is baud_rate/10.

If you assume a short line length (which slows things down because of
the more frequent scrolling required), you get these results (I
haven't bothered with speeds lower than 1200 baud; using such speeds
makes watching paint dry seem like a exciting spectator sport):

baud rate   chars/sec   time to first lost character (sec)

 1200       120        768/( 120-110) =  76.80
 2400       240        768/( 240-110) =  5.91
 4800       480        768/( 480-110) =  2.08
 9600       960        768/( 960-110) =  0.90
19200       1920        768/(1920-110) =  0.42

Note that the `time to first lost character' indicates the time to the
first time the buffer is full when a character needs to be added
(which causes a lost character) rather than the time to when the
display catches up and the lost character is noticeable, which may
well be rather longer.

Assuming a more reasonable line length (about 78 chars/line) you end
up with:

baud rate   chars/sec   time to first lost character (sec)

 1200       120        768/( 120-800) =  (never)
 2400       240        768/( 240-800) =  (never)
 4800       480        768/( 480-800) =  (never)
 9600       960        768/( 960-800) =  4.80
19200       1920        768/(1920-800) =  0.69

So, what does this all mean? Well, it depends on how you look at it.
In my experience, 2400 is reliable except in extreme cases (the
extreme case being long bursts of short lines - you need about 1500
bytes of short lines continuously to start losing chars at 2400). 4800
can usually keep up too, though it's more prone to buffer overruns.
You can use higher speeds if you want - they'll work, but you'll lose
characters increasingly frequently as the buffer fills up. Personally,
I just use 19200 the whole time. It's great for file transfers, and
the input buffer can generally handle the bursts of output when I use
it as a terminal at that speed.

One final note: If there's no more than a screen full of text
transmitted at a time - for example, if you're just using an editor on
the remote host - then you can probably get away with using any baud
rate. The reason is, assuming only 80 columns are used and 10 lines,
you get a max of 800 chars per screen refresh (usually less due to
status line(s) etc.), and a single burst of that size can (just
about!) be dealt with every second or two.

**** SYS d:

Add the system to a drive and make it bootable. I recommend you only
make A: drives bootable, as booting from B:, C: or D: means
remembering different, awkwa