home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpm / 22rsx / rsx12.ark.2 / RSXMAST.MAC < prev   
Encoding:
Text File  |  1985-11-18  |  24.1 KB  |  713 lines

  1.     title    RSXMAST outline RSX for CPM2.2 (85/11/13)
  2. ;
  3. ; Copyright (c) 1985 by C.B Falconer       (203) 281-1438
  4. ; 680 Hartford Tpk, Hamden, Ct 06517.   All rights reserved.
  5. ;
  6. ; This program may be copied/used/modified etc, but it may NOT
  7. ; be sold without express written permission from C.B. Falconer
  8. ;
  9. ; This system was assembled with SLR's SLRMAC.  M80 can also be
  10. ; used, but care must be taken with macro parameter names.
  11. ;
  12. rsxver    equ    12;    Version number to be filled in. <10 debug
  13. ;
  14. ; ==================== I M P O R T A N T =======================
  15. ; AN ACTUAL SYSTEM IS CONSTRUCTED WITH INCLUDE FILES.  THE FILES
  16. ; REQUIRED ARE:
  17. ;    RSXCUST.INC, RSXINIT.INC, BYERSX.INC and RSXMAIN.INC
  18. ; in addition to this file and BDOS.DEF
  19. ; If your assembler cannot handle include files, then you must
  20. ; make the insertions manually with your editor.
  21. ; ==============================================================
  22. ;
  23. false    equ    0
  24. true    equ    NOT false
  25. no    equ    false;        synonyms for convenience
  26. yes    equ    true
  27. ;
  28. ; The system implements a generalized CPM 2.2 RSX system.  The
  29. ; RSX is installed by running the system, and removed by running
  30. ; it again.  The program uses 8080 opcodes only in the RSX
  31. ; section, although the included files required may contain
  32. ; Z80 code.  This should ease porting to 8080 only systems.
  33. ;
  34. ; NOTE:    This source file requires SLRs SLRMAC or M80 for assembly,
  35. ;    and RELOCCP.SYS for run-time load and relocation.
  36. ;
  37. ; Revisions:        (in LIFO order)
  38. ; 1.2    85/11/13. FINDOS/CHKSYS are now application init callable
  39. ;    procs. BDOSLGH, BDOSARG, CCPLGH are now equates, to allow
  40. ;    for non-CPM systems.  Increased min. stack to 48 bytes.
  41. ;    Added boothk. Some name changes for M80 compatibility.
  42. ;    Modified the CCP re-entry mechanism for ZCPR compatibility.
  43. ; 1.1    85/11/09. Allowances for range of RSX's.  Drivers may now
  44. ;    be installed after a non-driver RSX has been mounted. These
  45. ;    changes allow implementation of a BYE replacement system.
  46. ;    Separate RSXCUST.INC file.
  47. ; 1.0    85/09/23. Initial release.
  48. ; 0.3    85/01/27. First working disk drive.
  49. ; 0.2    85/01/24. Provisions for BDOS driver installation,
  50. ;    checks etc.
  51. ; 0.1    85/01/05. Inactive causes reversion to original BDOS call in
  52. ;    case this was a substitute for it. debug allows testing.
  53. ;    Keep track of current DMA address.
  54. ; 0.0    Original version, by C.B. Falconer (85/Jan/04).
  55. ;
  56. ; This system is the outline of a generalized RSX system, with
  57. ; initialization and termination code.  It is expected to
  58. ; respond to BDOS calls with the value @RSX (normally larger
  59. ; than any usual CPM call value), and receive an argument of
  60. ; some form in the (de) register.  Two special values of (de)
  61. ; are reserved (0 and -1).  In usual operation the (de) value
  62. ; is normally a pointer, which cannot take on either of these
  63. ; special values.  For character output RSXs (e.g. list output
  64. ; replacement) this prevents sending a nul or a rubout with all
  65. ; bits set.  Remember this is a full word parameter.
  66. ;
  67. ; 0 implies a residence inquiry, and should return a zero
  68. ; value if the system is not resident, (as will CPM 2.2 for any
  69. ; invalid calls), and non-zero if resident and activated.  This
  70. ; allows the initialization code to detect that the system is
  71. ; already mounted, and avoid multiple loading.  Similarly
  72. ; application programs can check that the RSX is available.  A
  73. ; zero value returned in (a) signifies the RSX is not available.
  74. ;
  75. ; The second special value is 0ffffh (i.e. -1), which
  76. ; signals the system to become inactive, so that the next
  77. ; warm boot will remove it entirely.
  78. ;
  79. ; A third special argument is 0001h.  This is optional, and is
  80. ; used to return a data address.  For DSKDRIVE in particular
  81. ; this is used to return a pointer to the memory resident
  82. ; drive configuration table (whose structure thus should not
  83. ; be altered in order to maintain compatibility with auxiliary
  84. ; software).  (DSKDRIVE actually returns this pointer for all
  85. ; DE arguments other than 0 or -1, but this should not be
  86. ; counted on.)
  87. ;
  88. ; This file implements an example RSX, and indicates where the
  89. ; code should be installed, and the calling conventions for other
  90. ; RSXs.  See the label "chkparms" to allow initialization
  91. ; parameters, and the label "rsx" to install the actual code.
  92. ; Note especially than any code located ahead of the label
  93. ; "@keep" is available only during initialization.  However
  94. ; the initialization section can call routines in the retained
  95. ; portion.  The "bthook" connector allows re-initialization on
  96. ; each "warm boot" or disk reset.  "boothk" is different, and is
  97. ; called on each warm boot, but not at disk reset.
  98. ;
  99. ; The system, when combined with "RELOCCP", loads itself just
  100. ; below the CCP, and keeps the CCP resident. (See RELOCCP.OVR,
  101. ; which is an assembly time option for RELOCCP, for a method
  102. ; of minimizing memory wastage for multiple RSX's).  If RSX.COM
  103. ; is executed while resident, it attempts to remove itself and
  104. ; reclaim memory.  If other systems have been loaded below RSX
  105. ; it will not be able to reclaim memory until those systems
  106. ; (probably further RSX's) have been removed.  The customizable
  107. ; routine "killhk" allows manipulation of a resident RSX.
  108. ;
  109. ; To create a custom RSX modify the files RSXINIT, RSXMAIN, RSXCUST
  110. ; and possibly BYERSX.xxx, rename them with the extensions ".INC"
  111. ; and .DEF as required, and re-assemble RSXMAST.  Give the resultant
  112. ; relocatable file the appropriate name, and create the MYRSX.COM
  113. ; with RELOCCP (See RELOCCP documentation).  When executed you now
  114. ; have available a new BDOS function, which executes whatever you put
  115. ; in.  IF YOUR BDOS/CCP is non-standard see BDOS.DEF file. 
  116. ;
  117. ; Acknowledgement:  Some of the mechanisms used in this system
  118. ; have been taken from various public domain systems, especially
  119. ; those by Gary Novasielski and Bruce Ratoff.
  120. ;
  121. ; This system was created to ease installation of two operations:
  122. ; a generalized foreign disc driver, and a "CHAIN" mechanism
  123. ; whereby programs can load and execute arbitrary commands.  The
  124. ; pre-existing KEYS program can probably be converted to execute
  125. ; under this system, as can UNSPOOL40 (enhancement of Br. Ratoffs
  126. ; UNSPOL30).
  127. ;
  128. ; While some code economies could easily be made for any particular
  129. ; application, I feel that using one standard environment is much
  130. ; more important.  Thus the provisions for bios driver modification
  131. ; have been installed, with the complete check/restore system.  The
  132. ; disadvantage remains that custom code must be included in this
  133. ; source and assembled, rather than standing by itself.
  134. ;
  135. ; Definitions of BDOS functions.
  136. include BDOS.DEF
  137. ;
  138. ; Put any customization equates here
  139. include    RSXCUST.DEF
  140. ;
  141. ; Macro Definitions
  142. ;
  143. ; Force location counter zero modulo val
  144. ; with respect to "wrto" by filling with "fill" bytes
  145. align    macro    val,wrto,fill
  146.     local    here
  147. here    equ    $ - wrto
  148.     if    (here+val)/val*val-here-val
  149.      if    nul fill
  150.       ds    (here+val)/val*val-here
  151.      else;;    SLRMAC specific coding.
  152.       ds    (here+val)/val*val-here,fill
  153.      endif
  154.     endif
  155.     endm
  156. ;
  157. ; ************************************************************
  158. ; * This is my standard page relocatable system. See RELOCCP *
  159. ; ************************************************************
  160. ;
  161.     cseg;    system requires org 0 and org 100h modules
  162. ;        You may replace this with two "orgs" in two
  163. ;        different assemblies to get the overall system
  164. ;        for RELOCCP to prepare and relocate at run-time.
  165. ;
  166. ; This defines the first location of the relocated image.
  167. ; The portion from here to "@keep" is not retained after
  168. ; initialization.  The data here is used for relocation
  169. @base:    jmp    intro;        Following is std relocation data
  170. @size:    dw    segsiz;        size of segment to relocate
  171. @memsz:    db    pages;        total memory use in pages
  172. ;
  173. ; Patch/alter this value to non-zero if the RSX may only be
  174. ; loaded in a virgin system.  This should be done if the system
  175. ; installs bios modifications that the BDOS can see.
  176. chkflg:    db    driver;        Set non-zero for virgin system only
  177. ;
  178. ; This code gets everything started
  179. intro:    lhld    bdos+1;        First so other calls work
  180.     shld    gobdos+1;    Save the BDOS entry point
  181.     lxi    d,signon
  182.     call    tstr
  183.     call    findos
  184.     jnz    badsys;        Invalid system configuration
  185. ;    "    "
  186. ; Set up the connector to return to CCP on boots
  187.     lxi    d,-ccplgh-7+3;    Form pointer to CCP re-entry
  188.     dad    d
  189.     shld    ccpret+1;    and save for future use
  190. ;    "    "
  191. ; Do application specific parameter checking
  192.     call    chkparms;    Do any parameter checking needed
  193.     jc    exeunt;        ..with help message on carry=fault
  194. ;    "    "
  195. ; Check for initial load, or re-entry
  196.     lxi    d,0
  197.     mvi    a,@RSX;
  198.     call    DOS;        enquire whether loaded
  199.     ora    a;        If loaded, then
  200.     jnz    intro1;           bring it down
  201.     call    rsxset;        else initialize.
  202. ;    "    "
  203. ; Now do the user customizable initialization
  204.     call    init;        Customized portion
  205.     jmp    bootrq;        ..bootrq, which sets connectors
  206. ;
  207. ; already loaded, bring it down
  208. intro1:    call    killhk;        for systems that modify running RSX
  209.     lxi    d,-1
  210.     mvi    a,@RSX
  211.     call    DOS;        tell it to come down on next boot
  212.     jmp    boot;        which should kill it
  213. ;
  214. ; Setup the system.  First, check environment to see if
  215. ; BIOS vectors are accessible and reasonable.
  216. ; a,f,c,d,e,h,l
  217. rsxset:    lhld    boot+1
  218.     shld    boot0+1;    Save the BOOT vector
  219.     if    nodrive
  220.          inx    h
  221.      mov    e,m;        save warm boot connector
  222.      inx    h
  223.      mov    d,m
  224.      xchg
  225.      shld    bsave
  226.      lxi    h,bootrq;    and reconnect to our system
  227.      xchg
  228.      mov    m,d
  229.      dcx    h
  230.      mov    m,e
  231.      ret
  232.     else;        drivers to be available
  233.      lda    boot;        Location BOOT should
  234.      cpi    0c3h;        have a JMP instruction
  235.      jnz    vecterr
  236.      lhld    boot+1;        Location one points to
  237.      xchg;             the table of bios jumps
  238.      lhld    bdos+1;        This should point to BDOS
  239.      lda    chkflg
  240.      sta    kill+1;        Save for use at exit time. Unclean
  241.      ora    a;         but want it user patchable (1 place)
  242.      if    multidrv
  243.       call    findos
  244.      else;        NOT multidrv
  245.       cnz    chksys;        Hook, prevent loading invalid system
  246.      endif
  247.      xchg;            bios pointer to hl
  248.      mvi    c,nvects;    preserve z flag in here
  249.      lxi    d,biosv
  250.      push    d;        by default init our vector
  251.      jnz    vecterr;    after push, to correct stack
  252.      lxi    d,bsave;    which we move into
  253.      xchg;            the code.
  254. ;     "    "
  255. ; Now copy the original vectors into our tables, while verifying
  256. ; that they are reasonable (i.e. start with CALL or JMP).  The
  257. ; CALLs allow for warmboots that call a ROM routine, with the
  258. ; stack identifying the actual system location.
  259. rsxset1: mvi    a,nvects-n22vec
  260.      cmp    c
  261.      jnc    rsxset2;    stop checking after 2.2 types
  262.      ldax    d
  263.      xra    m;        another JMP?
  264.      ani    0f1h;        allow Call or Jmp
  265.      jnz    vecterr
  266. rsxset2: ldax    d
  267.      mov    m,a;        bsave[n,0]
  268.      inx    d
  269.      inx    h
  270.      xthl
  271.      inx    h
  272.      ldax    d
  273.      mov    m,a;        biosv[n,1]
  274.      inx    h
  275.      xthl
  276.      mov    m,a;        bsave[n,1]
  277.      inx    d
  278.      inx    h
  279.      ldax    d
  280.      mov    m,a;        bsave[n,2]
  281.      xthl
  282.      mov    m,a;        biosv[n,2]
  283.      inx    h;    biosv[n+1,0]
  284.      xthl
  285.      inx    h;    biosv[n+1,0]
  286.      inx    d
  287.      dcr    c;    n := n+1;
  288.      jnz    rsxset1
  289.      pop    h;        purge 2nd transfer address
  290. ; This was satisfactory, now if "driver" is TRUE, patch the
  291. ; BIOS drivers to point to the new copy (only the std CPM 2.2
  292. ; entries) so that new entries can be made locally.  The final
  293. ; exit mechanism will restore everything.
  294.      lda    chkflg
  295.      ora    a
  296.      rz;            no bios patches needed
  297. ;     "    "
  298. ; Patch the original bios drivers, which have been checked
  299. ; for validity and a reasonable location, to point to the
  300. ; new bios table. Only called when "driver" is TRUE.  DO NOT
  301. ; PATCH the original warm/cold boot entries.
  302. bpatch:     lhld    boot+1
  303.      inx    h
  304.      inx    h
  305.      lxi    d,biosv
  306.      mvi    c,n22vec-1;    count of 2.2 bios entries only
  307. bpat1:     inx    h
  308.      inx    d
  309.      inx    d
  310.      inx    d
  311.      inx    h
  312.      mov    m,e
  313.      inx    h
  314.      mov    m,d
  315.      dcr    c
  316.      jnz    bpat1;        more
  317.      ret
  318. ;
  319. ; Check system is in usable state. (de) holds the bios pointer,
  320. ; and (hl) holds the bdos pointer.  If the values are not
  321. ; reasonable, return non-zero flag.  If successful returns hl
  322. ; a pointer to location 7 on the BDOS entry page (CPM 2.2).
  323. ; Modifications here can allow installation of multiple 
  324. ; drivers.  This is safer as it stands.
  325. ; a,f,h,l
  326. chksys:     call    findos;        worked before, must work now
  327.      mov    a,e
  328.      cpi    3
  329.      rnz;            boot pointer should end in 3
  330.      mov    a,d
  331.      sub    h
  332.      sui    BDOSLGH;    Z flag if correct page,
  333.      ret;            else non-virgin BIOS pointer
  334. ;
  335. vecterr:
  336.      pop    d;        remove the extra pointer
  337.     endif;        NOT nodrive
  338. ;    "    "
  339. ; Exit with invalid system message
  340. badsys:    lxi    d,vcterrmsg
  341. ;    "    "
  342. ; exit with message de^
  343. exeunt:    call    tstr
  344.     jmp    boot;        try re-booting.
  345. ;
  346. vcterrmsg:
  347.     db    CR,LF,'Invalid system$'
  348. ;
  349. ; Find the actual location of BDOS by following the trail from
  350. ; the pointer in hl.  Return z flag and hl = pointer to location
  351. ; 7 of the base BDOS page if found, else nz flag.
  352. ; For this to function connectors must be of the form used in
  353. ; intercept below.  Scan for label "intercept:"
  354. ; Note that ENTRY IS IN THE MIDDLE, not the next instruction
  355. ; a,f,h,l
  356. fndos1:    cpi    03eh;        (mvi a).  Check for intercept
  357.     rnz;            not a connector, not found
  358.     inx    h;        ignore operand for MVI A,--
  359.     inx    h
  360.     mov    a,m
  361.     cpi    0b9h;        (cmp c)
  362.     rnz;            not a connector
  363.     inx    h
  364.     mov    a,m
  365.     ani    0e7h;        may be an intercept
  366.     cpi    0c2h;        jz, jnz, jc, jnc are acceptable
  367.     rnz;            not a connector
  368.     inx    h
  369. fndos2:    mov    a,m
  370. fndos3:    inx    h;        load the JMP operand
  371.     mov    h,m
  372.     mov    l,a;        and continue up the chain
  373. ;    "    "
  374. ; Main entry point here
  375. findos:    mov    a,m;        find the actual BDOS.   *** ENTRY <<<
  376.     cpi    0c3h;        (jmp).  Code for CPM 2.2 only
  377.     jnz    fndos1;        Not the real thing
  378. fndos4:    inx    h
  379.     mov    a,m
  380.     cpi    BDOSARG MOD 256;    known value in CPM 2.2
  381.     jnz    fndos3;        not end, continue up the chain
  382.     inx    h
  383.     mov    a,m
  384.     adi    BDOSARG / 256;    allow for non-CPM systems
  385.     cmp    h;        at end JMP is on same page (CPM2.2)
  386.     dcx    h;        point back to start of arg
  387.     jnz    fndos2;        else continue up the chain
  388.     ret;    (z)        FOUND it.
  389. ;
  390. ; =============================================================
  391. ; ****    Custom portion of initialization code here       ****
  392. ; =============================================================
  393. ;
  394. ; The following code is used on initialization and then discarded.
  395. ; See "RSXINIT.xxx" for details.  It may call on all routines in
  396. ; the system.
  397. include    RSXINIT.INC
  398. ;
  399. ; ------------------ End custom initialization area ----------------
  400. ;
  401.     align    256,@base,0;    ensure page aligned
  402. ;
  403. ; *******************************************************
  404. ; * The code from here up is retained in memory after     *
  405. ; * initialization.  It may be used by the initializer    *
  406. ; * This code MUST start on a page boundary.        *
  407. ; *******************************************************
  408. @keep:
  409. ;
  410. ; During operation, this location will point to intercept and will
  411. ; be jumped to by BDOS calls from location 5.  This organization
  412. ; depends on the fact that BDOS calls the bios directly (ignoring
  413. ; the pointer at location 1), except when needing a warm boot
  414. ; (e.g. after a disk error), when it uses the pointer at 1.
  415. ;
  416. ; This must be at the lowest location in the protected code segment.
  417. bdosv:    jmp    intercept;    the bdos link
  418. ;
  419. ; This will normally contain no code, but can be used to create a
  420. ; system compatible with the existing BYE programs.
  421. include    BYERSX.INC
  422. ;
  423.     if    nodrive
  424. bsave:     dw    $-$;        save original warm boot connector
  425.     else;        NOT nodrive
  426. ; This area replaces the bios jump table, allowing intercepts.
  427. ; Any intercepts (usually console commands) are set up by the
  428. ; initializing code, which is discarded after execution. See
  429. ; comments on "nvects" above.  Normally these bios vectors will be
  430. ; accessed only by executing programs, and not by the BDOS unit.
  431. ; To insert drivers in the bios it is necessary to save the original
  432. ; bios pointers (for restoration when the RSX is removed) and
  433. ; install jumps to this revised table in the original table.  Note
  434. ; that the original table may contain a CALL for the warmboot vector,
  435. ; so that ROM based code can tell the CPM system size when called.
  436. biosv:     REPT    nvects;;    biosv is the new warmboot connector
  437.      jmp    $-$
  438.      endm
  439. ;
  440. ; This table has two purposes - it allows connection to the original
  441. ; bios vectors destinations, and it saves all the values for
  442. ; restoration upon RSX exit.  Thus the custom initialization section
  443. ; can patch the real bios table to install new disk drivers, etc.
  444. ; Note that this can only work when this is the FIRST rsx installed.
  445. ; Further ones can only intercept user bios calls and BDOS calls.
  446. ; Provided that the bios table in effect on entry to this system
  447. ; does not hold any data areas, the restoration on RSX removal will
  448. ; be harmless.
  449. bsave:     REPT    nvects;;    bsave is the old warmboot connector
  450.      jmp    $-$
  451.      endm
  452. ;
  453. ; An example showing how to refer to the "old" entries needed.
  454. ; Index 0 here is warmboot, not cold.  Similarly for "new" entries
  455. ;@home        equ    bsave+(7*3)
  456. ;@seldk        equ    bsave+(8*3)
  457. ;@setrk        equ    bsave+(9*3)
  458. ;@setsec    equ    bsave+(10*3)
  459. ;@setdma    equ    bsave+(11*3)
  460. ;@read        equ    bsave+(12*3)
  461. ;@write        equ    bsave+(13*3)
  462. ;@sectran    equ    bsave+(15*3)
  463.     endif;        NOT nodrive
  464. ;
  465. ; This routine intercepts all BDOS calls.
  466. ; Note that the initial code sequence allows applications to
  467. ; find the actual BDOS, if necessary.  See SD88F6 for one use.
  468. intercept:
  469.     mvi    a,0ffh
  470.     cmp    c
  471.     jc    gobdos;        Never taken, but SD trackable
  472.     mvi    a,@SYS;        Get function
  473.     cmp    c
  474.     jz    sysreq;        a reboot request
  475.     mvi    a,@DMA
  476.     cmp    c
  477.     jz    dodma
  478.     mvi    a,@LOG
  479.     cmp    c
  480.     jz    drvreset;    reset this drive also
  481.     mvi    a,@RSX;        defined for this system
  482.     cmp    c
  483.     jz    inrange
  484.     mvi    a,@RSXX;    check for a special extra
  485.     cmp    c;         intercept (e.g. setuser for
  486.     jz    inrange;     BYE replacement)
  487.     mvi    a,@RSXY;    check for another special extra
  488.     cmp    c;         intercept (e.g. chain for
  489.     jz    inrange;     BYE replacement)
  490.     mvi    a,@RSXLO-1
  491.     cmp    c
  492.     jnc    gobdos;        not in range
  493.     mvi    a,@RSXHI
  494.     cmp    c
  495.     jc    gobdos;        not for us
  496. ; DO NOT optimize the above sequence.  It is intended to be
  497. ; trackable by utilities to list the RSX's active.  The series
  498. ; stops when the instruction is not "ld a,bytevalue".  The
  499. ; initial "ld a,0ffh" will not be counted by tracking utilities
  500. ; and the checks on @SYS and @DMA are always expected.  This
  501. ; organization allows a range of BDOS calls to be intercepted.
  502. ;    "    "
  503. inrange:
  504.     lxi    h,0;        intercepting, switch stacks
  505.     dad    sp;         because application may not
  506.     lxi    sp,lclstk;     allow sufficient room
  507.     push    h;        save entry stack pointer
  508.     call    doit;        This is an extension call
  509.     xchg;            save return value
  510.     pop    h;        restore entry stack
  511.     sphl
  512.     xchg;            return its result
  513.     mov    a,l;        copy result to (a)
  514.     mov    b,h;        so (ba)=(hl), like BDOS
  515.     ret;            to the caller.
  516. ;
  517. ; Reset this drive also when application wants a drive reset
  518. ; Added to RSX system for disk drive application.
  519. ; This is also called on any warm-boots
  520. drvreset:
  521.     push    b
  522.     call    bthook;        user customizable.
  523.     pop    b
  524.     jmp    gobdos
  525. ;
  526. ; Keep track of the current DMA address on general principles
  527. dodma:    xchg
  528.     shld    dmadr;        BDOS' view, not BIOS
  529.     xchg
  530. ;    "    "
  531. ; Connects to the "real" BDOS routine
  532. gobdos:    jmp    $-$;        Patched on entry
  533. ;
  534. ; The RSX (resident system extension).  Argument is de as usual,
  535. ; and the extension specified is (c).  Return value is put in hl.
  536. ; The stack is already set to the local stack, with the old
  537. ; stack pointer under the return from doit.
  538. ; a,f,b,c,d,e,h,l (allowed)
  539. doit:    lhld    active;        set "enquiry" return value in (l)
  540.     mov    a,l
  541.     ora    a
  542.     jz    gobdos;        inactive, use bdos call
  543.     mov    a,c
  544.     cpi    @RSX
  545.     jnz    rsx;        not the master call, ignore parm
  546.     mvi    h,0
  547.     mov    a,e;        check for "loaded enquiry"
  548.     ora    d
  549.     rz;            signal active on enquiry
  550.     mov    a,e
  551.     ana    d
  552.     inr    a
  553.     jnz    rsx;        not "pulldown" request.
  554. ;    "    "
  555. ; Inactivate the RSX.  Next boot will try to recover the memory.
  556. kill:    mvi    a,$-$;        patched with "chkflg" at init
  557.     ora    a
  558.     cnz    unpch;        Remove any bios alterations
  559.     xra    a
  560.     sta    active;        mark inactive
  561.     mov    l,a;        return 0, pulldown accepted
  562.     mov    h,a;        and we are now inactive.
  563.     ret
  564. ;
  565. unpch:    if    nodrive
  566.      ret
  567.     else;        NOT nodrive
  568. ; Remove any bios patches made on initialization, in case this is a
  569. ; driver being inactivated, and further RSX's are loaded beyond it.
  570. ; Thus a "kill" request will be logically executed, even though the
  571. ; memory is not reclaimed. However bios alterations via the pointer
  572. ; at 1 cannot be removed until a warm boot occurs (that pointer may
  573. ; be pointing to an RSX installed later).  Thus the table at biosv
  574. ; must be updated to point to the original bios entries
  575.      lxi    d,bsave+3
  576.      lhld    boot0+1
  577.      inx    h
  578.      inx    h
  579.      inx    h;        start at the constat entry
  580.      push    h
  581.      lxi    h,biosv+3
  582.      mvi    c,n22vec-1;    dont alter the warm boot entries
  583. unpch1:     mov    b,l;        offset, depends on page alignment
  584.      inx    d;        past opcode
  585.      inx    h;        Ignore the opcode (dont change)
  586.      mov    m,b;    biosv[n,1]  --> oldbios[n,0]
  587.      inx    h
  588.      xthl
  589.      mov    b,h;        oldbios page
  590.      inx    h
  591.      ldax    d;        lsb
  592.      mov    m,a;    oldbios[n,1]
  593.      inx    d;        ^msb
  594.      inx    h
  595.      ldax    d;        msb
  596.      mov    m,a;    oldbios[n,2]
  597.      inx    h;    oldbios[n+1,0]
  598.      xthl
  599.      mov    m,b;    biosv[n,2] --> oldbios[n,0]
  600.      inx    h;    biosv[n+1,0]
  601.      inx    d;        next opcode
  602.      dcr    c;    n := n+1
  603.      jnz    unpch1
  604.      pop    h
  605.      ret
  606.     endif;        NOT nodrive
  607. ;
  608. ; Note that the following "boot" entries will never be reached if a
  609. ; further RSX has been installed, since that RSX will intercept the
  610. ; boot and do a direct return to the CCP (unless it is inactive, and
  611. ; removes itself, when a whole chain of RSX removals can be started)
  612. ;
  613. ; The application process has requested a warm-boot by invoking BDOS
  614. ; function 0.  If the system is inactive remove it, otherwise return
  615. ; to the CCP via the stored (on initialization) CCP return value.
  616. sysreq:    jmp    bootrq;        This allows separation if needed
  617. ;
  618. ; The application process has requested a reboot by jumping to
  619. ; location 0.  If we are no longer active, we will honor the request
  620. ; by executing the address found in the BOOT vector at entry.
  621. ; Otherwise return to CCP without rebooting.
  622. bootrq:    lxi    sp,lclstk;    set up a valid stack
  623.     lda    active
  624.     ora    a
  625.     jz    done;        Not active, all done. Remove self
  626.     call    boothk;        For applications to detect reboot
  627.     mvi    c,@LOG
  628.     call    drvreset;    Reset drives, like any other reboot
  629.     lxi    d,actmsg;     does.  Calls bthook routine
  630.     call    tstr
  631.     lxi    d,altid;    added message portion for
  632.     call    tstr;          DSKDRIVE use
  633. ;    "    "
  634. ; Reset the system pointers to use this system.
  635.     lxi    h,bdosv
  636.     shld    bdos+1
  637.     if    NOT nodrive;    else leave connectors alone
  638.      lxi    h,bootrq
  639.      shld    biosv+1
  640.      lxi    h,biosv
  641.      shld    boot+1
  642.     endif;        NOT nodrive
  643.     lxi    h,tbuff
  644.     shld    dmadr;        Will be set by CCP
  645.     lda    drvusr
  646.     mov    c,a;        drive/user under which to re-enter
  647. ccpret:    jmp    $-$;        Patched on startup
  648. ;
  649. ; Done with the system
  650. done:    lxi    d,donemsg;    Message and jump to old boot addr.
  651.     call    tstr;        as originally read from memory wd 1
  652.     if    nodrive;    Then we have to reset the wboot
  653.      lhld    bsave
  654.      xchg
  655.      lhld    boot0+1;    The original destination
  656.      inx    h
  657.      mov    m,e
  658.      inx    h
  659.      mov    m,d;        restore it all
  660.     endif
  661. boot0:    jmp    $-$;        Reboot. Patched on initialization
  662. ;                This value points to old bios table
  663. ;                and the old reboot resets connectors
  664. ;
  665. ; ================================================================
  666. ;          Utility routine area
  667. ; ================================================================
  668. ;
  669. ; Put string (de) to console, '$' terminated
  670. ; a,f
  671. tstr:    mvi    a,@MSG
  672. ;    "    "
  673. ; dos call (a) without disturbing registers.  Does not use the RSX
  674. ; a,f
  675. DOS:    push    b
  676.     push    d
  677.     push    h
  678.     mov    c,a
  679.     call    gobdos
  680.     pop    h
  681.     pop    d
  682.     pop    b
  683.     ret
  684. ;
  685. ; ==================================================================
  686. ; **** To keep as much as possible constant, put real RSX here    ****
  687. ; ==================================================================
  688. ;
  689. ; The following allows for machine dependant code for i/o drivers
  690. ; the file may consist of comments only if not needed.
  691. include RSXIO.INC
  692. ;
  693. ; The following is the actual application code.  It may only call on
  694. ; the following routines: TSTR, DOS, GOBDOS. (See above)
  695. include RSXMAIN.INC
  696. ;
  697. ; This organization allows RSXMAIN to assign storage contiguous
  698. ; to the local stack, but not past it.
  699.     ds    STKSZ; Local stack of at least STKSZ/2 words
  700. ;            plus any remainder on page
  701.     ds    2;    allow for dmadr below, forced to page end
  702. ; align to next page boundary
  703.     align    256,bdosv
  704. ;
  705. lclstk    equ    $-2;    Reserve space for following
  706. dmadr    equ    lclstk;    Keeps track of current value known to DOS.
  707. ;            Note that this may not be that known to BIOS
  708. ;*************************************************
  709. ; End of segment to be relocated.
  710. pages    equ    ($-@base)/256;    So loader knows memory needs.
  711. ;
  712.     end
  713. r