Heater
Posts: 18758
Joined: Tue Jul 17, 2012 3:02 pm

Re: A Birthday Present for Fido

Thu Nov 05, 2020 6:57 am

ejolson wrote:
Wed Nov 04, 2020 9:37 pm
It is noticeable the Pi computers in both lab pictures were not actually being used for programming when the pictures were taken...
Maybe that is lesson 1. They have just installed Raspbian and booted a Pi for the first time. They look like they are all wondering "WTF?".
Memory in C++ is a leaky abstraction .

ejolson
Posts: 8628
Joined: Tue Mar 18, 2014 11:47 am

Re: A Birthday Present for Fido

Thu Nov 05, 2020 3:17 pm

lurk101 wrote:
Thu Nov 05, 2020 3:01 am
Surprised no one caught it, but room 2 is connected to room 4 twice.

Here's the bug fix. Add missing break statement.
Yikes! That's good news to fix the bug. I only checked the dodecahedrons not the other graphs. I'll rerun the search with the corrected graph generator to see if any new dodecahedrons appear.

I wonder how fast the remote SuperPET desktop could perform that task.

ejolson
Posts: 8628
Joined: Tue Mar 18, 2014 11:47 am

Re: A Birthday Present for Fido

Thu Nov 05, 2020 10:37 pm

ejolson wrote:
Thu Nov 05, 2020 3:17 pm
lurk101 wrote:
Thu Nov 05, 2020 3:01 am
Surprised no one caught it, but room 2 is connected to room 4 twice.

Here's the bug fix. Add missing break statement.
Yikes! That's good news to fix the bug. I only checked the dodecahedrons not the other graphs. I'll rerun the search with the corrected graph generator to see if any new dodecahedrons appear.

I wonder how fast the remote SuperPET desktop could perform that task.
As the Texas Instruments graphing calculators models TI-81 through TI-86 are all based on an 8-bit Z-80 processor, an interesting point of reference is to compare the speed of Pascal running on the SuperPET with a similar calculation done using Texas Instruments Basic.

To this end I considered a simple way to approximate the Euler-Mascheroni constant given by

Code: Select all

gamma = 1 + 1/2 + 1/3 + ... + 1/n - log(n)
for n large.

A program to approximate gamma on the calculator looks like
    tibasic.png
    tibasic.png (13.97 KiB) Viewed 1815 times
    http://fractal.math.unr.edu/~ejolson/46 ... /sn1ti.pdf
      and produces an approximation of gamma=0.5777155816 with n=1000 after 15.03 seconds. The resulting speed is 133 Flops.

      I wrote an equivalent program for the SuperPET which further illustrates how to obtain the time from the built-in clock using a system function call.

      Code: Select all

      program main(input,output);
      const n=1000;
      var k:integer;
          hn,timelast,t:real;
      
      function getsec:real;
      const gettime_=-20228;
      var t:packed array[1..4] of char;
      begin
          sysproc(gettime_,address(t));
          getsec:=(ord(t[1])*60.0+ord(t[2]))*60.0
                  +ord(t[3])+ord(t[4])/100.0
      end;
      
      procedure tic;
      begin
          timelast:=getsec
      end;
      
      function toc:real;
      begin
          toc:=getsec-timelast
      end;
      
      begin
          tic;
          hn:=0;
          for k:=n downto 1 do begin
              hn:=hn+1.0/k
          end;
          t:=toc;
          writeln('gamma(',n:1,') = ',
                  hn-ln(n):15:14);
          writeln('elapsed ',t:8:2,' seconds.');
          writeln('speed ',2*n/t:8:2,' flops.')
      end.
      
      When run on the SuperPET this code produces the output
        spflops.png
        spflops.png (34.31 KiB) Viewed 1815 times
          Thus, the SuperPET emulator running on a Raspberry Pi 4B is half the speed of a graphing calculator. Turning on warp mode, of course, goes much faster. Still, I'm not sure if this is good or bad news. I wonder what the corresponding GFlop per watt measurements are?

          ejolson
          Posts: 8628
          Joined: Tue Mar 18, 2014 11:47 am

          Re: A Birthday Present for Fido

          Fri Nov 06, 2020 3:48 am

          ejolson wrote:
          Wed Nov 04, 2020 9:37 pm
          After I decide what to do about the insert key and whether to map run-stop to ctrl-C instead, I'll post a complete symbolic layout for the SuperPET emulator.
          After putting the parenthesis and other symbols in their proper places, I decided that mapping ctrl+C to run-start so insert could function as insert was sensible. Then I went crazy and created additional keyboard mappings so I could use the remote SuperPET desktop from a Chromebook. I think the Chrombook may have an even simpler keyboard layout than an ADM3A video display terminal.

          In particular, I mapped a bunch of control-key sequences to various codes on the keypad used in the Waterloo editor. Now
          • ctrl+B -- page up
          • ctrl+C -- run-stop
          • ctrl+E -- exit edit mode
          • ctrl+F -- page down
          • ctrl+H -- cursor left
          • ctrl+I -- insert a line
          • ctrl+J -- cursor down
          • ctrl+K -- cursor up
          • ctrl+L -- cursor right
          • ctrl+O -- delete a line
          All this was done with a mapping file called sdl-sym-PET.vkm that I placed in the .config/vice subdirectory. Because it appears there are no other examples of symbolic keyboard maps for the SDL version of VICE, here is mine.

          Code: Select all

          # VICE keyboard mapping file
          #
          # A Keyboard map is read in as patch to the current map.
          #
          # File format:
          # - comment lines start with '#'
          # - keyword lines start with '!keyword'
          # - normal line has 'keysym/scancode row column shiftflag'
          #
          # Keywords and their lines are:
          # '!CLEAR'               clear whole table
          # '!INCLUDE filename'    read file as mapping file
          # '!LSHIFT row col'      left shift keyboard row/column
          # '!RSHIFT row col'      right shift keyboard row/column
          # '!VSHIFT shiftkey'     virtual shift key (RSHIFT or LSHIFT)
          # '!UNDEF keysym'        remove keysym from table
          #
          # Shiftflag can have the values:
          # 0      key is not shifted for this keysym/scancode
          # 1      key is shifted for this keysym/scancode
          # 2      left shift
          # 4      right shift
          # 8      key can be shifted or not with this keysym/scancode
          # 16     deshift key for this keysym/scancode
          # 32     another definition for this keysym/scancode follows
          #
          # Negative row values:
          # 'keysym -1 n' joystick #1, direction n
          # 'keysym -2 n' joystick #2, direction n
          # 'keysym -3 0' first RESTORE key
          # 'keysym -3 1' second RESTORE key
          # 'keysym -4 0' 40/80 column key
          # 'keysym -4 1' CAPS (ASCII/DIN) key
          #
          
          # this is a PET business (uk) keyboard mapping (symbolic)
          
          # Business (UK) keyboard matrix:
          #
          # Keys starting with 'KP' are on the number pad.
          #
          #       0        1        2        3        4        5        6        7
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 0 |   2    |   5    |   8    |   -    |  KP8   |crsr rgt|  ^N    |   .    |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 1 |   1    |   4    |   7    |   0    |  KP7   |   ^    |--------|  KP9   |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 2 | escape |   s    |   f    |   h    |   ]    |   k    |   ;    |  KP5   |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 3 |   a    |   d    |   g    |   j    | return |   l    |   @    |  KP6   |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 4 |  tab   |   w    |   r    |   y    |   \    |   i    |   p    |  del   |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 5 |   q    |   e    |   t    |   u    |crsr dwn|   o    |   [    |  KP4   |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 6 |l shift |   c    |   b    |   .    |  KP.   |  ^Y    |r shift |  KP3   |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 7 |   z    |   v    |   n    |   ,    |  KP0   |  ^O    | repeat |  KP2   |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 8 |  RVS   |   x    | space  |   m    | home   |  ^U    |   /    |  KP1   |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 9 |  <--   |   3    |   6    |   9    |runstop |   :    |--------|  ^V    |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          #
          #   ^N = both shifts + 2
          #   ^Y = left shift + TAB + I
          #   ^O = Z + A + L
          #   ^U = RVS + A + L
          #   ^V = TAB + <- + DEL
          #
          # Business (US) matrix (differences to UK)
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 2 |        |        |        |        |   ;    |        |   \    |        |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 3 |        |        |        |        |        |        |   [    |        |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 4 |        |        |        |        |   @    |        |        |        |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          # 5 |        |        |        |        |        |        |   ]    |        |
          #   +--------+--------+--------+--------+--------+--------+--------+--------+
          
          !CLEAR
          !LSHIFT 6 0
          !RSHIFT 6 6
          !VSHIFT RSHIFT
          
          8 0 5 1         /*         Bksp -> CRSR LEFT    */
          9 4 0 8         /*          TAB -> TAB          */
          13 3 4 32       /*       Return -> Return       */
          13 7 4 161      /* shift+Return -> shift+KP0    */
          13 7 4 1025     /*  crtl+Return -> shift+KP0    */
          27 2 0 8        /*          ESC -> ESC          */
          32 8 2 8        /*        Space -> Space        */
          39 1 2 33       /*            ' -> '            */
          39 0 0 128      /*      shift+' -> "            */
          44 7 3 8        /*            , -> ,            */
          45 0 3 32       /*            - -> -            */
          45 9 0 128      /*      shift+- -> _            */
          46 6 3 8        /*            . -> .            */
          47 8 6 8        /*            / -> /            */
          48 1 3 32       /*            0 -> 0            */
          48 9 3 128      /*      shift+0 -> )            */
          49 1 0 8        /*            1 -> 1            */
          50 0 0 32       /*            2 -> 2            */
          50 3 6 144      /*      shift+2 -> @            */
          51 9 1 8        /*            3 -> 3            */
          52 1 1 8        /*            4 -> 4            */
          53 0 1 8        /*            5 -> 5            */
          54 9 2 32       /*            6 -> 6            */
          54 1 5 144      /*      shift+6 -> ^            */
          55 1 2 32       /*            7 -> 7            */
          55 9 2 128      /*      shift+7 -> &            */
          56 0 2 32       /*            8 -> 8            */
          56 9 5 128      /*      shift+8 -> *            */
          57 9 3 32       /*            9 -> 9            */
          57 0 2 128      /*      shift+9 -> (            */
          59 2 6 32       /*            ; -> ;            */
          59 9 5 144      /*      shift+; -> ;            */
          61 0 3 33       /*            = -> =            */
          61 2 6 128      /*      shift+= -> +            */
          91 5 6 32       /*            [ -> [            */
          91 2 7 1025     /*       ctrl+[ -> shift+KP5    */
          92 4 4 8        /*            \ -> \            */
          93 2 4 8        /*            ] -> ]            */
          96 3 6 33       /*            ` -> `            */
          96 1 5 128      /*      shift+` -> ~            */
          97 3 0 8        /*            A -> A            */
          98 6 2 32       /*            B -> B            */
          98 1 7 1025     /*       ctrl+B -> shift+KP9    */
          99 6 1 32       /*            C -> C            */
          99 9 4 1024     /*       ctrl+C -> STOP         */
          100 3 1 8       /*            D -> D            */
          101 5 1 32      /*            E -> E            */
          101 2 7 1025    /*       ctrl+E -> shift+KP5    */
          102 2 2 32      /*            F -> F            */
          102 6 4 1025    /*       ctrl+F -> shift+KP.    */
          103 3 2 8       /*            G -> G            */
          104 2 3 32      /*            H -> H            */
          104 0 5 1025    /*       ctrl+H -> CRSR LEFT    */
          105 4 5 32      /*            I -> I            */
          105 7 4 1025    /*       ctrl+I -> shift+KP0    */
          106 3 3 32      /*            J -> J            */
          106 5 4 1024    /*       ctrl+J -> CRSR DOWN    */
          107 2 5 32      /*            K -> K            */
          107 5 4 1025    /*       ctrl+K -> CRSR UP      */
          108 3 5 32      /*            L -> L            */
          108 0 5 1024    /*       ctrl+L -> CRSR RIGHT   */
          109 8 3 8       /*            M -> M            */
          110 7 2 8       /*            N -> N            */
          111 5 5 32      /*            O -> O            */
          111 7 7 1025    /*       ctrl+O -> shift+KP2    */
          112 4 6 8       /*            P -> P            */
          113 5 0 8       /*            Q -> Q            */
          114 4 2 8       /*            R -> R            */
          115 2 1 8       /*            S -> S            */
          116 5 2 8       /*            T -> T            */
          117 5 3 8       /*            U -> U            */
          118 7 1 8       /*            V -> V            */
          119 4 1 8       /*            W -> W            */
          120 8 1 8       /*            X -> X            */
          121 4 3 8       /*            Y -> Y            */
          122 7 0 8       /*            Z -> Z            */
          127 4 7 8       /*          Del -> Del          */
          256 7 4 8       /*          KP0 -> KP0          */
          257 8 7 8       /*          KP1 -> KP1          */
          258 7 7 8       /*          KP2 -> KP2          */
          259 6 7 8       /*          KP3 -> KP3          */
          260 5 7 8       /*          KP4 -> KP4          */
          261 2 7 8       /*          KP5 -> KP5          */
          262 3 7 8       /*          KP6 -> KP6          */
          263 1 4 8       /*          KP7 -> KP7          */
          264 0 4 8       /*          KP8 -> KP8          */
          265 1 7 8       /*          KP9 -> KP9          */
          266 6 4 8       /*          KP. -> KP.          */
          267 8 6 16      /*          KP/ -> /            */
          268 9 5 1       /*          KP* -> *            */
          269 0 3 16      /*          KP- -> -            */
          270 2 6 1       /*          KP+ -> +            */
          271 3 4 8       /*     KP Enter -> Return       */
          273 5 4 1       /*           Up -> CRSR UP      */
          274 5 4 8       /*         Down -> CRSR DOWN    */
          275 0 5 32      /*        Right -> CRSR RIGHT   */
          275 4 7 176     /*  shift+Right -> Del          */
          275 4 7 1040    /*   ctrl+Right -> Del          */
          276 0 5 33      /*         Left -> CRSR LEFT    */
          276 4 7 160     /*   shift+Left -> shift+Del    */
          276 4 7 1024    /*    ctrl+Left -> shift+Del    */
          277 4 7 1       /*          Ins -> shift+Del    */
          278 8 4 8       /*         Home -> CLR/HOME     */
          279 2 7 1       /*          End -> shift+KP5    */
          280 1 7 1       /*      Page Up -> shift+KP9    */
          281 6 4 1       /*    Page Down -> shift+KP.    */
          303 6 6 4       /*  Right Shift -> Right Shift  */
          304 6 0 2       /*   Left Shift -> Left Shift   */
          
          Note that shift or control cursor left and right also function as insert and delete.

          After this I deleted most of the alt+key shortcuts for accessing things on the configuration menu because there were too many. This was done by creating a file called sdl-hotkey-PET.vkm, again in the .config/vice subdirectory. This file reads

          Code: Select all

          # VICE hotkey mapping file
          #
          # A hotkey map is read in as a patch to the current map.
          #
          # File format:
          # - comment lines start with '#'
          # - keyword lines start with '!keyword'
          # - normal line has 'keynum path&to&menuitem'
          #
          # Keywords and their lines are:
          # '!CLEAR'    clear all mappings
          #
          
          !CLEAR
          
          # ALT+L
          1132 Snapshot&Load snapshot image
          # ALT+P
          1136 Pause
          # ALT+Q
          1137 Quit emulator
          # ALT+S
          1139 Snapshot&Save snapshot image&Select filename and save snapshot
          # ALT+W
          1143 Speed settings&Warp mode
          
          Finally, I changed my .xsession file to map the VICE configuration menu to F1 and used xmodmap to identify the right control key with the left. These were done because the Chromebook doesn't have 12 function keys and VICE does not normally consider the right control key to be anything other than an ordinary button otherwise. I have edited the previous post

          viewtopic.php?p=1753110#p1753110

          to reflect the new version of .xsession, so I will not reproduce it here.

          Woohoo! Now I can connect to the SuperPET emulator running on the Pi 4B using remote desktop from any computer in the house. This might be better than a real super pet.

          viewtopic.php?p=1564477#p1564477

          At least it's not likely to jump off the roof.

          ejolson
          Posts: 8628
          Joined: Tue Mar 18, 2014 11:47 am

          Re: A Birthday Present for Fido

          Sat Nov 07, 2020 5:22 pm

          ejolson wrote:
          Fri Nov 06, 2020 3:48 am
          This might be better than a real super pet.
          Although the subsequent lack of programming skills being learned by young people after the end of the golden age of 8-bit personal computing was eventually noticed by the boffins at Cambridge and other places, there were a number of prophetic statements made by many before industry noticed and the universities did something about it. Here is a telling remark published in the SuperPET Gazette, which quotes Don Littlefield on the trend in public interest around 1986:
            donlittlefield.png
            donlittlefield.png (216.53 KiB) Viewed 1665 times
            The SuperPET Gazette, Vol. 2, No. 11, June-July 1986, page 305
            http://6502.org/documents/publications/ ... t_gazette/

            It is interesting that it took 26 years for the Raspberry Pi to finally reverse the trend of converting general purpose computers into televisions, typewriters and telephones. There is again a system on the market that comes with a variety of programming languages pre-installed that makes it easy for a beginner to start learning computer science. The full circle aspects of this whole process seems uniquely typified by the Pi 400, which finally insists that the computer again have a 'socially demeaning' keyboard.

            The days are over in which the child pampered by new electronic gadgets is put at a disadvantage!

            Instead of tablets, phones and game consoles, there is finally an option for a child (as well as an adult) to be gifted with a device that includes the keyboard and all the software tools needed for it to function, like a SuperPET, by default as a real programmable computer--just in time for Christmas.

            Heater
            Posts: 18758
            Joined: Tue Jul 17, 2012 3:02 pm

            Re: A Birthday Present for Fido

            Sat Nov 07, 2020 6:34 pm

            I was thinking that Don Littlefield was very prophetic there.

            Except .. the part about "no more complex that the telephone". Turns out the telephone became extinct and was replaced with something a thousand times more complex to use and far more annoying. Probably because of the "socially demeaning" need for a rotary dial on telephones, and later the "socially demeaning" touch tone keypads.

            I do like the Don's "vast minority" expression though.
            ejolson wrote:
            Sat Nov 07, 2020 5:22 pm
            ...a real programmable computer--just in time for Christmas....
            Wow, remember those days when every 8 bit computer vendor worked feverishly to get their next thing out for Christmas? Mostly because kids wanted to play games of course.

            I doubt any kid got a SuperPET for Christmas. Most would have been mightily upset with Santa if they did.
            Memory in C++ is a leaky abstraction .

            ejolson
            Posts: 8628
            Joined: Tue Mar 18, 2014 11:47 am

            Re: A Birthday Present for Fido

            Sat Nov 07, 2020 7:03 pm

            Heater wrote:
            Sat Nov 07, 2020 6:34 pm
            I doubt any kid got a SuperPET for Christmas. Most would have been mightily upset with Santa if they did.
            I don't think I'd have been unhappy with a super pet for Christmas or even a puppy. These days, however, I might prefer the white scarf and goggles, especially when compared to the N95 face mask needed for today's commercial flights.

            Heater
            Posts: 18758
            Joined: Tue Jul 17, 2012 3:02 pm

            Re: A Birthday Present for Fido

            Sat Nov 07, 2020 7:26 pm

            I'm really getting into that "white scarf and goggles" idea.

            Sounds like just the thing to adorn the anti-covid mask when visiting the local store. I have a bomber jacket to go with it somewhere...

            See how fetching I will be. Biggles flies undone:

            Image
            Memory in C++ is a leaky abstraction .

            ejolson
            Posts: 8628
            Joined: Tue Mar 18, 2014 11:47 am

            Re: A Birthday Present for Fido

            Sun Nov 08, 2020 4:31 am

            Heater wrote:
            Sat Nov 07, 2020 7:26 pm
            Biggles flies undone:
            Dashing. That's the requisite scarf and goggles. I noticed that volume 12 in the series is Biggles--Air Commodore.

            Speaking of Commodore, when I showed the dog developer my Flops result for the Euler-Mascheroni constant, the usually floppy ears perked up and Fido growled, you can not compare the flops of a super pet properly unless the timings are taken when running the Linpack benchmark.

            Upon quickly ending the Zoom meeting for everyone, I wrote the necessary code to solve systems of linear equations in Pascal and obtained
              splinpack.png
              splinpack.png (43.14 KiB) Viewed 1553 times
                Note that the above run was performed with some debugging code accidentally left in. After I took that code out the speed increased to 21.69 Flops.

                For reference, the final program was

                Code: Select all

                program main(output);
                
                const n=10;
                type row=array[1..n] of real;
                    rowptr=^row;
                    matrix=array[1..n] of rowptr;
                    perm=array[1..n] of integer;
                
                var w,x:integer;
                    timelast:real;
                
                function frand:real;
                begin
                    x:=x*x+w;
                    w:=w+345;
                    frand:=x/65536.0+0.5
                end;
                procedure srand(s:integer);
                var z:real;
                begin
                    x:=s; w:=1;
                    z:=frand; z:=frand
                end;
                
                function getsec:real;
                const gettime_=-20228;
                var t:packed array[1..4] of char;
                begin
                    sysproc(gettime_,address(t));
                    getsec:=(ord(t[1])*60.0+ord(t[2]))*60.0
                            +ord(t[3])+ord(t[4])/100.0
                end;
                procedure tic;
                begin
                    timelast:=getsec
                end;
                function toc:real;
                begin
                    toc:=getsec-timelast
                end;
                
                procedure plufact(var a:matrix;var p:perm);
                var i,j,k,tint:integer;
                    trow:rowptr;
                    alpha:real;
                begin
                    for i:=1 to n do p[i]:=i;
                    for j:=1 to n do begin
                        for i:=j+1 to n do begin
                            if abs(a[j]^[j])<abs(a[i]^[j]) then begin
                                trow:=a[i]; a[i]:=a[j]; a[j]:=trow;
                                tint:=p[i]; p[i]:=p[j]; p[j]:=tint
                            end
                        end;
                        if a[j]^[j]=0 then begin
                            writeln('Exact singularity at j=',j:1)
                        end;
                        for i:=j+1 to n do begin
                            alpha:=a[i]^[j]/a[j]^[j];
                            for k:=j+1 to n do begin
                                a[i]^[k]:=a[i]^[k]-alpha*a[j]^[k]
                            end;
                            a[i]^[j]:=alpha
                        end
                    end
                end;
                
                procedure plusolve(var a:matrix;var p:perm;var x,b:row);
                var i,j:integer;
                    y:row;
                begin
                    for i:=1 to n do begin
                        y[i]:=b[p[i]];
                        for j:=1 to i-1 do begin
                            y[i]:=y[i]-a[i]^[j]*y[j]
                        end
                    end;
                    for i:=n downto 1 do begin
                        x[i]:=y[i];
                        for j:=i+1 to n do begin
                            x[i]:=x[i]-a[i]^[j]*x[j]
                        end;
                        x[i]:=x[i]/a[i]^[i]
                    end
                end;
                
                procedure matvecmul(var a:matrix;var x,b:row);
                var i,j:integer;
                begin
                    for i:=1 to n do b[i]:=0;
                    for i:=1 to n do begin
                        for j:=1 to n do begin
                            b[i]:=b[i]+a[i]^[j]*x[j]
                        end
                    end
                end;
                
                procedure vecprint(x:row);
                var i:integer;
                begin
                    for i:=1 to n do writeln(x[i])
                end;
                
                function check(var x:row):real;
                var r,dx:real;
                    i:integer;
                begin
                    r:=0;
                    for i:=1 to n do begin
                        dx:=x[i]-1;
                        r:=r+dx*dx
                    end;
                    check:=sqrt(r)
                end;
                
                procedure dotest;
                var i,j:integer;
                    a:matrix;
                    b,x:row;
                    p:perm;
                    t,f:real;
                
                begin
                    for i:=1 to n do new(a[i]);
                    for i:=1 to n do begin
                        for j:=1 to n do begin
                            a[i]^[j]:=1.0-2*frand
                        end
                    end;
                    for i:=1 to n do x[i]:=1;
                    matvecmul(a,x,b);
                    writeln('Gaussian elimination with partial pivoting');
                    writeln('Solving Ax=b with n=',n:1);
                    tic;
                    plufact(a,p);
                    plusolve(a,p,x,b);
                    t:=toc;
                    writeln;
                    writeln('error ',check(x));
                    writeln('elapsed ',t:8:2,' seconds.');
                    f:=2*(n/3.0+1)*n*n/t;
                    writeln('speed ',f:8:2,' flops.')
                end;
                
                begin
                    srand(6351);
                    dotest;
                end.
                
                The only interesting part, if there is anything interesting at all, is the random number generator used to create the random matrix A.

                I tried first the Fibonacci generator from the Simtel archive random.pas used for the CP/M version of Hunt the Wumpus mentioned previously.

                viewtopic.php?p=1742942#p1742942

                That generator kept creating random matrices that were singular. As the theoretical probability such a singularity ever occurs is zero percent, the only explanation I could come up with was that of a psychokinetic force.

                After a quick read of the Wikipedia article

                https://en.wikipedia.org/wiki/List_of_r ... generators

                I decided to try the first idea on the list: the middle-square method developed by John von Neumann in 1946.

                John apparently said, "anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin." Though perhaps that's the case for everyone, upon reflection, I decided "sin." might in this case be an abbreviation for singularity. Therefore, since a 16-bit number is not big enough to have a middle, I omitted that part of the algorithm but added a Weyl sequence along with a prayer that the resulting matrix be singular no more.

                Lack of singularity was confirmed for matrices up to size 1000x1000 on the Raspberry Pi at which point I realized the super pet would likely require a much smaller matrix.

                For comparing super computers I now present the following table:

                Code: Select all

                System     Cores    TFlops  KWatts TFlops/KWatt
                SuperPET       2  21.7e-12   0.220    9.9e-11
                Fugaku   7299072    415530   28335      14.66
                
                At least the phosphor is green. I wonder where the Raspberry Pi 400 would fit?
                Last edited by ejolson on Sun Nov 08, 2020 9:54 pm, edited 2 times in total.

                ejolson
                Posts: 8628
                Joined: Tue Mar 18, 2014 11:47 am

                Re: A Birthday Present for Fido

                Sun Nov 08, 2020 8:59 pm

                lurk101 wrote:
                Thu Nov 05, 2020 3:01 am
                Surprised no one caught it, but room 2 is connected to room 4 twice.

                Here's the bug fix. Add missing break statement.
                I've updated the dodecahedron detector with the missing break statement and to reduce differences made a few additional changes including

                s/\]\[/,/g

                to index the two dimensional arrays using a comma. Was that comma syntax part of the original Pascal?

                At any rate, the super cheap cluster of Pi Zero computers is back at work searching for dodecahedrons using the following code:

                Code: Select all

                program wumpus_cave(input,output);
                
                uses sysutils;
                
                const first_room=1;
                const last_room=20;
                const first_tunnel=1;
                const second_tunnel=2;
                const last_tunnel=3;
                
                type t_room_num=first_room..last_room;
                type t_tunnel_num=first_tunnel..last_tunnel;
                type t_cave=set of t_room_num;
                type t_cycle=array[t_room_num] of t_room_num;
                type t_room=array[t_tunnel_num] of integer;
                type t_amatrix=array[t_room_num] of array[t_room_num] of LongWord;
                
                var rooms:array[t_room_num] of t_room;
                var asearch,bsearch:LongWord;
                
                var cycle:t_cycle;
                var cave:t_cave;
                
                var r:t_room_num;
                var t:t_tunnel_num;
                
                { Swap the referenced parameters if the 1st is greater than the 2nd }
                procedure exchange(var i,j:integer);
                begin
                    if (i > j) then begin
                        i:=i xor j;
                        j:=i xor j;
                        i:=i xor j
                    end
                end;
                
                { Return number elements in cave set }
                function room_count:integer;
                var r:t_room_num;
                var n:integer;
                begin
                    n:=0;
                    for r:=first_room to last_room do
                        if r in cave then
                            n:=n+1;
                    room_count:=n
                end;
                
                { Randomly pick and return an element from the cave set }
                function random_pick:t_room_num;
                var r:t_room_num;
                var n:integer;
                begin
                    n:=Random(room_count);
                    for r:=first_room to last_room do
                        if r in cave then begin
                            if n=0 then
                                break;
                            n:=n-1
                        end;
                    random_pick:=r
                end;
                
                { Add a tunnel to room f connecting to room t }
                procedure add_directed_tunnel(f,t:t_room_num);
                begin
                    if rooms[f,first_tunnel]=-1 then
                        rooms[f,first_tunnel]:=t
                    else if rooms[f,second_tunnel]=-1 then
                        rooms[f,second_tunnel]:=t
                    else
                        rooms[f,last_tunnel]:=t
                end;
                
                { Add tunnel connecting two rooms }
                procedure add_tunnel(f,t:t_room_num);
                begin
                {    writeln('    ',f,'->',t); }
                    add_directed_tunnel(f,t);
                    add_directed_tunnel(t,f)
                end;
                
                { Delete a tunnel from room f connecting to room t }
                procedure del_directed_tunnel(f,t:t_room_num);
                var i,j:t_tunnel_num;
                begin
                    for i:=first_tunnel to last_tunnel do
                        if (rooms[f,i]=t) then begin
                            for j:=i to last_tunnel-1 do
                                rooms[f,j]:=rooms[f,j+1];
                            rooms[f,last_tunnel]:=-1;
                            break
                        end
                end;
                
                { Delete tunnel connecting two rooms }
                procedure del_tunnel(f,t:t_room_num);
                begin
                {    writeln('    delete ',f,'->',t);}
                    del_directed_tunnel(f,t);
                    del_directed_tunnel(t,f)
                end;
                
                { Return whether two rooms are neighbors }
                function neighbors(i,j:t_room_num):boolean;
                begin
                    neighbors:=(cycle[i]=j) or (cycle[j]=i)
                end;
                
                { Build a directed wumpus graph and room map }
                procedure directed_cave;
                var r,s,e,c,d:t_room_num;
                begin
                {    writeln('Directed graph');}
                
                    { Clear the tunnel map }
                    for r:=first_room to last_room do
                        for t:=first_tunnel to last_tunnel do
                            rooms[r,t]:=-1;
                
                    { Step 1 - Put the set of numbers 0 to 19 into an array and shuffle them.
                      Produce a bunch of connections, edges, that link all the nodes together
                      in a loop. To do this just assume that every element in the array
                      connects to the next one. And wrap around at the end. This ensures that
                      we will never get disjoint graphs, we have already connected everything
                      in a loop. }
                
                    { Just produce a random cycle directly }
                    r:=first_room;
                    cave:=[first_room..last_room]-[r];
                    repeat
                        e:=random_pick;
                        cave:=cave-[e];
                        add_tunnel(r,e);
                        cycle[r]:=e;
                        r:=e;
                    until cave=[];
                    cycle[r]:=first_room;
                    add_tunnel(r,first_room);
                
                    { Connect the remaining 10 edges }
                    cave:=[first_room..last_room];
                    repeat
                        { Step 2 - Looking at that nice loop it seems that if we pick any two,
                          different, nodes at random and connect them together we create two
                          nodes that both have the required number of exits, 3. Doing that
                          produces two connected loops. }
                        { Step 3 - Given that the two nodes connected above now have the
                          required 3 exits we can remove them from further consideration. So
                          remove them from the set of nodes. }
                        s:=random_pick;
                        cave:=cave-[s];
                        { Handle the special case where the last 2 nodes are neighbors }
                        if room_count>1 then
                            repeat e:=random_pick;
                                until not neighbors(s,e)
                        else
                            e:=random_pick;
                        cave:=cave-[e];
                        { if still neighbors then there were only 2 choices,
                          then handle the special case }
                        if neighbors(s,e) then begin
                            cave:=[first_room..last_room]-[s,e];
                            repeat c:=random_pick;
                                until (c<>s) and (c<>e) and (cycle[c]<>s) and (cycle[c]<>e);
                            d:=cycle[c];
                            del_tunnel(c,d);
                            add_tunnel(s,c);
                            add_tunnel(e,d);
                            break
                        end
                        else
                            add_tunnel(s,e)
                    { Repeat till graph is empty }
                    until cave=[];
                
                    { Finally, sort the tunnels }
                    for r:=first_room to last_room do begin
                        exchange(rooms[r,first_tunnel],rooms[r,second_tunnel]);
                        exchange(rooms[r,second_tunnel],rooms[r,last_tunnel]);
                        exchange(rooms[r,first_tunnel],rooms[r,second_tunnel])
                    end
                end;
                
                procedure imatmul(var a,b,c:t_amatrix);
                var i,j,k:t_room_num;
                begin
                    for i:=first_room to last_room do begin
                        for j:=first_room to last_room do begin
                            A[i,j]:=0
                        end
                    end;
                    for i:=first_room to last_room do begin
                        for k:=first_room to last_room do begin
                            for j:=first_room to last_room do begin
                                A[i,j]:=A[i,j]+B[i,k]*C[k,j]
                            end
                        end
                    end
                end;
                
                function maybedo():boolean;
                var i,j,v:t_room_num;
                    d:t_tunnel_num;
                    A,T,TT:t_amatrix;
                    p:integer;
                begin
                    maybedo:=true;
                    for i:=first_room to last_room do begin
                        for j:= first_room to last_room do begin
                            A[i,j]:=0
                        end
                    end;
                    for v:=first_room to last_room do begin
                        for d:=first_tunnel to last_tunnel do begin
                            j:=v;
                            i:=rooms[v,d];
                            A[i,j]:=1
                        end
                    end;
                    for i:=first_room to last_room do begin
                        for j:=first_room to last_room do begin
                            T[i,j]:=A[i,j]
                        end
                    end;
                    for p:=2 to 5 do begin
                        imatmul(TT,A,T);
                        for i:=first_room to last_room do begin
                            for j:=first_room to last_room do begin
                                A[i,j]:=TT[i,j]
                            end
                        end
                    end;
                    for v:=first_room to last_room do begin
                        if A[v,v]<>6 then maybedo:=false
                    end
                end;
                
                procedure cdump(k:LongWord);
                begin
                    { Dump the cave map }
                    writeln;
                    writeln('Wumpus cave',k:1);
                    for r:=first_room to last_room do
                        writeln('    ',rooms[r,first_tunnel],' ',rooms[r,second_tunnel],
                            ' ',rooms[r,last_tunnel])
                end;
                
                procedure cgraph(k:LongWord);
                var r:t_room_num;
                    t:t_tunnel_num;
                begin
                    { Graph the cave map }
                    writeln('graph s',k:1,' {');
                    writeln('    overlap=false');
                    writeln('    splines=true');
                    writeln('    sep=1.0');
                    for r:=first_room to last_room do begin
                        for t:=first_tunnel to last_tunnel do begin
                            if r<rooms[r,t] then begin
                                writeln('    ',r:1,' -- ',rooms[r,t]:1)
                            end
                        end
                    end;
                    writeln('}');
                    flush(output)
                end;
                
                procedure dmake;
                begin
                    { Make a dodecahedron the easy way (sort of) }
                    rooms[1,1]:=2; rooms[1,2]:=5; rooms[1,3]:=8;
                    rooms[2,1]:=1; rooms[2,2]:=3; rooms[2,3]:=10;
                    rooms[3,1]:=2; rooms[3,2]:=4; rooms[3,3]:=12;
                    rooms[4,1]:=3; rooms[4,2]:=5; rooms[4,3]:=14;
                    rooms[5,1]:=1; rooms[5,2]:=4; rooms[5,3]:=6;
                
                    rooms[6,1]:=5; rooms[6,2]:=7; rooms[6,3]:=15;
                    rooms[7,1]:=6; rooms[7,2]:=8; rooms[7,3]:=17;
                    rooms[8,1]:=1; rooms[8,2]:=7; rooms[8,3]:=9;
                    rooms[9,1]:=8; rooms[9,2]:=10; rooms[9,3]:=18;
                    rooms[10,1]:=2; rooms[10,2]:=9; rooms[10,3]:=11;
                
                    rooms[11,1]:=10; rooms[11,2]:=12; rooms[11,3]:=19;
                    rooms[12,1]:=3; rooms[12,2]:=11; rooms[12,3]:=13;
                    rooms[13,1]:=12; rooms[13,2]:=14; rooms[13,3]:=20;
                    rooms[14,1]:=4; rooms[14,2]:=13; rooms[14,3]:=15;
                    rooms[15,1]:=6; rooms[15,2]:=14; rooms[15,3]:=16;
                
                    rooms[16,1]:=15; rooms[16,2]:=17; rooms[16,3]:=20;
                    rooms[17,1]:=7; rooms[17,2]:=16; rooms[17,3]:=18;
                    rooms[18,1]:=9; rooms[18,2]:=17; rooms[18,3]:=19;
                    rooms[19,1]:=11; rooms[19,2]:=18; rooms[19,3]:=20;
                    rooms[20,1]:=13; rooms[20,2]:=16; rooms[20,3]:=19;
                end;
                
                procedure dfind(a,b:LongWord);
                    var k:LongWord;
                begin
                    b:=b-1;
                    for k:=a to b do begin
                        { Seed the RNG }
                        RandSeed:=k;
                        { Generate the cave }
                        directed_cave;
                        if maybedo then begin
                            cgraph(k)
                        end
                    end
                end;
                
                begin
                    asearch:=0;
                    bsearch:=1000;
                    if paramCount()=2 then begin
                        asearch:=StrToInt(paramStr(1));
                        bsearch:=StrToInt(paramStr(2))
                    end;
                    writeln('Checking seeds ',asearch:1,' up to but not including ',
                        bsearch:1,'...');
                    flush(output);
                    dmake;
                    if not maybedo then writeln('Something is wrong!');
                    dfind(asearch,bsearch)
                end.
                
                Note that I launched five copies of this code across the cluster to search seeds from 0 to 499999999 in parallel using the Slurm batch files

                Code: Select all

                $ head *.slm
                ==> 0Mto1M.slm <==
                #!/bin/bash
                time ./wsearch 0 100000000
                
                ==> 1Mto2M.slm <==
                #!/bin/bash
                time ./wsearch 100000000 200000000
                
                ==> 2Mto3M.slm <==
                #!/bin/bash
                time ./wsearch 200000000 300000000
                
                ==> 3Mto4M.slm <==
                #!/bin/bash
                time ./wsearch 300000000 400000000
                
                ==> 4Mto5M.slm <==
                #!/bin/bash
                time ./wsearch 400000000 500000000
                
                submitted as

                Code: Select all

                $ for i in *.slm; do sbatch $i; done
                Submitted batch job 688
                Submitted batch job 689
                Submitted batch job 690
                Submitted batch job 691
                Submitted batch job 692
                
                The results should be ready in a few days. Do you think any new dodecahedrons will be found compared to last time?

                lurk101
                Posts: 1066
                Joined: Mon Jan 27, 2020 2:35 pm
                Location: Cumming, GA (US)

                Re: A Birthday Present for Fido

                Sun Nov 08, 2020 9:22 pm

                Did I miss your dodecahedron detector? Found it!

                This brings me back to my first contact with Pascal. I'd forgotten being blown away with its elegance and simplicity. Things like user types, ranges, sets, nested procedures were all new and empowering concepts (in my case anyway). An escape from the prevalent interpreted Basic with a half decent Pascal compiler and development GUI.

                lurk101
                Posts: 1066
                Joined: Mon Jan 27, 2020 2:35 pm
                Location: Cumming, GA (US)

                Re: A Birthday Present for Fido

                Sun Nov 08, 2020 10:12 pm

                Another significant retro computer and probably the least known machine ever. Fired up a cycle accurate emulation of the Acorn Archimedes series.
                20201108_215901-screen.png
                20201108_215901-screen.png (5.08 KiB) Viewed 1435 times
                It featured an early ARM2 or ARM3A RISC processor, the beginnings of a now dominant architecture.

                ejolson
                Posts: 8628
                Joined: Tue Mar 18, 2014 11:47 am

                Re: A Birthday Present for Fido

                Sun Nov 08, 2020 10:44 pm

                lurk101 wrote:
                Sun Nov 08, 2020 10:12 pm
                Another significant retro computer and probably the least known machine ever. Fired up a cycle accurate emulation of the Acorn Archimedes series.
                Nice screenshot. Maybe that should be the next emulator to set up for remote desktop login and access. I'm certain Fido would like it! Did the Archimedes include any programming languages other than Basic?

                ejolson
                Posts: 8628
                Joined: Tue Mar 18, 2014 11:47 am

                Re: A Birthday Present for Fido

                Sun Nov 08, 2020 10:57 pm

                lurk101 wrote:
                Sun Nov 08, 2020 9:22 pm
                Did I miss your dodecahedron detector? Found it!

                This brings me back to my first contact with Pascal. I'd forgotten being blown away with its elegance and simplicity. Things like user types, ranges, sets, nested procedures were all new and empowering concepts (in my case anyway). An escape from the prevalent interpreted Basic with a half decent Pascal compiler and development GUI.
                Sounds like Turbo Pascal! I also recall being astonished at how well the original IDE worked. Even without memory protection it didn't require rebooting the entire computer for every program bug. I became so fond of Turbo Pascal that I have since placed the original documentation right next to the binder describing HP2000F Time Shared Basic as a sentimental keepsake. Even though most processors these days have built-in memory protection hardware, it seems modern languages like Go and Rust still include range checking in software just to be sure.

                Heater
                Posts: 18758
                Joined: Tue Jul 17, 2012 3:02 pm

                Re: A Birthday Present for Fido

                Sun Nov 08, 2020 11:54 pm

                ejolson wrote:
                Sun Nov 08, 2020 10:57 pm
                Even though most processors these days have built-in memory protection hardware, it seems modern languages like Go and Rust still include range checking in software just to be sure.
                That is a thought that has crossed my mind for many years now.

                The virtual memory systems we have today are not much use for array bounds checks as they were on huge, fixed size, blocks of memory.

                If modern processors included hardware such that an array was not just a pointer in a register or whatever but also included the array size, then they could implement array bounds checks.

                Rather than do that to ensure programs are behaving themselves whilst maintaining performance processor designers have been using millions of transistors on things like branch predictors that enable malicious programs to do even more bad things :(

                The neat thing about Rust is that most of the time the compiler can optimize away array bounds checks, especially if one uses iterators rather than C style array indexing in "for" loops. No performance hit.
                Memory in C++ is a leaky abstraction .

                lurk101
                Posts: 1066
                Joined: Mon Jan 27, 2020 2:35 pm
                Location: Cumming, GA (US)

                Re: A Birthday Present for Fido

                Mon Nov 09, 2020 12:02 am

                ejolson wrote:
                Sun Nov 08, 2020 10:57 pm
                lurk101 wrote:
                Sun Nov 08, 2020 9:22 pm
                Did I miss your dodecahedron detector? Found it!

                This brings me back to my first contact with Pascal. I'd forgotten being blown away with its elegance and simplicity. Things like user types, ranges, sets, nested procedures were all new and empowering concepts (in my case anyway). An escape from the prevalent interpreted Basic with a half decent Pascal compiler and development GUI.
                Sounds like Turbo Pascal!
                And before that on the Burroughs B6700 mainframe.

                lurk101
                Posts: 1066
                Joined: Mon Jan 27, 2020 2:35 pm
                Location: Cumming, GA (US)

                Re: A Birthday Present for Fido

                Mon Nov 09, 2020 12:09 am

                Heater wrote:
                Sun Nov 08, 2020 11:54 pm
                If modern processors included hardware such that an array was not just a pointer in a register or whatever but also included the array size, then they could implement array bounds checks.
                This is the very thing that was implemented on the Burroughs B6700 series mainframes. A variable or container was only accessible via a descriptor containing position in memory, size, and access rights. These descriptors could only reside on the stack and it had no registers per se.
                Any bounds or access violation caused an fault.

                lurk101
                Posts: 1066
                Joined: Mon Jan 27, 2020 2:35 pm
                Location: Cumming, GA (US)

                Re: A Birthday Present for Fido

                Mon Nov 09, 2020 12:14 am

                ejolson wrote:
                Sun Nov 08, 2020 10:44 pm
                lurk101 wrote:
                Sun Nov 08, 2020 10:12 pm
                Another significant retro computer and probably the least known machine ever. Fired up a cycle accurate emulation of the Acorn Archimedes series.
                Nice screenshot. Maybe that should be the next emulator to set up for remote desktop login and access. I'm certain Fido would like it! Did the Archimedes include any programming languages other than Basic?
                Still looking for language disks. Seems they exist for many languages such as Fortran and Pascal, but only in a format suitable for the more popular software emulators. The screen shot above was taken from an FPGA based emulator which does have an controlling Unix system to emulate disk and floppies, but not supporting the common formats!

                User avatar
                Paeryn
                Posts: 3366
                Joined: Wed Nov 23, 2011 1:10 am
                Location: Sheffield, England

                Re: A Birthday Present for Fido

                Mon Nov 09, 2020 12:28 am

                ejolson wrote:
                Sun Nov 08, 2020 8:59 pm
                I've updated the dodecahedron detector with the missing break statement and to reduce differences made a few additional changes including

                s/\]\[/,/g

                to index the two dimensional arrays using a comma. Was that comma syntax part of the original Pascal?
                Yes, I wouldn't have thought to not use the comma, at least I wouldn't have way back when I was doing my A-levels before I learnt C.

                You can use it when defining the type too so instead of

                Code: Select all

                type t_amatrix=array[t_room_num] of array[t_room_num] of LongWord;
                
                you can write it as

                Code: Select all

                type t_amatrix=array[t_room_num, t_room_num] of LongWord;
                
                She who travels light — forgot something.
                Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

                Heater
                Posts: 18758
                Joined: Tue Jul 17, 2012 3:02 pm

                Re: A Birthday Present for Fido

                Mon Nov 09, 2020 12:45 am

                lurk101 wrote:
                Mon Nov 09, 2020 12:09 am
                Heater wrote:
                Sun Nov 08, 2020 11:54 pm
                If modern processors included hardware such that an array was not just a pointer in a register or whatever but also included the array size, then they could implement array bounds checks.
                This is the very thing that was implemented on the Burroughs B6700 series mainframes. A variable or container was only accessible via a descriptor containing position in memory, size, and access rights. These descriptors could only reside on the stack and it had no registers per se.
                Any bounds or access violation caused an fault.
                That sounds awesome. I want one.

                As wikipedia says " It was optimized for compiling ALGOL 60 programs extremely well". In ALGOL erroneous programs were not allowed to crash and burn. Program errors, like exceeding array bounds, were to halt with sensible error messages.

                If Ken Thompson and co. had a Burroughs to create Unix on instead of a PDP-7 then C would have been a memory safe language from the get go and the world would be a very different place.

                Actually, I think Intel did this with their i432 processor design. I recall reading the i432 data book and it had all kind of stuff in there about descriptors and objects. Again the i432 was designed to support a safe language, Ada. Sadly the i432 turned out to be too big, too expensive an too slow and the project was canned. So we ended up with the 8086 instead :(
                Memory in C++ is a leaky abstraction .

                User avatar
                Paeryn
                Posts: 3366
                Joined: Wed Nov 23, 2011 1:10 am
                Location: Sheffield, England

                Re: A Birthday Present for Fido

                Mon Nov 09, 2020 1:08 am

                Intel tried to implement bounds checking on pointers in x86/64 with the MPX extension in Skylake (about 5 years ago). It was so impressive at being flawed that compilers don't support it any more (GCC dropped it from version 9).
                She who travels light — forgot something.
                Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!

                lurk101
                Posts: 1066
                Joined: Mon Jan 27, 2020 2:35 pm
                Location: Cumming, GA (US)

                Re: A Birthday Present for Fido

                Mon Nov 09, 2020 3:09 am

                Paeryn wrote:
                Mon Nov 09, 2020 1:08 am
                Intel tried to implement bounds checking on pointers in x86/64 with the MPX extension in Skylake (about 5 years ago). It was so impressive at being flawed that compilers don't support it any more (GCC dropped it from version 9).
                It is more difficult in C due to the equivalence between an array reference and a pointer dereference. a[x] is equivalent to *(a+x), and to make things worse aliasing is a common pattern in C code.

                Heater
                Posts: 18758
                Joined: Tue Jul 17, 2012 3:02 pm

                Re: A Birthday Present for Fido

                Mon Nov 09, 2020 7:06 am

                lurk101 wrote:
                Mon Nov 09, 2020 3:09 am
                It is more difficult in C due to the equivalence between an array reference and a pointer dereference. a[x] is equivalent to *(a+x), and to make things worse aliasing is a common pattern in C code.
                Quite so.

                I imagine it's totally impossible. For example C does not have strings. So there isn't even a notion of length one could use to bounds check against!

                Or when mallocing a space for an array one gets a void*, not only does that not have a length it's not even a thing anyway.

                I did hear a member of the C++ standards committee opining that C++ should get rid of that business of arrays decaying to pointers. The cause of so many problems and of no use. I guess that is never going to happen.
                Memory in C++ is a leaky abstraction .

                lurk101
                Posts: 1066
                Joined: Mon Jan 27, 2020 2:35 pm
                Location: Cumming, GA (US)

                Re: A Birthday Present for Fido

                Mon Nov 09, 2020 7:29 am

                There is an excellent tutorial here on running the Acorn Archimedes arcem emulator on the Raspberry Pi. It works quite well!

                ejolson
                Posts: 8628
                Joined: Tue Mar 18, 2014 11:47 am

                Re: A Birthday Present for Fido

                Mon Nov 09, 2020 4:33 pm

                Heater wrote:
                Mon Nov 09, 2020 7:06 am
                lurk101 wrote:
                Mon Nov 09, 2020 3:09 am
                It is more difficult in C due to the equivalence between an array reference and a pointer dereference. a[x] is equivalent to *(a+x), and to make things worse aliasing is a common pattern in C code.
                Quite so.

                I imagine it's totally impossible. For example C does not have strings. So there isn't even a notion of length one could use to bounds check against!

                Or when mallocing a space for an array one gets a void*, not only does that not have a length it's not even a thing anyway.

                I did hear a member of the C++ standards committee opining that C++ should get rid of that business of arrays decaying to pointers. The cause of so many problems and of no use. I guess that is never going to happen.
                In my opinion these features of C are so much a part of the simple is better than correct philosophy of the original design, that there is no way to remove them from the present language while maintaining compatibility with the valuable legacy of existing code. To fix these problems it used to be necessary to go build your own language. These days Ken Thompson of wump.c fame along with Rob Pike and Robert Griesemer have already done so with the use of slices in the Go language.

                According to the dog developer, although tiered three-level segmented memory addressing is more efficient, the 64-bit virtual address space of more primitive processors such as used in the Pi 400 is sufficient for address randomisation to catch buffer overflows using per-malloc page mapping.

                This is employed in present-day versions of OpenBSD.
                Wikipedia wrote: The malloc implementation now in OpenBSD makes use of the mmap system call, which was modified so that it returns random memory addresses and ensures that different areas are not mapped next to each other. In addition, allocation of small blocks in shared areas are now randomized and the free function was changed to return memory to the kernel immediately rather than leaving it mapped into the process.
                https://en.m.wikipedia.org/wiki/OpenBSD ... y_features

                I recently watched an interview with Theo on performance challenges in OpenBSD. Getting the kernel to quickly create and tear down all those randomised virtual pages has been receiving lots of focus. I wonder if they have mitigated against psychokinetic influences that could be used to bias the random addresses in a way that makes a dodecahedron out of their memory map.

                Return to “Other projects”