CPMBIOS.S Bug Report CPMBIOS.S Bug Report CPMBIOS.S Bug Report Robert Heller Robert Heller Robert Heller Fri May 16, 1986 Fri May 16, 1986 Fri May 16, 1986 Chapter 1: The Problem I encountered the problem while working with the Special BIOS function (number 17) to change the shell Special Special address. The problem was, the shell address would not be set to the address I passed in (via A0). Instead, the system would effectively crash. I checked my code carefully and after being satisfied that my code was correct, I looked at CPMBIOS.S to see if there was a problem there. There was. Here is the code at the special special special label: ****************************************************************************** * * Special Entry Point. * * This BIOS function performs special functions. Register D1 is * further decoded into additional functions. * * Function codes: * * 0 set terminal control characters * 1 set shell entry address * 2 unused * 3 turn on BIOS Xon/Xoff stalling * 4 turn off BIOS Xon/Xoff stalling * 5 return pointer to environment space * special: cmp.w #5,d1 ; check the range of the BIOS function code bhi badcode ; jump if the code is out of range lsl.w #2,d1 ; convert the code to a table offset lea spectbl,a0 ; point to the base of the special table move.l 0(a0,d1.w),a0 ; fetch the address of the routine jsr (a0) ; go execute the routine badcode: rts ; return to caller spectbl: .dc.l setterm ; set the terminal control characters .dc.l setshell ; set the shell entry address .dc.l badcode ; unused .dc.l stallon ; turn on BIOS Xon/Xoff stalling .dc.l stalloff ; turn off BIOS Xon/Xoff stalling .dc.l getenvp ; return a pointer to the environment space This code uses a jump table to decode the sub-functions. Register A0 is used to access the jump table. Thus any shell address passed in A0 is invariably clobbered. Chapter 2: The Fix To fix this bug, I modified CPMBIOS.S to use register D2 to pass in the new shell address instead of A0. The code is as follows: ****************************************************************************** * * Set Shell Entry Address. * * This is a Special Function. It allows you to set the entry * address of a shell. The entry address is jumped to on warm boot. * The default shell entry address is _ccp. * ********This is wrong. it must never have been tested. * A0 contains the new shell entry address. The old shell entry * address is returned in D0. ******** ** changed to use D2 to hold new shell address. RPH Thr Feb 6, 1986 * setshell: move.l shell,d0 ; return the old shell address in D0 * move.l a0,shell ; set the new shell entry address move.l D2,shell ; set the new shell entry address (patch RPH) rts ; return to caller After making this change to CPMBIOS.S and rebuilding and reinstalling CPM.SYS, my program which changed the shell address worked.