bridger%monty@RAND.ORG (Bridger Mitchell) (11/27/90)
Mitch Mlinar wrote: >> Regarding BIOS: Kaypro assumed that you were in an 8080 world AND interrupts >> do not exist. (They wrote their BIOS in Z80 code, though, and used the >> "back-side" Z80 registers.) Bridger Mitchell (TurboROM) is better here in >> that he understands that interrupts might exist, but ALSO assumes that one >> lives in an 8080 world only. In other words, the assumption is that IX and >> IY registers are unchanged outside of your program. KayPLUS does not make >> any of those assumptions, especially since 90% of the CP/M computers are >> Z80 and replacement operating systems (like QP/M or ZCPR) all exploit the >> Z80 instruction set. >> >> Not many people are writing Z80 operating systems today (although interesting applications such as background reminder calendars continue to appear). However, I think some clarification of Mitch's comments is desirable. I (and others) have long argued strenuously for strict adherence to the following systems-programming guideline: **** SYSTEM CODE (BIOS, BDOS, INTERRUPT-SERVICE ROUTINES, AND BACKGROUND UTILITIES) SHOULD *ALWAYS PRESERVE* THE NON-8080 REGISTERS. **** This rule ensures that an application that uses Z80 opcodes can run on any z80 system without having to save and restore any of those registers before every BIOS and BDOS call. Note that system code can indeed *use* the Z80 registers (the TurboRom, BackGrounder ii, and ZSDOS, for example, do so extensively). The code must just push/pop or save/restore from memory any registers that it needs to use. A flagrant violations of this guideline is found in an early version of the Osborne Executive rom, which used an index register (probably IY) in a service interrupt routine. Not even the smartest application can safely use IY, since the interrupt is asynchronous, and until a corrected rom was issued early owners were baffled to find that some programs would simply not run correctly. Another egregious case is the BIOS in the ON! computer, which uses af' without preserving it. This topic -- appropriate use of registers -- is part of the larger subject I have called "environmental programming" and discussed at greater length in a column in The Computer Journal. Each programmer needs to be aware of the computer environment in which his/her code may be executing, and take appropriate steps to preserve that environment. Systems code has an especially heavy obligation to allow applications to thrive; hence the abvove guideline. But applications also have responsibilities -- for example, to verify that the host has the necessary resources (devices, type of BIOS, etc.) before executing code that can crash or do damage on the wrong platform. -- bridger
tilmann@cosmo.UUCP (Tilmann Reh) (12/02/90)
Hello world, Bridger Mitchell writes: > I (and others) have long argued strenuously for strict adherence to > the following systems-programming guideline: > > **** > SYSTEM CODE (BIOS, BDOS, INTERRUPT-SERVICE ROUTINES, AND BACKGROUND > UTILITIES) SHOULD *ALWAYS PRESERVE* THE NON-8080 REGISTERS. > **** > > This rule ensures that an application that uses Z80 opcodes can run on > any z80 system without having to save and restore any of those > registers before every BIOS and BDOS call. That's a guideline I don't agree with. Why should the system care about which registers the application program uses? The responsibility for register contents is *only* at the application program! So, before each and every system call it has to save those registers it want's to use afterwards (assuming with unchanged contents). This also reduces system overhead (thus increasing performance, though slightly) as not every register that *might* be used has to be saved, but only those that *are* used. The above guideline opens the door to very improper application programming. The only way to ensure that a program runs on *every* CP/M machine is to save all registers which must stay valid prior to any system call. BTW, I don't see why this should be so hard... Of course, interrupt routines must also save all registers they use, as this are asynchronous events. When will programmers (system *and* application) finally understand that everything should be programmed as portable and universal as possible ? Tilmann Reh tilmann@mcshh.uucp tilmann@mcshh.hanse.de
floyd@ims.alaska.edu (Floyd Davidson) (12/04/90)
In article <6209@balu.UUCP> tilmann@cosmo.UUCP (Tilmann Reh) writes: >Bridger Mitchell writes: >> SYSTEM CODE (BIOS, BDOS, INTERRUPT-SERVICE ROUTINES, AND BACKGROUND >> UTILITIES) SHOULD *ALWAYS PRESERVE* THE NON-8080 REGISTERS. >> **** >> >> This rule ensures that an application that uses Z80 opcodes can run on >> any z80 system without having to save and restore any of those >> registers before every BIOS and BDOS call. > >That's a guideline I don't agree with. >Why should the system care about which registers the application program uses? >The responsibility for register contents is *only* at the application [...] > >When will programmers (system *and* application) finally understand that >everything should be programmed as portable and universal as possible ? > You're last statement does not follow from the first. For maximum portability both should assume the other did it wrong. Both applications programmer and system programmer should protect the registers. I think the performance cost is small if a little thought is given to register use. Floyd -- Floyd L. Davidson floyd@hayes.ims.alaska.edu Salcha, AK 99714 paycheck connection to Alascom, Inc. When I speak for them, one of us will be *out* of business in a hurry.
pl@news.funet.fi.tut.fi (Lehtinen Pertti) (12/04/90)
From article <6209@balu.UUCP>, by tilmann@cosmo.UUCP (Tilmann Reh): > Hello world, > > Bridger Mitchell writes: >> I (and others) have long argued strenuously for strict adherence to >> the following systems-programming guideline: >> >> **** >> SYSTEM CODE (BIOS, BDOS, INTERRUPT-SERVICE ROUTINES, AND BACKGROUND >> UTILITIES) SHOULD *ALWAYS PRESERVE* THE NON-8080 REGISTERS. >> **** >> >> This rule ensures that an application that uses Z80 opcodes can run on >> any z80 system without having to save and restore any of those >> registers before every BIOS and BDOS call. > > That's a guideline I don't agree with. > Why should the system care about which registers the application program uses? The point is, that CP/M is specified to 8080 and first Z80 versions didn't use Z80-specific registers, so it appeared, that applications were free to use those registers without saving/restoring. Now, if new versions of CP/M take those registers in use, it could break old applications. > The responsibility for register contents is *only* at the application > program! So, before each and every system call it has to save those registers > it want's to use afterwards (assuming with unchanged contents). This also > reduces system overhead (thus increasing performance, though slightly) as > not every register that *might* be used has to be saved, but only those > that *are* used. System routine usually saves only those registers it really uses, so I don't really see, if it matters, who saves the registers, as long as it is clearly specified somewhere. > The above guideline opens the door to very improper application programming. > The only way to ensure that a program runs on *every* CP/M machine is to > save all registers which must stay valid prior to any system call. BTW, I > don't see why this should be so hard... > Yes, this is sure way to do that. But what is needed, is clear specification, which registers should be preserved and which not, just as in every subroutine calling standard. > Of course, interrupt routines must also save all registers they use, as this > are asynchronous events. > > When will programmers (system *and* application) finally understand that > everything should be programmed as portable and universal as possible ? > If system specification says which registers are to be preserved, it would be very easy. Up to that point there is always possibility to argue, who is brain damaged and who not. > > Tilmann Reh tilmann@mcshh.uucp > tilmann@mcshh.hanse.de pl@tut.fi ! All opinions expressed above are Pertti Lehtinen ! purely offending and in subject Tampere University of Technology ! to change without any further Software Systems Laboratory ! notice
tom@afthree.as.arizona.edu (Thomas J. Trebisky) (12/06/90)
>Bridger Mitchell writes: >> I (and others) have long argued strenuously for strict adherence to >> the following systems-programming guideline: >> >> **** >> SYSTEM CODE (BIOS, BDOS, INTERRUPT-SERVICE ROUTINES, AND BACKGROUND >> UTILITIES) SHOULD *ALWAYS PRESERVE* THE NON-8080 REGISTERS. >> **** > > Tilmann Reh writes >The above guideline opens the door to very improper application programming. >The only way to ensure that a program runs on *every* CP/M machine is to >save all registers which must stay valid prior to any system call. BTW, I >don't see why this should be so hard... Sorry to take exception with this. I don't think it is the applications programmers responsibility to guard against all manner of stupidity on the part of those writing systems code. Believe me, every modern OS puts the burden of saving and restoring machine state on the OS -- on a Unix system a system call is commonly implemented by a TRAP or INT, and the first thing the OS will do is save all the registers and whatever else is involved with the user context so it can restore it transparently. As you point out there is no possible way that user code can "guard against" what is done with registers in interrupt routines since they are completely asynchronous. The sad reality of things though is that you are right in a way, due to the abundance of funky systems software in the CPM realm. In the hey-day of CPM every Tom, Dick, and Harry was in a rush to port CPM to this or that platform, and some of the work was poorly done. This forces you and I to go to lengths we shouldn't have to, if we really want "portability" to every sleaze-ball system. However if the above guidelines for SYSTEMS code were followed, we would not have to do this. Another case could be made perhaps for efficiency, the applications programmer knows at any time exactly what he needs to save, whereas a systems call handler must necessarily save everything to be general. In the Z80 realm where every machine cycle is precious, this might have merit, but I would rather save the code space (and my keystrokes :-) ).
tilmann@mcshh.hanse.de (Tilmann Reh) (12/09/90)
In article <1990Dec4.131328.15594@ims.alaska.edu> floyd@ims.alaska.edu (Floyd Davidson) writes: > You're last statement does not follow from the first. For maximum > portability both should assume the other did it wrong. Of course, that is the safest way. But then, system behaviour is very well specified (see below). So I especially wanted to emphasize the responsibility of the application programmers (not to blame it all on the system programmers!). In article <1990Dec4.134833.17783@funet.fi> pl@news.funet.fi.tut.fi (Lehtinen Pertti) writes: > The point is, that CP/M is specified to 8080 and first Z80 versions > didn't use Z80-specific registers, so it appeared, that applications > were free to use those registers without saving/restoring. Sorry, but that's not logical. If one uses Z80 opcodes in an application, he must be aware that at least the BIOS also uses these instructions. > System routine usually saves only those registers it really uses, > so I don't really see, if it matters, who saves the registers, > as long as it is clearly specified somewhere. Of course, in fact it doesn't matter *who* saves. Just that the system may save registers which aren't used by the application at all. As for the spec's: see below. > Yes, this is sure way to do that. But what is needed, is clear > specification, which registers should be preserved and which not, > just as in every subroutine calling standard. > If system specification says which registers are to be preserved, > it would be very easy. I wonder if anyone of you ever read the CP/M Programmers Guide. In this (original DRI) document there is the clear specification. The CP/M-Plus Programmers Guide (as I use CP/M-Plus) tells me on page 27: When a transient program makes a BDOS function call, the BDOS does not restore registers to their entry values before returning to the calling program. The responsiblity for saving and restoring any critical register values rests with the calling program. So everyone who writes (or wants to write) applications programs should please read the specifications before doing so. Of course, that quotation doesn't mention Z80 registers. But if you think logically and carefully look at the sentence, it is absolutely clear that *every* register may be changed after returning from a system call. BTW, even commercial programs may have bugs: In Turbo-Pascal 3.0, the IX and IY registers aren't saved before calling the Console Input routine, but used afterwards. So be careful. (every other Char I/O is ok!) Tilmann Reh tilmann@mcshh.uucp tilmann@mcshh.hanse.de
bandy@catnip.berkeley.ca.us (Gun Control is Hitting Your Target) (12/10/90)
I agree with Bridger, disagree with Tilmann and give my take on the situation, plus official word from DRI. Bridger Mitchell writes: >> I (and others) have long argued strenuously for strict adherence to >> the following systems-programming guideline: >> >> **** >> SYSTEM CODE (BIOS, BDOS, INTERRUPT-SERVICE ROUTINES, AND BACKGROUND >> UTILITIES) SHOULD *ALWAYS PRESERVE* THE NON-8080 REGISTERS. >> **** >> >> This rule ensures that an application that uses Z80 opcodes can run on >> any z80 system without having to save and restore any of those >> registers before every BIOS and BDOS call. tilmann@cosmo.UUCP (Tilmann Reh) writes: >That's a guideline I don't agree with. >Why should the system care about which registers the application program uses? Why? "Because CP/M is an **8080** operating system - thus it may only use 8080 registers." I got this reply back from Digital Research back in '80 when I asked them about the Z/80 registers. >Of course, interrupt routines must also save all registers they use, as this >are asynchronous events. That's right, but the silly people who did the Osborne-1 roms didn't. Hence perfectly valid Z80 applications that ran on other folks' systems would crash on the Osborne. >When will programmers (system *and* application) finally understand that >everything should be programmed as portable and universal as possible ? Exactly. Yes, it would make an application even more bullet proof to have it save all the Z80 registers [or don't use them :-)] before it called into BDOS/BIOS, but folks who write BIOS software should preserve the Z80 registers to help maintain compatibility with "incorrect" software. -- real address: bandy@catnip.berkeley.ca.us last choice: lll-winken!catnip.berkeley.ca.us!bandy
fzsitvay@techbook.com (Frank Zsitvay) (12/12/90)
In article <663@catnip.berkeley.ca.us> bandy@catnip.berkeley.ca.us (Gun Control is Hitting Your Target) writes: >>> I (and others) have long argued strenuously for strict adherence to >>> the following systems-programming guideline: >>> >>> **** >>> SYSTEM CODE (BIOS, BDOS, INTERRUPT-SERVICE ROUTINES, AND BACKGROUND >>> UTILITIES) SHOULD *ALWAYS PRESERVE* THE NON-8080 REGISTERS. >>> **** >>> >>> This rule ensures that an application that uses Z80 opcodes can run on >>> any z80 system without having to save and restore any of those >>> registers before every BIOS and BDOS call. >>That's a guideline I don't agree with. >>Why should the system care about which registers the application program uses? > >Why? "Because CP/M is an **8080** operating system - thus it may only use >8080 registers." I got this reply back from Digital Research back in '80 >when I asked them about the Z/80 registers. well, CP/M itself doesn't use the special registers, but the BIOS might, since that was supplied from the manufacturer of the machine. there is another problem, though, in that some z-80 BIOS' were written in such way that the index registers of the z-80 as well as the alternate register set were used as temporary storage between calls, and applications that used these registers would bomb on machines that expected those values to still be there. CP/M itself (for BDOS calls) doesn't preserve any registers. (which led to programs being littered with PUSH B! PUSH D! PUSH H and corresponding pops after each BDOS call) perhaps it would be best to assume the bios doesn't save the special registers in the z-80. but an unacceptable situation is where the BIOS requires the application to not change the value of those registers. sure, CP/M is an 8080 operating system, but since most CP/M machines still working these days are Z-80 based, then perhaps it should be considered a z-80 operating system. writing applications to run under z-80 CP/M should be free to use those registers, but not expect the operating system to preserve the contents. (exception - interrupt handlers.) people who own machines with a BIOS that does store values in special z80 registers would probably have to hack their BIOS so that it doesn't. those writing programs that use special z80 registers should PUSH them before a BDOS call and POP them after the call, assuming they need to save the contents of those registers. -- fzsitvay@techbook.COM - but don't quote me on that.... American Oil Company motto - Bend over, We'll pump!!!