home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / CPM86 / RAMDISK.A86 < prev    next >
Text File  |  2000-06-30  |  14KB  |  599 lines

  1.  
  2.     title    'RAMDISK - A Memory-Based Virtual Drive'
  3.  
  4. ;    THIS PROGRAM IS HEREBY PLACED IN THE PUBLIC DOMAIN,
  5. ;        AND MAY BE FREELY COPIED AND DISTRIBUTED.
  6.  
  7. ;    program:    RAMDISK
  8. ;
  9. ;    created by      Context Sensitive Inc.
  10. ;                    4200 Aurora Ave. N.
  11. ;                    Seattle, WA  98103
  12. ;                    (206) 632-0301
  13. ;
  14. ;    version:    1.1        October 28, 1983
  15. ;    author:        Ron Blanford
  16. ;
  17. ;    The handler code for the RAM disk takes approximately 250h bytes,
  18. ;    or just over 1/2 kbyte.  In versions of CP/M-86 which include
  19. ;    hard disk support, the hard disk initialization code is only
  20. ;    executed once at cold boot, so this program can overlay it with the
  21. ;    handler code to save on memory usage.  To enable the overlay
  22. ;    logic, terminate the allocation size with a 'K', for example:
  23. ;        RAMDISK 128K
  24. ;    Otherwise the handler code will be placed at the beginning of
  25. ;    the TPA, reducing the available memory by a small amount.
  26. ;
  27. ;    In the standard CP/M the default interrupt vector does nothing but
  28. ;    an IRET and return to the program, effectively making all unplanned
  29. ;    interrupts (such as arithmetic exceptions and pressing the keyboard
  30. ;    reset button) invisible.  This program causes any such interrupt
  31. ;    to perform a warm boot, returning the user to the CP/M prompt.
  32.  
  33.  
  34. BIOS_segment    equ    0040h
  35. BIOS_jumptable    equ    2500h
  36.  
  37.     cseg
  38.     org    100h
  39.  
  40.     mov    dx,offset T_GETSEGT    ;get available memory size for messages
  41.     mov    cl,50
  42.     int    224
  43.     mov    ax,BIOS_segment
  44.     mov    es,ax
  45.     mov    ax,es:3[bx]
  46.     mov    cl,6            ;convert from pages to kbytes
  47.     shr    ax,cl
  48.     push    ax
  49.     mov    bx,offset h1_size+2
  50.     call    binasc
  51.     pop    ax
  52.     push    ax
  53.     mov    bx,offset h4_size+2
  54.     call    binasc
  55.     pop    ax
  56.     mov    bx,offset nm_size+2
  57.     call    binasc
  58.  
  59.     mov    dx,offset company_name    ;print company name message
  60.     mov    cl,9
  61.     int    224
  62.  
  63.     mov    bx,80h            ;check command buffer
  64.     mov    cl,[bx]            ; if no command tail was entered,
  65.     or    cl,cl            ; display help screens
  66.     jnz    RD04
  67.     mov    dx,offset help1
  68.     mov    cl,9
  69.     int    224
  70.     mov    cl,1
  71.     int    224
  72.     cmp    al,ctrl_C
  73.     jnz    $+5
  74.     jmp    exit1
  75.     mov    dx,offset help3
  76.     mov    cl,9
  77.     int    224
  78.     mov    cl,1
  79.     int    224
  80.     cmp    al,ctrl_C
  81.     jnz    $+5
  82.     jmp    exit1
  83.     mov    dx,offset help4
  84.     jmp    exit
  85.  
  86. RD04:    mov    dx,offset T_SELDSK    ;see if drive already exists
  87.     mov    cl,50
  88.     int    224
  89.     or    bx,bx
  90.     jz    RD05
  91.     mov    dx,offset I_exists
  92.     jmp    exit
  93.  
  94. RD05:    mov    bx,80h            ;get allocation size from command buffer
  95.     mov    cl,[bx]
  96.     sub    ch,ch
  97.     sub    ax,ax
  98. RD10:    inc    bx            ;convert ascii digits to binary
  99.     cmp    byte ptr [bx],' '
  100.     jbe    RD20
  101.     cmp    byte ptr [bx],'0'
  102.     jb    RD21
  103.     cmp    byte ptr [bx],'9'
  104.     ja    RD21
  105.     mul    ten
  106.     mov    dl,byte ptr [bx]
  107.     sub    dl,'0'
  108.     add    ax,dx
  109. RD20:    loop    RD10
  110. RD21:    or    ax,ax            ;make sure size specification is in range
  111.     jnz    RD30
  112.     mov    dx,offset nosize
  113.     jmp    exit
  114.  
  115. RD30:    mov    CBOOT_overlay,1        ;if nnnK entered, then put handlers
  116.     or    byte ptr [bx],20h    ; in space occupied by CBOOT code
  117.     cmp    byte ptr [bx],'k'
  118.     jz    RD35
  119.     mov    CBOOT_overlay,0
  120. RD35:    cmp    ax,512            ;max RAMDISK size is 512K
  121.     jbe    RD40
  122.     mov    ax,512
  123. RD40:    push    ax            ;put allocation in 'created' message
  124.     mov    bx,offset cr_size+2
  125.     call    binasc
  126.     pop    ax
  127.     mov    cl,6
  128.     cmp    ax,256            ;if >256K, then change parameters
  129.     jbe    RD45            ; to block at 2048
  130.     mov    byte ptr BSH,4        ; rather than default 1024
  131.     mov    byte ptr BLM,15
  132.     mov    byte ptr EXM,1
  133.     mov    word ptr DRM,127
  134.     shr    ax,1
  135.     mov    cl,7
  136. RD45:    mov    word ptr DSM,ax
  137.     dec    word ptr DSM
  138.     shl    ax,cl
  139.     mov    disk_pages,ax
  140. RD50:    mov    dx,offset T_GETSEGT    ;see if enough memory exists
  141.     mov    cl,50
  142.     int    224
  143.     mov    ax,BIOS_segment
  144.     mov    es,ax
  145.     mov    dx,es:3[bx]        ;number of pages available
  146.  
  147.     cmp    CBOOT_overlay,1
  148.     jz    RD55
  149.  
  150.     mov    ax,offset end_Kdrive    ;this code puts the RAMDISK handlers
  151.     sub    ax,offset init_Kdrive    ; at the beginning of the TPA
  152.     mov    cl,4            ; rather than overlaying CBOOT code.
  153.     shr    ax,cl
  154.     inc    ax
  155.     sub    dx,ax
  156.  
  157. RD55:    sub    dx,disk_pages
  158.     ja    RD60
  159.     mov    dx,offset nomem
  160.     jmp    exit
  161.  
  162. RD60:    mov    es:3[bx],dx        ;save new TPA length
  163.     mov    di,es:.BIOS_jumptable+1
  164.     add    di,BIOS_jumptable+3
  165.  
  166.     cmp    CBOOT_overlay,1
  167.     jz    RD65
  168.  
  169.     mov    di,es:1[bx]        ;this code puts the RAMDISK handlers
  170.     add    es:1[bx],ax        ; at the beginning of the TPA
  171.     mov    ax,es            ; rather than overlaying CBOOT code.
  172.     sub    di,ax
  173.     mov    cl,4
  174.     shl    di,cl
  175.  
  176. RD65:    mov    init_addr,di
  177.     add    dx,es:1[bx]
  178.     mov    disk_seg,dx
  179.     mov    bx,BIOS_jumptable+18h    ;move BIOS jumptable to local table
  180.     mov    di,offset BIOS_HOME    ; after converting from relative
  181.     mov    cx,10            ; to absolute addressing
  182. RD70:    inc    bx
  183.     mov    ax,es:[bx]
  184.     inc    bx
  185.     inc    bx
  186.     add    ax,bx
  187.     mov    [di],ax
  188.     inc    di
  189.     inc    di
  190.     loop    RD70
  191.  
  192.     mov    dx,init_addr        ;move my entry points to BIOS jump table
  193.     sub    dx,2
  194.     sub    dx,offset init_Kdrive
  195.     mov    di,BIOS_jumptable+18h
  196.     inc    di
  197.     mov    ax,offset HOME
  198.     add    ax,dx
  199.     sub    ax,di
  200.     mov    es:[di],ax
  201.     add    di,3
  202.     mov    ax,offset SELDSK
  203.     add    ax,dx
  204.     sub    ax,di
  205.     mov    es:[di],ax
  206.     add    di,3
  207.     mov    ax,offset SETTRK
  208.     add    ax,dx
  209.     sub    ax,di
  210.     mov    es:[di],ax
  211.     add    di,3
  212.     mov    ax,offset SETSEC
  213.     add    ax,dx
  214.     sub    ax,di
  215.     mov    es:[di],ax
  216.     add    di,3
  217.     mov    ax,offset SETDMA
  218.     add    ax,dx
  219.     sub    ax,di
  220.     mov    es:[di],ax
  221.     add    di,3
  222.     mov    ax,offset READ
  223.     add    ax,dx
  224.     sub    ax,di
  225.     mov    es:[di],ax
  226.     add    di,3
  227.     mov    ax,offset WRITE
  228.     add    ax,dx
  229.     sub    ax,di
  230.     mov    es:[di],ax
  231.     add    di,6            ;skip list status jump
  232.     mov    ax,offset SECTRAN
  233.     add    ax,dx
  234.     sub    ax,di
  235.     mov    es:[di],ax
  236.     add    di,3
  237.     mov    ax,offset SETDMAB
  238.     add    ax,dx
  239.     sub    ax,di
  240.     mov    es:[di],ax
  241.  
  242.     sub    ax,ax            ;set up interrupt handler
  243.     mov    es,ax            ; by replacing normal IRET
  244.     mov    di,es:.0        ; with JMP to my handler
  245.     mov    ax,es:.2
  246.     mov    es,ax
  247.     mov    al,0E9h            ;JMP instruction
  248.     mov    es:[di],al
  249.     inc    di
  250.     mov    ax,offset inttrap
  251.     add    ax,dx
  252.     sub    ax,di
  253.     mov    es:[di],ax
  254.  
  255.     add    dx,2            ;change local addresses to new location
  256.     mov    adj_offset,dx
  257.     add    DPH_offset,dx
  258.     add    DIRBUF_offset,dx
  259.     add    DPB_offset,dx
  260.     add    CSV_offset,dx
  261.     add    ALV_offset,dx
  262.  
  263.     mov    di,init_addr        ;move code and data into BIOS
  264.     mov    si,offset init_Kdrive
  265.     mov    cx,offset end_Kdrive
  266.     sub    cx,si
  267.     shr    cx,1
  268.     inc    cx
  269.     cld
  270.     rep movs ax,ax
  271.     mov    dx,offset created
  272.     mov    cl,9
  273.     int    224
  274.     jmpf    dword ptr init_addr    ;go execute disk initialization routine
  275. init_addr    dw    BIOS_jumptable+100h
  276.         dw    BIOS_segment
  277.  
  278.  
  279. ;    BINASC converts an unsigned binary number to ascii representation.
  280. ;        Input registers:    ax = number to convert
  281. ;                    bx = ptr to memory location
  282. ;                         for least significant digit
  283. binasc:
  284.     mov    byte ptr [bx],'0'
  285.     mov    cx,10
  286. ba10:    mov    dx,0            ;convert ax to ascii
  287.     div    cx
  288.     or    ax,ax
  289.     jnz    ba15
  290.     or    dx,dx
  291.     jz    ba20
  292. ba15:    or    dl,'0'
  293.     mov    byte ptr [bx],dl    ;store ascii digit in display area
  294.     dec    bx
  295.     jmps    ba10
  296. ba20:    ret
  297.  
  298. exit1:    mov    dx,offset abort_msg
  299. exit:    mov    cl,9
  300.     int    224
  301.     mov    dx,0
  302.     mov    cl,0
  303.     int    224
  304.  
  305.  
  306.     eject
  307.  
  308. ctrl_C        equ    03h
  309. cr        equ    0Dh
  310. lf        equ    0Ah
  311. esc        equ    1Bh
  312.  
  313. ten        dw    10
  314. CBOOT_overlay    db    1    ;1=overlay CBOOT code, 0=use part of TPA
  315.  
  316. T_SELDSK    db    9    ;direct BIOS call for disk selection
  317.         dw    10
  318.         dw    0
  319. T_GETSEGT    db    18    ;direct BIOS call for memory extents
  320.         dw    0
  321.         dw    0
  322.  
  323. company_name    db    esc,'[1;1H',esc,'[J',cr,lf,'       ',esc,'[2;3m ',esc,'[3;23m'
  324.         db    '                           RAMDISK  1.1                         '
  325.         db    esc,'[2m ',esc,'[m',cr,lf,'       ',esc,'[2;4m ',esc,'[4;20m'
  326.         db    '  Context Sensitive Inc.  Seattle, Washington   (206) NEC-0301  '
  327.         db    esc,'[2m '
  328.         db    esc,'[m',cr,lf,'$'
  329. help1        db    cr,lf,esc,'[19m'
  330.         db    cr,lf,'           Thank you for choosing RAMDISK from Context Sensitive Inc.'
  331.         db    cr,lf,esc,'[20m'
  332.         db    cr,lf,'          This program creates  a pseudo disk drive  using part of the'
  333.         db    cr,lf,'          random access memory (RAM)  of your computer.  Your computer'
  334.         db    cr,lf,'          has '
  335. h1_size    db    '   '
  336.         db    ' kbytes  of memory  available  for program execution.'
  337.         db    cr,lf,'          Most programs require less than 64 kbytes,  so any remaining'
  338.         db    cr,lf,'          memory would otherwise be unused.'
  339.         db    cr,lf
  340.         db    cr,lf,'          The main advantage  of using a RAM disk  is its speed.   The'
  341.         db    cr,lf,'          main drawback  is that it is  not permanent.   Each time the'
  342.         db    cr,lf,'          computer  is  turned  off  or  CP/M-86  rebooted  using  the'
  343.         db    cr,lf,'          CTRL-FNC-BREAK sequence,   all files stored  on the RAM disk'
  344.         db    cr,lf,'          are deleted and the RAM disk itself is eliminated. Therefore'
  345.         db    cr,lf,'          be sure  to save  all modified files  on a permanent disk at'
  346.         db    cr,lf,'          the end of every session with the computer.  In an emergency'
  347.         db    cr,lf,'          press the reset button behind the rubber stopper in the key-'
  348.         db    cr,lf,'          board to return to CP/M-86 without erasing the RAM disk.'
  349.         db    cr,lf
  350.         db    esc,'[25;1H',esc,'[21m          Press any key to continue...',esc,'[m$'
  351. help3        db    esc,'[7;1H',esc,'[J'
  352.         db    cr,lf,'          The  RAM disk  created  by this program  is called  drive K.'
  353.         db    cr,lf,'          Drive K  is used  the same way  as any other disk drive.  To'
  354.         db    cr,lf,'          list the directory of files, type:'
  355.         db    cr,lf,esc,'[23m                    DIR K:',esc,'[20m'
  356.         db    cr,lf,'          (Initially drive K is empty  and this command  will give the'
  357.         db    cr,lf,'          NO FILE  message.)   To  copy  programs  and  data  files to'
  358.         db    cr,lf,'          drive K, type:'
  359.         db    cr,lf,esc,'[23m                    PIP K:=filename.typ',esc,'[20m'
  360.         db    cr,lf,'          To select drive K as the default drive, just type:'
  361.         db    cr,lf,esc,'[23m                    K:',esc,'[20m'
  362.         db    cr,lf,'          in response to the CP/M-86 prompt.'
  363.         db    cr,lf
  364.         db    esc,'[25;1H',esc,'[21m          Press any key to continue...',esc,'[m$'
  365. help4        db    esc,'[7;1H',esc,'[J'
  366.         db    cr,lf,'          To create the RAM disk, type:'
  367.         db    cr,lf,esc,'[23m                    RAMDISK nnn',esc,'[20m'
  368.         db    cr,lf,'          where  nnn is the number of kbytes of memory to allocate for'
  369.         db    cr,lf,'          drive K.  Remember, this must be less than '
  370. h4_size        db    '   '
  371.         db    ' kbytes.'
  372.         db    cr,lf,esc,'[m$'
  373. abort_msg    db    0Bh,esc,'[m',esc,'[J$'
  374. nosize        db    cr,lf,esc,'[19m'
  375.         db    cr,lf,'                  A size must be specified for RAMDISK drive K'
  376.         db    cr,lf,esc,'[21m'
  377.         db    cr,lf,'              for example:  ''RAMDISK 128'' allocates 128K of memory'
  378.         db    esc,'[m',cr,lf,'$'
  379. nomem        db    cr,lf,esc,'[19m'
  380.         db    cr,lf,'                 RAMDISK drive K not created - not enough memory'
  381.         db    cr,lf,esc,'[21m'
  382.         db    cr,lf,'              Your computer only has '
  383. nm_size        db    '   '
  384.         db    ' kbytes of memory available'
  385.         db    esc,'[m',cr,lf,'$'
  386. I_exists    db    cr,lf,esc,'[19m'
  387.         db    cr,lf,'                 RAMDISK drive K not created - it already exists'
  388.         db    cr,lf,esc,'[21m'
  389.         db    cr,lf,'             CTRL-FNC-BREAK deletes all files and removes the drive'
  390.         db    esc,'[m',cr,lf,'$'
  391. created        db    cr,lf,esc,'[19m'
  392.         db    cr,lf,'                  RAMDISK drive K has been created ('
  393. cr_size        db    '   '
  394.         db    ' kbytes)'
  395.         db    cr,lf,esc,'[21m'
  396.         db    cr,lf,'             CTRL-FNC-BREAK deletes all files and removes the drive'
  397.         db    esc,'[m',cr,lf,'$'
  398.  
  399.  
  400.     title    'RAMDISK initialization and handler code'
  401.     eject
  402.  
  403. init_Kdrive:
  404.     call    adjust
  405.     mov    es,disk_seg[bx]
  406.     mov    ax,disk_pages[bx]
  407. init1:    push    ax            ;format the disk area
  408.     mov    cx,8000h
  409.     cmp    ax,1000h
  410.     ja    init2
  411.     mov    cl,3
  412.     shl    ax,cl
  413.     mov    cx,ax
  414. init2:    mov    di,0
  415.     mov    ax,0E5E5h
  416.     cld
  417.     rep stos ax
  418.     mov    ax,es
  419.     add    ax,1000h
  420.     mov    es,ax
  421.     pop    ax
  422.     sub    ax,1000h
  423.     ja    init1
  424.     mov    dx,0
  425.     mov    cl,0
  426.     int    224
  427.  
  428. HOME:    call    adjust
  429.     cmp    byte ptr sek_dsk[bx],10
  430.     jz    $+7
  431.     jmp    BIOS_HOME[bx]
  432.     ret
  433.  
  434. SELDSK:    call    adjust
  435.     mov    byte ptr sek_dsk[bx],cl
  436.     cmp    cl,10
  437.     jz    $+7
  438.     jmp    BIOS_SELDSK[bx]
  439.     mov    bx,DPH_offset[bx]
  440.     ret
  441.  
  442. SETTRK:    call    adjust
  443.     cmp    byte ptr sek_dsk[bx],10
  444.     jz    $+7
  445.     jmp    BIOS_SETTRK[bx]
  446.     mov    sek_trk[bx],cx
  447.     ret
  448.  
  449. SETSEC:    call    adjust
  450.     cmp    byte ptr sek_dsk[bx],10
  451.     jz    $+7
  452.     jmp    BIOS_SETSEC[bx]
  453.     mov    sek_sec[bx],cl
  454.     ret
  455.  
  456. SETDMA:    call    adjust
  457.     mov    DMA_offset[bx],cx
  458.     jmp    BIOS_SETDMA[bx]
  459.  
  460. READ:    call    adjust
  461.     cmp    byte ptr sek_dsk[bx],10
  462.     jz    $+7
  463.     jmp    BIOS_READ[bx]
  464.     pushf
  465.     push    ds
  466.     push    es
  467.     mov    es,DMA_seg[bx]
  468.     mov    di,DMA_offset[bx]
  469.     mov    ax,sek_trk[bx]
  470.     mov    cl,6
  471.     shl    ax,cl
  472.     add    al,sek_sec[bx]
  473.     mul    one_twenty_eight[bx]
  474.     mov    cl,12
  475.     shl    dx,cl
  476.     add    dx,disk_seg[bx]
  477.     mov    ds,dx
  478.     mov    si,ax
  479.     mov    cx,64
  480.     cld
  481.     rep movs ax,ax
  482.     pop    es
  483.     pop    ds
  484.     popf
  485.     sub    ax,ax
  486.     ret
  487.  
  488. WRITE:    call    adjust
  489.     cmp    byte ptr sek_dsk[bx],10
  490.     jz    $+7
  491.     jmp    BIOS_WRITE[bx]
  492.     pushf
  493.     push    ds
  494.     push    es
  495.     mov    ax,sek_trk[bx]
  496.     mov    cl,6
  497.     shl    ax,cl
  498.     add    al,sek_sec[bx]
  499.     mul    one_twenty_eight[bx]
  500.     mov    cl,12
  501.     shl    dx,cl
  502.     add    dx,disk_seg[bx]
  503.     mov    es,dx
  504.     mov    di,ax
  505.     mov    si,DMA_offset[bx]
  506.     mov    ds,DMA_seg[bx]
  507.     mov    cx,64
  508.     cld
  509.     rep movs ax,ax
  510.     pop    es
  511.     pop    ds
  512.     popf
  513.     sub    ax,ax
  514.     ret
  515.  
  516. SECTRAN: call    adjust
  517.     cmp    byte ptr sek_dsk[bx],10
  518.     jz    $+7
  519.     jmp    BIOS_SECTRAN[bx]
  520.     mov    bx,cx
  521.     ret
  522.  
  523. SETDMAB: call    adjust
  524.     mov    DMA_seg[bx],cx
  525.     jmp    BIOS_SETDMAB[bx]
  526.  
  527. inttrap:
  528.     cli
  529.     pop    ax            ;pop old IP, CS, and flags
  530.     pop    ax
  531.     pop    ax
  532.     or    ax,0200h        ;enable interrupts on return
  533.     push    ax
  534.     mov    ax,BIOS_segment        ;return to WBOOT
  535.     push    ax
  536.     mov    ax,BIOS_jumptable+3
  537.     push    ax
  538.     iret
  539.  
  540. adjust:        nop            ;all variables to be offset
  541.         db    0BBh        ; by the amount the program moved
  542. adj_offset    dw    0        ;this is a MOV BX,nnnn instruction
  543.         ret
  544.  
  545.  
  546.     eject
  547.  
  548. BIOS_HOME    DW    0
  549. BIOS_SELDSK    DW    0
  550. BIOS_SETTRK    DW    0
  551. BIOS_SETSEC    DW    0
  552. BIOS_SETDMA    DW    0
  553. BIOS_READ    DW    0
  554. BIOS_WRITE    DW    0
  555. BIOS_LISTST    DW    0
  556. BIOS_SECTRAN    DW    0
  557. BIOS_SETDMAB    DW    0
  558.  
  559. sek_dsk        db    0
  560. sek_sec        db    0
  561. sek_trk        dw    0
  562. DMA_offset    dw    0
  563. DMA_seg        dw    0
  564. disk_pages    dw    0
  565. disk_seg    dw    0
  566.  
  567. one_twenty_eight dw    128
  568.  
  569. DPH_offset    dw    offset DPH
  570.  
  571. DPH        dw    0    ;no sector translation
  572.         dw    0
  573.         dw    0
  574.         dw    0
  575. DIRBUF_offset    dw    offset DIRBUF
  576. DPB_offset    dw    offset DPB
  577. CSV_offset    dw    offset CSV
  578. ALV_offset    dw    offset ALV
  579.  
  580. DIRBUF        rs    128
  581. CSV        rs    0
  582. ALV        rs    32
  583.  
  584.                 ;disk size:   <256K        >256K
  585. DPB        dw    64    ;SPT
  586. BSH        db    3    ;BSH             3            4
  587. BLM        db    7    ;BLM             7           15
  588. EXM        db    0    ;EXM             0            1
  589. DSM        dw    0    ;DSM           #K-1      (#K/2)-1
  590. DRM        dw    63    ;DRM            63          127
  591.         db    0C0h    ;AL0
  592.         db    0    ;AL1
  593.         dw    0    ;CKS
  594.         dw    0    ;OFF
  595.  
  596. end_Kdrive    db    0
  597.  
  598.     end
  599.