diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 9b71fe33..686214ab 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -55,6 +55,8 @@ The full set of tests is only run for tagged releases. - tools/bin/asm-11: - BUGFIX: support @(R) modifier with omitted offset - BUGFIX: misused # and @ don't cause BUGCHECKs anymore + - BUFGIX: expressions: allow uunary after binary operator + - BUFGIX: proper sign handling for '/','*' operator and .if ge,gt,le,lt --- diff --git a/tools/asm-11/mlib/rtijmp.mac b/tools/asm-11/mlib/rtijmp.mac index 055a12c8..77dad33c 100644 --- a/tools/asm-11/mlib/rtijmp.mac +++ b/tools/asm-11/mlib/rtijmp.mac @@ -1,4 +1,4 @@ -; $Id: rtijmp.mac 1359 2023-01-27 20:58:50Z mueller $ +; $Id: rtijmp.mac 1360 2023-01-29 11:51:48Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2023- by Walter F.J. Mueller ; @@ -6,6 +6,7 @@ ; usage: rtijmp #cp.cmu+cp.t,#5100$ ; .macro rtijmp,newps,newpc + .mcall push2 push2 newps,newpc rti halt diff --git a/tools/asm-11/mlib/rttjmp.mac b/tools/asm-11/mlib/rttjmp.mac index 5cf265d6..3ebffe89 100644 --- a/tools/asm-11/mlib/rttjmp.mac +++ b/tools/asm-11/mlib/rttjmp.mac @@ -1,4 +1,4 @@ -; $Id: rttjmp.mac 1359 2023-01-27 20:58:50Z mueller $ +; $Id: rttjmp.mac 1360 2023-01-29 11:51:48Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2023- by Walter F.J. Mueller ; @@ -6,6 +6,7 @@ ; usage: rtijmp #cp.cmu+cp.t,#5100$ ; .macro rttjmp,newps,newpc + .mcall push2 push2 newps,newpc rtt halt diff --git a/tools/asm-11/tests-err/testerr_0700_Serror.mac b/tools/asm-11/tests-err/testerr_0700_Serror.mac new file mode 100644 index 00000000..b83c7c67 --- /dev/null +++ b/tools/asm-11/tests-err/testerr_0700_Serror.mac @@ -0,0 +1,18 @@ +; $Id: testerr_0700_Serror.mac 1360 2023-01-29 11:51:48Z mueller $ +; SPDX-License-Identifier: GPL-3.0-or-later +; Copyright 2023- by Walter F.J. Mueller +; +; test S error code (size error, asm-11 specific) +; + .asect + . = 1000 +; + .if df,...top ; asm-11 only + .nlist meb ; disable listing, only error lines printed + .rept 010000 + .word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;;!!S + .endr + .word 0 ;;!! 000000: ; should not be reached + .endc +; + .end diff --git a/tools/asm-11/tests/test_0020_expr.mac b/tools/asm-11/tests/test_0020_expr.mac index e7032a79..f243d271 100644 --- a/tools/asm-11/tests/test_0020_expr.mac +++ b/tools/asm-11/tests/test_0020_expr.mac @@ -1,4 +1,4 @@ -; $Id: test_0020_expr.mac 1184 2019-07-10 20:39:44Z mueller $ +; $Id: test_0020_expr.mac 1360 2023-01-29 11:51:48Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2013- by Walter F.J. Mueller ; @@ -20,6 +20,21 @@ u5 = ^c300 ;;!! 177477 u6 = ^c-300 ;;!! 000277 +; unary operator precedence (matters for ^c,- sequences) + + a = 1 + am = -1 +; + .word ^c-a ;;!! 000000 ; 000001 - 177777 ^c 000000 + .word -^ca ;;!! 000002 ; 000001 ^c 177776 - 000002 + .word ^c<-a> ;;!! 000000 ; 000001 - 177777 ^c 000000 + .word -<^ca> ;;!! 000002 ; 000001 ^c 177776 - 000002 +; + .word ^c-am ;;!! 177776 ; 177777 - 000001 ^c 177776 + .word -^cam ;;!! 000000 ; 177777 ^c 000000 - 000000 + .word ^c<-am> ;;!! 177776 ; 177777 - 000001 ^c 177776 + .word -<^cam> ;;!! 000000 ; 177777 ^c 000000 - 000000 + ; binary operators b1 = 1100 + 100 ;;!! 001200 @@ -29,6 +44,33 @@ b5 = 1770 & 0077 ;;!! 000070 b6 = 1000 ! 100 ;;!! 001100 +; unary after binary operators and proper sign in * and / + + .word 100.*5. ;;!! 000764 + .word 100.*-5. ;;!! 177014 + .word -100.*5. ;;!! 177014 + .word -100.*-5. ;;!! 000764 +; + .word 100./5. ;;!! 000024 + .word 100./-5. ;;!! 177754 + .word -100./5. ;;!! 177754 + .word -100./-5. ;;!! 000024 +; + a = 100. + b = 5. + .word a/b ;;!! 000024 + .word a/-b ;;!! 177754 + .word -a/b ;;!! 177754 + .word -a/-b ;;!! 000024 + .word -a/--b ;;!! 177754 +; + ma = -100. + mb = -5. + .word a/b ;;!! 000024 + .word a/mb ;;!! 177754 + .word ma/b ;;!! 177754 + .word ma/mb ;;!! 000024 + ; radix prefixes and suffixes r1 = 11 ;;!! 000011 diff --git a/tools/asm-11/tests/zbug_0006.mac b/tools/asm-11/tests/zbug_0006.mac new file mode 100644 index 00000000..3abd125f --- /dev/null +++ b/tools/asm-11/tests/zbug_0006.mac @@ -0,0 +1,43 @@ +; $Id: zbug_0006.mac 1360 2023-01-29 11:51:48Z mueller $ +; SPDX-License-Identifier: GPL-3.0-or-later +; Copyright 2023- by Walter F.J. Mueller +; +; for asm-11 prior rev 1360 +; +; ISSUE: faulty handling of unnary +/- in expresions +; +; REASON: error in parser (didnt allow uop after bop) and +; error in sign sign handling for '*" and '/' operator +; + .asect + . = 1000 +; + .word 100. ;;!! 000144 + .word -100. ;;!! 177634 +; + .word 100.*5. ;;!! 000764 + .word 100.*-5. ;;!! 177014 + .word -100.*5. ;;!! 177014 + .word -100.*-5. ;;!! 000764 +; + .word 100./5. ;;!! 000024 + .word 100./-5. ;;!! 177754 + .word -100./5. ;;!! 177754 + .word -100./-5. ;;!! 000024 +; + a = 100. + b = 5. + .word a/b ;;!! 000024 + .word a/-b ;;!! 177754 + .word -a/b ;;!! 177754 + .word -a/-b ;;!! 000024 + .word -a/--b ;;!! 177754 +; + ma = -100. + mb = -5. + .word a/b ;;!! 000024 + .word a/mb ;;!! 177754 + .word ma/b ;;!! 177754 + .word ma/mb ;;!! 000024 +; + .end diff --git a/tools/bin/asm-11 b/tools/bin/asm-11 index eafa9643..762d4bfb 100755 --- a/tools/bin/asm-11 +++ b/tools/bin/asm-11 @@ -1,10 +1,12 @@ #!/usr/bin/perl -w -# $Id: asm-11 1359 2023-01-27 20:58:50Z mueller $ +# $Id: asm-11 1360 2023-01-29 11:51:48Z mueller $ # SPDX-License-Identifier: GPL-3.0-or-later # Copyright 2013-2023 by Walter F.J. Mueller # # Revision History: # Date Rev Version Comment +# 2023-01-29 1360 1.2.5 BUFGIX: expressions: allow uop after bop operator; +# proper sign handling for '/','*' and .if ge,gt,le,lt # 2023-01-27 1359 1.2.4 add minimal .list,.nlist (cnd,me,meb); add -(n)list # 2023-01-26 1357 1.2.3 skip redundant loads in .mcall # 2023-01-25 1355 1.2.2 rewrite macro args handling; add .narg,.nchr,.ntype @@ -572,7 +574,7 @@ sub pass1_line { if (defined $$rl{oper} && $$rl{oper} eq '.endr') { if (scalar(@reptstk) > 0) { my $ifstklvl = scalar(@ifstk); # remember initial .if stack depth - my $cnt = $reptstk[-1]{cnt}; + my $cnt = int16($reptstk[-1]{cnt}); for (my $i=0; $i<$cnt; $i++) { # repeat body cnt times foreach my $rline (@{$reptstk[-1]{body}}) { $mexit = 0; @@ -1515,7 +1517,7 @@ sub parse_line { $rt = get_token(\%l, $tmask); if ($$rt{tag} eq 'OP' && $$rt{typ}=~'b') { # OP(b) $$rt{typ}='b'; - $state = 'e_bop1'; + $state = 'e_uop'; } elsif (check_token($rt, 'DEL', '>')) { if (scalar(@e_pbeg) == 0) { $state = 'q'; @@ -1533,17 +1535,6 @@ sub parse_line { $state = 'e_end'; } - } elsif ($state eq 'e_bop1') { # state: e_bop1 ------------------ - $rt = get_token(\%l, $tmask); - if ($$rt{tag} eq 'NUM' || $$rt{tag} eq 'SYM') { - $state = 'e_bop'; - } elsif (check_token($rt, 'DEL', '<')) { - push @e_pbeg, scalar(@{$l{tl}})-1; - $state = 'e_uop'; - } else { - $state = 'q'; - } - } elsif ($state eq 'e_end') { # state: e_end ------------------- $e_iend = scalar(@{$l{tl}})-1; $l{tl}[$e_ibeg]->{em} = '<>'; @@ -1651,6 +1642,7 @@ sub parse_line { if (scalar(@d_elist) == 1) { my $val = eval_exp(\%l, $d_elist[0]{ibeg}, $d_elist[0]{iend}); if (defined $val) { + $val = int16($val); # sign extend $tst = 1 if $ifcond eq 'eq' && $val == 0; $tst = 1 if $ifcond eq 'ne' && $val != 0; $tst = 1 if $ifcond eq 'gt' && $val > 0; @@ -1788,6 +1780,12 @@ sub parse_line { die "BUGCHECK: unexpected state '$state'\n"; } } + # check that no code is generated above 160000 + if (defined $l{dot} && $l{dot} >= 0160000) { # if '.' >= 160000 + add_err(\%l, 'S'); # -> signal S (asm-11 specific) + $mexit = 1; # abort .macro or .rept + $end = 1; # abort file reading + } return \%l; } @@ -1850,7 +1848,7 @@ sub setdot { sub incdot { my ($inc) = @_; return unless defined $inc; - setdot(getdot() + $inc); + setdot(0177777 & (getdot() + $inc)); return; } @@ -2001,22 +1999,24 @@ sub eval_exp { die "BUGCHECK: bop not defined" unless defined $bop; my $v2 = pop @val; my $v1 = pop @val; + my $v; return undef unless defined $v1 && defined $v2; if ($bop eq '+') { # '+': addition - push @val, int($v1) + int($v2); + $v = int($v1) + int($v2); } elsif ($bop eq '-') { # '-': subtraction - push @val, int($v1) - int($v2); + $v = int($v1) - int($v2); } elsif ($bop eq '*') { # '*': multiplication - push @val, int($v1) * int($v2); + $v = int16($v1) * int16($v2); } elsif ($bop eq '/') { # '/': division - push @val, int(int($v1) / int($v2)); + $v = int(int16($v1) / int16($v2)); } elsif ($bop eq '&') { # '&': bit-wise and - push @val, int($v1) & int($v2); + $v = int($v1) & int($v2); } elsif ($bop eq '!') { # '!': bit-wise or - push @val, int($v1) | int($v2); + $v = int($v1) | int($v2); } else { die "BUGCHECK: tag='OP(b)', val='$bop'\n"; } + push @val, (0177777 & $v); $bop = undef; } @@ -2024,6 +2024,15 @@ sub eval_exp { return pop @val; } +#------------------------------------------------------------------------------- +# returns 16bit sign extended integer value +sub int16 { + my ($val) = @_; + $val = 0177777 & int($val); + $val = ($val - 0200000) if (0100000 & $val); + return $val; +} + #------------------------------------------------------------------------------- # returns true if symbol looks like a local label (1234$) @@ -2660,10 +2669,12 @@ sub pass2_lst_line { return unless $list{cnd}; } if ($$rl{flag} =~ m/[mr]/) { - if (scalar(@ow)+scalar(@ob) == 0) { - return unless $list{me}; - } else { - return unless $list{me} || $list{meb}; + if ($$rl{err} eq '') { # show line in case of errors + if (scalar(@ow)+scalar(@ob) == 0) { + return unless $list{me}; + } else { + return unless $list{me} || $list{meb}; + } } } diff --git a/tools/man/man1/asm-11.1 b/tools/man/man1/asm-11.1 index e9d3bd0b..397563c6 100644 --- a/tools/man/man1/asm-11.1 +++ b/tools/man/man1/asm-11.1 @@ -1,5 +1,5 @@ .\" -*- nroff -*- -.\" $Id: asm-11.1 1359 2023-01-27 20:58:50Z mueller $ +.\" $Id: asm-11.1 1360 2023-01-29 11:51:48Z mueller $ .\" SPDX-License-Identifier: GPL-3.0-or-later .\" Copyright 2013-2023 by Walter F.J. Mueller .\" @@ -94,10 +94,14 @@ and thus restricted macro support and no psect support. .IP "-" 2 only single \.asect supported, no \.psect support .IP "-" +assembler stops with error code 'S' when '.' exceeds 160000 +.IP "-" registers must be named r0,..,r5,sp,pc .IP "-" the %n notation and register expressions are not supported .IP "-" +labeled assignment statements cause a 'Q' error (MACRO-11 accepts) +.IP "-" the \.emt and \.trap instruction must have the trap number specified .IP "-" a .macro definition must end with \.endm (\.endr not accepted) @@ -112,11 +116,38 @@ a \.if df/ndf sees opcodes as defined (MACRO-11 doesn't) .IP "-" a \.if df/ndf sees register names as undefined (MACRO-11 doesn't) .IP "-" -error codes on invail statements differ, especially A and Q +error codes on invail statements differ, especially 'A' and 'Q' .IP "-" the \.(n)list acts only on cnd, me and meb, ignores other values .IP "-" the \.(n)list default is cnd=0,me=0,meb=1 (MACRO-11 cnd=1,meb=0) +.IP "-" +the following directives are not supported: +\&.cross, +\&.csect, +\&.dsabl, +\&.enabl, +\&.flt2, +\&.flt4, +\&.globl, +\&.ident, +\&.iif, +\&.irp, +\&.irpc, +\&.library, +\&.limit, +\&.nocross, +\&.packed, +\&.page, +\&.psect, +\&.rad50, +\&.radix, +\&.rem, +\&.restore, +\&.save, +\&.sbttl, +\&.title, +\&.weak .PD .RE .PP diff --git a/tools/tcode/cpu_mmu.mac b/tools/tcode/cpu_mmu.mac index f4553c90..77378320 100644 --- a/tools/tcode/cpu_mmu.mac +++ b/tools/tcode/cpu_mmu.mac @@ -1,9 +1,10 @@ -; $Id: cpu_mmu.mac 1359 2023-01-27 20:58:50Z mueller $ +; $Id: cpu_mmu.mac 1360 2023-01-29 11:51:48Z mueller $ ; SPDX-License-Identifier: GPL-3.0-or-later ; Copyright 2022-2023 by Walter F.J. Mueller ; ; Revision History: ; Date Rev Version Comment +; 2023-01-28 1360 1.1.1 remove <../100> expressions for 6 bit right shift ; 2023-01-27 1358 1.1 use .mcall and mlib; use hta??? macros ; 2023-01-05 1346 1.0 Initial version ; 2022-07-24 1262 0.1 First draft @@ -33,6 +34,7 @@ .mcall hcmpeq,hcmbeq,htsteq,htstge,hbiteq,hbitne .mcall vecset,vecclr .mcall htabuf,htaadd,htaini,htacmp + .mcall rtijmp ; ; some useful definitions uipdr0 = uipdr+ 0 @@ -90,6 +92,18 @@ p6p1p2 = p6base+<1*100>+2 ; page 6, +1 click, +2 p7base = <7*20000> ; page 7 ; +; Helper macro to set mmu par from an absolute address +; Just needs an 6 bit right shift. A simple # doesnt work for +; addr >= 100000 because of the signed number behavior of the division operator. +; The macro distingishes the positive and negative address cases. +; + .macro setpar,addr,par + mov #addr,r0 + ash #-6.,r0 + bic #176000,r0 + mov r0,par + .endm +; ; Section A: pdr,par registers =============================================== ; A1.1 test that pdr/par are 16 bit write/readable ; A1.2 set up MMU default configuration @@ -412,16 +426,14 @@ tb0301: ; ; set user mode pdr/par, only short page 0 mov #<8.*md.plf>!md.arw,uipdr0 - mov #,uipar0 + setpar vc0,uipar0 ; set up data for user mode run mov #023456,vc0v0; mov #000123,vc0v1 mov #077321,vc0v2 ; start code in user mode mov #1000$,vhustp ; set up continuation address - mov #,-(sp) ; next psw: user mode - clr -(sp) ; will start at 0 - rti ; and launch it + rtijmp #,#0 ; start with PS=user, PC=0 halt 1000$: ; continuation point ; check psw @@ -438,16 +450,14 @@ tb0301: ; ; set supervisor mode pdr/par, only short page 0 mov #<8.*md.plf>!md.arw,sipdr0 - mov #,sipar0 + setpar vc0,sipar0 ; set up data for user mode run mov #017171,vc0v0 mov #000321,vc0v1 mov #100123,vc0v2 ; start code in supervisor mode mov #2000$,vhustp ; set up continuation address - mov #,-(sp) ; next psw: supervisor mode - clr -(sp) ; will start at 0 - rti ; and launch it + rtijmp #,#0 ; start with: PS=supervisor, PC=0 halt 2000$: ; continuation point ; check psw @@ -484,18 +494,16 @@ tb0302: ; ; set user mode pdr/par, only short page 0; I and D mov #<8.*md.plf>!md.arw,uipdr0 - mov #,uipar0 + setpar vc1,uipar0 mov #<8.*md.plf>!md.arw,udpdr0 - mov #,udpar0 + setpar vc1dat,udpar0 ; set up data for user mode run mov #020305,vc1v0 mov #000212,vc1v1 mov #033121,vc1v2 ; start code in user mode mov #1000$,vhustp ; set up continuation address - mov #,-(sp) ; next psw: user mode - clr -(sp) ; will start at 0 - rti ; and launch it + rtijmp #,#0 ; start with PS=user, PC=0 halt ; 1000$: ; continuation point @@ -668,14 +676,12 @@ tb0303: clr vc4l1 ; set user mode pdr/par, I page 0 and D page 1 mov #<8.*md.plf>!md.arw,uipdr0 ; I space writable - mov #,uipar0 + setpar vc4,uipar0 mov #<8.*md.plf>!md.arw,udpdr1 - mov #,udpar1 + setpar vc4dat,udpar1 ; start code in user mode mov #1000$,vhustp ; set up continuation address - mov #,-(sp) ; next psw: user mode - clr -(sp) ; will start at 0 - rti ; and launch it + rtijmp #,#0 ; start with PS=user, PC=0 halt ; 1000$: ; continuation point @@ -710,9 +716,7 @@ tb0401: clr mmr3 ; no d dspace, no 22bit mov #m0.ena,mmr0 ; enable mmu ;! MMU 18 vecset v..mmu,1000$ ; set up local mmu handler ; try to run a code in mode 10 - mov #^b1010000000000000,-(sp) ; next psw; cm=pm=10 - mov #p6base+200,-(sp) ; start address - rti ; fake code start + rtijmp #^b1010000000000000,#p6base+200 ; start with PS:cm=pm=10 halt ; test abort PC on stack 1000$: cmpb systyp,#sy.sih ; on SimH ? @@ -1364,11 +1368,14 @@ tc0203: vecset v..mmu,vhmmua ; set up mmu handler, pr0 kernel ; 9000$: clr cp.psw reset ; mmu off ;! MMU off - clr sipdr0 ; reset super/user pdf + clr sipdr0 ; reset super/user pdr/par + clr sipar0 clr sipdr1 + clr sipar1 clr sipdr7 clr sipar7 clr uipdr0 + clr uipar0 vecclr v..mmu ; restore mmu catcher 9999$: iot ; end of test C2.3 ; @@ -1691,11 +1698,11 @@ td0101: vc2seu = 037700 ; initial end of stack in user view ; mov #<8.*md.plf>!md.arw,uipdr0 - mov #,uipar0 + setpar vc2,uipar0 mov #<8.*md.plf>!md.arw,udpdr0 - mov #,udpar0 + setpar vc2dat,udpar0 mov #<127.*md.plf>!md.arw!md.dwn,udpdr1 - mov #<140000/100>,udpar1 + setpar 140000,udpar1 ; enable mmu mov #m3.dum,mmr3 ; user d dspace, no 22bit mov #m0.ena,mmr0 ; enable mmu ;! MMU 18 @@ -1713,9 +1720,7 @@ td0101: clr 3002$ ; start code in user mode mov #1000$,vhustp ; set up continuation address - mov #,-(sp) ; next psw: user mode - clr -(sp) ; will start at 0 - rti ; and launch it + rtijmp #,#0 ; start with PS=user, PC=0 halt 1000$: ; continuation point hcmpeq r5,#0 ; ran sob to end ? @@ -1840,9 +1845,9 @@ td0201: tstb systyp ; skip if not on w11 mov kipdr1,sipdr1 ; SM p1 1-to-1 mov kipar1,sipar1 mov #<8.*md.plf>,sipdr2 ; SM p2 code, non-resident - mov #,sipar2 + setpar vc3,sipar2 mov #<127.*md.plf>!md.arw!md.dwn,sipdr3 ; SM p3 stack, short - mov #<140000/100>,sipar3 + setpar 140000,sipar3 mov #<127.*md.plf>!md.att,sipdr7 ; SM p7 IOpage + rw-trap mov kipar7,sipar7 mov #m0.ent!m0.ena,mmr0 ; enable mmu ;! MMU 18