home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / p / safram.lbr / SAFRAM.AZM / SAFRAM.ASM
Encoding:
Assembly Source File  |  1993-10-25  |  17.1 KB  |  899 lines

  1. *    safram.asm                Roy Lipscomb
  2. *    Version 1.0                Aug 1, 1982
  3. *
  4. *    Creates a "safe" partition below BDOS.  Modules residing
  5. *    in the partition are safe from destruction until the
  6. *    the next system reset.
  7. *
  8. *    Copyright 1982 by Roy Lipscomb, Logic Associates, Chicago
  9. *
  10. *    Original distributor:  HP/RCPM, (312) 955-4493
  11. *
  12. *
  13. ********************************************************************
  14. *
  15. *    Description of this program is contained in SAFRAM.DOC and
  16. *    in SAFRAM.H.
  17. *
  18. *    Before attempting to assemble this source, please read the
  19. *    ASSEMBLING section in SAFRAM.DOC.
  20. *
  21. *********************************************************
  22. *        service/loader routines            *
  23. *********************************************************
  24.  
  25.     if    copy1        ;service routines
  26.     org     100h
  27.     jmp    begin
  28.  
  29.  
  30. no    equ    0
  31. yes    equ    1
  32.  
  33. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  34. ;        customizing variables            ;
  35. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  36. boot    equ    0        ;lowest address within CP/M
  37.  
  38. notify    equ    yes        ;at each ^C, notify of secure addr
  39.  
  40. hotboot    equ    0        ;set to 0 to deactivate.
  41.                 ;hotboot gives displacement from start
  42.                 ; of bios to first instruction after
  43.                 ; code that loads CCP/BDOS/BIOS.
  44.                 ; See document SAFRAM.H for information.
  45.  
  46. pagebnd    equ    no        ;to force all secure addresses
  47.                 ;to page boundary, change to "yes"
  48.  
  49. ;nothing below this point needs to be customized.
  50.  
  51. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  52. bell    equ    7
  53. coutdsp    equ    12-3        ;displacement of charout from wboot
  54. bdosjmp    equ    boot+5
  55. pstr    equ    9
  56. deffcb    equ    boot+5ch
  57. tbuff    equ    boot+80h
  58.  
  59. tab    equ    9
  60. cr    equ    13
  61. lf    equ    10
  62. blank    equ    ' '
  63.  
  64. pageopt    equ    (not pagebnd)/100h ;if pagebnd = no, pageopt = 0ffh
  65. secaddr    dw    0        ;highest available RAM excluding CCP
  66. loadpnt    dw    0
  67. modbase    dw    0        ;starting point of module
  68.                 ;(different from loadpnt if old module)
  69.  
  70. ;values used in setting traps
  71. biosdsp    dw    0
  72. biosav    dw    0
  73. trapent    dw    0
  74.  
  75. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  76. ;values used in manipulating the ccp
  77.  
  78. doslen1    equ    0d00h        ;length of cpm 1.x bdos
  79. doslen2    equ    0e00h        ;length of cpm 2.x bdos
  80.  
  81. ccplen    equ    800h        ;length of ccp
  82. ccpclen    equ    7        ;ccp command-length byte
  83. ccpcchr    equ    88h        ;ccp current-char displacement
  84. ccp    dw    0        ;ccp entry point
  85.  
  86. curdrv    equ    4        ;current drive in pg zero
  87. ccpstrt    dw    0        ;pointer to first char in ccp buff
  88.  
  89.  
  90.  
  91. ;messages
  92. eom    equ    '$'
  93.  
  94. baddr    db    cr,lf
  95.     db    bell
  96.     db    'Abort:  Valid address range at present is '
  97. badad1    db    '....H through '
  98. badad2    db    '....H.'
  99.     db    cr,lf
  100.     db    '$'
  101.  
  102. ccpmess    db    'Abort:  unable to locate CCP'
  103.     db    bell,cr,lf,cr,lf,eom
  104.  
  105. helpmes    db    cr,lf
  106.     db    '  SAFRAM'
  107.     db    '   Copyright 1982 by Roy Lipscomb, Logic Associates'
  108.     db    cr,lf
  109.     db    '              Version 1.0      Aug, 1982'
  110.     db    cr,lf
  111.     db    cr,lf
  112.     db    '  Assigns safe partition (removed only by system'
  113.     db    ' reset) below BDOS.'
  114.     db    cr,lf
  115.     db    '  (Multiple executions of SAFRAM are permitted).'
  116.     db    cr,lf
  117.     db    cr,lf
  118.     db    '   []  To secure the CCP or the boot+6 address, '
  119.     db    'type "SAFRAM".'
  120.     db    cr,lf
  121.     db    '   []  To secure a lower address, type "SAFRAM xxxx",'
  122.     db    ' where'
  123.     db    cr,lf
  124.     db    '       "xxxx" is address in hex.'
  125.     db    cr,lf
  126.     db    cr,lf
  127.     db    '    ',eom
  128.  
  129. crlf    db    cr,lf
  130.     db    eom
  131.  
  132.  
  133. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  134. ;        mainline                ;
  135. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  136.  
  137. begin    call    signon        ;print signon message
  138.  
  139.     call    getbase        ;compute load address: just below CCP
  140.     cz    ccperr        ;ccp not found
  141.     jz    exit
  142.  
  143. ;test for explicit address on command line.  Abort if bad.
  144.     call    expladr
  145.     jnz    exit        ;quit if error
  146.  
  147. ;if already loaded and active, don't load again (just update it)
  148.     call    tstact
  149.     cz    active
  150.     cnz    instal
  151.  
  152. ;if ddt executing, do restart 7; else return to cpm
  153. exit    lxi    h,0
  154.     dad    sp        ;if stack pointer <= 100,
  155.     mov    a,h        ; then ddt active
  156.     cpi    2
  157.     rnc        ;stack pointer >1ff, so must be cpm
  158.  
  159.     rst    7        ;ddt active;  do restart 7
  160.  
  161. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  162. ;        compute load address            ;
  163. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  164. ;if ccp not found, return with zero set
  165.  
  166. ;first try to find ccp:  standard method
  167. getbase    lhld    boot+6
  168.     shld    secaddr        ;secure-address if ccp already
  169.                 ;  secured (default)
  170.     lxi    d,0
  171.     call    tstccp        ;add de and hl for candidate ccpbase
  172.     jz    ccpnosc        ;ccp found, not secured
  173.  
  174. ;second try:  via cbios entry point of cpm 2.x
  175.     lhld    boot+1
  176.     lxi    d,-doslen2
  177.     call    tstccp        ;add de and hl for candidate ccpbase
  178.     jz    ccpsec        ;ccp found, secured
  179.  
  180. ;last try:  via cbios entry point of cpm 1.x
  181.     lhld    boot+1
  182.     lxi    d,-doslen1
  183.     call    tstccp        ;add de and hl for candidate ccpbase
  184.     jz    ccpsec        ;ccp found, secured
  185.  
  186. ;ccp not found
  187.     xra    a
  188.     ret            ;set zero flag ("not found")
  189.  
  190. ;ccp secured/not-secured
  191. ccpnosc    lhld    ccp        ;(really contains bdos addr here)
  192.     shld    secaddr        ;set to secure ccp
  193.  
  194. ccpsec    ori    1
  195.     ret
  196.  
  197.  
  198. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  199. ;test for explicit address on command line.  Abort if error
  200. ;if no error, return with z flag = yes
  201.  
  202. ;get parm length and address
  203. expladr    lxi    d,tbuff        ;get parm length
  204.     ldax    d
  205.     mov    b,a        ;save parm length byte
  206.     inr    b
  207.  
  208. ;skip leading blanks, exit if nothing left
  209. expl4    dcr    b
  210.     jz    expl9
  211.  
  212.     inx    d
  213.     ldax    d
  214.     call    blnktab        ;test for blank or tab
  215.     jz    expl4
  216.  
  217. ;digest the parm
  218.     lxi    h,0        ;initialize hex value
  219.  
  220. expl6    call    asc2hex        ;build hex value in hl
  221.     jnz    expl8        ;exit if error
  222.  
  223.     dcr    b
  224.     jz    expl7
  225.  
  226.     inx    d
  227.     ldax    d
  228.     call    blnktab        ;test for blank or tab
  229.     jnz    expl6
  230.  
  231. ;value digested:  verify it's acceptable
  232. expl7    xchg            ;save in de
  233.     lxi    h,progend+2
  234.     call    neghl
  235.     dad    d
  236.     jnc    expl8        ;error if below end of this prog...
  237.  
  238.     lhld    secaddr
  239.     inx    h
  240.     call    neghl
  241.     dad    d
  242.     jc    expl8        ;  ...or if higher than available top
  243.  
  244. ;value ok:  substitute it for implicit address
  245.     xchg
  246.     shld    secaddr
  247.  
  248.     xra    a        ;set z = "no error"
  249.     jmp    expl9
  250.  
  251. ;error exit:  display acceptable addr range, then exit.
  252. expl8    lxi    h,progend+3
  253.     call    hex2asc        ;put value in de and hl
  254.     lxi    h,badad1
  255.     call    put2bad
  256.  
  257.     lhld    secaddr
  258.     call    hex2asc
  259.     lxi    h,badad2
  260.     call    put2bad
  261.  
  262.     lxi    d,baddr
  263.     mvi    c,pstr
  264.     call    bdosjmp
  265.  
  266.     ori    1        ;set z = "error"
  267.  
  268. expl9    ret
  269.  
  270. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  271. ;test for blank or tab in a; if yes, return z = yes
  272. blnktab cpi    blank
  273.     rz
  274.  
  275.     cpi    tab
  276.  
  277.     ret
  278.  
  279. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  280. ;put address into error message
  281. put2bad    mov    m,b
  282.     inx    h
  283.  
  284.     mov    m,c
  285.     inx    h
  286.  
  287.     mov    m,d
  288.     inx    h
  289.  
  290.     mov    m,e
  291.  
  292.     ret
  293.  
  294. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  295. ;convert ascii characters into hex (using hl)
  296. asc2hex    sui    '0'
  297.     rc            ;exit if invalid char
  298.  
  299.     cpi    10
  300.     jc    asc2b
  301.     sui    7
  302.  
  303.     cpi    16
  304.     jnc    asc2x
  305.  
  306. asc2b    dad    h
  307.     dad    h
  308.     dad    h
  309.     dad    h
  310.  
  311.     add    l
  312.     mov    l,a
  313.  
  314.     xra    a        ;set z = "no error"
  315.  
  316.     ret
  317.  
  318. ;error exit
  319. asc2x    ori    1        ;set z = "error"
  320.  
  321.     ret
  322.  
  323. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  324. ;convert hex value to ascii
  325. hex2asc    call    hex2b
  326.     mov    b,d
  327.     mov    c,e
  328.  
  329. hex2b    call    hex2c
  330.     mov    d,a
  331.  
  332.     call    hex2c
  333.     mov    e,a
  334.  
  335.     ret
  336.  
  337. hex2c    mov    a,h
  338.  
  339.     dad    h
  340.     dad    h
  341.     dad    h
  342.     dad    h
  343.  
  344.     rar
  345.     rar
  346.     rar
  347.     rar
  348.  
  349.     ani    0fh
  350.     adi    '0'
  351.  
  352.     cpi    '9'+1
  353.     rc
  354.  
  355.     adi    7
  356.  
  357.     ret
  358.  
  359. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  360. ;convert hl to its negative
  361. neghl    push    psw
  362.  
  363.     mov    a,h
  364.     cma
  365.     mov    h,a
  366.  
  367.     mov    a,l
  368.     cma
  369.     mov    l,a
  370.  
  371.     inx    h
  372.  
  373.     pop    psw
  374.  
  375.     ret
  376.  
  377. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  378. ;test if this location has ccp
  379.  
  380. ;compute tentative ccpbase
  381. tstccp    mvi    l,0
  382.     dad    d        ;compute tentative bdos entry point
  383.  
  384.     lxi    d,-ccplen
  385.     dad    d        ;tentative bdos entry minus ccp length
  386.  
  387.     shld    ccp        ; ...gives tentative ccp entry
  388.  
  389. ;test for the two leading jumps in the ccp
  390.     mvi    a,jmp
  391.     lxi    b,3
  392.  
  393.     cmp    m
  394.     rnz
  395.  
  396.     dad    b
  397.     cmp    m
  398.     rnz
  399.  
  400. ;test for standard "maximum buffer length" value
  401.     dad    b
  402.     mov    a,m
  403.  
  404.     cpi    7fh        ;standard ccp maxbuff len
  405.     jz    tstcc4
  406.  
  407.     cpi    50h        ;standard zcp maxbuff len
  408.     rnz
  409.  
  410. ;test for "buffer length" < "maximum buffer length"
  411. tstcc4    inx    h
  412.     cmp    m
  413.     rc            ;give up if bufflen > maxbufflen
  414.  
  415.     xra    a        ;looks ok
  416.  
  417.     ret
  418. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  419. ;        test if module already active        ;
  420. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  421.  
  422. ;check address in bios table for wboot
  423. tstact    lhld    boot+1
  424.     inx    h
  425.     mov    e,m
  426.     inx    h
  427.     mov    d,m
  428.     xchg
  429.     shld    modbase        ;save it
  430.  
  431. ;test if "secure" message present where expected
  432.     lxi    d,wb2mess    ;get adjustment for message
  433.     dad    d
  434.  
  435. ;compare to unmoved module message
  436.     lxi    d,message+module1
  437.     mvi    b,testlen
  438. tstmess    ldax    d
  439.     cmp    m
  440.     jnz    failtst
  441.     inx    h
  442.     inx    d
  443.     dcr    b
  444.     jnz    tstmess
  445.  
  446. ;active already
  447.     xra    a
  448.     ret
  449.  
  450. failtst    ori    1        ;set flag
  451.     ret
  452.  
  453. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  454. ;    module already active:  process only stub    ;
  455. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  456.  
  457. ;determine where to install bypass
  458. active    lhld    secaddr
  459.     lxi    d,-3
  460.     dad    d
  461.     mvi    a,pageopt
  462.     ana    l
  463.     mov    l,a
  464.     shld    loadpnt
  465.  
  466. ;determine old module's start
  467.     lhld    modbase
  468.     lxi    d,-beforwb
  469.     dad    d
  470.     shld    modbase
  471.  
  472. ;secure, then update message and savearea
  473.     call    doprot
  474.  
  475. ;set for display of current secured address
  476.     lhld    modbase
  477.     lxi    d,bootflg
  478.     dad    d
  479.     mvi    m,on        ;set flag to "on"
  480.  
  481. ;set to bypass "not active" module
  482.     xra    a
  483.  
  484.     ret
  485.  
  486.  
  487. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  488. ;    module not active:  load from scratch        ;
  489. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  490.  
  491. ;if hotboot option requested, set it now
  492. instal    call    sethot
  493.  
  494. ;compute load point
  495.     lhld    secaddr
  496.     lxi    d,-length
  497.     dad    d
  498.     mvi    a,pageopt
  499.     ana    l
  500.     mov    l,a
  501.     shld    loadpnt
  502.     shld    modbase        ;modbase = new module entry
  503.  
  504. ;move it
  505.     call    chgaddr        ;convert to true addresses
  506.     call    movemod        ;move module to load address
  507.     call    traps        ;install traps
  508.     call    doprot        ;do secure, and update message
  509.  
  510.     ret
  511.  
  512. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  513. ;overlay warmboot jmptable entry with hotboot, if hotboot > bdos.
  514. sethot    lxi    b,hotboot
  515.     mov    a,b
  516.     ora    c
  517.     jz    noacex        ;hotboot option not in effect, so exit.
  518.  
  519.     lhld    boot+1        ;put warmstart jmptab entry into hl
  520.     mov    d,h
  521.     mov    e,l        ;  point de to warmboot jmp addr
  522.     inx    d
  523.  
  524.     dcx    b        ;normalize bc for warmstart, not cold
  525.     dcx    b
  526.     dcx    b
  527.     dad    b        ;compute hl = hotboot jump address
  528.  
  529.     mov    a,l        ;substitute hot for warm boot address
  530.     stax    d
  531.     inx    d
  532.  
  533.     mov    a,h
  534.     stax    d
  535.  
  536. noacex    ret
  537.  
  538. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  539. ;        convert module1 to true addresses    ;
  540. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  541.  
  542. ; change pseudo addresses to true addresses
  543. chgaddr    lxi    b,length
  544.     lxi    d,module1
  545.     lxi    h,module2
  546. truloop    ldax    d
  547.     cmp    m
  548.     cnz    convert
  549.  
  550.     inx    h
  551.     inx    d
  552.     dcx    b
  553.  
  554.     mov    a,b
  555.     ora    c
  556.     jnz    truloop
  557.  
  558.  
  559.     ret
  560.  
  561.  
  562. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  563. ;    convert displacement into address        ;
  564. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  565.  
  566. convert    push    b        ;length of module not yet processed
  567.     push    h        ;module2 character position
  568.  
  569. ; get displacement from instruction, put into bc.
  570.     ldax    d
  571.     mov    b,a
  572.     dcx    d
  573.     ldax    d
  574.     mov    c,a
  575.  
  576.     lxi    h,-module1    ;normalize displacement to zero
  577.     dad    b
  578.     push    h
  579.     pop    b
  580.  
  581.     lhld    loadpnt        ;add load point for true addr
  582.     dad    b
  583.  
  584. ; move true address to instruction
  585.     mov    a,l
  586.     stax    d
  587.     inx    d
  588.     mov    a,h
  589.     stax    d
  590.  
  591.     pop    h
  592.     pop    b
  593.  
  594.     ret
  595.  
  596. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  597. ;        move module into place            ;
  598. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  599.  
  600. movemod    lhld    loadpnt
  601.     xchg                ;de=destination
  602.     lxi    h,module1        ;hl=source 
  603.     lxi    b,length 
  604.  
  605.     call    move
  606.  
  607.  
  608.     ret
  609.  
  610. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  611. ;    install security, describe in message        ;
  612. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  613.  
  614. ;move the new secured address to de, then store wherever needed
  615.  
  616. ; secure the module
  617. doprot    lhld    6
  618.     xchg
  619.     lhld    loadpnt
  620.     shld    6
  621.  
  622. ;install bypass at base of secured RAM
  623.     push    h        ;save new secured address
  624.     mvi    m,jmp
  625.     inx    h
  626.     mov    m,e
  627.     inx    h
  628.     mov    m,d
  629.     pop    d        ;restore new secured address
  630.  
  631. ;store new secured address in module
  632.     lhld    modbase
  633.     lxi    b,savbase
  634.     dad    b
  635.     mov    m,e
  636.     inx    h
  637.     mov    m,d
  638.  
  639. ;convert hex address at location 6 to ascii, put in message
  640.     lhld    modbase        ;address message
  641.     lxi    b,messadr
  642.     dad    b        ;pointer to message into hl
  643.  
  644. ;output hi and lo bytes of address to message
  645.     call    hilo
  646. hilo    mov    a,d
  647.     mov    d,e        ;get next byte
  648.     push    psw
  649.     rar
  650.     rar
  651.     rar
  652.     rar
  653.     call    hexbyte
  654.     pop    psw
  655.  
  656. hexbyte    ani    0fh
  657.     adi    '0'
  658.     cpi    '9'+1
  659.     jc    movhex
  660.     adi    7
  661. movhex    mov    m,a
  662.     inx    h
  663.  
  664.     ret
  665.  
  666. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  667. ;        set all traps                ;
  668. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  669.  
  670. ;set trap for wboot
  671. traps    lxi    h,toboot+1
  672.     shld    biosav
  673.     lxi    h,beforwb
  674.     shld    trapent
  675.     lxi    h,0
  676.     shld    biosdsp
  677.  
  678.     call    settrap
  679.  
  680. ;set trap for conout
  681.     lxi    h,jmpcout+1
  682.     shld    biosav
  683.     lxi    h,pentry
  684.     shld    trapent
  685.     lxi    h,coutdsp
  686.     shld    biosdsp
  687.  
  688.     call    settrap
  689.  
  690.     ret
  691.  
  692. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  693. ;            set a trap            ;
  694. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  695.  
  696. settrap    lhld    modbase        ;get address of moved module
  697.     push    h
  698.     pop    b        ;save in bc
  699.  
  700.     lhld    biosdsp        ;get displace for bios jmptable into de
  701.     push    h
  702.     pop    d
  703.  
  704. ;get contents of bios jumptable entry
  705.     lhld    boot+1
  706.     dad    d        ;address bios jumptable entry
  707.     inx    h
  708.     push    h        ;...save pointer to table entry
  709.  
  710.     mov    e,m        ;...and get contents
  711.     inx    h
  712.     mov    d,m
  713.  
  714. ;store bios entry into trap savearea
  715.     lhld    biosav        ;save bios contents into trap mod
  716.     dad    b
  717.     mov    m,e
  718.     inx    h
  719.     mov    m,d
  720.  
  721. ;set bios entry to trap entry
  722.     lhld    trapent        ;get addr of appropriate trap into de
  723.     dad    b
  724.     xchg
  725.  
  726.     pop    h        ;store trap addr in bios jmptab
  727.     mov    m,e
  728.     inx    h
  729.     mov    m,d
  730.  
  731.     ret
  732.  
  733. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  734. ;        print messages                ;
  735. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  736. signon    lxi    d,helpmes
  737.     jmp    domess
  738.  
  739. ccperr    lxi    d,ccpmess
  740.  
  741. domess    mvi    c,pstr
  742.     call    bdosjmp
  743.     xra    a        ;set zero flag (for ccperr return)
  744.     ret
  745.  
  746.  
  747. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  748. ;        move block of data            ;
  749. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  750.  
  751. ;source in hl, destination in de, length in bc.
  752.  
  753. move    mov    a,b
  754.     ora    c
  755.     rz
  756.     mov    a,m
  757.     stax    d
  758.     inx    d
  759.     inx    h
  760.     dcx    b
  761.     jmp    move
  762.  
  763. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  764. ;        end of service routines            ;
  765. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  766.  
  767.     endif
  768.  
  769.  
  770.  
  771.  
  772. *********************************************************
  773. *********************************************************
  774. *    beginning of movable module            *
  775. *********************************************************
  776. *********************************************************
  777.  
  778.  
  779.     org    ($+0ffh)/100h*100h    ;must be page boundary
  780. adjust    set    $
  781.  
  782.     if    copy1
  783. module1    equ    $
  784.     endif
  785.  
  786.     if    not copy1
  787. module2    equ    $
  788.     endif
  789.  
  790.  
  791. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  792.  
  793. address    equ    0ffffh        ;various address to fill at runtime
  794. on    equ    0        ;do resecure
  795. off    equ    0ffh
  796. pflag    equ    on        ;harden security as soon as loaded
  797.  
  798. pbase    equ    $-adjust
  799.     jmp    address        ;security base:  "address" set at run
  800.                 ;time to jump to previous pbase
  801.  
  802. notiflg    equ    $-adjust
  803.     db    notify        ;yes/no for message at each ^C
  804. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  805. ;maintrap:  perform setup if wboot (or trap just loaded)
  806.  
  807. pentry    equ    $-adjust
  808. bootflg    equ    pentry+1
  809.     mvi    a,pflag        ;"on" for wboot
  810.     cpi    on        ;test for "on"
  811.     cz    afterwb+adjust
  812. jmpcout    equ    $-adjust
  813.     jmp    address        ;from bios conout jmptable entry
  814.                 ;("address" set at runtime)
  815.  
  816.  
  817. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  818. ;pre-wboot action:  set flag
  819. beforwb    equ    $-adjust
  820.     mvi    a,on
  821.     sta    bootflg+adjust
  822. toboot    equ    $-adjust
  823.     jmp    address        ;on to wboot (address set at runtime)
  824.  
  825. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  826. ;post-wboot action:  reset flag, restore security, rearm boot trap
  827. afterwb    equ    $-adjust
  828.     mvi    a,off
  829.     sta    bootflg+adjust    ;turn off flag
  830.  
  831. savbase    equ    $-adjust+1
  832.     lxi    h,address    ;restore secured address to 5h
  833.     shld    6        ;("address" filled at runtime)
  834.  
  835. ;if display option set, notify that security still in effect
  836.     lda    notiflg+adjust
  837.     cpi    yes
  838.     rnz
  839.  
  840.     push    b
  841.     lxi    d,message+adjust ;notify of current pbase
  842.  
  843. display    equ    $-adjust
  844.     ldax    d
  845.     inx    d
  846.     cpi    eom
  847.     jz    dispend+adjust
  848.  
  849.     mov    c,a
  850.     push    d
  851.     call    jmpcout+adjust
  852.     pop    d
  853.  
  854.     jmp    display+adjust
  855.  
  856.  
  857. dispend    equ    $-adjust
  858.     pop    b
  859.  
  860.     ret
  861.  
  862.  
  863.  
  864. ;don't remove the message below; used to test if module already present
  865.  
  866. message    equ    $-adjust
  867.  
  868. ;(number of blanks below is arbitrary)
  869.     db    '                                            '
  870.     db    '(Safram at '
  871. messadr    equ    $-adjust
  872.     db    '....)',cr,lf,eom
  873.  
  874. wb2mess    equ    message-beforwb        ;distance from wboot trap
  875. testlen    equ    messadr-message
  876.  
  877.  
  878. *********************************************************
  879. *        end of relocatable routines        *
  880. *********************************************************
  881.  
  882. ;get length of relocatable routines
  883. length    equ    $-adjust
  884.  
  885. ;flip the copy1/copy2 toggle
  886. copy1    set    not copy1
  887.  
  888. ;assemble address of end of this program
  889.     if    copy1
  890. progend    equ    $
  891.     endif
  892.  
  893. ;link a second copy, if this was the first copy
  894.     if    not copy1
  895.     link    safram
  896.     endif
  897. ram
  898.     if    copy1
  899. p