LGP-30 software & notes made available

From: jim <jwstephens_at_msm.umr.edu>
Date: Fri Nov 21 15:31:47 2003

pretty much c code

Tom Jennings wrote:

>
> Is this the simulator written in J?
>

// lgp30.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <conio.h>
#include <stdlib.h>


//
// +0000|0000|0011|1111|1111|2222|2222|2233|
// |0123|4567|8901|2345|6789|0123|4567|8901|
// |s.............|op..|..|track |sector|xx|

#define ROPMASK 0x000f0000
#define RADDRMASK 0x00003fc0

#define TRACKMASK 0x000000fc
#define SECTORMASK 0x0000003f

enum OPS
{
 B=0, // 0 bring
    A, // 1 add
 S, // 2 subtract
 H, // 3 hold
 C, // 4 clear
 E, // 5 extract
 D, // 6 divide
 M, // 7 multiply (most sig multiplicand)
 N, // 8 multiply (least sig multiplicand)
 Y, // 9 store address
 R, // 10 return address
 U, // 11 unconditional transfer
    T, // 12 test (uses sign bit to do neg )
 P, // 13 Print
 I, // 14 Input
 Z // 15 stop
};

// case is either upper or lower (0 or 1)
int ttycase = 0;


char Collate[64][2] =
{

 '\0', '\0', // P0000 start read
    'Z', 'z', // P0100 Z z 000001
 ')', '0', // P0200 ) 0 000010
 ' ', ' ', // P0300 space 000011
 '\0', '\0', // P0400 Lower Case 000100
 'B', 'b', // P0500 B b 000101
 'L', '1', // P0600 L l 000110
 '_', '-', // P0700 _ - 000111
 '\0', '\0', // P0800 Upper Case 001000
 'Y', 'y', // P0900 Y y 001001
 '*', '2', // P1000 * 2 001010
 '=', '+', // P1100 = + 001011
 '\0', '\0', // P1200 color shft 001100
 'R', 'r', // P1300 R r 001101
 '\"', '3', // P1400 " 3 001110
    ':', ';', // P1500 " ; 001111
 0x0d, 0x0d, // P1600 car return 010000
 'I', 'i', // P1700 I i 010001
 '^', '4', // P1800 ^ 4 010010
 '?', '/', // P1900 ? / 010011
 0x08, 0x08, // P2000 back sp 010100
 'D', 'd', // P2100 D d 010101
 '%', '5', // P2200 % 5 010110
 ']', '.', // P2300 ] . 010111
 0x09, 0x09, // P2400 tab 011000
 'N', 'n', // P2500 N n 011001
 '$', '6', // P2600 $ 6 011010
 '[', ',', // P2700 [ , 011011
 '\0', '\0', // P2800
 'M', 'm', // P2900 M m 011101
 '_at_', '7', // P3000 pi 7 011110
    'V', 'v', // P3100 V v 011111
 '\0', '\0', // P3200 cond stop 100000
 'P', 'p', // P3300 P p 100001
 'S', '8', // P3400 sigma 8 100010
 'O', 'o', // P3500 O o 100011
 '\0', '\0', // P3600
 'E', 'e', // P3700 E e 100101
 '(', '9', // P3800 ( 9 100110
 'X', 'x', // P3900 X x 100111
 '\0', '\0', // P4000
 'U', 'u', // P4100 U u 101001
 'F', 'f', // P4200 F f 101010
 '\0', '\0', // P4300
 '\0', '\0', // P4400
 'T', 't', // P4500 T t 101101
 'G', 'g', // P4600 G g 101110
 '\0', '\0', // P4700
 '\0', '\0', // P4800
 'H', 'h', // P4900 H h 110001
 'J', 'j', // P5000 J j 110010
 '\0', '\0', // P5100
 '\0', '\0', // P5200
 'C', 'c', // P5300 C c 110101
 'K', 'k', // P5400 K k 110110
    '\0', '\0', // P5500
 '\0', '\0', // P5600
 'A', 'a', // P5700 A a 111001
    'Q', 'q', // P5800 Q q 111010
 '\0', '\0', // P5900
 '\0', '\0', // P6000
 'S', 's', // P6100 S w 111101
 'W', 'w', // P6200 W w 111110
 '\0', '\0', // P6300 delete 111111

};


int Creg; // counter register
int Rreg; // instruction register
int Areg; // accumulator register

int Op; // operation
int Addr; // address stripped and shifted
int Track; // track addr
int Sector; // sector addr
__int64 mul1;
__int64 mul2;
__int64 mul3;

#define MEMSIZE 4096

int mem[MEMSIZE];

void afmt(int addr)
{
 printf("T%3.3iS%3.3i",
  (addr & TRACKMASK) >> 6,
  (addr & SECTORMASK)
  );
}

int init(void)
{
 int i;

 for(i=0;i<MEMSIZE;i++)
 {
  mem[i]=0;
 }

 mem[0] = 0x00000100;
 mem[1] = 0x00010101;
 mem[2] = 0x000b0000;

 mem[0x40] = 0x00000001;
 mem[0x41] = 0x00000002;


 Creg = 0;
 return 0;
}

void Execute(void)
{


 for(;;)
 {
  Rreg = mem[Creg];
  Op = ( Rreg & ROPMASK ) >> 16;
  Addr = ( Rreg & RADDRMASK ) >> 2;
  Track = Addr & TRACKMASK >> 6;
  Sector = Addr & SECTORMASK;

  switch(Op)
  {
  case B:
   afmt(Creg);
   printf(" Bring ");
   afmt(Addr);

   Areg = mem[Addr];

   printf(" accum %i", Areg);
   printf("\n");
   Creg += 1;


   break;
   // add
  case A:
   afmt(Creg);
   printf(" Add ");
   afmt(Addr);
   Areg = Areg + mem[Addr];
   printf(" accum %i", Areg);
   Creg += 1;
   printf("\n");
   break;
  case S:
   afmt(Creg);
   printf(" Sub ");
   Areg = Areg - mem[Addr];
   printf(" accum %i", Areg);
   Creg += 1;
   break;
   // deposit accumulator, hold value
  case H:
   afmt(Creg);
   printf(" Hold ");
   afmt(Addr);
   mem[Addr] = Areg;
   printf("\n");
   Creg += 1;
   break;
   // deposit accumulator and clear
  case C:
   afmt(Creg);
   printf(" Clear ");
   afmt(Addr);
   mem[Addr] = Areg;
   Areg = 0;
   printf("\n");
   Creg += 1;
   break;
  case E:
   afmt(Creg);
   printf(" Extract ");
   afmt(Addr);
   mem[Addr] = Areg;
   printf("\n");
   Creg += 1;
   break;
  case D:
   // divide
   afmt(Creg);
   printf(" Divide ");
   afmt(Addr);
   Areg = Areg / mem[Addr];
   printf("\n");
   Creg += 1;
   break;
  case M:
   // multiply, save upper
   afmt(Creg);
   printf(" Divide ");
   afmt(Addr);
   mul1 = (__int64) Areg;
   mul2 = (__int64) mem[Addr];
   mul3 = mul1 * mul2;
   Areg = (int)(mul3 >> 32);
   printf("\n");
   Creg += 1;
   break;
  case N:
   // multiply, save lower
   afmt(Creg);
   printf(" Divide ");
   afmt(Addr);
   mul1 = (__int64) Areg;
   mul2 = (__int64) mem[Addr];
   mul3 = mul1 * mul2;
   Areg = (int)(mul3 & 0x00000000ffffffff);
   printf("\n");
   Creg += 1;
   break;
  case Y:
   // store address
   afmt(Creg);
   printf(" st adr ");
   mem[Addr] = Addr & RADDRMASK;
   afmt(Addr);
   printf(" = ");
   afmt(mem[Addr]);
   Creg += 1;
   break;
  case R:
   // store return address at n
   afmt(Creg);
   printf(" rtn adr ");
   mem[Addr] = ((Creg + 1) << 2) & RADDRMASK;
   break;
  case U: // 0x000b0000
   afmt(Creg);
   printf(" ujmp ");
   afmt(Addr);
   Creg = Addr;
   printf("\n");
   break;
  case T: // 0x000c0000
   // conditional transfer
   afmt(Creg);
   printf(" test ");

   if( Rreg & 0x80000000 )
   {
    // transfer if T console sw on
    // or Areg neg
    if( Areg & 0x80000000 )
     Creg = Addr;
   }
   else
   {
    if( Areg & 0x80000000 )
     Creg = Addr;
   }
   break;
  case P: // 0x000d0000
   afmt(Creg);
   printf(" print ");

   // have to see if special
   // otherwise it is printable
   switch(Track)
   {
    // lower case
   case 4:
    ttycase = 1;
    printf("lower case\n");
    break;
   case 8:
    ttycase = 0;
    printf("upper case\n");
    break;
   case 16:
    printf("carriage return\n");
    break;
   default:
      printf("'%c'\n",Collate[ttycase][Track]);
      break;
   }
   Creg += 1;
   break;
  case I:
   Creg += 1;
   break;
  case Z:
   return;
   break;

  default:
   // not an opcode
   return;
   break;
  }

  if(Creg > 0x00000fff)
  {
   Creg = 0;
  }
 }

}

int main(int argc, char* argv[])
{
 printf("LGP-30!\n");

 init();
 Execute();

 return 0;
}
Received on Fri Nov 21 2003 - 15:31:47 GMT

This archive was generated by hypermail 2.3.0 : Fri Oct 10 2014 - 23:36:20 BST