home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / 22rsx / 22rsx-20.ark / 22INSTA.ASM next >
Assembly Source File  |  1984-10-13  |  12KB  |  456 lines

  1. ;
  2. ;Program name: 22INSTA.ASM v2.0
  3. ;Author      : James Whorton
  4. ;Date written: 10/13/84
  5. ;(Derived from 22RSX.ASM v1.0  09/23/84)
  6. ;
  7. ;This is the first segment of the driver module for installing Resident
  8. ;System Extensions to BDOS in a CP/M 2.2 environment. The idea for this
  9. ;came from the CP/M 3.0 RSX facility.
  10. ;When a suitable object module is attached to this driver and the
  11. ;result is assembled and loaded, it will, on execution, install
  12. ;the BDOS extension into the system. On all subsequent calls to
  13. ;BDOS, this and any other extension present will intercept and 
  14. ;anaylyze it first, passing it along to the next function or doing
  15. ;other processing as desired.
  16. ;If one or more 22RSX modules are already present, the current one
  17. ;will be patched in underneath the last extension, and the appro-
  18. ;piate pointers will be adjusted. 
  19. ;>> Note: the 22RSX manager MUST be installed first. If it is not resident
  20. ;when this driver is run, an error will occurr and the driver will abort.
  21. ;
  22. ; vers. 2.0  (10/13/84):This module is taken from 22RSX 1.0. An RSX manager
  23. ;            is first installed by running 22RSX, then the
  24. ;            module .COM file is run, installing the RSX desired.
  25. ;            For assembly instructions, see .DOC.
  26. ;            (Note: the PARM code herein has been left in place
  27. ;            to facilitate future improvments I have on the draw-
  28. ;            ing board. If you want details, contact me. JHW)
  29. ;
  30. ;
  31. ;BDOS equates
  32. ;
  33. bdos:    equ    5
  34. cout:    equ    2
  35. callrsx:equ    59        ;RSX function call
  36. rtwrm:    equ    1        ;RSX Return WMLOC function #
  37. ;
  38. ;other equates
  39. ;
  40. lxid:    equ    11h        ;define byte of LIX D,nnnn to fake loader
  41. cr:    equ    13
  42. lf:    equ    10
  43. tab:    equ    9
  44. bell:    equ    7
  45. esc:    equ    27
  46. ;
  47. ;        ***
  48. ;
  49. ;Program starts here
  50. ;
  51.     org    0100h
  52. ;
  53.     jmp    hitit        ;pass the following
  54. ;
  55. ;this line is an assembler trap to warn the user if he doesn't have the
  56. ;RSX module terminated properly...
  57. ;
  58. call ilprt ;** ERROR -- CHECK RSX MODULE FOR LINK '22INSTB' AT END.
  59. ;
  60. hitit:    lxi    h,0        ;save old stack pointer
  61.     dad    sp
  62.     shld    oldstk
  63.     lxi    sp,stack    ;set stack for local ops.
  64. ;
  65. ;Print signon message
  66. ;
  67.     lxi    h,signon
  68.     call    ilprt
  69. ;
  70.     lxi    h,begobj    ;setup table for loader
  71.     shld    parm        ;first param.
  72.     lxi    h,endobj
  73.     shld    parm+2        ;second param
  74.     lxi    h,pend
  75.     shld    parm+4        ;third param.
  76. ;
  77.     mvi    a,0        ;set flag for return
  78.     mvi    c,callrsx    ;get WMLOC from manager
  79.     lxi    d,rtwrm
  80.     call    bdos        ;do it
  81.     cpi    0FFh        ;manager there?
  82.     jz    dupchk        ;yes, proceed
  83.     lxi    h,nogo$msg    ;manager wasn't there, so abort
  84.     call    ilprt
  85.     jmp    wrap        ;byebye...
  86. ;
  87. ;check to see if RSX module has already been loaded;;;
  88. ;
  89. dupchk:    push    d        ;save returned addr.
  90.     lhld    bdos+1
  91.     shld    point        ;starting pointer
  92. ;
  93. chk1:    lhld    point        ;get pointer
  94.     lxi    d,16        ;offset to name
  95.     dad    d
  96.     push    h        ;save for a sec...
  97.     lxi    h,begobj    ;point to local name
  98.     lxi    d,16
  99.     dad    d
  100.     pop    d        ;get param back
  101.     mvi    b,8        ;check 8 bytes
  102.     call    compar        ;a match?
  103.     jnz    chk2        ;no, go ahead
  104.     lxi    h,dup$msg    ;tell user and abort
  105.     call    ilprt
  106.     jmp    wrap        ;exit
  107. ;check for manager
  108. chk2:    lhld    point        ;get current pointer
  109.     lxi    d,16        ;offset to name
  110.     dad    d
  111.     xchg            ;put in <de>
  112.     lxi    h,manchk    ;manager name block
  113.     mvi    b,8
  114.     call    compar        ;match?
  115.     jz    load        ;yes, module wasn't installed, go ahead
  116. ;set up for next loop
  117.     lhld    point
  118.     lxi    d,10
  119.     dad    d
  120.     lxi    d,point
  121.     mvi    b,2
  122.     call    move
  123.     jmp    chk1        ;cycle again
  124. ;
  125. ;The following loader section, which loads the object code
  126. ;into high memory, then adjusts any addresses contained
  127. ;therein, is a modified version of that found in BYE3-23.
  128. ;Many thanks to all concerned.
  129. ;
  130. load:    pop    d        ;get addr. back
  131.     xchg            ;put WMLOC in <hl> to store
  132.     shld    wmloc        ;store it for later
  133.     lhld    bdos+1        ;get current jump addr.
  134.     shld    parm+6        ;save it for later (prevd)
  135.     lhld    bdos+1        ;get pointer again
  136.     lxi    d,-32        ;subtract 32 bytes to be safe
  137.     dad    d        ;destination for this module
  138. ;
  139. ;HL now contains the destination address of the object module
  140. ;
  141.     push    h        ;save
  142.     lhld    parm+4        ;set up the source pointer
  143.     dcx    h
  144.     xchg
  145.     push    d
  146.     lxi    b,pend-begobj    ;set up byte counter
  147.     lhld    parm
  148.     xchg
  149.     lhld    parm+4
  150.     call    sbc        ;subtract de from hl
  151.     push    h        ;save it
  152. ;
  153. ;Now pop them back off the stack
  154. ;
  155.     pop    b
  156.     pop    d
  157.     pop    h
  158. block:    ldax    d        ;get object module byte    
  159.     mov    m,a        ;move it
  160.     mov    a,b        ;get byte count
  161.     ora    c        ;finished block transfer?
  162.     jz    update        ;yes, check on the opcode values
  163.     dcx    d        ;no, set source pointer
  164.     dcx    h        ;set destination pointer
  165.     dcx    b        ;set byte counter
  166.     jmp    block        ;continue transfer
  167. ;
  168. update:    xchg            ;move the source address into HL
  169.     call    neghl        ;prepare value for subtraction
  170.     dad    d        ;form the proper offset
  171.     shld    offset        ;save the offset
  172.     xchg            ;set up the offset register
  173.     lhld    parm+2        ;get the ending addr of the RSX code. (endobj)
  174.     dad    d        ;form the new ending addr (new location)
  175.     shld    endrng        ;save the ending addr of the RSX code.
  176.     lhld    parm        ;get the start addr of the object module (begobj)
  177.     dad    d        ;form new beginning addr (new location)
  178. ;
  179. ;The following code determines whether or not an address is within the
  180. ;object module and sets it to the new address if it is - otherwise it will
  181. ;not disturb the code...
  182. ;
  183.     dcx    h        ;set up source pointer for the modi-
  184.                 ;..fication routine entry
  185. modify:    inx    h        ;point to the next (hopefully) instr.
  186.     db    lxid        ;get the address of the end of object module
  187. ;
  188. endrng:    dw    0
  189.     mov    a,e
  190.     sub    l
  191.     mov    a,d
  192.     sbb    h        ;have we finished moving this block?
  193.     jc    patch        ;yes, we can patch now
  194. ;
  195. ;Here is where we test for 3-byte opcodes
  196. ;
  197.     mvi    b,inst3e-inst3    ;get th number of elements in the table
  198.     lxi    d,inst3        ;set up the 3-byte opcodes table pointer
  199. ;
  200. thrbyt:    ldax    d        ;get opcode byte from table
  201.     cmp    m        ;is this byte a 3-byte opcode?
  202.     jz    change        ;change the 2nd and 3rd bytes if needed
  203.     inx    d        ;no, advance table pointer
  204.     dcr    b        ;end of 3-byte table?
  205.     jnz    thrbyt        ;no, keep looking
  206. ;
  207. ;Skip all the 2-byte opcodes - this keeps the transfer program from
  208. ;trying to figure out what the second byte is.
  209. ;
  210.     mvi    b,inst2e-inst2    ;get the number of elements in the table
  211.     lxi    d,inst2        ;set up the 2-byte opcodes table pointer
  212. ;
  213. twobyt:    ldax    d        ;get opcode byte from table
  214.     cmp    m        ;is this byte a 2-byte opcode?
  215.     jz    skip        ;yes, skip it and continue
  216.     dcr    b        ;no, end of 2-byte table?
  217.     inx    d        ;advance table pointer
  218.     jnz    twobyt        ;no, keep looking
  219.     jmp    modify        ;yes, it's a one-byte opcode, keep going
  220. ;
  221. skip:    inx    h        ;advance object code pointer
  222.     jmp    modify        ;continue search
  223. ;
  224. change:    push    h        ;save pointer
  225.     lhld    parm+2        ;set up end of range pointer (endobj)
  226.     push    h        ;stack it up
  227.     lhld    parm        ;set up beginning of range pointer (begobj)
  228.     push    h        ;stack it up...
  229.     pop    b        ;now pop them off in order
  230.     pop    d
  231.     pop    h
  232. ;
  233. ;See if the address is above the range
  234. ;
  235.     inx    h        ;advance pointer to the LSB of the addr
  236.     mov    a,e
  237.     sub    m
  238.     inx    h        ;advance pointer to the MSB of the addr
  239.     mov    a,d
  240.     sbb    m
  241.     jc    modify
  242. ;
  243. ;See if the address is below the range
  244. ;
  245.     dcx    h        ;set back pointer to the LSB of the addr
  246.     mov    a,m
  247.     sub    c
  248.     inx    h        ;advance pointer to the MSB of the addr
  249.     mov    a,m
  250.     sbb    b
  251.     jc    modify
  252. ;
  253. ;Update the value of this address by adding the offset to it
  254. ;
  255.     dcx    h        ;set back pointer to the LSB of the addr
  256.     db    lxid        ;load DE with the offset value
  257. ;
  258. offset:    dw    0
  259.     mov    a,m        ;get base address
  260.     add    e        ;change LSB to new address
  261.     mov    m,a        ;update memory
  262.     inx    h        ;advance pointer to the MSB of the addr
  263.     mov    a,m        ;get the MSB of the base addr
  264.     adc    d        ;change LSB to new address
  265.     mov    m,a        ;update memory
  266.     jmp    modify        ;take care of the next instruction
  267. ;
  268. ;Small routine to negate the contents of HL
  269. ;
  270. neghl:    mov    a,h
  271.     cma
  272.     mov    h,a        ;get the complement of the MSB
  273.     mov    a,l
  274.     cma
  275.     mov    l,a        ;get th complement of the LSB
  276.     inx    h        ;make 'HL' totally negative
  277.     ret
  278. ;
  279. patch:    lhld    parm        ;calc. dest (begobj)
  280.     xchg            ;put it in <de>
  281.     lhld    offset
  282.     dad    d
  283.     shld    dest        ;save it
  284. ;
  285.     lhld    bdos+1        ;get pointer to current module (or manager)
  286.     lxi    d,12        ;offset to PREV field
  287.     dad    d
  288.     xchg            ;put it in <de>
  289.     lxi    h,dest        ;point to new module addr.
  290.     mvi    b,2
  291.     call    move        ;patch it in
  292. ;
  293.     lhld    dest        ;get module address
  294.     shld    bdos+1
  295.     lhld    wmloc        ;update warm boot routine so that
  296.     xchg            ;it won't reset our vector to
  297.     lxi    h,dest        ;something wierd
  298.     mvi    b,2
  299.     call    move
  300. ;
  301. ;Patch this RSX in front of the previous one.
  302. ;
  303. patch1:    lhld    parm        ;patch NEXT field with address of
  304.                 ;previously installed RSX
  305.     lxi    d,10        ;offset to NEXT field
  306.     dad    d
  307.     xchg
  308.     lhld    offset
  309.     dad    d
  310.     xchg    
  311.     lxi    h,parm+6    ;(prevd)
  312.     mvi    b,2
  313.     call    move
  314. ;
  315. ;patches done, let user know what has been added
  316. ;
  317. patch2:    lxi    h,mod1$msg    ;print module name
  318.     call    ilprt
  319.     lhld    parm        ;point to RSX name (NAME)
  320.     lxi    d,16        ;offset 16 bytes
  321.     dad    d
  322.     xchg
  323.     lhld    offset
  324.     dad    d
  325.     mvi    b,8    
  326. loop:    mov    e,m        
  327.     push    h
  328.     push    b
  329.     mvi    c,cout
  330.     call    bdos
  331.     pop    b
  332.     pop    h
  333.     inx    h
  334.     dcr    b        ;finished?
  335.     jnz    loop        ;no, do it again
  336. ;
  337.     lxi    h,mod2$msg    ;print load addr.
  338.     call    ilprt
  339.     lhld    bdos+1
  340.     call    outhl
  341.     lxi    h,mod3$msg
  342.     call    ilprt
  343. ;
  344. wrap:    lhld    oldstk        ;get back old stack pointer
  345.     sphl            ;put it in <sp>
  346.     ret            ;back to CP/M...
  347. ;
  348. ;The following table defines the 3-byte load instructions used in the
  349. ;8080 instruction set.
  350. ;
  351. inst3:    db    01h
  352.     db    11h
  353.     db    21h
  354.     db    22h
  355.     db    2Ah
  356.     db    31h
  357.     db    32h
  358.     db    3Ah
  359.     db    0C2h
  360.     db    0C3h
  361.     db    0C4h
  362.     db    0CAh
  363.     db    0CCh
  364.     db    0CDh
  365.     db    0D2h
  366.     db    0D4h
  367.     db    0DAh
  368.     db    0DCh
  369.     db    0E2h
  370.     db    0E4h
  371.     db    0EAh
  372.     db    0ECh
  373.     db    0F2h
  374.     db    0F4h
  375.     db    0FAh
  376.     db    0FCh
  377. ;
  378. inst3e:    equ    $        ;end of 3-byte opcodes
  379. ;
  380. ;The following table is the listing of the 2-byte opcodes used in the
  381. ;8080 instruction code set.
  382. ;
  383. inst2:    db    06h
  384.     db    0Eh
  385.     db    16h
  386.     db    1Eh
  387.     db    26h
  388.     db    2Eh
  389.     db    36h
  390.     db    3Eh
  391.     db    0C6h
  392.     db    0CEh
  393.     db    0D3h
  394.     db    0D6h
  395.     db    0DBh
  396.     db    0DEh
  397.     db    0E6h
  398.     db    0EEh
  399.     db    0F6h
  400.     db    0FEh
  401. ;
  402. inst2e:    equ    $        ;end of 2-byte opcodes
  403. ;
  404. ;>> Driver storage area <<
  405. ;
  406.     ds    20h
  407. stack:    dw    0        ;top of stack
  408. oldstk:    dw    0        ;old stack pointer
  409. ;
  410. ;the following 7 or so addresses are stored here for the RSX manager
  411. ;to access. it accesses them through a pointer to the first address stored,
  412. ;so that parm=begobjp, parm+2=endobjp, parm+4=pendp, etc...
  413. ;
  414. parm:    ds    2        ;beginning of code
  415.     ds    2        ;end of code
  416.     ds    2        ;end of module
  417.     ds    2        ;storage for previous RSX dest.
  418. dest:    ds    2        ;destination of module
  419. point:    ds    2        ;work pointer
  420. signon:    db    cr,lf,'22INSTAL v2.0  10/13/84'
  421.     db    cr,lf,'Copyright (C) 1984 by James H. Whorton'
  422.     db    cr,lf,'RSX Generation Module for CP/M 2.x'
  423.     db    cr,lf,0
  424. mod1$msg:db    cr,lf,lf,'Installing extension...'
  425.     db    cr,lf,lf,'RSX module name: ',0
  426. mod2$msg:db    cr,lf,'Installed at:    ',0
  427. mod3$msg:db    cr,lf,lf,'Installation complete.',0
  428. nogo$msg:db    cr,lf,lf,'** 22RSX Manager not installed **'
  429.     db    cr,lf,'** To install, run 22RSX.COM',bell,cr,lf,0
  430. dup$msg:db    cr,lf,'++ RSX module already installed!',cr,lf,0
  431. manchk:    db    '22RSX   '
  432. wmloc:    dw    0
  433. ;
  434. ;===============================================================
  435. ;
  436. ;    ** RSX modules to be used with this sytem should conform
  437. ;    ** to the DRI format, with one(1) exception.
  438. ;    ** The END must be replaced with LINK 'INSTB'.
  439. ;    ** Other than that, any RSX's written for CP/M 3.0 that
  440. ;    ** deal with functions found in CP/M 2.x should work
  441. ;    ** properly.
  442. ;
  443. ;    The following module gets moved to memory
  444. ;    just underneath the CCP or the previous
  445. ;    RSX by the loader routine.
  446. ;
  447. ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  448. ;
  449. begobj:    equ    $        ;marks start of object module
  450. ;
  451.     link    '22MODULE'    ;this is the renamed module file
  452.                 ;to be linked into the driver.
  453. ;
  454. $        ;marks start of object module
  455. ;
  456.     link    '22MODULE'    ;this is the