• Please review our updated Terms and Rules here

CP/M-80 binaries on V20 with PDOS/86-V20

kerravon

Experienced Member
Joined
Oct 31, 2021
Messages
138
Hi.

I just bought one of these NEW laptops that apparently contain a V20 chip:


(it says 8088, but I can see from the photo that it is a V20 - although maybe mine won't have that)

Assuming I get a V20, I was thinking of modifying PDOS/86 to run CP/M-80 binaries UNMODIFIED.

In real timeline, with a real 8088, people were forced to translate their CP/M-80 applications at the source level, to then be built as true 8086 binaries.

But the V20 had an 8080 mode. I'm planning on having PDOS/86 start, and then any .com files that are run will have a switch to 8080 mode so that they are treated as 8080 binaries. And yes, that means if you have an 8086 .com file it will no longer work on PDOS/86. I could trigger that via config.sys or some other method.

But my main interest is just running 8080 binaries. I can run 8086 binaries even on a modern computer. But I can't buy an 8-bit computer anymore (new, and not as a kit). Until now.

I'm only interested in running well-behaved CP/M-80 binaries.

Alternatively, I could have a competing API for 8080 binaries, instead of being a CP/M clone. But it would have to be something that was still capable of running on real, original 8080-based computers. I already have a Pos* API (basically MSDOS 2.0 with a C wrapper) but I don't know if it is practical for the 8080.

Any thoughts?

Thanks. Paul.
 
In the 1980s, I brought out 22Nice, which could be configured to use the 8080 alternate instruction set on the V-series (not just the V20, but the V30, V40, V50 as well as some of the oddball ones like the V33). Versions since about 1992, not longer support this mode, although the code is still there for a very simple reason: a fast 80286 or 386 can easily outpace a V20 and support the Z80 codes as well.
Recall that you still have to do I/O in 8086 mode--8080 doesn't support 10 bit I/O addresses that the PC uses.

The V20 8080 mode isn't perfect, by any means. One of the standard products that flopped hard was JRT Pascal.
I think I even posted a copy of CPMulater a couple years ago here.
 
In the 1980s, I brought out 22Nice, which could be configured to use the 8080 alternate instruction set on the V-series (not just the V20, but the V30, V40, V50 as well as some of the oddball ones like the V33). Versions since about 1992, not longer support this mode, although the code is still there for a very simple reason: a fast 80286 or 386 can easily outpace a V20 and support the Z80 codes as well.
Recall that you still have to do I/O in 8086 mode--8080 doesn't support 10 bit I/O addresses that the PC uses.

The V20 8080 mode isn't perfect, by any means. One of the standard products that flopped hard was JRT Pascal.
I think I even posted a copy of CPMulater a couple years ago here.

Hi Chuck. Thanks for your reply.

Yes, after I posted that I was pointed elsewhere to 22Nice where I saw the use of the V20's 8080 mode - cool. It requires modification of the .com file though.

Regarding the I/O - so long as it does it via a "call 5", that's the (hopefully small amount of) functionality that I would have added to PDOS/86 to make it redirect that in terms of the existing PDOS/86 (which will do everything in 8086 mode - including (IBM PC) BIOS calls for I/O.

But since posting that, I'm now leaning towards a variant of the other possibility I mentioned - bringing MSDOS 2.0 (sort of) to the 8080.

The specific variant is that I am thinking of using the PDOS-generic interface (where apps receive a pointer to a structure on the stack, with callbacks - similar to UEFI) for the 8080. I think this would have eliminated the issues caused by CP/M doing a hardcoded "call 5".

Note that the "BDS C" C compiler for the 8080 is public domain now, so that might be of interest too.

BFN. Paul.
 
Not so much modification, as renaming it from .com to .cpm. That's a good safety measure too, because DOS will load anything (even your grocery list) with a .com type and try to execute it. By renaming to .CPM, you avoid this--then the "loader" has the .COM extension and works safely.
 
Not so much modification, as renaming it from .com to .cpm. That's a good safety measure too, because DOS will load anything (even your grocery list) with a .com type and try to execute it. By renaming to .CPM, you avoid this--then the "loader" has the .COM extension and works safely.

The documentation in what I downloaded says:

3. Interface conventions between the 22Nice resident and
GENCOM-produced programs have changed. You'll have to
re-GENCOM your programs.


(and I read further about gencom and its options - which modify the .com)

And yes - I understand the need for the rename. Which is why I was considering turning this into a CP/M-80-only system.

Or maybe I will use BDS C (possibly running under 22Nice) to create PDOS-generic-80 apps.

BTW, the 22Nice I have is dated 1992, ie pre-internet. Is there an official website for it now?

Thanks. Paul.
 
The last version was 1.44, released in 2005. V20 emulation, while present, is disabled in GENCOM. There are a couple of good reasons for that--one is the ability to auto-detect Z80 vs. 8080 instruction mode. Another is to be able to trap and remap-I/O port accesses. (There used to be a large industrial sheet metal punch press running from a PC executing the 8080 PLC software some years ago).

Let's also be clear about the fact that we're emulating CP/M, mapping it into the MSDOS/Windows file structure. There is not a byte of DRI code in the emulation--as a matter of fact, if you dig into the BIOS that's provided, you'll see that function calls are transferred over to the x86 side. The result is a CP/M program that fits almost transparently into your DOS environment. As a matter of interest, I run 22Nice under DOSEMU emuation under x64 Linux.

But it was yards and yards of assembly code that I had little interest in continuing. There's not a line of C anywhere--which figures, because the original dates from about 1986 as a interesting project. I worked with NEC Natick Division, who was very supportive of the effort.

Attached is the readme from the 2005 version.
 

Attachments

  • 22readme.zip
    972 bytes · Views: 5
I'm able to run 8080 programs on my V20 equipped PC now but I would like to run CP/M-80 on it. IMHO it should be possible because the V20-MBC can. I have a clone of it and it works fine. It boots from a SD card using an Atmel but I haven't figured out how it is done. Roughly, yes, but not the details.

If this V20-MBC can, I don't see any reason why a PC cannot. Maybe I oversimplify it but IMHO it a matter of placing all needed CP/M files in a directory and we need a (CP/M) BIOS that translates all requests towards the hardware of the PC. With a bit of luck this work already has be done but I never found anything about it on Internet.
 
I'm able to run 8080 programs on my V20 equipped PC now but I would like to run CP/M-80 on it. IMHO it should be possible because the V20-MBC can. I have a clone of it and it works fine. It boots from a SD card using an Atmel but I haven't figured out how it is done. Roughly, yes, but not the details.

If this V20-MBC can, I don't see any reason why a PC cannot. Maybe I oversimplify it but IMHO it a matter of placing all needed CP/M files in a directory and we need a (CP/M) BIOS that translates all requests towards the hardware of the PC. With a bit of luck this work already has be done but I never found anything about it on Internet.

Hi Ruud. This post of yours set off another flurry of activity.

First of all - what 8080 programs are you able to run with your V20-equipped PC? Are you using 22Nice running under MSDOS or something?

As far as I can tell, you are not referring to the "V20-MBC", as apparently that is *already* a working solution.

Anyway - that was a very interesting possibility that I hadn't even considered - running the genuine CP/M-80 itself, not just CP/M-80 applications.

And yes - as you said, it should be possible to rewrite the CP/M BIOS layer to pretty much just stub it to return to 8086 mode where it can execute PDOS/86 (or an application running under PDOS/86 - which would be some sort of pseudo-BIOS) and thus the IBM PC BIOS (equivalent).

I'm not familiar with either CP/M or 8080 assembler, but started looking within the last 24 hours.

I'm familiar with C (which is what PDOS/86 is written in) and 8086 assembler.

Are you interested in working with me on this? If so, are you happy to make the code public domain? And if so, which bit do you think you are capable of writing? I'm good at anything that can be written in C. Also there is an existing 8086 infrastructure (including public domain 8086 assembler written in C) around PDOS/86. Although I've only ever tried to run the assembler under Windows (it should run on PDOS/386 too, and with a recompile it should run on PDOS/86 too - but it has never been priority for me personally to test that).

Note that I've never personally run CP/M (any flavor) - including under an emulator. So the first time I would see it for real would be if the above started working and my new laptop actually arrives (it needs to go from China to the Philippines - which isn't very far - their warships don't seem to have a problem harassing Filipino fishermen - but the shipping status hasn't changed from "Order processed by shipper" all of today, but just getting a tracking number was a great step).

Thanks. Paul.
 
First of all - what 8080 programs are you able to run with your V20-equipped PC? Are you using 22Nice running under MSDOS or something?
I already consider a piece of code that displays "Hello world!" on the screen as a program as well. In this case I don't know anymore what I ran but it was something quite simple to proof that it could be done at all. IIRC IIRC the program did:
- switch to 8080 mode
- write some numbers somewhere in memory
- switch to 8088 mode
Then you had to check with debug if the numbers were indeed written.
So no 22Nice or whatever.

Are you interested in working with me on this?
I would love to but I only have limited time at my disposal, certainly no with the renovation of my youngest son's house and it former room. And unfortunately I'm not a C programmer.
 
I already consider a piece of code that displays "Hello world!" on the screen as a program as well. In this case I don't know anymore what I ran but it was something quite simple to proof that it could be done at all. IIRC IIRC the program did:
- switch to 8080 mode
- write some numbers somewhere in memory
- switch to 8088 mode
Then you had to check with debug if the numbers were indeed written.
So no 22Nice or whatever.


I would love to but I only have limited time at my disposal, certainly no with the renovation of my youngest son's house and it former room. And unfortunately I'm not a C programmer.

Ok, thanks for the info. Note that I can do anything that requires C - it's the assembler (especially 8080) that will be a challenge. Plus any CP/M BIOS knowledge.

Anyway - another opportunity has arisen - I realized I should be able to get my win32 programs to run on commercially-supported OS/2 (ArcaOS) by doing the same thing I planned to do on Windows 3.11 with Win32s - have a different flavor of my msvcrt.dll to open a graphics Window and write 80 * 25 text to it.

I need to decide which way to jump.

Or maybe I'll try seeing if I can get PDOS/386 to build totally (ie including 16-bit components) with commercially-supported Digital Mars.
 
If this V20-MBC can, I don't see any reason why a PC cannot.

So an obvious difference here that makes it easier for this SBC is the SBC has all its I/O at 8080/Z80 compatible addresses. Per Chuck's comments about 10 bit I/O addresses above, I think the point he made there is if you just took CP/M-80 intending to write a 5150 BIOS for it a wall you're going to hit is that you won't be able to use the 8080 IN/OUT commands on any I/O port higher than FF. I imagine a further complication is in a PC with memory-mapped video you're going to have the video buffer in a different segment than where you're running the code. I have no idea if the V20's 8080 emulation has any way to deal with having to reach outside your segment other than having to bail out and call 8086 code.

I mean, I guess that's not the end of the world, you could have access to the keyboard, PIC, and PIT in 8080 mode but... you're not going to be able to reach the parallel and serial ports, the floppy controller, the control registers for any standard PC video card... etc, all of those are going to be calls switching back to "native" mode. For user CPM/80 programs they don't need to care if you make your CP/M BIOS rely heavily on switching to 8086 code for actually executing said call, but it seems like it does mean you'll be rewriting a lot of the OS *proper* to run in native mode. (It'd be pretty silly/awkward, for instance, to try to keep the floppy driver "native" but have to make a 8086 call every time you actually have to reach the floppy controller.)
 
I have no idea if the V20's 8080 emulation has any way to deal with having to reach outside your segment other than having to bail out and call 8086 code.
Yes, that is indeed the idea! There are Z80 cards for the PC, like the Baby Blue II. These cards cannot access "their" keyboard as well but still run. The reason: the BIOS does the job by asking the 8086 to check if a key has been pressed. If indeed, the value is transferred to the board and sent to the Z80. In this case the interface is different but the effect is the same: the value read by the 8086 is sent to the 8080. In the same way the CP/M-BIOS takes care of sending a character to the screen.
 
Last edited:
… sure, but your question was why it was “any easier” for that V20-MBC board to run straight-up CPM-80 than a PC with a V20, and the answer is that its hardware doesn’t *need* you to write a BIOS that calls x86 code. Its disk access and serial port can be pounded on directly in 8080 mode and there’s no framebuffer in another segment to write to; a port of CPM-80 to it literally only needs to switch into emulation mode in the boot sector and never speak x86 again.
 
It is probably easier to implement a wrapper in 8086 assembly around the 8080 mode (i.e. a hypervisor), and then write a CP/M-80 BIOS to simply call into that wrapper. I don't know whether 8080 code can switch to 8086 mode and back itself.

Since CP/M application have no business in the BIOS insides, the BIOS is free to handle the requests in whatever way it pleases - including switching CPU mode.
 
It is probably easier to implement a wrapper in 8086 assembly around the 8080 mode (i.e. a hypervisor), and then write a CP/M-80 BIOS to simply call into that wrapper. I don't know whether 8080 code can switch to 8086 mode and back itself.

It doesn’t work as a “hypervisor”, that would imply some kind of instruction trapping.

It’s pretty simple and it seems like that’s kind of getting lost. If you need something that only the 8086 code can do then, yes, you need to have a BIOS call or whatever that calls out of the 8080 bubble and switches back to it when done, that’s how the V20 works and it’s how both those MS-DOS wrappers for CP/M programs and the clever extensions to glom 8080 support into CP/M-86 work. The thing I was pointing out in relation to Ruud’s question about that non-PC compatible single board computer is that if you built a V20 computer that *had* all the necessary hardware reachable from 8080 mode (IE, all port I/O confined to the 8-bit port range and nothing memory mapped outside the 8080 segment) then you could literally just run the same CP/M-80 that would run on that hardware with an 8080 or Z80 in place of the V20; just have the first few instruction in the boot ROM set up the 8080 segment with 8080 IPL code, switch modes, and go nuts.

Again, I agree there is nothing stopping you from making a “CP/M-80” that runs on a PC with a V20 in it that dispenses with having a “different“ OS under it. It is simply more complicated than the above because you have to decide *how much* of your ”CP/M-80” BIOS is actually 8086 code, just a bootloader doesn’t cut it anymore. Do you write as much of the BIOS as possible to be “native” for efficiency, in which case you’re basically just writing a weird subset of CP/M-86 to exclusively host the 8080 program box, or do you try to keep as much of it 8080 code as possible and just switch modes as absolutely necessary? Whatever floats your boat.
 
I'm planning on having PDOS/86 start, and then any .com files that are run will have a switch to 8080 mode so that they are treated as 8080 binaries. And yes, that means if you have an 8086 .com file it will no longer work on PDOS/86. I could trigger that via config.sys or some other method.

You can (almost) perfectly detect if a .com file contains 8080 code by looking at the first one or two bytes.

It's somewhat widely known that most CP/M programs start with a jump instruction (because it's convenient to have the entry point somewhere other than the start of the file), opcode C3h. On the 8086 that causes the program to immediately exit, since it's the opcode for RET there.

Looking at all the possible instructions that make sense as the start of a CP/M-80 program (i.e. excluding anything that depends on undefined register contents and "system" instructions like IN/OUT):

Code:
opc | instruction | conflict with x86?
-----------------------------------------------
00  | NOP         | no
01  | LXI B,i16	  | no
11  | LXI D,i16   | no
21  | LXI H,i16   | no
31  | LXI SP,i16  | may be XOR reg with itself
2A  | LHLD i16    | may be SUB reg with itself
3A  | LDA i16     | no
06  | MVI B,i8    | unlikely, PUSH ES
0E  | MVI C,i8    | unlikely, PUSH CS
16  | MVI D,i8    | unlikely, PUSH SS
1E  | MVI E,i8    | unlikely, PUSH DS
26  | MVI H,i8    | unlikely, ES: pfx.
2E  | MVI L,i8    | unlikely, CS: pfx.
3E  | MVI A,i8    | unlikely, DS: pfx.
37  | STC         | no
97  | SUB A       | no
AF  | XRA A       | no
C9  | RET         | no
C3  | JMP i16     | not really, program would do nothing
CD  | CALL i16    | unlikely, except maybe INT 11h/12h (or INT 20h which exits)

Also considering the Z80 (even though it can't be emulated on V20), we have:

Code:
18    | JR i8       | no
DD 21 | LD IX,i16   | no
DD 2A | LD IX,(i16) | no
DD 26 | LD IXH,i8   | no
DD 2E | LD IXL,i8   | no
FD 21 | LD IY,i16   | unlikely, STD
FD 2A | LD IY,(i16) | ""
FD 26 | LD IYH,i8   | ""
FD 2E | LD IYL,i8   | ""
ED 4B | LD BC,(i16) | no
ED 5B | LD DE,(i16) | no

If the file starts with 31h or 2Ah, also look at the second byte: if the high two bits are set, and the lower two octal digits (bit 0-2 and 3-5) are the same, assume x86, otherwise 8080.

I wrote a TSR for DOS that intercepts the "exec" function (INT 21h / AX=4B00h) and loads programs in an emulator if they are for the 8080. Not sure if I'm going to make the code public (it's a bit hacky, especially the Z80 emulator), but you are free to use this idea in your public domain operating system.
 
22NICE (that thing again) has a test mode. It starts by executing in 8080 mode until it hits a z80 instruction and notifies the user. It also checks for I/O port access in case the user wants to re-map or implemented an emulated peripheral. None of this, of course, can happen in V20 8080 mode. So we were doing this 30 years ago....
 
22NICE (that thing again) has a test mode. It starts by executing in 8080 mode until it hits a z80 instruction and notifies the user. It also checks for I/O port access in case the user wants to re-map or implemented an emulated peripheral. None of this, of course, can happen in V20 8080 mode. So we were doing this 30 years ago....

But not auto-detection of x86 vs. 8080/Z80 programs ;)

The idea is that while .COM files don't have a header, you can look at the first instruction's opcode and determine for which CPU it was intended, with very little possibility of conflict. Because the register contents are undefined, it would have to either be a jump/call or load some value. And it's almost like Intel designed the instructions that do this to have distinct opcodes, even though it's certainly accidental.
 
Last edited:
So when the first instruction is 31 xx xx, it's a what? (e.g. DRI ASM, GENHEX, etc.)--or 01 xx xx (DDT/ZSID). C3 is very common, particularly when initialization code is at the high addresses and will be overlaid (e.g. EBAS). A relative jump at the beginning is only useful when the jump distance is short.
A program can use the flags register (slightly different behavior between 8080 and Z80) to determine what the host CPU is, but few do. Many just use 8080 code to be safe.
 
Back
Top