i650: New IBM 650 Simulator

This commit is contained in:
Roberto Sancho Villa 2018-03-25 10:17:35 -07:00 committed by Mark Pizzolato
parent 94727159e8
commit 2eb49c13b7
26 changed files with 10772 additions and 1 deletions

14
I650/650_test.ini Normal file
View file

@ -0,0 +1,14 @@
cd sw
; set debug -n debug.txt
; set debug stdout
; set cpu debug=cmd;data;detail
; set throttle 11k
do Build_soap_from_source.ini
do soap_and_run.ini soap_example_1_src.txt 1000
do Build_is_from_decks.ini ntr lbox
do is_run.ini is_example_1_src.txt

733
I650/i650_cdp.c Normal file
View file

@ -0,0 +1,733 @@
/* i650_cdp.c: IBM 650 Card punch.
Copyright (c) 2018, Roberto Sancho
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERTO SANCHO BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This is the standard card punch.
These units each buffer one record in local memory and signal
ready when the buffer is full or empty. The channel must be
ready to recieve/transmit data when they are activated since
they will transfer their block during chan_cmd. All data is
transmitted as BCD characters.
*/
#include "i650_defs.h"
#include "sim_card.h"
#define UNIT_CDP UNIT_ATTABLE | MODE_026
/* std devices. data structures
cdp_dev Card Punch device descriptor
cdp_unit Card Punch unit descriptor
cdp_reg Card Punch register list
cdp_mod Card Punch modifiers list
*/
uint32 cdp_cmd(UNIT *, uint16, uint16);
t_stat cdp_srv(UNIT *);
t_stat cdp_reset(DEVICE *);
t_stat cdp_attach(UNIT *, CONST char *);
t_stat cdp_detach(UNIT *);
t_stat cdp_help(FILE *, DEVICE *, UNIT *, int32, const char *);
const char *cdp_description(DEVICE *dptr);
t_stat cdp_set_wiring (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat cdp_show_wiring (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat cdp_set_echo (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat cdp_show_echo (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
UNIT cdp_unit[] = {
{UDATA(cdp_srv, UNIT_CDP, 0), 600}, // unit 0 is the printing mechanism of 407
{UDATA(cdp_srv, UNIT_CDP, 0), 600},
{UDATA(cdp_srv, UNIT_CDP, 0), 600},
{UDATA(cdp_srv, UNIT_CDP, 0), 600},
};
MTAB cdp_mod[] = {
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT", &sim_card_set_fmt, &sim_card_show_fmt, NULL, "Set card format"},
{MTAB_XTD | MTAB_VUN, 0, "WIRING", "WIRING", &cdp_set_wiring, &cdp_show_wiring, NULL, "Set card punch/print control panel Wiring"},
{MTAB_XTD | MTAB_VUN, 0, "ECHO", "ECHO", &cdp_set_echo, &cdp_show_echo, NULL, "Set console printout for punched cards"},
{MTAB_XTD | MTAB_VUN, 1, "PRINT", "PRINT", &cdp_set_echo, &cdp_show_echo, NULL, "Set printout on CDP0 unit for punched cards"},
{0}
};
DEVICE cdp_dev = {
"CDP", cdp_unit, NULL, cdp_mod,
4, 8, 15, 1, 8, 8,
NULL, NULL, NULL, NULL, &cdp_attach, &cdp_detach,
&cdp_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug,
NULL, NULL, &cdp_help, NULL, NULL, &cdp_description
};
static struct card_wirings wirings[] = {
{WIRING_8WORD, "8WORD"},
{WIRING_SOAP, "SOAP"},
{WIRING_IS, "IS"},
{0, 0},
};
// vars where card is encoded for punching
char card_buf[120];
int card_nbuf;
// vars where card is encoded for printing
char card_lpt[120];
int card_nlpt;
void encode_char(int cPunch, int cLpt)
{
if ((cPunch) && (card_nbuf < 80)) {
card_buf[card_nbuf++] = cPunch;
}
if ((cLpt) && (card_nlpt < 120)) {
card_lpt[card_nlpt++] = cLpt;
}
}
void encode_lpt_spc(int nSpaces)
{
while (nSpaces-- >0) encode_char(0, 32);
}
void encode_lpt_str(const char * buf)
{
while (*buf) encode_char(0, *buf++);
}
void encode_lpt_num(t_int64 d, int l)
{
char s[20];
int i,n;
d=AbsWord(d);
for (i=9;i>=0;i--) {
n = (int) (d % 10);
d = d / 10;
s[i] = '0' + n;
}
s[10] = 0;
encode_lpt_str(&s[10-l]);
}
#define wf_NNNNNNNNNNs 0
#define wf_NN_NNNN_NNNNs 1
#define wf_sN_NNNNNNN_NN 3
#define wf_sN_NNN_NNN_NNN 4
void encode_lpt_word(t_int64 d, int NegZero, int wFormat)
{
int n;
int neg=0;
if (d < 0) {d=-d; neg=1;} else if ((d==0) && (NegZero)) neg=1;
if (wFormat == wf_NN_NNNN_NNNNs) {
n = Shift_Digits(&d, 2); encode_lpt_num(n, 2); encode_lpt_spc(1);
n = Shift_Digits(&d, 4); encode_lpt_num(n, 4); encode_lpt_spc(1);
n = Shift_Digits(&d, 4); encode_lpt_num(n, 4);
encode_char(0, neg ? '-':' ');
} else if (wFormat == wf_sN_NNNNNNN_NN) {
encode_char(0, neg ? '-':'+');
n = Shift_Digits(&d, 1); encode_lpt_num(n, 1); encode_lpt_spc(1);
n = Shift_Digits(&d, 7); encode_lpt_num(n, 7); encode_lpt_spc(1);
n = Shift_Digits(&d, 2); encode_lpt_num(n, 2);
} else if (wFormat == wf_sN_NNN_NNN_NNN) {
encode_char(0, neg ? '-':'+');
n = Shift_Digits(&d, 1); encode_lpt_num(n, 1); encode_lpt_spc(1);
n = Shift_Digits(&d, 3); encode_lpt_num(n, 3); encode_lpt_spc(1);
n = Shift_Digits(&d, 3); encode_lpt_num(n, 3); encode_lpt_spc(1);
n = Shift_Digits(&d, 3); encode_lpt_num(n, 3);
} else { // default: wFormat == wf_NNNNNNNNNNs
encode_lpt_num(d,10);
encode_char(0, neg ? '-':' ');
}
}
// set pch_word[10] with encoded word d.
// if d negative, sign on last digit (units digit)
// if bSetHiPuch=1, set HiPunch on last digit.
// if bSetHiPuch=2, set HiPunch on last digit and on second digit.
void sprintf_word(char * pch_word, t_int64 d, int NegZero, int bSetHiPuch)
{
int i,n,neg, hi;
if (d < 0) {
neg = 1;
d = -d;
} else if ((d == 0) && (NegZero)) {
neg = 1; // Negative Zero -> also puncho X(11) on last 0 digit
} else {
neg = 0;
}
for (i=9;i>=0;i--) {
hi = 0;
if ((i==1) && (bSetHiPuch == 2)) hi = 1; // Set Hi Punch on second digit
if ((i==9) && (bSetHiPuch > 0)) hi = 1; // Set Hi Punch on last digit (units digit)
n = (int) (d % 10);
d = d / 10;
n = n + hi * 10;
if ((neg == 1) && (i==9)) n = n + 20; // Set negative punch X(11) on last digit
pch_word[i] = digits_ascii[n];
}
pch_word[10] = 0;
}
void encode_pch_str(const char * buf)
{
while (*buf) {
encode_char(*buf++, 0);
}
}
void encode_8word_wiring(int addr)
{
// encode 8 numerical words per card
// get the decoded data from drum at addr
int i, NegZero;
t_int64 d;
char pch_word[20];
// punch card
for(i=0;i<8;i++) {
ReadDrum(addr + i, &d, &NegZero);
sprintf_word(pch_word, d, NegZero, 0);
encode_pch_str(pch_word);
}
// print out card contents
// 8 words in format NN NNNN NNNN+
for(i=0;i<8;i++) {
ReadDrum(addr + i, &d, &NegZero);
encode_lpt_word(d, NegZero, wf_NN_NNNN_NNNNs);
encode_lpt_spc(1);
}
}
void encode_soap_wiring(int addr)
{
// encode soap card simulating soap control panel wiring for 533
// from SOAP II manual at http://www.bitsavers.org/pdf/ibm/650/24-4000-0_SOAPII.pdf
// storage in output block
// Word 1977: | <- Location -> | Alphabetic
// 1978: | <- Data Addr -> | Alphabetic
// 1979: | <- Inst Addr -> | Alphabetic
// +-+-+-|-+-+-|-+-|-+-|
// 1980: | Op Code |DTg|ITg| Alphabetic
// +-+-+-|-+-+-|-+-|-+-|
// 1981: | <- Remarks -> | Alphabetic
// 1982: | <- Remarks -> | Alphabetic
// 1983: |<-Assembled Instr->|
// +-+-|-+-+-+-|-+-+-|-|
// 1984: | |N N N N| |T| N N N N=Location, T=Type (0 if Blank)
// 1985: | |N N N N| N N N N=Card Number
// 1986: |a|b|c|d|e|f|g|h|i|j| a = 0/8 (for non blank type)
// b = 0/8 (negative)
// c = 0/8 (bypass)
// d = 0/8 (punch a) =8 -> do not print Loc op da ir
// e = 0/8 (punch b) =8 -> punch availability table
// f = 0/8 (800X instruction)
// g = 0/8 (blank out L)
// h = 0/8 (blank out D)
// i = 0/8 (blank out I)
// j = 0/8 (blank out OP)
//
// SOAP printout format
// | Sg | Location | OpCode | Data Addr | Tg | Instr Addr | Tg | Remarks | Drum Addr | NN NNNN NNNN[-] (signed word value at this drum addr)
// SOAP punch format (load card, 1 word per card)
// simulates punching over prepunched 1-word load card
// | word1 | nnnn | 24 addr 800? | NNNNNNNNNN[-] | source soap line
// nnnn=card number
// addr=drum address where the word is loaded
// NNNNNNNNNN=word to be loaded at addr, with sign
char loc[6], data_addr[6], inst_addr[6], OpCode[6], Data_Tag[6], Instr_Tag[6], rem1[6], rem2[6];
char pch_word[20];
t_int64 d, instr;
int location, CardNum, ty;
int b_non_blank, neg, b_blk_op, b_blk_i, b_blk_d, b_blk_l, b_800X, b_pch_b, b_pch_a, b_bypass; // punch control flags
int i, sv_card_nbuf, n;
int pat1, pat2;
word_to_ascii(loc, 1, 5, DRUM[addr + 0]);
word_to_ascii(data_addr, 1, 5, DRUM[addr + 1]);
word_to_ascii(inst_addr, 1, 5, DRUM[addr + 2]);
word_to_ascii(OpCode, 1, 3, DRUM[addr + 3]);
word_to_ascii(Data_Tag, 4, 1, DRUM[addr + 3]);
word_to_ascii(Instr_Tag, 5, 1, DRUM[addr + 3]);
word_to_ascii(rem1, 1, 5, DRUM[addr + 4]);
word_to_ascii(rem2, 1, 5, DRUM[addr + 5]);
instr = DRUM[addr + 6];
location = (int) ((DRUM[addr + 7] / D4) % D4);
ty = (int) ( DRUM[addr + 7] % 10);
CardNum = (int) ( DRUM[addr + 8] % D4);
d = DRUM[addr + 9];
b_blk_op = ((int) (d % 10) == 8) ? 1:0; d = d / 10;
b_blk_i = ((int) (d % 10) == 8) ? 1:0; d = d / 10;
b_blk_d = ((int) (d % 10) == 8) ? 1:0; d = d / 10;
b_blk_l = ((int) (d % 10) == 8) ? 1:0; d = d / 10;
b_800X = ((int) (d % 10) == 8) ? 1:0; d = d / 10;
b_pch_b = ((int) (d % 10) == 8) ? 1:0; d = d / 10;
b_pch_a = ((int) (d % 10) == 8) ? 1:0; d = d / 10;
b_bypass = ((int) (d % 10) == 8) ? 1:0; d = d / 10;
neg = ((int) (d % 10) == 8) ? 1:0; d = d / 10;
b_non_blank = ((int) (d % 10) == 8) ? 1:0; d = d / 10;
// printf("bits %06d%04d%c ", printfw(DRUM[addr + 9])); // to echo the status digits of punched card
// generate card
if (b_pch_b) {
// punch availability table (pat pseudo-op output)
for(i=0;i<8;i++) {
sprintf_word(pch_word, DRUM[addr + i], 0, 1);
encode_pch_str(pch_word);
}
} else {
if (b_pch_a) {
// punch non generating code card
encode_pch_str("0?0000800?"); // load card
sprintf(pch_word, " %04d", CardNum); // card number
encode_pch_str(pch_word);
encode_pch_str(" "); // two blank words
encode_pch_str(" ");
if (b_non_blank) encode_pch_str("1"); else encode_pch_str(" ");
} else {
// punch generating code card
if (b_800X) {
encode_pch_str("6I1954800?"); // load card for word to be stored in 800X addr
} else {
encode_pch_str("6I1954195C"); // load card for word to be stored in drum
}
sprintf(pch_word, " %04d", CardNum); // card number
encode_pch_str(pch_word);
sprintf(pch_word, "24%04d800?", location);// addr to place the loaded word
encode_pch_str(pch_word);
sprintf_word(pch_word, AbsWord(instr) * (neg ? -1:1), ((neg) && (instr == 0)) ? 1:0, 1);
encode_pch_str(pch_word);
encode_char(ty == 0 ? ' ' : '0'+ty, 0);
}
encode_pch_str(" ");
sv_card_nbuf = card_nbuf; // save pch bufer current pos
encode_pch_str(loc); encode_pch_str(OpCode);
encode_pch_str(data_addr); encode_pch_str(Data_Tag);
encode_pch_str(inst_addr); encode_pch_str(Instr_Tag);
encode_pch_str(rem1); encode_pch_str(rem2);
// convert to lowercase for punching
for (i=sv_card_nbuf;i<card_nbuf;i++)
if ((card_buf[i] >= 'A') && (card_buf[i] <= 'Z'))
card_buf[i] = card_buf[i] - 'A' + 'a';
card_buf[card_nbuf] = 0;
}
// generate printout
if (b_pch_b) {
// print availability table (pat pseudo-op output)
for(i=0; i<4; i++) {
d = DRUM[addr + i*2];
pat1 = (int) ((d / D4) % D4);
pat2 = (int) ( d % D4);
d = DRUM[addr + i*2 + 1];
encode_lpt_num(pat1, 4);
encode_lpt_spc(2);
encode_lpt_num(d, 10);
encode_lpt_spc(2);
encode_lpt_num(pat2, 4);
encode_lpt_spc(5);
}
} else if (ty == 1) {
// print coment line
encode_lpt_str("1");
encode_lpt_spc(14);
encode_lpt_str(loc); encode_lpt_str(OpCode);
encode_lpt_str(data_addr); encode_lpt_str(Data_Tag);
encode_lpt_str(inst_addr); encode_lpt_str(Instr_Tag);
encode_lpt_str(rem1); encode_lpt_str(rem2);
} else {
encode_lpt_spc(1);
encode_lpt_str(loc);
encode_lpt_spc(2); encode_char(0, neg ? '-':' '); encode_lpt_spc(1);
encode_lpt_str(OpCode); encode_lpt_spc(3);
encode_lpt_str(data_addr); encode_lpt_str(Data_Tag); encode_lpt_spc(2);
encode_lpt_str(inst_addr); encode_lpt_str(Instr_Tag); encode_lpt_spc(5);
encode_lpt_str(rem1); encode_lpt_str(rem2);
if (b_pch_a) {
// blank op -> do not print location and intruction
if (b_bypass) {
encode_lpt_spc(4);
encode_lpt_str("BYPASS");
}
} else {
encode_lpt_spc(4);
if (b_blk_l) { encode_lpt_spc(4); } else encode_lpt_num(location, 4);
encode_lpt_spc(2); encode_char(0, neg ? '-':' '); encode_lpt_spc(1);
d = instr;
n = Shift_Digits(&d, 2); // operation code (2 digits)
if (b_blk_op) { encode_lpt_spc(2); } else encode_lpt_num(n, 2);
encode_lpt_spc(2);
n = Shift_Digits(&d, 4); // data addr (4 digits)
if (b_blk_d) { encode_lpt_spc(4); } else encode_lpt_num(n, 4);
encode_lpt_spc(2);
n = Shift_Digits(&d, 4); // instr addr (4 digits)
if (b_blk_i) { encode_lpt_spc(4); } else encode_lpt_num(n, 4);
encode_lpt_spc(1);
if (b_blk_l) encode_lpt_str("BLANK L"); else
if (b_blk_op) encode_lpt_str("BLANK OP"); else
if (b_blk_d) encode_lpt_str("BLANK D"); else
if (b_blk_i) encode_lpt_str("BLANK I");
}
}
}
void encode_is_wiring(int addr)
{
// encode Floationg Decimal Interpretive System (IS) card simulating control panel wiring for 533 as described
// in manual at http://www.bitsavers.org/pdf/ibm/650/28-4024_FltDecIntrpSys
// storage in output block
// +-+-+-+-+-+-|-+-+-+-|
// Word 1977: |Trc|N N N N| | Location
// 1978: | |N N N N| | Word Count
// +-------------------+
// 1979: | word1 |
// 1980: | word2 |
// 1981: | word3 |
// 1982: | word4 |
// 1983: | word5 |
// 1984: | word6 |
// +-------------------+
// 1985: | Problem Number |
// 1986: | |N N N N| | Card Number
// +-------------------+
//
// if word at 1977 is negative, a load card is punched, but no printout is generated
// if word at 1977 is positive, regular output card format is used on punch
// Column: 1 2 3 4 | 5 6 | 7 8 9 | 10 | 11 | 12 - 21 | 22 | 23 - 32 | 33 | 34 - 43 | 44 | 45 - 54 | 55 | 56 - 65 | 66 | 67 - 76 | 77 78 79 | 80
// Card | | | Location | wc | s1 | Word1 | s2 | Word2 | s3 | Word3 | s4 | Word4 | s5 | Word5 | s6 | Word6 | Problem |
// Num | if location is > 9999, will use column 6 Num
// wordN is printed as +N NNNNNNN NN (IT sci notation)
//
// IT printout format for non tracing cards:
// | Location | Word1 | Word2 | Word3 | Word4 | Word5 | Word6
// wordN is printed as +N NNNNNNN NN (IT sci notation)
//
// IT printout format for tracing cards (Trc digits in word 1977 are non-zero):
// | Location | Word1 | Word2 | Word3 | Word4 | Word5 | Word6
// word1 to 3 are printed as +N NNN NNN NNN (IT instruction format)
// word4 to 6 are printed as +N NNNNNNN NN (IT sci notation)
//
int i, NegZero;
t_int64 d;
int CardNum, loc, wc, PrNum, bTraceCard;
char pch_word[20];
int bSetHiPunch;
bSetHiPunch = (DRUM[addr] < 0) ? 2 : 0; // first bSetHiPunch is 2 if word negative (signals a load card must be punched)
loc = (int) ((DRUM[addr] / D4) % D4);
CardNum = (int) ((DRUM[addr+9] / D4) % D4);
wc = (int) ((DRUM[addr+1] / D4) % D4);
PrNum = (int) ( DRUM[addr+8]);
bTraceCard = (DRUM[addr] / D8) > 0 ? 1 : 0; // if to higher digits are nonzero -> is a trace card
if (bSetHiPunch) {
// punch a load card
for(i=0;i<8;i++) {
ReadDrum(addr + i, &d, &NegZero);
if ((i==0) && (d < 0)) d = -d; // get absolute value for DRUM[addr + 0]
sprintf_word(pch_word, d, NegZero, bSetHiPunch);
if (bSetHiPunch==2) bSetHiPunch = 1; // if bSetHiPunch is 2 change it to bSetHiPunch = 1
encode_pch_str(pch_word);
}
} else {
// punch a card using output format
if (loc < 1000) {
sprintf(pch_word, "%04d %03d%01d", CardNum, loc, wc);
} else {
sprintf(pch_word, "%04d %04d%01d", CardNum, loc, wc);
}
encode_pch_str(pch_word);
for(i=0;i<6;i++) {
if (i<wc) {
ReadDrum(addr + i + 2, &d, &NegZero);
if ((d < 0) || ((d==0) && (NegZero))) {
encode_pch_str("-");
d = -d;
} else {
encode_pch_str("+");
}
sprintf_word(pch_word, d, 0, 0);
encode_pch_str(pch_word);
} else {
encode_pch_str(" "); // 11 spaces
}
}
if (PrNum < 0) PrNum = 0;
if (PrNum > 999) PrNum = 999;
sprintf(pch_word, "%03d", PrNum);
encode_pch_str(pch_word);
}
if (bSetHiPunch) {
// load card, does not generate printout
// mark lpt output buffer to not print
if (card_nlpt == 0) {
card_lpt[card_nlpt++] = 0;
}
} else {
// not load card -> do normal printout for card
if (wc > 6) wc = 6;
if (loc < 1000) {
encode_lpt_spc(1);
encode_lpt_num(loc, 3);
} else {
encode_lpt_num(loc, 4);
}
for(i=2;i<2+wc;i++) {
encode_lpt_spc(2);
ReadDrum(addr + i, &d, &NegZero);
if ((bTraceCard) && (i<5)) {
// if printing a trace card, first three words are printed as intructions (+N NNN NNN NNN)
encode_lpt_word(d, NegZero, wf_sN_NNN_NNN_NNN);
} else {
// print numbers adding spaces to ease reading IT floating point format (+N NNNNNNN NN)
encode_lpt_word(d, NegZero, wf_sN_NNNNNNN_NN);
}
}
}
}
/* Card punch routine */
uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 addr)
{
int i,c,h;
struct _card_data *data;
uint32 wiring;
/* Are we currently tranfering? */
if (uptr->u5 & URCSTA_BUSY)
return SCPE_BUSY;
/* Test ready */
if ((uptr->flags & UNIT_ATT) == 0) {
sim_debug(DEBUG_CMD, &cdp_dev, "No cards (no file attached)\r\n");
return SCPE_NOCARDS;
}
// copy and translate drum memory words to chars to punch
// using the control panel wiring.
wiring = (uptr->flags & UNIT_CARD_WIRING);
card_nbuf = card_nlpt = 0;
if (wiring == WIRING_SOAP) {
// encode soap card simulating soap control panel wiring for 533 (gasp!)
encode_soap_wiring(addr);
} else if (wiring == WIRING_IS) {
// encode it card
encode_is_wiring(addr);
} else if (wiring == WIRING_8WORD) {
// encode 8 words per card
encode_8word_wiring(addr);
} else {
// default wiring: decode up to 8 numerical words per card
encode_8word_wiring(addr);
}
if ((card_nlpt == 1) && (card_lpt[0] == 0)) {
// skip this line printout & echo
} else {
/* echo? */
encode_char(0, 13); encode_char(0, 10);
if (uptr->flags & UNIT_CARD_ECHO) {
for (i=0;i<card_nlpt;i++) sim_putchar(card_lpt[i]);
}
/* printout punched cards? */
if (uptr->flags & UNIT_CARD_PRINT) {
// printout will be directed to file attached to CDP0 unit, if any
if (cdp_unit[0].flags & UNIT_ATT) {
sim_fwrite(&card_lpt, 1, card_nlpt, cdp_unit[0].fileref);
}
}
}
// trim right spaces for printing punch card
card_buf[card_nbuf] = 0;
sim_debug(DEBUG_DETAIL, &cpu_dev, "Punch Card: %s\r\n", card_buf);
/* punch the cards */
data = (struct _card_data *)uptr->up7;
for (i=0; i<80; i++) {
if (i >= card_nbuf) {
c = 32;
} else {
c = card_buf[i];
}
if (c == 32) {
// no punch
data->image[i] = 0;
} else {
// punch char
h = ascii_to_hol[c & 127];
data->image[i] = h;
}
}
sim_punch_card(uptr, NULL);
sim_debug(DEBUG_CMD, &cdp_dev, "PUNCH\r\n");
uptr->u5 |= URCSTA_BUSY;
uptr->u4 = 0;
uptr->u5 &= ~URCSTA_BUSY;
return SCPE_OK;
}
/* Handle transfer of data for card punch */
t_stat
cdp_srv(UNIT *uptr) {
// I/O is synchronous. No need to set up srv
return SCPE_OK;
}
/* Set card read/punch control panel wiring */
t_stat cdp_set_wiring (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
int f;
if (uptr == NULL) return SCPE_IERR;
if (cptr == NULL) return SCPE_ARG;
for (f = 0; wirings[f].name != 0; f++) {
if (strcmp (cptr, wirings[f].name) == 0) {
uptr->flags = (uptr->flags & ~UNIT_CARD_WIRING) | wirings[f].mode;
return SCPE_OK;
}
}
return SCPE_ARG;
}
/* Show card read/punch control panel wiring */
t_stat cdp_show_wiring (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
int f;
for (f = 0; wirings[f].name != 0; f++) {
if ((uptr->flags & UNIT_CARD_WIRING) == wirings[f].mode) {
fprintf (st, "%s wiring", wirings[f].name);
return SCPE_OK;
}
}
fprintf (st, "invalid control panel wiring (%d)", uptr->flags & UNIT_CARD_WIRING);
return SCPE_OK;
}
/* Set card read/punch echo to console */
t_stat cdp_set_echo (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
int u = (uptr - cdp_unit);
t_stat r;
int num;
if (uptr == NULL) return SCPE_IERR;
if (cptr == NULL) {
num = 1; // no param means set (=1)
} else {
num = (int) get_uint (cptr, 10, 1, &r);
if (r != SCPE_OK) return r;
}
if (u == 0) {
sim_printf("this option cannot be set for CDP0\r\n");
return SCPE_ARG;
}
switch(val) {
case 0:
if (num== 0) {
uptr->flags = uptr->flags & ~UNIT_CARD_ECHO;
} else {
uptr->flags = uptr->flags | UNIT_CARD_ECHO;
}
break;
case 1:
if (num== 0) {
uptr->flags = uptr->flags & ~UNIT_CARD_PRINT;
} else {
uptr->flags = uptr->flags | UNIT_CARD_PRINT;
}
break;
}
return SCPE_OK;
}
/* Show card read/punch control panel wiring */
t_stat cdp_show_echo (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
switch(val) {
case 0:
fprintf (st, (uptr->flags & UNIT_CARD_ECHO) ? "ECHO": "No ECHO");
break;
case 1:
fprintf (st, (uptr->flags & UNIT_CARD_PRINT) ? "PRINT": "No PRINT");
break;
}
return SCPE_OK;
}
t_stat
cdp_attach(UNIT * uptr, CONST char *file)
{
t_stat r;
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
return r;
uptr->u5 = 0;
return SCPE_OK;
}
t_stat
cdp_detach(UNIT * uptr)
{
return sim_card_detach(uptr);
}
t_stat
cdp_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
fprintf (st, "%s\r\n\r\n", cdp_description(dptr));
fprintf (st, "The 533 Card Read-punch writes cards using the selected\r\n");
fprintf (st, "control panel wiring to set the format of punched cards.\r\n");
fprintf (st, "It is possible to simulate a 407 accounting machine for\r\n");
fprintf (st, "printing using SET CDP1 PRINT=1. In this case, punched\r\n");
fprintf (st, "cards will be printed to file attached to unit 0 (CDP0).\r\n");
fprintf (st, "SET CDP ECHO=1 will display on console cards printout.\r\n");
sim_card_attach_help(st, dptr, uptr, flag, cptr);
fprint_set_help(st, dptr);
fprint_show_help(st, dptr);
return SCPE_OK;
}
const char *
cdp_description(DEVICE *dptr)
{
return "533 Card Punch + 407 Accounting for printing";
}

556
I650/i650_cdr.c Normal file
View file

@ -0,0 +1,556 @@
/* i650_cdr.c: IBM 650 Card reader.
Copyright (c) 2018, Roberto Sancho
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERTO SANCHO BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This is the standard card reader.
These units each buffer one record in local memory and signal
ready when the buffer is full or empty. The channel must be
ready to recieve/transmit data when they are activated since
they will transfer their block during chan_cmd. All data is
transmitted as BCD characters.
*/
#include "i650_defs.h"
#include "sim_card.h"
#define UNIT_CDR UNIT_ATTABLE | UNIT_RO | MODE_026
/* std devices. data structures
cdr_dev Card Reader device descriptor
cdr_unit Card Reader unit descriptor
cdr_reg Card Reader register list
cdr_mod Card Reader modifiers list
*/
uint32 cdr_cmd(UNIT *, uint16, uint16);
t_stat cdr_srv(UNIT *);
t_stat cdr_reset(DEVICE *);
t_stat cdr_attach(UNIT *, CONST char *);
t_stat cdr_detach(UNIT *);
t_stat cdr_help(FILE *, DEVICE *, UNIT *, int32, const char *);
const char *cdr_description(DEVICE *dptr);
t_stat cdr_set_wiring (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat cdr_show_wiring (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
UNIT cdr_unit[] = {
{UDATA(cdr_srv, UNIT_CDR, 0), 300}, // 4 readers. Unit 0 not used
{UDATA(cdr_srv, UNIT_CDR, 0), 300},
{UDATA(cdr_srv, UNIT_CDR, 0), 300},
{UDATA(cdr_srv, UNIT_CDR, 0), 300},
};
MTAB cdr_mod[] = {
{MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT", &sim_card_set_fmt, &sim_card_show_fmt, NULL, "Set card format"},
{MTAB_XTD | MTAB_VUN, 0, "WIRING", "WIRING", &cdr_set_wiring, &cdr_show_wiring, NULL, "Set card read control panel Wiring"},
{0}
};
DEVICE cdr_dev = {
"CDR", cdr_unit, NULL, cdr_mod,
4, 8, 15, 1, 8, 8,
NULL, NULL, NULL, NULL, &cdr_attach, &sim_card_detach,
&cdr_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug,
NULL, NULL, &cdr_help, NULL, NULL, &cdr_description
};
static struct card_wirings wirings[] = {
{WIRING_8WORD, "8WORD"},
{WIRING_SOAP, "SOAP"},
{WIRING_IS, "IS"},
{0, 0},
};
// decode digit 0-9 read from card to get value and X(11) and Y(12) punch state (minus/HiPunch)
// return -1 if not a digit number
int decode_digit(char c1, int * HiPunch, int * NegPunch)
{
int i,n;
*HiPunch = *NegPunch = 0;
// N is 0..9 or ?A..I (0..9 with Y(12) High Punch set)
// or !J..R (0..9 with X(11) Minus Punch set).
// or &S..Z# (0..9 with both X(11) and Y(12) Punch set).
if (c1 == 32) return 0; // space read as zero
for (i=0; i<40; i++) {
if (c1 == digits_ascii[i]) {
n = i % 10;
i = i / 10;
*HiPunch = (i & 1);
*NegPunch = (i >> 1);
return n;
}
}
return -1; // not a valid digit
}
// get 10 digits word from buf, with sign. return 1 if HiPunch set on any digit
int decode_8word_wiring(char * buf, int addr)
{
// decode up to 8 numerical words per card
// input card
// NNNNNNNNNN ... 8 times
// N is 0..9 or ?A..I (0..9 with Y(12) High Punch set)
// or !J..R (0..9 with X(11) Minus Punch set).
// or &S..Z# (0..9 with both X(11) and Y(12) Punch set).
// If last digit of word has X(11) punch whole word is set as negative value
// If N is a space, a 0 is assumed
// put the decoded data in drum at addr (if addr < 0 -> do not store in drum)
// return 1 if any colum has Y(12) hi-punch set
int c1,c2,wn,eor,iCol;
int HiPunch, hip;
int NegPunch, NegZero;
int nDigits;
t_int64 d;
NegZero = 0; // flag set if negative zero is read
HiPunch = 0; // set to 1 if Y(12) high punch found
eor = 0; // signals end of card record
iCol = 0; // current read colum in card
for (wn=0;wn<8;wn++) { // one card generates 8 words in drum mem
d = 0;
nDigits=0; // number of digits
while (1) {
c1 = buf[iCol++];
if (c1 < ' ') {eor = 1; break;} // end of card
c2 = decode_digit(c1, &hip, &NegPunch);
if (hip) HiPunch = 1; // if any column has Hi Punch Y(12) set, signal it
if (c2 < 0) c2 = 0; // nondigits chars interpreted as zero
d = d * 10 + c2;
nDigits++;
if (nDigits == 10) {
// end of word
if (NegPunch) { // has last digit a minus X(11) punch set?
d = -d; // yes, change sign of word read
if (d == 0) NegZero=1; // word read is minus zero
}
break;
}
}
if (nDigits == 0) break; // no well-formed word read -> terminate card processing
if (addr >= 0) WriteDrum(addr++, d, NegZero); // store word read from card into drum
if (eor) break; // end of card sensed -> terminate card processing
}
return HiPunch;
}
t_int64 decode_num_word(char * buf, int nDigits, int bSpaceIsZero)
{
t_int64 d;
int i,c;
d = 0;
for (i=0;i<nDigits;i++) {
c = *buf++;
if ((c == 32) && (bSpaceIsZero)) c = '0';
if ((c < '0') || (c > '9')) {
d = -1; // not a number
break;
}
d = d * 10 + c - '0';
}
if (d < 0) {
// not a number -> return all 9's
d = 0;
for (i=0;i<nDigits;i++) d = d * 10 + 9;
}
return d;
}
t_int64 decode_alpha_word(char * buf, int n)
{
t_int64 d;
int i;
d = 0;
for (i=0;i<n;i++) {
d = d * 100 + ascii_to_NN(*buf++);
}
return d;
}
void decode_soap_wiring(char * buf, int addr)
{
// decode soap card simulating soap control panel wiring for 533
// from SOAP II manual at http://www.bitsavers.org/pdf/ibm/650/24-4000-0_SOAPII.pdf
// input card
// Column: 41 | 42 | 43 44 45 46 47 | 48 49 50 | 51 52 53 54 55 | 56 | 57 58 59 60 61 | 62 | 63 64 65 66 67 68 69 70 71 72
// Ty | Sg | Location | OpCode | Data Addr | Tg | Instr Addr | Tg | Remarks
//
// Ty = Type = blank, 1 or 2
// Sg = sign = blank or -
// Tg = Tag =
// storage in input block
// Word 1951: | <- Location -> | Alphabetic
// 1952: | <- Data Addr -> | Alphabetic
// 1953: | <- Inst Addr -> | Alphabetic
// +-+-+-|-+-+-|-+-|-+-|
// 1954: | Op Code |DTg|ITg| Alphabetic
// +-+-+-|-+-+-|-+-|-+-|
// 1955: | <- Remarks -> | Alphabetic
// 1956: | <- Remarks -> | Alphabetic
// +-+-+-+-+-+-|-+-+-+-|
// 1957: | |N N N N| L Absolute Part
// 1958: | |N N N N| D Absolute Part
// 1959: | |N N N N| I Absolute Part
// 1960: | |T b n| T=Type (0 if Blank), b=0/8 (for non blank type), n=0/8 (for negative)
//
int ty,neg;
DRUM[addr + 0] = decode_alpha_word(&buf[42], 5); // Location (5 chars)
DRUM[addr + 1] = decode_alpha_word(&buf[50], 5); // Data Addr (5 chars)
DRUM[addr + 2] = decode_alpha_word(&buf[56], 5); // Inst Addr (5 chars)
DRUM[addr + 3] = decode_alpha_word(&buf[47], 3) * D4 + // OpCode (3 chars only)
decode_alpha_word(&buf[55], 1) * 100 + // Data Addr Tag (1 char only)
decode_alpha_word(&buf[61], 1); // Instr Addr Tag (1 char only)
DRUM[addr + 4] = decode_alpha_word(&buf[62], 5); // Remarks
DRUM[addr + 5] = decode_alpha_word(&buf[67], 5); // Remarks
DRUM[addr + 6] = decode_num_word(&buf[43], 4, 0); // Absolute Part of location
DRUM[addr + 7] = decode_num_word(&buf[51], 4, 0); // Absolute Part of Data Addr
DRUM[addr + 8] = decode_num_word(&buf[57], 4, 0); // Absolute Part of Instr Addr
if (buf[40] == '1') {ty = 18; } else
if (buf[40] == '2') {ty = 28; } else {ty = 0; }
neg = (buf[41] == '-') ? 8:0;
DRUM[addr + 9] = ty * 10 + neg; // |T b n| T=Type (0 if Blank), b=0/8 (for non blank type), n=0/8 (for negative)
}
int sformat(char * buf, const char * match)
{
char m,c;
while(1) {
m = *match++;
if (m == 0) break;
c = *buf++;
if (c == 0) return 0; // end of buf str before end of match string -> return 0 -> buf does not match
if ((m == ' ') && (c == ' ')) continue;
if ((m == 'N') && (c >= '0') && (c <= '9')) continue;
if ((m == '+') && ((c == '+') || (c == '-'))) continue;
return 0; // buf does not match -> return 0 -> buf does not match
}
return 1; // end of match string -> return 1 -> buf matches
}
void decode_is_wiring(char * buf, int addr)
{
// decode Floationg Decimal Interpretive System (IS) card simulating control panel wiring for 533 as described
// in manual at http://www.bitsavers.org/pdf/ibm/650/28-4024_FltDecIntrpSys
// input card
// Column: 1 2 3 4 | 5 6 | 7 8 9 | 10 | 11 | 12 - 21 | 22 | 23 - 32 | 33 | 34 - 43 | 44 | 45 - 54 | 55 | 56 - 65 | 66 | 67 - 76 | 77 78 79 | 80
// Card | | Location | wc | s1 | Word1 | s2 | Word2 | s3 | Word3 | s4 | Word4 | s5 | Word5 | s6 | Word6 | Problem |
// Num | Num
//
// wc = Word Count (space for 1)
// s1 = sign of word 1 (space for +)
// Tr = Tracing identification
//
// Alternate input format to allow system deck loading
// Column: 1 2 | 3 | 4 5 6 | 7 | 8 9 10 11 | 12 | 13 - 24
// Deck | sp | Card | | NNNN | | NN NNNN NNNN
// Num | | Num |
//
// Alternate input format to allow IT source program loading
// Column: 1 2 3 4 | 5 6 | 7 8 9 | 10 | 11 | 12 - 24
// Card | Blank | Location | | sg | N NNN NNN NNN <- This is an IT instruction (format O1 A B C)
// Num |
// Column: 1 2 3 4 | 5 6 | 7 8 9 | 10 | 11 | 12 - 23
// Card | Blank | Location | | sg | N NNNNNNN NN <- This is an IT float numeric constant (mantissa and exponent)
// Num |
// Column: 1 2 3 4 | 5 6 | 7 8 9 | 10 - 23
// Card | Blank | Location | blanks <- This is an IT transfer card (location is start of IT program)
// Num |
//
// storage in input block
// +-+-+-+-+-+-|-+-+-+-|
// Word 1951: | |N N N N| | Location
// 1952: | |N N N N| | Word Count
// +-------------------+
// 1953: | word1 |
// 1954: | word2 |
// 1955: | word3 |
// 1956: | word4 |
// 1957: | word5 |
// 1958: | word6 |
// +-------------------+
// 1959: | Problem Number |
// +-------------------+
// input card
// WordN is 0..9,<space>
// sign is -,+,<space>
// put the decoded data in drum at addr (if addr < 0 -> do not store in drum)
// card number is ignored on reading
int wc,neg,i;
int NegZero;
t_int64 d;
if ( sformat(&buf[6], " ")) {
// blank card: read as all zero, one word count
// this allows to have blank cards/comments card as long as the comment starts on column 27 of more
DRUM[addr + 1] = 1 * D4; // word count
} else if ( sformat(&buf[5], " NNN ")) {
// alternate format for loading IT program (IT transfer card)
DRUM[addr + 0] = decode_num_word(&buf[6], 3, 0) * D4; // start location (3 digits)
DRUM[addr + 1] = 0; // word count = 0
} else if ( sformat(&buf[5], " NNN +N NNN NNN NNN ")) {
// alternate format for loading IT program (IT instruction)
DRUM[addr + 0] = decode_num_word(&buf[6], 3, 0) * D4; // location (3 digits)
DRUM[addr + 1] = 1 * D4; // word count
NegZero = 0;
neg = (buf[10] == '-') ? 1:0;
d = decode_num_word(&buf[11], 1, 0) * 10 * D8 + // O1
decode_num_word(&buf[13], 3, 0) * 100 * D4 + // O2 or A
decode_num_word(&buf[17], 3, 0) * 1000 + // B
decode_num_word(&buf[21], 3, 0); // C
if (neg) {
d=-d;
if (d==0) NegZero = 1;
}
WriteDrum(addr + 2, d, NegZero);
} else if ( sformat(&buf[5], " NNN +N NNNNNNN NN ")) {
// alternate format for loading IT program (numeric constant in float format)
DRUM[addr + 0] = decode_num_word(&buf[6], 3, 0) * D4; // location (3 digits)
DRUM[addr + 1] = 1 * D4; // word count
NegZero = 0;
neg = (buf[10] == '-') ? 1:0;
d = decode_num_word(&buf[11], 1, 0) * 10 * D8 + // integer part of mantissa
decode_num_word(&buf[13], 7, 0) * 100 + // factional part of mantissa
decode_num_word(&buf[21], 2, 0); // exponent
if (neg) {
d=-d;
if (d==0) NegZero = 1;
}
WriteDrum(addr + 2, d, NegZero);
} else if ( (sformat(&buf[6], " NNNN NN NNNN NNNN ")) ||
(sformat(&buf[6], " NNNN NN NNNN ")) ||
(sformat(&buf[6], " NNNN NN NNNN ")) ||
(sformat(&buf[6], " NNNN NN "))
) {
// alternate format for loading main IT system deck
DRUM[addr + 0] = decode_num_word(&buf[7], 4, 0) * D4; // location (4 digits)
DRUM[addr + 1] = 1 * D4; // word count = 1
DRUM[addr + 2] = decode_num_word(&buf[12], 2, 1) * D8 + // op
decode_num_word(&buf[15], 4, 1) * D4 + // data address
decode_num_word(&buf[20], 4, 1); // instr addr, no negative zero allowed
} else {
// regular IT read/punch format
DRUM[addr + 0] = decode_num_word(&buf[6], 3, 0) * D4; // location (3 digits)
wc = (int) decode_num_word(&buf[9], 1, 1);
if (wc > 6) wc = 6;
DRUM[addr + 1] = wc * D4; // word count
for (i=0;i<wc;i++) {
NegZero = 0;
neg = (buf[10 + 11*i] == '-') ? 1:0;
d = decode_num_word(&buf[11 + 11*i], 10, 1);
if (neg) {
d=-d;
if (d==0) NegZero = 1;
}
WriteDrum(addr + 2 + i, d, NegZero);
}
DRUM[addr + 9] = decode_num_word(&buf[76], 3, 1); // problem number
}
}
/*
* Device entry points for card reader.
*/
uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 addr)
{
int i,c;
struct _card_data *data;
char buf[81];
int buf_len;
uint32 wiring;
/* Are we currently tranfering? */
if (uptr->u5 & URCSTA_BUSY)
return SCPE_BUSY;
// clear read buffer in drum (where words read from cards will be stored)
for (i=0;i<10;i++) WriteDrum(addr + i, 0, 0);
/* Test ready */
if ((uptr->flags & UNIT_ATT) == 0) {
sim_debug(DEBUG_CMD, &cdr_dev, "No cards (no file attached)\r\n");
return SCPE_NOCARDS;
}
/* read the cards */
sim_debug(DEBUG_CMD, &cdr_dev, "READ\r\n");
uptr->u5 |= URCSTA_BUSY;
switch(sim_read_card(uptr)) {
case SCPE_EOF:
sim_debug(DEBUG_DETAIL, &cdr_dev, "EOF\r\n");
uptr->u5 = 0;
return SCPE_NOCARDS;
case SCPE_UNATT:
sim_debug(DEBUG_DETAIL, &cdr_dev, "Not Attached\r\n");
uptr->u5 = 0;
return SCPE_NOCARDS;
case SCPE_IOERR:
sim_debug(DEBUG_DETAIL, &cdr_dev, "ERR\r\n");
uptr->u5 = 0;
return SCPE_NOCARDS;
case SCPE_OK:
break;
}
data = (struct _card_data *)uptr->up7;
// make local copy of card
buf_len = data->ptr;
if (buf_len == 0) {
buf_len = data->len;
}
for (i=0;i<80;i++) {
if (i < buf_len) {
c = data->cbuff[i];
if (c < ' ') c = ' ';
buf[i] = c;
} else {
buf[i] = ' ';
}
}
buf[80] = 0; // terminate string
// trim right spaces for printing read card
for (i=80;i>=0;i--) if (buf[i] > 32) break;
c = buf[i+1]; buf[i+1]=0;
sim_debug(DEBUG_DETAIL, &cpu_dev, "Read Card: %s\r\n", buf);
buf[i+1]=c;
// check if it is a load card (Y(12) = HiPunch set on any column of card) signales it
if (decode_8word_wiring(buf, -1)) {
uptr->u5 |= URCSTA_LOAD;
} else {
uptr->u5 &= ~URCSTA_LOAD;
}
wiring = (uptr->flags & UNIT_CARD_WIRING);
// translate chars read from card and copy to drum memory words
// using the control panel wiring.
if (uptr->u5 & URCSTA_LOAD) {
// load card -> use 8 words per card encoding
decode_8word_wiring(buf, addr);
} else if (wiring == WIRING_SOAP) {
// decode soap card simulating soap control panel wiring for 533 (gasp!)
decode_soap_wiring(buf, addr);
} else if (wiring == WIRING_IS) {
// decode it card
decode_is_wiring(buf, addr);
} else {
// default wiring: decode up to 8 numerical words per card. Can be a load card
decode_8word_wiring(buf, addr);
}
uptr->u5 &= ~URCSTA_BUSY;
return SCPE_OK;
}
/* Handle transfer of data for card reader */
t_stat
cdr_srv(UNIT *uptr) {
// I/O is synchronous. No need to set up svr
return SCPE_OK;
}
/* Set card read/punch control panel wiring */
t_stat cdr_set_wiring (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
int f;
if (uptr == NULL) return SCPE_IERR;
if (cptr == NULL) return SCPE_ARG;
for (f = 0; wirings[f].name != 0; f++) {
if (strcmp (cptr, wirings[f].name) == 0) {
uptr->flags = (uptr->flags & ~UNIT_CARD_WIRING) | wirings[f].mode;
return SCPE_OK;
}
}
return SCPE_ARG;
}
/* Show card read/punch control panel wiring */
t_stat cdr_show_wiring (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
int f;
for (f = 0; wirings[f].name != 0; f++) {
if ((uptr->flags & UNIT_CARD_WIRING) == wirings[f].mode) {
fprintf (st, "%s wiring", wirings[f].name);
return SCPE_OK;
}
}
fprintf (st, "invalid control panel wiring (%d)", uptr->flags & UNIT_CARD_WIRING);
return SCPE_OK;
}
t_stat
cdr_attach(UNIT * uptr, CONST char *file)
{
t_stat r;
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
return r;
uptr->u5 = 0;
uptr->u4 = 0;
uptr->u6 = 0;
return SCPE_OK;
}
t_stat
cdr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
fprintf (st, "%s\r\n\r\n", cdr_description(dptr));
fprintf (st, "The 533 Card Read-punch supported a load mode, and\r\n");
fprintf (st, "several predefined control panel wiring. Default\r\n");
fprintf (st, "wiring is up to 8 numeric words per card.\r\n\r\n");
sim_card_attach_help(st, dptr, uptr, flag, cptr);
fprint_set_help(st, dptr);
fprint_show_help(st, dptr);
return SCPE_OK;
}
const char *
cdr_description(DEVICE *dptr)
{
return "533 Card Read-Ounch unit";
}

1074
I650/i650_cpu.c Normal file

File diff suppressed because it is too large Load diff

247
I650/i650_defs.h Normal file
View file

@ -0,0 +1,247 @@
/* i650_defs.h: IBM 650 simulator definitions
Copyright (c) 2018, Roberto Sancho
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERTO SANCHO BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "sim_defs.h" /* simulator defns */
/* Simulator stop codes */
#define STOP_HALT 1 /* HALT */
#define STOP_IBKPT 2 /* breakpoint */
#define STOP_UUO 3 /* invalid opcode */
#define STOP_CARD 4 /* Stop on card reader/punch error (no card in hopper, read/punch failure, no cards, stop pressed on cdr/cdp*/
#define STOP_PROG 5 /* Programmed stop */
#define STOP_OV 6 /* Overflow stop */
#define STOP_ERRO 7 /* Error in opcode execution: BRD in witch position tested not 8 or 9, TLU failure */
#define STOP_ADDR 8 /* Address stop: Store attempt on addr 800X, address out of drum mem */
/* Memory */
#define MAXMEMSIZE (4000)
#define MEMSIZE cpu_unit.capac /* actual memory size */
#define MEMMASK (MEMSIZE - 1) /* Memory bits */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
extern t_int64 DRUM[MAXMEMSIZE];
extern int DRUM_NegativeZeroFlag[MAXMEMSIZE];
extern int WriteDrum(int AR, t_int64 d, int NegZero);
extern int ReadDrum(int AR, t_int64 * d, int * NegZero);
/* digits contants */
#define D10 (10000000000LL) // ten digits (10 zeroes)
#define D8 (100000000L) // eight digits (8 zeroes)
#define D4 (10000L) // four digits (4 zeroes)
/* Device information block */
struct dib {
uint8 upc; /* Units per channel */
uint32 (*cmd)(UNIT *up, uint16 cmd, uint16 dev);/* Issue command. */
void (*ini)(UNIT *up, t_bool f);
};
typedef struct dib DIB;
/* Debuging controls */
#define DEBUG_CMD 0x0000010 /* Show device commands */
#define DEBUG_DETAIL 0x0000020 /* Show details */
#define DEBUG_EXP 0x0000040 /* Show error conditions */
#define DEBUG_DATA 0x0000080 /* Show data details */
extern DEBTAB dev_debug[];
extern DEBTAB crd_debug[];
/* Returns from read/write */
#define DATA_OK 0 /* Data transfered ok */
#define TIME_ERROR 1 /* Channel did not transfer last operation */
#define END_RECORD 2 /* End of record */
/* Returns from device commands */
#define SCPE_BUSY (1) /* Device is active */
#define SCPE_NOCARDS (2) /* No cards to read or ti write */
/* Global device definitions */
#ifdef CPANEL
extern DEVICE cp_dev;
#endif
extern DIB cdr_dib;
extern DEVICE cdr_dev;
extern uint32 cdr_cmd(UNIT *, uint16, uint16);
extern UNIT cdr_unit[];
extern DIB cdp_dib;
extern DEVICE cdp_dev;
extern uint32 cdp_cmd(UNIT *, uint16, uint16);
extern UNIT cdp_unit[];
/* Device status information stored in u5 */
#define URCSTA_ERR 0002 /* Error reading record */
#define URCSTA_BUSY 0010 /* Device is busy */
#define URCSTA_LOAD 01000 /* Load flag for 533 card reader */
/* Character codes in IBM 650 as stated in p4 Andree Programming the IBM 650 Mag Drum
Also stated in www.bitsavers.org/pdf/ibm/650/28-4028_FOR_TRANSIT.pdf p37
*/
#define CHR_BLANK 00
#define CHR_DOT 18 // card code: 12-3-8 .
#define CHR_RPARENT 19 // 12-4-8 )
#define CHR_AMPERSAND 20 // 12 +
#define CHR_DOLLAR 28 // 11-3-8 $
#define CHR_STAR 29 // 11-4-8 *
#define CHR_NEG 30 // 11 - minus sign for negative value
#define CHR_SLASH 31 // 0-1 /
#define CHR_COMMA 38 // 0-3-8 ,
#define CHR_LPARENT 39 // 0-4-8 (
#define CHR_EQUAL 48 // 3-8 =
#define CHR_MINUS 49 // 4-8 -
#define CHR_A 61
#define CHR_B 62
#define CHR_C 63
#define CHR_D 64
#define CHR_E 65
#define CHR_F 66
#define CHR_G 67
#define CHR_H 68
#define CHR_I 69
#define CHR_J 71
#define CHR_K 72
#define CHR_L 73
#define CHR_M 74
#define CHR_N 75
#define CHR_O 76
#define CHR_P 77
#define CHR_Q 78
#define CHR_R 79
#define CHR_S 82
#define CHR_T 83
#define CHR_U 84
#define CHR_V 85
#define CHR_W 86
#define CHR_X 87
#define CHR_Y 88
#define CHR_Z 89
#define CHR_0 90
#define CHR_1 91
#define CHR_2 92
#define CHR_3 93
#define CHR_4 94
#define CHR_5 95
#define CHR_6 96
#define CHR_7 97
#define CHR_8 98
#define CHR_9 99
extern char digits_ascii[40];
extern char mem_to_ascii[100];
extern int ascii_to_NN(int ch);
extern uint16 ascii_to_hol[128];
/* Generic devices common to all */
extern DEVICE cpu_dev;
extern UNIT cpu_unit;
extern REG cpu_reg[];
extern int cycle_time;
/* I/O Command codes */
#define IO_RDS 1 /* Read record */
#define IO_WRS 4 /* Write one record */
extern const char *cpu_description(DEVICE *dptr);
/* Opcodes */
#define OP_AABL 17 // Add absolute to lower accumulator
#define OP_AL 15 // Add to lower accumulator
#define OP_AU 10 // Add to upper accumulator
#define OP_BRNZ 45 // Branch on accumulator non-zero
#define OP_BRMIN 46 // Branch on minus accumulator
#define OP_BRNZU 44 // Branch on non-zero in upper accumulator
#define OP_BROV 47 // Branch on overflow
#define OP_BRD1 91 // Branch on 8 in distributor positions 1-10
#define OP_BRD2 92
#define OP_BRD3 93
#define OP_BRD4 94
#define OP_BRD5 95
#define OP_BRD6 96
#define OP_BRD7 97
#define OP_BRD8 98
#define OP_BRD9 99
#define OP_BRD10 90
#define OP_DIV 14 // Divide
#define OP_DIVRU 64 // Divide and reset upper accumulator
#define OP_LD 69 // Load distributor
#define OP_MULT 19 // Multiply
#define OP_NOOP 00 // No operation
#define OP_PCH 71 // Punch a card
#define OP_RD 70 // Read a card
#define OP_RAABL 67 // Reset accumulator and add absolute to lower accumulator
#define OP_RAL 65 // Reset accumulator and add to lower accumulator
#define OP_RAU 60 // Reset accumulator and add to upper accumulator
#define OP_RSABL 68 // Reset accumulator and subtract absolute from lower accumulator
#define OP_RSL 66 // Reset accumulator and subtract from lower accumulator
#define OP_RSU 61 // Reset accumulator and subtract from upper accumulator
#define OP_SLT 35 // Shift accumulator left
#define OP_SCT 36 // Shift accumulator left and count
#define OP_SRT 30 // Shift accumulator right
#define OP_SRD 31 // Shift accumulator right and round accumulator
#define OP_STOP 01 // Stop if console switch is set to stop, otherwise continue as a NO-OP
#define OP_STD 24 // Store distributor into memory
#define OP_STDA 22 // Store lower accumulator data address into distributor, then store distributor into memory
#define OP_STIA 23 // Store lower accumulator instruction address into distributor, then store distributor into memory
#define OP_STL 20 // Store lower accumulator into memory
#define OP_STU 21 // Store upper accumulator into memory
#define OP_SABL 18 // Subtract absolute from lower accumulator
#define OP_SL 16 // Subtract from lower accumulator
#define OP_SU 11 // Subtract from upper accumulator
#define OP_TLU 84 // Table lookup
#define NEGZERO_value 0x7fffFFFFffffFFFF
#define AccNegative (((AccNegativeZeroFlag) || (ACC[1]<0) || (ACC[0]<0)) ? 1:0)
#define AbsWord(d) ((d < 0) ? -d:d)
#define printfw(d,negzero) (int32) AbsWord(d/D4), (int32) AbsWord(d%D4), ((d<0) || (negzero)) ? '-':'+'
#define printfd printfw(DIST, DistNegativeZeroFlag)
#define printfa (int32) AbsWord(ACC[1]/D4),(int32) AbsWord(ACC[1]%D4), printfw(AbsWord(ACC[0]), AccNegative)
/* Standard control panel wiring for card read/punch/print */
#define UNIT_CARD_WIRING ( 0xF00 << UNIT_V_CARD_MODE)
#define WIRING_8WORD ( 0x000 << UNIT_V_CARD_MODE)
#define WIRING_SOAP ( 0x100 << UNIT_V_CARD_MODE)
#define WIRING_IS ( 0x200 << UNIT_V_CARD_MODE)
#define UNIT_CARD_ECHO ( 0x1000 << UNIT_V_CARD_MODE)
#define UNIT_CARD_PRINT ( 0x2000 << UNIT_V_CARD_MODE)
struct card_wirings {
uint32 mode;
const char *name;
};
/* Decimal helper functions */
extern int Get_HiDigit(t_int64 d);
extern int Shift_Digits(t_int64 * d, int nDigits);
extern char * word_to_ascii(char * buf, int CharStart, int CharLen, t_int64 d);

518
I650/i650_sys.c Normal file
View file

@ -0,0 +1,518 @@
/* i650_sys.c: IBM 650 Simulator system interface.
Copyright (c) 2018, Roberto Sancho
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERTO SANCHO BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "i650_defs.h"
#include "sim_card.h"
#include <ctype.h>
/* SCP data structures and interface routines
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax number of words for examine
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
sim_load binary loader
*/
char sim_name[] = "IBM 650";
REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 1;
DEVICE *sim_devices[] = {
&cpu_dev,
&cdr_dev,
&cdp_dev,
//XXX &mta_dev,
NULL
};
/* Device addressing words */
DIB cdr_dib = { 1, &cdr_cmd, NULL };
DIB cdp_dib = { 3, &cdp_cmd, NULL };
//XXX DIB mt_dib = { CH_TYP_76XX, NUM_UNITS_MT, 0000, 0000, &mt_cmd, &mt_ini };
/* Simulator stop codes */
const char *sim_stop_messages[] = {
"Unknown error",
"HALT instruction",
"Breakpoint",
"Unknown Opcode",
"Card Read/Punch Error",
"Programmed Stop",
"Overflow",
"Opcode Execution Error",
"Address Error",
0
};
/* Simulator debug controls */
DEBTAB dev_debug[] = {
{"CMD", DEBUG_CMD},
{"DATA", DEBUG_DATA},
{"DETAIL", DEBUG_DETAIL},
{"EXP", DEBUG_EXP},
{0, 0}
};
DEBTAB crd_debug[] = {
{"CMD", DEBUG_CMD},
{"DATA", DEBUG_DATA},
{"DETAIL", DEBUG_DETAIL},
{"EXP", DEBUG_EXP},
{0, 0}
};
// code of char in IBM 650 memory
char mem_to_ascii[100] = {
/* 00 */ ' ', '~', '~', '~', '~', '~', '~', '~', '~', '~',
/* 10 */ '~', '~', '~', '~', '~', '~', '~', '~', '.', ')',
/* 20 */ '+', '~', '~', '~', '~', '~', '~', '~', '$', '*',
/* 30 */ '-', '/', '~', '~', '~', '~', '~', '~', ',', '(',
/* 40 */ '~', '~', '~', '~', '~', '~', '~', '~', '=', '-',
/* 50 */ '~', '~', '~', '~', '~', '~', '~', '~', '~', '~',
/* 60 */ '~', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
/* 70 */ '~', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
/* 80 */ '~', '~', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
/* 90 */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
};
// representation of word digit 0-9 in card including Y(12) and X(11) punchs
char digits_ascii[40] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', /* 0-9 */
'?', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', /* 0-9 w/HiPunch Y(12) */
'!', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', /* 0-9 w/Negative Punch X(11) */
'&', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '#' /* 0-9 with botch Negative Punch X(11) and HiPunch Y(12)*/
};
uint16 ascii_to_hol[128] = {
/* Control */
0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000, /*0-37*/
/*Control*/
0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,
/*Control*/
0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,
/*Control*/
0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,0xf000,
/* sp ! " # $ % & ' */
/* none Y28 78 T28 Y38 T48 XT 48 */
0x000, 0x600, 0x006, 0x282, 0x442, 0x222, 0xA00, 0x022, /* 40 - 77 */
/* ( ) * + , - . / */
/* T48 X48 Y48 X T38 T X38 T1 */
0x222, 0x822, 0x422, 0x800, 0x242, 0x400, 0x842, 0x300,
/* 0 1 2 3 4 5 6 7 */
/* T 1 2 3 4 5 6 7 */
0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004,
/* 8 9 : ; < = > ? */
/* 8 9 58 Y68 X68 38 68 X28 */
0x002, 0x001, 0x012, 0x40A, 0x80A, 0x042, 0x00A, 0x882,
/* @ A B C D E F G */
/* 82 X1 X2 X3 X4 X5 X6 X7 */
0x022, 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, /* 100 - 137 */
/* H I J K L M N O */
/* X8 X9 Y1 Y2 Y3 Y4 Y5 Y6 */
0x802, 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408,
/* P Q R S T U V W */
/* Y7 Y8 Y9 T2 T3 T4 T5 T6 */
0x404, 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208,
/* X Y Z [ \ ] ^ _ */
/* T7 T8 T9 X58 X68 T58 T78 28 */
0x204, 0x202, 0x201, 0x812, 0x20A, 0x412, 0x406, 0x082,
/* ` a b c d e f g */
0x212, 0xB00, 0xA80, 0xA40, 0xA20, 0xA10, 0xA08, 0xA04, /* 140 - 177 */
/* h i j k l m n o */
0xA02, 0xA01, 0xD00, 0xC80, 0xC40, 0xC20, 0xC10, 0xC08,
/* p q r s t u v w */
0xC04, 0xC02, 0xC01, 0x680, 0x640, 0x620, 0x610, 0x608,
/* x y z { | } ~ del */
/* Y78 X78 78 79 */
0x604, 0x602, 0x601, 0x406, 0x806,0x0006,0x0005,0xf000
};
/* Load a card image file into memory. */
t_stat
sim_load(FILE * fileref, CONST char *cptr, CONST char *fnam, int flag)
{
/* Currently not implimented until I know format of load files */
return SCPE_NOFNC;
}
/* Symbol tables */
typedef struct _opcode
{
uint16 opbase;
const char *name;
uint8 bReadData; // =1 if inst fetchs data from memory
}
t_opcode;
/* Opcodes */
t_opcode base_ops[] = {
{OP_AABL, "AABL", 1},
{OP_AL, "AL", 1},
{OP_AU, "AU", 1},
{OP_BRNZ, "BRNZ", 0},
{OP_BRMIN, "BRMIN", 0},
{OP_BRNZU, "BRNZU", 0},
{OP_BROV, "BROV", 0},
{OP_BRD1, "BRD1", 0},
{OP_BRD2, "BRD2", 0},
{OP_BRD3, "BRD3", 0},
{OP_BRD4, "BRD4", 0},
{OP_BRD5, "BRD5", 0},
{OP_BRD6, "BRD6", 0},
{OP_BRD7, "BRD7", 0},
{OP_BRD8, "BRD8", 0},
{OP_BRD9, "BRD9", 0},
{OP_BRD10, "BRD10", 0},
{OP_DIV, "DIV", 1},
{OP_DIVRU, "DIVRU", 1},
{OP_LD, "LD", 1},
{OP_MULT, "MULT", 1},
{OP_NOOP, "NOOP", 0},
{OP_PCH, "PCH", 0},
{OP_RD, "RD", 0},
{OP_RAABL, "RAABL", 1},
{OP_RAL, "RAL", 1},
{OP_RAU, "RAU", 1},
{OP_RSABL, "RSABL", 1},
{OP_RSL, "RSL", 1},
{OP_RSU, "RSU", 1},
{OP_SLT, "SLT", 0},
{OP_SCT, "SCT", 0},
{OP_SRT, "SRT", 0},
{OP_SRD, "SRD", 0},
{OP_STOP, "STOP", 0},
{OP_STD, "STD", 0},
{OP_STDA, "STDA", 0},
{OP_STIA, "STIA", 0},
{OP_STL, "STL", 0},
{OP_STU, "STU", 0},
{OP_SABL, "SABL", 1},
{OP_SL, "SL", 1},
{OP_SU, "SU", 1},
{OP_TLU, "TLU", 0},
{0, NULL, 0}
};
/* Print out an instruction */
void
print_opcode(FILE * of, t_int64 val, t_opcode * tab)
{
int sgn;
int IA;
int DA;
int op;
int n;
if (val < 0) {sgn = -1; val = -val;} else sgn = 1;
op = Shift_Digits(&val, 2); // opcode
DA = Shift_Digits(&val, 4); // data address
IA = Shift_Digits(&val, 4); // intruction address
while (tab->name != NULL) {
if (tab->opbase == op) {
fputs(tab->name, of);
n = strlen(tab->name);
while (n++<6) fputc(' ', of);
fprintf(of, "%04d ", DA);
fputc(' ', of);
fprintf(of, "%04d ", IA);
return;
}
tab++;
}
fprintf(of, " %d Unknown opcode", op);
}
/* Symbolic decode
Inputs:
*of = output stream
addr = current PC
*val = pointer to values
*uptr = pointer to unit
sw = switches
Outputs:
return = status code
*/
t_stat
fprint_sym(FILE * of, t_addr addr, t_value * val, UNIT * uptr, int32 sw)
{
t_int64 inst;
int NegZero;
int ch;
if (*val == NEGZERO_value) {
inst = 0;
NegZero = 1;
} else {
inst = *val;
NegZero = 0;
}
/* Print value in decimal */
fputc(' ', of);
fprintf(of, "%06d%04d%c", printfw(inst,NegZero)); // fprintf 10 digits word n, with sign
inst = AbsWord(inst);
if (sw & SWMASK('C') ) {
int i;
fputs(" '", of);
for (i=0;i<5;i++) {
ch = Shift_Digits(&inst, 2);
fputc(mem_to_ascii[ch], of);
}
fputc('\'', of);
}
if (sw & SWMASK('M')) {
fputs(" ", of);
inst = AbsWord(inst);
print_opcode(of, inst, base_ops);
}
return SCPE_OK;
}
t_opcode *
find_opcode(char *op, t_opcode * tab)
{
while (tab->name != NULL) {
if (*tab->name != '\0' && strcmp(op, tab->name) == 0)
return tab;
tab++;
}
return NULL;
}
/* read n digits, optionally with sign NNNN[+|-]
Inputs:
*cptr = pointer to input string
sgnFlag = 1 to allow signed value
Outputs:
d = parsed value
*/
CONST char * parse_sgn(int *neg, CONST char *cptr)
{
*neg=0;
while (isspace(*cptr)) cptr++;
if (*cptr == '+') {
cptr++;
} else if (*cptr == '-') {
cptr++; *neg = 1;
}
return cptr;
}
CONST char * parse_n(t_int64 *d, CONST char *cptr, int n)
{
int i = 0;
*d = 0;
while (1) {
if ((n == 10) && (isspace(*cptr))) {
cptr++; // on 10 digit words, allow spaces
continue;
}
if (*cptr < '0' || *cptr > '9') break;
if (i++ > n) {
cptr++;
} else {
*d = (*d * 10) + (*cptr++ - '0');
}
}
if (n == 4) {*d = *d % D4; } else
if (n == 10) {*d = *d % D10;}
return cptr;
}
/* Symbolic input
Inputs:
*cptr = pointer to input string
addr = current PC
uptr = pointer to unit
*val = pointer to output values
sw = switches
Outputs:
status = error status
*/
// convert ascii char to two digits IBM 650 code
int ascii_to_NN(int ch)
{
int i;
if ((ch >= 'a') && (ch <= 'z')) ch = ch -'a'+'A';
for (i=0;i<100;i++) if (mem_to_ascii[i] == ch) return i;
return 0;
}
t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT * uptr, t_value * val, int32 sw)
{
t_int64 d;
int da, ia;
char ch, opcode[100];
t_opcode *op;
int i;
int neg, IsNeg;
while (isspace(*cptr)) cptr++;
d = 0; IsNeg = 0;
if (sw & SWMASK('M')) {
/* Grab opcode */
cptr = parse_sgn(&neg, cptr);
if (neg) IsNeg = 1;
cptr = get_glyph(cptr, opcode, 0);
op = find_opcode(opcode, base_ops);
if (op == 0) return STOP_UUO;
while (isspace(*cptr)) cptr++;
/* Collect first argument: da */
cptr = parse_n(&d, cptr, 4);
da = (int) d;
/* Skip blanks */
while (isspace(*cptr)) cptr++;
/* Collect second argument: ia */
cptr = parse_n(&d, cptr, 4);
ia = (int) d;
// construct inst
d = op->opbase * (t_int64) D8 + da * (t_int64) D4 + (t_int64) ia;
} else if (sw & SWMASK('C')) {
d = 0;
for(i=0; i<5;i++) {
d = d * 100;
ch = *cptr;
if (ch == '\0') continue;
cptr++;
d = d + ascii_to_NN(ch);
}
} else {
cptr = parse_sgn(&neg, cptr);
if (neg) IsNeg = 1;
cptr = parse_n(&d, cptr, 10);
}
cptr = parse_sgn(&neg, cptr);
if (neg) IsNeg = 1;
if ((IsNeg) && (d == 0)) {
*val = NEGZERO_value; // val has this special value to represent -0 (minus zero == negative zero)
} else {
if (IsNeg) d=-d;
*val = (t_value) d;
}
return SCPE_OK;
}
// get data for opcode
// return pointer to opcode name if opcode found, else NULL
const char * get_opcode_data(int opcode, int * bReadData)
{
t_opcode * tab = base_ops;
*bReadData = 0;
while (tab->name != NULL) {
if (tab->opbase == opcode) {
*bReadData = tab->bReadData;
return tab->name;
}
tab++;
}
return NULL;
}
/* Helper functions */
// set in buf string ascii chars form word d ( chars: c1c2c3c4c5 )
// starts at char start (1..5), for CharLen chars (0..5)
// to convert the full word use (buf, 1, 5, d)
char * word_to_ascii(char * buf, int CharStart, int CharLen, t_int64 d)
{
int i,c1,c2;
char * buf0;
buf0 = buf; // save start of buffer
for (i=0;i<5;i++) { // 5 alpha chars per word
c1 = Shift_Digits(&d, 2);
c2 = mem_to_ascii[c1];
if (i < CharStart-1) continue;
if (i >= CharStart+CharLen-1) continue;
*buf++ = c2;
}
*buf++ = 0;
return buf0;
}
// return hi digit (digit 10) al leftmost position in number (no sign)
int Get_HiDigit(t_int64 d)
{
return (int) ((AbsWord(d) * 10) / D10);
}
// shift d value for nDigits positions (max 7)
// if nDigit > 0 shift left, if < 0 then shift right
// return value of shifted digits (without sign)
int Shift_Digits(t_int64 * d, int nDigits)
{
int i,n;
int neg = 0;
if (nDigits == 0) return 0; // no shift
if (*d < 0) {*d=-*d; neg = 1;}
n = 0;
if (nDigits > 0) { // shift left
for (i=0;i<nDigits;i++) {
n = n * 10 + (int) (*d / (1000000000L)); // nine digits (9 zeroes)
*d = (*d % (1000000000L)) * 10;
}
} else { // shift right
for (i=0;i<-nDigits;i++) {
n = *d % 10;
*d = *d / 10;
}
}
if (neg) *d=-*d;
return n;
}

View file

@ -0,0 +1,101 @@
; set console -n log=log.txt
; set debug -n debug.txt
; set debug stdout
; set cpu debug=cmd;data;detail
; params: %1 %2 ... (case insensitive)
; possible values:
; Tr build include trace deck (deck number 10)
; Set_LoopBox build include set loopbox instruction deck (deck number 21)
; Load SOAP deck into core (1 word per card format), but does not execute it
set cpu 2k
att cdr1 -q soapII.dck
echo ***
echo *** load soap deck into drum
echo ***
d csw 7019519999
d ar 8000
go
; now put interpretive system loader source cards in reader and start SOAP assembler
att cdr1 is_sys_load_src.txt
set cdr1 wiring=soap
att cdp1 -n -q deck_out.dck
set cdp1 echo, print, wiring=soap
att cdp0 -n -q print.txt
echo ***
echo *** Assemble interpretive system loader
echo ***
d ar 1000
go
echo ***
echo *** load interpretive system loader into core
echo ***
det cdp1
att cdr1 deck_out.dck
d csw 7019519999
d ar 8000
go
; create is deck with main system and optional user selected extra decks
! copy is_main_src.txt deck_in.dck > nul
:add_extra_decks
if "%1" == "" goto run
set env deck="void"
if -i "%1" == "TR" set env deck="is_trace_src.txt"
if -i "%1" == "LBOX" set env deck="is_set_loopbox.txt"
if %deck == "void" goto next_extra
! copy deck_in.dck a.dck > nul
! copy a.dck + %deck deck_in.dck > nul
! del a.dck > nul
:next_extra
shift
goto add_extra_decks
:run
att cdr1 deck_in.dck
set cdr1 wiring=is
; execute the loader to create Interpretive system deck
echo ***
echo *** run system loader
echo ***
d ar 0880
go
; generate a 1-word load card deck with whole interpretive system, ready to run
echo ***
echo *** run is system generation to create
echo interpretive system (is) 1-word per card load deck
echo ***
att cdp1 -n -q is.dck
set cdp1 echo, print, wiring=is
d ar 0801
go
:end

View file

@ -0,0 +1,28 @@
; set console -n log=log.txt
; set debug -n debug.txt
; set debug stdout
; set cpu debug=cmd;data;detail
set cpu 2k
set cdr1 wiring=soap
; prepare deck: SOAP (condensed deck as 7 word per card format) then SOAP source code to assemblre
! copy soapII_condensed_card.dck + soap_src.txt deck_in.dck > nul
att cdr1 deck_in.dck
att cdp1 -n -q deck_out.dck
set cdp1 echo, print, wiring=soap
att cdp0 -n -q print.txt
; load soap deck (condensed soap deck autostarts)
d csw 7019511951
d ar 8000
go
:end

1100
I650/sw/is.dck Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,68 @@
prime number generator using the sieve of eratosthenes
converted to ibm 650 floating poing interpretive system (is)
uses two extra o2 codes: o2=800 (set lbox) and o2=453 (tr zero)
warning: comments are allowed past column 28 but some characters
are forbidden: uppercase letters, question mark, exclamation, number char,
ampersand char. if these chars are used, the line (i.e. the card for this
line) will be interpreted as a load card, and program will crash on trying
to execute it.
100 -9 000 201 400 initp -move i1 prime initp: prime[c]=1
101 +0 001 050 100 loop c 050 initp c++; if c<50 goto initp
102 +9 000 201 300 move i1 num num=1
103 +1 300 201 300 loop1 add num i1 num loop1: num++
104 +2 300 203 000 sub num i50 last
105 +0 201 120 106 tr sgn loope cont if num >= 50 goto loope
106 +0 800 002 300 set lbox b num b=num
107 -9 000 400 000 -move prime last last=prime[b]
108 +0 453 103 110 tr zero loop1 cont if last = 0 goto loop1
110 +9 000 300 301 move num mult mult=num
111 +1 300 301 301 loop2 add num mult mult loop2: mult=mult+num
112 +2 301 203 000 sub mult i50 last
113 +0 201 103 114 tr sgn loop1 cont if mult >= 50 goto loop1 (go to b if +, go to c if -)
114 +0 800 003 301 set lbox c mult c=mult
115 -9 000 200 400 -move zero prime prime[c]=0
116 +0 203 000 111 tr loop2 goto loop2
120 +9 000 201 300 loope move i1 num loope: num=1
121 +0 800 002 202 set lbox b i2 b=2
122 +1 300 201 300 prt1 add num i1 num prt1: num++
123 -9 000 400 000 -move prime last last=prime[b]
124 +0 453 127 126 tr zero prt2 cont if last = 0 goto prt2
126 +0 410 300 300 pch num num punch num
127 +0 010 050 122 prt2 loop b 050 prt1 prt2: b++; if b<50 goto prt1
128 +0 000 000 000 unc stop end
constants
200 +0 0000000 50 zero
201 +1 0000000 50 i1
202 +2 0000000 50 i2
203 +5 0000000 51 i50
variables
300 +0 0000000 50 num current number to check for being prime
301 +0 0000000 50 mult multiple
400 +0 0000000 50 prime array of numbers 400-449
100 program start address

1145
I650/sw/is_main_src.txt Normal file

File diff suppressed because it is too large Load diff

48
I650/sw/is_run.ini Normal file
View file

@ -0,0 +1,48 @@
; set console -n log=log.txt
; set debug -n debug.txt
; set debug stdout
; set cpu debug=cmd;data;detail
; params: %1 source card deck to run with Floating Point Interpretive System (IS)
; %2 input card deck (if empty, do not attach input card
; Load IS deck into (1 word per card format), but does not execute it
set cpu 2k
echo ***
echo *** load is deck into drum
echo ***
att cdr1 -q is.dck
d csw 7019519999
d ar 8000
go
; now put IS program cards in reader and load them
! copy %1 deck_in.dck > nul
if "%2" == "" goto run
! copy %1 + %2 deck_in.dck > nul
:run
att cdr1 deck_in.dck
set cdr1 wiring=is
att cdp1 -n -q deck_out_run.dck
set cdp1 echo, print, wiring=is
att cdp0 -n -q print.txt
echo ***
echo *** load and run IS program
echo ***
d csw 7019511333
d ar 8000
go
:end

View file

@ -0,0 +1,77 @@
deck 21. extra instr for general computing
set loopbox O2=800
tr zero O2=453
21 1 1800 00 0000 0970 set loopbox: 0 800 00r nnn
if r=0 resets loopbox (= 000 000 000)
if r=1 sets loopbox for a-param, with value 0-999 from float
contents of register nnn. clears loobox value
for b and c. if float value at register is outside
range 0-999 program stops at 2222
if r=2 sets loobox for b
if r=3 sets loobox for c
21 2 0998 00 1000 0000 param1m (const to decrement param)
21 3 0997 35 0006 0987 bxa slt 0006 svlb
21 4 0996 35 0003 0987 bxb slt 0003 svlb
21 5 0995 00 0000 0987 bxc nop svlb
21 6 0994 60 0000 0950 fldc rau 0000 setb1
21 7 0993 00 0000 0000 shbx
21 8 0992 00 0000 0000 svfc
21 9 0991 01 0000 0000 hi01
21 10 0990 50 0000 0000 hi50
21 11 0970 65 1045 0971 ral paramb is nnn0000000
21 12 0971 45 0972 0987 brnz (cont) svlb
21 13 0972 16 0998 0973 sl param1m
21 14 0973 45 0975 0977 brnz (cont) seta
21 15 0975 16 0998 0976 sl param1m
21 16 0976 45 0979 0978 brnz setc setb
21 17 0977 69 0997 0980 seta ld bxa setbx
21 18 0978 69 0996 0980 setb ld bxb setbx
21 19 0979 69 0995 0980 setc ld bxc setbx
21 20 0980 24 0993 0981 setbx std shbx
21 21 0981 65 1023 0982 ral paramc lower acc is nnn0000000
21 22 0982 30 0003 0983 srt 3 00 0nnn 000
21 23 0983 15 0994 8002 al fldc 8002
8002 rau [c] setb1 read float value at [c] as nnnxxxxxee
21 24 0984 35 0003 0985 setb2 slt 3 upper acc is 000000nnn
21 25 0985 16 8002 0986 setb3 sl 8002 clear lower acc
21 26 0986 69 0993 8001 ld shbx 8001
8001 slt [0,3,6] upper acc is 000 000 nnn, 000 nnn 000, or nnn 000 000
21 27 0987 21 1017 1095 svlb stu lbox 1095 save loopbox
21 28 0950 21 0992 0951 setb1 stu svfc save [c] float value
21 29 0951 44 0952 0987 brnzu svlb if [c] is zero go to save loopbox
21 30 0952 46 1315 0953 brmin 1315 if [c] is <0 go to 2222 stop
21 31 0953 35 0008 0954 slt 8 upper acc is ee00000000
21 32 0954 11 0990 0955 su hi50
21 33 0955 44 0956 0962 brnzu i00n jump if [c] is in range 0-9
21 34 0956 11 0991 0957 su hi01
21 35 0957 44 0958 0961 brnzu i0nn jump if [c] is in range 10-99
21 36 0958 11 0991 0959 su hi01
21 37 0959 44 1315 0960 brnzu 1315 innn jump if [c] is in range 100-999, else go to 2222 stop
21 38 0960 69 0969 0963 innn ld stnnn ixxx
21 39 0961 69 0968 0963 i0nn ld stn0n ixxx
21 40 0962 69 0967 0963 i00n ld st00n ixxx
21 41 0963 24 0984 0964 ixxx std setb2
21 42 0964 65 0992 0984 ral svfc setb2
21 43 1453 60 1009 0965 rau last get last result
tr zero: 0 453 bbb ccc
goto b if last result is zero
goto c if last result is non zero
21 44 0965 30 0002 0966 srt 2
21 45 0966 44 1120 0974 brnzu gotoc gotob
21 46 0974 60 1045 1027 gotob rau paramb goto
21 47 0967 35 0001 0985 st00n slt 1 setb3
21 48 0968 35 0002 0985 st0nn slt 2 setb3
21 49 0969 35 0003 0985 stnnn slt 3 setb3
21 50 0988 00 0000 0000 vacant location
21 51 0989 00 0000 0000 vacant location

View file

@ -0,0 +1,97 @@
1
1 interpretive system (is) loader
1 creates a 1-word load cards
1 deck by reading cards as
1 writen in manual
1
1 this program is manually
1 assembled (just using soap to
1 load it) as is (1956) predates
1 soap (1957)
1
0880 70 1951 0881 rdcrd rd loc read card
0881 60 1951 0892 rau loc lbl1 prepare accumulator for move
0882 10 0870 0883 lbl2 au stw
0883 15 0871 0884 al ldw
0884 10 1952 0885 au wc
0885 21 0874 0886 stu nwc
0886 11 1952 8002 su wc
8002 69 1953 8003 ld w move one word form card read area
8003 24 0000 0887 std
0887 15 0872 0888 nxt al iaddr increase address by 1
0888 10 8001 0889 au 8001
0889 11 0874 0890 su nwc test for end of moving
0890 44 0891 0880 brnzu lbl3 rdcrd
0891 10 0874 8002 lbl3 au nwc nxt return to move another word
0892 44 0893 0880 lbl1 brnzu rdcrd if loc is zero read next card
0893 11 0873 0894 su i2000
0894 46 0895 0880 brmin rdcrd if loc >= 2000 read next card
0895 10 0873 0882 au i2000 lbl2
1
1 constants
1
0870 24 0000 0887 stw std 0000 nxt store word
0871 69 1953 8003 ldw ld w load word from card read
0872 00 0001 0000 iaddr
0873 00 2000 0000 i2000
0874 00 0000 0000 nwc temp variable
1
1 card read area
1
1 1951 00 1002 0000 loc location
1 1952 00 0002 0000 wc word count
1 1953 00 3333 4444 W word1
1 1954 00 5555 6666 word2
1 1955 00 0000 0000 word3
1 1956 00 0000 0000 word4
1 1957 00 0000 0007 word5
1 1958 00 0000 0008 word6
1
1
1 generate system
1 punch the whole is system on a 1
1 word per card format
1 from 0900 to 1999
1
0801 65 0852 0802 lblw ral loc1 prepare accumulator for move
0802 10 0850 0803 au stw2
0803 15 0851 8002 al ldw2
8002 69 0000 8003 ld move one word to card punch area
8003 24 0000 0804 std ww
0804 65 0852 0805 p1w ral loc1 set word loc in card punch area
0805 15 0854 0806 al wloc0
0806 20 1979 0807 stl wloc
0807 10 1978 0808 au cnum set card number in card punch area
0808 10 0855 0809 au icard
0809 21 1978 0810 stu cnum
0810 71 1977 0811 pch1w pch 1977 punch 1w card
0811 65 0852 0812 ral loc1
0812 16 0853 0813 sl loc2
0813 46 0814 9999 brmin 9999 if loc1 >= loc2 terminate
0814 15 0853 0815 al loc2
0815 15 0872 0816 al iaddr increment loc1
0816 20 0852 0801 stl loc1 lblw go punch next word
1
1 constants
1
0850 24 1980 0804 stw2 std wdata p1w store word for punch
0851 69 0000 8003 ldw2 ld 0000 load word
0852 00 0900 0000 loc1 first location to punch
0853 00 1999 0000 loc2 last location to punch
0854 24 0000 8000 wloc0 word location on 1e load card format
0855 00 0000 0001 icard just one
1
1 card punch area (1 word per card load card)
1 make first word negative so is control panel
1 punchs a load card with y(12) hi punch set
1
- 1977 69 1954 1953
1978 00 0000 0000 cnum card number
1979 24 0000 8000 wloc word location
1980 00 0000 0000 wdata word data in load card
1981 00 0000 0000
1982 00 0000 0000
1983 00 0000 0000
1984 00 0000 0000
1985 00 0000 0000
1986 00 0000 0000

59
I650/sw/is_trace_src.txt Normal file
View file

@ -0,0 +1,59 @@
10 1 1061 21 1980 1386
10 2 1386 30 0003 1946
10 3 1946 20 1023 1947
10 4 1947 60 8003 1948
10 5 1948 30 0003 1949
10 6 1949 20 1045 1950
10 7 1950 60 8003 1961
10 8 1961 24 1260 1962
10 9 1962 30 0003 1963
10 10 1963 44 1965 1968
10 11 1965 65 8002 1966
10 12 1966 30 0003 1967
10 13 1967 15 1998 8002
10 14 8002 60 1968
10 15 1968 21 1982 1969
10 16 1969 65 1045 1970
10 17 1970 30 0003 1971
10 18 1971 15 1999 8002
10 19 8002 69 1972
10 20 1972 24 1983 1973
10 21 1973 69 1974
10 22 1974 24 1984 1975
10 23 1975 69 1017 1987
10 24 1987 24 1981 1988
10 25 1988 65 1098 1989
10 26 1989 24 1977 1990
10 27 1990 15 1997 8002
10 28 8002 69
10 29 1991 24 1979 1992
10 30 1992 65 1986 1993
10 31 1993 15 1024 1994
10 32 1994 20 1986 1995
10 33 1995 71 1977 1996
10 34 1996 60 1260 1105
10 35 1450 69 1976 1331
10 36 1331 24 1061 1095
10 37 1451 69 1154 1358
10 38 1358 24 1061 1095
10 39 1452 69 1976 1332
10 40 1332 24 1061 1091
10 41 1091 65 1098 1165
10 42 1165 16 1173 1334
10 43 1334 69 1141 8002
10 44 8002 24 1095
10 45 1997 09 0884
10 46 1998 60 1968
10 47 1999 69 1972
10 48 1141 04 5400
10 49 1173 36 0012
10 50 1154 30 0003 1019
10 51 1978 00 0006 0008
10 52 1964 00 1095
10 53 1976 21 1980 1386
10 54 1024 00 0001
10 55 1958 44 1965 1968

1400
I650/sw/soapII.dck Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,173 @@
6I195219536919521951241995195469195519566919541953241996195769195880006919561955
2D19971952691953195469195819572419981955691957195624199919997019950000
2D000019967000489999240048199765000100302400301998690034003924003919992200440047
2D004719963500040025240025199715800100312400311998220036003224003219996500350040
2D004019961000448002240020199710002300272400271998158001003324003319991100360041
2D004119964400450000240045199710800180022400341998240000002024003519996900028003
2D002300000000010000
0?080000070004040998000404099833232209990005050998000505099800050509980005050998
0?080700070005050998331212099933020209993305040999330504099999999999999999999999
0?081400073311100999330504099933050409993305040999330504099933212009995403030999
0?082100074503030999340303099934030309993303030999440505099800050509980005050998
0?082800073312120999330202099900000009880000000888332726099933272609993300000999
0?083500070000000988000000098833272609993327260999330000099933040409983304040998
0?084200073304040998330404099834040509984305040998330404099833050509983304040998
0?084900073304040998000000089800000008980000000898000000089844050509980005050998
0?085600070005050998000505099800000008980000000898330504099933050409999999999999
0?086300079999999999331110099933050409993305040999330504099933050409993303030999
0?087000070000000999000000099900000009990000000999000000099900000009990000000999
0?087700070000000999000000099900050509990000000898000000089800000008980000000898
0?088400073305060999000606099800060609980006060998000000089800000008984405050998
0?089100073305050998330505099833050509983305050998330505099833050509983305050998
0?089800073305050998440505099865165313080100000901651958126330000812210000000943
0?090500076519591313300008117500000009576519511455000000101315151912731515191273
0?091200076519861191691016096900000080032015191322651986119165195909156913711174
0?091900076913721275651223091565198611916519861191201872162860158518396519570931
0?092600076917801174691830127565122309316516821801601585183969178417506015851839
0?093300072018721927101688174369173814426015851839201492095260154213982017931696
0?094000076015421398651958094469164511746916461275691448175060154213986512230944
0?094700076518821801601542139869182818263500041878691928182635000419302014920968
0?095400076519861742651959096069183511746918851275691983154065198617426919351750
0?096100076519861742651223096065149018016519861742691736182669198317866918361826
0?096800076919831886241196189960151913232119840987241196194965195713110000001500
0?097500070100000975691262136546118011830000001504211961121469195213556919531356
0?098200076919541357691955120869195612096519850989151189124310099009956019601015
0?098900071509920997000000199015198618910000000001000000091324060012472019868003
0?099600072411961349201985098860196117656019521407691950135369140413536519591363
0?100300076914061309651952150769140613596912161359691460096960151114056519521757
0?101000076519521807691406140960097512296519861441000000200030000209716910190972
0?101700042419791350151771142569135014530000010000
0?105000076173661007617376001561747300176184770010618761005061876200526187630058
0?105700076264760090626491009162649200926264930093626494009462649500956264960096
0?106400076264970097626498009862649900996269750026627361100362737910026274610041
0?107100076274620043627463004962746900466276771001627685004762828300576469850014
0?107800076485790064657884100566616400326661740037666485003466747700396682620033
0?108500076682740038686564100968738300017364640069736469000973696200087477880019
0?109200077565660054757677000075838200257589610040758962004275896300481616011756
0?109900076019531457758965004575898400447761831008776368007179616100807961620082
0?110600077961630088796173006579617400677961840060796279101279636400707963910072
0?111300077963920075796393007879648200867964910070796492007379649300767965671004
0?112000077965731010796578101179778800797982610081798262008379826300897982730066
0?112700077982740068798284006179836100057983630003798375000479866400558263830036
0?113400078264610022826482008582658300278269610023826962002882737600168273830035
0?114100078274730018827964003182798300308283640024828369002982837300208283840021
0?114800073500041809101352800382847700118287610051828762005382876300598288751006
0?115500078373840084846661000286648200878679910071867992007486799300778683610007
0?116200078683740056868375000699999900016019571261601957136115102080031610201525
0?116900074611720973221217122069198411871080010979651957141124141616701009788003
0?117600070100001176350006149100000000904611821183158001131122196215151010140979
0?118300076012370991601401175565800212936519531707221984123730000914010000000029
0?119000076913501553151500150516134514492411960999000000000800000009080100001196
0?119700073500041557350006196621196113640019990000007999000300800300010080040003
0?120400070080070001008999000300905900029999990003241981098424198209850000000902
0?121100074411651166011212800!24141619196914501503651959146390000000002099981402
0?121800076919711224461222117335000411811009748003100975117901000012232416641971
0?122500071611781233221962800145128013316519531857151959136301000012300100001231
0?123200073500041493460986100260140118051611881343300004139769119011936580021547
0?123900071516061711600600157915099411495505050999461002119735000419113500011451
0?124600070100001246111550165520196116683000101401002322252410070607062007060908
0?125300073009081110401110131250131215146015141716701716191880191821209021202322
0?126000070000000905111014116901000012621610141319010000126410195816131017191423
0?126700074414711196161020177516127209771615731227691400150300000090606909761279
0?127400073500041947241416132020143114841417711332101601141624141615201515331487
0?128100071012841239678001148915800212410100001284141288114810133913931180011245
0?128800070000020000691242139960060115792212311334690600800310124613512215751328
0?129500073500031803151249170369150615596080011813201653155619990606007999070700
0?130200078000080800800106060080020908008003080900905908080099990909004513621813
0?130900072412121215211021100235000411716919608002161014141982766177926019531607
0?131600076917691472651231123569121618704615641563211601165469140016036019521657
0?13230007691400150300000004502013291400651575153414138013906580011285011329800!
0?133000073000011587691434153760800316894414371416101337142315133880031511891443
0?133700072006000900000500050010000000001580031897300002134769080080034512961297
0?134400070008000000909000000035000117532019611414608001181865195416597119771950
0?135100073000011907691952800224181318682419770980241978098124197909822419800983
0?135800072007960900241262131500000009171110141219161565166916195814136912171170
0?136500079014000970691565147235000214732419861739151958094465161414200000890915
0?137200070000000920151264161944137715281580021283151958156210143013354414811282
0?137900071010208003000000005024153416372019771702471286128635000113911513888002
0?138600076517891643441341119200000100004416731244658003141644129513462119861927
0?139300074713960998600799157945109815493500021853151650800210198615922414521196
0?140000076019501405010000140111196212672411961849601950140515198616418000000000
0?140700076912101213000196000024126214156917131275151264126915186514871080011271
0?1414000716800116716519591763011416800!1611781433651324182946156815671614671921
0?142100071519618003150975161921140116042419781752211230171519167915521014801385
0?142800071519591562350001118520198517020100001431691485160046133609986516141800
0?143500074514381196221983148621196216651513421248698003149669184319641511941499
0?144200072418721839460998144765168716919016491701690400138965099214970000000949
0?14490007350002190565196113112116061609011452800!241196183320123111843500021211
0?145600076014011705691260121330000014011013121167691952155569131410176904001378
0?146300071619581513300008133335000413756517251820650000139520198317021519590960
0?147000076912781381108001137924124612991080031281441427157816800214838413001912
0?147700071615301435961531163321128412872419861752678001143944153513868412001656
0?148400071680011591651538159330000414982016148001241329143230000414390000890958
0?149100073000061706011492800!15144616513000001722201915126823122313261019611715
0?149800071018811902201986128900880000001619611615151906161224181313166914581661
0?150500072019861350350000152130000812250001950000220901145465195815616919501403
0?151200076509601445108001132135000414756012171421118003187310010010016014241879
0?151900070100001519691623122621117614293500061387101178138300149914992019031487
0?152600072118131576010111121820196215184410131384690799800369163417873500021680
0?153300076504001395010000153465158816432219831586241610171400060007996580031697
0?154000072319831590118001159900000008004412981348219999182530000417101111111111
0?154700073500031806691782196465141618716919588002150992800215800317602411961099
0?155400076911881291241983118616800119131513101265450000000124090115046519591611
0?156100072009751228160992174765126413696509751369000000000165195809446512641469
0?156800076509751469461422137365195909603000031479151771800265039913953500081543
0?157500070100001575201962162600102110497119771477441583158424166417241580011639
0?158200073000011730360000166060168716910000008000300004154835000415970000008002
0?158900077119778003101230164015196114312119861196101546180200000080002419611418
0?15960007011596800!1518501856011598800!2019611814241196119901000016016580011810
0?16030007241813136610155880033000041465011606800!691360121365000015011180011367
0?161000070100001610201264140020168780011012168002010000161435000615290000000004
0?161700072399841416241984175215101409152216731276151506176115099280022199871541
0?162400070000000599141771123269196119642419611526101230163515168718416519611813
0?163100071014061774691212187765800317410000001851151575188022198316866980031294
0?16380007221984119630000319471515751690151344169969198315361619621726011644800!
0?16450007000088094400000009462014161370011648800!651416162269080013996917041808
0?165200070000800000010000165369175818614414591950151709800269141016636519621417
0?165900073000041819350001171724123112341519151612241813176801011112186080021523
0?166600076519831887300001172365196217182016531456300008153984105018551580021741
0?167300070100001673691527158015195715621417711482951680153244183117320000000500
0?168000073000091727651961177600009009231080011791691813177700008809373000041728
0?168700070100001687000008000015196118166919361279161394174900008909536918131677
0?16940007011694800!000000008010123017353500041858011698800!20198615891000000000
0?170100073500011908111468137469150615092299851416111358186310141618214513501461
0?170800074514121664600000117714161614263500041621241584173700000009106514671487
0?171500071514161721931772182230000118231615241829200800090096177316751680028001
0?172200076080031629691416172065157716310100001725451630168119101416846914521778
0?172900076580021972151961181369173412136516851801161240154500000009251515751932
0?1736000700008909686512401612011738800!6912921595201738193669144417971516951934
0?174300076915961442011744800!2418721196011746800!4616491416011748800!4515021754
0?175000072414161969161804185911161814742019831236691909171211140814234516101811
0?175700073000081325651614127000000000041180011767200901155415800216721610141569
0?176400071915171238691018166365187212771019621817698003157400000000002017251478
0?177100070000000002651983193795137614286918131600201804161215099218139617301582
0?177800079111961783691452186200009009316518721927000008183220187211960000000933
0?1785000765179309522319831889221961196469179212130000008003011790800!1514948002
0?1792000700000009550100001793011794800!011795800!011796800!2415841837011798800!
0?179900072019868003161903170869121219656919181600151196155101000018041115081423
0?180600071917591330451510156122191118641514628002011810800!65161414701518668002
0?181300070100001813300004162511800380014419221972191920134010132918134515221013
0?182000071509928002151961181535000219472019621516011824800!11800117332418131876
0?182700074417311632000088093710138280010000000928691834121320173817286019531883
0?18340007000000094100008909600000991939151290149560195219331019861392011840800!
0?18410007691544184720159619360000091740011844800!011845800!011846800!2219018001
0?18480007011848800!691652136865000113953500041762961824187444128616586919741627
0?185500071516088002201865116845156016111515128002451662191435000118672416101764
0?18620007931916194746126613176916171620011865800!650000197316800219256516241929
0?18690007158001175324121214661509921647011872800!3500041683011874800!6514521910
0?187600072019611926901781092469198314361519618002691781127920159617280000880939
0?188300074417881838901988095900000009622319831936300004199765169218011018421854
0?18900007011890800!1515941799011892800!011893800!011894800!011895800!011896800!
0?189700071180011725011898800!60195118276919501403011901800!69192416270100001903
0?190400072019611676168002196360080015791011761231658002166765168717519216661716
0?191100070100001911151967800210800315710102221318010000191535000419471680021975
0?191800076914061968211961146400000000502015751278350002172965145218600000081904
0?192500073500011581601954197635000419870000981931211985148869198316363500041642
0?193200076917851279441888193820198611960000000965691492174530000411986912121884
0?193900076919831989011940800!1518721327011942800!011943800!011944800!011945800!
0?19460005011946800!2019611766011948800!60195216787019991998
0?196300073000011869241416197090177018201680021476650000127424121216742019611514
0?197000079519231875651416157230000819413500021779000009190484125018123500071693
0?19870007691984163865149209682319831440690993099660195014056911950996011993800!
0?19940006011994800!011995800!011996800!350009191769195113546519511605
0?000000010000001000

78
I650/sw/soap_and_run.ini Normal file
View file

@ -0,0 +1,78 @@
; set console -n log=log.txt
; set debug -n debug.txt
; set debug stdout
; set cpu debug=cmd;data;detail
; params: %1 source card deck to assemble with soap
; %2 start address to run program (If empty, program not run)
; %3 input card deck (if empty, do not attach input card
set cpu 2k
; Load SOAP deck into core (1 word per card format), but does not execute it
att cdr1 -q soapII.dck
echo ***
echo *** load soap deck into drum
echo ***
d csw 7019519999
d ar 8000
go
; now put source cards in reader and start SOAP assembler
att cdr1 %1
set cdr1 wiring=soap
att cdp1 -n -q deck_out.dck
set cdp1 echo, print, wiring=soap
att cdp0 -n -q print.txt
echo ***
echo *** run soap
echo ***
d ar 1000
go
if "%2" == "" goto end
; load assembled deck into core
det cdp1
set cdr1 wiring=8WORD
att cdr1 deck_out.dck
att cdp1 -n -q deck_out_run.dck
set cdp1 echo, print, wiring=8WORD
echo ***
echo *** load assembled program
echo ***
d csw 7019519999
d ar 8000
go
; attach input deck
if "%3" == "" goto run
att cdr1 %3
; now execute the loaded deck
:run
echo ***
echo *** run assembled program
echo ***
d ar %2
go
:end

View file

@ -0,0 +1,39 @@
1
1 example 1 calculate f of x
1
1 f(x) = a*x*x+b*x+c
1
1 card output
1 word1 word2
1 x f(x)
1
blr 1951 1960 read area
regp0027 0028 punch area
1
synstart 1000 prgm start
1
startnop 0000 setx
setx rauone stx set x
stx stup0001 to 1
mpya calculate
alob f
rau 8002
mpyp0001
aloc
stlp0002
pchp0001 punch
raup0001 is x max
supxmax
nzu 9999
aupi01 stx step x
1
one 00 0000 0001 constants
xmax 00 0000 0100
i01 00 0000 0101
1
a 00 0000 0002 params
b 00 0000 0003 for f(x)
c 00 0000 0004
1
-neg 00 0000 0006
-negz 00 0000 0000

1449
I650/sw/soap_listing.txt Normal file

File diff suppressed because it is too large Load diff

1399
I650/sw/soap_src.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -83,6 +83,8 @@
#### Hans-Åke Lund has implemented an SCELBI (SCientic-ELectronics-BIology) simulator.
#### Roberto Sancho has implemented an IBM 650 simulator.
### New Host Platform support - HP-UX and AIX
### Simulator Front Panel API

View file

@ -0,0 +1,335 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="I650"
ProjectGUID="{95B64699-4B93-4BFE-9024-0A2302D9B71A}"
RootNamespace="I650"
Keyword="Win32Proj"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="./;../;../I650/;&quot;../../windows-build/PCRE/include/&quot;"
PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;USE_SIM_CARD;USE_INT64"
KeepComments="false"
MinimalRebuild="true"
BasicRuntimeChecks="0"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wsock32.lib winmm.lib pcrestaticd.lib pcreposixstaticd.lib"
LinkIncremental="2"
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
GenerateDebugInformation="true"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd LIBPCRE"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="./;../;../I650/;&quot;../../windows-build/PCRE/include/&quot;"
PreprocessorDefinitions="_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;SIM_NEED_GIT_COMMIT_ID;HAVE_PCREPOSIX_H;PCRE_STATIC;USE_SIM_CARD;USE_INT64"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
CompileAs="1"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="wsock32.lib winmm.lib pcrestatic.lib pcreposixstatic.lib"
LinkIncremental="1"
AdditionalLibraryDirectories="../../windows-build/PCRE/lib/"
GenerateDebugInformation="false"
SubSystem="1"
StackReserveSize="10485760"
StackCommitSize="10485760"
OptimizeReferences="2"
EnableCOMDATFolding="2"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="..\I650\i650_cdp.c"
>
</File>
<File
RelativePath="..\I650\i650_cdr.c"
>
</File>
<File
RelativePath="..\I650\i650_cpu.c"
>
</File>
<File
RelativePath="..\I650\i650_sys.c"
>
</File>
<File
RelativePath="..\scp.c"
>
</File>
<File
RelativePath="..\sim_card.c"
>
</File>
<File
RelativePath="..\sim_card.h"
>
</File>
<File
RelativePath="..\sim_console.c"
>
</File>
<File
RelativePath="..\sim_disk.c"
>
</File>
<File
RelativePath="..\sim_ether.c"
>
</File>
<File
RelativePath="..\sim_fio.c"
>
</File>
<File
RelativePath="..\sim_serial.c"
>
</File>
<File
RelativePath="..\sim_sock.c"
>
</File>
<File
RelativePath="..\sim_tape.c"
>
</File>
<File
RelativePath="..\sim_timer.c"
>
</File>
<File
RelativePath="..\sim_tmxr.c"
>
</File>
<File
RelativePath="..\sim_video.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc"
>
<File
RelativePath="..\I650\i650_defs.h"
>
</File>
<File
RelativePath="..\scp.h"
>
</File>
<File
RelativePath="..\sim_console.h"
>
</File>
<File
RelativePath="..\sim_defs.h"
>
</File>
<File
RelativePath="..\sim_disk.h"
>
</File>
<File
RelativePath="..\sim_ether.h"
>
</File>
<File
RelativePath="..\sim_fio.h"
>
</File>
<File
RelativePath="..\sim_rev.h"
>
</File>
<File
RelativePath="..\sim_serial.h"
>
</File>
<File
RelativePath="..\sim_sock.h"
>
</File>
<File
RelativePath="..\sim_tape.h"
>
</File>
<File
RelativePath="..\sim_timer.h"
>
</File>
<File
RelativePath="..\sim_tmxr.h"
>
</File>
<File
RelativePath="..\sim_video.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -244,10 +244,19 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "isys8024", "isys8024.vcproj
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imds-225", "imds-225.vcproj", "{A66F0D85-174F-4AFE-A44E-7FAE3D3727BC}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ibmpc", "ibmpc.vcproj", "{76EF8599-7AB0-4C8D-997B-AAEEE724A5D0}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ibmpcxt", "ibmpcxt.vcproj", "{0026A4C2-655A-4C03-B6CA-B1EAF79FA4D1}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scelbi", "scelbi.vcproj", "{1E92CC4B-9ED5-4CD4-BD35-061F25126523}"
ProjectSection(ProjectDependencies) = postProject
@ -286,6 +295,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "I7010", "I7010.vcproj", "{5
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "I650", "I650.vcproj", "{95B64699-4B93-4BFE-9024-0A2302D9B71A}"
ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -532,6 +546,10 @@ Global
{55A727F0-B5C8-48E8-9EF2-D5DAF679C520}.Debug|Win32.Build.0 = Debug|Win32
{55A727F0-B5C8-48E8-9EF2-D5DAF679C520}.Release|Win32.ActiveCfg = Release|Win32
{55A727F0-B5C8-48E8-9EF2-D5DAF679C520}.Release|Win32.Build.0 = Release|Win32
{95B64699-4B93-4BFE-9024-0A2302D9B71A}.Debug|Win32.ActiveCfg = Debug|Win32
{95B64699-4B93-4BFE-9024-0A2302D9B71A}.Debug|Win32.Build.0 = Debug|Win32
{95B64699-4B93-4BFE-9024-0A2302D9B71A}.Release|Win32.ActiveCfg = Release|Win32
{95B64699-4B93-4BFE-9024-0A2302D9B71A}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

BIN
doc/i650_doc.doc Normal file

Binary file not shown.

View file

@ -1388,6 +1388,12 @@ I7094 = ${I7094D}/i7094_cpu.c ${I7094D}/i7094_cpu1.c ${I7094D}/i7094_io.c \
I7094_OPT = -DUSE_INT64 -I ${I7094D}
I650D = I650
I650 = ${I650D}/i650_cpu.c ${I650D}/i650_cdr.c ${I650D}/i650_cdp.c \
${I650D}/i650_sys.c
I650_OPT = -I ${I650D} -DUSE_INT64 -DUSE_SIM_CARD
IBM1130D = Ibm1130
IBM1130 = ${IBM1130D}/ibm1130_cpu.c ${IBM1130D}/ibm1130_cr.c \
${IBM1130D}/ibm1130_disk.c ${IBM1130D}/ibm1130_stddev.c \
@ -1717,7 +1723,8 @@ ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri \
i7094 ibm1130 id16 id32 sds lgp h316 cdc1700 \
swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 isys8010 isys8020 \
isys8030 isys8024 imds-225 scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090
isys8030 isys8024 imds-225 scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 \
i650
all : ${ALL}
@ -2137,6 +2144,12 @@ ${BIN}i701${EXE} : ${I701} ${SIM}
${MKDIRBIN}
${CC} ${I701} ${SIM} ${I701_OPT} $(CC_OUTSPEC) ${LDFLAGS}
i650 : $(BIN)i650$(EXE)
${BIN}i650${EXE} : ${I650} ${SIM}
${MKDIRBIN}
${CC} ${I650} ${SIM} ${I650_OPT} $(CC_OUTSPEC) ${LDFLAGS}
# Front Panel API Demo/Test program
frontpaneltest : ${BIN}frontpaneltest${EXE}