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
'@', '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;
}