home *** CD-ROM | disk | FTP | other *** search
- ; From Dr. Dobb's Journal, Number 73, November 1982, pp. 6
-
- ; A letter from Oscar Goldman, extracted from
- ; CP/M EXCHANGE by Gene Head
-
- ; Dear Gene,
- ; This scheme is based on intercepting calls to the BDOS. The
- ; only visible entry point into the BDOS is the jump instruction
- ; at the absolute memory address of 5. WHile it might seem a
- ; simple matter to change the address at 6 and 7 in order to
- ; effect the interception, many applications programs (e.g., DDT)
- ; determine memory size from the information contained there.
- ; Therefore, it would seem prudent to leave the content of 6 and
- ; 7 alone. Fortunately, for our purpose, the instruction jumped
- ; to from 5 is also a jump instruction. This observation is the
- ; key to the interception process.
- ; Here is an outline of the modifications to be made in the
- ; BIOS. (If necessary, change the identifiers to avoid
- ; duplication.)
- ; Add the following two equates:
-
- ; MAXFUN EQU 49 ; Last of the standard BDOS function numbers
- ; EXTRA EQU ? ; Replace the "?" with the actual number
- ; of new BDOS calls. The new function
- ; numbers will start from 50.
-
- ; Toward the end of the warm boot, there is a routine called
- ; "gocpm". (This name is used by Digital Research in the listing
- ; of the skeletal CBIOS.) Somewhere in there will be found the
- ; two lines:
-
- ; LXI H,BDOS
- ; SHLD 6
-
- ; Immediately after these, insert the following 4 lines:
-
- ; LHLD BDOS+1
- ; SHLD NORMAL+1
- ; LXI H,DIVERT
- ; SHLD BDOS+1
-
- ; and finish with the rest of "gocpm".
- ; At a convenient point in the BIOS, add the following:
-
- NORMAL: EQU JMP 0 ; The 0 will be replaced during
- ; the warm boot.
- DIVERT:
- ; This point is reached with the function number in C
- ; and the BDOS call information in DE.
- MVI A,MAXFUN
- CMP C ; Is it an old or new call?
- JNC NORMAL ; Old ones are diverted to NORMAL.
- ADI EXTRA
- CMP C ; Are we exceeding the number of
- ; allowed calls?
- JNC OKAY ; Continue if not.
- LXI H,0 ; Protocol requires these registers
- ; to be zeroed for out-of-range calls.
- RET
- ;
- OKAY:
- ; Here we handle the new functions
- LXI H,0 ; HL is lost.
- DAD SP
- SHLD SAVSTK ; Save the stack pointer for later return,
- LXI SP,SAVSTK ; and set up a local stack.
- XCHG
- SHLD NTRPAR ; Save the entry parameters.
- LXI D,FIN
- PUSH D ; A place to return to when done.
- MOV A,c
- SBI MAXFUN+1 ; Start counting from 0.
- ADD A ; Double it
- MOV E,A
- MVI D,0
- LXI D,TABLE
- DAD D ; HL points to the revelent table entry.
- MOV E,M ; Get the address
- INX H ; contained there,
- MOV D,M ; and move it
- XCHG ; into HL.
- PCHL ; Go do it.
- ;
- FIN:
- ; Return to here when done.
- LHLD SAVSTK
- SPHL ; Restore old stack pointer.
- LHLD XITPAR ; Get the result of the routine.
- MOV A,L
- MOV B,H ; As per CP/M protocol.
- RET ; All done.
- ;
- TABLE:
- ; Jump table for the various new BDOS calls.
- ; There should be one entry for each of "EXTRA" items.
- NEW0: DW DONEW0
- NEW1: DW DONEW1
- ...
- ...
- ;
- NITPAR: DS 2 ; Save the entry value of DE.
- XITPAR: DS 2 ; Save the result of the BDOS call.
- DS 40 ; Ample local stack -
- ; change this if necessary.
- SAVSTK: DS 2 ; Save the stack pointer on entry.
- ;
- ; Each of the following routines must end with a RET instruction.
- ; If the routine returns a value, then it should be stored in XITPAR.
- ;
- DONEW0: ; Actual routine #0.
-
- DONEW1: ; Actual routine #1.
-
- etc.
-