diff --git a/Makefile b/Makefile index 315d803..afaf3ec 100644 --- a/Makefile +++ b/Makefile @@ -14,3 +14,10 @@ altrun: buildit clean: cd build && $(MAKE) clean + +binaries: buildit + mkdir -p binaries + cp build/image.fs binaries/ + cp build/boot.rim binaries/ + cp build/unixv0.simh binaries/ + diff --git a/README.md b/README.md index d33504e..454f2ba 100644 --- a/README.md +++ b/README.md @@ -49,15 +49,9 @@ Press `ctl-e` to break out the simulator into simh ### Precompiled Binaries -You can also run pdp7-unix from precompiled binaries in the [/binaries](/binaries) directory. There are **orig** binaries and **alt** binaries. +You can also run pdp7-unix from precompiled binaries in the [/binaries](/binaries) directory. -The orig binaries use the unixv0 directory semantics as restored from the printouts. To run pdp7-unix orig: - -`cd binaries/orig; pdp7 unixv0.simh` - -The alt binaries use the more familiar "." and ".." diretory semanatics as found in later unix. To run pdp7-unix alt: - -`cd binaries/alt; pdp7 unixv0.simh` +`cd binaries/; pdp7 unixv0.simh` ### Typical Output diff --git a/binaries/boot.rim b/binaries/boot.rim new file mode 100644 index 0000000..d5bf44b --- /dev/null +++ b/binaries/boot.rim @@ -0,0 +1 @@ +ธ€‚ธ›‚ธนกฟ€ธน”ฝ€€ธนข‘€ฆถ‡ˆ•€คธน„‘€ขธนคธน‘ฑ€ธนšผ‰€ผ€ ฟฐ€ธน”‘€ฃธนข‘€ฆถ‡ˆ•€ฅธน„‘€ขธนคธน‘ฑ€œธนšผ‰€ผ€ ฐ€€€€ฐ€˜€€˜ˆ€€€ฑ€ภ \ No newline at end of file diff --git a/binaries/image.fs b/binaries/image.fs new file mode 100644 index 0000000..e57d7a3 Binary files /dev/null and b/binaries/image.fs differ diff --git a/binaries/unixv0.simh b/binaries/unixv0.simh new file mode 100644 index 0000000..297ef35 --- /dev/null +++ b/binaries/unixv0.simh @@ -0,0 +1,31 @@ +set cpu 8k +set cpu eae +set cpu history=100 +show cpu + +# set up SIMH devices: + +# UNIX character translations (CR to NL, ESC to ALTMODE): +set tti unix + +# RB09 fixed head disk: +set rb ena +att rb image.fs + +# uncomment to TELNET in GRAPHICS-2 keyboard/display(!!) +# (requires github.com/philbudne/simh) +set g2in ena +att -U g2in 12345 + +# disable hardware UNIX-7 doesn't know about: +set lpt disa +set drm disa +set dt disa + +# show device settings: +show dev + +# load and run the paper tape bootstrap +# (loads system from disk) +load boot.rim 010000 +go diff --git a/src/other/brt.s b/src/other/brt.s index 03ae284..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 @@ -230,29 +230,23 @@ flush: 0 jmp flush i initio: 0 + law .argv " build argument list + dac 8 " auto-inc pointer argvp = &argv[-1] lac 017777 i -" sad d4 - jmp 2f - sad d8 - jmp 1f + cll rtr + dac 8 i " *++argvp = arg count + cma + tad d1 + dac t1 " count = -argv[0] + lac 017777 + dac lastv " set top of heap + tad d1 " ac = addr of arg0 +1: + dac 8 i " *++argvp = ac + tad d4 " ac += 4 + isz t1 " while ++count != 0 + jmp 1b - law 9 - tad 017777 - dac .+3 - law 017 - sys creat; .. - spa - jmp stop - dac .fout -1: - law 5 - tad 017777 - dac .+2 - sys open; ..; 0 - spa - jmp stop - dac .fin -2: lac lastv dac eibufp dac cibufp @@ -280,7 +274,7 @@ iflg: 0 eobufp: 0 cobufp: 0 oflg: 0 -lastv: 017770 +lastv: 0 o777: 0777 d4:o4: 4 diff --git a/src/other/brtb.b b/src/other/brtb.b index 8439a52..34d792c 100644 --- a/src/other/brtb.b +++ b/src/other/brtb.b @@ -2,68 +2,61 @@ char(s, n) { if (n & 1) return(s[n/2] & 0777); - return ((s[n/2]/512) & 0777); + return((s[n/2]/512) & 0777); } lchar(s, n, c) { if (n & 1) s[n/2] = (s[n/2] & 0777000) | c; else s[n/2] = (s[n/2] & 0777) | (c*512); + return(c); } -putstr(s) { - auto c, i; +putnum(n, b) { + auto a, d; - i = 0; - while ((c = char(s,i)) != '*e') { - putchr(c); - i = i+1; + d = 0; + if (n < 0) { + n = -n; + if (n < 0) { + n = n-1; + d = 1; + } else + putchar('-'); } -} - -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; diff --git a/src/other/ctype.b b/src/other/ctype.b new file mode 100644 index 0000000..8e05611 --- /dev/null +++ b/src/other/ctype.b @@ -0,0 +1,9 @@ +/* ctype.b - character types */ + +isalpha(c) { + return((c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z')); +} + +isdigit(c) { + return(c >= '0' & c <= '9'); +} diff --git a/src/other/string.b b/src/other/string.b new file mode 100644 index 0000000..7731be8 --- /dev/null +++ b/src/other/string.b @@ -0,0 +1,58 @@ +/* string.b - B string library + + mostly from: https://www.bell-labs.com/usr/dmr/www/btut.html +*/ + +strcopy(sl, s2) { + auto i; + i = 0; + while (lchar(sl,i,char(s2,i)) != '*e') + i = i+1; + return(s1); +} + +strcat(s1, s2) { + auto i,j; + i = j = 0; + while (char(s1,i) != '*e') + i = i+1; + while(lchar(s1,i,char(s2,j)) != '*e') { + i = i+1; + j = j+1; + } + return(s1); +} + +strlen(s) { + auto i; + i = 0; + while (char(s,i) != '*e') + i = i+1; + return(i); +} + +strcmp(s1, s2) { + auto c,i; + i = 0; + while ((c=char(s1,i)) == char(s2,i)) { + if (c == '*e') + return(0); + i = i+1; + } + return(c - char(s2,i)); +} + +/* convert command line argument into a string */ +strarg(s, a) { + auto i, c; + i = 0; + while (i < 8) { + if ((c = char(a,i)) == ' ') + goto done; + lchar(s,i,c); + i = i+1; + } +done: + lchar(s,i,'*e'); + return(s); +} diff --git a/src/other/test.b b/src/other/test.b index c0259a8..e398c3d 100644 --- a/src/other/test.b +++ b/src/other/test.b @@ -7,14 +7,41 @@ perl a7out test.out */ +/* convert command line argument into a string */ +strarg(s, a) { + auto i, c; + i = 0; + while (i < 8) { + if ((c = char(a,i)) == ' ') + goto done; + lchar(s,i,c); + i = i+1; + } +done: + lchar(s,i,'*e'); + return(s); +} + main { - extrn fname, fin; - auto ch,p; + extrn fname, fin, fout, argv; + auto ch,p,n,str 5; p = 017777; printf("mem[0%o] = 0%o*n",p,*p); printf("mem[0%o] = %d*n",*p,**p); + printf("argv = %d*n",argv); + printf("**argv = %d*n",*argv); + printf("argv[0] = %d*n",argv[0]); + n = 0; + while (n < argv[0]) { + n = n+1; + printf("argv[%d] = 0%o *"%s*"*n",n,argv[n],strarg(str,argv[n])); + } + + printf("array(0) = 0%o*n",array(0)); + printf("array(64) = 0%o*n",array(64)); + printf("array(0) = 0%o*n",array(0)); /* fin = open(fname, 0); */ fin = open("abc ", 0); diff --git a/src/sys/s1.s b/src/sys/s1.s index a7a07ab..7532526 100644 --- a/src/sys/s1.s +++ b/src/sys/s1.s @@ -65,7 +65,7 @@ sysexit: " common system call exit code 1: dzm .insys " clear "in system call" flag jms chkint " pending user interrupt? - skp " no + skp " no, return to user jmp .save " yes: dump core jms copy; u.rq+2; 10; 6 " restore auto-index locations 10-15 lac u.rq+1 " restore auto-index location 9 @@ -77,7 +77,7 @@ sysexit: " common system call exit code lac u.ac " restore AC register jmp u.rq+8 i " return to user - " scheduler / idle loop + " scheduler / swapper / idle loop swap: 0 ion 1: @@ -176,8 +176,8 @@ locn: " call: " .insys/ 0 " jms chkint - " no: no interrupt, or intflg set (discards interrupt) - " yes: PI off, .insys set + " + " chkint: 0 lac .insys sza " in system? diff --git a/src/sys/s2.s b/src/sys/s2.s index 4195e78..c430198 100644 --- a/src/sys/s2.s +++ b/src/sys/s2.s @@ -216,7 +216,7 @@ sza " zero (read) lac d1 " no: get write mode bit sna " non-zero (write)? - lac d2 " no: get read mode bot + lac d2 " no: get read mode bit dac mode " save for access call lac u.cdir " get current working directory jms namei; 0:0 " search for file diff --git a/src/sys/s3.s b/src/sys/s3.s index af143d0..386dbfe 100644 --- a/src/sys/s3.s +++ b/src/sys/s3.s @@ -330,9 +330,9 @@ rppti: jmp .+3 alss 9 jmp passone - lac sfiles+3 - sma - rsa + lac sfiles+3 " get sleep word + sma " high bit set? + rsa " no: reader select alphanumeric mode 1: jms sleep; sfiles+3 jms swap diff --git a/src/sys/s4.s b/src/sys/s4.s index fe07ba5..8f273e3 100644 --- a/src/sys/s4.s +++ b/src/sys/s4.s @@ -3,60 +3,61 @@ " 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 - 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 " 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: diff --git a/src/sys/s5.s b/src/sys/s5.s index af6ed77..55f242c 100644 --- a/src/sys/s5.s +++ b/src/sys/s5.s @@ -248,13 +248,13 @@ dspinit: 0 jmp dspinit i " "move display" (change display buffer pointer) - " called with new buffer pointer in AC?? + " called with new buffer pointer in AC movdsp: 0 iof - cdf - dac dspbufp + cdf " clear display flags (stop) + dac dspbufp " save display buf pointer -1 - dac .dspb + dac .dspb " .dspb = -1 ion jmp movdsp i diff --git a/src/sys/s6.s b/src/sys/s6.s index 5ba1097..6adf94d 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,7 +297,7 @@ 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 @@ -299,10 +307,10 @@ iread: 0 lac 9f+t+1 dac 9f+t+2 cma - tad d1 - sna - jmp iread i - dac 9f+t+1 + tad d1 " 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 +320,7 @@ iread: 0 and o77 tad dskbufp tad dm1 - xct iwrite + xct iwrite " skip if write jmp .+3 dac 10 cskp: diff --git a/src/sys/s7.s b/src/sys/s7.s index f6b2a7a..7f6a999 100644 --- a/src/sys/s7.s +++ b/src/sys/s7.s @@ -1,28 +1,28 @@ "** 01-s1.pdf page 41 " s7 -pibreak: " priority interrupt break processing "chain" - dac .ac " save interrupt AC +pibreak: " priority interrupt break processing "chain" + dac .ac " save interrupt AC "** CROSSED OUT.... - dpsf - jmp 1f " disable the Graphics-2 I/O + dpsf " skip on data phone flag set + jmp 1f " not set: check next device - dpcf - dprs - dac dpstat - sma ral - jmp 2f - dprc - dac dpchar + dpcf " clear dataphone flag + dprs " read dataphone status + dac dpstat " save for user + sma ral " REC FLG set? rotate flags left + jmp 2f " no + dprc " read char (bit zero set if parity correct) + dac dpchar " save for user -1 - dac dpread - lac dpstat - ral + dac dpread " dpread = -1 + lac dpstat " get status back + ral " rotate up 2: - sma - jmp piret + sma " XMIT FLG set? + jmp piret " no: return from interrupt -1 - dac dpwrite + dac dpwrite " dpwrite = -1 jmp piret "** END OF CROSSOUT 1: clsf " clock overflow (line frequency ticks)? @@ -40,7 +40,7 @@ pibreak: " priority interrupt break processing "chain" cnop: " fetched as constant in iread nop -1 - dac 7 " set location 7 to -1 (nothing ever clears it) + dac 7 " set location 7 to -1 (nothing ever checks/clears it?) clon " enable clock interrupts, reset flag lac ttydelay " tty delay positive? spa " yes: skip to skp @@ -49,141 +49,142 @@ cnop: " fetched as constant in iread jms ttyrestart " yes: start output "** START CROSSED OUT: written: lac tty lac .dspb - sna - jmp piret - isz .dsptm - skp - jmp dsprestart - sad d3 - jmp piret - isz .dspb - jmp piret - jmp dsprestart "** END CROSSED OUT + sna " .dspb != 0? + jmp piret " no: return + isz .dsptm " increment .dsptm; is zero? + skp " no + jmp dsprestart " yes: restart display + sad d3 " .dspb == 3? + jmp piret " yes: return + isz .dspb " increment .dspb; is zero? + jmp piret " no: return from interrupt + jmp dsprestart " yes: restart display + "** END CROSSED OUT -1: dssf " disk flag set? - jmp 1f " no +1: dssf " disk flag set? + jmp 1f " no - -1 " set .dskb = -1 + -1 " set .dskb = -1 dac .dskb "** 01-s1.pdf page 42 - dsrs " get disk status in .dske + dsrs " get disk status in .dske dac .dske - dscs " clear status register + dscs " clear status register jmp piret "** BEGIN CROSSED OUT -1: lds " load display status (see 03-scope.pdf pg 25) - sma ral " display trap set? (and rotate left) - jmp 1f " not set - cdf " display done executing; clear display flags +1: lds " load display status (see 03-scope.pdf pg 25) + sma ral " display trap set? (and rotate left) + jmp 1f " not set + cdf " display done executing; clear display flags lac .dspb sna - jmp piret " return now if .dspb == 0 + jmp piret " return now if .dspb == 0 tad dm3 sna - jmp dsprestart " start display if .dspb == 3 - dac .dspb " otherwise, .dspb -= 3 and return + jmp dsprestart " start display if .dspb == 3 + dac .dspb " otherwise, .dspb -= 3 and return jmp piret dsprestart: lac d1 - dac .dspb " set .dspb = 1 - lac dspbufp " load display buf pointer - beg " start display processor + dac .dspb " set .dspb = 1 + lac dspbufp " load display buf pointer + beg " start display processor -10 - dac .dsptm " set .dsptm = -10 (10 ticks) + dac .dsptm " set .dsptm = -10 (10 ticks) jmp piret -1: sma ral " edges flag set?? (and rotate) - jmp .+3 " no - raef " "resume after edges flag" - jmp piret " return - sma " light pen flag? - jmp 1f " no - lda " G-2: load display address - dac .lpba " save - rlpd " G-2: resume after light pen stop +1: sma ral " edges flag set?? (and rotate) + jmp .+3 " no + raef " "resume after edges flag" + jmp piret " return + sma " light pen flag? + jmp 1f " no + lda " G-2: load display address + dac .lpba " save + rlpd " G-2: resume after light pen stop jmp piret -1: ksf " (TTY) keyboard flag set? - jmp 1f " no +1: ksf " (TTY) keyboard flag set? + jmp 1f " no - lac ttydelay " get TTY delay - sma " minus (waiting for output)? - isz ttydelay " no: increment??? (make more positive) - krb " read keyboard buffer - dac char " save in char - sad o375 " interrupt char (TTY ALT MODE?) - jmp intrp1 " yes + lac ttydelay " get TTY delay + sma " minus (waiting for output)? + isz ttydelay " no: increment??? (make more positive) + krb " read keyboard buffer + dac char " save in char + sad o375 " interrupt char (TTY ALT MODE?) + jmp intrp1 " yes lac d1 jms putchar dzm char - lac sfiles+0 " get sleep word for ttyin - jms wakeup " wake processes - dac sfiles+0 " clear sleep word - lac char " get character - sad o212 " new line (with parity)?? - skp " yes - jmp piret " no: done - lac sfiles+1 " get ttyout sleep word - sma " highest bit set? - xor o400000 " no, make it so (why???) - dac sfiles+1 " save back + lac sfiles+0 " get sleep word for ttyin + jms wakeup " wake processes + dac sfiles+0 " clear sleep word + lac char " get character + sad o212 " new line (with parity)?? + skp " yes + jmp piret " no: done + lac sfiles+1 " get ttyout sleep word + sma " highest bit set? + xor o400000 " no, make it so (why???) + dac sfiles+1 " save back "** 01-s1.pdf page 43 - jms putcr " output CR next - jms ttyrestart " start output + jms putcr " output CR next + jms ttyrestart " start output jmp piret -1: tsf " TTY output flag set? - jmp 1f " no +1: tsf " TTY output flag set? + jmp 1f " no - tcf " yes: clear flag - jms ttyrestart " transmit next character + tcf " yes: clear flag + jms ttyrestart " transmit next character jmp piret ttyrestart: 0 - lac ttydelay " get tty delay - spa " positive? - jmp ttyrestart i " no: keep waiting - lac nttychar " get pending CR, if any - dzm nttychar " clear it - sza " need to send CR? - jmp 3f " yes - isz ttydelay " increment ttydelay (make more positive) + lac ttydelay " get tty delay + spa " positive? + jmp ttyrestart i " no: keep waiting + lac nttychar " get pending CR, if any + dzm nttychar " clear it + sza " need to send CR? + jmp 3f " yes + isz ttydelay " increment ttydelay (make more positive) lac d2 - jms getchar " get a character - jmp 2f " none found?? + jms getchar " get a character + jmp 2f " none found?? 3: - tls " start output - sad o12 " newline? - jms putcr " yes: put CR next - sad o15 " CR? - skp " yes - jmp ttyrestart i " no: return - lac ttydelay " get current tty delay - tad o20 " bump by 16 - rcr " divide by two - cma " complement - dac ttydelay " save + tls " start output + sad o12 " newline? + jms putcr " yes: put CR next + sad o15 " CR? + skp " yes + jmp ttyrestart i " no: return + lac ttydelay " get current tty delay + tad o20 " bump by 16 + rcr " divide by two + cma " complement + dac ttydelay " save jmp ttyrestart i 2: - lac sfiles+1 " run out of characters to send: wake user(s) + lac sfiles+1 " run out of characters to send: wake user(s) jms wakeup dac sfiles+1 jmp ttyrestart i "** written arrow up 2 copies "** BEGIN CROSSED OUT -1: sck " Graphic-2 keyboard flag set? - jmp 1f " no. +1: sck " Graphic-2 keyboard flag set? + jmp 1f " no. - cck " yes: clear flag - lck " read character + cck " yes: clear flag + lck " read character dac char - sad o33 " code 33 (ESCAPE?) - jmp intrp2 " yes: mark interrupt + sad o33 " code 33 (ESCAPE?) + jmp intrp2 " yes: mark interrupt lac d3 jms putchar nop @@ -192,21 +193,21 @@ ttyrestart: 0 dac sfiles+2 jmp piret -1: rsf " paper tape ready? - jmp 1f " no +1: rsf " paper tape reader ready? + jmp 1f " no "** 01-s1.pdf page 44 lac npptchar - sna - jmp .+5 - dac char - rrb - dac npptchar + sna " have saved char? + jmp .+5 " no: jump to second rrb + dac char " yes: save as current char + rrb " clear flag, read reader buffer + dac npptchar " save as saved char jmp .+3 - rrb - dac char + rrb " here without saved char: read new + dac char " save as current 3: lac char sna @@ -218,16 +219,16 @@ ttyrestart: 0 sad d4 jmp 4f 2: - lac npptchar - sna - jmp .+4 - dac char - dzm npptchar + lac npptchar " get saved char (if any) + sna " had saved char? + jmp .+4 " no: wake up writer + dac char " yes: save as char to send + dzm npptchar " clear saved char jmp 3b - rsa + rsa " reader select alphanumeric mode lac sfiles+3 - jms wakeup - xor o400000 + jms wakeup " wake sleepers; returns zero + xor o400000 " set high bit (rsa before sleep) dac sfiles+3 jmp piret 3: @@ -239,43 +240,43 @@ ttyrestart: 0 dac sfiles+3 jmp piret -1: psf " paper tape ready? - jmp 1f " no +1: psf " paper tape punch ready? + jmp 1f " no - pcf " clear ptp flag + pcf " clear ptp flag lac d5 - jms getchar " get next char - jmp .+3 - psa - jmp piret - lac sfiles+4 - jms wakeup - dac sfiles+4 - jmp piret + jms getchar " get next char + jmp .+3 " none: wake sleepers + psa " punch set alphanumeric mode + jmp piret " return from interrupt + lac sfiles+4 " get sleeper bit vector + jms wakeup " wake them + dac sfiles+4 " store zero + jmp piret " return from PI "** BEGIN CROSSED OUT -1: spb " any graphic-2 push button? - jmp 1f " no +1: spb " any graphic-2 push button? + jmp 1f " no - cpb " clear push button flag - lpb " load push button value + cpb " clear push button flag + lpb " load push button value dac pbsflgs+1 "** 01-s1.pdf page 45 - and o2000 " get push button 7 - sna " set? - jmp piret " no: done - jms dspinit " yes: reset display buffer - lac sfiles+6 " wake up anyone sleeping on display + and o2000 " get push button 7 + sna " set? + jmp piret " no: done + jms dspinit " yes: reset display buffer + lac sfiles+6 " wake up anyone sleeping on display jms wakeup dac sfiles+6 - cla " clear button lights + cla " clear button lights wbl jmp piret "** END CROSSED OUT -1: crsf " card reader flag set? - jmp 1f " no +1: crsf " card reader flag set? + jmp 1f " no crrb dac crchar @@ -283,14 +284,14 @@ ttyrestart: 0 dac crread jmp piret -1: crrb " read card reader buffer?? +1: crrb " read card reader buffer?? -piret: " return from priority interrupt - lac 0 " get LINK/PC - ral " restore LINK - lac .ac " restore AC - ion " reenable interrupts - jmp 0 i " return from interrupt +piret: " return from priority interrupt + lac 0 " get LINK (in bit 0) + ral " restore LINK + lac .ac " restore AC + ion " reenable interrupts + jmp 0 i " return from interrupt " wake sleeping processes " NOTE!! Called from interrupt service, so avoids indirect!!! @@ -299,35 +300,35 @@ piret: " return from priority interrupt " jms wakeup " AC/ 0 (to store in sfiles word) wakeup: 0 - dac 9f+t " save vector in t0 + dac 9f+t " save vector in t0 -mnproc - dac 9f+t+1 " loop count in t1 - lac tadu " get "tad ulist" + dac 9f+t+1 " loop count in t1 + lac tadu " get "tad ulist" dac 2f - lac dacu " get "dac ulist" + lac dacu " get "dac ulist" dac 2f+1 1: lac 9f+t - ral " rotate vector up one + ral " rotate vector up one dac 9f+t - sma " high bit set? - jmp 2f+2 " no: skip the fun - lac o700000 " yes: decrement process status (wake) -2: tad .. " (avoiding indirect) + sma " high bit set? + jmp 2f+2 " no: skip the fun + lac o700000 " yes: decrement process status (wake) +2: tad .. " (avoiding indirect) dac .. - lac 2b " advance tad operand by 4 words + lac 2b " advance tad operand by 4 words tad d4 dac 2b - lac 2b+1 " advance tad operand by 4 words + lac 2b+1 " advance tad operand by 4 words tad d4 dac 2b+1 - isz 9f+t+1 " done? - jmp 1b " no, keep going - cla " return zero in AC + isz 9f+t+1 " done? + jmp 1b " no, keep going + cla " return zero in AC jmp wakeup i t = t+2 - " call to output CR after LF (NL) + " call to output CR after LF (NL) on TTY putcr: 0 lac o15 dac nttychar @@ -337,43 +338,43 @@ putcr: 0 cla jmp putcr i -intrp1: " here with TTY interrupt character - lac d6 " get keyboard special device number - dac .int1 " save as interrupt source - lac d1 " drain tty input buffer? +intrp1: " here with TTY interrupt character + lac d6 " get keyboard special device number + dac .int1 " save as interrupt source + lac d1 " drain tty input buffer? jms getchar skp jmp .-3 - lac d2 " drain tty output buffer? + lac d2 " drain tty output buffer? jms getchar skp jmp .-3 - lac sfiles+0 " wake ttyin sleepers + lac sfiles+0 " wake ttyin sleepers jms wakeup dac sfiles+0 - lac sfiles+1 " wake ttyout sleepers + lac sfiles+1 " wake ttyout sleepers jms wakeup dac sfiles+1 - jms chkint " check if user interrupted - jmp piret " no, return from PI - jmp 1f " yes: return thru system call code (dump core) -intrp2: " here with display interrupt character - lac d7 " get keyboard special device number - dac .int2 " save as interrupt source - lac d3 " drain keyboard buffer? + jms chkint " check if user interrupted + jmp piret " no, return from PI + jmp 1f " yes: return thru system call code (dump core) +intrp2: " here with display interrupt character + lac d7 " get keyboard special device number + dac .int2 " save as interrupt source + lac d3 " drain keyboard buffer? jms getchar skp jmp .-3 - lac sfiles+2 " wake up any "keyboard" sleepers + lac sfiles+2 " wake up any "keyboard" sleepers jms wakeup dac sfiles+2 - lac sfiles+6 " wake up any "display" sleepers + lac sfiles+6 " wake up any "display" sleepers jms wakeup dac sfiles+6 - jms chkint " check if user interrupted - jmp piret " no, return from PI + jms chkint " check if user interrupted + jmp piret " no, return from PI 1: - lac 0 " get interrupt PC - dac 020 " save as system call return PC - lac .ac " restore AC from interrupt - jmp 021 " join system call processing (dump core?) + lac 0 " get interrupt PC + dac 020 " save as system call return PC + lac .ac " restore AC from interrupt + jmp 021 " join system call processing (dump core?) diff --git a/src/sys/s8.s b/src/sys/s8.s index 4cf8fb4..0d84bf9 100644 --- a/src/sys/s8.s +++ b/src/sys/s8.s @@ -95,28 +95,30 @@ 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 " X-Y: invisible, no delay, Y=01740 (992) " X-Y: invisible, settling delay, X=0 .=.+30 + " Kernel startup (reused for display buffer) coldentry: dzm 0100 " not re-entrant caf " clear all flags @@ -145,29 +147,30 @@ edskbsp: . uquant: .=.+1 " number of ticks user has been running dspbufp: .=.+1 " pointer to display buffer pbsflgs: .=.+2 " buttons on last tick, last button interrupt -mode: .=.+1 +mode: .=.+1 " user access mode: 1 for write, 2 for read nttychar: .=.+1 " CR to send next, or zero -npptchar: .=.+1 +npptchar: .=.+1 " saved PTR char ttydelay: .=.+1 " delay count for TTY output -name: .=.+4 -lnkaddr: .=.+1 -char: .=.+1 -dskaddr: .=.+1 +name: .=.+4 " file name for current sys call +lnkaddr: .=.+1 " temp for character queue routines +char: .=.+1 " current char: temp for PI +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 @@ -176,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 @@ -187,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 @@ -242,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 diff --git a/tools/as7 b/tools/as7 index 6735b8c..a2fb1a0 100755 --- a/tools/as7 +++ b/tools/as7 @@ -342,7 +342,7 @@ sub parse_line { print "parse_line: '$line'\n" if ($debug); - while ($line =~ s{^([a-z0-9\.]+):\s*}{}) { # labels + while ($line =~ s{^([A-Za-z0-9\.]+):\s*}{}) { # labels process_label($1); } @@ -440,7 +440,7 @@ sub parse_expression { print "\tfound >x\n" if ($debug); $syllable = ord($1) # absolute } - elsif ($line =~ s{^([a-z\.][a-z0-9\.]*)}{}) { + elsif ($line =~ s{^([A-Za-z\.][A-Za-z0-9\.]*)}{}) { my $sym = $1; print "\tsym: $sym\n" if ($debug); if (defined($Var{$sym})) {