LGP-30 software & notes made available

From: Tom Jennings <tomj_at_wps.com>
Date: Fri Nov 21 16:48:12 2003

On Fri, 2003-11-21 at 13:31, jim wrote:

> > Is this the simulator written in J?

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

I guess not! Thanks!



> //
>
> #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 - 16:48:12 GMT

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