Insomnia time! I need a new project or a new videogame. Nothing seems great at the moment. I should probably rewind the repo to the beginning and start again with some actual tests. The two integral tests are fine and it would probably be good to build in unit tests mainly to help me understand what the code is actually doing.
It might also be useful to build a few modernization aids. Fortran is notorious for the use of GOTO; it didn't get ALGOL-style block structure until F77. Prior to that (F66 and earlier) there was no if-then-else structure, just arithmetic if (`if ([some numeric value]) [line number if positive], [... if negative], [... if zero]`) along with if-goto, computed goto, and assigned goto. Assigned goto is pretty rare (thankfully) but there's a lot of obvious if-then-else constructs implemented with the various jump-to-line-number statememts. It's tedious to manually detect and replace them and that process can introduce errors. I know there are (or were) tools to convert the goto structures to block structures and do similar refactorings (fprettify only works on F90 and later, findent works on F66 and later) but I'm not sure there's an open tool that covers what I want to do.
I probably should look closer at findent and possibly send in a PR or just fork it.
Maybe that's the right direction - build some useful tooling. One of the big problems is that compilers are great at emitting errors and warnings but have no capacity to fix them. I think I have an F66 parser somewhere that builds an AST that stays connected to the source code with the intent of generating fragments of modernized code. A limited source-to-source translator.
Another common legacy Fortran misfeature is implicit declaration and typing. Modern practice is to declare every variable along with type and dimension using a single expression. Often you see variables assigned a type in one statement and a dimension in another (scalar vs array). Sometimes only a dimension is specified but there's no explicit type assignment; it's inferred from the first letter of the variable name. Variables with names starting with I through N are integers, everything else is a single-precision real. The goal is to disable implicit typing without breaking the code. There's a need to find all the variables local to a routine and declare, type, and dimension them, find which are shared via COMMON block (a named blob of memory with no controls on it), which are arguments, which are aliases, etc.
Older compilers would generate a map file that gave you diagnostics on all of that plus let you see the projected memory usage of a routine. Knowing which variables are written to is important for refactoring routines that maintain state by saving the values of all locals when the routine exits. Modern Fortran has better ways of sharing information (modules) but migrating COMMON and SAVEd variables to modules is tedious and can be error-prone. When you have a map file it's a lot easier to do the migration, especially for SAVEd variables. Ideally you'd know which SAVEd variables were always assigned before use - those should be local variables, the remainder belong in a module or object.
Another use for detecting the read-only, write-only, and read/write status of dummy variables (arguments) is to explicitly set that so the compiler can flag inadvertent mutations and unassigned write-only variables. Fortran is pass-by-reference and arguments are mutable by default. Units that return values are functions, those that don't are subroutines. Both can mutate their arguments. Modern Fortran can set mutability but you need to know how each argument is used before you can explicitly specify mutability.
I don't even want to touch aliasing, the dreaded EQUIVALENCE statement. Untangling GOTOs is nowhere near as difficult as undoing some clever chap's use of COMMON blocks and EQUIVALENCE as Fortran's only dynamic memory allocation scheme until F90. Fortran has pointers now and actual dynamic memory allocation and with that comes null pointer errors and dynamic memory problems. I'm not sure double free is a problem in Fortran but it might well be. I'm focusing on legacy code so that's a different problem for a different day.