Yet Another SHell - a z88dk example

395 views
Skip to first unread message

Phillip Stevens

unread,
Feb 9, 2020, 4:30:14 AM2/9/20
to RC2014-Z80
Wading through documentation is always hard and, to quote the IETF "we believe in rough consensus and running code", I thought that it would be worthwhile building an example which demonstrates many of the capabilities of the z88dk with respect to the RC2014 community, and platform.

The example is a kind of a C shell (Yet Another SHell) that can read an underlying FAT32 (or smaller) file system, and allow you to do a number of things to that file system, such as creating directories, copying and deleting files, and modifying file characteristics.

The program is not a finished, polished, product. But rather it is supposed to demonstrate the following things with running code.
  • Use of C language with no assembly required, invoking the zsdcc and the rest of the z88dk development kit, to produce finished binaries.
  • Use of all of the different subtypes possible for the RC2014 target. Including the ACIA and SIO subtypes for building bare metal ROMs, and the CPM and HBIOS subtypes for use with CP/M and RomWBW.
  • Use of serial input and output to capture commands and output results at a high level using standard C library calls.
  • Installation and usage of the time and ff (ChaN FAT file system) libraries, together with the appropriate diskio library to interface to the hardware or bios API as relevant.
  • An implementation of Stephen Brennan's shell, or at github code in lsh.
To build the example, start off by installing z88dk, using the instructions found here, there, and everywhere.
Then clone or download these z88dk-libraries. From the base directory, install the libraries relevant to the RC2014, including the HBIOS libraries too.

> z88dk-lib +rc2014 time ff

> z88dk-lib +hbios time ff diskio_hbios

Then download the example program, or any other example. And from the same directory you can choose a command line.

> zcc +rc2014 -subtype=acia -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/rc2014/time -llib/rc2014/ff yash.c -o yash -create-app

> zcc +rc2014 -subtype=sio -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/rc2014/time -llib/rc2014/ff yash.c -o yash -create-app

> zcc +rc2014 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/rc2014/time -llib/rc2014/ff yash.c -o yash -create-app

> zcc +rc2014 -subtype=cpm -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/rc2014/time -llib/rc2014/ff yash.c -o yash -create-app

This is for the RC2014 when it has a 82C55 IDE diskio Interface. The output will be written to the first FAT file system found on the drive.
Most likely to be used with CP/M-IDE firmware, but any CPM that supports the standard 82C55 IDE interface will work.
The drive will be seen as Drive 0:

#include <arch/rc2014.h>            /* Declarations of IDE functions */
#include <lib/rc2014/ff.h>          /* Declarations of FatFs API */
#include <arch/rc2014/diskio.h>     /* Declarations of diskio functions */

The following are ONLY needed for the hbios subtype.  To allow buffers to be copied using the hbios api, they have to be located above 0x8000, so this is where the BSS section starts.
A warning is produced should the BSS section need to be moved to prevent clashing with the DATA section (using the #pragma), so watch for warnings to confirm there is no overlap between DATA and BSS sections, and set as needed.

#include <arch/hbios.h>             /* Declarations of HBIOS functions */
#pragma output CRT_ORG_BSS = 0x9000 // move bss origin to address 0x9000

It is also possible to link in the hbios diskio layer and use that to interface to any drive (not just an IDE drive).
The command looks quite similar, except for the extra diskio library that takes precedence over the inbuilt IDE diskio functions.

> zcc +rc2014 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/hbios/time -llib/hbios/diskio_hbios -llib/hbios/ff yash.c -o yash -create-app

#include <arch/rc2014.h>            /* Declarations of IDE functions */
#include <arch/hbios.h>             /* Declarations of HBIOS functions */
#include <lib/hbios/ff.h>           /* Declarations of FatFs API */
#include <lib/hbios/diskio_hbios.h> /* Declarations of diskio functions */
#pragma output CRT_ORG_BSS = 0x9000 // move bss origin to address 0x9000

This is for the RC2014 when it has RomWBW firmware and any type of drive. The drive number is the same as the logical drive number reported on boot.
The program is loaded in the monitor, and started by R100.

Note that relative directories are not working currently for hbios (a limitation of the example code that I've not bothered to fix), so just use the full path.
i.e "mkdir 2:/test", "ls 2:/test", and  "cp 2:/test.bin 2:/test/test2.bin"

If the example were to be extended, it would be possible to copy from multiple volumes (currently only one volume supported), and to move files between FATFS and CP/M, for example.
But today, the program reports the following options.

>R100
> help
yash v1
.0 2020
The following functions are built in:
  md
- [origin] - memory dump
  help
- this is it
 
exit - exit
  mount
[drive:] - mount a FAT file system
  umount
[drive:] - unmount a FAT file system
  ls
[path] - directory listing
  rm
[file] - delete a file
  cp
[src][dest] - copy a file
  cd
[path] - change the current working directory
  pwd
- show the current working directory
  mkdir
[path] - create a new directory
  chmod
[path][attr][mask] - change file or directory attributes
  ds
[drive:] - disk status
  dd
[drive][sector] - disk dump, drive in decimal, sector in decimal
  clock
[timestamp] - set the time (UNIX epoch) 'date +%s'
  tz
[tz] - set timezone (no daylight saving)
  diso
- local time ISO format: 2013-03-23 01:03:52
  date
- local time: Sun Mar 23 01:03:52 2013

>

Hope this sparks interest.

Enjoy

Phillip

Alan Cox

unread,
Feb 9, 2020, 8:29:32 AM2/9/20
to rc201...@googlegroups.com
> The example is a kind of a C shell (Yet Another SHell) that can read an underlying FAT32 (or smaller) file system, and allow you to do a number of things to that file system, such as creating directories, copying and deleting files, and modifying file characteristics.

Add the ability to load and run code from the fat filesystem and some
kind of a call interface and you've just re-invented MSXDOS but in an
open and maintainable form (and MSXDOS could run CP/M apps except a
few that went poking around at BIOS level) 8)

Alan

Phillip Stevens

unread,
Feb 9, 2020, 5:52:59 PM2/9/20
to RC2014-Z80
Alan Cox wrote:
Add the ability to load and run code from the fat filesystem and some kind of a call interface and you've just re-invented MSXDOS  but in an open and maintainable form (and MSXDOS could run CP/M apps except a few that went poking around at BIOS level) 8)

That's a good idea, and a good next step. I was considering it, and I have some load binary and store binary code, but it is tied to specific hardware and making it work with CP/M and HBIOS is not straight forward.

If I'm not mistaken (assuming we're not handling fragmented files), the process would to 1. store a copy of yash on the drive, 2. write a small binary/hex loader into Page 0 somewhere safe, 4. bend RST0 to call the binary loader, 5. call the loader and get it to save where I'm stored. 6. use the loader to load and run the nominated program, which would then exit and would call RST0, and 7. load and run yash. But that's more than a quick quick Sunday afternoon project.

I don't even think a special call interface is necessary, if the CP/M or HBIOS calls could be relied upon. Is that right?
Might have a go at that on the next quiet Sunday.

Phillip

Phillip Stevens

unread,
Sep 29, 2020, 12:28:33 AM9/29/20
to RC2014-Z80
Alan Cox wrote:
Add the ability to load and run code from the fat file system and some kind of a call interface and you've just re-invented MSXDOS  but in an open and maintainable form (and MSXDOS could run CP/M apps except a few that went poking around at BIOS level) 8)

That's a good idea, and a good next step. I was considering it, and I have some load binary and store binary code, but it is tied to specific hardware and making it work with CP/M and HBIOS is not straight forward.
Might have a go at that on the next quiet Sunday.

Well a few quiet Sunday's have gone by, and I've finally made a small interesting step forward with this demonstration shell. I've added the ability to mount CP/M drives from the underlying FATFS file system.

So today using yash from within CP/M it is possible to rename, copy, delete, etc, FATFS files. And if those files are CP/M drive images then they can be mounted on one of the 4 CP/M-IDE drive bays, and then used from CP/M.
That's a tiny bit more comfortable than moving the files around in the monitor, and having to boot CP/M before using XMODEM or similar.

The yash is written in C, and is an extra demonstration application for z88dk.

yash v1.0 2020
The following functions are built in:

  cmount drive
: [path]file - mount a drive
  md
- [origin] - memory dump

  help
- this is it
 
exit - exit
  mount
[drive:] - mount a FAT file system
  umount
[drive:] - unmount a FAT file system
  ls
[path] - directory listing
  rm
[file] - delete a file
  cp
[src][dest] - copy a file
  cd
[path] - change the current working directory
  pwd
- show the current working directory
  mkdir
[path] - create a new directory
  chmod
[path][attr][mask] - change file or directory attributes
  ds
[drive:] - disk status
  dd
[drive][sector] - disk dump, drive in decimal, sector in decimal

This works because the CP/M-IDE maintains a table of LBA for the 4 drive bays. To mount a new CP/M drive (file) the correct new base LBA just needs to be entered into the table.
Other CP/M ports will need to have their drive references correctly entered, for this to work too.

It works like this...

RC2014 CP/M-IDE
feilipu
2020

> :? :-)

> cpm sys.cpm user.cpm
Opening "sys.cpm" at LBA 149384
Opening "user.cpm" at LBA 198536
Initialised CP/M

A
>dir

A
: ASM      COM : CAL      COM : DDIR     COM : DDT      COM
A
: DUMP     COM : ED       COM : ERASE    SUB : FULLPRMP SUB
A
: INFO     COM : KERMIT   COM : LOAD     COM : LS       COM
A
: LUA      COM : LU       COM : MAC      COM : MBASIC   COM
A
: MLOAD    COM : MOVCPM   COM : NORMPRMP SUB : NSWP     COM
A
: PIP      COM : SD       COM : SH       COM : SH       OVR
A
: SHSAVE   COM : STAT     COM : SUBMIT   COM : SURVEY   COM
A
: SYSGEN   COM : TE       COM : UNARC    COM : UNCR     COM
A
: USQ      COM : XMODEM   COM : XSUB     COM : Z80ASM   COM
A
: ZEXALL   COM : ZEXDOC   COM : ZSID     COM : ZTRAN    COM
A
: CP       COM : YASH     COM : PI-32    COM : PI-9511  COM
A
>yash

> ls
----A 2020/04/27 19:55   8388608  BBCBASIC.CPM
----A 2020/04/27 19:55   8388608  HITECHC.CPM
----A 2020/04/27 19:55   8388608  MSBASCOM.CPM
----A 2020/04/27 19:55   8388608  MSCOBOL.CPM
----A 2020/01/01 00:00     65536  MULTHI.BIN
----A 2020/01/01 00:00     65536  MULTLO.BIN
----A 2020/05/13 18:03   8388608  NZCOM.CPM
----A 2020/04/27 19:55   8388608  NZSYS.CPM
----A 2020/05/10 21:04   8388608  PLI.CPM
----A 2020/05/10 21:05   8388608  PLISRC.CPM
----A 2020/05/03 14:18   1048576  RANDOM1.TXT
----A 2020/04/27 19:55   8388608  SYS.CPM
----A 2020/04/27 19:55   8388608  TEMPLATE.CPM
----A 2020/05/10 22:03   8388608  UNDRSTND.CPM
----A 2020/04/28 17:22   8388608  USER.CPM
----A 2020/04/28 17:22   8388608  USER2.CPM
----A 2020/04/28 17:22   8388608  USER3.CPM
----A 2020/04/27 19:55   8388608  ZORK.CPM
 
18 File(s), 127008768 bytes total
   
0 Dir(s), 1908469760 bytes free

> cmount c pli.cpm
Mounting "pli.cpm" on c: at LBA 114568

> cmount d msbascom.cpm
Mounting "msbascom.cpm" on d: at LBA 48776

> exit

A
>d:
D
>dir

D
: BASCOM2  HLP : BASCOM   COM : BASCOM   HLP : BASLIB   REL
D
: BRUN     COM : CREF80   COM : CREF     COM : D        COM
D
: L80      COM : LIB80    COM : M80      COM : MBASIC   COM
D
: OBSLIB   REL : RANTEST  ASC : RANTEST  BAS : RANTEST  COM
D
: RANTEST  REL : SAMPLE   BAS : COLOUR   BAS : COLOUR   PRN
D
: BCLOAD       : COLOUR   REL : COLOUR   COM
D
>

Cheers, Phillip

Phillip Stevens

unread,
Dec 1, 2020, 10:36:13 PM12/1/20
to RC2014-Z80
Phillip Stevens wrote:
Well a few quiet Sunday's have gone by, and I've finally made a small interesting step forward with this demonstration shell. I've added the ability to mount CP/M drives from the underlying FATFS file system.

So today using yash from within CP/M it is possible to rename, copy, delete, etc, FATFS files. And if those files are CP/M drive images then they can be mounted on one of the 4 CP/M-IDE drive bays, and then used from CP/M.
That's a tiny bit more comfortable than moving the files around in the monitor, and having to boot CP/M before using XMODEM or similar.

The yash is written in C, and is an extra demonstration application for z88dk.
Cheers, Phillip

A bit of time has passed since Richard suggested to add a "mv" command to yash. Anyway, it is done now.

The "mv" command will enable a FAT file to be moved to another directory, and / or more commonly to be renamed, from within CP/M. The "mv" command doesn't rewrite the file (like the "cp" command), but rather just changes its linkage in the FAT directory structure. This makes it quite fast for large files.


Cheers,
 

Richard Deane

unread,
Dec 2, 2020, 5:53:43 AM12/2/20
to rc201...@googlegroups.com
Thank you Phillip, I look forward to trying it. Sounds like a very usable tool for your IDE flavour of CP/M
Richard 

--
You received this message because you are subscribed to the Google Groups "RC2014-Z80" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rc2014-z80+...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/rc2014-z80/0fd5f187-2a65-4d40-b324-c789981413c2n%40googlegroups.com.

J.B. Langston

unread,
Dec 2, 2020, 11:36:02 AM12/2/20
to RC2014-Z80
You could probably make use of my code from z80ctrl to allow CP/M programs to run and access files directly from the FAT filesystem.  In the case of z80ctrl it's running on the AVR using a DMA mailbox with the Z80 but there's no reason with z88dk that it couldn't run directly on the Z80... https://github.com/jblang/z80ctrl/blob/master/firmware/bdosemu.c

J.B. Langston

unread,
Dec 2, 2020, 12:02:12 PM12/2/20
to RC2014-Z80
A few more missing pieces:

Here is the code that loads and prepares the program to run: https://github.com/jblang/z80ctrl/blob/master/firmware/cli.c#L1501-L1531

And this is the BDOS/BIOS stub that runs on the Z80: https://github.com/jblang/z80ctrl/blob/master/examples/bdos.asm

On z80ctrl's BDOS emulation, the character I/O functions still run directly on the Z80 and send characters to emulated UART ports since using the DMA interface for single-byte transfers would have introduced too much overhead.  

Jeff Greer

unread,
Dec 2, 2020, 12:46:23 PM12/2/20
to rc201...@googlegroups.com
I purchased a z80ctrl kit via Tindie in January 2019. The board is labeled Rev. 4. with MightyCore v2.0.1 boot loader.

I am just now getting around to building this kit. Should I just order a new version of this kit or can I upgrade to the newer version?

Thank you,
v/r
Jeff

--
You received this message because you are subscribed to the Google Groups "RC2014-Z80" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rc2014-z80+...@googlegroups.com.

J.B. Langston

unread,
Dec 2, 2020, 1:01:13 PM12/2/20
to RC2014-Z80
You don't need a new board. The latest firmware still works with REV3 thru REV6.

You received this message because you are subscribed to a topic in the Google Groups "RC2014-Z80" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rc2014-z80/FIw9F8fNnIo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rc2014-z80+...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/rc2014-z80/CALnunYKQj3D1%3DwP1kvA0AR78gShNSz34SGg5BdyuuAv9iqHH5A%40mail.gmail.com.

Jeff Greer

unread,
Dec 2, 2020, 1:17:27 PM12/2/20
to rc201...@googlegroups.com

Phillip Stevens

unread,
Dec 3, 2020, 6:30:23 PM12/3/20
to RC2014-Z80
J.B. Langston wrote:
You could probably make use of my code from z80ctrl to allow CP/M programs to run and access files directly from the FAT filesystem.  In the case of z80ctrl it's running on the AVR using a DMA mailbox with the Z80 but there's no reason with z88dk that it couldn't run directly on the Z80... https://github.com/jblang/z80ctrl/blob/master/firmware/bdosemu.c

Phillip Stevens wrote:
Well a few quiet Sunday's have gone by, and I've finally made a small interesting step forward with this demonstration shell. I've added the ability to mount CP/M drives from the underlying FATFS file system.
The yash is written in C, and is an extra demonstration application for z88dk.

Hi JB,
thanks that would get close to what Alan mentioned previously, the MSX platform.
It is off topic for this thread, but I can see most of the CP/M systems we have here along a "vector" of FAT file system compliance.
It would be (imho) quite an interesting project to build the missing link system.

LEAST FAT
Grant's CP/M - supports 16 fixed drive slices on a Flash card.
RomWBW - supports 16 fixed drive slices on multiple drives. Has access to a FAT file system on remaining disk capacity through FAT.COM.
CP/M-IDE - supports 4 freely selectable "CP/M drives" from an underlying FAT file system. Contents of "CP/M drives" can be modified outside CP/M by cpmtools, but not by non CP/M OS.
z80ctrl - supports freely selectable CP/M drives from AVR based FAT file system and hardware. Uses the file image format from Schorn Altair emulator from an underlying FAT file system.
THE MISSING LINK - a CP/M system supporting FAT directories as CP/M drives. Contents of the FAT directories can be read and manipulated by non CP/M OS.
MSX - MSX OS emulating CP/M applications running on FAT file system.
MOST FAT

Cheers, Phillip

J.B. Langston

unread,
Dec 3, 2020, 6:34:32 PM12/3/20
to RC2014-Z80
I intend to make z80ctrl so that multiple directories can be mapped to CP/M drive letters, but I haven't gotten around to it yet.

--
You received this message because you are subscribed to a topic in the Google Groups "RC2014-Z80" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/rc2014-z80/FIw9F8fNnIo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to rc2014-z80+...@googlegroups.com.

Phillip Stevens

unread,
Oct 23, 2022, 11:30:40 PM10/23/22
to RC2014-Z80
 Phillip wrote:
Well a few quiet Sunday's have gone by, and I've finally made a small interesting step forward with this demonstration shell. I've added the ability to mount CP/M drives from the underlying FATFS file system.

So today using yash from within CP/M it is possible to rename, copy, delete, etc, FATFS files. And if those files are CP/M drive images then they can be mounted on one of the 4 CP/M-IDE drive bays, and then used from CP/M.

The yash is written in C, and is an extra demonstration application for z88dk.
A bit of time has passed since Richard suggested to add a "mv" command to yash. Anyway, it is done now.
The "mv" command will enable a FAT file to be moved to another directory, and / or more commonly to be renamed, from within CP/M. The "mv" command doesn't rewrite the file (like the "cp" command), but rather just changes its linkage in the FAT directory structure. This makes it quite fast for large files.

Finally got around 'tuit and added a mkdrv command to yash.

This means the the CP/M-IDE drive template file is now almost irrelevant, as any number of new CP/M drive files can be created and then mounted from within CP/M-IDE.

mkdrv mydrive.cpm  to create the drive. There are options to create non-standard numbers of directory extents or file size (which can be ignored).
frag mydrive.cpm to check that the file was not created fragmented. This is an optional one time check, if it makes you feel happy.
dmount d mydrive.cpm to mount the new drive on a new CP/M drive letter. You can overwrite an existing mounted drive to "swap" drives, and ^C to log-in the new drive.

Anyway, this should make life easier for anyone using CP/M-IDE.
Don't know why I didn't do it previously.

Cheers, Phillip
Reply all
Reply to author
Forward
0 new messages