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 / CPM / CPM3 / RSXDEMO.LBR / RSXDMO.AQM / RSXDMO.ASM
Assembly Source File  |  2000-06-30  |  7KB  |  281 lines

  1. ;RSXDEMO.ASM  version 1.0   Copyright (c) 1983 by George F Peace   7-15-83
  2.  
  3. ;This is a demonstration of a Resident System Extension (RSX) under CP/M Plus.
  4. ;The routine intercepts all console-related BDOS function calls and displays
  5. ;the function number for each one called. If BDOS was CALLed via address 0005h,
  6. ;the address of the CALL will also be displayed.
  7.  
  8. ;See RSXDEMO.DOC for information on RSX configuration and operation.
  9.  
  10. conout    equ    2        ;output character to console
  11. pstring    equ    9        ;print string function
  12. cr    equ    00dh
  13. lf    equ    00ah
  14. esc    equ    01bh
  15.  
  16. ;    BDOS function 60 sub-functions used by this RSX
  17.  
  18. rsxfunc1 equ    13        ;RSX initialize function code
  19. rsxfunc2 equ    14        ;RSX terminate function code
  20.  
  21. ;    RSX Prefix Structure
  22.  
  23. serial:    db    0,0,0,0,0,0    ;room to insert serial number
  24. start:    jmp    ftest        ;beginning of program
  25. next:    db    0C3H        ;jump instruction op-code
  26.     dw    0        ;next module in line (or BDOS)
  27. prev:    dw    0        ;previous module
  28. remov:    db    00h        ;remove flag clear
  29. nonbnk:    db    0        ;>0 to load only in non-banked CP/M
  30. rsxnam:    db    'RSXDEMO '    ;the name of this RSX
  31. loader:    db    0        ;loader flag
  32.     db    0,0        ;reserved
  33.  
  34. ftest:
  35.  
  36. ;The first thing we want to do is save the caller's environment to allow
  37. ;normal processing of the BDOS request in the next (and subsequent) RSX.
  38.  
  39.     push    h        ;save caller's hl on the original stack
  40.     lxi    h,0        ;clear hl
  41.     dad    sp        ;compute caller's stack address
  42.     shld    ret$stack    ;save so we can restore caller's environment
  43.     lxi    sp,loc$stack    ;load new stack address
  44.     push    d        ;save caller's de on local stack
  45.     push    b        ;save caller's bc on local stack
  46.  
  47. ;Pick up the BDOS function number and test for one of those getting
  48. ;special treatment.
  49.  
  50.     mov    a,c        ;get BDOS function
  51.     cpi    0        ;warm boot?
  52.     jz    finish        ;  yes - ignore it
  53.     cpi    50        ;direct BIOS call?
  54.     jz    bdos50
  55.     cpi    60        ;one of my calls?
  56.     jz    bdos60
  57.     cpi    111        ;print block?
  58.     jz    bdos111
  59.     cpi    112        ;list block?
  60.     jz    bdos112
  61.     cpi    12        ;less than 12?
  62.     jnc    finish        ;nope - not my call
  63.     cpi    1        ;console input?
  64.     jz    bdos1
  65.     cpi    2        ;console output?
  66.     jz    bdos2
  67.     cpi    3        ;aux: input?
  68.     jz    bdos3
  69.     cpi    4        ;aux. output?
  70.     jz    bdos4
  71.     cpi    5        ;list output?
  72.     jz    bdos5
  73.     cpi    6        ;direct console i/o?
  74.     jz    bdos6
  75.     cpi    7        ;aux: input status?
  76.     jz    bdos7
  77.     cpi    8        ;aux: output status?
  78.     jz    bdos8
  79.     cpi    9        ;print string?
  80.     jz    bdos9
  81.     cpi    10        ;read console buffer?
  82.     jz    bdos10
  83.     cpi    11        ;console status?
  84.     jz    bdos11
  85.     jmp    finish
  86.  
  87. bdos1:
  88.     jmp    bdostrap
  89.  
  90. bdos2:
  91.     jmp    bdostrap
  92.  
  93. bdos3:
  94.     jmp    bdostrap
  95.  
  96. bdos4:
  97.     jmp    bdostrap
  98.  
  99. bdos5:
  100.     jmp    bdostrap
  101.  
  102. bdos6:
  103.     jmp    bdostrap
  104.  
  105. bdos7:
  106.     jmp    bdostrap
  107.  
  108. bdos8:
  109.     jmp    bdostrap
  110.  
  111. bdos9:
  112.     jmp    bdostrap
  113.  
  114. bdos10:
  115.     jmp    bdostrap
  116.  
  117. bdos11:
  118.     jmp    bdostrap
  119.  
  120. bdos50:
  121.     jmp    bdostrap
  122.  
  123. bdos60:
  124. ;This is the RSX-specific BDOS call. Check to see if it's one of our own.
  125. ;It might be necessary to add checks for both function and parameter match
  126. ;before assuming that this is for us in case multiple RSXs are in effect.
  127.     ldax    d        ;get RSX function number from parameter block
  128.     cpi    rsxfunc1    ;is it initialize?
  129.     jz    rsxinit        ;yes - initialize the RSX environment
  130.     cpi    rsxfunc2    ;is it terminate?
  131.     jnz    finish        ;no match - continue
  132.     lda    remov        ;get RSX remove flag
  133.     cpi    0FFh        ;already flagged to be removed?
  134.     jz    finish        ;yes - exit with no further activity
  135.     mvi    a,0FFh        ;get remove flag
  136.     sta    remov        ;flag to drop this RSX on next warm boot
  137.     jmp    finish        ;finished with RSX function, continue
  138. rsxinit:
  139.     mvi    c,pstring    ;print string on console
  140.     lxi    d,initmsg    ;print initialization message
  141.     call    next        ;call next RSX
  142.     jmp    finish        ;exit this RSX
  143.  
  144. bdos111:
  145.     jmp    bdostrap
  146.  
  147. bdos112:
  148.     jmp    bdostrap
  149.  
  150. bdostrap:
  151. ;General BDOS function trap routine.
  152. ;This routine displays pertinent data about the BDOS call being performed.
  153.     mvi    c,pstring    ;display string on console
  154.     lxi    d,string1    ;first part of trap message
  155.     call    next        ;call next RSX
  156.  
  157.     pop    b        ;retrieve bc register pair
  158.     push    b        ;replace bc pair on stack
  159.     mov    a,c        ;position the BDOS function for print
  160.     call    outbyte        ;print as two hex digits
  161.     mvi    c,pstring    ;print string on console
  162.     lxi    d,string2    ;finish up trap notification
  163.     call    next        ;call next RSX
  164.  
  165.     lhld    ret$stack    ;get caller's stack address
  166.  
  167. ;Check the three bytes preceding the address stored at the top of the caller's
  168. ;stack. If the instruction was (or at least looks like) a CALL 5, print its
  169. ;address. Although the code checks for both Jxx and Cxx instruction op-codes,
  170. ;only the Cxx codes will be encountered as the Jxx instructions don't update
  171. ;the stack.
  172.     inx    h        ;move up to previous entry on stack since
  173.     inx    h        ;  our initialization added HL to the stack
  174.     mov    e,m        ;get low order byte of last entry on stack
  175.     inx    h        ;point to next byte on stack
  176.     mov    d,m        ;get high order byte of last entry on stack
  177.     xchg            ;move stack entry to HL
  178.  
  179.     dcx    h        ;point to high byte of possible call/jmp 5
  180.     mov    a,m        ;get the byte
  181.     cpi    00h        ;is it 00h (as in call/jmp 0005)?
  182.     jnz    nobdos        ;no - skip display
  183.     dcx    h        ;point to low byte of possible call/jmp 5
  184.     mov    a,m        ;get the byte
  185.     cpi    05h        ;is it 00h (as in call/jmp 0005)?
  186.     jnz    nobdos        ;no - skip display
  187.     dcx    h
  188.     mov    a,m
  189. ;all the jmp/call series instructions have bits 6 and 7 set to 1
  190.     ani    0c0h        ;and out all bits except the common ones
  191.     cpi    0c0h        ;have (likely) match on opcode?
  192.     jnz    nobdos        ;not a match - skip display
  193. bdosaddr:
  194.     push    h        ;hl points to call/jmp BDOS
  195.     mvi    c,pstring    ;print string on console
  196.     lxi    d,string3    ;print call address header
  197.     call    next        ;call next RSX
  198.     pop    h        ;retrieve BDOS call address
  199.     call    printhl        ;display address in HL
  200.     call    space        ;print a space
  201. nobdos:
  202.     jmp    finish
  203.  
  204. finish:
  205. ;We're finished with the BDOS call. Restore the caller's original environment
  206. ;and pass control to the next RSX or BDOS.
  207.     pop    b        ;restore caller's bc
  208.     pop    d        ;restore caller's de
  209.     lhld    ret$stack    ;restore user stack address
  210.     sphl            ;load stack pointer
  211.     pop    h        ;load caller's hl
  212.     jmp    next        ;pass control to next RSX
  213.  
  214. ;------ subroutines ------
  215.  
  216. outbyte:
  217. ;display the single byte in the accumulator as two hex digits
  218.     push    psw        ;save the byte
  219.     rrc            ;shift accumulator right 4 bits
  220.     rrc
  221.     rrc
  222.     rrc
  223.     call    outnib        ;print high digit
  224.     pop    psw        ;restore byte
  225.     jmp    outnib        ;print low digit
  226. outnib:
  227.     ani    0fh        ;mask 4 bits
  228.     adi    90h        ;add offset
  229.     daa            ;dec adjust
  230.     aci    40h        ;add offset
  231.     daa            ;dec adjust
  232.     mov    e,a        ;to E for output
  233.     mvi    c,conout    ;console output request
  234.     jmp    next        ;call BDOS
  235.  
  236. printhl:
  237. ;print HL on the console as four hex digits
  238.     push    h        ;save address
  239.     mov    a,h        ;position H for display
  240.     push    h        ;save address on our stack
  241.     call    outbyte        ;display the high order byte
  242.     pop    h        ;restore address
  243.     mov    a,l        ;position L for display
  244.     call    outbyte        ;display the byte
  245.     pop    h        ;restore address
  246.     ret
  247. space:
  248. ;print a single space on the console
  249.     mvi    c,conout    ;console output request
  250.     mvi    e,' '        ;outout a space
  251.     call    next        ;call BDOS
  252.     ret
  253.  
  254. ;------ literals ------
  255.  
  256. initmsg:
  257.     db    cr,lf,'RSXDEMO has been loaded'
  258.     db    '$'
  259.  
  260. string1:
  261.     db    cr,lf,'BDOS function '
  262.     db    '$'
  263.  
  264. string2:
  265.     db    'h trapped '
  266.     db    '$'
  267.  
  268. string3:
  269.     db    'at address '
  270.     db    '$'
  271.  
  272. ret$stack:
  273. ;caller's stack pointer
  274.     dw    0
  275.  
  276. ;local stack storage
  277.     ds    40        ; 20 level stack
  278. loc$stack:
  279.  
  280.     end
  281.