BDOS calls in CP/M 2.2

General discussions related to the Altair 8800 Clone

BDOS calls in CP/M 2.2

Postby mail@gabrielegan.com » April 14th, 2017, 5:59 pm

Does anyone know where to find a list of just which BDOS calls in CP/M 2.2 trash which registers, or should a programmer assume that all registers will be trashed by a BDOS call? I ask because I had some code that was behaving oddly around a BDOS call for the function WRTCHAR (02h) that puts a single character (passed using register E) onto the console.

I knew that my contents in register BC would be trashed, since the 02h code specifying this function is passed via register C, and that my contents in register DE would be trashed, since the character to be output is placed in register E. But I did not expect my contents in register HL to get trashed too. The code would not work until I also saved HL by PUSHing it before the BDOS call and POPping it afterwards.

Is the sensible thing to do just to PUSH everything (A, PSW, B, C, D, E, H, and L) onto the stack before a BDOS call and POP them all back again after? Seems like a pain to have to do this each time.

Regards

Gabriel
mail@gabrielegan.com
 
Posts: 104
Joined: October 11th, 2014, 8:12 am

Re: BDOS calls in CP/M 2.2

Postby AltairClone » April 14th, 2017, 9:07 pm

You should assume that all registers are trashed whenever a call is made to the BDOS. You don't have to blindly save all registers every call, just those registers that your code requires to remain unmodified from before to after the BDOS call.

Mike
AltairClone
Site Admin
 
Posts: 632
Joined: April 5th, 2013, 10:55 am

Re: BDOS calls in CP/M 2.2

Postby mail@gabrielegan.com » April 15th, 2017, 11:05 am

Thanks, MIke, that's useful to know. The trouble with saving only the registers that contain values I'm using is that I may be relying, at a distant point in the code, on the preservation of a value in a register that I'm not actively using around the point where I make the BDOS call. This may be bad programming style on my part. That is, I may be using registers to hold onto values right across my code when I should in fact be using memory locations to do that and loading their contents into registers as and when I need to work on them. I'll try that in the next bit of programming. The Assembler in CP/M 2.2 does such a great job of managing labels to make pseudo-variables that I should probably exploit it more. Do you recommend any particular books on good style in assembly language programming? I'm using Waite & Lafore's 'Soul of CP/M' and Intel's '8080/8085 Assembly Language Programming Manual'.

Regards

Gabriel
mail@gabrielegan.com
 
Posts: 104
Joined: October 11th, 2014, 8:12 am

Re: BDOS calls in CP/M 2.2

Postby AltairClone » April 16th, 2017, 8:48 am

There is nothing wrong with dedicating a register or two to permanently hold frequently accessed values throughout the execution of a program or section of a program. Even if these registers are not accessed immediately before or after the BDOS call, they still fall into the "must be saved across the BDOS call" category.

As far as programming style goes, I love the days of the 8080 because programming "tricks" for speed optimization and/or saving a few bytes of code were often an important part of the solution. As long as you clearly comment the why and how of the "tricks" in your code, I think it's period-appropriate coding. With more modern processors, I'd recommend coding in a clean, logical fashion that a subsequent programmer is less likely to be confused by. Write your code such that another programmer's assumptions of what your code is doing at a quick glance are probably correct. It may not be the absolute fastest or smallest solution, but it works just fine and is more maintainable.

Just my thoughts.

Mike
AltairClone
Site Admin
 
Posts: 632
Joined: April 5th, 2013, 10:55 am


Return to General Discussions

Who is online

Users browsing this forum: No registered users and 19 guests

cron