From 6e38dad003f36989d72a96f3a31a2d3792e6efb8 Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Tue, 1 Mar 2016 12:37:35 -0500 Subject: [PATCH 1/3] fix sna --- misc/asm_syntax.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/asm_syntax.txt b/misc/asm_syntax.txt index 596f8bc..17ec18e 100644 --- a/misc/asm_syntax.txt +++ b/misc/asm_syntax.txt @@ -225,7 +225,7 @@ bits: sza = 0740200 " OPR: skip on zero AC snl = 0740400 " OPR: skip on non-zero link skp = 0741000 " OPR: skip unconditionally - sna = 0741200 " OPR: skip on negative AC + sna = 0741200 " OPR: skip on non-zero AC szl = 0741400 " OPR: skip on zero link rtl = 0742010 " OPR: rotate two left rtr = 0742020 " OPR: rotate two right @@ -240,8 +240,8 @@ With some limitations, OPR instructions can be OR-ed together. order in the source!!): sna cla " skip on negative AC, clear AC - sna spa " skip on negative or positive AC - sna ral " skip on negative AC, rotate AC left + sna spa " skip on non-zero or positive AC(??) + sna ral " skip on non-zero AC, rotate AC left cla cll sza " skip on AC zero, clear AC, clear LINK The last "operate" instruction is not microcoded: From ed467cdb02a73dee282840fc13aed6db1533d2f4 Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Tue, 1 Mar 2016 15:18:17 -0500 Subject: [PATCH 2/3] more comments --- src/cmd/as.s | 237 ++++++++++++++++++++++++++------------------------- 1 file changed, 120 insertions(+), 117 deletions(-) diff --git a/src/cmd/as.s b/src/cmd/as.s index af36131..ce06006 100644 --- a/src/cmd/as.s +++ b/src/cmd/as.s @@ -1,18 +1,18 @@ "** 05-1-4.pdf page 32 " as - jms init1 " initialize + jms init1 " initialize for pass 1 assm1: lac eofflg sza " saw EOF? - jmp assm2 " no. - lac passno + jmp assm2 " no. + lac passno " yes sza " pass==0? jmp finis " no, pass 2: done - jms init2 " pass 1: init for pass2 + jms init2 " initialize for pass 2 -assm2: +assm2: " main loop jms gchar " get character sad d4 " comma space or tab? jmp assm1 " yes, ignore @@ -41,7 +41,7 @@ assm2: assm3: lac rand sad d2 - jmp assm4 + jmp assm4 " yes sza jmp assm6 lac rator " fetch operator @@ -67,9 +67,9 @@ assm4: lac rand+1 tad d4 dac lvrand - lac rator - sza - jmp assm5 + lac rator " get operator + sza " ':'? + jmp assm5 " no lac dot " load dot type dac r " save as r type lac dot+1 " get dot value @@ -171,13 +171,13 @@ finis: sys close -1 tad namsiz - cma - rcl + cma " get positive count of namelist entries + rcl " multiply by 6 to get words dac char rcl tad char dac 1f - lac o17 + lac o17 " ?? creat mode bits?? sys creat; n.out " create "n.out" dac bfi sys write; namlst; 1: 0 " write name list @@ -197,16 +197,16 @@ process: 0 jmp proc4 " no, give "." error sza " zero? jmp proc1 " no - -1 - tad cmflx+1 " '..' - 1 + -1 " yes (".." type) + tad cmflx+1 cma - tad lvrand + tad lvrand " get "." - ".." dac lvrand proc1: lac lvrand - spa - jmp proc4 + spa " is relocated value positive? + jmp proc4 " no, give "." error and o17700 " mask to block sad bufadd " same block as buffer? jmp proc2 " yes, same block @@ -224,25 +224,25 @@ proc1: sys read; buf; 64 proc2: - lac lvrand - and o77 " get word within block - jms betwen; dm1; maxsto - dac maxsto - tad bufp - dac lvrand - lac r - sna - jmp proc3 - sad d3 - jmp proc5 + lac lvrand " destination address + and o77 " word within block + jms betwen; dm1; maxsto " inside buffer? + dac maxsto " no, increment buffer size + tad bufp " add pointer to buffer + dac lvrand " save buffer pointer + lac r " get r type? + sna " non-zero ("." or label)? + jmp proc3 " no: zero (..) + sad d3 " three (user label)? + jmp proc5 " yes lac cmflx+1 " get ".." value - tad r+1 + tad r+1 " add to r value dac r+1 proc3: - lac r+1 - dac i lvrand - jmp i process + lac r+1 " get r value + dac i lvrand " save in buffer + jmp i process " return proc4: jms error; .> @@ -266,18 +266,18 @@ bufwr: 0 " write current buffer to a.out file dac maxsto jmp i bufwr -number: 0 " print decimal number? - dac 3f +number: 0 " print decimal number: append to buffer at index 8 + dac 3f " save number lac d1000 - dac 2f + dac 2f " save divisor 1: lac 3f cll idiv; 2: 0 dac 3f lacq - tad o60 - dac i 8 + tad o60 " add ascii '0' + dac i 8 " save char lac 2b cll idiv; 10 @@ -288,17 +288,18 @@ number: 0 " print decimal number? jmp i number 3: 0 - " get character from buffer + " get character from buffer (two characters per word) " call with: " jms getsc; pointer_pointer - " where pointer_pointer contains a pointer to buffer + " where pointer_pointer refers to a pointer to buffer + " high bit in pointer indicates low char is next getsc: 0 lac i getsc " get pointer pointer dac sctalp " save isz getsc " skip pointer pointer lac i sctalp " fetch pointer dac sctal " save - add o400000 " toggle high bit of pointer + add o400000 " toggle high bit, increment on wrap dac i sctalp " save pointer back ral " rotate high bit into link reg lac i sctal " load word from buffer @@ -308,7 +309,7 @@ getsc: 0 jmp i getsc " return " save characters: word after call is addr of pointer, -count pair - " high bit in pointer used to indicate high or low byte next? + " high bit in pointer used to indicate high/low putsc: 0 and o177 " strip character to 7 bits lmq " save in MQ @@ -318,7 +319,7 @@ putsc: 0 "** 05-1-4.pdf page 37 lac i sctalp " get pointer dac sctal " save - add o400000 " toggle sign bit by adding -0 + add o400000 " toggle pointer sign bit, increment on wrap dac i sctalp " save pointer sma cla " skip if minus & clear AC jmp 1f " AC positive @@ -329,7 +330,7 @@ putsc: 0 1: lac i sctal " load target word - omq " or in char from MQ + omq " or in low char from MQ dac i sctal " save word back lacq " restore character jmp i putsc " return @@ -400,27 +401,27 @@ error: 0 jmp i error " return 1: -1 - tad mesp - dac 8 - lac i error - dac i 8 - lac o40 - dac i 8 - lac rator - sad d5 - jmp 1f - lac savchr - sad o12 - jmp 1f - lac lineno + tad mesp " get mes-1 + dac 8 " save as index + lac i error " get error + dac i 8 " save in mess + lac o40 " get space + dac i 8 " save in mess + lac rator " get operator + sad d5 " word break (semi, newline)? + jmp 1f " yes + lac savchr " no, get saved char + sad o12 " newline? + jmp 1f " yes + lac lineno " get lineno jmp 2f 1: -1 - tad lineno + tad lineno " get lineno -1 2: - jms number - lac o12 - dac i 8 + jms number " convert line number to ascii + lac o12 " get newline + dac i 8 " append to mess -2 tad mesp cma @@ -591,8 +592,8 @@ lqot: " left quote (<) rqot: " right quote (>) lac namc " get previous(?) char 1: - dac rand+1 - lac d7 + dac rand+1 " save value + lac d7 " return as literal dac rator jmp i gsymb @@ -770,20 +771,20 @@ lu2: namep: name gpair: 0 - jms gsymb + jms gsymb " get a symbol lac rator " get operator sad d4 " space tab or comma? jmp gpair+1 " yes, get another - jms betwen; dm1; d6 " anything but a digit? - jmp gp1 " no-- a digit - dzm rand + jms betwen; dm1; d6 " plus, minus, comma, semi? + jmp gp1 " no + dzm rand " clear "rand" dzm rand+1 - jmp i gpair -gp1: " here with digit - sad d7 - lac d4 - tad dm4 - dac rand + jmp i gpair " return +gp1: + sad d7 " digit?? + lac d4 " yes: switch to space?? + tad dm4 " subtract 4?? + dac rand " save as operand?? jms gsymb lac rator sad d4 " whitespace? @@ -867,13 +868,15 @@ grand: 0 dac rand+1 jmp i grand + " called with + " jms oper; argument oper: 0 tad opsw dac oper1 -1 - tad i oper - dac 8 - isz oper + tad i oper " pick up argument + dac 8 " store as index + isz oper " skip argument lac r sad d3 jmp oper2 @@ -958,10 +961,10 @@ o77: 077 o74: 074 o76: 076 -namsiz: -2 -namlstp: namlst -fnamep: fakename -lactab: lac .+1 " character class table (8 unless noted) +namsiz: -2 " negative numberof namelist entries +namlstp: namlst " pointer to namelist +fnamep: fakename " pointer to fake namelist entry +lactab: lac .+1 " character (operator) class table (8 unless noted) 8;8;8;8;8;8;8;8 8;4;5;8;8;8;8;8 " TAB=4 NL=5 8;8;8;8;8;8;8;8 @@ -979,44 +982,44 @@ lactab: lac .+1 " character class table (8 unless noted) 6;6;6;6;6;6;6;6 6;6;6;8;8;8;8;8 -fbflg: .=.+1 -tal: .=.+1 -talc: .=.+1 -tal1: .=.+1 -tal1c: .=.+1 -narg: .=.+1 -lvrand: .=.+1 -eofflg: .=.+1 -namc: .=.+1 -passno: .=.+1 -char: .=.+1 -savchr: .=.+1 -comflg: .=.+1 -rator: .=.+1 -orator: .=.+1 -rand: .=.+2 -srand: .=.+2 -r: .=.+2 -name: .=.+4 -buf: .=.+64 -iobuf: .=.+64 -fbx: .=.+10 " forward/backward pointers? -mes: .=.+20 -iof: .=.+1 -bfi: .=.+1 -bfo: .=.+1 -lineno: .=.+1 +fbflg: .=.+1 " f/b label flag +tal: .=.+1 " iobuf pointer +talc: .=.+1 " -bytecount-1 +tal1: .=.+1 " namebuf pointer +tal1c: .=.+1 " -bytecount-1 +narg: .=.+1 " argc +lvrand: .=.+1 " numeric constant, word address +eofflg: .=.+1 " 0 on EOF?? +namc: .=.+1 " saved char, temporary +passno: .=.+1 " 0=pass1, 1=pass2 +char: .=.+1 " current character +savchr: .=.+1 " pushed back char +comflg: .=.+1 " comment flag +rator: .=.+1 " (opo)rator (char type) +orator: .=.+1 " ?? (op)orator +rand: .=.+2 " ?? (ope)rand (type/address pair) +srand: .=.+2 " ?? another operand +r: .=.+2 " ?? yet another?? +name: .=.+4 " buffer for accumulating names +buf: .=.+64 " a.out output buffer +iobuf: .=.+64 " input buffer +fbx: .=.+10 " forward/backward counters +mes: .=.+20 " (error) message buffer +iof: .=.+1 " source file fd +bfi: .=.+1 " a.out input fd +bfo: .=.+1 " a.out output fd +lineno: .=.+1 " source file line number -fakename: .=.+6 " dummy entry returned by tlookup?? -namlst: -.=.+4 -dot: " dot type, value -.=.+6 -cmflx: " dotdot type, value - - " first four words of name list are symbol (space padded) +fakename: .=.+6 " dummy namelist entry returned by tlookup?? +namlst: " symbol table +.=.+4 " dot name +dot: " dot type, value +.=.+6 " dot dot name +cmflx: " dotdot type, value + " namelist (symbol table) entries are 6 words. + " four words of symbol (space padded) name " next word is type?? " 0: initial dotdot type - " 1: initial dot type - " 3: set by "lookup" - " last word is value?? \ No newline at end of file + " 1: initial dot type (reset on error) + " 3: set by "lookup" (user symbol) + " last word is value?? From 1bb80f01ec6b6ce62ec59cb669ddd4a6262728e0 Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Tue, 1 Mar 2016 19:30:18 -0500 Subject: [PATCH 3/3] add --output, --namelist, rim output format, always set 0200 on ptp/rim output --- tools/as7 | 73 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/tools/as7 b/tools/as7 index 537c2f1..2ba3f01 100755 --- a/tools/as7 +++ b/tools/as7 @@ -4,7 +4,7 @@ # and convert them into PDP-7 machine code # # (c) 2016 Warren Toomey, GPL3 -# Tweaked by Phil Budne (line, expression parsing, "list", "ptr" formats) +# Tweaked by Phil Budne (line, expression parsing, output formats) # use strict; use warnings; @@ -28,21 +28,26 @@ my $errors = 0; # set to non-zero on error my $line_error = ' '; my $file; # current file name my $lineno; # current line number +my $OUTPUT; # output file + +### Main program ### ## command line options my $debug = 0; # Run in debug mode my $format = 'a7out'; # output format +my $namelist = 0; # output n.out file +my $output = 'a.out'; # output file # keep this near the GetOptions call to make it easy to add documentation! sub usage { - die("Usage: $0 [--debug] [--format=a7out|list|ptr ] file1.s [file2.s ...]\n") + die("Usage: $0 [--debug] [--format=a7out|list|ptr|rim ] [--out file] file1.s [file2.s ...]\n") } -### Main program ### - GetOptions( - 'debug|d' => \$debug, + 'debug|d' => \$debug, 'format|f=s' => \$format, + 'namelist|n' => \$namelist, + 'output|o=s' => \$output, ) or usage(); usage() if ( @ARGV < 1 ); @@ -179,14 +184,17 @@ usage() if ( @ARGV < 1 ); # Parse all the files foreach my $file (@ARGV) { + print STDERR "I $file\n"; # like the real as parse_file($file); } # Now do it all again, pass two $Var{'.'} = 0; $stage = 2; -print("PASS 2\n") if ($debug); +open(my $OUT, ">$output") || die "$output"; + foreach my $file (@ARGV) { + print STDERR "II $file\n"; # like the real as parse_file($file); } @@ -194,33 +202,44 @@ if ($format eq 'a7out') { # print out the contents of memory for my $i ( 0 .. $#Mem ) { if ( defined( $Mem[$i] ) ) { - printf( "%06o: %06o\t%s\n", $i, $Mem[$i], $Mline[$i] || "" ); + printf $OUT "%06o: %06o\t%s\n", $i, $Mem[$i], ($Mline[$i] || ""); } } } elsif ($format eq 'list') { - print "\n"; - print "Labels:\n"; + print $OUT "\n"; + print $OUT "Labels:\n"; foreach my $key (sort keys %Label) { - printf("%-8.8s %#06o\n", $key, $Label{$key}); + printf $OUT "%-8.8s %#06o\n", $key, $Label{$key}; } } elsif ($format eq 'ptr') { # dump absolute memory in PTR binary for my $loc ( 0 .. $#Mem ) { - my $m = $Mem[$loc] || 0; - printf("%c%c%c", ($m >> 12) & 077, ($m >> 6) & 077, $m & 077); + punch($Mem[$loc] || 0); } } +elsif ($format eq 'rim') { # PDP-7 Read In Mode + for my $loc ( 0 .. $#Mem ) { + if (defined($Mem[$loc])) { + punch(0200000 | $loc ); # LAC addr + punch($Mem[$loc] || 0); + } + } + punch($OUT, 0740040 ); # HLT +} else { die("unknown format $format"); } +close($OUT); -# as.s writes a binary file named n.out, ours is ascii -open (my $NOUT, ">n.out") || die "n.out"; -foreach my $key (sort keys %Label) { - printf $NOUT "%-8.8s %#06o\n", $key, $Label{$key}; +if ($namelist) { + # as.s writes a binary file named n.out, ours is ascii + open (my $NOUT, ">", "n.out") || die "n.out"; + foreach my $key (sort keys %Label) { + printf $NOUT "%-8.8s %#06o\n", $key, $Label{$key}; + } + close($NOUT); } -close($NOUT); exit($errors); @@ -234,7 +253,7 @@ sub err { $errors = 1; # exit status if ($stage == 2) { print STDERR "$file:$lineno: $msg\n"; - print "$file:$lineno: $msg\n" if (! -t STDOUT && $format ne 'ptr'); + print $OUT "$file:$lineno: $msg\n" if ($format eq 'list'); } return 0; # expression value } @@ -248,7 +267,8 @@ sub parse_file { $lineno++; chomp($line); # Lose the end of line $origline = $line; - print "\t\t$line\n" if ($stage == 2 && $line ne '' && $format eq 'list'); + print $OUT "\t\t$line\n" + if ($stage == 2 && $line ne '' && $format eq 'list'); parse_line(); } close($IN); @@ -312,7 +332,8 @@ sub parse_line { my $word = parse_expression(); printf( "Setting variable %s to 0%o\n", $lhs, $word ) if ($debug); $Var{$lhs} = $word; - printf("\t%06o %s\n", $word, $line_error) if ($stage == 2 && $format eq 'list'); + printf $OUT "\t%06o %s\n", $word, $line_error + if ($stage == 2 && $format eq 'list'); } else { # bare expression (not assignment) # Get its value on pass two and save to memory @@ -324,7 +345,8 @@ sub parse_line { $Mline[$location] = $origline; $origline = ''; if ($format eq 'list' and defined($word)) { - printf( "%06o: %06o %s\n", $location, $word, $line_error); + printf $OUT "%06o: %06o %s\n", + $location, $word, $line_error; } } # Move up to the next location in both passes @@ -471,3 +493,12 @@ sub find_relative_label { } return err('U', "undefined relative reference $label$direction"); } + +sub punch { # output a word in paper tabe binary format + my $word = shift; + + printf $OUT "%c%c%c", + (($word >> 12) & 077) | 0200, + (($word >> 6) & 077) | 0200, + ($word & 077) | 0200; +}