nc100em - an Amstrad NC100/NC150/NC200 emulator
dnc100em/gnc100em/tnc100em/xnc100em [-125ahimpsw] [-r rate] [-S scale] [file_to_boot.bin]
nc100em is an Amstrad NC100/NC150/NC200 emulator. There are these versions:
dnc100em - an
SDL2-based version
xnc100em - an Xlib-based version for X
gnc100em - a GTK2-based version for X
tnc100em - a tty-based version
All versions apart from tnc100em can run both Amstrad’s ROM software and ZCN, my free CP/M-like OS. (The tty version can only run ZCN.) ZCN is available from https://zgedneil.nfshost.com/zcn.html .
(If you’re new to nc100em and wondering how to get it going, see the SETTING UP NC100EM section below.)
-1 |
emulate an NC100. This is the usual default. | ||
-2 |
emulate an NC200. This is the default if the emulator’s command name ends in ’200em’. | ||
-5 |
emulate an NC150. This is the default if the emulator’s command name ends in ’150em’. The NC150 support is experimental and is likely to be somewhat inaccurate, and may be difficult to use. | ||
-a |
enable audio (sound) support, if it was enabled at compile time (it isn’t by default). Not usually worth bothering with, it’s not often used for anything more than a beep (and even those are rare). The emulation is approximate at best. | ||
-h |
gives help on command line options. | ||
-i |
invert graphics (swap black and white). | ||
-m |
modify ’colour’ key messages in (real) ROM (no effect when using the builtin ROM), to make them more understandable when using nc100em. For example, "YELLOW & RED" is changed to "INSERT & LEFT". This only works when in NC100 mode using a UK ROM. | ||
-p |
use the builtin PD ROM even if e.g. ~/nc100/nc100.rom is present. Can be useful when booting a file. | ||
-r |
specifies how often the screen is redrawn, measured in (10ms) interrupts. A setting of 2 would redraw every 20ms (50 times per second), 4 would redraw every 40ms, etc. The default setting is 1 in all versions. (Even tnc100em lets you set a refresh rate, but it is ignored.) | ||
-s |
enable emulated serial I/O on stdin/stdout. Only relevant to the X versions, it’s always enabled in tnc100em. | ||
-S |
set initial pixel scaling factor in range 1 to 16. This only has an effect when running dnc100em or gnc100em, when it sets how much the NC100 screen is initially scaled up. The default is 3. | ||
-w |
wait for two seconds before starting the Z80, to give you time to hold down a few keys (for resets etc.). |
file_to_boot.bin
specifies a file to be loaded into memory at 100h and booted. This only works if you’re using the builtin PD ROM (you get an error message if not).
Most aspects of the NC100 are emulated, including context-saving, memory cards, the serial port, and the parallel (printer) port. (Sound is not normally emulated.)
You’ll probably want to disable auto-power-off, as this isn’t really what you want when running an emulator. :-)
The emulated NC100’s CPU runs at 4.606MHz, and only uses as much host CPU time as it needs to do this. If it can’t run in real-time (not likely nowadays), then it slows down interrupts to match so that the emulated NC100 won’t be affected. (However, the real-time clock always reports real time, so clock programs may act oddly at slow speeds.)
The parallel (printer) port is emulated in a quite straightforward fashion. If the NC100 outputs anything to the printer, this output is appended (verbatim) to the file ~/nc100/printout.dat, which is created if it doesn’t already exist. Note that if you’re printing from the ROM software’s word processor and have the ’Simple’ printer type selected, printout is sometimes preceded by a NUL (zero) byte. But this doesn’t seem to be a bug in nc100em - that NUL really is being sent to the printer! So watch out for that when treating the output as a plain text file.
The serial port is always emulated on tnc100em, but on the other versions must be enabled with ’-s’. If enabled, it’s hooked up to the emulator’s standard input/output. If you’re using ZCN it can be handy to then redirect output to the serial port with ’|s’, so (if you ran nc100em from a terminal emulator) you effectively have text and graphics windows. :-)
tnc100em (the tty version) is a little strange, so some discussion of that is needed here. The way it works is as above - the emulated serial port is hooked up to stdin/stdout. When it starts up, tnc100em emulates both shifts being held for a short while, then types ’|s’ then enter. If you’re running ZCN, this is enough to reboot and redirect console I/O to the serial port. Obviously, this only works with ZCN!
As of ZCN 1.2 you can exit tnc100em with the ’off’ command. With earlier versions, or if a program crashes, you’ll have to kill tnc100em off by hand with something like ’killall tnc100em’ from another terminal.
Note that the RAM is never saved when using tnc100em, to avoid possible problems with the output having been redirected to the serial port.
The NC150 is very simplistically emulated, as literally just an NC100 with 512k ROM and 128k RAM like the NC200 has. The emulator will probably lack a sensible keyboard layout mapping in many cases, if nothing else. I recommend emulating either the NC100 or NC200 in preference to the NC150, unless you have a particular need to try emulating it.
The NC200 emulation is comparable to that of the NC100.
The main addition for the NC200 is the floppy disk drive emulation. This is experimental, and only supported if the ’lib765’ library was installed when nc100em was compiled (if the ROM software complains about batteries being too low to use the drive, it wasn’t). It works on the disk image ~/nc100/nc200.dsk, which is created as a blank unformatted image if it doesn’t exist. Be sure to format any newly-created disk image before using it. (And much as with the memory card, there is no way to change disks while nc100em is running.)
The disk image is stored in CPCEMU .dsk format, while the actual disk data itself will be in MS-DOS format, if formatted by the ROM software. One way to convert the nc200.dsk file to a "raw" file - which can e.g. be directly mounted by Linux, or used with things like dosbox, QEMU, and mtools - is to use the "dskconv" tool from more recent versions of libdsk, like this:
dskconv -format pcw720 -itype dsk nc200.dsk -otype raw disk.raw
And to convert the other way, you could do this:
dskconv -format pcw720 -itype raw disk.raw -otype dsk nc200.dsk
To mount a raw disk image in dosbox for example, run dosbox with "dosbox ." or similar then at the prompt type:
imgmount -size 512,9,2,80 a: disk.raw
The contents should then be available on the A: drive, and files can be copied to/from the C: drive (i.e. the current directory) using DOS commands like COPY.
This section covers setting up for NC100 emulation; for NC150 and NC200 details, see NC150 SETUP and NC200 SETUP.
The first thing to do is run ’makencmemcard’ to make a 1024k memory card image. You don’t have to do this, but the NC is generally a lot nicer to use with a memory card. Also, you may need one to run ZCN. :-)
Having got that out of the way, there are three main ways to use nc100em - using ZCN with the builtin PD ROM, using ZCN with the Amstrad ROM, or using the ROM software with the Amstrad ROM.
ZCN with the
builtin ROM
Just run it with (e.g.) ’dnc100em zcn.bin’,
where zcn.bin is from the bin directory in the
ZCN distribution. (Note that zcn.bin is read as a
normal file from the usual Unix filesystem, not from the
memory card image!) This boots ZCN. If you use F10 (or
gnc100em’s ’Exit nicely’ button) to exit
(which saves context), you shouldn’t need to run it
with ’zcn.bin’ specified again unless you want
to cold-boot.
Once you’ve booted ZCN for the first time, go through doc/zcn.txt in the ZCN distribution. You’ll probably want to skip most of the installation stuff. ’Installation epilogue’ is a good place to stop skipping. For reference, your ’memory card’ is 1024k, and you’ll want to format drives a:, b:, c: and d:.
To transfer files to/from the memory card image, use ’cpmtools’ with the ZCN formats zcna_boot, zcna_nonboot, zcnb, zcnc, and/or zcnd as appropriate. See the USING CPMTOOLS section below, and the cpmls, cpmcp, and cpmrm man pages for details. You should exit any running emulator before using cpmtools.
Note that anything in ZCN which requires the Amstrad ROM is bound to have problems with the builtin ROM (see below).
ZCN with the
Amstrad ROM
There are some limited benefits to running ZCN with the real
ROM - if you want bbcbas, bbcmin, calc, rrxfer, runrom,
spell, or spellwd to work, you must use the real ROM
(and mostly the one from the UK NC100, at least for ZCN
1.3). Most of them will crash horribly without it.
Just make sure you stick with one ROM or the other - the context-saving works slightly differently with each. If you really want to switch ROMs, then (for a builtin to Amstrad ROM switch) delete ~/nc100/nc100.ram, or (for an Amstrad to builtin ROM switch) cold-boot as described above.
From ZCN 1.4, ZCN should come with preinstalled memory card images - in this case you could just copy nc100.card and your ROM file to ~/nc100 then do Function-X (Insert-X) to boot, as below.
For ZCN 1.3, things are rather more complicated than with the builtin ROM, but here’s a guide:
First, boot ZCN with (e.g.) ’dnc100em -p zcn.bin’. Then do ’format a:’ then ’sys a:’ to initialise the memory card (you should also format the b:/c:/d: drives). Now quit the emulator, remove any ~/nc100/nc100.ram as we’re about to switch ROMs, and make sure that the nc100.rom you transferred with romdump (if you haven’t done that yet, do it now) is in ~/nc100.
Now do plain ’dnc100em’ (i.e. no args); you should get the ROM software’s main menu screen. Do ’Function-X’ (by doing Insert-X, using Insert like a shift key), which should finally boot ZCN. Quit with F10, and that should save context so you won’t have to do the ’Function-X’ next time.
Yep, sure is easy when you know how (cough, splutter). :-)
ROM software
with the Amstrad ROM
This is easy enough - just get the 256k of ROM across from
your NC100 with romdump (this takes a while...) as
~/nc100/nc100.rom, then run nc100em. The only problem
is, there’s no direct way to transfer files to/from
the ROM software. (You could print files to get them out,
which does work, but isn’t that great and only
transfers files one way.)
If you’re prepared to run ZCN, at least for file transfer, you could use its ’runrom’ and ’rrxfer’ programs to transfer files to the ROM OS. This would be painfully indirect, but should work.
For NC150, do the same as for NC100 above but with ~/nc100/nc150.* and, if available, zcn150.bin. Make sure to run nc100em with the ’-5’ option.
For NC200, do the same as for NC100 above but with ~/nc100/nc200.* and zcn200.bin. Make sure to run nc100em with the ’-2’ option.
For the ROM OS, you have the option of using the emulated floppy disk to transfer files, with e.g. libdsk’s dskconv and dosbox (as described in NC200 SUPPORT above).
F10 |
quit [dgx]nc100em by causing an NMI/interrupt, just like pressing the power on/off button on a real NC100/NC150/NC200. I recommend you use this to exit. Your GUI’s ’close window’ button (or menu option) should also have this effect, as will gnc100em’s ’Exit nicely (NMI)’ button. | ||
F5 |
does the same as F10 (for ’compatibility’ with previous versions). | ||
F8 |
quit [dgx]nc100em by just stopping dead. This doesn’t cause an NMI, and the RAM isn’t saved. Useful if the emulated NC crashes, as in that case an NMI may not be enough to exit. (The gnc100em ’Abrupt stop’ button also has this effect.) |
In gnc100em,
the display is scrollable so you can use a window smaller
than the NC’s display, should you want to. This can be
useful when you’re using a scaled-up display. There
are also two buttons in this version which have yet to be
mentioned:
Scale down
scale the NC screen down, so the display is smaller.
Scale up
No prizes for guessing what this does.
Those keys
which also exist on the NC are mapped as-is, with other
mapped keys being:
Alt/Meta
emulated as Symbol
Backspace
emulated as ’<-Del’
Delete |
also emulated as ’<-Del’ (see below) |
|||
End |
emulated as ’Del->’ |
|||
’ |
emulated as Menu |
|||
Esc |
emulated as Stop |
|||
Home |
emulated as Backslash (see below) |
Insert/F1
emulated as Function
Any extra modifier keys you have will probably act as Function too.
The SDL2 version should do the best job with keyboard mapping in general - it works with "scancodes" which should be based on the physical keyboard layout, giving the best possible chance of just passing keypresses to the emulated NC relatively intact, however they happen to be mapped on your OS/GUI. Any remaining mapping should depend solely on the emulated NC’s ROM, or ZCN’s configuration.
On the other versions, some of the mappings are probably still assuming a UK keyboard layout unfortunately, and some keys may be inaccessible on other layouts.
As shown above, both Backspace and Delete are actually mapped to ’<-Del’. This is a bit dubious, but saves trouble with certain setups (like on Linux, which commonly follows the traditional PC approach). The ’Del->’ key is available on End.
On e.g. US (ANSI) or Japanese (JIS) keyboards, the NC’s Backslash key may not normally be available in a conventional manner, so it’s also available on Home. Note that some NC ROMs actually map this key to less-than.
The ROM software refers to certain keys by the names Yellow, Red, Green, Blue, and White. In nc100em these are available as follows:
Yellow |
Insert |
|||
Red |
Cursor left |
|||
Green |
Cursor right |
|||
Blue |
Cursor down |
|||
White |
Cursor up |
You can use cpmtools (e.g. cpmls, cpmcp, cpmrm) to access drives on a memory card image in ZCN format. Some NC100 examples follow.
List files on bootable A: drive, also showing disk space used/left:
cpmls -D -f zcna_boot ~/nc100/nc100.card
Copy a file to bootable A: drive:
cpmcp -f zcna_boot ~/nc100/nc100.card foo.com 0:
Copy *.com to B: drive:
cpmcp -f zcnb ~/nc100/nc100.card *.com 0:
Copy all files from C: drive to current directory (note the quoting):
cpmcp -f zcnc ~/nc100/nc100.card 0:’*.*’ .
Delete wibble.txt on D: drive:
cpmrm -f zcnd ~/nc100/nc100.card wibble.txt
Show free space on all drives:
for i in a_boot
b c d; do
cpmls -D -f zcn$i ~/nc100/nc100.card|grep Free;done
Note that usually, you’ll want to use zcna_boot to access the A: drive. However, if you have a non-bootable A: drive formatted by ZCN 1.3 or earlier, you should use zcna_nonboot instead.
zcnb/zcnc/zcnd are for the usual B:/C:/D: drives, which must be non-bootable for the definitions to work.
While I contributed diskdefs entries for cpmtools, you may find you have to add them to the diskdefs file in e.g. /usr/local/share/cpmtools or perhaps /etc/cpmtools yourself, by adding the text below to the end of the file.
diskdef
zcna_boot
seclen 1024
tracks 256
sectrk 1
blocksize 1024
maxdir 64
skew 0
boottrk 13
os 2.2
end
diskdef
zcna_nonboot
seclen 1024
tracks 256
sectrk 1
blocksize 1024
maxdir 64
skew 0
boottrk 1
os 2.2
end
diskdef zcnb
seclen 1024
tracks 256
sectrk 1
blocksize 1024
maxdir 64
skew 0
boottrk 1
os 2.2
offset 256KB
end
diskdef zcnc
seclen 1024
tracks 256
sectrk 1
blocksize 1024
maxdir 64
skew 0
boottrk 1
os 2.2
offset 512KB
end
diskdef zcnd
seclen 1024
tracks 256
sectrk 1
blocksize 1024
maxdir 64
skew 0
boottrk 1
os 2.2
offset 768KB
end
The files
mentioned below are assumed to be in ~/nc100 by default, but
their location can be changed by setting the
NC100EM_HOME environment variable to the preferred
path. When run, nc100em will create this dir if it
doesn’t yet exist.
~/nc100/nc100.rom
this should be a copy of Amstrad’s NC100 ROM. If not present, a builtin PD ROM is used instead; this is only capable of running ZCN, though.
~/nc100/nc100.ram
the NC100’s RAM. This is saved when the ROM turns off the emulated NC100. If this is not present when the emulator starts up, blank RAM is used instead.
~/nc100/nc100.card
the PCMCIA memory card image. If not present, no card is present in the emulated NC100. The size should be a multiple of 16k, and it should be no larger than 1024k. (You can use ’makencmemcard’ to make a blank 1024k memory card image.)
~/nc100/printout.dat
if the emulated NC100 prints anything, it’s appended to this file (which is created if not already present).
~/nc100/nc200.*
when running in NC200 mode, the various files which start with nc100 are no longer used; instead, nc200-prefixed filenames are used, such as nc200.card. These files remain in ~/nc100, though (confusingly :-)).
~/nc100/nc150.*
as above, but for NC150 mode.
~/nc100/nc200.dsk
if floppy disk emulation is supported (i.e. ’lib765’ was installed when nc100em was compiled), this is the NC200’s floppy disk image. It’s created as an unformatted disk image if absent, which can then be formatted from the ROM software.
Probably too much of a UK bias, particularly in the non-SDL2 versions.
The SDL2 version is probably slower than it could be.
The NC200 floppy disk support has IRQ-related issues, and the current ugly workaround is probably only good enough to get the ROM software working.
The serial support can’t easily be used for file transfer. Serial file transfers are technically possible via e.g. C-Kermit, but the setup is fairly involved and I wouldn’t recommend doing this in general.
makencmemcard(1), cpmcp(1), cpmls(1), cpmrm(1)
doc/zcn.txt in the ZCN distribution.
Russell Marks.
The Z80 emulation is largely as written by Ian Collier, for xz80.
NC200 floppy disk support uses John Elliott’s ’lib765’ library.