home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / progjour / 1991 / 01 / swap.asm < prev    next >
Assembly Source File  |  1990-11-01  |  5KB  |  247 lines

  1.     title    swap file manager
  2.     include    asm.inc
  3.  
  4.     public    swap_in            ; swap block from file to ram
  5.     public    swap_out        ; swap block from ram to file
  6.  
  7. NULL_SWAP    equ    0
  8. SWAP_MAX    equ    1024        ; 16 megabytes of swap space
  9.  
  10.  
  11. XPB    segment word public 'DATA'    ; close and delete swap file on exit
  12. XPB    ends
  13. XP    segment word public 'DATA'
  14.     dw    on_exit_swap
  15. XP    ends
  16. XPE    segment word public 'DATA'
  17. XPE    ends
  18.  
  19.  
  20. XCB    segment word public 'DATA'    ; just delete swap file on termination
  21. XCB    ends
  22. XC    segment word public 'DATA'
  23.     dw    on_terminate_swap
  24. XC    ends
  25. XCE    segment word public 'DATA'
  26. XCE    ends
  27.  
  28.  
  29.     .const
  30. ertx_swap_full    db    'Swap space full',0
  31. ertx_swap_read    db    'Swap read',0
  32.  
  33.  
  34.     .data?
  35. swap_icount    dw    ?        ; number of blocks swapped in
  36. swap_ocount    dw    ?        ; number of blocks swapped out
  37.  
  38. swap_handle    dw    ?        ; swap file handle
  39.  
  40. swap_bits    db    SWAP_MAX/8 dup(?)
  41.  
  42. swap_fname    db    FILENAME_MAX dup(?)
  43.  
  44.  
  45.     .code
  46.  extn close_file,dialog_error_beta,move_file_pointer,ms_dos_dialog
  47.  extn read_from_file,remove,save_most,err_disk_full
  48.  
  49.  
  50. ;;    create swap file
  51. ;
  52. ;    exit    BX    file handle (swap_handle set)
  53. ;    uses    AX,CX,DX
  54. ;
  55. create_swap_file proc
  56.     push    ds
  57.     mov    ah,5Ah            ; create uniquely named file
  58.     movx    cx,0
  59.     lea    dx,swap_fname
  60.     movx    ds,DGROUP_SEGMENT
  61.     mov    swap_fname[bp],NULL_CHAR
  62.     call    ms_dos_dialog
  63.     jc    csf1            ;  if create failed
  64.  
  65.     mov    swap_handle,ax        ;  (DS==DGROUP here)
  66.     mov    bx,ax            ;\
  67. csf1:    pop    ds
  68.     ret
  69. create_swap_file endp
  70.  
  71.  
  72. ;;    get swap index
  73. ;
  74. ;    exit    AX    swap index (0..MAX-1)
  75. ;        Cf    if swap file full
  76. ;
  77. get_swap_index proc
  78.     pushm    cx,si
  79.     mov    al,1
  80.     mov    cx,SWAP_MAX
  81.     lea    si,swap_bits-1
  82.  
  83.     even                ; search swap bits for next free index
  84. gwi1:    ror    al,1
  85.     adc    si,ZER0
  86.     test    al,[bp+si]
  87.     loopnz    gwi1
  88.     jnz    gwi3            ; if no handles left (swap space full)
  89.     or    [bp+si],al
  90.  
  91.     mov    ax,SWAP_MAX-1
  92.     sub    ax,cx
  93.  
  94. gwi2:    popm    si,cx
  95.     ret
  96.  
  97. gwi3:    lea    ax,ertx_swap_full    ; *Swap space full*
  98.     call    dialog_error_beta
  99.     jmp    gwi2
  100. get_swap_index endp
  101.  
  102.  
  103. ;;    on exit swap
  104. ;
  105. ;    uses    AX,BX,SI,DS
  106. ;
  107. on_exit_swap proc
  108.     mov    bx,swap_handle[bp]
  109.     cmpx    bx,NULL_HANDLE
  110.     je    oes1            ;  if no swap file
  111.     call    close_file
  112. oes1:    ret
  113. on_exit_swap endp
  114.  
  115.  
  116. ;;    on terminate swap
  117. ;
  118. ;    uses    AX,CX,SI,DS
  119. ;
  120. on_terminate_swap proc
  121.     movx    cx,NULL_HANDLE        ; (during exit intercept, this proc 
  122.     xchg    cx,swap_handle[bp]    ; may execute under COMMAND.COM's PSP)
  123.     jcxz    ots1            ;  if no swap file
  124.  
  125.     movx    ds,DGROUP_SEGMENT    ;  else delete swap file (notice that
  126.     lea    si,swap_fname        ;   swap file is already closed by
  127.     call    remove            ;   dos terminator or on_exit routine)
  128. ots1:    ret
  129. on_terminate_swap endp
  130.  
  131.  
  132. ;;    swap in
  133. ;
  134. ;    entry    AX    swap index
  135. ;        ES:DI    destination (no disk I/O if NULL)
  136. ;    exit    Cf    if error
  137. ;    uses    AX
  138. ;
  139. swap_in proc
  140.     call    save_most
  141.     dec    ax            ; clear swap index bit
  142.     js    sin1            ;  if bad swap index (cannot be -)
  143.     mov    si,ax
  144.     mov    cl,3            ;  (divide bit number by 8 to select
  145.     shr    si,cl            ;   byte)
  146.  
  147.     mov    cl,al            ;  (use the 3 least significant bits
  148.     and    cl,7            ;   to rotate a mask)
  149.     mov    ch,10000000b
  150.     ror    ch,cl
  151.     test    swap_bits[bp+si],ch
  152.     jz    sin1            ;  if bad swap index (internal error)
  153.     xor    swap_bits[bp+si],ch
  154.  
  155.     mov    cx,es            ; do not read swap file if NULL output
  156.     jcxz    sin2            ;  if NULL destination
  157.  
  158.     mov    bx,swap_handle[bp]
  159.     cmpx    bx,NULL_HANDLE
  160.     je    sin1            ;  if no handle (internal error)
  161.  
  162.     mov    cx,BLOCK_SIZE        ; position swap pointer
  163.     mul    cx
  164.     call    move_file_pointer
  165.     jc    sin2
  166.  
  167.     call    read_from_file        ; read block from swap file
  168.     jc    sin2
  169.     inc    swap_icount[bp]
  170.     cmp    ax,cx
  171.     je    sin2            ;  if full 16k block read from file
  172.  
  173. sin1:    lea    ax,ertx_swap_read    ; *Swap read*
  174.     call    dialog_error_beta
  175.  
  176. sin2:    ret
  177. swap_in endp
  178.  
  179.  
  180. ;;    swap out
  181. ;
  182. ;    entry    ES:DI    source pointer
  183. ;    exit    AX    swap index (1..MAX) or 0 if error
  184. ;        Cf    if error (full disk or swap file, not DOS 3+)
  185. ;
  186. swap_out proc
  187.     call    save_most
  188.     mov    bx,swap_handle[bp]
  189.     cmpx    bx,NULL_HANDLE
  190.     je    out2            ; if no swap file
  191.     
  192. out1:    call    get_swap_index
  193.     jc    out3            ;  if swap file full
  194.     mov    si,ax
  195.     inc    si            ;  (offset swap index by 1)
  196.  
  197.     mov    cx,BLOCK_SIZE        ; position swap file pointer
  198.     mul    cx
  199.     call    move_file_pointer
  200.     jc    out3            ;  if unlikely dos error
  201.  
  202.     call    write_swap_file        ; write block to swap file
  203.     jc    out3            ;  if disk full
  204.     inc    swap_ocount[bp]
  205.  
  206.     mov    ax,si
  207.     ret
  208.  
  209. out2:    call    create_swap_file
  210.     jnc    out1
  211.  
  212. out3:    mov    ax,si            ; clear swap bit
  213.     movx    di,NULL_POINTER
  214.     mov    es,di
  215.     call    swap_in
  216.  
  217.     movx    ax,NULL_SWAP
  218.     stc
  219.     ret
  220. swap_out endp
  221.  
  222.  
  223. ;;    write swap file
  224. ;
  225. ;    entry    BX    file handle
  226. ;        CX    byte count
  227. ;        ES:DI    source
  228. ;    exit    Cf    if error
  229. ;    uses    AX
  230. ;
  231. write_swap_file proc
  232.     mov    ah,40h
  233.     pushm    ds,es
  234.     pop    ds
  235.     xchg    dx,di
  236.     call    ms_dos_dialog
  237.     xchg    dx,di
  238.     pop    ds
  239.     jc    wsf1            ; if error
  240.     cmp    ax,cx
  241.     je    wsf1            ; if successful (Cf==0)
  242.     jmp    err_disk_full        ; else disk full
  243. wsf1:    ret
  244. write_swap_file endp
  245.  
  246.     end
  247.