home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
beehive
/
utilitys
/
peek22.arc
/
PEEKBDOS.MAC
< prev
next >
Wrap
Text File
|
1992-05-28
|
10KB
|
393 lines
title 'PEEKBDOS v2.0 RSX for CP/M 2.x'
;
; Taken directly from PEEKBDOS v1.0 (C) by Ron Fowler. Modifications for
; CP/M 2.x by Mark A. Howard.
;
; This program is an RSX running under CP/M 2.x in conjunction with the
; RSX manager (SETRSX) written by Jim Lopushinsky. It's purpose is
; to trace file-related BDOS calls, and display information regarding each
; call on a selected device. It must be combined with the companion module,
; "PEEK22.MAC" in the manner described in the comment section of that file.
;
; PEEK22's output device defaults to the system console, and can be changed
; by doing "peek a" (aux), "peek l" (list), or "peek c" (console). Note
; that "peek p" sets the pause flag, causing the trace to pause after the
; call to bdos. Note also that a "*" is printed at the pause; the program
; then waits for input. Any character other than "Q" will simply cause a
; return to the caller. A "Q" resets the pause flag, and the program then
; displays without pausing.
;
; "PEEK22 Q" removes the RSX from memory.
;
; Note that this RSX uses one level of caller's stack. Also, if you modify
; this code, be VERY careful with the registers; I save only what is absol-
; utely necessary, in order to conserve memory.
;
; Ron Fowler
; Fort Atkinson, WI
; 08/22/83
;
; UPDATE INFORMATION:
;
; -- if you update this program, please pass along a copy to Fort Fone File
; Folder (FFFF) RCP/M, Fort Atkinson, WI: (414) 563-9932 (no ringback).
; Please update the version number in both modules (PEEK22.MAC also).
;
; updates (in reverse order to minimize reading time):
;
; 1.0 originally written by Ron Fowler 08/22/83
; 2.0 modified for CP/M 2.x 09/12/84
;
; Removed duplicate RSX check, as CP/M 2.2 does not return the
; desired code in AC. Moved check to TPA module, as that is
; where RSX is loaded anyway. - Mark Howard - SYSOP
; CNY Technical RCP/M
; (315) 437-4890 300/1200
;
;------------------------------------------------------------
;
; CP/M equates
;
conotf equ 2 ;output character to console
auxotf equ 4 ;aux output
lstotf equ 5 ;list output
diriof equ 6 ;direct console i/o
printf equ 9 ;print string function
openf equ 15 ;open file
closf equ 16 ;close file
srchf equ 17 ;search for file 1st occurance
srchn equ 18 ;search for file next occurance
erasf equ 19 ;erase file
readf equ 20 ;read sequential
writf equ 21 ;write sequential
creat equ 22 ;create file
renmf equ 23 ;rename file
sdmaf equ 26 ;set transfer address
rdran equ 33 ;read random
wrran equ 34 ;write random
;
; character equates
;
cr equ 13 ;carriage-return code
lf equ 10 ;linefeed code
;
;
;
; RSX prefix
;
db 0,0,0,0,0,0 ;space for CPM3 to insert serial #
jmp begin ;jump to entry point
next: db jmp ;jump instruction op-code
dw 0 ;next RSX or loader
dw 0 ;previous RSX or 0
rmvflg: db 0 ;removes RSX when non-0
db 0 ;flag for non-banked only
myname: db 'PEEKBDOS' ;our name
db 0 ;loader flag
db 0,0 ;reserved
;
; This is the BDOS call intercept. Here we determine if the
; call is one of those we process. If not, we simply pass
; control on to the next module.
;
begin: mov a,c ;get function code
cpi 60 ;for RSX's only?
jz rsxfnc ;go if so
lxi h,fnctbl ;nope, test for one of ours
scan: mov a,m ;get first/next table opcode
inx h
ora a ;end-of-table?
jz next ;then quit now
cmp c ;ours?
jz trap ;go trap if so
mvi a,6 ;nope, calculate next table entry
call addha
jmp scan ;continue
;
; Here when we've determined that we must display the system call.
; First save caller's stackpointer and load a local stack.
;
trap: shld tblptr ;save pointer to function string
lxi h,0 ;get user's sp
dad sp
shld spsave
lxi sp,stack ;load local stack
;
; begin the trace: do newline, then print the function string
;
mvi a,cr ;carriage
call type
mvi a,lf
call type
lhld tblptr ;get string pointer
call prathl ;print it
call ilprnt ;colon, open paren
db ': '
db '('+80h
;
; print fcb address (or dma address)
;
mov a,d ;get parameter hi
call hexout
mov a,e ;then lo
call hexout
call ilprnt ;closing paren
db ')',' '+80h
mov a,c ;get function code
cpi sdmaf ;set-dma?
jz exit ;then done
;
; Not setdma function. Print out the FCB information
;
push d ;save fcb pointer
ldax d ;get drive code
inx d
call hexsp ;print hex byte, space
;
; Print the file name
;
mvi b,11 ;eleven characters
fnprnt: ldax d ;get first/next char
inx d ;advance fcb pointer
call type ;print it
dcr b ;all 11
jnz fnprnt
mvi a,' ' ;separate filename
call type
;
; print ex,s1,s2,rc
;
mvi b,4 ;four of these
lxi h,idbase ;ascii id's for each field
idloop: call prathl ;print id
ldax d ;get field
inx d ;advance fcb pointer
call hexsp ;print in hex, space
dcr b ;all 4
jnz idloop
;
; print the nr field
;
call prathl ;last id string
lxi h,16 ;offset to nr field
dad d
mov a,m ;fetch it
call hexout ;print it
pop d ;restore fcb pointer
;
; here after fcb info printed. Allow the call to pass upward,
; then print the returned value.
;
exit: call next ;give call to bdos
shld hlsave ;save returned registers
push d
push b
push psw ;save returned value
lxi h,rtnmsg ;print "Ret: "
call prathl
pop psw ;restore, resave returned a
push psw
call hexout ;print it in hex
lda pause ;do a pause?
ora a
jz nopaus ;jump if not
call ilprnt ;yep, print prompt
db ' ','*'+80h
mvi c,diriof ;get a character
mvi e,0FDH ;don't come back 'till we have one
call next
ani 5fh ;convert char to upper case
cpi 'Q' ;quit-pause?
jnz nopaus ;no
xra a ;yes
sta pause
nopaus: pop psw ;restore 'em all
pop b
pop d
lhld spsave ;restore stackpointer
sphl
lhld hlsave
ret ;back to caller
;
; Handler for function 60: call RSX. Here we insure that the
; call is for us. The RSX parameter block passed in DE must
; contain two parameters, the first of which is a pointer to
; our name (near absolute insurance that there won't be any
; confusion). The second parameter is a pointer to a request
; code (one of: "Q", quit, "C", console, "L", list, "A", aux).
;
rsxfnc: push d ;save user de
xchg ;rsx pb pointer to hl
inx h ;ignore function code
mov a,m ;get # parameters
cpi 2 ;two?
jnz pass ;quit if not
inx h ;skip # of parameters
mov e,m ;fetch parameter #1
inx h
mov d,m
inx h ;hl points to 2nd parm
shld spsave ;save that pointer
lxi h,myname ;check for our name
mvi b,8 ;8 characters
ckname: ldax d ;compare first/next character
inx d
cmp m ;compare with our name
inx h
jnz pass ;if fails, pass to next rsx
dcr b ;all 8
jnz ckname
;
; rsx request is for us, get rsx pointer, load 2nd parameter
;
pop d ;recall passed parameter
lhld spsave ;get rsx pointer
mov a,m ;fetch next parameter
inx h
mov h,m ;into hl
mov l,a ;hl points to request
inx h ;point to pause flag
mov a,m ;fetch it
cpi 0ffh ;null? (don't alter pauseflag)
jz pntreq ;jump if so
sta pause ;no, stuff it
pntreq: dcx h ;point to request
mov a,m ;fetch request
;
; a now has the function request character passed from the tpa
;
cpi 'Q' ;quit?
jz quit
cpi 'A' ;output to aux?
mvi c,auxotf ;prep function code
jz setout
cpi 'C' ;output to console?
mvi c,conotf ;prep code
jz setout
mvi c,lstotf ;process of elimination (list)
setout: mov a,c ;get new output device code
sta curdev ;stuff it
xra a ;return a=0
ret
;
; here when call 60 is not for us
;
pass: pop d ;clear stack
jmp next ;to next rsx
;
; here to quit
;
quit: mvi a,0ffh ;flag loader to remove us
sta rmvflg
xra a ;we still return 0
ret
;
; ***************
; * subroutines *
; ***************
;
; print in-line message terminated by char w/bit7=1
;
ilprnt: xthl ;msg pointer to hl
call prathl ;print it
xthl
ret
;
; print string pointed to by hl, until char w/bit7=1
;
prathl: mov a,m ;fetch first/next char
inx h ;advance pointer
call type ;print it
ani 80h ;terminator?
jz prathl ;continue if not
ret
;
; output a in hex, followed by space
;
hexsp: call hexout ;print it
mvi a,' '
jmp type
;
; output a as 2 hex digits
;
hexout: push psw ;save it
rrc ;hi nybble into lo
rrc
rrc
rrc
call nybble ;print it
pop psw ;now restore, fall into lo
nybble: ani 0fh ;zap any garbage in hi nybble
adi 90h ;this little beauty...
daa ;...is from the old (and maybe
aci 40h ;...still existing) Intel library
daa ;fall into type
;
; type char in a on console via current output device.
;
type: push psw ;save all
push h
push d
push b
ani 7fh ;allow no parity bits to pass
mov e,a ;align character
lda curdev ;get device function code
mov c,a
call next ;output the character
pop b ;clean up
pop d
pop h
pop psw
ret
;
; add a to hl
;
addha: add l
mov l,a
rnc
inr h
ret
;
; Table of locally-processed system function calls. Format is function
; code followed by id string. Note that more functions may be added to
; this table, but if they are not fcb-related functions, you'll have to
; modify the TRAP routine to process the new data types.
;
fnctbl: db openf,'opnfi','l'+80H
db closf,'clsfi','l'+80H
db readf,'rd se','q'+80H
db writf,'wr se','q'+80H
db sdmaf,'setdm','a'+80H
db srchf,'srch ','1'+80H
db srchn,'srch ','n'+80H
db renmf,'renam','e'+80H
db erasf,'erase',' '+80H
db rdran,'rd ra','n'+80H
db wrran,'wr ra','n'+80H
db creat,'creat','e'+80H
;
db 0
;
; table of fcb id strings
;
idbase: db 'ex','='+80h
db 's1','='+80h
db 's2','='+80h
db 'rc','='+80h
db 'nr','='+80h
;
rtnmsg: db ' Ret:',' '+80h
;
; data area
;
curdev: db auxotf ;system-call # for output
pause: db 0 ;non-0 = pause after bdos calls
tblptr: dw 0 ;saved pointer into fnctbl
hlsave: dw 0 ;save for hl
spsave: dw 0 ;stackpointer save
ds 24 ;12-level stack
stack:
;
;
end