home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
BEEHIVE
/
UTILITYS
/
C10CPM.ARC
/
CPM1.Z80
< prev
Wrap
Text File
|
1990-07-21
|
10KB
|
299 lines
; CPM RSX program for the Cromemco C-10 running CDOS vers 3.07
; written by Brett and John Hunter.
;
; Version :- 1.02
; 13/07/86
DEST: EQU 0E100H ;Destination
DEST1: EQU 0E1H ;
; The Destination should be about 200H less than the bottom of Cdos.
; The bottom of Cdos can easily be found by looking at bytes 6 and 7.
;
; Dest1 is just the first byte of Dest, and is used in the system
; call 151 (changing the bottom of Cdos)
;
CDOS: EQU 0005H
WARMBT: EQU 0000H
CDOSC: EQU 0E409H ; CDOS call routine location (1st jump in cdos)
; Cdosc is the address found at the first and third jumps of the
; jump table (the beginning of the jump table is pointed by bytes 6 & 7)
; And for all Cdos users that think Cdos has a jump table like the
; CP/M jump table, you are totally wrong. The Cdos jump table consists
; of only three jumps in the form
; JP CDOSC
; JP CDOSB
; JP CDOSC
;
CDOSB: EQU 0E418H ; CDOS warm boot routine (2nd jump in cdos table)
CDOSR: EQU CDOSB-1 ; CDOS RET (just before warm boot routine)
; Cdosr is the address of the "RET" of Cdos. ie. this is the RET that
; returns the system call to the calling program (the users program).
; Its location can be found by the fact that the system calling routines
; finish just before the warm boot routines. This is why it is Cdosb-1.
; We intercept the "RET" so we can fix up the returning parameters of certain
; system calls. We do this by changing the RET to a RST (it must be
; 1 byte only). We have chosen RST 10H since we think that this location is
; not used by any (or few) programs. If a program does use locations 10H-12H
; then I suggest that you change first part of this program so that you
; load the jump in at, say 18H etc, and so that it is a RST 18H, etc.
LF: EQU 0AH
CR: EQU 0DH
ORG 100H
BEGIN: LD DE,MESSAGE ; Print overlay message.
LD C,09 ;
CALL CDOS ;
LD C,97H ; Change bottom of Cdos with call 151 (97H)
LD E,DEST1 ; The new bottom is now (DEST1 00H)
CALL CDOS ;
LD A,195 ; loading location 10H with "JP"
LD (10H),A ;
LD HL,MODS ; loading location 11-12H with the location
LD (11H),HL ; of the "call modification routines".
LD A,215 ;
LD (CDOSR),A ; changing the RET to a RST 10H in high cdos.
; you can change LD (10H),A to LD (18H),A and LD (11H),HL to LD (19H),HL
; and LD A,215 (D7H) to LD A,0DFH if you want the "interceptor" jump at
; another location other than 10H. (in this example 18H)
MOVEUP: LD BC,PEND-START+1 ;number of bytes to move
LD HL,DEST+PEND-START+1;end of moved code
LD DE,SOURCE+PEND-START;end of source code
MVLP: LD A,(DE) ;get byte
DEC HL ;bump pointers
LD (HL),A ;new home
DEC DE
DEC BC ;bump byte count
LD A,B ;check if zero
OR C
JP NZ,MVLP ;if not, do some more
; You could possibly change this to an LDDR, but I am not sure.
SOURCE: EQU $
OFFSET: EQU DEST-SOURCE
START: EQU $+OFFSET
JP FIRSTJ ;Change the jump table to redivert a system
JP CDOSB ;call
JP FIRSTJ ; No adjustments on warm boot, so let it pass.
;
; System call 151 puts a new 3 Jp jump table in at locations DEST1 00 to
; DEST1 09. We now overlay this jump table with our own jump table. In fact
; the entire process of changing the bottom of cdos can be done by
; locating where Cdos stores the old and new bottom of cdos and changing the
; bytes of the new bottom of cdos to your own and then putting in your jump
; table. We opted for the system call 151 since it was easier and smaller.
; The location of where cdos stores the locations of CDOS OLD and CDOS NEW
; can be found by using system call 81H and then adding 7 to the DE register
; to get .SYSBOT (NEW BOTTOM OF CDOS) and 9 to the DE to get .SYSBOL (Old)
; If no relocating of Cdos has occurred then OLD=NEW.
FIRSTJ: EQU $+OFFSET
LD (STCAL),BC ;stores the system call for later retrival.
PUSH AF ;
LD A,C ; if the system call is 20H (set/change user
CP 20H ; area) then go to our own routines and not
JP Z,USERC ; Cdos's.
CP 1AH
JP Z,SETBUF ; if call is 1AH (set file buf) then go to
; routine to store where they are setting
; the buffer at. (needed for user areas)
POP AF
JP CDOSC ; now let the call continue on its way to
; CDOS.
SETBUF: EQU $+OFFSET ; keep a record of where the file buffer
LD (SDMA),DE ; is kept, since we need it later.
POP AF
JP CDOSC
USERC: EQU $+OFFSET
LD A,E ; if E contains FF then load A with the
CP 0FFH ; value store at UCODE, else if E is not
JP NZ,USERC2 ; FF then store E at the address UCODE.
POP AF
LD A,(UCODE)
RET
USERC2: EQU $+OFFSET
LD (UCODE),A
POP AF ;.return to the calling program (NOTE: this
RET ; call never goes to CDOS since CDOS does
; not do anything with it)
MODS: EQU $+OFFSET
LD (TEMP),HL ;fixs the stack, because of RST instead of
POP HL ;the normal RET
LD HL,(TEMP) ; (could be a simplier way to do it)
JP PUSHER ;saves all registers.
;
; The code MODS is needed since when the Z80 does a "call" it pushs the
; address of where it was on the stack. Since the program calls CDOS
; and we have no RET, then there is an extra address on the stack.
; MODS merely gets rid of it. We do not know if this is proper or not
; but it works. If anyone has any suggestions or comments please send
; us them at the address in the DOC file
;
MOD2: EQU $+OFFSET
LD BC,(STCAL) ; has just returned from the system call and
LD A,C ; we now look what call it was.
CP 15 ;.is it call 15? If yes then go to M15
JP Z,M15 ; (not sure if these calls (15,16) need
CP 16 ; to be fixed) (wont hurt)
JP Z,M15
CP 17 ;.if 17 then also go to M18 (this is
JP Z,M18 ; a very important fix for call 17)
CP 18 ;.if 18 then go to M18, a special mod.
JP Z,M18 ; for this call (to include user areas)
CP 22 ;.possibly needs to be fixed, it wont hurt
JP Z,M15 ; even if it doesn't (insurance)
CP 27 ;.if call=27 then go to routine to fix it.
JP Z,M27 ; (this is the allocation map call)
POP AF ;.if it was not any of the above calls
POP HL ; then restore all the registers and
POP DE ; return to the calling program.
POP BC
; Cdos calls and all other calls not specified above are not changed in any way
; and thus should not effect the program in any way. So the system calls
; 128 (80H) to 164 (A4H) still function as usual.
RET ;returns to user program
M15: EQU $+OFFSET ; fix up calls
POP AF ; 15,16,21.
CP 255 ; if 255 (FF) then don't do anything
JP Z,POPER+1
AND 03 ; else (and 3) and return to user program.
JP POPER+1
M18: EQU $+OFFSET ; fix up calls 17,18
POP AF ;
CP 255 ; if 255 (FF) then don't do anything
JP Z,POPER+1
AND 03 ; else (and 3)
PUSH AF ; We now find out where the FCB's are and
CP 00 ; which one we are pointing at. (in the
CALL Z,M18A ; file buff)
CP 01 ;
CALL Z,M18B
CP 02
CALL Z,M18C
CP 03
CALL Z,M18D
; NOTE: Cdos has no user codes and thus we are using the attribute bits
; (eg USER,WRITE,READ,SYS) as our "user areas" (ie by changing the attr
; bits we can change the files user code.)
; This is a bit crude but is useful in BBS programs such as ROS that need
; user areas to seperate files. It is useless in most other applications.
; This is explained more in the DOC file.
EX DE,HL
LD HL,UCODE
LD A,(DE) ; We get the first byte of the FCB
RRCA ; and rotate it so the attribute bits
RRCA ; are now the first four bits
RRCA
RRCA
AND 00001111B ; we (and) out the drive code.
CP (HL)
JP NZ,MORE
POP AF
JP POPER+1
M18A: EQU $+OFFSET
LD HL,(SDMA)
RET
M18B: EQU $+OFFSET
LD HL,32
LD DE,(SDMA)
ADD HL,DE
RET
M18C: EQU $+OFFSET
LD HL,64
LD DE,(SDMA)
ADD HL,DE
RET
M18D: EQU $+OFFSET
LD HL,96
LD DE,(SDMA)
ADD HL,DE
RET
MORE: EQU $+OFFSET
POP AF
POP BC
POP DE
POP HL
LD C,18 ; if the user code is not that of the file then
CALL 0005 ; go do the call again.
; If the file has its attribute bits that corresponds to the current User area
; then the call is finished, but if they don't we do the system call again
; until we either find a file or the dir is exhausted.
M27: EQU $+OFFSET ; pop back the registers but in the
POP AF ; wrong order, as so to swap BC and HL
POP BC ; So CDOS is now like the proper thing
POP DE ; except it returns more values that CPM
POP HL ; does.
RET
PUSHER: EQU $+OFFSET
PUSH BC
PUSH DE
PUSH HL
PUSH AF
JP MOD2
POPER: EQU $+OFFSET
POP AF
POP HL
POP DE
POP BC
RET
STCAL: EQU $+OFFSET
DEFW 0
UCODE: EQU $+OFFSET ; storage area for current user area
DEFB 0
SDMA: EQU $+OFFSET ; storage area for file buff address
DEFW 80H,00 ; defaults to 80H
TEMP: EQU $+OFFSET ; trash collection
DEFW 0
PEND: EQU $+OFFSET
JP WARMBT
MESSAGE DEFB 'CP/M OVERLAY for CROMEMCO C-10. Vers 1.02',CR,LF
DEFB 'Copyrighted by Brett and John Hunter 13/7/86',CR,LF,'$'
END BEGIN