From bb72a137a55c6b9ccc4a0eb74379c9ad6fad8892 Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 29 Feb 2016 13:38:51 -0500 Subject: [PATCH 1/6] update, extend asm_syntax.txt --- misc/asm_syntax.txt | 277 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 254 insertions(+), 23 deletions(-) diff --git a/misc/asm_syntax.txt b/misc/asm_syntax.txt index 6e9b072..596f8bc 100644 --- a/misc/asm_syntax.txt +++ b/misc/asm_syntax.txt @@ -1,42 +1,273 @@ -Basics of the Unix assembler syntax +Basics of the "Unix v0" 'as' assembler syntax and PDP-7 coding: -Lines starting with " are comment lines +ASSEMBLER SYNTAX: +================= + +Anything from " to end of line is a comment. . is the location counter, where the next code or constant will be placed -.. is the relocation counter +.. is the relocation counter (not currently handled) -t = 0 Sets a built-in variable to this value without generating any machine code. - Variables so far are . .. and t. Not sure what t's purpose is yet. +Symbol names start with a letter, and can contain letters and "." +The dump of label values in "scans/sysmap" appears to show truncation +after 8 characters (not currently enforced by the "as7" Perl script). -orig: is a label. It looks like labels can have dots in them. - Dots seem to separate structures and fields, e.g. u.base - but there are some symbols that start with dots, e.g. .seek +symbol = expression -jms copy; 10; u.rg+2; 6 Semicolons separate instructions and - word expressions that follow the instruction + Sets a built-in variable to this value without generating any + machine code. - Some expressions are 0:0, not sure about this. - Is it two 9-bit fields? No idea + as7 enters machine instructions and the indirect bit (i) + into the variable table. -jmp 1f Jump back to the closest 1: label -jmp 1b Jump forward to the closest 1: label +label: is a label. -Some lines are indented differently to others e.g. + single digit decimal numbers can be used as "local" labels, + which are referenced with Nf and Nb: - jms betwen; o10000; o17762 - jms error - dac .+1 + jmp 1f Jump back to the closest 1: label + jmp 1b Jump forward to the closest 1: label -I think this is to indicate the skip logic, but it plays no part in the assembly syntax. - --1 occurs instead of instructions, so it looks like the assembler allows -literal constants at any time. +multiple words can be entered on one line, separated by semi-colon. String literals seem to be two characters decorated with < > characters, e.g. "ab" is b. I'm guessing these are placed as pairs in one word. The syntax is confusing, because I've also seen ; 040 ; ; ; Date: Mon, 29 Feb 2016 13:40:20 -0500 Subject: [PATCH 2/6] add (tab separated) comments --- src/sys/sop.s | 180 +++++++++++++++++++++++++------------------------- 1 file changed, 89 insertions(+), 91 deletions(-) diff --git a/src/sys/sop.s b/src/sys/sop.s index 22ca2a4..124ee9d 100644 --- a/src/sys/sop.s +++ b/src/sys/sop.s @@ -1,97 +1,95 @@ "** 01-s1.pdf page 62 " sop -dac = 0040000 -jms = 0100000 -dzm = 0140000 -lac = 0200000 -xor = 0240000 -add = 0300000 -tad = 0340000 -xct = 0400000 -isz = 0440000 -and = 0500000 -sad = 0540000 -jmp = 0600000 -nop = 0740000 -i = 020000 -law = 0760000 -cma = 0740001 -las = 0750004 -ral = 0740010 -rar = 0740020 -hlt = 0740040 -sma = 0740100 -sza = 0740200 -snl = 0740400 -skp = 0741000 -sna = 0741200 -szl = 0741400 -rtl = 0742010 -rtr = 0742020 -cil = 0744000 -rcl = 0744010 -rcr = 0744020 -cia = 0750000 -lrs = 0640500 -lrss = 0660500 -lls = 0640600 -llss = 0660600 -als = 0640700 -alss = 0660700 -mul = 0653323 -idiv = 0653323 -lacq = 0641002 -clq = 0650000 -omq = 0650002 -cmq = 0650004 -lmq = 0652000 +dac = 0040000 " MEM: deposit AC +jms = 0100000 " MEM: jump to subroutine +dzm = 0140000 " MEM: deposit zero to memory +lac = 0200000 " MEM: load AC +xor = 0240000 " MEM: XOR with AC +add = 0300000 " MEM: one's complement add +tad = 0340000 " MEM: two's complement add +xct = 0400000 " MEM: execute +isz = 0440000 " MEM: increment and skip if zero +and = 0500000 " MEM: AND +sad = 0540000 " MEM: skip if AC different +jmp = 0600000 " MEM: jump +nop = 0740000 " OPR: no-op +i = 020000 " indirect +law = 0760000 " OPR: load accumulator with (instr) +cma = 0740001 " OPR: complement AC +las = 0750004 " OPR: load AC from switches +ral = 0740010 " OPR: rotate AC left +rar = 0740020 " OPR: rotate AC right +hlt = 0740040 " OPR: halt +sma = 0740100 " OPR: skip on minus AC +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 +szl = 0741400 " OPR: skip on zero link +rtl = 0742010 " OPR: rotate two left +rtr = 0742020 " OPR: rotate two right +cll = 0744000 " OPR: clear link +rcl = 0744010 " OPR: clear link, rotate left +rcr = 0744020 " OPR: clear link, rotate right +cla = 0750000 " OPR: clear AC +lrs = 0640500 " EAE: long right shift +lrss = 0660500 " EAE: long right shift, signed +lls = 0640600 " EAE: long left shift +llss = 0660600 " EAE: long left shift, signed +als = 0640700 " EAE: AC left shift +alss = 0660700 " EAE: AC left shift, signed +mul = 0653323 " EAE: multiply +idiv = 0653323 " EAE: integer divide +lacq = 0641002 " EAE: load AC with MQ +clq = 0650000 " EAE: clear MQ +omq = 0650002 " EAE: OR MQ into AC +cmq = 0650004 " EAE: complement MQ +lmq = 0652000 " EAE: load MQ from AC -dscs = 0707141 -dslw = 0707124 -dslm = 0707142 -dsld = 0707104 -dsls = 0707144 -dssf = 0707121 -dsrs = 0707132 - -iof = 0700002 -ion = 0700042 -caf = 0703302 -clon = 0700044 -clsf = 0700001 +dscs = 0707141 " DSK: clear status register +dslw = 0707124 " DSK: clear and load WC from AC +dslm = 0707142 " DSK: clear and load MAC from AC +dsld = 0707104 " DSK: clear and load TA and SA from AC +dsls = 0707144 " DSK: load status +dssf = 0707121 " DSK: skip on flags +dsrs = 0707132 " DSK: read status register +iof = 0700002 " PIC: interrupts off +ion = 0700042 " PIC: interrupts on +caf = 0703302 " CPU: clear all flags +clon = 0700044 " CLK: clear flag, enable +clsf = 0700001 " CLK: skip if overflow "** 01-s1.pdf page 63 -clof = 0700004 -ksf = 0700301 -krb = 0700312 -tsf = 0700401 -tcf = 0700402 -tls = 0700406 -sck = 0704301 -cck = 0704304 -lck = 0704312 -rsf = 0700101 -rsa = 0700104 -rrb = 0700112 -psf = 0700201 -pcf = 0700202 -psa = 0700204 -cdf = 0700501 -lds = 0701052 -lda = 0701012 -wcga = 0704206 -raef = 0700742 -rlpd = 0700723 -beg = 0700547 -spb = 0704401 -cpb = 0704404 -lpb = 0704412 -wbl = 0704424 -dprs = 0704752 -dpsf = 0704741 -dpcf = 0704761 -dprc = 0704712 -crsf = 0706701 -crrb = 0706712 - +clof = 0700004 " CLK: clear flag, disable +ksf = 0700301 " KBD: skip if flag set +krb = 0700312 " KBD: read buffer +tsf = 0700401 " TTY: skip if flag set +tcf = 0700402 " TTY: clear flag +tls = 0700406 " TTY: load buffer, select +sck = 0704301 " S-2: skip on console keyboard +cck = 0704304 " S-2: clear console keyboard +lck = 0704312 " S-2: load console keyboard +rsf = 0700101 " PTR: skip if flag set +rsa = 0700104 " PTR: select alphanumeric mode +rrb = 0700112 " PTR: clear flag, or read buffer +psf = 0700201 " PTP: skip if flag set +pcf = 0700202 " PTP: clear flag +psa = 0700204 " PTP: alphanumeric mode +cdf = 0700501 " ??? +lds = 0701052 " S-2: load display status +lda = 0701012 " S-2: load display address +wcga = 0704206 " S-2: ??? +raef = 0700742 " S-2: resume after edges flag +rlpd = 0700723 " S-2: resume after light pen stop, disabled +beg = 0700547 " S-2: begin +spb = 0704401 " S-2: skip on push button flag +cpb = 0704404 " S-2: clear push button flag +lpb = 0704412 " S-2: load push buttons +wbl = 0704424 " S-2: write button lights +dprs = 0704752 " dataphone: read status +dpsf = 0704741 " dataphone: skip on flag +dpcf = 0704761 " dataphone: clear flag +dprc = 0704712 " dataphone: read character +crsf = 0706701 " CDR: skip if ready +crrb = 0706712 " CDR: read buffer From 2def710c4845a8ab3f36e257cb762e6ffc5008c6 Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 29 Feb 2016 14:22:27 -0500 Subject: [PATCH 3/6] add some (tab separated) comments; fixed some typos --- src/sys/s1.s | 86 ++++++++++++++++++++++++++-------------------------- src/sys/s2.s | 27 +++++++++-------- src/sys/s7.s | 18 +++++------ 3 files changed, 67 insertions(+), 64 deletions(-) diff --git a/src/sys/s1.s b/src/sys/s1.s index 80bc1c0..8dcf364 100644 --- a/src/sys/s1.s +++ b/src/sys/s1.s @@ -21,61 +21,61 @@ orig: jmp 1f+1 1f 1: 0 - iof - dac u.ac + iof " interrupts off + dac u.ac " save user AC lacq - dac u.mq + dac u.mq " save user MQ lac 8 - dac u.rq + dac u.rq " save user auto-index location 8 lac 9 - dac u.rq+1 - jms copy; 10; u.rq+2; 6 - lac 1b - dac u.rq+8 + dac u.rq+1 " save user auto-index location 9 + jms copy; 10; u.rq+2; 6 " save user auto-index locations 10-15 + lac 1b " load user PC after system call + dac u.rq+8 " save user PC + -1 " load -1 + dac .savblk " set "save" flag (cleared by disk I/O?) + dac .insys " set "in system" flag + lac uquant " load user quantum count + jms betwen; d0; maxquant " check if between 0 & maxquant?? + jms swap " no: swap processes + ion " interrupts on -1 - dac .savblk - dac .insys - lac uquant - jms betwen; d0; maxquant - jms swap - ion - -1 - tad u.rq+8 - jms laci - jms betwen; o20001; swn - jmp badcal - tad swp - dac .+1 - jmp .. i + tad u.rq+8 " get address of system call + jms laci " load AC indirect?? + jms betwen; o20001; swn " range check + jmp badcal " bad system call + tad swp " add system call table base + dac .+1 " save as next instruction + jmp .. i " dispatch system call . = orig+0100 jmp coldentry jms halt okexit: - dzm: u.ac -sysexit: - ion - lac .savblk - sza - jmp 1f - jms copy; sysdata; dskbuf; 64 + dzm u.ac " 'OK' system call exit: clear user AC +sysexit: " common system call exit code + ion " enable interrupts + lac .savblk " load "save" flag + sza " is zero (cleared by disk I/O)? + jmp 1f " no: no disk I/O done? + jms copy; sysdata; dskbuf; 64 " copy system data to disk buffer cla - jms dskio; 07000 + jms dskio; 07000 " save to disk? 1: - dzm .insys + dzm .insys " clear "in system call" flag jms chkint skp - jmp .save - jms copy; u.rq+2; 10; 6 - lac u.rq+1 + jmp .save " dump core?? + jms copy; u.rq+2; 10; 6 " restore auto-index locations 10-15 + lac u.rq+1 " restore auto-index location 9 dac 9 - lac u.rq + lac u.rq " restore auto-index location 8 dac 8 - lac u.rq + lac u.mq " restore MQ register lmq - lac u.ac - jmp u.rq+8 i + lac u.ac " restore AC register + jmp u.rq+8 i " return to user swap: 0 ion @@ -129,21 +129,21 @@ swap: 0 jmp swap i t = t+1 -swp: - jmp . +swp: " system call dispatch table + jmp . " base instruction .save; .getuid; .open; .read; .write; .creat; .seek; .tell .close; .link; .unlink; .setuid; .rename; .exit; .time; .intrp .chdir; .chmod; .chown; badcal; .sysloc; badcal; .capt; .rele .status; badcal; .smes; .rmes; .fork swn: - .-swp-1 i + .-swp-1 i " count of system calls, plus indirect! .intrp: lac u.ac dac u.intflg jmp okexit -.sysloc: +.sysloc: " "sysloc": syscall to return system addresses lac u.ac and o17777 jms betwen; d1; locn @@ -154,7 +154,7 @@ swn: dac u.ac jmp sysexit -locsw: +locsw: " table of system data structures for "sysloc" call lac . iget; inode; userdata; sysdata; copy; copyz; betwen; dskrd dskwr; dskbuf; dpdata; namei; pbsflgs; alloc; free; dspdata diff --git a/src/sys/s2.s b/src/sys/s2.s index 9d7af58..3424c44 100644 --- a/src/sys/s2.s +++ b/src/sys/s2.s @@ -53,9 +53,9 @@ jms iput jmp okexit -.getuid: +.getuid: " getuid system call lac u.uid - dac u.ac + dac u.ac " return u.uid in user AC jmp sysexit .seek: @@ -146,12 +146,12 @@ jms iput jmp sysexit -.setuid: - lac u.uid - sma - jms error - lac u.ac - dac u.uid +.setuid: " setuid system call + lac u.uid " load current user id + sma " negative? + jms error " no: error!! + lac u.ac " load user AC + dac u.uid " save as new uid jmp sysexit .rename: @@ -168,11 +168,14 @@ jms copy; 1:0; d.name; 4 jmp okexit + " time system call returns line (mains) frequency ticks since boot? + " note: returns uptime!? + " at 60Hz, 36 bits would last 36+ years! .time: - lac s.tim - dac u.ac - lac s.tim+1 - dac u.mq + lac s.tim " load high order bits + dac u.ac " return in AC + lac s.tim+1 " load low order bits + dac u.mq " return in MQ jmp sysexit .chdir: diff --git a/src/sys/s7.s b/src/sys/s7.s index c5b307b..46e53ac 100644 --- a/src/sys/s7.s +++ b/src/sys/s7.s @@ -1,7 +1,7 @@ "** 01-s1.pdf page 41 " s7 -pibreak: +pibreak: " priority interrupt processing "chain" dac .ac "** CROSSED OUT.... dpsf @@ -25,15 +25,15 @@ pibreak: dac dpwrite jmp piret "** END OF CROSSOUT -1: clsf - jmp 1f +1: clsf " clock overflow (line frequency ticks)? + jmp 1f " no - lpb - dac pbsflgs - isz s.tim+1 - skp - isz s.tim - isz uquant + lpb " load display push buttons + dac pbsflgs " save + isz s.tim+1 " increment low order tick count + skp " no overflow, skip second increment + isz s.tim " low order overflowed, increment high order count + isz uquant " increment user quantum counter "** written: ttydelay -> ttyd1 "** written: ttyrestart -> ttyres1 cnop: From 249ce47e44082cc57a76c8cba096b39313135dcf Mon Sep 17 00:00:00 2001 From: Phil Budne Date: Mon, 29 Feb 2016 14:24:37 -0500 Subject: [PATCH 4/6] OR syllables by default (allows multiple OPR instructions) --- tools/as7 | 125 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 66 insertions(+), 59 deletions(-) diff --git a/tools/as7 b/tools/as7 index 2a4b958..943121b 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 (expression parsing, "list" format) +# Tweaked by Phil Budne (line, expression parsing, "list" format) # use strict; use warnings; @@ -25,7 +25,6 @@ my $origline; # The original current input line of code my $line; # line being parsed my $stage = 1; # Pass one or pass two my $errors = 0; # set to non-zero on error -my %Undef; # undefined symbols: only complain once my $line_error = ' '; my $file; # current file name my $lineno; # current line number @@ -149,7 +148,7 @@ usage() if ( @ARGV < 1 ); rsb => 0700144, # select PTR in binary mode psf => 0700201, # skip if PTP flag set - pcf => 0700202, # clear PTP clag + pcf => 0700202, # clear PTP flag psa => 0700204, # punch PTP in alphanumeric mode psb => 0700244, # punch PTP in binary mode @@ -157,7 +156,7 @@ usage() if ( @ARGV < 1 ); krb => 0700312, # read KBD buffer iors => 0700314, # input/output read status - tsf => 0700401, # if if TTY output flag set + tsf => 0700401, # skip if if TTY output flag set tcf => 0700402, # clear TTY output flag tls => 0700406, # load TTY output buffer and select @@ -272,8 +271,9 @@ sub parse_file { close($IN); } -# process a label and set its value to the location counter (only called on pass 1) -# (if called on pass 2, should check if values are identical) +# process a label and set its value to the location counter +# only called on pass 1; +# if called on pass 2, should check if values are identical sub process_label { my $label = shift; @@ -294,25 +294,21 @@ sub process_label { } # Blame Phil for this.... -# parses global $line based on prefixes -# (nibbling of a bit at a time) +# parses global $line based on prefixes, nibbling of a bit at a time +# (: and ; can appear in char literals) # handles multiple ';' separated words per line sub parse_line { - $line_error = ' '; - + # Lose any leading whitespace + $line =~ s{^\s*}{}; + while (1) { - # Lose any leading whitespace - $line =~ s{^\s*}{}; + $line_error = ' '; # clear listing error indicator + + return if ($line eq '' || $line =~ m{^"}); # empty or comment: quit print "parse_line: '$line'\n" if ($debug); - return if ($line eq ''); - - if ($line =~ m{^"}) { # remainder of line is comment - return; - } - - if ($line =~ s{^([a-z0-9\.]+):}{}) { # label + while ($line =~ s{^([a-z0-9\.]+):\s*}{}) { # labels my $label = $1; # First pass: parse the labels @@ -321,44 +317,40 @@ sub parse_line { process_label($1); } } - else { - my $lhs = undef; - if ( $line =~ s{^(\S+)\s*=}{}) { # assignment - $lhs = $1; - } + + if ( $line =~ s{^(\S+)\s*=}{}) { # assignment + my $lhs = $1; my $word = parse_expression(); - if ($lhs) { - 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'); - } - else { # bare expression - # Get its value on pass two and save to memory - # Also save the input line that altered memory - if ( $stage == 2 ) { - my $location = $Var{'.'}; - $Mem[$location] = $word; - $Mline[$location] = $origline; - $origline = ''; - if ($format eq 'list') { - printf( "%06o: %06o %s\n", $location, $word, $line_error); - } + 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'); + } + else { # bare expression + # Get its value on pass two and save to memory + # Also save the input line that altered memory + my $word = parse_expression(); + if ( $stage == 2 ) { + my $location = $Var{'.'}; + $Mem[$location] = $word; + $Mline[$location] = $origline; + $origline = ''; + if ($format eq 'list') { + printf( "%06o: %06o %s\n", $location, $word, $line_error); } - # Move up to the next location in both passes - $Var{'.'}++; - } # expr - } # assignment or expression + } + # Move up to the next location in both passes + $Var{'.'}++; + } # expr # eat trailing whitespace and ";", if any - $line =~ s{^\s*}{}; - $line =~ s{^;}{}; + $line =~ s{^\s*;?}{}; } # while } # Blame Phil for this bit too... # Parse an expression off $line and return a PDP-7 word # as a series of whitespace separated "syllables" -# and adds them together. +# ORed, added, or subtracted sub parse_expression { my $word = 0; @@ -366,23 +358,22 @@ sub parse_expression { while (1) { my $syllable = 0; - my $sign = 1; + my $op = '|'; $line =~ s{^\s+}{}; - print " '$line'\n" if ($debug); if ($line eq '' || $line =~ m{^[";]}) { # EOL ; and " terminate expr printf("\tparse_expression => %#o\n", $word) if ($debug); return $word; } + print " '$line'\n" if ($debug); + if ($line =~ s{^-}{}) { - # leading '-' negates upcomming syllable. - $sign = -$sign; + $op = '-'; } - else { - # ignore leading '+' - $line =~ s{^\+}{}; + elsif ($line =~ s{^\+}{}) { + $op = '+'; } if ($line =~ s{^<(.)}{}) { # Date: Mon, 29 Feb 2016 14:27:34 -0500 Subject: [PATCH 5/6] add missing ; --- scans/trysys.s | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scans/trysys.s b/scans/trysys.s index 029db17..90f429a 100644 --- a/scans/trysys.s +++ b/scans/trysys.s @@ -32,7 +32,7 @@ error: 1: 077012 a.out: - ;;; Date: Mon, 29 Feb 2016 14:28:03 -0500 Subject: [PATCH 6/6] fix typos --- scans/s1.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scans/s1.s b/scans/s1.s index 80bc1c0..7a0ee42 100644 --- a/scans/s1.s +++ b/scans/s1.s @@ -53,7 +53,7 @@ orig: jms halt okexit: - dzm: u.ac + dzm u.ac sysexit: ion lac .savblk @@ -72,7 +72,7 @@ sysexit: dac 9 lac u.rq dac 8 - lac u.rq + lac u.mq lmq lac u.ac jmp u.rq+8 i