Yea, ok.
Folks mentioned FLEX, so I took a gander at it. It's interesting to contrast CP/M and FLEX.
Specifically, all calls to BDOS in CP/M go through a single entry point, whereas in FLEX, the calls go to specific addresses.
Now, in CP/M there's simply a JMP at the single entry point, to go wherever the dispatch code is (which, coincidentally appears to be the same as FBASE, and I think the entry point in to CP/M is BASE+0005H, which would make it JMP FBASE, anyway).
But in FLEX, it's clear that all of the entry point address are also simply place to put a JMP in to the actual code.
However the architecture mandate is different. FLEX assumes code at specific locations in higher memory ($CXXX), whereas CP/M requires only some byte in very low memory. JMP 0000H is how a program "exits", and warmstarts CP/M. The CP/M technique also seems a bit more extensible (up to 255 functions using the basic function number, could always have an extended function).
Down side is that CP/M is a bit more expensive: set the register, JSR to a JMP to some dispatch code that inevitably calls the desired routine vs a simple JSR to a JMP. But, easy to argue that these calls are high level enough, and so slow anyway (couple of more instructions are going to save you when you hit that floppy…) that they're not missed.
Now, contrast this to how the Atari did it.
With the Atari, they had a single entry point to the Central IO system. They allowed 8 channels, also at a specified point in memory. They also had a table of device drivers.
So you would select a channel, specify a device name (like K: for keyboard, or D:FILE.TXT for a disk file), "open" the device, then call the common entry point with X set to the channel number. The table of device drivers was extensible, you could add your own, or override a system supplied one.
Whereas CP/M and FLEX had a different routine for writing to disk vs writing to the console, with the Atari you just wrote to the D device instead of the S(screen) device. To format a diskette on the Atari, you made an extended command to the Disk driver. The calls were the same. Much like in Unix, you basically have open, read, write, close, and ioctl that works for "anything". In CP/M you would pass a pointer to a FCB, whereas with the Atari, you passed the channel number to a list of fixed "FCBs" (they don't call them that). Likely they chose to do this because passing pointer is more of a pain than simply passing a register on the 6502.
The Atari had no real need to strive for portability, but it's easy to see if you make the Atari CIO call similar to the way CP/M does it (through a RAM vector), it could be quite portable.
|