From: nealcrook Date: Tue, 22 Nov 2016 17:13:59 +0000 (+0000) Subject: Dual-build. Working but need to add checks for return status after X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=218402fd585c4ebe66ffecb6b51642952e174e82;p=FUZIX.git Dual-build. Working but need to add checks for return status after file operation. --- diff --git a/Applications/BCPL/blib.c b/Applications/BCPL/blib.c index e8e3b6f2..a33ba8b6 100644 --- a/Applications/BCPL/blib.c +++ b/Applications/BCPL/blib.c @@ -17,6 +17,9 @@ static int fi, fo; /* Abstract away the difference between the paged and non-paged implementations */ #ifdef PAGEDMEM +void wrM(uint16_t addr, uint16_t data) ; +uint16_t rdM(uint16_t addr); + #else extern uint16_t *M; diff --git a/Applications/BCPL/icint.c b/Applications/BCPL/icint.c index 0cd80c06..98833d79 100644 --- a/Applications/BCPL/icint.c +++ b/Applications/BCPL/icint.c @@ -124,6 +124,152 @@ static void icputbyte(uint16_t, uint16_t, uint16_t); /* Abstract away the difference between the paged and non-paged implementations */ #ifdef PAGEDMEM +/* -1 if unmapped, n if this virtual page is in physcal buffer n */ +int vmap[VBLKS]; +/* -1 if unmapped, n if physcal buffer n holds this virtual page */ +int pmap[VBLKS]; +/* stats for replacement algorithm: increment each access */ +int acnt[VBLKS]; +/* stats for replacement algorithm: translation count - like a time-stamp */ +int tcnt[VBLKS]; +/* state of page */ +#define PAGNEVER 0 +#define PAGCLEAN 1 +#define PAGDIRTY 2 +int pagstate[VBLKS]; + +int translations = 0; +int pfp; + +static int pagein(uint16_t page); + +/* Given a virtual page number that is not mapped, map it. Take care of + any disk read/write. +*/ +static int +pagein(uint16_t page) +{ + int i; + int victim_block; + + /* First attempt: search pmap for an unassigned block */ + for (i=0; i= 0) { + // [NAC HACK 2016Nov19] check read return value, too + i = read(pfp, (unsigned char *)(M+i*BLKSIZE), 2*BLKSIZE); + } + else { + perror("Seek error replacing clean block"); + } + } + return; + } + } + + /* Third attempt: search pmap for least recently used block to reassign */ + /* [NAC HACK 2016Nov22] for now, always reassign physical block 5 */ + victim_block = 5; + + /* victim_block is dirty so must be written to disk. Its offset in the + pagefile is pmap[victim_block]*2*BLKSIZE. It comes from the physical + buffer at byte offset victim_block*2*BLKSIZE. It is 2*BLKSIZE bytes. + */ + if (lseek(pfp, (uint16_t)(pmap[victim_block]*2*BLKSIZE), SEEK_SET) >= 0) { + // [NAC HACK 2016Nov19] check write return value, too + i = write(pfp, (unsigned char *)(M+victim_block*BLKSIZE), 2*BLKSIZE); + } + else { + perror("Seek error evicting dirty block"); + } + pagstate[pmap[victim_block]] = PAGCLEAN; + vmap[pmap[victim_block]] = -1; + + + pmap[victim_block] = page; + vmap[page] = victim_block; + if (pagstate[page] == PAGCLEAN) { + /* Page has been used before, and therefore must be read from disk. + Page on disk is at byte offset page*2*BLKSIZE + and it will go into the buffer at (of course) the same place as + victim_block was written out from. Transfer 2*BLKSIZE bytes. + */ + + if (lseek(pfp, (uint16_t)(page*2*BLKSIZE), SEEK_SET) >= 0) { + // [NAC HACK 2016Nov19] check read return value, too + i = read(pfp, (unsigned char *)(M+victim_block*BLKSIZE), 2*BLKSIZE); + } + else { + perror("Seek error replacing dirty block"); + } + } +} + + +void +wrM(uint16_t addr, uint16_t data) +{ + if (vmap[addr>>10] == -1) { + pagein(addr>>10); + } + + translations++; + acnt[addr>>10]++; + pagstate[addr>>10] = PAGDIRTY; + tcnt[addr>>10] = translations; + M[(vmap[addr>>10]<<10) | (addr & 0x3ff)] = data; /* hardwired for BLKSIZE=1024 */ +} + +void +add2M(uint16_t addr, uint16_t data) +{ + if (vmap[addr>>10] == -1) { + pagein(addr>>10); + } + + translations += 2; + acnt[addr>>10] += 2; + tcnt[addr>>10] = translations; + M[(vmap[addr>>10]<<10) | (addr & 0x3ff)] = M[(vmap[addr>>10]<<10) | (addr & 0x3ff)] + data; /* hardwired for BLKSIZE=1024 */ +} + +uint16_t +rdM(uint16_t addr) +{ + if (vmap[addr>>10] == -1) { + pagein(addr>>10); + } + + translations++; + acnt[addr>>10]++; + tcnt[addr>>10] = translations; + return M[(vmap[addr>>10]<<10) | (addr & 0x3ff)]; /* hardwired for BLKSIZE=1024 */ +} + #else #define wrM(address, data) M[address]=data @@ -418,7 +564,6 @@ uint16_t pgvec[PSIZE]; int main(int argc, char *argv[]) { - if (argc != 2) { write(2, "usage: icint file\n",18); return 1; @@ -428,6 +573,38 @@ int main(int argc, char *argv[]) perror(argv[1]); return 0; } + +#ifdef PAGEDMEM + int i, status; + char * buf; + + for (i=0; i