home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug167.arc / ZMP-BEE.LBR / RSXMAST.MZC / RSXMAST.MAC
Text File  |  1979-12-31  |  25KB  |  714 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.     .z80
  162.     cseg            ;     system requires org 0 and org 100h modules
  163. ;        You may replace this with two "orgs" in two
  164. ;        different assemblies to get the overall system
  165. ;        for RELOCCP to prepare and relocate at run-time.
  166. ;
  167. ; This defines the first location of the relocated image.
  168. ; The portion from here to "@keep" is not retained after
  169. ; initialization.  The data here is used for relocation
  170. @base:    jp    intro        ;         Following is std relocation data
  171. @size:    dw    segsiz        ;         size of segment to relocate
  172. @memsz:    db    pages        ;         total memory use in pages
  173. ;
  174. ; Patch/alter this value to non-zero if the RSX may only be
  175. ; loaded in a virgin system.  This should be done if the system
  176. ; installs bios modifications that the BDOS can see.
  177. chkflg:    db    driver        ;         Set non-zero for virgin system only
  178. ;
  179. ; This code gets everything started
  180. intro:    ld    hl,(bdos+1)    ;         First so other calls work
  181.     ld    (gobdos+1),hl    ;     Save the BDOS entry point
  182.     ld    de,signon
  183.     call    tstr
  184.     call    findos
  185.     jp    nz,badsys    ;         Invalid system configuration
  186. ;    "    "
  187. ; Set up the connector to return to CCP on boots
  188.     ld    de,-ccplgh-7+3    ;     Form pointer to CCP re-entry
  189.     add    hl,de
  190.     ld    (ccpret+1),hl    ;     and save for future use
  191. ;    "    "
  192. ; Do application specific parameter checking
  193.     call    chkparms    ;     Do any parameter checking needed
  194.     jp    c,exeunt    ;         ..with help message on carry=fault
  195. ;    "    "
  196. ; Check for initial load, or re-entry
  197.     ld    de,0
  198.     ld    a,@rsx        ; 
  199.     call    dos        ;         enquire whether loaded
  200.     or    a        ;         If loaded, then
  201.     jp    nz,intro1    ;            bring it down
  202.     call    rsxset        ;         else initialize.
  203. ;    "    "
  204. ; Now do the user customizable initialization
  205.     call    init        ;         Customized portion
  206.     jp    bootrq        ;         ..bootrq, which sets connectors
  207. ;
  208. ; already loaded, bring it down
  209. intro1:    call    killhk        ;         for systems that modify running RSX
  210.     ld    de,-1
  211.     ld    a,@rsx
  212.     call    dos        ;         tell it to come down on next boot
  213.     jp    boot        ;         which should kill it
  214. ;
  215. ; Setup the system.  First, check environment to see if
  216. ; BIOS vectors are accessible and reasonable.
  217. ; a,f,c,d,e,h,l
  218. rsxset:    ld    hl,(boot+1)
  219.     ld    (boot0+1),hl    ;     Save the BOOT vector
  220.      if    nodrive
  221.     inc    hl
  222.     ld    e,(hl)        ;         save warm boot connector
  223.     inc    hl
  224.     ld    d,(hl)
  225.     ex    de,hl
  226.     ld    (bsave),hl
  227.     ld    hl,bootrq    ;     and reconnect to our system
  228.     ex    de,hl
  229.     ld    (hl),d
  230.     dec    hl
  231.     ld    (hl),e
  232.     ret
  233.      else            ;         drivers to be available
  234.     ld    a,(boot)    ;         Location BOOT should
  235.     cp    0c3h        ;         have a JMP instruction
  236.     jp    nz,vecterr
  237.     ld    hl,(boot+1)    ;         Location one points to
  238.     ex    de,hl        ;              the table of bios jumps
  239.     ld    hl,(bdos+1)    ;         This should point to BDOS
  240.     ld    a,(chkflg)
  241.     ld    (kill+1),a    ;         Save for use at exit time. Unclean
  242.     or    a        ;          but want it user patchable (1 place)
  243.      if    multidrv
  244.     call    findos
  245.      else            ;         NOT multidrv
  246.     call    nz,chksys    ;         Hook, prevent loading invalid system
  247.      endif
  248.     ex    de,hl        ;             bios pointer to hl
  249.     ld    c,nvects    ;     preserve z flag in here
  250.     ld    de,biosv
  251.     push    de        ;         by default init our vector
  252.     jp    nz,vecterr    ;     after push, to correct stack
  253.     ld    de,bsave    ;     which we move into
  254.     ex    de,hl        ;             the code.
  255. ;     "    "
  256. ; Now copy the original vectors into our tables, while verifying
  257. ; that they are reasonable (i.e. start with CALL or JMP).  The
  258. ; CALLs allow for warmboots that call a ROM routine, with the
  259. ; stack identifying the actual system location.
  260. rsxset1:ld    a,nvects-n22vec
  261.     cp    c
  262.     jp    nc,rsxset2    ;     stop checking after 2.2 types
  263.     ld    a,(de)
  264.     xor    (hl)        ;         another JMP?
  265.     and    0f1h        ;         allow Call or Jmp
  266.     jp    nz,vecterr
  267. rsxset2:ld    a,(de)
  268.     ld    (hl),a        ;         bsave[n,0]
  269.     inc    de
  270.     inc    hl
  271.     ex    (sp),hl
  272.     inc    hl
  273.     ld    a,(de)
  274.     ld    (hl),a        ;         biosv[n,1]
  275.     inc    hl
  276.     ex    (sp),hl
  277.     ld    (hl),a        ;         bsave[n,1]
  278.     inc    de
  279.     inc    hl
  280.     ld    a,(de)
  281.     ld    (hl),a        ;         bsave[n,2]
  282.     ex    (sp),hl
  283.     ld    (hl),a        ;         biosv[n,2]
  284.     inc    hl        ;     biosv[n+1,0]
  285.     ex    (sp),hl
  286.     inc    hl        ;     biosv[n+1,0]
  287.     inc    de
  288.     dec    c        ;     n := n+1;
  289.     jp    nz,rsxset1
  290.     pop    hl        ;         purge 2nd transfer address
  291. ; This was satisfactory, now if "driver" is TRUE, patch the
  292. ; BIOS drivers to point to the new copy (only the std CPM 2.2
  293. ; entries) so that new entries can be made locally.  The final
  294. ; exit mechanism will restore everything.
  295.     ld    a,(chkflg)
  296.     or    a
  297.     ret    z        ;             no bios patches needed
  298. ;     "    "
  299. ; Patch the original bios drivers, which have been checked
  300. ; for validity and a reasonable location, to point to the
  301. ; new bios table. Only called when "driver" is TRUE.  DO NOT
  302. ; PATCH the original warm/cold boot entries.
  303. bpatch:    ld    hl,(boot+1)
  304.     inc    hl
  305.     inc    hl
  306.     ld    de,biosv
  307.     ld    c,n22vec-1    ;     count of 2.2 bios entries only
  308. bpat1:    inc    hl
  309.     inc    de
  310.     inc    de
  311.     inc    de
  312.     inc    hl
  313.     ld    (hl),e
  314.     inc    hl
  315.     ld    (hl),d
  316.     dec    c
  317.     jp    nz,bpat1    ;         more
  318.     ret
  319. ;
  320. ; Check system is in usable state. (de) holds the bios pointer,
  321. ; and (hl) holds the bdos pointer.  If the values are not
  322. ; reasonable, return non-zero flag.  If successful returns hl
  323. ; a pointer to location 7 on the BDOS entry page (CPM 2.2).
  324. ; Modifications here can allow installation of multiple 
  325. ; drivers.  This is safer as it stands.
  326. ; a,f,h,l
  327. chksys:    call    findos        ;         worked before, must work now
  328.     ld    a,e
  329.     cp    3
  330.     ret    nz        ;             boot pointer should end in 3
  331.     ld    a,d
  332.     sub    h
  333.     sub    bdoslgh        ;     Z flag if correct page,
  334.     ret            ;             else non-virgin BIOS pointer
  335. ;
  336. vecterr:
  337.     pop    de        ;         remove the extra pointer
  338.      endif            ;         NOT nodrive
  339. ;    "    "
  340. ; Exit with invalid system message
  341. badsys:    ld    de,vcterrmsg
  342. ;    "    "
  343. ; exit with message de^
  344. exeunt:    call    tstr
  345.     jp    boot        ;         try re-booting.
  346. ;
  347. vcterrmsg:
  348.     db    cr,lf,'Invalid system$'
  349. ;
  350. ; Find the actual location of BDOS by following the trail from
  351. ; the pointer in hl.  Return z flag and hl = pointer to location
  352. ; 7 of the base BDOS page if found, else nz flag.
  353. ; For this to function connectors must be of the form used in
  354. ; intercept below.  Scan for label "intercept:"
  355. ; Note that ENTRY IS IN THE MIDDLE, not the next instruction
  356. ; a,f,h,l
  357. fndos1:    cp    03eh        ;         (mvi a).  Check for intercept
  358.     ret    nz        ;             not a connector, not found
  359.     inc    hl        ;         ignore operand for MVI A,--
  360.     inc    hl
  361.     ld    a,(hl)
  362.     cp    0b9h        ;         (cmp c)
  363.     ret    nz        ;             not a connector
  364.     inc    hl
  365.     ld    a,(hl)
  366.     and    0e7h        ;         may be an intercept
  367.     cp    0c2h        ;         jz, jnz, jc, jnc are acceptable
  368.     ret    nz        ;             not a connector
  369.     inc    hl
  370. fndos2:    ld    a,(hl)
  371. fndos3:    inc    hl        ;         load the JMP operand
  372.     ld    h,(hl)
  373.     ld    l,a        ;         and continue up the chain
  374. ;    "    "
  375. ; Main entry point here
  376. findos:    ld    a,(hl)        ;         find the actual BDOS.   *** ENTRY <<<
  377.     cp    0c3h        ;         (jmp).  Code for CPM 2.2 only
  378.     jp    nz,fndos1    ;         Not the real thing
  379. fndos4:    inc    hl
  380.     ld    a,(hl)
  381.     cp    bdosarg mod 256    ;     known value in CPM 2.2
  382.     jp    nz,fndos3    ;         not end, continue up the chain
  383.     inc    hl
  384.     ld    a,(hl)
  385.     add    a,bdosarg / 256    ;     allow for non-CPM systems
  386.     cp    h        ;         at end JMP is on same page (CPM2.2)
  387.     dec    hl        ;         point back to start of arg
  388.     jp    nz,fndos2    ;         else continue up the chain
  389.     ret            ;     (z)        FOUND it.
  390. ;
  391. ; =============================================================
  392. ; ****    Custom portion of initialization code here       ****
  393. ; =============================================================
  394. ;
  395. ; The following code is used on initialization and then discarded.
  396. ; See "RSXINIT.xxx" for details.  It may call on all routines in
  397. ; the system.
  398.     include    RSXINIT.INC
  399. ;
  400. ; ------------------ End custom initialization area ----------------
  401. ;
  402.     align 256,@base,0    ;     ensure page aligned
  403. ;
  404. ; *******************************************************
  405. ; * The code from here up is retained in memory after     *
  406. ; * initialization.  It may be used by the initializer    *
  407. ; * This code MUST start on a page boundary.        *
  408. ; *******************************************************
  409. @keep:
  410. ;
  411. ; During operation, this location will point to intercept and will
  412. ; be jumped to by BDOS calls from location 5.  This organization
  413. ; depends on the fact that BDOS calls the bios directly (ignoring
  414. ; the pointer at location 1), except when needing a warm boot
  415. ; (e.g. after a disk error), when it uses the pointer at 1.
  416. ;
  417. ; This must be at the lowest location in the protected code segment.
  418. bdosv:    jp    intercept    ;     the bdos link
  419. ;
  420. ; This will normally contain no code, but can be used to create a
  421. ; system compatible with the existing BYE programs.
  422.     include    BYERSX.INC
  423. ;
  424.      if    nodrive
  425. bsave:    dw    $-$        ;         save original warm boot connector
  426.      else            ;         NOT nodrive
  427. ; This area replaces the bios jump table, allowing intercepts.
  428. ; Any intercepts (usually console commands) are set up by the
  429. ; initializing code, which is discarded after execution. See
  430. ; comments on "nvects" above.  Normally these bios vectors will be
  431. ; accessed only by executing programs, and not by the BDOS unit.
  432. ; To insert drivers in the bios it is necessary to save the original
  433. ; bios pointers (for restoration when the RSX is removed) and
  434. ; install jumps to this revised table in the original table.  Note
  435. ; that the original table may contain a CALL for the warmboot vector,
  436. ; so that ROM based code can tell the CPM system size when called.
  437. biosv:    rept nvects        ; ;    biosv is the new warmboot connector
  438.     jp    $-$
  439.      endm
  440. ;
  441. ; This table has two purposes - it allows connection to the original
  442. ; bios vectors destinations, and it saves all the values for
  443. ; restoration upon RSX exit.  Thus the custom initialization section
  444. ; can patch the real bios table to install new disk drivers, etc.
  445. ; Note that this can only work when this is the FIRST rsx installed.
  446. ; Further ones can only intercept user bios calls and BDOS calls.
  447. ; Provided that the bios table in effect on entry to this system
  448. ; does not hold any data areas, the restoration on RSX removal will
  449. ; be harmless.
  450. bsave:    rept nvects        ; ;    bsave is the old warmboot connector
  451.     jp    $-$
  452.      endm
  453. ;
  454. ; An example showing how to refer to the "old" entries needed.
  455. ; Index 0 here is warmboot, not cold.  Similarly for "new" entries
  456. ;@home        equ    bsave+(7*3)
  457. ;@seldk        equ    bsave+(8*3)
  458. ;@setrk        equ    bsave+(9*3)
  459. ;@setsec    equ    bsave+(10*3)
  460. ;@setdma    equ    bsave+(11*3)
  461. ;@read        equ    bsave+(12*3)
  462. ;@write        equ    bsave+(13*3)
  463. ;@sectran    equ    bsave+(15*3)
  464.      endif            ;         NOT nodrive
  465. ;
  466. ; This routine intercepts all BDOS calls.
  467. ; Note that the initial code sequence allows applications to
  468. ; find the actual BDOS, if necessary.  See SD88F6 for one use.
  469. intercept:
  470.     ld    a,0ffh
  471.     cp    c
  472.     jp    c,gobdos    ;         Never taken, but SD trackable
  473.     ld    a,@sys        ;         Get function
  474.     cp    c
  475.     jp    z,sysreq    ;         a reboot request
  476.     ld    a,@dma
  477.     cp    c
  478.     jp    z,dodma
  479.     ld    a,@log
  480.     cp    c
  481.     jp    z,drvreset    ;     reset this drive also
  482.     ld    a,@rsx        ;         defined for this system
  483.     cp    c
  484.     jp    z,inrange
  485.     ld    a,@rsxx        ;     check for a special extra
  486.     cp    c        ;          intercept (e.g. setuser for
  487.     jp    z,inrange    ;      BYE replacement)
  488.     ld    a,@rsxy        ;     check for another special extra
  489.     cp    c        ;          intercept (e.g. chain for
  490.     jp    z,inrange    ;      BYE replacement)
  491.     ld    a,@rsxlo-1
  492.     cp    c
  493.     jp    nc,gobdos    ;         not in range
  494.     ld    a,@rsxhi
  495.     cp    c
  496.     jp    c,gobdos    ;         not for us
  497. ; DO NOT optimize the above sequence.  It is intended to be
  498. ; trackable by utilities to list the RSX's active.  The series
  499. ; stops when the instruction is not "ld a,bytevalue".  The
  500. ; initial "ld a,0ffh" will not be counted by tracking utilities
  501. ; and the checks on @SYS and @DMA are always expected.  This
  502. ; organization allows a range of BDOS calls to be intercepted.
  503. ;    "    "
  504. inrange:
  505.     ld    hl,0        ;         intercepting, switch stacks
  506.     add    hl,sp        ;          because application may not
  507.     ld    sp,lclstk    ;      allow sufficient room
  508.     push    hl        ;         save entry stack pointer
  509.     call    doit        ;         This is an extension call
  510.     ex    de,hl        ;             save return value
  511.     pop    hl        ;         restore entry stack
  512.     ld    sp,hl
  513.     ex    de,hl        ;             return its result
  514.     ld    a,l        ;         copy result to (a)
  515.     ld    b,h        ;         so (ba)=(hl), like BDOS
  516.     ret            ;             to the caller.
  517. ;
  518. ; Reset this drive also when application wants a drive reset
  519. ; Added to RSX system for disk drive application.
  520. ; This is also called on any warm-boots
  521. drvreset:
  522.     push    bc
  523.     call    bthook        ;         user customizable.
  524.     pop    bc
  525.     jp    gobdos
  526. ;
  527. ; Keep track of the current DMA address on general principles
  528. dodma:    ex    de,hl
  529.     ld    (dmadr),hl    ;         BDOS' view, not BIOS
  530.     ex    de,hl
  531. ;    "    "
  532. ; Connects to the "real" BDOS routine
  533. gobdos:    jp    $-$        ;         Patched on entry
  534. ;
  535. ; The RSX (resident system extension).  Argument is de as usual,
  536. ; and the extension specified is (c).  Return value is put in hl.
  537. ; The stack is already set to the local stack, with the old
  538. ; stack pointer under the return from doit.
  539. ; a,f,b,c,d,e,h,l (allowed)
  540. doit:    ld    hl,(active)    ;         set "enquiry" return value in (l)
  541.     ld    a,l
  542.     or    a
  543.     jp    z,gobdos    ;         inactive, use bdos call
  544.     ld    a,c
  545.     cp    @rsx
  546.     jp    nz,rsx        ;         not the master call, ignore parm
  547.     ld    h,0
  548.     ld    a,e        ;         check for "loaded enquiry"
  549.     or    d
  550.     ret    z        ;             signal active on enquiry
  551.     ld    a,e
  552.     and    d
  553.     inc    a
  554.     jp    nz,rsx        ;         not "pulldown" request.
  555. ;    "    "
  556. ; Inactivate the RSX.  Next boot will try to recover the memory.
  557. kill:    ld    a,$-$        ;         patched with "chkflg" at init
  558.     or    a
  559.     call    nz,unpch    ;         Remove any bios alterations
  560.     xor    a
  561.     ld    (active),a    ;         mark inactive
  562.     ld    l,a        ;         return 0, pulldown accepted
  563.     ld    h,a        ;         and we are now inactive.
  564.     ret
  565. ;
  566. unpch:     if    nodrive
  567.     ret
  568.      else            ;         NOT nodrive
  569. ; Remove any bios patches made on initialization, in case this is a
  570. ; driver being inactivated, and further RSX's are loaded beyond it.
  571. ; Thus a "kill" request will be logically executed, even though the
  572. ; memory is not reclaimed. However bios alterations via the pointer
  573. ; at 1 cannot be removed until a warm boot occurs (that pointer may
  574. ; be pointing to an RSX installed later).  Thus the table at biosv
  575. ; must be updated to point to the original bios entries
  576.     ld    de,bsave+3
  577.     ld    hl,(boot0+1)
  578.     inc    hl
  579.     inc    hl
  580.     inc    hl        ;         start at the constat entry
  581.     push    hl
  582.     ld    hl,biosv+3
  583.     ld    c,n22vec-1    ;     dont alter the warm boot entries
  584. unpch1:    ld    b,l        ;         offset, depends on page alignment
  585.     inc    de        ;         past opcode
  586.     inc    hl        ;         Ignore the opcode (dont change)
  587.     ld    (hl),b        ;     biosv[n,1]  --> oldbios[n,0]
  588.     inc    hl
  589.     ex    (sp),hl
  590.     ld    b,h        ;         oldbios page
  591.     inc    hl
  592.     ld    a,(de)        ;         lsb
  593.     ld    (hl),a        ;     oldbios[n,1]
  594.     inc    de        ;         ^msb
  595.     inc    hl
  596.     ld    a,(de)        ;         msb
  597.     ld    (hl),a        ;     oldbios[n,2]
  598.     inc    hl        ;     oldbios[n+1,0]
  599.     ex    (sp),hl
  600.     ld    (hl),b        ;     biosv[n,2] --> oldbios[n,0]
  601.     inc    hl        ;     biosv[n+1,0]
  602.     inc    de        ;         next opcode
  603.     dec    c        ;     n := n+1
  604.     jp    nz,unpch1
  605.     pop    hl
  606.     ret
  607.      endif            ;         NOT nodrive
  608. ;
  609. ; Note that the following "boot" entries will never be reached if a
  610. ; further RSX has been installed, since that RSX will intercept the
  611. ; boot and do a direct return to the CCP (unless it is inactive, and
  612. ; removes itself, when a whole chain of RSX removals can be started)
  613. ;
  614. ; The application process has requested a warm-boot by invoking BDOS
  615. ; function 0.  If the system is inactive remove it, otherwise return
  616. ; to the CCP via the stored (on initialization) CCP return value.
  617. sysreq:    jp    bootrq        ;         This allows separation if needed
  618. ;
  619. ; The application process has requested a reboot by jumping to
  620. ; location 0.  If we are no longer active, we will honor the request
  621. ; by executing the address found in the BOOT vector at entry.
  622. ; Otherwise return to CCP without rebooting.
  623. bootrq:    ld    sp,lclstk    ;     set up a valid stack
  624.     ld    a,(active)
  625.     or    a
  626.     jp    z,done        ;         Not active, all done. Remove self
  627.     call    boothk        ;         For applications to detect reboot
  628.     ld    c,@log
  629.     call    drvreset    ;     Reset drives, like any other reboot
  630.     ld    de,actmsg    ;      does.  Calls bthook routine
  631.     call    tstr
  632.     ld    de,altid    ;     added message portion for
  633.     call    tstr        ;           DSKDRIVE use
  634. ;    "    "
  635. ; Reset the system pointers to use this system.
  636.     ld    hl,bdosv
  637.     ld    (bdos+1),hl
  638.      if    not nodrive    ;     else leave connectors alone
  639.     ld    hl,bootrq
  640.     ld    (biosv+1),hl
  641.     ld    hl,biosv
  642.     ld    (boot+1),hl
  643.      endif            ;         NOT nodrive
  644.     ld    hl,tbuff
  645.     ld    (dmadr),hl    ;         Will be set by CCP
  646.     ld    a,(drvusr)
  647.     ld    c,a        ;         drive/user under which to re-enter
  648. ccpret:    jp    $-$        ;         Patched on startup
  649. ;
  650. ; Done with the system
  651. done:    ld    de,donemsg    ;     Message and jump to old boot addr.
  652.     call    tstr        ;         as originally read from memory wd 1
  653.      if    nodrive        ;     Then we have to reset the wboot
  654.     ld    hl,(bsave)
  655.     ex    de,hl
  656.     ld    hl,(boot0+1)    ;     The original destination
  657.     inc    hl
  658.     ld    (hl),e
  659.     inc    hl
  660.     ld    (hl),d        ;         restore it all
  661.      endif
  662. boot0:    jp    $-$        ;         Reboot. Patched on initialization
  663. ;                This value points to old bios table
  664. ;                and the old reboot resets connectors
  665. ;
  666. ; ================================================================
  667. ;          Utility routine area
  668. ; ================================================================
  669. ;
  670. ; Put string (de) to console, '$' terminated
  671. ; a,f
  672. tstr:    ld    a,@msg
  673. ;    "    "
  674. ; dos call (a) without disturbing registers.  Does not use the RSX
  675. ; a,f
  676. dos:    push    bc
  677.     push    de
  678.     push    hl
  679.     ld    c,a
  680.     call    gobdos
  681.     pop    hl
  682.     pop    de
  683.     pop    bc
  684.     ret
  685. ;
  686. ; ==================================================================
  687. ; **** To keep as much as possible constant, put real RSX here    ****
  688. ; ==================================================================
  689. ;
  690. ; The following allows for machine dependant code for i/o drivers
  691. ; the file may consist of comments only if not needed.
  692.     include    RSXIO.INC
  693. ;
  694. ; The following is the actual application code.  It may only call on
  695. ; the following routines: TSTR, DOS, GOBDOS. (See above)
  696.     include    RSXMAIN.INC
  697. ;
  698. ; This organization allows RSXMAIN to assign storage contiguous
  699. ; to the local stack, but not past it.
  700.     ds    stksz        ; Local stack of at least STKSZ/2 words
  701. ;            plus any remainder on page
  702.     ds    2        ;     allow for dmadr below, forced to page end
  703. ; align to next page boundary
  704.     align 256,bdosv
  705. ;
  706. lclstk    equ    $-2        ;     Reserve space for following
  707. dmadr    equ    lclstk        ;     Keeps track of current value known to DOS.
  708. ;            Note that this may not be that known to BIOS
  709. ;*************************************************
  710. ; End of segment to be relocated.
  711. pages    equ    ($-@base)/256    ;     So loader knows memory needs.
  712. ;
  713.     end
  714.