User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Front panel program?

Fri May 18, 2018 4:59 am

I don't think I ever saw an Imsai but I remember a 16 bit TI computer from the 1980s. 16 bit address and maybe data bus. To reboot the thing you had to enter addresses and data on toggle switches. My first exposure to FFTs though.
imsai2.jpg
imsai2.jpg (39.47 KiB) Viewed 2130 times
Just for fun you could have a front panel as a screensaver that sat there with blinking lights. Have some low priority thread read registers and display them on the screen. 32 or 64 of those in a row would be impressive. If you did it realtime it would just be a blur, but you could have it update a few times a second.

BTW this arm64 Debian has a /boot/config.txt that starts with

Code: Select all

# Switch the CPU from ARMv7 into ARMv8 (aarch64) mode
arm_control=0x200
And sure enough, lscpu looks like

Code: Select all

Architecture:        aarch64
Byte Order:          Little Endian
CPU(s):              4
On-line CPU(s) list: 0-3
Thread(s) per core:  1
Core(s) per socket:  4
Socket(s):           1
NUMA node(s):        1
Vendor ID:           ARM
Model:               4
Model name:          Cortex-A53
Stepping:            r0p4
BogoMIPS:            38.40
NUMA node0 CPU(s):   0-3
Flags:               fp asimd evtstrm crc32 cpuid
A little like doing a USB mode switch I guess. But just think, you could have 64 blinking lights. :)
unknown.jpg
unknown.jpg (45.62 KiB) Viewed 2130 times
wp7891b322_06.jpg
wp7891b322_06.jpg (74.67 KiB) Viewed 2130 times

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Fri May 18, 2018 1:46 pm

A 64 bit machine is impressive when you think of 2^64 or 18,446,744,073,709,551,616. 20 decimal digits? Not just a mere 4,294,967,296. I don't want to play some silly game, this is way more computing power than the Apollo Lunar Lander had. Makes Star Trek's computer seem like a reality.

If the distance to the moon is 406,700 km (at apogee), that's 406,700,000 meters. (2^64)/406700000 = 45357128285. You could divide every meter of that distance into 45,357,128,285 parts and keep track of them as integers, none of this vague floating point scientific notation nonsense.

Love the apcalc program in the debs for the sake of being able to copy and paste to and from it.

Code: Select all

 calc '2^64'
	18446744073709551616
How to get snapshots of the address and data buses from C I'm not sure. There are probably security issues. Nobody in their right mind wants to do this, at least not often. If you can address 2^64 words and each is 64 bits long, oh my.

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

Re: Front panel program?

Fri May 18, 2018 3:46 pm

ab1jx,
How to get snapshots of the address and data buses from C I'm not sure
You could run your program under the gdb debugger. When you single step through the code you can see the state of the program counter and other registers at each step. That info could be used to light up the address and data bits in your front panel.

No security issues so far, you are debugging your own program in user memory space.

Of course you are seeing the processes view of memory as created by the processors memory management unit the Linix kernel rather than actual physical memory addresses. But I think that would be good enough.
Nobody in their right mind wants to do this, at least not often.
More people than you might think. This guy is building a 32 bit RISC V processor from logic chips with a LED display of every one of it's 32 register and the PC:

https://www.youtube.com/watch?v=yLs_NRwu1Y4&t=8s

Well, OK, that is only a 32 bit machine, but still.

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Sat May 19, 2018 2:45 am

I'm never done any ARM assembly, just some x86 in the 80s. But isn't the program counter going to be relative to the start of the program's memory space, not absolute? I learned under DOS, sorry.

Something like adding to an existing interrupt handler that's called at random times comes to mind. Pass it a pointer to a C variable and have it put the address in there. I don't want it to always be showing an address within a small range.

But it would be simpler and perfectly acceptable to fake the whole thing. Pick some random number, shift it left some number of bits so it looks like an offset address. Meander around the least significant bits for a while like something's actually going on, then pick a new offset and start over.
Last edited by ab1jx on Sat May 19, 2018 3:11 am, edited 1 time in total.

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

Re: Front panel program?

Sat May 19, 2018 3:06 am

The thing is that your "front panel" program will be running as a process under Linux. As far as it is concerned it has access to memory from zero up to some limit. I forget the details. As far as it is concerned it is running on the machine and that is the memory space.

But this is Linux. The memory addresses used by your program are not the actual physical addresses of actual RAM locations. Rather they get translated from "user space" addresses to physical addresses by the memory management hardware built into the ARM processor. Which in turn is configured by the Linux kernel.

Have a google for "Virtual Memory"to get a better idea of all this.

User avatar
rpdom
Posts: 12585
Joined: Sun May 06, 2012 5:17 am
Location: Essex, UK

Re: Front panel program?

Sat May 19, 2018 3:25 am

Heater wrote:
Sat May 19, 2018 3:06 am
the memory management hardware built into the ARM processor.
You're making me feel old now :lol:

In the first ARM computer (Acorn Archimedes), the memory management was a separate chip to the ARM, as was the IO controller and Video/audio controller. Acorn produced all four chips (called ARM2, MEMC, IOC and VIDC. The last three also had "code" names which were something like Albion, Anna and Arrabella. I could be wrong about some of those. The original OS was called Arthur.)

Still amazed it can all be done from one chip now :-)

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

Re: Front panel program?

Sat May 19, 2018 3:34 am

I seriously lusted after an Acorn Archimedes at the time.

A proper 32 bit machine. Faster than any PC available at the time. A nice GUI operating system as opposed to MS-DOS crap.

But alas, too expensive for me at the time.

If I understand correctly the ARM1 only had about 24000 transistors on the chip. Now we are up into the multi-millions and billions of transistors. So you can put everything on one chip. A System on a Chip (SoC)

It is kind of mind boggling to think of this progress.

User avatar
rpdom
Posts: 12585
Joined: Sun May 06, 2012 5:17 am
Location: Essex, UK

Re: Front panel program?

Sat May 19, 2018 3:41 am

Heater wrote:
Sat May 19, 2018 3:34 am
I seriously lusted after an Acorn Archimedes at the time.
I got an early one (with a decent trade discount), after I'd seen them at the launch party in London, then played with one at Acorn in Cambridge. It was really nice to work with. :-)
If I understand correctly the ARM1 only had about 24000 transistors on the chip.
One of the nice things about the ARM series in those days was the simplicity of the design and instruction set. Only 16 basic instructions, all of which could be conditional. The barrel shifter. The pipeline (ok, only three instructions, but still better than the previous 6502 by a long way)

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Sat May 19, 2018 1:07 pm

I think I had both a Sinclair ZX80 https://en.wikipedia.org/wiki/ZX80 and ZX81 https://en.wikipedia.org/wiki/ZX81 at different times. I spent $400 (I think) on an Interact https://en.wikipedia.org/wiki/Interact_Home_Computer. Then a Commodore 64. Then because Jameco Electronics was selling Taiwanese parts I built my first 2 IBM compatibles. One with 4 floppy drives because I couldn't afford a hard drive. I had both used Apples and IBMs much later.

BASIC in 1968 at 14, RPG about 1972. Apple 2 and VAX Pascal starting around 1982 at a job. Took a C course about 1994 and then taught myself 8086/8088 assembly the following summer because I wanted something faster than C. I remember reading coordinates from the mouse and moving an object around the screen, but in C it was too slow. C (Borland) exposed how to do it though and I eventually found it was a thin wrapper around the underlying BIOS routines. Somehow got my hands on a copy of Peter Norton's PC Programmer's Bible https://www.barnesandnoble.com/w/pc-pro ... 1000159291 and about wore the covers off it, lugging it around for weeks and reading it cover-cover.

But the Pi has a well-deserved place in the history books too https://en.wikipedia.org/wiki/Raspberry_Pi. My Model B died, I now have 3 3Bs, a zero and a ZeroW.

I remember going to visit the VAX in the building next to where I was supposed to be working. It was rooms full of stuff with blinking lights, monitors all over the place, connecting wires running under floor panels that lifted for access. No idea how many KW it drew but it was always air conditioned and cool. The elite tended it, I was thrilled to be able to connect some wires to it and hook up a terminal

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

Re: Front panel program?

Sun May 20, 2018 6:25 am

Thought you might be interested in this http://obsolescence.wixsite.com/obsolescence/pidp-11

An actual hardware reproduction PDP-11 front panel, (6:10 scale) including injection molded plastic surround, working switches and most importantly working blinkenlights.
All designed to work with the SIMH PDP-11 simulator running on a Pi.
PDP-11-panel.jpg
PDP-11-panel.jpg (57.03 KiB) Viewed 1868 times
I've already started saving for when it is generally available....

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Sun May 20, 2018 12:01 pm

Hmm, seems like trying to go back to the good old days which under closer scrutiny usually turn out to be not so good after all. Yes, you can look up simh in Synaptic and read the description
This is the SIMH set of emulators for 33 different computers:
DEC PDP-1, PDP-4, PDP-7, PDP-8, PDP-9, DEC PDP-10, PDP-11, PDP-15, Data General Nova, Eclipse, GRI-909, Honeywell 316, 516, HP 2100, IBM System 3 Model 10, 1401, 7094, IBM 1620 Model 1, IBM 1620 Model 2, Interdata 3, 4, 5, 70, 80, 7/16, 8/16, 8/16E, Interdata 7/32, 8/32, SDS 940, LGP-21, LGP-30, DEC VAX (but cannot include the microcode due to copyright).
I hadn't looked before. Old computers generally waste a lot of electricity and software has gotten so bloated they crawl. Pokey Python, give me a break. Not with my CPU cycles you don't, no room for designed-in inefficiency.

Heathkit (Benton Harbor, Michigan) sold a PDP-11 (maybe 8) you could build as a kit. One of my bosses in the 80s had one, 8 inch floppy disks and all. But he was a physical chemistry professor and it was a tool, not a toy. I'm familiar with VMS as an end-user, never got exposed to Unix until about 1995. I remember a VAX 11/780 in its heyday, could support maybe 100 users or so, but it was running VMS. Very good documentation and help system compared to Linux. And file versioning, every file got saved with multiple versions, you had to explicitly delete the extras. You could set something like purge keep=3 in your login batch file. People ran Unix on Vaxen I guess, I just never saw one.

I got this far working in xlib, using XFillRectangle() to make the lights, in a loop. It reads the screen size, you set up the number of bits and you get a line of lights. This is from a 1920x1080 screen with 64 bits.
fp_2018-05-20.jpg
fp_2018-05-20.jpg (28.55 KiB) Viewed 1844 times
I'm trying to decide about making the fake data. Seems like the most significant bits (how wide?) should be an offset and the right part should be more fine-grained. The offset bits change and stay there a while, the right bits are showing quickly changing random numbers. This is a "lamp test" mode, I haven't gotten to displaying an actual data word, but they should be able to just overwrite each other and real data should work as well as fake.

Running on arm64 Debian Buster, with LXDE BTW. On a Pi of course.

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

Re: Front panel program?

Sun May 20, 2018 12:44 pm

SIMH is great.

I few years back I wrote, in assembler, an emulator for the Zilog Z80 that ran on a Propeller microcontroller from Parallax Inc. I used SIMH as a reference implementation to test against. Not having a real Z80 to hand. Then I got CP/M booting on the Propeller using an SD card for disks. SIMH provided all the source code for CP/M and the boot loader that I could tweak to my specific hardware configuration.

It all worked a treat. Thanks to SIMH.

There is even a bug fix of mine in the SIMH sources now.

Old computers were not efficient. But today we can emulate them or implement them in FPGA ending up with something much faster and consuming thousands of times less power.

With the bonus that there is no room in there for modern bloaty software!

I admire your tenacity in programming graphics with xlib. I had a go at that, years ago, I soon decided that life was to short for all that and realized why people use Gtk or Qt which make things much easier and give you a cross platform solution.

Today, I do all my graphics in a browser which is super simple by comparison. Including 3D animation with webgl. Of course that is far too much bloat, but hey we have a browser on machines all the way down to the size of a Pi, might as well make use of it.

Anyone who was there, back in the good old days, will of course tell you they were indeed better. I can vouch for them :)

jahboater
Posts: 2721
Joined: Wed Feb 04, 2015 6:38 pm

Re: Front panel program?

Sun May 20, 2018 1:01 pm

ab1jx wrote:
Fri May 18, 2018 1:46 pm
A 64 bit machine is impressive when you think of 2^64 or 18,446,744,073,709,551,616. 20 decimal digits? Not just a mere 4,294,967,296. I don't want to play some silly game, this is way more computing power than the Apollo Lunar Lander had. Makes Star Trek's computer seem like a reality.
When the Pi is in 64-bit mode, you get access to 128-bit floating point (IEEE quad precision - binary128).
33 digits of precision. ("long double" in C).
For that matter you get 128-bit integers too ("__int128" in C) .....

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Sun May 20, 2018 9:40 pm

Heater wrote:
Sun May 20, 2018 12:44 pm
I admire your tenacity in programming graphics with xlib. I had a go at that, years ago, I soon decided that life was to short for all that and realized why people use Gtk or Qt which make things much easier and give you a cross platform solution.

Anyone who was there, back in the good old days, will of course tell you they were indeed better. I can vouch for them :)
Not much tenacity lately at least. A year or more ago viewtopic.php?t=174679 I was looking for an efficient way to do graphics in X for Software Defined Radio so that program is written such that you can leave out the payload and have a template. I just added a couple lines to make it fill the screen and it's still only 96 lines (payload in). I dug that out and started from there. It did take a lot of wading through PDFs in the first place. But just Google xlib.pdf (or get https://www.x.org/docs/X11/xlib.pdf) there's not much point in reading the 1980 versions.

Ah, but I wish I'd known then what I know now.

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Tue May 22, 2018 12:15 am

This will no doubt amuse the simple minded. Might be as good as a baby mobile. To stop it hit ctrl-C in the terminal that launched it or use the X in the window manager's decoration. It should size to fit any screen resolution. Change the sleep time as desired to speed it up or slow it down.

Code: Select all

/*
  Example of something not quite right
  
  You can replace initgeom() and randtest() with your routines
  
  makefile:
fpanel: fpanel.c
    gcc -O -Wall -g -lm -o fp -I/usr/X11R6/include/ -I/usr/include \
    -L/usr/X11R6/lib/ -lX11 fpanel.c
*/

#include <X11/Xlib.h> // Every Xlib program must include this
#include <assert.h>   // I include this to test return values the lazy way
#include <unistd.h>  
#include <stdio.h> 
#include <stdlib.h> 
#include <stdint.h> // for int16_t, int32_t, unambiguous
#include <time.h>   // time_t to seed random()
#include <math.h>   // for pow mostly

#define NBITS 64  // 32, 64, 16, etc (only 64 will work)
// It's mostly the width of the data to pass that's hard to change (uint64_t)

// designer colors :)
#define ONCOLOR 0x00f88305
#define OFFCOLOR 0x00202020

Display *dpy;  // *struct
int blackcolor,whitecolor;
Window w;  // ID #
GC gc;
XEvent e; // a struct
XSetWindowAttributes setwinattr; // another struct
Screen *scrn;
Visual vis;
int screenw, screenh; // as read from X, fit monitors

struct myrect {  // lights are in constant positions
  uint16_t x;
//  uint16_t y;  // leave out?  Use a line Y value
  uint32_t color;  // allow 24 bit color
};

struct myrect abus[NBITS];  // address bus

uint64_t random64(void) {  // just random 64 bit words
// but RAND_MAX is only 32 bits
  return (pow(2,64)-1) * (((random() * 1.0) / (RAND_MAX * 1.0)));
}

void draw64(uint64_t inp){ // draws a (fake) data word
  int i = 0;
  int lwidth = (screenw / NBITS) -2;
  XSetForeground(dpy,gc,ONCOLOR);  // draw 1 bits
  for (i=0; i<64;  i++) {
  if ((inp & (1<<i)) > 0) {  // if the bit is a 1
      XFillRectangle(dpy,w,gc,abus[i].x,500,lwidth,100);
    }
  }
  XSetForeground(dpy,gc,OFFCOLOR);  // draw 0 bits
  for (i=0; i<64;  i++) {
    if ((inp & (1<<i)) == 0) {  // the bit is a 0
      XFillRectangle(dpy,w,gc,abus[i].x,500,lwidth,100);
    }
  }
}

void randtest(void) {  // just random numbers, not even address-like yet
  while (1) {
    draw64(random64());
    XFlush(dpy);
//    sleep(1);
    usleep(300000);
  }
}

// for bits these should really start (abus[0]) at right, not left
void initgeom(void) {  // fill array
  int lightx = 1; // don't start at left edge
  int lightwidth = (screenw / NBITS) - 2;
  int i = 0;
printf("lightwidth = %i\n",lightwidth);
  while ((lightx + lightwidth) < screenw) {
    abus[i].x = lightx;
    lightx += lightwidth + 2;
    abus[i].color = ONCOLOR; // changed anyway
    i++;
  }
}

int main(void) {
  srandom((unsigned int) time(NULL)); // seed random from time
  dpy = XOpenDisplay(NULL);
  assert(dpy);  // be sure we've got dpy
  blackcolor = BlackPixel(dpy, DefaultScreen(dpy));
  whitecolor = WhitePixel(dpy, DefaultScreen(dpy));
  //  By default the background of the new window is whatever was under it
  setwinattr.background_pixel = blackcolor;   // wnitecolor works too
  scrn = DefaultScreenOfDisplay(dpy);
  screenw = WidthOfScreen(scrn);
  screenh = HeightOfScreen(scrn);
  w = XCreateWindow(dpy,DefaultRootWindow(dpy),0,0,screenw,screenh,0,24,\
    InputOutput,DefaultVisual(dpy,DefaultScreen(dpy)),CWBackPixel,&setwinattr);
  XSelectInput(dpy,w,StructureNotifyMask); // watching for MapNotify later
  XMapWindow(dpy,w); 
  gc = XCreateGC(dpy,w,0,NULL);
  XSetFunction(dpy,gc,GXxor); // sets xor mode
  // MapNotify wait loop, wait for a MapNotify event before drawing
  // confirms that XMapWindow worked. Could also wait for an Expose?
  for (;;) {
    XNextEvent(dpy,&e);  // fetch an event
    if (e.type == MapNotify)  // done when we find one
      break;
  }
  initgeom();  // payload part 1
  randtest();  // payload part 2
  return 0;
}
But there's something strange happening. I define ONCOLOR and OFFCOLOR which are an orange and near-black. I also get black and yellow from somewhere. I don't use any backing store so when I use LXDE's pager to switch to a different workspace what's on the screen gets trashed without repainting. Except it doesn't get repainted the way I designed it.
oddcolors1.gif
oddcolors1.gif (8.38 KiB) Viewed 1717 times
oddcolors2.gif
oddcolors2.gif (8.25 KiB) Viewed 1717 times

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Tue May 22, 2018 3:17 am

There's (at least) a problem in the bit shifting and anding. I was a little vague on how to do that, got it working once a long time ago but I didn't test well enough here. I made a variation that just counts instead of doing randoms and it was easier to see I was getting nonsense. The colors seem to be different too, almost no yellow.

edit:
Checking into it the next day I see that something isn't handling the 64 bit width. If I set a 64 bit word to 0 every bit is 0. But if I increment it bits 0 and 32 are 1. It's like the 2^32 bit isn't doing anything or isn't there. This is with gcc 6.4, I've also got 4.7, 7.3 and 8.1 installed. I'm not sure yet where it's happening.

It's only the output of draw64() that's wrong, I can printf the number and it's right.

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Wed May 23, 2018 5:58 pm

Crossing threads here: viewtopic.php?f=33&t=214272&p=1319188#p1319188 If you use uint64_ts any constants you put into them need a ULL follwing otherwise everything gets reduced to a 32 bit int. This works for this step: out = 1ULL << shft;

But there are still strange things happening with X. Delays and twice as many colors as I defined.
4colors_16c.gif
4colors_16c.gif (8.62 KiB) Viewed 1507 times
Besides showing randoms I show time_t's so it's a binary clock and calender. If it worked. There's also a subroutine to just count in binary.

User avatar
PeterO
Posts: 4182
Joined: Sun Jul 22, 2012 4:14 pm

Re: Front panel program?

Wed May 23, 2018 6:32 pm

I've been working on this again ... https://www.youtube.com/watch?v=3zezUiJ8NI8
Currently I'm getting to grips with Blender to fully model the console.
PeterO
Discoverer of the PI2 XENON DEATH FLASH!
Interests: C,Python,PIC,Electronics,Ham Radio (G0DZB),Aeromodelling,1960s British Computers.
"The primary requirement (as we've always seen in your examples) is that the code is readable. " Dougie Lawson

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Wed May 23, 2018 6:58 pm

I got a kick out of the Obey button. Blender I haven't used much, Povray is more my speed. There were a couple Windows 3D programs from 20-25 years ago with GUIs I used to use a bit. But Povray is almost like C, you can make loops to do animations.
tree_shiny.png
tree_shiny.png (104.54 KiB) Viewed 1493 times

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Wed May 23, 2018 10:41 pm

Wow, 35 years of computing. OK, back to work.
gwss_32c.gif
gwss_32c.gif (114.78 KiB) Viewed 1452 times

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Wed May 23, 2018 11:57 pm

Oh, Peter, re your readable code quote from Dougie, ever think of this? https://en.wikipedia.org/wiki/Internati ... de_Contest

But as it turns out there's benefit from reading man pages. Many XLib functions don't return an error code, but XSetForeground() does and it's giving me a big fat 1 as a return code. I just have to figure out what that means in this case. That's why there are strange colors.

Duh: https://tronche.com/gui/x/xlib/event-ha ... rText.html Tronche makes XLib bearable, even if from just putting man pages on the web where search engines crawl them. There's a Linux man page actually. The XSetForeground man page says XSetForeground can generate BadAlloc or BadGC errors, by GetErrorText I'm getting a BadRequest. Maybe the GC's bogus. I don't know why I love this stuff, I guess because I never got the chance to do it before, it was like the carrot on a stick I never got. I feel like getting a paper copy of the O'Reilly volume and building it a plexiglass case.

Conclusion for the night: I'm getting this BadRequest (but I don't know an opcode or extension) and over half my Xorg.0.log is filled with:

Code: Select all

[ 19353.804] (EE) FBDEV(0): FBIOPUTCMAP: Invalid argument
[ 19353.804] (EE) FBDEV(0): FBIOPUTCMAP: Invalid argument
[ 19353.804] (EE) FBDEV(0): FBIOPUTCMAP: Invalid argument
Seems to happen on setting the foreground color, which sometimes works. I'm thinking FBIOPUTCMAP has to do with trying to use a certain colormap on the frame buffer device. fbset shows it's 32 bpp, I don't see the problem. Unless because it's truecolor and doesn't use a colormap really.

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Sat May 26, 2018 11:24 pm

Still working on it. Figured out a few things. Most people ignore the return code from XSetForeground it seems, I tried looking at the return values in a couple working examples and it's usually (always?) 1, not 0. 1 may actually mean success. Another option instead of all those setforegrounds is to use 2 GCs for drawing in 2 colors alternately. Haven't gotten that to work yet.

But what explains the sluggishness and intermittent nature I think are scheduling issues. The computer can do millions of things per second but it has its own agenda. It works on a queue of events. I've gotten to the point where keystrokes and mouse clicks are recognized, it starts up full screen by reading the screen size. I'm working on a menu of sorts, right now it quits if I hit Q or Escape, I'm still working on the other items.

I have a working 32 bit clock displaying a time_t in binary. I found https://www.linuxquestions.org/question ... ost2431345 very useful. I don't fully understand select and blocking but the technique opens a file descriptor to the display then uses that file descriptor with select to schedule some time to do my stuff.
working1.gif
working1.gif (12.36 KiB) Viewed 1256 times
It's still not quite right (timing in the carries is weird), and in my menus (yet to write) are selecting 64 bit or 32 bit mode, counting up from 0, showing random numbers in binary. I also want to try writing the time and date on the screen now that I have a working example of how to do that, all from xlib. 0.3% CPU usage by Top but it's very intermittent in nature, it only does something once a second in this mode. 14752 byte executable.

User avatar
ab1jx
Posts: 636
Joined: Thu Sep 26, 2013 1:54 pm
Location: Heath, MA USA
Contact: Website

Re: Front panel program?

Tue May 29, 2018 1:46 am

OK, I guess I'm going to call this done, since it doesn't actually accomplish anything. But I've learned a few things, probably the most startling is that you can't just write to the screen whenever you want to. How to put text and graphics up, make the application recover from having something else on top of it, being minimized and restored, changing panes in your pager. How to handle mouse clicks and key presses. All from just bare xlib, requiring almost no CPU time and with an executable that's 15,136 bytes. I wouldn't write a web browser or word processor this way, but after years of being stuck at a command line wishing I had a way to draw simple plots without studying GTK, QT, FLTK, whatever, this is a livable approach. For my SDR program I mostly need a way to do fast plots with some text and buttons, that's more approachable now.

I gave up at least for now on reading the actual data bus and/or address bus. That's probably a privileged operation anyway. Maybe some process could grab snapshots and put them somewhere and something else could access them by a pointer, but it hardly seems worthwhile. I know now I could put the data on the screen if i had it.

So this has 3 modes, the default reads the current time (and date) as a time_t , draws that as binary. There's a mode that counts up from 0, another mode does random numbers as binary. You can switch modes any time with 1 keystroke (c,r,u). Quit with Escape or q or click in the window. It should size itself to fill your screen and things are positioned by proportions, not absolute coordinates. Here are the 3 modes in one image (combined with GIMP).
compos1.png
compos1.png (9.23 KiB) Viewed 1122 times

Code: Select all

/*
  More fun with xlib
  
  Save as st3.c, compile with
    gcc -O -Wall -o st3 -lX11 st3.c
  needs only xlib.
  
  modes:
  0: clock - hit c
  1: counting - hit u
  2: random - hit r
  
  Escape, q, or click the screen to quit
  
  Alan Corey  2018-05-28
*/

// designer colors :)
#define ONCOLOR 0xf88305
#define OFFCOLOR 0x202020
#define TEXTCOLOR 0x0de70d

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>

int swidth, sheight;  // screen size
Display *dpy = NULL;
Window w;
static int mode = 0; // clock mode by default
static uint16_t cells32[32]; // left edges
static int ctops = 0;
static int cheight = 0;
int texty = 0; // y location of clock text
int textx = 0;
int blackcolor;
GC offgc, ongc;
time_t old_t, cur_t;
int x11_fd;
static uint32_t count = 0UL;  // for counting up
static uint32_t out32;  // value to be displayed

void show32(uint32_t inp) {/// display a 32 bit value
  uint32_t shft = 0;
  uint32_t test32 = 0UL;
  char last = 0;
  XSetForeground(dpy,offgc,OFFCOLOR);
  last = 0;
  for (shft=0; shft<32; shft++ ) {
    test32 = 1UL << shft;
    if ((inp & test32) > 0) { // 1 bit
      if (last != 1) {
        XSetForeground(dpy,ongc,ONCOLOR);
        last = 1;
      }
      XFillRectangle(dpy,w,ongc,cells32[shft],ctops,(swidth/32)-2,cheight);
    } else { // 0 bit
      if (last != 0) {
        XSetForeground(dpy,offgc,OFFCOLOR);
        last = 0;
      }
      XFillRectangle(dpy,w,offgc,cells32[shft],ctops,(swidth/32)-2,cheight);        
    }
  }  // end for shft
}

void erase(void) { // blot out strings
  XSetForeground(dpy,ongc,blackcolor);
  XFillRectangle(dpy,w,ongc,textx-5,texty-10,160,20); // erase
}

void redisp(void) {  // expose event calls this, can redraw
  char timestr[30];
  char countstr[] = "Counting";
  char randstr[] = "Randoms";
  switch (mode) {
    case 1  : erase();
              XSetForeground(dpy,ongc,TEXTCOLOR);
              XDrawString(dpy,w,ongc,textx,texty,countstr,strlen(countstr));
              show32(count);
              count++;       
              break; 
    case 2 :  erase();
              XSetForeground(dpy,ongc,TEXTCOLOR);
              XDrawString(dpy,w,ongc,textx,texty,randstr,strlen(randstr));
              out32 = ((random()*1.0)/(RAND_MAX*1.0)) * 0xFFFFFFFF;
              show32(out32);
              break;
    case 0 :  
    default:  cur_t = time(NULL);
              show32((uint32_t) cur_t);
              erase();
              XSetForeground(dpy,ongc,TEXTCOLOR);
              strncpy(timestr,ctime(&cur_t),30);
              XDrawString(dpy,w,ongc,textx,texty,timestr,strlen(timestr)-1);
              break;
  }  // end switch mode
  XFlush(dpy); 
}

void layout(void) {  // general init
  int cwidth32; // cell width
  int i,j;
  cwidth32 = swidth/32;  // cell widths
  j = swidth - cwidth32;;
  i = 0;
  while (j>0) {  // work out cells for drawing binary bits
    cells32[i] = j;
    i++;  // i and j go opposite directions
    j-= cwidth32;
  }
  ctops = sheight/3;    // y of cell tops
  cheight = sheight/4;  // height of cells
  texty = 2 * ctops; // 2/3 of the way down screen
  textx = (swidth/2) - 80;  // ballpark
  blackcolor = BlackPixel(dpy, DefaultScreen(dpy));
  srandom((unsigned int) time(NULL)); // seed random from time
  old_t = time(NULL);
}

void processEvent(void){ // can be expose, mouse, keyclick events
  XEvent ev;
  int kn = 0;
  XNextEvent(dpy, &ev);
  mode = 0;  // enforce default
  switch (ev.type) {
    case Expose:
      printf("Expose event\n");
      redisp(); // causes redraw as needed
      break;
    case ButtonPress:
      printf("Button Press\n");
      exit(0);  // any mouse button quits
      break;
    case KeyPress:
      kn = ev.xkey.keycode;
      printf("Key Press, code %i\n",kn);
      switch (kn) {
        case 9:  exit(0);              // escape
        case 24: exit(0);              // q - quit
                 break;
        case 27: mode = 2;  // r - random
                 printf("keypress for random mode\n");        
                 break;
        default:
        case 54: mode = 0;  // c - clock mode
                 printf("keypress for clock mode\n");
                 break;
        case 30: mode = 1;  // u - counting mode
                 printf("keypress for counting mode\n");        
                 break;
      }
      redisp(); // redraw in newly chosen mode
      break;
    default:
      printf("Unknown event\n");
      break;
  }
}

/* 
Many thanks to a post from 2006 by AngryLlama at
https://www.linuxquestions.org/questions/showthread.php?p=2431345#post2431345
select() gets a time window from X to draw in
*/


int main(void) {
  struct timeval tv;
  fd_set in_fds;
  dpy = XOpenDisplay(NULL);
  if (dpy == NULL) {
    printf("XOpenDisplay failed.\n");
    exit(1);
  }
  Visual *visual=DefaultVisual(dpy, 0);
  if (visual == NULL) {
    printf("Getting the display's default visual failed.\n");
    exit(1);
  }
  Screen *scrn = DefaultScreenOfDisplay(dpy);
  if (scrn == NULL) {
    printf("Error getting default screen\n");
    exit(1);
  }
  swidth = WidthOfScreen(scrn);
  sheight = HeightOfScreen(scrn);
  w = XCreateSimpleWindow(dpy, RootWindow(dpy, 0), 0, 0, swidth, \
    sheight, 1, 0, 0);
  if(visual->class!=TrueColor) {
    printf("Sorry, this only works on TrueColor\n");
    exit(1);
  }
  XSelectInput(dpy, w, KeyPressMask|ButtonPressMask|ExposureMask);
  offgc = DefaultGC(dpy, 0);
  ongc = DefaultGC(dpy, 0);
  XMapWindow(dpy,w);
  layout();
  x11_fd = ConnectionNumber(dpy);
  if (x11_fd < 0) {
    printf("Error getting file descriptor for x11\n");
    exit(1);
  }
  while (1) {
    FD_ZERO(&in_fds);
    FD_SET(x11_fd, &in_fds);
    tv.tv_usec = 200000;  // 1/5 second
    tv.tv_sec = 0;    
      // Wait for X Event or a Timer
    if (select(x11_fd+1, &in_fds, 0, 0, &tv))
      printf("Event Received!\n");
    else {
      // Handle timer here (original comment, had other contents)
      if (mode == 0) {
        cur_t = time(NULL); // read again
      }
      redisp(); // without this the display doesn't change
    }
      // Handle XEvents and flush the input 
    while(XPending(dpy))
      processEvent();  // my event handler
  }  // end while (1) 
  return 0;  
 } // end program

Return to “Off topic discussion”

Who is online

Users browsing this forum: Steve Drain and 3 guests