From ce6b5c488796671a90c5be3be974715ff308373b Mon Sep 17 00:00:00 2001 From: rswier Date: Wed, 13 Apr 2016 05:09:24 -0400 Subject: [PATCH 1/5] Cleaned up B run-time Pared down the B run-time to a minimal functionality. This is based on research decompiling the pdp-11 libb.a run-time. --- src/other/brt.s | 4 +-- src/other/brtb.b | 84 ++++++++++++++++++------------------------------ 2 files changed, 34 insertions(+), 54 deletions(-) diff --git a/src/other/brt.s b/src/other/brt.s index b86b106..0fe2046 100644 --- a/src/other/brt.s +++ b/src/other/brt.s @@ -112,7 +112,7 @@ jmp start isz sp jmp fetch -.getchr: .+1 +.getchar: .+1 s 2 n 8 n 7 @@ -125,7 +125,7 @@ jmp start isz sp jmp fetch -.putchr: .+1 +.putchar: .+1 s 2 n 8 n 7 diff --git a/src/other/brtb.b b/src/other/brtb.b index 0c48c9a..34d792c 100644 --- a/src/other/brtb.b +++ b/src/other/brtb.b @@ -11,72 +11,52 @@ lchar(s, n, c) { return(c); } -getstr(s) { - auto c, i; +putnum(n, b) { + auto a, d; - i = 0; - while ((c = getchr()) != '*n') { - lchar(s,i,c); - i = i+1; + d = 0; + if (n < 0) { + n = -n; + if (n < 0) { + n = n-1; + d = 1; + } else + putchar('-'); } - lchar(s,i,'*e'); - return(s); -} - -putstr(s) { - auto c, i; - - i = 0; - while ((c = char(s,i)) != '*e') { - putchr(c); - i = i+1; - } -} - -putnum(n) { - if (n > 9) { - putnum(n / 10); - n = n % 10; - } - putchr(n + '0'); -} - -octal(n) { - if (n > 7) { - octal(n / 8); - n = n & 7; - } - putchr(n + '0'); + if (a = n/b) + putnum(a, b); + putchar(n%b + '0' + d); } printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9) { - auto adx, c, i; + auto adx, a, c, i, n; i = 0; adx = &x1; loop: - while ((c = char(fmt,i)) != '%') { - if (c=='*e') + while ((c = char(fmt, i)) != '%') { + if (c == '*e') return; - putchr(c); + putchar(c); i = i+1; } i = i+1; - c = char(fmt,i); - if (c=='d') { - if (*adx < 0) { - putchr('-'); - *adx = -*adx; - } - putnum(*adx); - } else if (c=='o') - octal(*adx); + a = *adx; + c = char(fmt, i); + if (c=='d') + putnum(a, 10); + else if (c=='o') + putnum(a, 8); else if (c=='c') - putchr(*adx); - else if (c=='s') - putstr(*adx); - else { - putchr('%'); + putchar(a); + else if (c=='s') { + n = 0; + while ((c = char(a, n)) != '*e') { + putchar(c); + n = n+1; + } + } else { + putchar('%'); goto loop; } i = i+1; From 032dc377053f79afbe06c8126f99ea68049c74f1 Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Thu, 14 Apr 2016 10:34:54 -0400 Subject: [PATCH 2/5] sys: alloc comments --- src/sys/s4.s | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sys/s4.s b/src/sys/s4.s index fe07ba5..f31686f 100644 --- a/src/sys/s4.s +++ b/src/sys/s4.s @@ -18,15 +18,15 @@ alloc: 0 lac 9f+t jmp alloc i " Return from routine 1: - lac s.nxfblk - sna + lac s.nxfblk " next block with list of free blocks + sna " any? jms halt " OUT OF DISK - dac s.fblks - jms dskrd - lac dskbuf - dac s.nxfblk - jms copy; dskbuf+1; s.fblks+1; 9 - lac d10 + dac s.fblks " save as first free block # + jms dskrd " read the block + lac dskbuf " get first word (pointer to next in chain) + dac s.nxfblk " save as new "next" + jms copy; dskbuf+1; s.fblks+1; 9 " copy remaining 9 as free + lac d10 " reset free count dac s.nfblks jmp alloc+1 From cb187e12bebb6338827b8290b5f6c8ec273ccc1c Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Fri, 15 Apr 2016 00:52:09 -0400 Subject: [PATCH 3/5] update queue (and other) storage comments --- src/sys/s8.s | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/sys/s8.s b/src/sys/s8.s index ba3dc86..0d84bf9 100644 --- a/src/sys/s8.s +++ b/src/sys/s8.s @@ -95,22 +95,23 @@ dm1: -1 9: .=.+t " per-routine temp variables c1: .=.+1 " not used? -q1: q2;q2+98 " ** 90? 96?? " queue element free list? - .=.+14 - " queues (two words each, head and tail pointers?) + " character queues (two words each, head and tail pointers?) + " 0: free list " 1: tty input " 2: tty output " 3: display keyboard " 4: paper tape reader " 5: paper tape punch -q2: +q1: q2;q2+98 " queue element free list + .=.+14 " room for 7 queues (5 used) +q2: " queue elements (and two words padding??) .+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0 .+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0 .+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0 .+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0 .+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;0;0 -dsploc: .=.+1 -dsplno: .=.+1 +dsploc: .=.+1 " pointer into dspbuf +dsplno: .=.+1 " display current line number dspbuf: 0065057;0147740;0160000 " display commands: see 03-scope.pdf pg 20 " PARAM: clear blink, clear light pen, scale=1, intensity=3 @@ -157,18 +158,19 @@ dskaddr: .=.+1 " number of block in dskbuf uniqpid: 1 " pid generator lu: .=.+4 " user (process) table entry copy sfiles: .=.+10 " wait addresses for special files - " (bit vector of waiting processes?) + " (bit vectors of waiting processes?) + " bit zero (MSB) is special, bit 1 first ulist entry, .... " offsets: 0: ttyin, 1: ttyout, 2: keyboard, " 3: ptr, 4: ptp, 6: display -dpdata: +dpdata: " dataphone data dpstat: .=.+1 dpread: .=.+1 dpwrite: .=.+1 dpchar: .=.+1 -dspdata: +dspdata: " display data .dspb: .=.+1 .lpba: .=.+1 "** 4 written on listing -crdata: +crdata: " card reader data crread: .=.+1 crchar: .=.+1 sysdata: " system data 64 words saved to disk @@ -177,7 +179,7 @@ sysdata: " system data 64 words saved to disk s.fblks: .=.+10 " cached free block numbers s.uniq: .=.+1 " next unique value s.tim: .=.+2 " (up?)time in 60Hz ticks (low, high) - " process table + " user (process) table " first word " bits 0:2 -- status " 0: free slot @@ -188,7 +190,7 @@ sysdata: " system data 64 words saved to disk " bits 3:17 -- disk swap address/8 " second word: process pid " third word: smes/rmes status: - " 0: not waiting + " 0: not waiting " -1: this process waiting (rmes) " other: complement of sender pid " fourth word: smes message @@ -243,7 +245,7 @@ dnode: " directory entry: d.name: .=.+4 " name (space padded) d.uniq: .=.+1 " unique number from directory inode . = dnode+8 -fnode: " open file entry +fnode: " open file entry (copied from u.ofiles) f.flags: .=.+1 " see below f.badd: .=.+1 " offset f.i: 0 " file i-number From c8129d7fa4ab2609290ac2e6dfd892ccb9332ecb Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Fri, 15 Apr 2016 00:52:26 -0400 Subject: [PATCH 4/5] s4.s: comment disk block free and (self modifiying) char queue routines --- src/sys/s4.s | 198 +++++++++++++++++++++++++++------------------------ 1 file changed, 106 insertions(+), 92 deletions(-) diff --git a/src/sys/s4.s b/src/sys/s4.s index f31686f..8f273e3 100644 --- a/src/sys/s4.s +++ b/src/sys/s4.s @@ -3,19 +3,19 @@ " allocate a free disk block for a file (data or indirect) alloc: 0 - -1 " Decrement the # free block numbers in the cache - tad s.nfblks " kept at s.fblks. Jump to 1f if no free blocks left. - spa - jmp 1f + -1 " decrement the count + tad s.nfblks " of free blocks at s.fblks + spa " any left? + jmp 1f " no dac s.nfblks " Update the count of free block numbers - tad fblksp - jms laci - dac 9f+t - jms copyz; dskbuf; 64 - lac 9f+t - jms dskwr - dzm .savblk - lac 9f+t + tad fblksp " get pointer to last valid entry in s.fblks + jms laci " fetch the word + dac 9f+t " save in t0 + jms copyz; dskbuf; 64 " zero dskbuf + lac 9f+t " get block number back + jms dskwr " write out the zeros + dzm .savblk " cancel system block write + lac 9f+t " get the block number back jmp alloc i " Return from routine 1: lac s.nxfblk " next block with list of free blocks @@ -32,31 +32,32 @@ alloc: 0 " free the disk block whose number is in AC free: 0 - lmq - lac s.nfblks - sad d10 - jmp 1f - tad fblksp - dac 9f+t - lacq - dac 9f+t i - dzm .savblk - isz s.nfblks - jmp free i + lmq " save block in MQ + lac s.nfblks " get number of free blocks + sad d10 " 10? + jmp 1f " yes + tad fblksp " no: get addr in s.fblks to store new block in + dac 9f+t " save pointer + lacq " get block number + dac 9f+t i " save it in s.fblks + dzm .savblk " cancel system block write + isz s.nfblks " increment free count + jmp free i " return 1: - lac s.nxfblk - dac dskbuf - jms copy; s.fblks+1; dskbuf+1; 9 - lacq - dac s.nxfblk - jms dskwr - dzm .savblk - lac d1 - dac s.nfblks - jmp free i " Return from the routine + lac s.nxfblk " get head of free chain + dac dskbuf " save (as chain ptr) in first word of disk buf + jms copy; s.fblks+1; dskbuf+1; 9 " with 9 of the 10 free blocks + lacq " get the newly freed block back + dac s.nxfblk " save as new head of free chain + jms dskwr " write dskbuf to the newly freed block + dzm .savblk " cancel system block write + lac d1 " reset free count to one + dac s.nfblks " (the first word in s.fblks) + jmp free i " Return from the routine t = t+1 " load AC indirect (without using indirect!) + " need to avoid use of indirect in interrupt service routines " AC/ address " jms laci " AC/ contents of address @@ -141,92 +142,105 @@ copyz: 0 jmp copyz i " return t = t+1 - " put queued character - " CALLED FROM PI: AVOIDS INDIRECT!! - " queue number in AC -putchar: 0 -"** 01-s1.pdf page 23 - dac 9f+t - cla - jms takeq - jmp putchar i - tad o40001 - dac .+4 - lac 9f+t - jms putq - lac char - dac q2+1 .. - isz putchar - jmp putchar i -t = t+1 + " Character queue management routines + " (CALLED FROM PI: USE OF INDIRECT AVOIDED!) - " get queued character - " CALLED FROM PI: AVOIDS INDIRECT!! - " queue number in AC: + " Queue numbers: + " 0: free list " 1: tty input " 2: tty output " 3: display keyboard " 4: paper tape reader " 5: paper tape punch -getchar: 0 + + " queue headers are two words: "first" and "last"(??) + " queue entries are two words: "next" and "char" + + " put queued character + " character to store in "char" + " queue number in AC + +putchar: 0 +"** 01-s1.pdf page 23 + dac 9f+t " save queue number in t0 + cla " get entry from free list jms takeq - jmp i getchar - tad o200001 + jmp putchar i " none free: return w/o skip + tad o40001 " turn into "dac addr+1" + dac .+4 + lac 9f+t " get queue number back + jms putq " add entry + lac char " get char + dac q2+1 .. " save in second word of queue entry + isz putchar " give skip return + jmp putchar i +t = t+1 + + " get queued character + " queue number in AC + " returns with skip if something found +getchar: 0 + jms takeq " get entry from head of queue + jmp i getchar " nothing there: return w/o skip + tad o200001 " turn into "lac qentry+1" (fetch stored char) dac .+3 cla - jms putq - lac q2+1 .. - isz getchar + jms putq " put qentry on free list + lac q2+1 .. " fetch queued character(!!!) + isz getchar " give skip return jmp i getchar - " CALLED FROM PI: AVOIDS INDIRECT!! + " fetch first entry from a queue + " queue number in AC + " returns with skip if something dequeued takeq: 0 - rcl - tad lacq1 + rcl " multiply queue number by two + tad lacq1 " add "lac q1" dac .+7 - tad o640000 + tad o640000 " turn "lac" into "dac" dac .+17 - tad d1 + tad d1 " increment addr dac .+14 - tad o500000 + tad o500000 " turn "dac" into "sad" dac .+5 - lac q1 .. - sna - jmp takeq i + lac q1 .. " load queue head + sna " non-zero? + jmp takeq i " no: return zero w/o skip dac lnkaddr - sad q1+1 .. - jmp .+5 - tad o200000 - dac .+1 - lac q2 .. + sad q1+1 .. " different from tail(??) + jmp .+5 " no -- (last entry?) + tad o200000 " yes: turn into lac + dac .+1 " save lac + lac q2 .. " get next pointer from queue entry jmp .+3 - cla - dac q1+1 .. - dac q1 .. - isz takeq - lac lnkaddr + cla " here with head == tail(??) + dac q1+1 .. " clear tail + dac q1 .. " save (clear) head + isz takeq " give skip return + lac lnkaddr " return queue entry pointer jmp i takeq + " save queue entry (at lnkaddr) to a queue (queue number in AC) putq: 0 - rcl - tad dacq1 + rcl " multiply by two + tad dacq1 " turn into "dac qhead" dac .+14 - tad d1 + tad d1 " turn into "dac qtail" dac .+13 - tad o140000 + tad o140000 " turn into "lac qtail" dac .+1 - lac q1-1 .. + lac q1-1 .. " fetch tail "** 01-s1.pdf page 24 - sna - jmp .+6 - tad o40000 + sna " non-zero? + jmp .+6 " no: is zero + tad o40000 " turn into "dac qentry" (append to queue) dac .+2 - lac lnkaddr - dac q2 .. + lac lnkaddr " get new entry + dac q2 .. " append to tail entry jmp .+3 - lac lnkaddr - dac q1 .. - dac q1+1 .. + lac lnkaddr " here with tail == 0 + dac q1 .. " save new entry as head + dac q1+1 .. " save new tail jmp putq i " NOTE!! srcdbs, collaps, dskrd, dskwr share the same "temp" vars: From 1a4c0c3c7180ec8e3ddf0838392c90f1d70fd1bd Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Sun, 17 Apr 2016 13:25:14 -0400 Subject: [PATCH 5/5] s6.s: add comments --- src/sys/s6.s | 124 ++++++++++++++++++++++++++------------------------- 1 file changed, 63 insertions(+), 61 deletions(-) diff --git a/src/sys/s6.s b/src/sys/s6.s index 5ba1097..891dc9b 100644 --- a/src/sys/s6.s +++ b/src/sys/s6.s @@ -99,6 +99,8 @@ namei: 0 jmp 1b " yes: keep going jmp namei i " Didn't find it, return zero in AC (without skip) t = t+2 + + " NOTE: iget/iput share "temp" vars!!! " Given an i-number in AC, fetch that i-node " from disk and store it in the inode buffer iget: 0 @@ -113,49 +115,50 @@ iget: 0 cll; mul; 12 " Multiply the i-num within the block by 12 lacq " to get the offset into the block tad dskbufp " Add on the base of the disk buffer - dac 9f+t + dac 9f+t " save pointer into dskbuf in "t0" dac .+2 jms copy; ..; inode; 12 " Copy 12 words from buffer to inode jmp iget i " and return iput: 0 - lac 9f+t+1 - jms dskrd - law inode-1 - dac 8 + lac 9f+t+1 " get block number saved by iget + jms dskrd " read the block + law inode-1 " pointer to "in core" inode + dac 8 " in index 8 -1 - tad 9f+t - dac 9 - -12 - dac 9f+t+2 + tad 9f+t " get saved pointer into buffer + dac 9 " in index 9 + -12 " 12 word loop count + dac 9f+t+2 " in t2 1: - lac 8 i + lac 8 i " fetch source word "** 01-s1.pdf page 36 - sad 9 i - skp - jmp 2f - isz 9f+t+2 - jmp 1b - jmp iput i -2: - -1 + sad 9 i " differs from disk? + skp " no: + jmp 2f " yes: + isz 9f+t+2 " no difference: done? + jmp 1b " no: keep going + jmp iput i " yes: return w/o writing to disk +2: " here with in-core inode changed + -1 " back up both pointers tad 8 dac 8 -1 tad 9 dac 9 1: - lac 8 i - dac 9 i - isz 9f+t+2 - jmp 1b - lac 9f+t+1 - jms dskwr - jmp iput i + lac 8 i " fetch word + dac 9 i " copy to dskbuf + isz 9f+t+2 " done? + jmp 1b " no: keep going + lac 9f+t+1 " get block number + jms dskwr " write back to disk + jmp iput i " return t = t+3 + " NOTE! dget/dput share "temp" vars " allocate directory entry " AC/ entry number dget: 0 @@ -164,30 +167,31 @@ dget: 0 dac 9f+t " save in t0 jms pget " get free disk block dac 9f+t+1 " save in t1 - jms dskrd - lac 9f+t - and o77 - tad dskbufp - dac 9f+t+2 - dac .+2 - jms copy; ..; dnode; 8 - lac 9f+t - tad d8 - jms betwen; d0; i.size - skp - jmp dget i - jms dacisize - dzm d.i - jmp dget i + jms dskrd " read block + lac 9f+t " get word number + and o77 " get word within block + tad dskbufp " make pointer into dskbuf + dac 9f+t+2 " save in t2 + dac .+2 " save as copy source + jms copy; ..; dnode; 8 " copy entry into dnode + lac 9f+t " get word number + tad d8 " of end of new node + jms betwen; d0; i.size " already allocated? + skp " no + jmp dget i " yes: return + jms dacisize " store new file size + dzm d.i " mark new entry as free + jmp dget i " return + " write directory entry (back) to disk dput: 0 - lac 9f+t+1 - jms dskrd - lac 9f+t+2 - dac .+3 - jms copy; dnode; ..; 8 - lac 9f+t+1 - jms dskwr + lac 9f+t+1 " get disk block number back + jms dskrd " read into dskbuf + lac 9f+t+2 " get pointer into dskbuf + dac .+3 " save as copy dest + jms copy; dnode; ..; 8 " copy into dskbuf + lac 9f+t+1 " get disk block number + jms dskwr " write back to disk jmp dput i t = t+3 @@ -262,6 +266,10 @@ pget: 0 jmp pget i " return it t = t+3 + " write to file referenced by loaded inode + " AC/ file offset + " jms iwrite; addr; count + iwrite: 0 dac 9f+t " save arg in t0 lac iwrite " load return address @@ -273,14 +281,14 @@ iwrite: 0 dac iwrite " save as iwrite instruction jmp 1f - " iread from file referenced by loaded inode + " read from file referenced by loaded inode " AC/ file offset " jms iread; addr; count iread: 0 dac 9f+t " save offset in t0 lac cnop " get nop dac iwrite " save as iwrite instruction -1: +1: " common code for iread/iwrite -1 tad iread i " get word before return addr dac 10 " store in index 10 & 11 @@ -289,20 +297,14 @@ iread: 0 lac iread i " load addr dac 9f+t+1 " save in t1 isz iread " increment return addr - lac o70000 + lac o70000 " get max file size xct iwrite " skip if write lac i.size " read: get file size cma - tad 9f+t " add offset - cma - jms betwen; d0; 9f+t+1 - lac 9f+t+1 - dac 9f+t+2 - cma - tad d1 - sna - jmp iread i - dac 9f+t+1 + tad 9f+t " subtract offset + sna " offset == size? + jmp iread i " yes, return + dac 9f+t+1 " save size-offset in t1 1: lac 9f+t jms pget @@ -312,7 +314,7 @@ iread: 0 and o77 tad dskbufp tad dm1 - xct iwrite + xct iwrite " skip if write jmp .+3 dac 10 cskp: