/*
http://members.iinet.net.au/~dgreen/deuce/deuce.html

> I have a soft spot for DEUCE. It was the computer on which I learned to program.
> However, I think DEUCE has a fair claim to being, for programmers, the most complicated
> computer ever put into general production. See for yourself. The programming manual is
> available at John Barrett's Web site. Or check out an example of some program code - the
> solution to a simple programming exercise given to new chums at Kidsgrove: specification
> (44kB), flowchart (261kB), coding sheet (551kB).

I was bored at work this afternoon, so when I saw this page,
I thought I'd see if I could remember my 'tables of finite differences'
lecture from 30 years ago...

The code below is written in a simple style that should
transliterate pretty easily to DEUCE code (ignoring the C
code for I/O).  If I were programming for the machine I'd
effectively hand compile this after learning the instruction
set.  I've tried to keep this to relatively simple 3-address
metacode to ease translation.

Note, no use of multiply.  Just like the old days :-)  (Did the
DEUCE have a hardware multiply or did the Kidsgrove programmers
also use a table of finite differences?  Or was there a soft
multiply subroutine or extracode available?)

It's actually still quite a challenging problem, at least if
you limit yourself to coding with one hand tied behind your back :-)

Graham Toal <gtoal@gtoal.com>

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
  int rc, mem[328], init[6] = {0, -1, 0, -6, 0, 1};

  toploop:

  memmove(mem, init, 6*sizeof(int));  /* move from constant area to ram */

  fprintf(stderr, "\nN1:");

  rc = scanf("%d", &mem[6]);
  if (rc != 1) goto err;
  if (mem[6] <= 0) goto err;

  fprintf(stderr, "N2:");

  rc = scanf("%d", &mem[7]);
  if (rc != 1) goto err;

  if (mem[7] > 1024) goto err;
  mem[7] -= mem[6];
  if ((unsigned int)mem[7] > 319) goto err;
  mem[7] += mem[6];

  rc = fgetc(stdin); ungetc(rc, stdin);
  if (rc > 32) goto err; /* Ascii */

  /* Calculate cubes efficiently (ie without using a multiply) */
  loop:
    if (mem[0] >= mem[7]) goto print;  /* upper bound */
    mem[1] += 1;
    mem[2] += mem[1];
    mem[3] += 6;
    mem[5] += mem[3];
    mem[4] += mem[5];
    mem[0] += 1;
    if (mem[0] < mem[6]) goto loop; /* lower bound - time to start */

    /* Store results in mem[8..327] corresponding to 1..320 (really 0..319)*/
    /* Would have been easier to print on the fly, but this enforces a memory test) */
    mem[0] -= mem[6];
    (mem+8)[mem[0]] = mem[4];
    mem[0] += mem[6];
  goto loop;

  print:

  mem[1] = mem[7] - mem[6];

  mem[0] = 8;
  mem[1] += 8;

  printloop:
    fprintf(stderr, "%d", mem[mem[0]]);
    mem[0] += 1;
    if ((mem[0] & 7) == 0) goto line; /* print 8 per line (I think the specified */
        /* 12 per line would require an extra variable, or too complex bit twiddling... (x+x+x)>>1) */
      fprintf(stderr, " ");
      goto endline;
    line:
      fprintf(stderr, "\n");
    endline:
  if (mem[0] <= mem[1]) goto printloop;
  goto toploop;

  err:
  fprintf(stderr, "No!\n");
  exit(1);
  return(1);
}