home *** CD-ROM | disk | FTP | other *** search
- ;RSXDEMO.ASM version 1.0 Copyright (c) 1983 by George F Peace 7-15-83
-
- ;This is a demonstration of a Resident System Extension (RSX) under CP/M Plus.
- ;The routine intercepts all console-related BDOS function calls and displays
- ;the function number for each one called. If BDOS was CALLed via address 0005h,
- ;the address of the CALL will also be displayed.
-
- ;See RSXDEMO.DOC for information on RSX configuration and operation.
-
- conout equ 2 ;output character to console
- pstring equ 9 ;print string function
- cr equ 00dh
- lf equ 00ah
- esc equ 01bh
-
- ; BDOS function 60 sub-functions used by this RSX
-
- rsxfunc1 equ 13 ;RSX initialize function code
- rsxfunc2 equ 14 ;RSX terminate function code
-
- ; RSX Prefix Structure
-
- serial: db 0,0,0,0,0,0 ;room to insert serial number
- start: jmp ftest ;beginning of program
- next: db 0C3H ;jump instruction op-code
- dw 0 ;next module in line (or BDOS)
- prev: dw 0 ;previous module
- remov: db 00h ;remove flag clear
- nonbnk: db 0 ;>0 to load only in non-banked CP/M
- rsxnam: db 'RSXDEMO ' ;the name of this RSX
- loader: db 0 ;loader flag
- db 0,0 ;reserved
-
- ftest:
-
- ;The first thing we want to do is save the caller's environment to allow
- ;normal processing of the BDOS request in the next (and subsequent) RSX.
-
- push h ;save caller's hl on the original stack
- lxi h,0 ;clear hl
- dad sp ;compute caller's stack address
- shld ret$stack ;save so we can restore caller's environment
- lxi sp,loc$stack ;load new stack address
- push d ;save caller's de on local stack
- push b ;save caller's bc on local stack
-
- ;Pick up the BDOS function number and test for one of those getting
- ;special treatment.
-
- mov a,c ;get BDOS function
- cpi 0 ;warm boot?
- jz finish ; yes - ignore it
- cpi 50 ;direct BIOS call?
- jz bdos50
- cpi 60 ;one of my calls?
- jz bdos60
- cpi 111 ;print block?
- jz bdos111
- cpi 112 ;list block?
- jz bdos112
- cpi 12 ;less than 12?
- jnc finish ;nope - not my call
- cpi 1 ;console input?
- jz bdos1
- cpi 2 ;console output?
- jz bdos2
- cpi 3 ;aux: input?
- jz bdos3
- cpi 4 ;aux. output?
- jz bdos4
- cpi 5 ;list output?
- jz bdos5
- cpi 6 ;direct console i/o?
- jz bdos6
- cpi 7 ;aux: input status?
- jz bdos7
- cpi 8 ;aux: output status?
- jz bdos8
- cpi 9 ;print string?
- jz bdos9
- cpi 10 ;read console buffer?
- jz bdos10
- cpi 11 ;console status?
- jz bdos11
- jmp finish
-
- bdos1:
- jmp bdostrap
-
- bdos2:
- jmp bdostrap
-
- bdos3:
- jmp bdostrap
-
- bdos4:
- jmp bdostrap
-
- bdos5:
- jmp bdostrap
-
- bdos6:
- jmp bdostrap
-
- bdos7:
- jmp bdostrap
-
- bdos8:
- jmp bdostrap
-
- bdos9:
- jmp bdostrap
-
- bdos10:
- jmp bdostrap
-
- bdos11:
- jmp bdostrap
-
- bdos50:
- jmp bdostrap
-
- bdos60:
- ;This is the RSX-specific BDOS call. Check to see if it's one of our own.
- ;It might be necessary to add checks for both function and parameter match
- ;before assuming that this is for us in case multiple RSXs are in effect.
- ldax d ;get RSX function number from parameter block
- cpi rsxfunc1 ;is it initialize?
- jz rsxinit ;yes - initialize the RSX environment
- cpi rsxfunc2 ;is it terminate?
- jnz finish ;no match - continue
- lda remov ;get RSX remove flag
- cpi 0FFh ;already flagged to be removed?
- jz finish ;yes - exit with no further activity
- mvi a,0FFh ;get remove flag
- sta remov ;flag to drop this RSX on next warm boot
- jmp finish ;finished with RSX function, continue
- rsxinit:
- mvi c,pstring ;print string on console
- lxi d,initmsg ;print initialization message
- call next ;call next RSX
- jmp finish ;exit this RSX
-
- bdos111:
- jmp bdostrap
-
- bdos112:
- jmp bdostrap
-
- bdostrap:
- ;General BDOS function trap routine.
- ;This routine displays pertinent data about the BDOS call being performed.
- mvi c,pstring ;display string on console
- lxi d,string1 ;first part of trap message
- call next ;call next RSX
-
- pop b ;retrieve bc register pair
- push b ;replace bc pair on stack
- mov a,c ;position the BDOS function for print
- call outbyte ;print as two hex digits
- mvi c,pstring ;print string on console
- lxi d,string2 ;finish up trap notification
- call next ;call next RSX
-
- lhld ret$stack ;get caller's stack address
-
- ;Check the three bytes preceding the address stored at the top of the caller's
- ;stack. If the instruction was (or at least looks like) a CALL 5, print its
- ;address. Although the code checks for both Jxx and Cxx instruction op-codes,
- ;only the Cxx codes will be encountered as the Jxx instructions don't update
- ;the stack.
- inx h ;move up to previous entry on stack since
- inx h ; our initialization added HL to the stack
- mov e,m ;get low order byte of last entry on stack
- inx h ;point to next byte on stack
- mov d,m ;get high order byte of last entry on stack
- xchg ;move stack entry to HL
-
- dcx h ;point to high byte of possible call/jmp 5
- mov a,m ;get the byte
- cpi 00h ;is it 00h (as in call/jmp 0005)?
- jnz nobdos ;no - skip display
- dcx h ;point to low byte of possible call/jmp 5
- mov a,m ;get the byte
- cpi 05h ;is it 00h (as in call/jmp 0005)?
- jnz nobdos ;no - skip display
- dcx h
- mov a,m
- ;all the jmp/call series instructions have bits 6 and 7 set to 1
- ani 0c0h ;and out all bits except the common ones
- cpi 0c0h ;have (likely) match on opcode?
- jnz nobdos ;not a match - skip display
- bdosaddr:
- push h ;hl points to call/jmp BDOS
- mvi c,pstring ;print string on console
- lxi d,string3 ;print call address header
- call next ;call next RSX
- pop h ;retrieve BDOS call address
- call printhl ;display address in HL
- call space ;print a space
- nobdos:
- jmp finish
-
- finish:
- ;We're finished with the BDOS call. Restore the caller's original environment
- ;and pass control to the next RSX or BDOS.
- pop b ;restore caller's bc
- pop d ;restore caller's de
- lhld ret$stack ;restore user stack address
- sphl ;load stack pointer
- pop h ;load caller's hl
- jmp next ;pass control to next RSX
-
- ;------ subroutines ------
-
- outbyte:
- ;display the single byte in the accumulator as two hex digits
- push psw ;save the byte
- rrc ;shift accumulator right 4 bits
- rrc
- rrc
- rrc
- call outnib ;print high digit
- pop psw ;restore byte
- jmp outnib ;print low digit
- outnib:
- ani 0fh ;mask 4 bits
- adi 90h ;add offset
- daa ;dec adjust
- aci 40h ;add offset
- daa ;dec adjust
- mov e,a ;to E for output
- mvi c,conout ;console output request
- jmp next ;call BDOS
-
- printhl:
- ;print HL on the console as four hex digits
- push h ;save address
- mov a,h ;position H for display
- push h ;save address on our stack
- call outbyte ;display the high order byte
- pop h ;restore address
- mov a,l ;position L for display
- call outbyte ;display the byte
- pop h ;restore address
- ret
- space:
- ;print a single space on the console
- mvi c,conout ;console output request
- mvi e,' ' ;outout a space
- call next ;call BDOS
- ret
-
- ;------ literals ------
-
- initmsg:
- db cr,lf,'RSXDEMO has been loaded'
- db '$'
-
- string1:
- db cr,lf,'BDOS function '
- db '$'
-
- string2:
- db 'h trapped '
- db '$'
-
- string3:
- db 'at address '
- db '$'
-
- ret$stack:
- ;caller's stack pointer
- dw 0
-
- ;local stack storage
- ds 40 ; 20 level stack
- loc$stack:
-
- end
- db '$'
-
- ret$stack:
- ;caller's stac