DataMuseum.dk

Presents historical artifacts from the history of:

DANOSI

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DANOSI

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦06384e132⟧ TextFile

    Length: 40111 (0x9caf)
    Types: TextFile
    Names: »VMMUNIT.PAS«

Derivation

└─⟦02956c927⟧ Bits:30010510 DVBS1.SW2114.src.2.14-1 SW2114 REAL #1/4 TIME PASCAL SOURCE REL 2.14
    └─⟦this⟧ »RTP\VMMUNIT.PAS« 
└─⟦4f587ad96⟧ Bits:30010518 DVBS1.SW2114.src.2.7-1 SW2114 1/4 Real Time Pascal 2.7 92.06.16
    └─⟦this⟧ »RTP\VMMUNIT.PAS« 
└─⟦a2a9e188c⟧ Bits:30010526 DVBS1.SW2114.src.2.6-4 RTP Compiler Source SW2104+SW2114 Disk 1 92.02.03 HEJ HHA
    └─⟦this⟧ »RTP\VMMUNIT.PAS« 
└─⟦b607d6035⟧ Bits:30010532 RTP compiler Source 1 2.14 26/9(?)-92 DVBS1.SW2114.src.2.14-8
    └─⟦this⟧ »VMMUNIT.PAS« 
└─⟦fd2665794⟧ Bits:30010523 DVBS1.SW2114.src.2.6-1 RTP compiler source SW2104+SW2114 Disk#1 30/1-92 HHA
    └─⟦this⟧ »RTP\VMMUNIT.PAS« 

TextFile

(* ---------------    VIRTUAL MEMORY MANAGER    --------------- *)\r
{$F+,O+}\r
unit vmmunit;\r
\r
\r
interface\r
uses pscplm, mpaunit, vmmdump;\r
\r
FUNCTION vmmallocate(seg_size: word; VAR exc: word): POINTER;\r
FUNCTION vmmcreatetable(VAR user_tbl_ptr: ptr_tbl_dscr_type;\r
                        VAR vmm_tbl_name: string;\r
                        max_residents, page_size: word): WORD;\r
FUNCTION vmmdeletetable(VAR user_tbl_ptr: ptr_tbl_dscr_type): WORD;\r
FUNCTION vmmgetspecial(VAR user_tbl_ptr: ptr_tbl_dscr_type;\r
                       VAR vmm_tbl_name: string;\r
                       max_residents: WORD;\r
                       VAR str: string;\r
                       VAR conn: file): WORD;\r
FUNCTION vmmgettable(VAR user_tbl_ptr: ptr_tbl_dscr_type;\r
                     VAR vmm_tbl_name: string;\r
                     max_residents: WORD;\r
                     VAR str: string;\r
                     VAR special: st_address): WORD;\r
FUNCTION vmmsavespecial(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                          VAR str: string;\r
                          VAR conn: FILE): WORD;\r
FUNCTION vmmsavetable(VAR user_tbl: tbl_dscr_type;\r
                      VAR str: string;\r
                      special_va_high, special_va_low: WORD): WORD;\r
FUNCTION vmmretrieve(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                      va_high_offset, va_low_offset: WORD;\r
                      page_lock, page_update: BOOLEAN;\r
                      VAR rec_ptr): WORD;\r
FUNCTION vmmextend(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                   VAR va: st_address;  (* - address of virtual address of searched record. *)\r
                   record_size: WORD;  (* - size of requested record. *)\r
                   lock_page: BOOLEAN;    (* - true: permanent lock. false: no permanent lock. *)\r
                   VAR rec_ptr (* - address of pointer to new record. *)\r
                  ): WORD;\r
FUNCTION vmmextendcopy(VAR vmm_tbl_dscr: tbl_dscr_type; (* - address of table descriptor. *)\r
                       VAR va: st_address; (* - address of virtual address of searched record. *)\r
                       record_size: WORD; (* - size of requested record. *)\r
                       lock_page: BOOLEAN; (* - true: permanent lock. false: no permanent lock. *)\r
                       VAR rec_ptr; (* - address of pointer to new record. *)\r
                       va_to_copy_high, va_to_copy_low: WORD):WORD;\r
FUNCTION vmmlock(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                     vmm_page_dscr_ptrr: pointer): WORD;\r
FUNCTION vmmunlock(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                       vmm_page_dscr_ptrr: pointer): WORD;\r
FUNCTION vmmupdate(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                       vmm_page_dscr_ptrr: pointer): WORD;\r
\r
implementation\r
const\r
  e_ok = 0;\r
  e_fexist = 32;\r
  e_fnexist = 33;\r
  e_vmm_tbl_exist = 8208;\r
  e_vmm_tbl_nexist = 8209;\r
  e_vmm_fexist = 8210;\r
  e_vmm_va_nexist = 8211;\r
  e_vmm_size = 8212;\r
  e_vmm_overflow = 8213;\r
  e_vmm_underflow = 8214;\r
  e_vmm_nresident = 8215;\r
  e_vmm_memory = 8216;\r
  e_vmm_va_overflow = 8217;\r
  e_vmm_version = 8218;\r
\r
\r
CONST\r
  write_access = 2;\r
  read_access = 1;\r
  read_write_access = 3;\r
  seek_rel_backw = 1;\r
  seek_abs_loc = 2;\r
  seek_rel_forw = 3;\r
  seek_eof_rel_backw = 4;\r
VAR\r
  min_va_low: WORD;\r
  min_va_high: WORD;\r
  \r
     \r
\r
(* ---------------       UNSIGNED ARIT          -------------- *)\r
FUNCTION u_add_dw_w(VAR dw: st_address; w: word ):BOOLEAN;\r
BEGIN\r
  dw.va_low:= dw.va_low + w;\r
  IF dw.va_low<w THEN BEGIN\r
    dw.va_high:= dw.va_high + 1;\r
    u_add_dw_w:= dw.va_high<>0;\r
  END ELSE\r
    u_add_dw_w:= true;\r
END;\r
\r
\r
\r
\r
(* ---------------         VMMALLOCATE        --------------- *)\r
FUNCTION vmmallocate(seg_size: word; VAR exc: word): POINTER;\r
VAR\r
  addr:  POINTER;\r
BEGIN\r
  seg_size := seg_size + 16;\r
\r
  getmem(addr, seg_size);\r
  addr := ptr(seg(addr^) + 1,0);\r
  exc:= 0;\r
  vmmallocate:= addr;\r
END;\r
\r
 \r
(* ---------------        VMMDEALLOCATE       --------------- *)\r
PROCEDURE vmmdeallocate(VAR seg_ptr: ptr_page_dscr_type; VAR exc: word);\r
BEGIN\r
  exc:= 0;\r
  (* dqfree( seg( seg_ptr ), exc ); !!! TURBO !!! *)\r
  IF ( exc = e_ok ) THEN seg_ptr:= nil;\r
END;\r
\r
(* ---------------     VMMLOCATECANDIDATE    --------------- *)\r
\r
FUNCTION vmmlocatecandidate(VAR vmm_tbl_dscr: tbl_dscr_type; VAR rec_ptr: ptr_page_dscr_type): word;\r
VAR\r
  vmm_page_dscr_ptr: ptr_page_dscr_type;\r
 (* vmm_page_dscr: page_dscr_type; hha *)\r
  page_offset: WORD;\r
  step: WORD;\r
  best_is_refered: WORD;\r
  exc_code: WORD;\r
  dummy_exc: WORD;\r
  state: BYTE;\r
BEGIN\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0E20) = $0A20 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Locate Cand.');\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
\r
  exc_code:= e_ok;\r
  state:= 0;\r
  WHILE ( exc_code = e_ok ) AND ( state < 3 ) DO\r
  BEGIN\r
    state:= state + 1;\r
    CASE state OF\r
     0: ;\r
     1:  BEGIN\r
          (* start address: *)\r
          vmm_page_dscr_ptr:= vmm_tbl_dscr.page_chain_head;\r
          rec_ptr:= nil;\r
          (* locate resident page to receive off core resident *)\r
          best_is_refered:=max_word;\r
          FOR step:=2 TO vmm_tbl_dscr.no_of_page DO\r
          BEGIN\r
(*#BEGINTEST\r
            IF testvmm>0 THEN\r
              IF (WORD(testvmm) AND $0F20) = $0820 THEN\r
              BEGIN\r
                vmmdumproutine('VMM  -1-  Locate Cand.');\r
                vmmdumpva(vmm_page_dscr_ptr^.va.va_high,vmm_page_dscr_ptr^.va.va_low);\r
                vmmdumplocks(vmm_page_dscr_ptr^.perm_locks);\r
                vmmdumpptr(vmm_page_dscr_ptr^);\r
                vmmdumpnewline;\r
              END;\r
(*ENDTEST#*)\r
             vmm_page_dscr_ptr:=vmm_page_dscr_ptr^.succ_ptr;\r
             IF (best_is_refered>vmm_page_dscr_ptr^.is_refered) AND\r
                (vmm_page_dscr_ptr^.perm_locks=0) THEN\r
             BEGIN\r
               best_is_refered:=vmm_page_dscr_ptr^.is_refered;\r
               rec_ptr:=vmm_page_dscr_ptr;\r
             END;\r
           END;\r
\r
           vmm_page_dscr_ptr:= rec_ptr;\r
           IF ( rec_ptr = nil ) THEN exc_code:= e_vmm_memory;\r
\r
         END;\r
      2: BEGIN\r
           IF vmm_page_dscr_ptr^.updated THEN\r
           BEGIN\r
           if vmm_page_dscr_ptr^.va.va_high <> 0 then\r
           state := 2;\r
             seek( vmm_tbl_dscr.file_conn, longint(vmm_page_dscr_ptr^.va) );\r
           END ELSE state:= 3;  (* ! *)\r
         END;\r
      3: BEGIN\r
(*#BEGINTEST\r
           vmm_tbl_dscr.stcs.disk_writes:= vmm_tbl_dscr.stcs.disk_writes+1;\r
(*ENDTEST#*)\r
           blockwrite( vmm_tbl_dscr.file_conn, vmm_page_dscr_ptr^.data_area,\r
                    vmm_tbl_dscr.page_size );\r
         END;\r
    END; (* CASE state OF 0..3 *)\r
  END;  (* WHILE exc_code = e_ok *)\r
\r
(*#BEGINTEST\r
  IF (testvmm>=0) AND (exc_code<>e_ok) THEN\r
  BEGIN\r
    vmmdumproutine('VMM  ERR  Locate Cand.');\r
    vmmdumpline;\r
    vmmdumperror(state,exc_code);\r
    vmmdumpnewline;\r
  END;\r
(*ENDTEST#*)\r
\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0D20) = $0920 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  <--  Locate Cand.');\r
      vmmdumpskip;\r
      vmmdumpskip;\r
      vmmdumpptr(rec_ptr^);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
\r
  vmmlocatecandidate:=exc_code;\r
END; (*vmmlocatecandidate*)\r
\r
\r
(* ------------      VMMLOCATERESIDENT    ------------- *)\r
\r
FUNCTION vmmlocateresident(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                           va_low_offset, va_high_offset: word;\r
                           VAR vmm_page_dscr_ptr: ptr_page_dscr_type): boolean;\r
VAR\r
  temp_page_dscr_ptr: ptr_page_dscr_type;\r
  chain_no: WORD;\r
  help: boolean;\r
BEGIN\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0E10) = $0A10 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Locate Resident');\r
      vmmdumpva(va_high_offset,va_low_offset);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
\r
  va_low_offset:= va_low_offset AND vmm_tbl_dscr.low_page_mask;\r
  chain_no:= (va_low_offset SHR vmm_tbl_dscr.bits_to_page_offset) AND 15;\r
  temp_page_dscr_ptr:= vmm_tbl_dscr.page_ptrs[chain_no];\r
  chain_no:= vmm_tbl_dscr.no_in_page_chains[chain_no] + 1;\r
  WHILE chain_no>1 DO\r
  BEGIN\r
    IF (temp_page_dscr_ptr^.va.va_low=va_low_offset) AND\r
       (temp_page_dscr_ptr^.va.va_high=va_high_offset)\r
    THEN chain_no:= 0\r
    ELSE BEGIN\r
      chain_no:= chain_no-1;\r
      temp_page_dscr_ptr:= temp_page_dscr_ptr^.pred_ptr;\r
    END;\r
  END;\r
  IF chain_no=0 THEN\r
  BEGIN\r
    vmm_page_dscr_ptr:= temp_page_dscr_ptr;\r
    help:= true;\r
  END ELSE\r
  BEGIN\r
    vmm_page_dscr_ptr:=nil;\r
    help:= false;\r
  END;\r
\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0D10) = $0910 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  <--  Locate Resident');\r
      vmmdumpword('  LOW = ',OFS(vmm_page_dscr_ptr^));\r
      vmmdumpword(' HIGH = ',SEG(vmm_page_dscr_ptr^));\r
      vmmdumpptr(vmm_page_dscr_ptr^);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
  vmmlocateresident:= help;\r
END; (* vmmlocateresident *)\r
\r
\r
(* ---------------        VMMCHAINPAGE       --------------- *)\r
PROCEDURE vmmchainpage(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                       va_low_offset, va_high_offset: word;\r
                       VAR vmm_page_dscr: page_dscr_type);\r
VAR\r
  chain_no: WORD;\r
  vmm_succ_page_dscr_ptr: ptr_page_dscr_type;\r
  vmm_pred_page_dscr_ptr: ptr_page_dscr_type;\r
BEGIN\r
  chain_no:= (va_low_offset SHR vmm_tbl_dscr.bits_to_page_offset) AND 15;\r
  IF vmm_tbl_dscr.no_in_page_chains[chain_no] = 0 THEN\r
  BEGIN\r
    vmm_succ_page_dscr_ptr:= vmm_tbl_dscr.page_chain_head;\r
    vmm_pred_page_dscr_ptr:= vmm_succ_page_dscr_ptr^.pred_ptr;\r
  END ELSE\r
  BEGIN\r
    vmm_pred_page_dscr_ptr:= vmm_tbl_dscr.page_ptrs[chain_no];\r
    vmm_succ_page_dscr_ptr:= vmm_pred_page_dscr_ptr^.succ_ptr;\r
  END;\r
  vmm_tbl_dscr.page_ptrs[chain_no]:= @vmm_page_dscr;\r
  vmm_succ_page_dscr_ptr^.pred_ptr:= @vmm_page_dscr;\r
  vmm_pred_page_dscr_ptr^.succ_ptr:= @vmm_page_dscr;\r
  vmm_tbl_dscr.no_in_page_chains[chain_no]:= vmm_tbl_dscr.no_in_page_chains[chain_no] + 1;\r
  vmm_page_dscr.va.va_low:= va_low_offset;\r
  vmm_page_dscr.va.va_high:= va_high_offset;\r
  vmm_page_dscr.succ_ptr:= vmm_succ_page_dscr_ptr;\r
  vmm_page_dscr.pred_ptr:= vmm_pred_page_dscr_ptr;\r
  vmm_page_dscr.perm_locks:= 0;\r
  vmm_page_dscr.updated:= false;\r
END; (* vmmchainpage *)\r
\r
\r
(* ---------------       VMMUNCHAINPAGE      --------------- *)\r
PROCEDURE vmmunchainpage(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                         VAR vmm_page_dscr: page_dscr_type);\r
VAR\r
  chain_no: WORD;\r
  neighb_page_ptr: ptr_page_dscr_type;\r
  (* neighb_page_dscr = neighb_page_ptr^ *)\r
BEGIN\r
  chain_no:= (vmm_page_dscr.va.va_low SHR vmm_tbl_dscr.bits_to_page_offset) AND 15;\r
  IF @vmm_page_dscr = vmm_tbl_dscr.page_ptrs[chain_no]\r
  THEN vmm_tbl_dscr.page_ptrs[chain_no]:= vmm_page_dscr.pred_ptr;\r
  vmm_tbl_dscr.no_in_page_chains[chain_no]:=\r
    vmm_tbl_dscr.no_in_page_chains[chain_no] - 1;\r
  neighb_page_ptr:= vmm_page_dscr.pred_ptr;\r
  neighb_page_ptr^.succ_ptr:= vmm_page_dscr.succ_ptr;\r
  neighb_page_ptr:= vmm_page_dscr.succ_ptr;\r
  neighb_page_ptr^.pred_ptr:= vmm_page_dscr.pred_ptr;\r
END; (* vmmunchainpage *)\r
\r
\r
(* ---------------       VMMCREATETABLE      --------------- *)\r
FUNCTION vmmcreatetable(VAR user_tbl_ptr: ptr_tbl_dscr_type;\r
                        VAR vmm_tbl_name: string;\r
                        max_residents, page_size: word): WORD;\r
VAR\r
  vmm_tbl_dscr_ptr: ptr_tbl_dscr_type;\r
  page_dscr_ptr: ptr_page_dscr_type;\r
  stcs_ptr: ptr_page_dscr_type;\r
  temp_vmm_tbl_dscr: tbl_dscr_type;\r
  rec_ptr: ptr_page_dscr_type;\r
  virtual_addr: st_address;\r
  state: BYTE;\r
  step: WORD;\r
  exc_code: WORD;\r
  help_str_ptr: ptr_string;\r
BEGIN\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0E00) = $0A00 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Create');\r
      vmmdumpskip;\r
      vmmdumpsize(page_size);\r
      vmmdumpsize(max_residents);\r
      vmmdumpstring(vmm_tbl_name);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
\r
  vmm_tbl_dscr_ptr:= @temp_vmm_tbl_dscr;\r
  state:= 0;\r
  exc_code:= e_ok;\r
  page_dscr_ptr:= nil;\r
  rec_ptr:= nil;\r
(* !!! TURBO !!!  vmm_tbl_dscr_ptr^.file_conn:= max_word; *)\r
  vmm_tbl_dscr_ptr^.page_chain_head:= nil;\r
  vmm_tbl_dscr_ptr^.stcs.access_low:= 0;\r
  vmm_tbl_dscr_ptr^.stcs.access_high:= 0;\r
  vmm_tbl_dscr_ptr^.stcs.disk_reads:= 0;\r
  vmm_tbl_dscr_ptr^.stcs.disk_writes:= 0;\r
  vmm_tbl_dscr_ptr^.va_eoi.va_low:= min_va_low;\r
  vmm_tbl_dscr_ptr^.va_eoi.va_high:= min_va_high;\r
  vmm_tbl_dscr_ptr^.no_of_residents:= 0;\r
  vmm_tbl_dscr_ptr^.max_residents:= 1; (* max user for table descriptor *)\r
  vmm_tbl_dscr_ptr^.no_of_page:= 0;\r
  (* - Round 'page_size' to nearest higher power of two. *)\r
  (* - and page_size can contain table descriptor        *)\r
  vmm_tbl_dscr_ptr^.bits_to_page_offset:=0;\r
  IF page_size<SIZEOF(tbl_dscr_type) THEN page_size:=SIZEOF(tbl_dscr_type);\r
  vmm_tbl_dscr_ptr^.page_size:= page_size;\r
  vmm_tbl_dscr_ptr^.low_page_mask:= max_word;\r
  WHILE ( 1 < page_size ) DO\r
  BEGIN\r
    vmm_tbl_dscr_ptr^.low_page_mask:= vmm_tbl_dscr_ptr^.low_page_mask SHL 1;\r
    page_size:= page_size SHR 1;\r
    vmm_tbl_dscr_ptr^.bits_to_page_offset:=vmm_tbl_dscr_ptr^.bits_to_page_offset+1;\r
  END;\r
  page_size:= ( NOT vmm_tbl_dscr_ptr^.low_page_mask ) + 1;  (* - nearest lower power of two. *)\r
  IF ( vmm_tbl_dscr_ptr^.page_size <> page_size ) THEN\r
  BEGIN\r
    vmm_tbl_dscr_ptr^.low_page_mask:= vmm_tbl_dscr_ptr^.low_page_mask SHL 1;\r
    vmm_tbl_dscr_ptr^.bits_to_page_offset:=vmm_tbl_dscr_ptr^.bits_to_page_offset+1;\r
  END;\r
  vmm_tbl_dscr_ptr^.offset_mask:= NOT vmm_tbl_dscr_ptr^.low_page_mask;\r
  vmm_tbl_dscr_ptr^.page_size:= vmm_tbl_dscr_ptr^.offset_mask + 1;\r
  vmm_tbl_dscr_ptr^.page_seg_size:= vmm_tbl_dscr_ptr^.page_size + SIZEOF( page_dscr_type ) - max_page_data_length - 1;\r
  vmm_tbl_dscr_ptr^.no_in_page_chains[0]:= 1;\r
  FOR step:=1 TO 15 DO vmm_tbl_dscr_ptr^.no_in_page_chains[step]:= 0;\r
  WHILE ( exc_code = e_ok ) AND ( state < 10 ) DO\r
  BEGIN\r
    state:= state + 1;\r
\r
(*#BEGINTEST\r
    IF testvmm>0 THEN\r
      IF (WORD(testvmm) AND $0E00) = $0A00 THEN\r
      BEGIN\r
        vmmdumproutine('VMM  ---  Create');\r
        vmmdumpskip;\r
        vmmdumpstring(vmm_tbl_name);\r
        IF state>7 THEN  vmmdumpptr(rec_ptr^);\r
        IF state>9 THEN BEGIN\r
          help_str_ptr:= ptr_string(rec_ptr);\r
          vmmdumpstring(help_str_ptr^);\r
        END;\r
        vmmdumpnewline;\r
      END;\r
(*ENDTEST#*)\r
    CASE state of\r
     0: ;\r
     1: IF ( user_tbl_ptr <> nil ) THEN exc_code:= e_vmm_tbl_exist;\r
     2: (* allocate first page to hold table description. *)\r
        page_dscr_ptr:=\r
          ptr_page_dscr_type(\r
            vmmallocate( vmm_tbl_dscr_ptr^.page_seg_size, exc_code ));\r
     3: BEGIN\r
          page_dscr_ptr^.va.va_low:= min_va_low;\r
          page_dscr_ptr^.va.va_high:= min_va_high;\r
          page_dscr_ptr^.pred_ptr:= page_dscr_ptr;\r
          page_dscr_ptr^.succ_ptr:= page_dscr_ptr;\r
          page_dscr_ptr^.perm_locks:= 0;\r
          page_dscr_ptr^.updated:= false;\r
          vmm_tbl_dscr_ptr^.page_ptrs[0]:= page_dscr_ptr;\r
          vmm_tbl_dscr_ptr:= @page_dscr_ptr^.data_area[0];\r
          user_tbl_ptr:= @page_dscr_ptr^.data_area[0];\r
          MOVE(temp_vmm_tbl_dscr, vmm_tbl_dscr_ptr^, SIZEOF( tbl_dscr_type ) );\r
          vmm_tbl_dscr_ptr^.page_chain_head:= page_dscr_ptr;\r
          vmm_tbl_dscr_ptr^.no_of_residents:= vmm_tbl_dscr_ptr^.no_of_residents + 1;\r
          state:= 4; (* no test of file already exist *)\r
        END;\r
     4: BEGIN\r
          assign(vmm_tbl_dscr_ptr^.file_conn, vmm_tbl_name );\r
          IF ( exc_code = e_fnexist ) THEN exc_code:= e_ok ELSE\r
          IF ( exc_code = e_fexist ) THEN\r
          BEGIN (* - file exists. *)\r
            (*dqdetach( vmm_tbl_dscr_ptr^.file_conn, exc_code ); !!! TURBO !!! *)\r
            exc_code:= e_vmm_fexist;\r
          END;\r
        END;\r
     5:  assign(vmm_tbl_dscr_ptr^.file_conn, vmm_tbl_name );\r
     6:  rewrite( vmm_tbl_dscr_ptr^.file_conn, 1);\r
     7: exc_code:= vmmextend( vmm_tbl_dscr_ptr^, virtual_addr,\r
                              SIZEOF( tbl_dscr_type ), true, rec_ptr );\r
     8: exc_code:= vmmextend( vmm_tbl_dscr_ptr^, vmm_tbl_dscr_ptr^.name_va,\r
                              LENGTH(vmm_tbl_name) + 1, false, rec_ptr );\r
     9: MOVE( vmm_tbl_name, rec_ptr^, LENGTH(vmm_tbl_name) + 1 );\r
     10: BEGIN\r
           vmm_tbl_dscr_ptr^.max_residents:= max_residents+vmm_tbl_dscr_ptr^.no_of_residents;\r
           (* add use of table descriptor *)\r
         END;\r
    END; (* CASE state OF 0..10 *)\r
  END; (* WHILE exc_code = e_ok *)\r
\r
(*#BEGINTEST\r
  IF (testvmm>=0) AND (exc_code<>e_ok) THEN \r
  BEGIN \r
    vmmdumproutine('VMM  ERR  Create');\r
    vmmdumpline;\r
    vmmdumperror(state,exc_code);\r
    vmmdumpnewline;\r
  END;\r
(*ENDTEST#*)\r
\r
\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0D00) = $0900 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  <--  Create');\r
      help_str_ptr:= ptr_string(rec_ptr);\r
      vmmdumpstring(help_str_ptr^);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
\r
  vmmcreatetable:= exc_code;\r
END; (* vmmcreatetable *)\r
\r
\r
(* ---------------       VMMDELETETABLE      --------------- *)\r
FUNCTION vmmdeletetable(VAR user_tbl_ptr: ptr_tbl_dscr_type): WORD;\r
VAR\r
  vmm_tbl_dscr_ptr: ptr_tbl_dscr_type;\r
  (* vmm_tbl_dscr = vmm_tbl_dscr_ptr^ *)\r
  state: BYTE;\r
  exc_code: WORD;\r
  file_name_ptr: ptr_string;\r
  vmm_page_dscr_ptr: ptr_page_dscr_type;\r
  (* vmm_page_dscr = vmm_page_dscr_ptr^ *)\r
\r
BEGIN\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0E00) = $0A00 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Delete');\r
      vmmdumpskip;\r
      vmmdumpskip;\r
      vmmdumpptr(user_tbl_ptr^);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
\r
  vmm_tbl_dscr_ptr:= user_tbl_ptr;\r
  exc_code:= e_ok;\r
  state:= 0;\r
  WHILE ( exc_code = e_ok ) AND ( state < 7 ) DO\r
  BEGIN\r
    state:= state + 1;\r
    CASE state OF\r
     0: ;\r
     1:  IF ( vmm_tbl_dscr_ptr = nil )\r
        THEN exc_code:= e_vmm_tbl_nexist\r
        ELSE exc_code:= vmmretrieve(vmm_tbl_dscr_ptr^,\r
                                    vmm_tbl_dscr_ptr^.name_va.va_high,\r
                                    vmm_tbl_dscr_ptr^.name_va.va_low,\r
                                    false,false,\r
                                    ptr_page_dscr_type(file_name_ptr));\r
     2: BEGIN\r
(*#BEGINTEST\r
          IF testvmm>=0 THEN \r
            vmmdumpstcs(file_name_ptr^,vmm_tbl_dscr_ptr^.stcs);\r
(*ENDTEST#*)\r
          close(vmm_tbl_dscr_ptr^.file_conn);\r
          IF exc_code = e_ok \r
          THEN erase( vmm_tbl_dscr_ptr^.file_conn ); (*file_name_ptr^*)\r
          state:= 6; (* skip deallocate of pages *)\r
        END;\r
     3: BEGIN\r
          vmm_page_dscr_ptr:= vmm_tbl_dscr_ptr^.page_chain_head;\r
          vmm_page_dscr_ptr:= vmm_page_dscr_ptr^.succ_ptr;\r
        END;\r
     4: vmmunchainpage( vmm_tbl_dscr_ptr^, vmm_page_dscr_ptr^ );\r
     5: vmmdeallocate( vmm_page_dscr_ptr, exc_code );\r
     6: BEGIN\r
          vmm_tbl_dscr_ptr^.no_of_residents:= vmm_tbl_dscr_ptr^.no_of_residents - 1;\r
          IF ( 0 < vmm_tbl_dscr_ptr^.no_of_residents )\r
          THEN  (* loop *) state:= 2;\r
        END;\r
     7:  user_tbl_ptr:= nil;\r
    END; (* CASE state OF 0..7 *)\r
  END; (* WHILE exc_code = e_ok *)\r
\r
(*#BEGINTEST\r
  IF (testvmm>=0) AND (exc_code<>e_ok) THEN \r
  BEGIN \r
    vmmdumproutine('VMM  ERR  Delete');\r
    vmmdumpline; \r
    vmmdumperror(state,exc_code);\r
    vmmdumpnewline;\r
  END;\r
(*ENDTEST#*)\r
\r
\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0D00) = $0900 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  <--  Delete');\r
      vmmdumpstring(file_name_ptr^);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
\r
  vmmdeletetable:= exc_code;\r
END; (* vmmdeletetable *)\r
\r
\r
\r
FUNCTION vmmgetspecial(VAR user_tbl_ptr: ptr_tbl_dscr_type;\r
                       VAR vmm_tbl_name: string;\r
                       max_residents: WORD;\r
                       VAR str: string;\r
                       VAR conn: FILE): WORD;\r
VAR\r
  p_size: WORD;\r
  p_no: WORD;\r
  step: WORD;\r
  read_bytes: WORD;\r
  vmm_tbl_dscr_ptr: ptr_tbl_dscr_type;\r
  (* vmm_tbl_dscr = vmm_tbl_dscr_ptr^ *)\r
  page_dscr_ptr: ptr_page_dscr_type;\r
  (* page_dscr = page_dscr_ptr *)\r
  va: st_address;\r
  rec_ptr: ptr_page_dscr_type;\r
  exc: WORD;\r
\r
BEGIN\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0E00) = $0A00 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Get');\r
      vmmdumpsize(max_residents);\r
      vmmdumpstring(str);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
  exc:= 0;\r
  assign(conn,str);\r
  IF exc=0 THEN reset(conn, 1);\r
  IF exc=0 THEN blockread(conn,p_size,2,read_bytes);\r
  IF (exc=0) AND (read_bytes<>2) THEN exc:= e_vmm_tbl_nexist;\r
  IF (exc=0) AND (p_size<SIZEOF(tbl_dscr_type)) THEN exc:= e_vmm_tbl_nexist;\r
  IF exc=0 THEN page_dscr_ptr:=\r
    ptr_page_dscr_type(vmmallocate(p_size+SIZEOF(page_dscr_type) - max_page_data_length -1,exc));\r
  IF exc=0 THEN\r
  BEGIN\r
    page_dscr_ptr^.va.va_low:= min_va_low;\r
    page_dscr_ptr^.va.va_high:= min_va_high;\r
    page_dscr_ptr^.pred_ptr:= page_dscr_ptr;\r
    page_dscr_ptr^.succ_ptr:= page_dscr_ptr;\r
    page_dscr_ptr^.perm_locks:= 1;\r
    page_dscr_ptr^.updated:= false;\r
    vmm_tbl_dscr_ptr:= @page_dscr_ptr^.data_area[0];\r
    vmm_tbl_dscr_ptr^.page_size:= p_size;\r
    blockread(conn,page_dscr_ptr^.data_area[2],p_size-2,read_bytes);\r
    IF (exc=0) AND (read_bytes<>p_size-2) THEN exc:= e_vmm_tbl_nexist;\r
    p_no:= vmm_tbl_dscr_ptr^.no_of_page;\r
    vmm_tbl_dscr_ptr^.page_chain_head:= page_dscr_ptr;\r
    vmm_tbl_dscr_ptr^.no_of_page:= 1;\r
    vmm_tbl_dscr_ptr^.last_used_ptr:= page_dscr_ptr;\r
    vmm_tbl_dscr_ptr^.no_of_residents:= 1;\r
    vmm_tbl_dscr_ptr^.max_residents:= max_residents + 1 ;\r
    vmm_tbl_dscr_ptr^.stcs.access_low:= 1;\r
    vmm_tbl_dscr_ptr^.stcs.access_high:= 0;\r
    vmm_tbl_dscr_ptr^.stcs.disk_reads:= 0;\r
    vmm_tbl_dscr_ptr^.stcs.disk_writes:= 0;\r
    vmm_tbl_dscr_ptr^.va_eoi.va_low:= min_va_low;\r
    vmm_tbl_dscr_ptr^.va_eoi.va_high:= min_va_high;\r
    IF u_add_dw_w(vmm_tbl_dscr_ptr^.va_eoi,p_size) THEN\r
    ELSE exc:= e_vmm_va_overflow;\r
    vmm_tbl_dscr_ptr^.page_ptrs[0]:= page_dscr_ptr;\r
    vmm_tbl_dscr_ptr^.no_in_page_chains[0]:= 1;\r
    FOR step:= 1 TO 15 DO vmm_tbl_dscr_ptr^.no_in_page_chains[step]:= 0;\r
  END;\r
  IF exc=0 THEN assign(vmm_tbl_dscr_ptr^.file_conn, vmm_tbl_name);\r
  IF exc=0 THEN rewrite(vmm_tbl_dscr_ptr^.file_conn,1);\r
  FOR step:= 2 TO p_no DO\r
  BEGIN\r
     IF exc=0 THEN exc:= vmmextend(vmm_tbl_dscr_ptr^,va,p_size,false,rec_ptr);\r
    IF exc=0 THEN\r
     blockread(conn,rec_ptr^,p_size,read_bytes);\r
    IF (exc=0) AND (read_bytes<>p_size) THEN exc:= e_vmm_tbl_nexist;\r
  END;\r
  IF exc=0 THEN exc:= vmmextend(vmm_tbl_dscr_ptr^,vmm_tbl_dscr_ptr^.name_va,\r
                                 LENGTH(vmm_tbl_name) + 1,false,rec_ptr);\r
  IF exc=0 THEN MOVE(vmm_tbl_name, rec_ptr^ , LENGTH(vmm_tbl_name)+1);\r
  IF exc=0 THEN \r
  BEGIN\r
    user_tbl_ptr:= vmm_tbl_dscr_ptr;\r
    IF (checktimelow=0) AND (checktimehigh=0) THEN\r
    BEGIN\r
      checktimelow:= vmm_tbl_dscr_ptr^.low_check_time;\r
      checktimehigh:= vmm_tbl_dscr_ptr^.high_check_time;\r
    END ELSE\r
    BEGIN\r
      IF (checktimelow<>vmm_tbl_dscr_ptr^.low_check_time) OR\r
         (checktimehigh<>vmm_tbl_dscr_ptr^.high_check_time)\r
      THEN exc:=e_vmm_version;\r
    END;\r
  END;\r
  vmmgetspecial:= exc;\r
END; (* vmmgetspecial *)\r
\r
FUNCTION vmmgettable(VAR user_tbl_ptr: ptr_tbl_dscr_type;\r
                     VAR vmm_tbl_name: string;\r
                     max_residents: WORD;\r
                     VAR str: string;\r
                     VAR special: st_address): WORD;\r
VAR\r
  tbl_ptr: ptr_tbl_dscr_type;\r
  conn: FILE;\r
  exc: WORD;\r
BEGIN\r
  exc:= vmmgetspecial(user_tbl_ptr, vmm_tbl_name,\r
                       max_residents,str,conn);\r
  IF exc=0 THEN close(conn);\r
  tbl_ptr:= user_tbl_ptr;\r
  special.va_low:= tbl_ptr^.special_va.va_low;\r
  special.va_high:= tbl_ptr^.special_va.va_high;\r
\r
(*#BEGINTEST\r
  IF testvmm>=0 THEN\r
    IF ((WORD(testvmm) AND $0D00) = $0900) OR (exc<>0) THEN \r
    BEGIN\r
      vmmdumproutine('VMM  <--  Get');\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
  vmmgettable:= exc;\r
END; (* vmmgettable *)\r
\r
\r
(* ------------     VMM SAVE ----------- *)\r
\r
FUNCTION vmmsavespecial(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                          VAR str: string;\r
                          VAR conn: FILE): WORD;\r
VAR\r
  i: WORD;\r
  va: st_address;\r
  rec_ptr: ptr_page_dscr_type;\r
  exc: WORD;\r
BEGIN\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0E00) = $0A00 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Save');\r
      vmmdumpptr(vmm_tbl_dscr);\r
      vmmdumpstring(str);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
  exc:= 0;\r
  vmm_tbl_dscr.low_check_time:= starttimelow;\r
  vmm_tbl_dscr.high_check_time:= starttimehigh;\r
  assign(conn,str);\r
  IF exc=0 THEN rewrite(conn,1);\r
  va.va_low:= min_va_low;\r
  va.va_high:= min_va_high;\r
  FOR i:= 1 TO vmm_tbl_dscr.no_of_page DO\r
  BEGIN\r
    IF exc=0 THEN exc:= vmmretrieve(vmm_tbl_dscr,va.va_high,va.va_low,\r
                        false,false,rec_ptr);\r
    IF exc=0 THEN blockwrite(conn,rec_ptr^,vmm_tbl_dscr.page_size);\r
    IF exc=0 THEN\r
    BEGIN\r
      IF u_add_dw_w(va,vmm_tbl_dscr.page_size) THEN\r
      ELSE exc:= e_vmm_va_overflow;\r
    END;\r
  END;\r
  vmmsavespecial:= exc;\r
END; (* vmmsavespecial *)\r
\r
FUNCTION vmmsavetable(VAR user_tbl: tbl_dscr_type;\r
                      VAR str: string;\r
                      special_va_high, special_va_low: WORD): WORD;\r
VAR\r
  conn: FILE;\r
  exc: WORD;\r
BEGIN\r
  user_tbl.special_va.va_low:= special_va_low;\r
  user_tbl.special_va.va_high:= special_va_high;\r
  exc:= vmmsavespecial(user_tbl, str , conn);\r
  IF exc=0 THEN close(conn);\r
\r
(*#BEGINTEST\r
  IF testvmm>=0 THEN\r
    IF ((WORD(testvmm) AND $0D00) = $0900) OR (exc<>0) THEN \r
    BEGIN\r
      vmmdumproutine('VMM  <--  Save');\r
      vmmdumpnewline;  \r
    END;\r
(*ENDTEST#*)\r
  vmmsavetable:= exc;\r
END; (* vmmsavetable *)\r
\r
      \r
\r
FUNCTION vmmretrieve(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                      va_high_offset, va_low_offset: WORD;\r
                      page_lock, page_update: BOOLEAN;\r
                      VAR rec_ptr): WORD;\r
VAR\r
  read_bytes: WORD;\r
  vmm_page_dscr_ptr: ptr_page_dscr_type;\r
  help_rec_ptr: ptr_page_dscr_type;\r
  (* vmm_page_dscr = vmm_page_dscr_ptr^ *)\r
  page_offset: WORD;\r
  step: WORD;\r
  cand_ptr: ptr_page_dscr_type;\r
  exc_code: WORD;\r
  dummy_exc: WORD;\r
  state: BYTE;\r
  help_va: st_address;\r
BEGIN\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0E02) = $0A02 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Retrieve');\r
      vmmdumpva(va_high_offset,va_low_offset);\r
      vmmdumpline;\r
      IF page_lock THEN    vmmdumpstring('lock  ');\r
      IF page_update THEN    vmmdumpstring('update');\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
  exc_code:= e_ok;\r
  state:= 0;\r
  IF vmm_tbl_dscr.stcs.access_low = max_word THEN\r
  BEGIN\r
(*#BEGINTEST\r
    vmm_tbl_dscr.stcs.access_high:= vmm_tbl_dscr.stcs.access_high + 1;\r
(*ENDTEST#*)\r
    vmm_tbl_dscr.stcs.access_low:= 0;\r
    (* for all resident pages: is_refered = 0 *)\r
    vmm_page_dscr_ptr:= vmm_tbl_dscr.page_chain_head;\r
    FOR step:= 1 TO vmm_tbl_dscr.no_of_page DO\r
    BEGIN\r
      vmm_page_dscr_ptr^.is_refered:= 0;\r
      vmm_page_dscr_ptr:= vmm_page_dscr_ptr^.succ_ptr;\r
    END;\r
  END ELSE vmm_tbl_dscr.stcs.access_low:= vmm_tbl_dscr.stcs.access_low + 1;\r
  WHILE ( exc_code = e_ok ) AND ( state < 8 ) DO\r
  BEGIN\r
    state:= state + 1;\r
    CASE state OF\r
     0: ;\r
     1: BEGIN\r
          page_offset:= va_low_offset AND vmm_tbl_dscr.offset_mask;\r
          va_low_offset:= va_low_offset XOR page_offset;\r
          IF vmmlocateresident( vmm_tbl_dscr, va_low_offset,\r
                                  va_high_offset, help_rec_ptr )\r
          THEN  state:= 7;\r
          vmm_page_dscr_ptr:= help_rec_ptr;\r
        END;\r
     2: IF (va_high_offset>=vmm_tbl_dscr.va_eoi.va_high) AND\r
           ((va_low_offset>vmm_tbl_dscr.va_eoi.va_low) OR\r
           (va_high_offset>vmm_tbl_dscr.va_eoi.va_high))\r
        THEN exc_code:= e_vmm_va_nexist;\r
     3:  exc_code:= vmmlocatecandidate( vmm_tbl_dscr, help_rec_ptr );\r
     4: vmmunchainpage( vmm_tbl_dscr, help_rec_ptr^ );\r
     5: vmmchainpage(vmm_tbl_dscr,va_low_offset,va_high_offset,help_rec_ptr^);\r
     6:BEGIN\r
           help_va.va_low:= va_low_offset;\r
           help_va.va_high:= va_high_offset;\r
           seek(vmm_tbl_dscr.file_conn, longint(help_va)); (* !!! TURBO !!! *)\r
       end;\r
     7: BEGIN\r
          vmm_page_dscr_ptr:= help_rec_ptr;\r
          vmm_tbl_dscr.last_used_ptr:= help_rec_ptr;\r
(*#BEGINTEST\r
          vmm_tbl_dscr.stcs.disk_reads:= vmm_tbl_dscr.stcs.disk_reads +1;\r
(*ENDTEST#*)\r
          blockread(vmm_tbl_dscr.file_conn, vmm_page_dscr_ptr^.data_area,\r
                               vmm_tbl_dscr.page_size,read_bytes);\r
(*#BEGINTEST\r
            IF testvmm>0 THEN\r
              IF (WORD(testvmm) AND $0F02) = $0802 THEN\r
              BEGIN\r
                vmmdumproutine('VMM  -6-  Retrieve');\r
                vmmdumpline;\r
                vmmdumpsize(read_bytes);\r
                vmmdumpnewline;\r
              END;\r
(*ENDTEST#*)\r
          IF (vmm_tbl_dscr.page_size<>read_bytes) AND (exc_code=e_ok)\r
          THEN exc_code:= e_vmm_va_nexist;\r
        END;\r
     8: BEGIN  (* resident page. *)\r
          help_rec_ptr:= @vmm_page_dscr_ptr^.data_area[page_offset];\r
                    (*         if va_high_offset <> 0 then\r
                            state :=8;*)\r
          vmm_page_dscr_ptr^.is_refered:= vmm_tbl_dscr.stcs.access_low;\r
          IF page_lock THEN\r
          BEGIN\r
            IF vmm_page_dscr_ptr^.perm_locks=255\r
            THEN exc_code:= e_vmm_overflow\r
            ELSE vmm_page_dscr_ptr^.perm_locks:= vmm_page_dscr_ptr^.perm_locks + 1;\r
          END;\r
          (* ? overflow ? *)\r
          IF page_update THEN vmm_page_dscr_ptr^.updated:= true;\r
        END;\r
    END;  (* CASE state OF 0..8 *)\r
  END; (* WHILE exc_code = e_ok *)\r
\r
(*#BEGINTEST\r
  IF (testvmm>=0) AND (exc_code<>e_ok) THEN\r
  BEGIN\r
    vmmdumproutine('VMM  ERR  Retrieve');\r
    vmmdumpva(va_high_offset,va_low_offset OR page_offset);\r
    vmmdumpline;\r
    vmmdumpnewline;\r
    vmmdumproutine(' ');\r
    vmmdumperror(state,exc_code);\r
    vmmdumpnewline;\r
  END;\r
(*ENDTEST#*)\r
\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0D02) = $0902 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  <--  Retrieve');\r
      vmmdumpskip;\r
      vmmdumplocks(vmm_page_dscr_ptr^.perm_locks);\r
      vmmdumpptr(help_rec_ptr^);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
  POINTER(rec_ptr):= help_rec_ptr;\r
  vmmretrieve:= exc_code;\r
END; (* vmmretrieve *)\r
\r
\r
(* ---------------          VMMEXTEND         --------------- *)\r
FUNCTION vmmextend(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                   VAR va: st_address;  (* - address of virtual address of searched record. *)\r
                   record_size: WORD;  (* - size of requested record. *)\r
                   lock_page: BOOLEAN;    (* - true: permanent lock. false: no permanent lock. *)\r
                   VAR rec_ptr (* - address of pointer to new record. *)\r
                  ): WORD;\r
VAR\r
  help_rec_ptr: ptr_page_dscr_type;\r
  page_offset: WORD;\r
  exc_code: WORD;\r
  state: BYTE;\r
BEGIN\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0E01) = $0A01 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Extend');\r
      vmmdumpva(vmm_tbl_dscr.va_eoi.va_high,vmm_tbl_dscr.va_eoi.va_low);\r
      vmmdumpsize(record_size);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
\r
  exc_code:= e_ok;\r
  state:= 0;\r
  page_offset:= vmm_tbl_dscr.va_eoi.va_low AND vmm_tbl_dscr.offset_mask;\r
  WHILE ( exc_code = e_ok ) AND ( state < 6 ) DO\r
  BEGIN\r
    state:= state + 1;\r
    CASE state OF\r
     0: ;\r
     1: IF ( vmm_tbl_dscr.page_size < record_size ) THEN exc_code:= e_vmm_size\r
        ELSE BEGIN\r
          IF ( vmm_tbl_dscr.page_size - page_offset ) < record_size THEN\r
          BEGIN  (* - page boundary. Adjust EOI. *)\r
            vmm_tbl_dscr.va_eoi.va_low:= vmm_tbl_dscr.va_eoi.va_low AND vmm_tbl_dscr.low_page_mask;\r
            IF u_add_dw_w( vmm_tbl_dscr.va_eoi, vmm_tbl_dscr.page_size )\r
            THEN\r
              BEGIN\r
                vmm_tbl_dscr.no_of_page:= vmm_tbl_dscr.no_of_page + 1;\r
                 (* - address space for a new page. *)\r
              END\r
            ELSE exc_code:= e_vmm_va_overflow;\r
          END ELSE (* - ELSE room in existing page. *)\r
                IF page_offset=0 THEN vmm_tbl_dscr.no_of_page:= vmm_tbl_dscr.no_of_page+1;\r
        END;\r
     2: IF vmmlocateresident( vmm_tbl_dscr, vmm_tbl_dscr.va_eoi.va_low,\r
                                vmm_tbl_dscr.va_eoi.va_high, help_rec_ptr )\r
        THEN state:= 4\r
        ELSE BEGIN\r
          IF ( vmm_tbl_dscr.no_of_residents = vmm_tbl_dscr.max_residents )\r
          THEN exc_code:= vmmlocatecandidate(vmm_tbl_dscr, help_rec_ptr)\r
          ELSE BEGIN\r
            help_rec_ptr:=\r
              ptr_page_dscr_type(vmmallocate(vmm_tbl_dscr.page_seg_size,exc_code));\r
            IF ( exc_code = e_ok )\r
            THEN vmm_tbl_dscr.no_of_residents:= vmm_tbl_dscr.no_of_residents + 1;\r
            state:= 3;\r
          END;\r
        END;\r
     3: vmmunchainpage(vmm_tbl_dscr, help_rec_ptr^);\r
     4: (* 'rec_ptr.stored_rec_ptr' is adressing an idle page . *)\r
        (* Chain before page with table descriptor (VA 0, 0)   *)\r
        vmmchainpage(vmm_tbl_dscr, vmm_tbl_dscr.va_eoi.va_low,\r
                       vmm_tbl_dscr.va_eoi.va_high,help_rec_ptr^);\r
     5: exc_code:= vmmretrieve(vmm_tbl_dscr,vmm_tbl_dscr.va_eoi.va_high,\r
                                vmm_tbl_dscr.va_eoi.va_low,lock_page,\r
                                true (* implicit update *),help_rec_ptr);\r
     6: BEGIN\r
          va := vmm_tbl_dscr.va_eoi;\r
          IF u_add_dw_w(vmm_tbl_dscr.va_eoi, record_size ) THEN;\r
             (* - has been checked: new EOI. *)\r
        END;\r
    END; (* CASE state OF 0..6 *)\r
  END; (* WHILE exc_code = e_ok *)\r
\r
(*#BEGINTEST\r
  IF (testvmm>=0) AND (exc_code<>e_ok) THEN\r
  BEGIN  \r
    vmmdumproutine('VMM  ERR  Extend');\r
    vmmdumpline;\r
    vmmdumperror(state,exc_code);\r
    vmmdumpnewline;\r
  END;\r
(*ENDTEST#*)\r
\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0D01) = $0901 THEN \r
    BEGIN\r
      vmmdumproutine('VMM  <--  Extend');\r
      vmmdumpva(va.va_high,va.va_low);\r
      vmmdumpskip;\r
      vmmdumpptr(help_rec_ptr^);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
\r
  POINTER(rec_ptr):= help_rec_ptr;\r
  vmmextend:= exc_code;\r
END; (* vmmextend *)\r
\r
(* ---------------          VMMEXTENDCOPY         --------------- *)\r
FUNCTION vmmextendcopy(VAR vmm_tbl_dscr: tbl_dscr_type; (* - address of table descriptor. *)\r
                       VAR va: st_address; (* - address of virtual address of searched record. *)\r
                       record_size: WORD; (* - size of requested record. *)\r
                       lock_page: BOOLEAN; (* - true: permanent lock. false: no permanent lock. *)\r
                       VAR rec_ptr; (* - address of pointer to new record. *)\r
                       va_to_copy_high, va_to_copy_low: WORD):WORD;\r
VAR\r
  help_rec_ptr: ptr_page_dscr_type;\r
  copy_ptr: ptr_page_dscr_type;\r
  exc: WORD;\r
BEGIN\r
  exc:= vmmextend(vmm_tbl_dscr,va,record_size,true,help_rec_ptr);\r
  IF exc=0 THEN\r
  BEGIN\r
    exc:= vmmretrieve(vmm_tbl_dscr,va_to_copy_high,va_to_copy_low,\r
                       false,false,copy_ptr);\r
    IF exc=0 THEN\r
    BEGIN\r
      MOVE(copy_ptr^ ,help_rec_ptr^ ,record_size);\r
      IF NOT lock_page THEN exc:= vmmunlock(vmm_tbl_dscr,help_rec_ptr);\r
    END;\r
  END;\r
  POINTER(rec_ptr):= help_rec_ptr;\r
  vmmextendcopy:= exc;\r
END; (* vmmextendcopy *)\r
\r
\r
(* ---------------           VMMLOCK          --------------- *)\r
FUNCTION vmmlock(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                     vmm_page_dscr_ptrr: pointer): WORD;\r
VAR\r
  vmm_page_dscr_ptr: ptr_page_dscr_type;\r
  exc_code: WORD;\r
BEGIN\r
  vmm_page_dscr_ptr:=vmm_page_dscr_ptrr;\r
  (*#BEGINTEST\r
  IF testvmm>0 THEN;\r
    IF (WORD(testvmm) AND $0E04) = $0A04 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Lock');\r
      vmmdumpptr(vmm_page_dscr_ptr^);\r
      vmmdumpline;\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
  exc_code:= e_ok;\r
  vmm_page_dscr_ptr:= PTR(SEG(vmm_page_dscr_ptr^),0);\r
  IF ( vmm_page_dscr_ptr^.perm_locks < 255 )\r
  THEN vmm_page_dscr_ptr^.perm_locks:= vmm_page_dscr_ptr^.perm_locks + 1\r
  ELSE  (* - logic error: lock overflow - *) exc_code:= e_vmm_overflow;\r
\r
(*#BEGINTEST\r
  IF (testvmm>=0) AND (exc_code<>e_ok) THEN\r
  BEGIN\r
    vmmdumproutine('VMM  ERR  Lock');\r
    vmmdumpptr(vmm_page_dscr_ptr^);\r
    vmmdumpnewline;\r
    vmmdumproutine(' ');\r
    vmmdumpline;\r
    vmmdumperror(1,exc_code);\r
    vmmdumpnewline;\r
  END;\r
(*ENDTEST#*)\r
\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0D04) = $0904 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  <--  Lock');\r
      vmmdumpskip;\r
      vmmdumplocks(vmm_page_dscr_ptr^.perm_locks);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
  vmmlock:= exc_code;\r
END; (* vmmlock *)\r
\r
(* ---------------          VMMUNLOCK         --------------- *)\r
FUNCTION vmmunlock(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                       vmm_page_dscr_ptrr: pointer): WORD;\r
VAR\r
  vmm_page_dscr_ptr: ptr_page_dscr_type;\r
  exc_code: WORD;\r
BEGIN\r
  vmm_page_dscr_ptr:=vmm_page_dscr_ptrr;\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0E08) = $0A08 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Unlock');\r
      vmmdumpptr(vmm_page_dscr_ptr^);\r
      vmmdumpline;\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
\r
  exc_code:= e_ok;\r
  vmm_page_dscr_ptr:=PTR(SEG(vmm_page_dscr_ptr^),0);\r
\r
  IF ( 0 < vmm_page_dscr_ptr^.perm_locks ) THEN\r
  BEGIN\r
    vmm_page_dscr_ptr^.perm_locks:= vmm_page_dscr_ptr^.perm_locks - 1;\r
(*#BEGINTEST\r
    IF testvmm>0 THEN\r
      IF (WORD(testvmm) AND $0F08) = $0808 THEN\r
      BEGIN\r
        vmmdumproutine('VMM  -U-  Unlock');\r
        vmmdumpptr(vmm_page_dscr_ptr^);\r
        vmmdumpline;\r
        vmmdumpnewline;\r
      END;\r
(*ENDTEST#*)\r
  END ELSE\r
  (* - logic error: - lock underflow *) exc_code:= e_vmm_underflow;\r
\r
(*#BEGINTEST\r
  IF (testvmm>=0) AND (exc_code<>e_ok) THEN\r
  BEGIN\r
    vmmdumproutine('VMM  ERR  Unlock');\r
    vmmdumpptr(vmm_page_dscr_ptr^);\r
    vmmdumpline;\r
    vmmdumpnewline;\r
    vmmdumproutine(' ');\r
    vmmdumperror(1,exc_code);\r
    vmmdumpnewline;\r
  END;\r
(*ENDTEST#*)\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0D08) = $0908 THEN \r
    BEGIN\r
      vmmdumproutine('VMM  <--  Unlock');\r
      vmmdumpskip;\r
      vmmdumplocks(vmm_page_dscr_ptr^.perm_locks);\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
  vmmunlock:= exc_code;\r
END; (* vmmunlock *)\r
\r
\r
(* ---------------           VMMUPDATE          --------------- *)\r
FUNCTION vmmupdate(VAR vmm_tbl_dscr: tbl_dscr_type;\r
                       vmm_page_dscr_ptrr: pointer): WORD;\r
VAR\r
  vmm_page_dscr_ptr: ptr_page_dscr_type;\r
  exc_code: WORD;\r
BEGIN\r
  vmm_page_dscr_ptr := vmm_page_dscr_ptrr;\r
(*#BEGINTEST\r
  IF testvmm>0 THEN;\r
    IF (WORD(testvmm) AND $0E04) = $0A04 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  -->  Update');\r
      vmmdumpptr(vmm_page_dscr_ptr^);\r
      vmmdumpline;\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
    exc_code:= e_ok;\r
    vmm_page_dscr_ptr:= PTR(SEG(vmm_page_dscr_ptr^),0);\r
    vmm_page_dscr_ptr^.updated:= TRUE;\r
\r
(*#BEGINTEST\r
  IF testvmm>0 THEN\r
    IF (WORD(testvmm) AND $0D04) = $0904 THEN\r
    BEGIN\r
      vmmdumproutine('VMM  <--  Update');\r
      vmmdumpskip;\r
      vmmdumpnewline;\r
    END;\r
(*ENDTEST#*)\r
  vmmupdate:= exc_code;\r
END; (* vmmupdate *)\r
\r
(* INITIALIZATION *)\r
BEGIN\r
  min_va_low:= 0;\r
  min_va_high:= 0;\r
END.\r
\r
«eof»