View Full Version : Bootstrapping KERMIT onto CP/M-86

November 12th, 2016, 01:22 PM
Don't know if anyone has any ideas here... I'm trying to bootstrap some form of comms program onto my Victor 9000 under CP/M (I have MS-DOS comms working fine, but you can't copy from dos to CP/M on this system so far as I can tell!)

I've found the cp/m-86 kermit archive, but I think I'm going to need ASM86 to do anything with it...

All I've got is PIP and MS BASIC 5.2 :-/

All thoughts gratefully received!

November 12th, 2016, 04:19 PM
There is always PIPMODEM.ASM & PIPMODEM.DOC,and MBOOT3.ASM. Plus, you can patch PIP (PIPIO) to be able to transfer smaller
programs, or small blocks of code, and then mload several to create the *.COM file. Are you wanting Kermit or Modem7 or xxxx,
which will depend on your RS-232 Hardware and Driver. If you know which USART the machine has you might not have to write a

I sent you a PM, so lets start there and go forward. I need to know a bit more information on the Victor 9000.


34284 34285

November 12th, 2016, 10:54 PM
Replied to PM - the problem we have here is nothing else can write the disks, and I don't have DDT86 or ASM86 :? There's a kermit version for the victor 9000, so that's probably the easiest thing to get working in the first instance.

November 13th, 2016, 12:57 AM
Hi drdanj

Step 0: Prerequisites
Bootstrapping Kermit is fairly easy (but time consuming) if you have certain prerequisites in place:

Target machine that boots CP/M, has RS232 port, PIP.COM and LOAD.COM and has a configuration program for the serial port.
PC with a serial port and terminal emulator such as Hyperterm or Teraterm.
Null modem cable to connect PC and target machines with the right plugs on each end.
A copy of the files CPSKER.HEX and the customisation file for the target machine - find them here: http://www.z80.eu/kermit.html. I see nothing for a Victor 9000 there, so you should try the CPVGEN.HEX file.
A copy of the file MLOAD.HEX from ftp://kermit.columbia.edu/kermit/a

I will assume you have these already.

Step 1: Set up basic serial coms
Connect the machines together using the null modem cable. Go into the terminal program and set the serial port to 300 baud, 8 bits, no parity, 1 stop bit, no handshake. Set the terminal to local echo. On the target machine, launch the configuration program and set the serial port to match.

Now let's do a little test. On the target machine, enter the command pip a:test.txt=rdr:[e] . This launches pip and listens to the rdr: device, which is normally configured as the serial port. Nothing will happen and that's because it's waiting for serial data. Switch to the PC and (in the terminal program) open the connection you configured and enter some text in the window. Any ASCII will do. You should see the characters appearing on the screen of the target machine, because we specified "eho" option in the pip command (that's the [e] part of the command). After doing this, type ^Z (CRTL-Z) and you should hear disk activity on the target machine. Pip is writing the text you entered to the file. Check the file is correct by entering type test.txt on the target. You should see the same text you entered appear on the screen.

Step 2: Determine the size of PIP's file buffer
During the test of Step 1, you transferred text to the target and created a file copy. We need to do this for CPSKER.HEX and the customisation file (which I will call CPVGEN.HEX during this description). However, there is a problem. When pip receives a file from the serial port, it copies the data into a buffer which, when full, is written to the output file. While it is doing this, it isn't listening to the serial port, and so it misses any data sent while it is writing to the file. This is bad! So, we need to do some experiments to work out how much data it can receive into its buffer before having to write to the file. The easy way to do this is to send CPSKER.HEX to it, and examine the file on the target to see where the break occurs. This is easy because hex files have what looks like a line number at the start of each line (it's really an address for the line).


On the target, enter pip tst.txt:=rdr:[e]
On the PC, open CPSKER.TXT in a text editor like notepad.exe and copy the entire file to the clipboard, then switch to the terminal program and paste it.
You should see the hex file on the target machine window. There should be clear lines with carriage returns. If you do not see these, and it is just filling the whole screen with no line ends, you will need to set the terminal options to send CR with every linefeed, and try again.
You should hear the occasional disk activity on the target. Wait until the text stops scrolling on its screen. This should be becasue the data has all been sent. Go back to the PC terminal program and type a ^Z (CTRL-Z). You should hear disk activity on the target again.
Now let's see what we have. On the target, enter type test.txt. Be ready with ^S - this pauses the screen, and restarts it. Watch the address counter at the start of each line, you will see it incrementing. You are looking for a gap, or sudden jump in the number (it's hexadecimal so will have A B C D E F as well as 0-9). When you see it, hit ^S and take note of the highest value before the jump. Round it down to the nearest 00.

So, we have a point at which pip's buffer is full. We can reliably transfer that much text over the serial line with no handshaking.

Step 3: Transfer the hex files
In order to transfer CPSKER.HEX to the target, we need to chop it up into segments that are small enough to fit into pip's file buffer, then send it a piece at a time. Go back to the text editor on the PC and locate the line that has the address we determined in Step 2. Cut the text from the start of the file to this line. Now:

On the target, enter pip C1.HEX:=rdr:[e]
On the PC, paste the cut portion of CPSKER.HEX into the terminal program.
Wait for the text to stop appearing on the target screen
Type ^Z on the PC's terminal program. You should hear disk activity on the target.
Look at the next line in the PC editor (should be the first line as you cut the last segment) and add the buffer size value to its address.
Locate the line with that address and cut from the start of the file to that line.

Repeat these steps, adding 1 to the file name Cn.HEX each time. When you have sent all the CPSKER.HEX file, you will have a set of text files on the target called Cn.HEX, where n starts at 1 and goes up to the number of times you had to repeat the process. On the Model II I had 9 of these files.

To transfer CPVGEN.HEX and MLOAD.HEX, you should be able to do each in one segment. Open it in the PC's text editor and look at the last lines. Note the address indicator. Hopefully it is lower than the value we determined in step 2. If so just copy the file across in one go: on the target, enter pip CPVGEN.HEX:=rdr:[e], then on the PC in notepad, copy the entire file into the terminal program. As before, wait until it stops scrolling on the target display, and enter a ^Z on the terminal. If you find that the file is too big, you will have to use the segmented transfer approach you used to copy CPSKEL.HEX across. Repeat for MLOAD.HEX.

Step 4. Combine the files on the target.
So, we have a bunch of files on the target that together comprise the CPSKER.HEX file, plus one file that is the customisation file. We need to combine all these files into one, and to do this we are once again going to use our best mate pip. Like this:

On the target, enter pip CPSKER.HEX:=C1.HEX,C2.HEX,C3.HEX,C4.HEX,C5.HEX,C6. HEX - add or remove Cn.HEX files according to how many you have. The main point is they are all there and in the correct order.
On the PC, paste the cut portion of CPSKEL.HEX into the terminal program.
Wait for the text to stop appearing on the target screen
Type ^Z on the PC's terminal program. You should hear disk activity on the target.
Look at the next line in the PC editor (should be the first line as you cut the last segment) and add the buffer size value to its address.
Locate the line with that address and cut from the start of the file to that line.

Step 5 - Combine the hex files into executables
By this point you should have a copies of CPSKER.HEX, CPVGEN.HEX and MLOAD.HEX on the target. Now we need to turn them into executables, and according to the instructions on the Kermit page I linked to at the start of this post, you need to use MLOAD.COM, so...

On the target, issue the command load mload.hex - this will read MLOAD.HEX and write MLOAD.COM.
Now, to create KERMIT.COM, enter the command mload cpsker.hex,cpvgen.hex - MLOAD will create a file called CPVSKER.COM which you should rename to KERMIT.COM with the command ren kermit.com=cpsker.com

Step 6. Enjoy your new KERMIT executable
That's it, you're done. You can up the baud rate on the PC and target machine and start using kermit immediately. You don't actually need hardware handshaking if you're transferring small files. Have a play, see what setup works best for you.

November 13th, 2016, 01:55 AM
Hi Jon - thanks. Unfortunately I don't have LOAD.COM (I should also re-iterate this is CP/M-86) on my CP/M disk - just PIP, PBASIC86, ED, ERA, HELP, RUN, TOD, STAT, FORMAT, DCOPY, BOOTCOPY and something to set the serial port speed. I can PIP text files across from the PC fine at 9600bps. AXI: is the input from serial port A.

Victor 9000 KERMIT for CP/M-86 is here:
(XV9 being the Victor specific files)

November 13th, 2016, 02:25 AM
Errrm, without LOAD.COM you have a problem. I just amended the description to include acquisition of MLOAD.COM but it uses a HEX file so you need LOAD.COM.

So, what you need to do next is attempt to bootstrap it using the BASIC method, because you appear to have a BASIC interpreter. Hang on, I have an idea.... in the meantime, see if you can find a version of LOAD.COM for CP/M 86 to download on the PC.

November 13th, 2016, 02:37 AM
Hmm, can't find LOAD - can find: GENCMD.CMD, ASM86.CMD and DDT86.CMD? -> I think GENCMD turns a H86 file (x86 hex) into CMD?

My MS-BASIC is rather non-existant and I couldn't work out how it treats standard CP/M IO streams..

November 13th, 2016, 02:38 AM
I have to go... see if you can work out how to use PIP to capture a binary file with the [o] parameter. Then send a CP/M 86 LOAD.COM (or GENCMD.CMD) across. If you can do that, you can use my method for building KERMIT.

I'll look in on the thread later on today, please report your findings... :)

November 13th, 2016, 03:01 AM
Thanks :D - I'll have a go at it a bit later. - my only confusion is how to make sure PIP saves the file if it's ignoring ^Z - how do you signal to quit and save what you've received? :?

November 13th, 2016, 03:48 AM
If you append a 0x1A byte at the end of the file you are transferring, that should be a CONTROL Z.

These sites have some CP/M-86 downloads available:
http://www.actsirius1.co.uk/ #Lots of good information # HOWTO --> FILE TRANSFERS #


November 13th, 2016, 05:02 AM
True, Larry, but in object mode (that's the binary mode with option [o] set), it ignores ^Z, per http://www.gaby.de/cpm/manuals/archive/cpm22htm/ch1.htm#Section_1.6.4

[O] - Transfers non-ASCII object files. The normal CP/M end-of-file is ignored.

So we need a way to tell PIP that the file transfer is complete.

[Edit: And for me, it doesn't work. pip test.com=rdr:[o] just loads pip which exits immediately, leaving an empty test.com file.]

November 13th, 2016, 05:32 AM
I think it's a question of knocking something together in basic to get gencmd.cmd across, then the rest should (in theory!) be fairly straight forward. The alternative is to write something in BASICA in MSDOS to write files to CP/M format discs, and use that to get it there..? It might be slightly easier than trying to mess with IO streams in CP/M basic.?

November 13th, 2016, 06:00 AM
Good point! I didn't know that, or if I did I forgot it.

Well, there is always uuencode & uudecode for DOS. I've located those at : http://lf.8k.com/TOOLS/TOOLS.HTM
They should work. Plus, I found those on the CPM-86 Image.

There is also pipmodem.asm (& .DOC) and mboot3.asm in the
/Walnut_Creek_CPM/WalnutCreek/CPM/STARTKIT/ subdirectory.

A youtube video explains the process:

Information about bootstrapping on Superbrain (similar situation):

If you can tell me which files from this site "http://www.cpm.z80.de/binary.html#operating",
I can take the IMAGES (whatever format) and extract the files with cpmtools (under Linux)
for DDT-86, ASM86, and LOAD or MLOAD, plus anything else you need. I've got cpmtools
built with libdsk, and it works well for accessing the CP/M.

I'd need you to PM me your email address too!


November 13th, 2016, 07:13 AM
Done - and many thanks! I'm starting to delve into my BASIC options at the moment. *shakes fist at the sky* :D

November 13th, 2016, 12:14 PM
Try this:

10 REM Quick hack to create MLOAD.COM from MLOAD.HEX
20 REM (C) Jon Bradbury 2016 - VCF form member 'JonB'
30 OPEN "I",1,"MLOAD.HEX": REM Input HEX filename
40 OPEN "O",2,"MLOAD.COM": REM Output binary filename
50 IF EOF(1) THEN 100
60 INPUT #1,A$
80 GOSUB 130
90 GOTO 50
100 CLOSE #1 : CLOSE #2
110 PRINT "Done."
120 END
130 H$=MID$(A$,2,2):GOSUB 210:BC=HV
140 H$=MID$(A$,8,2):GOSUB 210:RT=HV
150 IF RT <> 0 THEN GOTO 200
160 ENDPOS=8+(BC*2)
180 H$=MID$(A$,DPOS,2):GOSUB 210:PRINT #2, CHR$(HV);
210 HI=0:LO=0
220 HI$=LEFT$(H$,1):LO$=RIGHT$(H$,1)
230 IF HI$>="A" THEN GOTO 250
240 HI=(ASC(HI$)-48)*16:GOTO 260
250 HI=(ASC(HI$)-55)*16
260 IF LO$>="A" THEN GOTO 280
270 LO=(ASC(LO$)-48):GOTO 290
280 LO=(ASC(LO$)-55)
290 HV=HI+LO

Given a copy of MLOAD.HEX, it will create MLOAD.COM. You now need a CPM/86 version of MLOAD.HEX, is it on the kermit site? Get that, make sure it has CR/LF line ends, transfer it across as text, transfer the BASIC program across as text, load it into your basic interpreter and run. If you need to turn other HEX files into executables, just alter the filenames on lines 30 & 40 accordingly.

I ran it on my Model II with MLOAD.HEX and the MLOAD.COM it produced worked flawlessly (in fact, I tested it by using it to create another version of KERMIT.COM, which also worked perfectly).

And I would like to say, I really enjoyed writing that! Thanks!



PS, All stuff required to bootstrap Kermit-80 is attached in this zip file:


November 13th, 2016, 12:39 PM
Brilliant :D - I shall give it a go in a short moment or 3 and report back! We're assuming the 16-bit hex (h86) files and HEX files are essentially the same here? (Just a cursory glance of the documentation suggests they are to all intents and purposes).

So far as I'm aware there's not a "useful" copy of cp/m-86 that anyone has running on a victor 9000 at present, so if we're now in the position to start generating boot floppies with comms software on them you've just successfully brought something back to life as it were :)

November 13th, 2016, 11:43 PM
Hummm, no, this might not work for 16 bit hex files, assuming there is such a thing. I used the Intel hex file format specification as a guide. Can't see why there is a need for a "16 bit" format, as a HEX file is just a byte-wise dump of the binary. Would be the same for 8, 16, 32, or 64 bit executables, just byte, byte, byte and so on until EOF. Try it and see if it pans out... you do have the MLOAD.HEX for CP/M 86? And I wouldn't take all the credit for resurrecting the Victor - it's a community thing, innit?


A few other points: The program could be extended fairly easily. It ignores all record types other than data records, so types 01 - 05 are ignored, which means that I am assuming a contiguous byte stream and I do not care about "extended segmented" or "extended linear" addresses, or the EOF record, because I detect EOF anyway. Further, when reading the data records, I ignore the address field (that's the "contiguous byte stream" assumption) and the checksum byte (so I do no error checking on the HEX file). I am a Very Bad Programmer, indeed! But then, someone trying to bootstrap this may have to type it in, and it's not terribly fast because it's interpreted BASIC, plus I'm lazy and / or I ran out of time last night. :)

Once you create MLOAD.COM you can use it instead of LOAD.COM. No need to go hunting for a CP/M 86 LOAD.COM, unless you are really after the genuine experience, in which case any one will do. Doesn't have to come off a Victor 9000 CP/M disk. Same for all the other CP/M executables. So you should be able to recreate a Victor boot disk with all the standard CP/M trimmings pretty easily, once you have Kermit.

November 14th, 2016, 12:41 AM
Gotcha. It's definitely gencmd.cmd rather than load/mload (they don't seem to exist for CP/M-86). Thanks to Larry sending me the files in a ZIP, I've managed now to get that into intel binary format with contiguous addresses, so we should be good to go. I've got the V9K kermit in H86 format, but the addresses aren't contiguous in that. This evening I'll PIP across your basic program, gencmd.cmd and kermit's h86 - hopefully that will be enough to get everything up and running! Unfortunately events resulted in me not having a go yesterday.

I really appreciate the help with this - various snippets of CP/M memory are gradually coming back.

November 14th, 2016, 12:54 AM
No problem, it's been a nice break from Z80 ASM and IDE driver code... :)

November 14th, 2016, 12:41 PM
Well, I can get the files across fine, but the BASIC interpreter is having a very bad day :( It won't load files "Bad file mode", and if I try entering a program I just get "Illegal Function Call" when I type a line number - I have a horrible feeling it's borked. :( Plan B is to try and write to a CP/M disc from MS-DOS. I think it might require a bit of low-level jiggery-pokery though, which I'm not massively looking forward to.

edit: I think, having had a really detailed trawl, that pbasic86 is a runtime version -> I have no idea how to get it to do anything useful :(

November 15th, 2016, 09:20 AM
Where are you located? If there are imgdsk images for it I could send you a floppy. And if there is a diskdef for it I could create a new floppy with MSBASIC-80 or MLOAD / Kermit.

November 15th, 2016, 09:55 AM
Alas that won't work - the Victor uses a strange and unique format - zoned clv (it changes the speed of the spindle depending on the track it's writing), not index aligned, and GCR encoding. Basically nothing other than a victor can write victor disks. :(

I've found a V9K disk sector editor that runs under MS-DOS, and given the CP/M discs are the same physical format, if it lets me edit sectors on CP/M discs I'm going to see if I can use it to enter GENCMD a byte at a time then update the directory to point to it. :?

Watch this space! (I have no idea what format runtime basic expects files in, but it's certainly not happy with ascii... :()

November 15th, 2016, 10:25 AM
Have you tried load "load.bas",a ?

November 15th, 2016, 11:04 AM
Yup, no dice :(

November 17th, 2016, 09:36 AM
Just to keep things up to date here :D

I'm going low-level in BBC BASIC (which was my weapon of choice back in the day). Fortunately I found some BIOS documentation so I'm now in a position to read raw sectors from the floppy. Which also means I'm in a position to write them. Which in turn means I'm in a position to add files to the disc and add them to the directory! - Assuming I can work out the format it's using! :D

Here's the code (it's very simple inline assembler in BBC BASIC, it just took a while to work out how to make sure I was pointing at the right addresses!):
And here it is chucking out raw sector data!