• Please review our updated Terms and Rules here

CP/M for the 6502

hjalfi

Experienced Member
Joined
Feb 11, 2017
Messages
265
Location
Zürich, Switzerland
I've just done a basic port of CP/M to the 6502.

https://github.com/davidgiven/cpm65

It currently runs on the BBC Micro (and Master and Tube), and the Commodore 64 (very slowly). It adds relocatable binaries, necessary to make programs portable between systems, but is otherwise essentially CP/M 2.2, just rewritten for the 6502. Naturally, there is no software whatsoever for it...

Also, if you're interested in watching about 45 hours of Youtube, I recorded myself programming it. Videos will be appearing here:

https://www.youtube.com/playlist?list=PLuQ2s_IbSWv48cCusm2SIstRZL8K0zRDA
 
Each binary contains two relocation tables, one for ZP addresses and one for RAM addresses. The relocation routine just walks through the binary adding on the start ZP byte or RAM page to the appropriate addresses. RAM relocations must be page-aligned, because that avoids the need to do 16-bit relocations --- it's a very old trick (original CP/M PRL files did this). The relocation routine is tiny, and ends up in the BIOS so the BDOS itself can be relocatable: https://github.com/davidgiven/cpm65/blob/master/src/relocate.inc
 
Wrote a tool! It just does the ancient trick of assembling the program multiple times at different addresses, and comparing the results to see which bytes have changed to figure out which bytes need relocation.

However, now I do have a bespoke binary generator for producing relocatable binaries from llvm-mos ELF files. Needs work, though.
 
Darn, not on the Apple II yet.

The Apple II had a few alternate 6502 DOSes that were more CP/M-like:

1. Randy Hyde's ANIX, used as the base of his Lazer Pascal and L.I.SA. assembler. It was really a shell over DOS 3.3, but sported CP/M commands like STAT and many more.


2. MuMath for the Apple II 2nd edition had a custom DOS called ADIOS-81. (The 1st edition was still Z80-code and only worked on the CP/M card.) ADIOS was its own thing and not DOS 3.3 compatible, not even a file transfer utility. Presumably they wrote it to maximize memory for MuMath.


(Strictly speaking, my answer should go in the Apple part of the forum instead of the CP/M one. But I couldn't help pointing this out.)
 
Incidentally, what makes a DOS a CP/M DOS? Just the user commands? The calling API? The branding name? The company that markets it?

CP/M-68000 and CP/M-8000 had completely different code than CPM-80, but were by the same company and were called "CP/M", so they are CP/M!

A competing Z80 DOS that used the same calling API like should count. TPM was supposed to run regular CP/M (1.4) binaries while extending the API to allow things like re-entrancy. But it was for the same processor.

But Patterson's 86-DOS (MS-DOS) is not considered CP/M, even though it had an API that was closer to CP/M-80 than the official CP/M-86 had!

I guess what you did is much more "CP/M" than what Patterson did, since you translated the actual CP/M source. And there would be a CP/M-style calling API. But for a completely different processor by a completely outside programmer, is it "CP/M" or "CPMish"? :)
 
CP/M is whatever the sales and marketing department decide to sell to bring money in!

Nice job though...

Dave
 
If anyone wants a Apple II port, I'd love to get a pull request! There would be two main ways of doing it:
  • implement it as a program running on top of DOS, with the CP/M file system in a big file and using DOS file I/O services to do disk access
  • implement it bare metal, doing raw disk and screen I/O
The latter would be faster and probably give more spare RAM. The former would be much easier and more portable as it'd work on things like hard drives. The complicated bit is that, IIRC, on the Apple II most of the disk controller was done in software, so raw disk I/O would need to duplicate this logic.

The biggest thing I need, though, is software. Command-line Apple DOS programs (e.g. compilers, assemblers etc) would probably be relatively easy to port, if anyone knows of useful ones with actual open source licenses...
 
If anyone wants a Apple II port, I'd love to get a pull request

My ignorant thought would be that a port of CP/M to the Apple II would be significantly complicated by the memory map of that machine, but I guess it probably depends on how strictly you define “CP/M”; with relocatable binaries I guess you shouldn’t be much worse off than a 32k BBC micro in terms of contiguous RAM…
 
I think I've only ever even touched an Apple II, like, twice --- they're not common here in Europe --- but from random stuff I've dug up online it doesn't look too bad. Running bare metal you'd get contiguous RAM from 0x0000 to 0xc000, with the screen at 0x400, then I/O, then bank-switched RAM from 0xd000 up.

Right now the way I'd do it is to load the BIOS into the bank-switched RAM so that it can claim the vectors, with the BDOS and CCP low. It'd be fairly possible to adapt it so that the BDOS and CCP loaded high too, giving a TPA of 46kB. This would depend on how big the BIOS was given that it would need to contain an entire floppy driver.
 
Incidentally, what makes a DOS a CP/M DOS? Just the user commands? The calling API?
Both. A CP/M has a boot sector, a BIOS, a BDOS and a TPA. MS-DOS is very CP/M like but we'd all agree that it's not a CP/M. It has all of those things, though perhaps not with those terms, but it's not CP/M compatible. It's REALLY CLOSE, and while it's an obvious child of CP/M, you can not port CP/M source code to it directly and expect it to work.

The API is the key, but not everything. POSIX does not make a UNIX, but it's a big chunk of it. So, the CLI is certainly part of what CP/M is.

Which brings up valid questions about, say, what about things like ZCPR and its ilk? Solid questions indeed.

I would say that if you could take a C program written for CP/M, adjusted for the proper calling convention (I don't know how the 6502 CP/M invokes system calls in contrast to CP/M stuffing of registers and CALL 5), and assuming the C code does no more than call the BDOS properly, then I think it's fair to call the 6502 thing a CP/M.
 
MSDOS (in whatever incarnation it currently uses) still honors doing a CALL 5 (in the PSP) to make system requests. What's odd is that CP/M-86 didn't. With PCDOS 1.x, many of the FCB fields even matched up with CP/M-80, not to mention the numbers for the system request APIs.
 
I must admit it would be really neat to see CP/M run on an Apple II without a Z80 softcard. Regardless, this is great work!
 
I'll respectively submit that given the hardware differences, the result isn't CP/M, at least not as envisioned by the people at DRI. It may be CP/M-like, and you can call it what you will, but it doesn't correspond to a product that DRI produced. I think someone else here has tried to make the same point.
Consider my 22Nice--it implements the CP/M API in an emulated x80 environment and runs most things (including Wordstar), but it's basically a translation layer to MS-DOS. It's definitely not worthy of being called CP/M.
 
I think I've only ever even touched an Apple II, like, twice --- they're not common here in Europe --- but from random stuff I've dug up online it doesn't look too bad. Running bare metal you'd get contiguous RAM from 0x0000 to 0xc000, with the screen at 0x400, then I/O, then bank-switched RAM from 0xd000 up.
Well there's also the tiny little problem that the 6502 stack can only exist at 0100-01FF, which on an x80 or x86 is the standard location for the start of a loaded .COM file. It was significant enough that MSDOS did that too. And it's why I never had delusions of running CP/M on my TRS-80 Model I, because even with a compatible CPU, there's no point when everything would have to be re-assembled to 0x4100 or so. At that point you might as well just patch all the OS calls in Wordstar to work with TRSDOS.

What makes CP/M important isn't just that it let you manage some files on a disk. The large amount of programs written for it and its API are at least as important. There is very little point in running it on an alien architecture with no existing software for it.

I would say that if you could take a C program written for CP/M, adjusted for the proper calling convention (I don't know how the 6502 CP/M invokes system calls in contrast to CP/M stuffing of registers and CALL 5), and assuming the C code does no more than call the BDOS properly, then I think it's fair to call the 6502 thing a CP/M.
The problem is most CP/M programs were written in assembly language. C really wants to be a 16-bit language. Using C on an x80 is a bit tight, but on the register-poor, stack-poor 6502, it's not a very good fit at all. UCSD Pascal was somewhat successful on the Apple II because it paved over the limitations of the 6502 with P-code.
 
>>> What makes CP/M important isn't just that it let you manage some files on a disk. The large amount of programs written for it and its API are at least as important. There is very little point in running it on an alien architecture with no existing software for it.

My wife would argue there is very little point in my hobby at all! But there you have it...

However, this is another interesting 'strand' to our hobby - the 'what if' scenario...

What if CP/M was targeted to a 6502 for instance. How could it look, behave and perform.

I have done a similar thing with the 6800 FLEX O/S - and ported it to a Z80. Of course, CP/M is always going to be more powerful than FLEX - but to get the '#' prompt on my Z80 - priceless! I also learned an awful lot about FLEX itself in the process. Is it of use - of course not - but it answers my question of 'what if...'.

Dave
 
It's interesting, but it's like running DOOM on the configuration screen of a printer. Or a dog chasing a car and actually catching it.
 
Back
Top