Tuesday, January 22, 2019

Basic and Fortran programs to read temperature and pressure from the BMP driver on the PiDP-11/70

    In my last entry, I wrote about a program to read the BMP180 temperature and pressure sensor connected to a PiDP-11/70, and running the BM device driver.

  That example was written in Macro-11. I understand that not every RSX enthusiast is proficient in that language, so I coded  examples in BASIC-Plus 2 and Fortran 77.

  They do the usual - assign a LUN, and do a QIOW (via WTQIO). The results are formatted and printed out - what could be easier? The conversion of the data was a lot easier in BP2 and F77  than it was in Macro, that's for certain. It did actually take me a few hours to write this - I've written thousands of lines of BP2, but that was circa 1982 - the language has changed quite a bit in the ensuing decades. And, I thought I had written my last FORMAT statement decades ago, but, here one is in the F77 example.


  Here they are....

getoneb.b2s

getonef.ftn

  To use them, compile and link like any other BP2 or F77 program. They will return the temperature and pressure in Celsius, Fahrenheit, Bars and Inches of mercury.

>run getoneb
Temp C 22.60, Temp F 72.68, Press B 1.0171,Press Hg 30.03

>run getonef
Temp C 22.60 Temp F 72.68 Press B 1.0171 Press Hg 30.03

Friday, January 18, 2019

Program to read temperature and pressure from the BMP180 driver on a PiDP-11/70

 In our last chapter, we discussed adding a BMP180 to a PiDP11, and adding a device driver to RSX to read it (and when I say RSX, I'm talking RSX11 M-Plus).

  If you followed all that and got the thing assembled and built, loaded and connected, you were rewarded with an online, ready device...

>DEV BM0:
BM0: Loaded
>

  But, that's not all that useful, or interesting. One presumes that if there is a device there, it would be good to see some data out of it.

  So it's time for a demo program. All you have to do is assign a channel to the device, and then do an IO.RLB QIOW to it. What could be easier?

  I wrote getone.mac to do just that. It also converts the data to ASCII, in units we are familiar with - the BMP180 returns data as Celsius*100 , and Bars*10000 - I converted to degrees F and Bars, then write 'em out for your viewing pleasure.

  So, here's the code....reading the values from the device is about 4 or 5 lines of code - the rest was arithmetic and formatting.

getone.mac

  To use it, assemble and link it...

mac getone=getone
tkb getone=getone

Then run it...

>run getone
Temperature 76.20 degrees F. Pressure 1.0116 bar.

  Whew...starting to get a little warm in here...time to open the door and let a little winter air in. Next entry, I'll show a couple of high level language examples, for people who aren't familiar with Macro-11.

RSX11 M-Plus device driver for the BMP180 sensor on the PiDP-11/70

  I mentioned in the previous post that I now have a PiDP-11/70. This is a scale model of the front console of a PDP-11/70. It's controlled by  SIMH, running on a Raspbery PI. 

  The creator of this product, Oscar Vermuelen, has detailed how to extend the hardware of the PiDP-11, by connecting things to the I2C bus of the Raspberry Pi (most of the other GPIO pins are used to drive the console, but I2C was not used).

  As an example, he detailed what it would take to connect a BMP180 temperature and pressure sensor to the device, and how to add support for it to SIMH, so it could be "seen" by the virtual PDP-11 and the front panel. All of this work is detailed in http://obsolescence.wixsite.com/obsolescence/pidp-11-temp-barometer-hack.

  I undertook to do this, and, with a bit of a struggle allocating vectors that SIMH was happy with (SIMH was unhappy with a lot of the unassigned vectors I tried - I finally found it was happy with 360 and 364) I got it to work. Oscar's example used the vectors used by the paper tape devices, but I had to use new ones, since I wanted the paper tape devices to also be available, and devices can't share vectors. 

  At this point, it was possible to read the temperature and pressure, both using the lights and switches on the console, and from the SIMH command line.

  But that's only the first step of the journey. I'd like to be able to read the temperature from a program running under RSX, with an eye to displaying it and logging it.

  There are several ways to access device data in RSX. The easiest and simplest way is to write a privileged program. Privileged programs (usually) have their highest addresses mapped to the IO page of the system, so they can access device registers with simple memory reads and writes. But this is a limited trivial sort of approach, not very flexible or general, and fraught with potential for problems, if a bug causes reads and writes to go where they shouldn't. 

  The best way to access a device under RSX is a device driver. A device driver accepts requests for access to a device, and then it handles the actual IO in a (hopefully) controlled manner. A device driver also does not consume an eighth of the address space in your program to map the IO page - and lack of memory in your address space is often a problem on RSX,  since you only get 64KB of it (neglecting I&D space and supervisor mode for the moment). It also presents a uniform interface for IO, and does some  processing of the data, so it doesn't have to be included in every program that wants to access the device.

  This is a simple device, so it doesn't take a very complicated device driver to deal with it. BMDRV is a minimal implementation of a driver that can read the pressure and temperature. It only acts on read logical block requests, and returns 2 words - the first is the Celsius temperature*100. The second word is the pressure, in Bars*10000.

  Here's the data table part of the driver

bmtab.mac

  And here's the code part of the driver. 


bmdrv.mac

  To use this, first, connect the BMP180 chip to the I2C bus on your Raspberry PI. Like I said above, how to do this is documented on Oscar's page.

  Then, modify the SIMH sources, per Oscar's document mentioned above. However, use vectors 360 and 364 for the new devices you create - don't use the existing vectors to the paper tape devices.  Remember to include the attach statement in your SIMH .ini file.

  Copy the two files above to your RSX system, and assemble them

mac bmdrv,bmdrv=lb:[1,1]exemc/ml,[11,10]rsxmc/pa:1,sy:[200,200]bmdrv.mac
mac bmtab,bmtab=lb:[1,1]exemc/ml,[11,10]rsxmc/pa:1,sy:[200,200]bmtab.mac

  Substitute the directory that the files are in for [200,200] above.

  Then, time to task build

>TKB
TKB>bmdrv/-mm/-hd/sq,bmdrv/-sp,bmdrv=
bmdrv,bmtab,lb:[1,54]rsx11m.stb/ss,lb:[1,1]exelib/lb
 /
stack=0
par=gen:120000:40000
//


  Then copy bmdrv.stb and bmdrv.tsk to [1,54].

>pip [1,54]=bmdrv.tsk/nv
>pip [1,54]=bmdrv.stb/nv

  Now load the driver 

>loa bm:

  Then bring the controller and unit online

>CON ONL BMA
>CON ONL BM0:

  Have a look and see if it all loaded and connected OK

>DEV BM0:

  You should see

BM0:     Loaded

  If you see something else...then something went wrong....

  Now, you should be able to do a QIO to the BM0: device, to read a temp & pressure value.

  I'll post an example program in my next post - this is already getting too long...

PiDP11 display register and RSX11


  Recently, a fellow in Switzerland, Oscar Vermuelen,  has been producing some scale models of the PDP-11/70 front panel.  Driven by SIMH running on a Raspberry Pi, and using software from Jorg H )

  It comes in kit form, but only takes a few hours to assemble. The build quality on the components of this kit is really great. I've really enjoyed having mine - it's been a long time since I've had access to the lights and switches of a PDP-11 console. 

  Here's a really terrible phone camera picture of it. It looks much better in person.





   PDP-11 consoles (both real and PiDP11 emulated) came with a switches and display register. A read to this register would read the values set in the console toggle switches. A write to it would cause the value written to be displayed in the DATA lights, if the console display select switch was set to DISPLAY REGISTER.

  RSX comes with a utility for reading the console switches (the SWR utility), but doesn't include any facility for setting the display register lights from a program.

 I wanted a demo program to show how to read  the switches and write to the display from an RSX program. The display register's address is 17777570. But, on RSX, it's not a simple as just writing a program to store a value at that address. The PDP-11/70 (and the PiDP11 simulator) has a 22 bit address memory  space. Programs running on a 70 under RSX  have a 16 bit address space. They access real memory in 8KB chunks, that are mapped to  8KB chunks in the 22 bit memory space.

  The top of that 22 bit space is called the IO page. It's where the CPU and device registers are (IO is mostly memory mapped on the PDP11, mostly). In order for a program to access the IO page, it has to be task-built as a privileged task. Among other things, this causes  the  top 8KB chunk of the task to be mapped to the IO page. When this is done, the 16 bit addresses in the task that are in that top 8KB chunk correspond to the addresses in the IO page. Thus, 17777570 in the IO page, in 22 bit space,  can now be accessed as 177570 in the program. And this is the sketchiest bare bones explanation of PDP-11/70 memory management you'll ever find - don't get me started about I&D space, or user, supervisor and kernel mode mapping registers. 

  Here's a trivial example of how to do that. It reads the switch settings, and writes them into the display register. To use, switch the PiDP display to "DISPLAY REGISTER" from "DATAPATHS", set a value in the switches, and then run the program. The value in the switches will then be shown in the console data lights.

File readwrite.mac


******************************
        .mcall  exit$s

        .psect  cod,ro,i,gbl,rel,con

readwrite:
        mov     @#177570,r0     ;read the switches
        mov     r0,@#177570     ;write the display

        exit$s                             ;donesville

        .end    readwrite

[EOB]



********************************

  To build it, save the above as readwrite.mac, then assemble and link it:


>tkb readwrite/pr=readwrite,[1,1]exelib/lb,[1,54]rsx11m.stb

  Substitute the directory that readwrite.mac is located in for the [200,200] on the first mac line above.

  The above MAC and TKB command lines work fine, but Hugh Sparks pointed out that they are overkill for this project. The commands above are the boilerplate command lines I use when doing more complicated privileged programs that make use of symbols in the exec. For this project, since we don't do anything with symbols, actually all you need to do is...

>tkb readwrite/pr=readwrite
>


 Anyway, it's privileged, and mapped to the IO page, so be careful when you modify it...mistakes here will give you an excellent opportunity  to learn how to use XDT to analyze a crash dump.