This commit is contained in:
Warren Toomey
2017-01-22 23:49:47 +10:00
19 changed files with 594 additions and 454 deletions
+7
View File
@@ -14,3 +14,10 @@ altrun: buildit
clean: clean:
cd build && $(MAKE) 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/
+2 -8
View File
@@ -49,15 +49,9 @@ Press `ctl-e` to break out the simulator into simh
### Precompiled Binaries ### 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/; pdp7 unixv0.simh`
`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`
### Typical Output ### Typical Output
+1
View File
@@ -0,0 +1 @@
¸€‚¸›‚¸¹¡¿€¸¹”½€€¸¹¢‘€¦¶‡ˆ•€¤¸¹„‘€¢¸¹¤¸¹‘±€¸¹š¼‰€¼€ ¿°€¸¹”‘€£¸¹¢‘€¦¶‡ˆ•€¥¸¹„‘€¢¸¹¤¸¹‘±€œ¸¹š¼‰€¼€ °€€€€°€˜€€˜ˆ€€€±€À
BIN
View File
Binary file not shown.
+31
View File
@@ -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
+18 -24
View File
@@ -112,7 +112,7 @@ jmp start
isz sp isz sp
jmp fetch jmp fetch
.getchr: .+1 .getchar: .+1
s 2 s 2
n 8 n 8
n 7 n 7
@@ -125,7 +125,7 @@ jmp start
isz sp isz sp
jmp fetch jmp fetch
.putchr: .+1 .putchar: .+1
s 2 s 2
n 8 n 8
n 7 n 7
@@ -230,29 +230,23 @@ flush: 0
jmp flush i jmp flush i
initio: 0 initio: 0
law .argv " build argument list
dac 8 " auto-inc pointer argvp = &argv[-1]
lac 017777 i lac 017777 i
" sad d4 cll rtr
jmp 2f dac 8 i " *++argvp = arg count
sad d8 cma
jmp 1f tad d1
dac t1 " count = -argv[0]
law 9 lac 017777
tad 017777 dac lastv " set top of heap
dac .+3 tad d1 " ac = addr of arg0
law 017
sys creat; ..
spa
jmp stop
dac .fout
1: 1:
law 5 dac 8 i " *++argvp = ac
tad 017777 tad d4 " ac += 4
dac .+2 isz t1 " while ++count != 0
sys open; ..; 0 jmp 1b
spa
jmp stop
dac .fin
2:
lac lastv lac lastv
dac eibufp dac eibufp
dac cibufp dac cibufp
@@ -280,7 +274,7 @@ iflg: 0
eobufp: 0 eobufp: 0
cobufp: 0 cobufp: 0
oflg: 0 oflg: 0
lastv: 017770 lastv: 0
o777: 0777 o777: 0777
d4:o4: 4 d4:o4: 4
+30 -37
View File
@@ -8,36 +8,28 @@ char(s, n) {
lchar(s, n, c) { lchar(s, n, c) {
if (n & 1) s[n/2] = (s[n/2] & 0777000) | c; if (n & 1) s[n/2] = (s[n/2] & 0777000) | c;
else s[n/2] = (s[n/2] & 0777) | (c*512); else s[n/2] = (s[n/2] & 0777) | (c*512);
return(c);
} }
putstr(s) { putnum(n, b) {
auto c, i; auto a, d;
i = 0; d = 0;
while ((c = char(s,i)) != '*e') { if (n < 0) {
putchr(c); n = -n;
i = i+1; if (n < 0) {
n = n-1;
d = 1;
} else
putchar('-');
} }
} if (a = n/b)
putnum(a, b);
putnum(n) { putchar(n%b + '0' + d);
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');
} }
printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9) { printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9) {
auto adx, c, i; auto adx, a, c, i, n;
i = 0; i = 0;
adx = &x1; adx = &x1;
@@ -45,25 +37,26 @@ loop:
while ((c = char(fmt, i)) != '%') { while ((c = char(fmt, i)) != '%') {
if (c == '*e') if (c == '*e')
return; return;
putchr(c); putchar(c);
i = i+1; i = i+1;
} }
i = i+1; i = i+1;
a = *adx;
c = char(fmt, i); c = char(fmt, i);
if (c=='d') { if (c=='d')
if (*adx < 0) { putnum(a, 10);
putchr('-'); else if (c=='o')
*adx = -*adx; putnum(a, 8);
}
putnum(*adx);
} else if (c=='o')
octal(*adx);
else if (c=='c') else if (c=='c')
putchr(*adx); putchar(a);
else if (c=='s') else if (c=='s') {
putstr(*adx); n = 0;
else { while ((c = char(a, n)) != '*e') {
putchr('%'); putchar(c);
n = n+1;
}
} else {
putchar('%');
goto loop; goto loop;
} }
i = i+1; i = i+1;
+9
View File
@@ -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');
}
+58
View File
@@ -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);
}
+29 -2
View File
@@ -7,14 +7,41 @@
perl a7out test.out 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 { main {
extrn fname, fin; extrn fname, fin, fout, argv;
auto ch,p; auto ch,p,n,str 5;
p = 017777; p = 017777;
printf("mem[0%o] = 0%o*n",p,*p); printf("mem[0%o] = 0%o*n",p,*p);
printf("mem[0%o] = %d*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(fname, 0); */
fin = open("abc ", 0); fin = open("abc ", 0);
+4 -4
View File
@@ -65,7 +65,7 @@ sysexit: " common system call exit code
1: 1:
dzm .insys " clear "in system call" flag dzm .insys " clear "in system call" flag
jms chkint " pending user interrupt? jms chkint " pending user interrupt?
skp " no skp " no, return to user
jmp .save " yes: dump core jmp .save " yes: dump core
jms copy; u.rq+2; 10; 6 " restore auto-index locations 10-15 jms copy; u.rq+2; 10; 6 " restore auto-index locations 10-15
lac u.rq+1 " restore auto-index location 9 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 lac u.ac " restore AC register
jmp u.rq+8 i " return to user jmp u.rq+8 i " return to user
" scheduler / idle loop " scheduler / swapper / idle loop
swap: 0 swap: 0
ion ion
1: 1:
@@ -176,8 +176,8 @@ locn:
" call: " call:
" .insys/ 0 " .insys/ 0
" jms chkint " jms chkint
" no: no interrupt, or intflg set (discards interrupt) " <already ".insys", no interrupt, or intflg set (ignore interrupt)>
" yes: PI off, .insys set " <found user interrupt: PI off, .insys set>
chkint: 0 chkint: 0
lac .insys lac .insys
sza " in system? sza " in system?
+1 -1
View File
@@ -216,7 +216,7 @@
sza " zero (read) sza " zero (read)
lac d1 " no: get write mode bit lac d1 " no: get write mode bit
sna " non-zero (write)? sna " non-zero (write)?
lac d2 " no: get read mode bot lac d2 " no: get read mode bit
dac mode " save for access call dac mode " save for access call
lac u.cdir " get current working directory lac u.cdir " get current working directory
jms namei; 0:0 " search for file jms namei; 0:0 " search for file
+3 -3
View File
@@ -330,9 +330,9 @@ rppti:
jmp .+3 jmp .+3
alss 9 alss 9
jmp passone jmp passone
lac sfiles+3 lac sfiles+3 " get sleep word
sma sma " high bit set?
rsa rsa " no: reader select alphanumeric mode
1: 1:
jms sleep; sfiles+3 jms sleep; sfiles+3
jms swap jms swap
+113 -99
View File
@@ -3,60 +3,61 @@
" allocate a free disk block for a file (data or indirect) " allocate a free disk block for a file (data or indirect)
alloc: 0 alloc: 0
-1 " Decrement the # free block numbers in the cache -1 " decrement the count
tad s.nfblks " kept at s.fblks. Jump to 1f if no free blocks left. tad s.nfblks " of free blocks at s.fblks
spa spa " any left?
jmp 1f jmp 1f " no
dac s.nfblks " Update the count of free block numbers dac s.nfblks " Update the count of free block numbers
tad fblksp tad fblksp " get pointer to last valid entry in s.fblks
jms laci jms laci " fetch the word
dac 9f+t dac 9f+t " save in t0
jms copyz; dskbuf; 64 jms copyz; dskbuf; 64 " zero dskbuf
lac 9f+t lac 9f+t " get block number back
jms dskwr jms dskwr " write out the zeros
dzm .savblk dzm .savblk " cancel system block write
lac 9f+t lac 9f+t " get the block number back
jmp alloc i " Return from routine jmp alloc i " Return from routine
1: 1:
lac s.nxfblk lac s.nxfblk " next block with list of free blocks
sna sna " any?
jms halt " OUT OF DISK jms halt " OUT OF DISK
dac s.fblks dac s.fblks " save as first free block #
jms dskrd jms dskrd " read the block
lac dskbuf lac dskbuf " get first word (pointer to next in chain)
dac s.nxfblk dac s.nxfblk " save as new "next"
jms copy; dskbuf+1; s.fblks+1; 9 jms copy; dskbuf+1; s.fblks+1; 9 " copy remaining 9 as free
lac d10 lac d10 " reset free count
dac s.nfblks dac s.nfblks
jmp alloc+1 jmp alloc+1
" free the disk block whose number is in AC " free the disk block whose number is in AC
free: 0 free: 0
lmq lmq " save block in MQ
lac s.nfblks lac s.nfblks " get number of free blocks
sad d10 sad d10 " 10?
jmp 1f jmp 1f " yes
tad fblksp tad fblksp " no: get addr in s.fblks to store new block in
dac 9f+t dac 9f+t " save pointer
lacq lacq " get block number
dac 9f+t i dac 9f+t i " save it in s.fblks
dzm .savblk dzm .savblk " cancel system block write
isz s.nfblks isz s.nfblks " increment free count
jmp free i jmp free i " return
1: 1:
lac s.nxfblk lac s.nxfblk " get head of free chain
dac dskbuf dac dskbuf " save (as chain ptr) in first word of disk buf
jms copy; s.fblks+1; dskbuf+1; 9 jms copy; s.fblks+1; dskbuf+1; 9 " with 9 of the 10 free blocks
lacq lacq " get the newly freed block back
dac s.nxfblk dac s.nxfblk " save as new head of free chain
jms dskwr jms dskwr " write dskbuf to the newly freed block
dzm .savblk dzm .savblk " cancel system block write
lac d1 lac d1 " reset free count to one
dac s.nfblks dac s.nfblks " (the first word in s.fblks)
jmp free i " Return from the routine jmp free i " Return from the routine
t = t+1 t = t+1
" load AC indirect (without using indirect!) " load AC indirect (without using indirect!)
" need to avoid use of indirect in interrupt service routines
" AC/ address " AC/ address
" jms laci " jms laci
" AC/ contents of address " AC/ contents of address
@@ -141,92 +142,105 @@ copyz: 0
jmp copyz i " return jmp copyz i " return
t = t+1 t = t+1
" put queued character " Character queue management routines
" CALLED FROM PI: AVOIDS INDIRECT!! " (CALLED FROM PI: USE OF INDIRECT AVOIDED!)
" 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
" get queued character " Queue numbers:
" CALLED FROM PI: AVOIDS INDIRECT!! " 0: free list
" queue number in AC:
" 1: tty input " 1: tty input
" 2: tty output " 2: tty output
" 3: display keyboard " 3: display keyboard
" 4: paper tape reader " 4: paper tape reader
" 5: paper tape punch " 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 jms takeq
jmp i getchar jmp putchar i " none free: return w/o skip
tad o200001 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 dac .+3
cla cla
jms putq jms putq " put qentry on free list
lac q2+1 .. lac q2+1 .. " fetch queued character(!!!)
isz getchar isz getchar " give skip return
jmp i getchar 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 takeq: 0
rcl rcl " multiply queue number by two
tad lacq1 tad lacq1 " add "lac q1"
dac .+7 dac .+7
tad o640000 tad o640000 " turn "lac" into "dac"
dac .+17 dac .+17
tad d1 tad d1 " increment addr
dac .+14 dac .+14
tad o500000 tad o500000 " turn "dac" into "sad"
dac .+5 dac .+5
lac q1 .. lac q1 .. " load queue head
sna sna " non-zero?
jmp takeq i jmp takeq i " no: return zero w/o skip
dac lnkaddr dac lnkaddr
sad q1+1 .. sad q1+1 .. " different from tail(??)
jmp .+5 jmp .+5 " no -- (last entry?)
tad o200000 tad o200000 " yes: turn into lac
dac .+1 dac .+1 " save lac
lac q2 .. lac q2 .. " get next pointer from queue entry
jmp .+3 jmp .+3
cla cla " here with head == tail(??)
dac q1+1 .. dac q1+1 .. " clear tail
dac q1 .. dac q1 .. " save (clear) head
isz takeq isz takeq " give skip return
lac lnkaddr lac lnkaddr " return queue entry pointer
jmp i takeq jmp i takeq
" save queue entry (at lnkaddr) to a queue (queue number in AC)
putq: 0 putq: 0
rcl rcl " multiply by two
tad dacq1 tad dacq1 " turn into "dac qhead"
dac .+14 dac .+14
tad d1 tad d1 " turn into "dac qtail"
dac .+13 dac .+13
tad o140000 tad o140000 " turn into "lac qtail"
dac .+1 dac .+1
lac q1-1 .. lac q1-1 .. " fetch tail
"** 01-s1.pdf page 24 "** 01-s1.pdf page 24
sna sna " non-zero?
jmp .+6 jmp .+6 " no: is zero
tad o40000 tad o40000 " turn into "dac qentry" (append to queue)
dac .+2 dac .+2
lac lnkaddr lac lnkaddr " get new entry
dac q2 .. dac q2 .. " append to tail entry
jmp .+3 jmp .+3
lac lnkaddr lac lnkaddr " here with tail == 0
dac q1 .. dac q1 .. " save new entry as head
dac q1+1 .. dac q1+1 .. " save new tail
jmp putq i jmp putq i
" NOTE!! srcdbs, collaps, dskrd, dskwr share the same "temp" vars: " NOTE!! srcdbs, collaps, dskrd, dskwr share the same "temp" vars:
+4 -4
View File
@@ -248,13 +248,13 @@ dspinit: 0
jmp dspinit i jmp dspinit i
" "move display" (change display buffer pointer) " "move display" (change display buffer pointer)
" called with new buffer pointer in AC?? " called with new buffer pointer in AC
movdsp: 0 movdsp: 0
iof iof
cdf cdf " clear display flags (stop)
dac dspbufp dac dspbufp " save display buf pointer
-1 -1
dac .dspb dac .dspb " .dspb = -1
ion ion
jmp movdsp i jmp movdsp i
+63 -55
View File
@@ -99,6 +99,8 @@ namei: 0
jmp 1b " yes: keep going jmp 1b " yes: keep going
jmp namei i " Didn't find it, return zero in AC (without skip) jmp namei i " Didn't find it, return zero in AC (without skip)
t = t+2 t = t+2
" NOTE: iget/iput share "temp" vars!!!
" Given an i-number in AC, fetch that i-node " Given an i-number in AC, fetch that i-node
" from disk and store it in the inode buffer " from disk and store it in the inode buffer
iget: 0 iget: 0
@@ -113,49 +115,50 @@ iget: 0
cll; mul; 12 " Multiply the i-num within the block by 12 cll; mul; 12 " Multiply the i-num within the block by 12
lacq " to get the offset into the block lacq " to get the offset into the block
tad dskbufp " Add on the base of the disk buffer tad dskbufp " Add on the base of the disk buffer
dac 9f+t dac 9f+t " save pointer into dskbuf in "t0"
dac .+2 dac .+2
jms copy; ..; inode; 12 " Copy 12 words from buffer to inode jms copy; ..; inode; 12 " Copy 12 words from buffer to inode
jmp iget i " and return jmp iget i " and return
iput: 0 iput: 0
lac 9f+t+1 lac 9f+t+1 " get block number saved by iget
jms dskrd jms dskrd " read the block
law inode-1 law inode-1 " pointer to "in core" inode
dac 8 dac 8 " in index 8
-1 -1
tad 9f+t tad 9f+t " get saved pointer into buffer
dac 9 dac 9 " in index 9
-12 -12 " 12 word loop count
dac 9f+t+2 dac 9f+t+2 " in t2
1: 1:
lac 8 i lac 8 i " fetch source word
"** 01-s1.pdf page 36 "** 01-s1.pdf page 36
sad 9 i sad 9 i " differs from disk?
skp skp " no:
jmp 2f jmp 2f " yes:
isz 9f+t+2 isz 9f+t+2 " no difference: done?
jmp 1b jmp 1b " no: keep going
jmp iput i jmp iput i " yes: return w/o writing to disk
2: 2: " here with in-core inode changed
-1 -1 " back up both pointers
tad 8 tad 8
dac 8 dac 8
-1 -1
tad 9 tad 9
dac 9 dac 9
1: 1:
lac 8 i lac 8 i " fetch word
dac 9 i dac 9 i " copy to dskbuf
isz 9f+t+2 isz 9f+t+2 " done?
jmp 1b jmp 1b " no: keep going
lac 9f+t+1 lac 9f+t+1 " get block number
jms dskwr jms dskwr " write back to disk
jmp iput i jmp iput i " return
t = t+3 t = t+3
" NOTE! dget/dput share "temp" vars
" allocate directory entry " allocate directory entry
" AC/ entry number " AC/ entry number
dget: 0 dget: 0
@@ -164,30 +167,31 @@ dget: 0
dac 9f+t " save in t0 dac 9f+t " save in t0
jms pget " get free disk block jms pget " get free disk block
dac 9f+t+1 " save in t1 dac 9f+t+1 " save in t1
jms dskrd jms dskrd " read block
lac 9f+t lac 9f+t " get word number
and o77 and o77 " get word within block
tad dskbufp tad dskbufp " make pointer into dskbuf
dac 9f+t+2 dac 9f+t+2 " save in t2
dac .+2 dac .+2 " save as copy source
jms copy; ..; dnode; 8 jms copy; ..; dnode; 8 " copy entry into dnode
lac 9f+t lac 9f+t " get word number
tad d8 tad d8 " of end of new node
jms betwen; d0; i.size jms betwen; d0; i.size " already allocated?
skp skp " no
jmp dget i jmp dget i " yes: return
jms dacisize jms dacisize " store new file size
dzm d.i dzm d.i " mark new entry as free
jmp dget i jmp dget i " return
" write directory entry (back) to disk
dput: 0 dput: 0
lac 9f+t+1 lac 9f+t+1 " get disk block number back
jms dskrd jms dskrd " read into dskbuf
lac 9f+t+2 lac 9f+t+2 " get pointer into dskbuf
dac .+3 dac .+3 " save as copy dest
jms copy; dnode; ..; 8 jms copy; dnode; ..; 8 " copy into dskbuf
lac 9f+t+1 lac 9f+t+1 " get disk block number
jms dskwr jms dskwr " write back to disk
jmp dput i jmp dput i
t = t+3 t = t+3
@@ -262,6 +266,10 @@ pget: 0
jmp pget i " return it jmp pget i " return it
t = t+3 t = t+3
" write to file referenced by loaded inode
" AC/ file offset
" jms iwrite; addr; count
iwrite: 0 iwrite: 0
dac 9f+t " save arg in t0 dac 9f+t " save arg in t0
lac iwrite " load return address lac iwrite " load return address
@@ -273,14 +281,14 @@ iwrite: 0
dac iwrite " save as iwrite instruction dac iwrite " save as iwrite instruction
jmp 1f jmp 1f
" iread from file referenced by loaded inode " read from file referenced by loaded inode
" AC/ file offset " AC/ file offset
" jms iread; addr; count " jms iread; addr; count
iread: 0 iread: 0
dac 9f+t " save offset in t0 dac 9f+t " save offset in t0
lac cnop " get nop lac cnop " get nop
dac iwrite " save as iwrite instruction dac iwrite " save as iwrite instruction
1: 1: " common code for iread/iwrite
-1 -1
tad iread i " get word before return addr tad iread i " get word before return addr
dac 10 " store in index 10 & 11 dac 10 " store in index 10 & 11
@@ -289,7 +297,7 @@ iread: 0
lac iread i " load addr lac iread i " load addr
dac 9f+t+1 " save in t1 dac 9f+t+1 " save in t1
isz iread " increment return addr isz iread " increment return addr
lac o70000 lac o70000 " get max file size
xct iwrite " skip if write xct iwrite " skip if write
lac i.size " read: get file size lac i.size " read: get file size
cma cma
@@ -299,10 +307,10 @@ iread: 0
lac 9f+t+1 lac 9f+t+1
dac 9f+t+2 dac 9f+t+2
cma cma
tad d1 tad d1 " subtract offset
sna sna " offset == size?
jmp iread i jmp iread i " yes, return
dac 9f+t+1 dac 9f+t+1 " save size-offset in t1
1: 1:
lac 9f+t lac 9f+t
jms pget jms pget
@@ -312,7 +320,7 @@ iread: 0
and o77 and o77
tad dskbufp tad dskbufp
tad dm1 tad dm1
xct iwrite xct iwrite " skip if write
jmp .+3 jmp .+3
dac 10 dac 10
cskp: cskp:
+53 -52
View File
@@ -4,25 +4,25 @@
pibreak: " priority interrupt break processing "chain" pibreak: " priority interrupt break processing "chain"
dac .ac " save interrupt AC dac .ac " save interrupt AC
"** CROSSED OUT.... "** CROSSED OUT....
dpsf dpsf " skip on data phone flag set
jmp 1f " disable the Graphics-2 I/O jmp 1f " not set: check next device
dpcf dpcf " clear dataphone flag
dprs dprs " read dataphone status
dac dpstat dac dpstat " save for user
sma ral sma ral " REC FLG set? rotate flags left
jmp 2f jmp 2f " no
dprc dprc " read char (bit zero set if parity correct)
dac dpchar dac dpchar " save for user
-1 -1
dac dpread dac dpread " dpread = -1
lac dpstat lac dpstat " get status back
ral ral " rotate up
2: 2:
sma sma " XMIT FLG set?
jmp piret jmp piret " no: return from interrupt
-1 -1
dac dpwrite dac dpwrite " dpwrite = -1
jmp piret "** END OF CROSSOUT jmp piret "** END OF CROSSOUT
1: clsf " clock overflow (line frequency ticks)? 1: clsf " clock overflow (line frequency ticks)?
@@ -40,7 +40,7 @@ pibreak: " priority interrupt break processing "chain"
cnop: " fetched as constant in iread cnop: " fetched as constant in iread
nop nop
-1 -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 clon " enable clock interrupts, reset flag
lac ttydelay " tty delay positive? lac ttydelay " tty delay positive?
spa " yes: skip to skp spa " yes: skip to skp
@@ -49,16 +49,17 @@ cnop: " fetched as constant in iread
jms ttyrestart " yes: start output jms ttyrestart " yes: start output
"** START CROSSED OUT: written: lac tty "** START CROSSED OUT: written: lac tty
lac .dspb lac .dspb
sna sna " .dspb != 0?
jmp piret jmp piret " no: return
isz .dsptm isz .dsptm " increment .dsptm; is zero?
skp skp " no
jmp dsprestart jmp dsprestart " yes: restart display
sad d3 sad d3 " .dspb == 3?
jmp piret jmp piret " yes: return
isz .dspb isz .dspb " increment .dspb; is zero?
jmp piret jmp piret " no: return from interrupt
jmp dsprestart "** END CROSSED OUT jmp dsprestart " yes: restart display
"** END CROSSED OUT
1: dssf " disk flag set? 1: dssf " disk flag set?
jmp 1f " no jmp 1f " no
@@ -192,21 +193,21 @@ ttyrestart: 0
dac sfiles+2 dac sfiles+2
jmp piret jmp piret
1: rsf " paper tape ready? 1: rsf " paper tape reader ready?
jmp 1f " no jmp 1f " no
"** 01-s1.pdf page 44 "** 01-s1.pdf page 44
lac npptchar lac npptchar
sna sna " have saved char?
jmp .+5 jmp .+5 " no: jump to second rrb
dac char dac char " yes: save as current char
rrb rrb " clear flag, read reader buffer
dac npptchar dac npptchar " save as saved char
jmp .+3 jmp .+3
rrb rrb " here without saved char: read new
dac char dac char " save as current
3: 3:
lac char lac char
sna sna
@@ -218,16 +219,16 @@ ttyrestart: 0
sad d4 sad d4
jmp 4f jmp 4f
2: 2:
lac npptchar lac npptchar " get saved char (if any)
sna sna " had saved char?
jmp .+4 jmp .+4 " no: wake up writer
dac char dac char " yes: save as char to send
dzm npptchar dzm npptchar " clear saved char
jmp 3b jmp 3b
rsa rsa " reader select alphanumeric mode
lac sfiles+3 lac sfiles+3
jms wakeup jms wakeup " wake sleepers; returns zero
xor o400000 xor o400000 " set high bit (rsa before sleep)
dac sfiles+3 dac sfiles+3
jmp piret jmp piret
3: 3:
@@ -239,19 +240,19 @@ ttyrestart: 0
dac sfiles+3 dac sfiles+3
jmp piret jmp piret
1: psf " paper tape ready? 1: psf " paper tape punch ready?
jmp 1f " no jmp 1f " no
pcf " clear ptp flag pcf " clear ptp flag
lac d5 lac d5
jms getchar " get next char jms getchar " get next char
jmp .+3 jmp .+3 " none: wake sleepers
psa psa " punch set alphanumeric mode
jmp piret jmp piret " return from interrupt
lac sfiles+4 lac sfiles+4 " get sleeper bit vector
jms wakeup jms wakeup " wake them
dac sfiles+4 dac sfiles+4 " store zero
jmp piret jmp piret " return from PI
"** BEGIN CROSSED OUT "** BEGIN CROSSED OUT
1: spb " any graphic-2 push button? 1: spb " any graphic-2 push button?
@@ -286,7 +287,7 @@ ttyrestart: 0
1: crrb " read card reader buffer?? 1: crrb " read card reader buffer??
piret: " return from priority interrupt piret: " return from priority interrupt
lac 0 " get LINK/PC lac 0 " get LINK (in bit 0)
ral " restore LINK ral " restore LINK
lac .ac " restore AC lac .ac " restore AC
ion " reenable interrupts ion " reenable interrupts
@@ -327,7 +328,7 @@ wakeup: 0
jmp wakeup i jmp wakeup i
t = t+2 t = t+2
" call to output CR after LF (NL) " call to output CR after LF (NL) on TTY
putcr: 0 putcr: 0
lac o15 lac o15
dac nttychar dac nttychar
+21 -18
View File
@@ -95,28 +95,30 @@ dm1: -1
9: .=.+t " per-routine temp variables 9: .=.+t " per-routine temp variables
c1: .=.+1 " not used? c1: .=.+1 " not used?
q1: q2;q2+98 " ** 90? 96?? " queue element free list? " character queues (two words each, head and tail pointers?)
.=.+14 " 0: free list
" queues (two words each, head and tail pointers?)
" 1: tty input " 1: tty input
" 2: tty output " 2: tty output
" 3: display keyboard " 3: display keyboard
" 4: paper tape reader " 4: paper tape reader
" 5: paper tape punch " 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;.+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 .+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;.+2;0;0;0
dsploc: .=.+1 dsploc: .=.+1 " pointer into dspbuf
dsplno: .=.+1 dsplno: .=.+1 " display current line number
dspbuf: dspbuf:
0065057;0147740;0160000 " display commands: see 03-scope.pdf pg 20 0065057;0147740;0160000 " display commands: see 03-scope.pdf pg 20
" PARAM: clear blink, clear light pen, scale=1, intensity=3 " PARAM: clear blink, clear light pen, scale=1, intensity=3
" X-Y: invisible, no delay, Y=01740 (992) " X-Y: invisible, no delay, Y=01740 (992)
" X-Y: invisible, settling delay, X=0 " X-Y: invisible, settling delay, X=0
.=.+30 .=.+30
" Kernel startup (reused for display buffer)
coldentry: coldentry:
dzm 0100 " not re-entrant dzm 0100 " not re-entrant
caf " clear all flags caf " clear all flags
@@ -145,29 +147,30 @@ edskbsp: .
uquant: .=.+1 " number of ticks user has been running uquant: .=.+1 " number of ticks user has been running
dspbufp: .=.+1 " pointer to display buffer dspbufp: .=.+1 " pointer to display buffer
pbsflgs: .=.+2 " buttons on last tick, last button interrupt 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 nttychar: .=.+1 " CR to send next, or zero
npptchar: .=.+1 npptchar: .=.+1 " saved PTR char
ttydelay: .=.+1 " delay count for TTY output ttydelay: .=.+1 " delay count for TTY output
name: .=.+4 name: .=.+4 " file name for current sys call
lnkaddr: .=.+1 lnkaddr: .=.+1 " temp for character queue routines
char: .=.+1 char: .=.+1 " current char: temp for PI
dskaddr: .=.+1 dskaddr: .=.+1 " number of block in dskbuf
uniqpid: 1 " pid generator uniqpid: 1 " pid generator
lu: .=.+4 " user (process) table entry copy lu: .=.+4 " user (process) table entry copy
sfiles: .=.+10 " wait addresses for special files 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, " offsets: 0: ttyin, 1: ttyout, 2: keyboard,
" 3: ptr, 4: ptp, 6: display " 3: ptr, 4: ptp, 6: display
dpdata: dpdata: " dataphone data
dpstat: .=.+1 dpstat: .=.+1
dpread: .=.+1 dpread: .=.+1
dpwrite: .=.+1 dpwrite: .=.+1
dpchar: .=.+1 dpchar: .=.+1
dspdata: dspdata: " display data
.dspb: .=.+1 .dspb: .=.+1
.lpba: .=.+1 "** 4 written on listing .lpba: .=.+1 "** 4 written on listing
crdata: crdata: " card reader data
crread: .=.+1 crread: .=.+1
crchar: .=.+1 crchar: .=.+1
sysdata: " system data 64 words saved to disk 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.fblks: .=.+10 " cached free block numbers
s.uniq: .=.+1 " next unique value s.uniq: .=.+1 " next unique value
s.tim: .=.+2 " (up?)time in 60Hz ticks (low, high) s.tim: .=.+2 " (up?)time in 60Hz ticks (low, high)
" process table " user (process) table
" first word " first word
" bits 0:2 -- status " bits 0:2 -- status
" 0: free slot " 0: free slot
@@ -242,7 +245,7 @@ dnode: " directory entry:
d.name: .=.+4 " name (space padded) d.name: .=.+4 " name (space padded)
d.uniq: .=.+1 " unique number from directory inode d.uniq: .=.+1 " unique number from directory inode
. = dnode+8 . = dnode+8
fnode: " open file entry fnode: " open file entry (copied from u.ofiles)
f.flags: .=.+1 " see below f.flags: .=.+1 " see below
f.badd: .=.+1 " offset f.badd: .=.+1 " offset
f.i: 0 " file i-number f.i: 0 " file i-number
+2 -2
View File
@@ -342,7 +342,7 @@ sub parse_line {
print "parse_line: '$line'\n" if ($debug); 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); process_label($1);
} }
@@ -440,7 +440,7 @@ sub parse_expression {
print "\tfound >x\n" if ($debug); print "\tfound >x\n" if ($debug);
$syllable = ord($1) # absolute $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; my $sym = $1;
print "\tsym: $sym\n" if ($debug); print "\tsym: $sym\n" if ($debug);
if (defined($Var{$sym})) { if (defined($Var{$sym})) {