Saturday, November 18, 2017

Happy birthday to Fortran!

A recent article reminded me that the Fortran programming language is now sixty years old! This is a major milestone. And while I don't really write Fortran code anymore, the article was a great reminder of my early use of Fortran.

My first compiled language was Fortran. I was an undergraduate physics student at the University of Wisconsin-River Falls, and as part of the physics program, every student had to learn Fortran programming. Since this was the very early 1990s, we used FORTRAN 77 (the new capitalization of "Fortran" would be established with Fortran 90, a few years later).

We learned FORTRAN 77 so could do numerical analysis, or other programmatic analysis of lab data. For example, while spreadsheets of the era could calculate a linear fit to x-y data, including standard deviations, we could not fit polynomials to nonlinear data. But given a maths textbook, you could write your own program in FORTRAN 77. I wrote many programs like this throughout my undergraduate career.

As a research intern at a national lab between my junior and senior years, my mentors discovered I knew FORTRAN. So I got the assignment to port a FORTRAN IV program to FORTRAN 77 (Fortran 90 had recently been defined, and the lab didn't have the compiler yet). It was my first programming "job" and through experience I realized I wanted a career in IT rather than physics research.

I also taught myself the C programming language, and thereafter switched to C when I needed to write a program. I haven't needed to write Fortran code since then.

The last time I wrote anything in Fortran was a few years ago. At the time, I read an article about a proposed proof to the Collatz conjecture: the so-called "hailstone" sequence. From Slashdot: "A hailstone sequence starts from any positive integer n the next number in the sequence is n/2 if n is even and 3n+1 if n is odd. The conjecture is that this simple sequence always ends in 1. Simple to state but very difficult to prove and it has taken more than 60 years to get close to a solution."

I hadn't heard of the hailstone sequence before, but I thought it was an interesting problem. I could have easily written this program in C or even Bash, but I used the opportunity to return to my roots with Fortran. I created a simple FORTRAN 77 program to iterate the hailstone sequence. To celebrate Fortran's milestone birthday, I'd like to share my program with you:

      PROGRAM HAILSTN
C     A PROGRAM TO ITERATE THE HAILSTONE SEQUENCE.
C
C     THE RULE FOR A HAILSTONE SEQUENCE IS:
C
C     START AT ANY POSITIVE INTEGER, N.
C     IF N IS EVEN, THE NEXT NUMBER IS N/2. IF N IS ODD, THE NEXT NUMBER
C     IS 3N+1. ITERATE.
C
C     IN THEORY, ALL HAILSTONE SEQUENCES WILL END WITH 1.

 10   PRINT *, 'Enter starting number (any positive integer):'
      READ *, N

C      PRINT *, 'You entered: ', N

      IF (N.LT.1) THEN
         PRINT *, 'You must enter a positive integer'
         GOTO 10
      ENDIF

C     ITERATE

      PRINT *, N

      ITER = 0

 20   IF (MOD(N,2).EQ.0) THEN
         N = N / 2
      ELSE
         N = (3 * N) + 1
      ENDIF

      ITER = ITER + 1

      PRINT *, N
      IF (N.NE.1) GOTO 20

      PRINT *, 'Number of iterations: ', ITER

      END PROGRAM

This program doesn't demonstrate the best programming practices, but it does represent many FORTRAN 77 programs. To illustrate, allow me to walk you through the code:

First, FORTRAN code was originally written on punched cards. The first FORTRAN used columns to understand the program listing. FORTRAN 77 programs used the same column rules:

  • If a C or * in column 1, the line is a comment
  • Program labels (line numbers) are in columns 1–5
  • Program statements begin on column 7, but cannot go beyond column 72
  • Any character in column 6 will continue the line from the preceding line (not used here)

While you could (and should) declare variables to be of a certain type, FORTRAN 77 used a set of implicit rules to assign variable types: all variables starting IN are assumed INTEGER, and variables starting with other letters are declared REAL (floating point).

My program uses only two variables, N and ITER, which are both integer variables.

FORTRAN 77 is a simple language, so you should be able to figure out what the program is doing based on those rules. I'll add a note about the code starting with line label 20. FORTRAN 77 doesn't have a do-while loop concept, so you end up constructing your own using a label, IF, and GOTO.

And that's what happens starting at label 20. The program begins a loop iteration, following the rules of the hailstone sequence: for each positive integer n the next number in the sequence is n/2 if n is even and 3n+1 if n is odd. After updating the ITER iteration count and printing the current value of N, the program continues to loop back to line label 20 (using GOTO) until N reaches 1.

When the loop is complete, the program prints the number of iterations, and exits.

Here's a sample run:

 Enter starting number (any positive integer):
11
          11
          34
          17
          52
          26
          13
          40
          20
          10
           5
          16
           8
           4
           2
           1
 Number of iterations:           14

Happy birthday, Fortran!

Wednesday, November 15, 2017

QEMU and function keys (follow-up)

Since I posted my suggestion for QEMU a few weeks ago, I've learned a few things about QEMU. Thanks so much to the folks who contacted me via email to help me out.

A brief review of my issue:

I like to run FreeDOS in QEMU, on my Linux laptop. QEMU makes it really easy to boot FreeDOS or to test new installations. During our run up to the FreeDOS 1.2 release, I tested every pre-release version by installing under QEMU.

But one problem pops up occasionally when using QEMU. A lot of old DOS software uses the function keys to do various things. The most common was F1 for help, but it was common for an install program to use F10 to start the install.

And with QEMU, you can use those keys. Except some of them. Some function keys, like F10, are intercepted by the window system or desktop environment. You can get around this in QEMU by using the QEMU console (available in the menu bar or tabs) and typing a sendkey command, like sendkey f10. But that's kind of awkward, especially for new users. Nor is it very fast if you often need to use the function keys.

So I suggested that QEMU add a toolbar with the function keys.

Of course, QEMU's preference is that QEMU should grab the keyboard and intercept all the function keys, blocking the window system shortcut keys like F10. So QEMU wants to do this. And I understand that QEMU used to do this. Sounds like the current issue is a regression in the Wayland implementation—and I run Fedora Linux, so I'm using Wayland.

As Daniel responded via the QEMU tracker for my bug:

Recently though, there has been a regression in this area. With the switch to Wayland instead of Xorg, the standard GTK APIs for doing this keyboard grabbing / accel blocking no longer work correctly. Instead apps need to add custom code to talk to the Wayland compositor IIRC. There's work underway to address this but its a way off.

So that explains it. I'm happy to have this captured by the application. Doing the keyboard interception "live" is a much better solution (better usability) than the toolbar I suggested. Thanks!

Wednesday, November 1, 2017

My suggestion for QEMU

I have been involved in open source software since 1993. And in 1994, I believed so strongly in the ability for people to come together to write code that I created the FreeDOS Project, to replicate the functionality of MS-DOS. And twenty-three years later, I'm still using and developing FreeDOS.

My desktop system is Linux, and I run FreeDOS using QEMU (Quick EMUlator). QEMU is very easy to use, and provides great flexbility to define your virtual machine. I run FreeDOS in QEMU when I want to play an old DOS game, or when I want to test some legacy software, or when I want to write code to update a FreeDOS program.

But one problem pops up occasionally when using QEMU. A lot of old DOS software uses the function keys to do various things. The most extreme example is WordPerfect, which was arguably the most popular commercial word processor of the day. WordPerfect is notorious for using all of the function keys, in every combination, including use of Ctrl and Alt to access all the common features. I think WordPerfect probably used all of the expanded keys too, like Home and End.

Other DOS programs use the function keys in different ways. The most common was F1 for help, but it was common for an install program to use F10 to start the install.

And with QEMU, you can use those keys. Except some of them. And strictly speaking, that's not QEMU's fault. Some function keys, like F10, are intercepted by the window system or desktop environment. You can get around this in QEMU by using the QEMU console (available in the menu bar or tabs) and typing a sendkey command, like sendkey f10. But that's kind of awkward, especially for new users. Nor is it very fast if you often need to use the function keys.

So as a frequent user of QEMU, I'd like to suggest a modification to the user interface: a toolbar with the function keys. Here's a simple mock-up to show what I mean:


A possible improvement would be to add "modifier" buttons for Ctrl, Shift, and Alt to make it easier for users to enter combinations like Ctrl-F1 or Shift-F5 or Alt-F7.

I've already submitted this idea as a feature request in the QEMU tracker, and it's been added to a Wishlist. If you are a QEMU developer, or want to make a contribution to QEMU, I encourage you to work on this toolbar.