Merge pull request #15 from philbudne/master

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