1
0
mirror of https://github.com/simh/simh.git synced 2026-05-04 15:05:39 +00:00

I650: Release 3

New Hardware support:
- IBM 653 Storage Unit: provides machine opcodes
  for Floating Point, Immediate Access Storage (IAS),
  Three Index registers, Cards Punch-read
  synchronizers 2 and 3.
New Software included:
- FORTRANSIT: version II (S), plus run time PACKAGE
  with standard Fortran functions.
- Reorganized sw directory, separating each language
  in its own folder. Each one Includes a 00_readme.txt
  file with restoration notes and comments.
New features:
- Support for SOAP opcode mnemonics in addition
  to regular IBM mnemonics
- FAST / REALTIME CPU options
- PROP pseudo register
- CARDDECK ECHOLAST command
This commit is contained in:
Roberto Sancho Villa
2018-05-18 21:58:24 +02:00
parent b51d250598
commit 13cb294274
79 changed files with 16830 additions and 803 deletions

View File

@@ -74,16 +74,20 @@ DEVICE cdr_dev = {
NULL, NULL, &cdr_help, NULL, NULL, &cdr_description
};
// buffer to hold read cards in take hopper of each unit
// to be printed by carddeck command
char ReadHopper[3 * MAX_CARDS_IN_READ_TAKE_HOPPER * 80];
int ReadHopperLast[3];
// get 10 digits word with sign from card buf (the data struct). return 1 if HiPunch set on any digit
int decode_8word_wiring(struct _card_data * data, int addr)
int decode_8word_wiring(struct _card_data * data, int bCheckForHiPunch)
{
// decode up to 8 numerical words per card
// input card
// NNNNNNNNNN ... 8 times
// If last digit of word has X(11) punch whole word is set as negative value
// If N is non numeric, a 0 is assumed
// put the decoded data in drum at addr (if addr < 0 -> do not store in drum)
// put the decoded data in IO Sync buffer (if bCheckForHiPunch = 1 -> do not store in IO Sync Buffer)
// return 1 if any colum has Y(12) hi-punch set
uint16 c1,c2;
int wn,iCol,iDigit;
@@ -113,7 +117,7 @@ int decode_8word_wiring(struct _card_data * data, int addr)
c1 = c1 & 0x3FF; // remove X and Y punches
c2 = data->hol_to_ascii[c1]; // convert to ascii again
c2 = c2 - '0'; // convert ascii to binary digit
if (c2 > 9) c2 = 0; // nondigits chars interpreted as zero
if (c2 > 9) c2 = 0; // nondigits chars interpreted as zero
d = d * 10 + c2;
}
// end of word. set sign
@@ -121,15 +125,18 @@ int decode_8word_wiring(struct _card_data * data, int addr)
d = -d; // yes, change sign of word read
if (d == 0) NegZero=1; // word read is minus zero
}
if (addr >= 0) WriteDrum(addr++, d, NegZero); // store word read from card into drum
if (bCheckForHiPunch == 0) {
IOSync [wn]=d;
IOSync_NegativeZeroFlag[wn]=NegZero;
}
}
return HiPunch;
}
// load soap symbolic info, This is a facility to help debugging of soap programs into SimH
// does not exist in real hw
void decode_soap_symb_info(struct _card_data * data, int addr)
void decode_soap_symb_info(struct _card_data * data)
{
t_int64 d;
int op,da,ia,i,i2,p;
@@ -137,16 +144,16 @@ void decode_soap_symb_info(struct _card_data * data, int addr)
uint16 c1,c2;
// check soap 1-word load card initial word
d = DRUM[addr + 0];
d = IOSync[0];
if (d != 6919541953LL) return; // not a 1-word load card
// get the address where the 1-word card will be loaded (into da)
d = DRUM[addr+2];
d = IOSync[2];
op = Shift_Digits(&d, 2); // current inst opcode
da = Shift_Digits(&d, 4); // addr of data
ia = Shift_Digits(&d, 4); // addr of next instr
if ((op != 24) && (ia != 8000)) return; // not a 1-word load card
if (da >= (int)MEMSIZE) return; // destination address out of range
if (da >= (int)DRUMSIZE) return; // symbolic info can only be associated to drum addrs
// convert card image punches to ascii buf for processing, starting at col 40
// keep 026 fortran charset
@@ -210,7 +217,7 @@ t_int64 decode_alpha_word(char * buf, int n)
}
void decode_soap_wiring(struct _card_data * data, int addr)
void decode_soap_wiring(struct _card_data * data)
{
// 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
@@ -254,26 +261,26 @@ void decode_soap_wiring(struct _card_data * data, int addr)
}
buf[80] = 0; // terminate string
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
IOSync[0] = decode_alpha_word(&buf[42], 5); // Location (5 chars)
IOSync[1] = decode_alpha_word(&buf[50], 5); // Data Addr (5 chars)
IOSync[2] = decode_alpha_word(&buf[56], 5); // Inst Addr (5 chars)
IOSync[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)
IOSync[4] = decode_alpha_word(&buf[62], 5); // Remarks
IOSync[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
IOSync[6] = decode_num_word(&buf[43], 4, 0); // Absolute Part of location
IOSync[7] = decode_num_word(&buf[51], 4, 0); // Absolute Part of Data Addr
IOSync[8] = decode_num_word(&buf[57], 4, 0); // Absolute Part of Instr Addr
ty = buf[40] - '0';
if ((ty < 0) || (ty > 9)) ty = 0;
neg = (buf[41] == '-') ? 8:0;
DRUM[addr + 9] = ty * 100 +
(ty ? 80:0) +
neg; // |T b n| T=Type (0 if Blank), b=0/8 (for non blank type), n=0/8 (for negative)
IOSync[9] = ty * 100 +
(ty ? 80:0) +
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)
@@ -293,7 +300,7 @@ int sformat(char * buf, const char * match)
return 1; // end of match string -> return 1 -> buf matches
}
void decode_is_wiring(struct _card_data * data, int addr)
void decode_is_wiring(struct _card_data * data)
{
// 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.pdf
@@ -339,7 +346,6 @@ void decode_is_wiring(struct _card_data * data, int addr)
// 1959: | Problem Number |
// +-------------------+
//
// 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;
@@ -360,15 +366,15 @@ void decode_is_wiring(struct _card_data * data, int addr)
if ( sformat(&buf[6], " ")) {
// card with firsts 26 cols blank = 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
IOSync[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
IOSync[0] = decode_num_word(&buf[6], 3, 0) * D4; // start location (3 digits)
IOSync[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
IOSync[0] = decode_num_word(&buf[6], 3, 0) * D4; // location (3 digits)
IOSync[1] = 1 * D4; // word count
NegZero = 0;
neg = (buf[10] == '-') ? 1:0;
d = decode_num_word(&buf[11], 1, 0) * 10 * D8 + // O1
@@ -379,11 +385,12 @@ void decode_is_wiring(struct _card_data * data, int addr)
d=-d;
if (d==0) NegZero = 1;
}
WriteDrum(addr + 2, d, NegZero);
IOSync [2]=d;
IOSync_NegativeZeroFlag[2]=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
IOSync[0] = decode_num_word(&buf[6], 3, 0) * D4; // location (3 digits)
IOSync[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
@@ -393,24 +400,25 @@ void decode_is_wiring(struct _card_data * data, int addr)
d=-d;
if (d==0) NegZero = 1;
}
WriteDrum(addr + 2, d, NegZero);
IOSync [2]=d;
IOSync_NegativeZeroFlag[2]=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
IOSync[0] = decode_num_word(&buf[7], 4, 0) * D4; // location (4 digits)
IOSync[1] = 1 * D4; // word count = 1
IOSync[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)
IOSync[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
IOSync[1] = wc * D4; // word count
for (i=0;i<wc;i++) {
NegZero = 0;
neg = (buf[10 + 11*i] == '-') ? 1:0;
@@ -419,13 +427,14 @@ void decode_is_wiring(struct _card_data * data, int addr)
d=-d;
if (d==0) NegZero = 1;
}
WriteDrum(addr + 2 + i, d, NegZero);
IOSync [2+i]=d;
IOSync_NegativeZeroFlag[2+i]=NegZero;
}
DRUM[addr + 9] = decode_num_word(&buf[76], 3, 1); // problem number
IOSync[9] = decode_num_word(&buf[76], 3, 1); // problem number
}
}
void decode_it_wiring(struct _card_data * data, int addr)
void decode_it_wiring(struct _card_data * data)
{
// decode IT compiler card simulating control panel wiring for 533
// from IT manual at http://www.bitsavers.org/pdf/ibm/650/CarnegieInternalTranslator.pdf
@@ -485,22 +494,143 @@ void decode_it_wiring(struct _card_data * data, int addr)
if (buf[2] == '+') {
// type 1 data card
// re-read as 8 word per card
decode_8word_wiring(data, addr);
decode_8word_wiring(data, 0);
return;
}
DRUM[addr + 0] = decode_alpha_word(&buf[42], 5); // Statement (5 chars)
DRUM[addr + 1] = decode_alpha_word(&buf[47], 5); // Statement (5 chars)
DRUM[addr + 2] = decode_alpha_word(&buf[52], 5); // Statement (5 chars)
DRUM[addr + 3] = decode_alpha_word(&buf[57], 5); // Statement (5 chars)
DRUM[addr + 4] = decode_alpha_word(&buf[62], 5); // Statement (5 chars)
DRUM[addr + 5] = decode_alpha_word(&buf[67], 3); // Statement (3 chars)
IOSync[0] = decode_alpha_word(&buf[42], 5); // Statement (5 chars)
IOSync[1] = decode_alpha_word(&buf[47], 5); // Statement (5 chars)
IOSync[2] = decode_alpha_word(&buf[52], 5); // Statement (5 chars)
IOSync[3] = decode_alpha_word(&buf[57], 5); // Statement (5 chars)
IOSync[4] = decode_alpha_word(&buf[62], 5); // Statement (5 chars)
IOSync[5] = decode_alpha_word(&buf[67], 3); // Statement (3 chars)
DRUM[addr + 6] = decode_num_word(&buf[0], 4, 1); // Statement Number (space is read as digit zero)
IOSync[6] = decode_num_word(&buf[0], 4, 1); // Statement Number (space is read as digit zero)
}
void decode_fortransit_wiring(struct _card_data * data)
{
// decode FORTRANSIT translator card simulating control panel wiring for 533
// from FORTRANSIT manual at http://bitsavers.org/pdf/ibm/650/28-4028_FOR_TRANSIT.pdf
// implemented Fortransit II (S)
// fortran source program input card
// Column: 1 | 2 3 4 5 | 6 | 7 - 36 | 37 - 80 |
// C | N N N N | cont | Statement | Blank |
//
// C = Blank or Comment if C is present
// NNNN = Blank or statement number
// cont = Blank or non-blank/non-zero for continuation card
//
// storage in input block
// +-------------------+
// Word 1951: | <- Statement -> | Alphabetic
// 1952: | <- Statement -> | Alphabetic
// 1953: | <- Statement -> | Alphabetic
// 1954: | <- Statement -> | Alphabetic
// 1955: | <- Statement -> | Alphabetic
// 1956: | <- Statement -> | Alphabetic
// +-------------------+
// 1957: | | Not used
// 1958: | | Not used
// 1959: | | Not used
// +-+-+-------+-------+
// 1960: |m t| |N N N N| m = 8/0 (8 -> comment card)
// +---+-------+-------+ t = 8/0 (8 -> continuatin card)
// NNNN = statement sumber
//
// it source program input card
// Column: 1 2 3 4 | 5 | 6 - 42 | 43 - 70 | 71 72 | 73 - 80 |
// N N N N | + | | Statement | | Comments |
// Statement | Y(12) | | max 28 | | max 8 |
// Number | Punch | | chars | | chars |
//
// storage in input block
// +-------------------+
// Word 0051: | <- Statement -> | Alphabetic
// 0052: | <- Statement -> | Alphabetic
// 0053: | <- Statement -> | Alphabetic
// 0054: | <- Statement -> | Alphabetic
// 0055: | <- Statement -> | Alphabetic
// 0056: | <- Statement -> | Alphabetic
// +-+-+-+-+-+-|-+-+-+-|
// 0057: | |N N N N| Statement Number
// +-+-+-+-+-+-|-+-+-+-|
// 0058: | | Not used
// 0059: | | Not used
// 0060: | | Not used
// +-------------------+
//
// fortransit input data card
// Column: 1 - 10 | 11 - 20 | 21 - 30 | 31 - 40 | 41 - 50 | 51 - 60 | 61 - 70 | 71 72 | 73 | 74 - 80 |
// Word1 | Word2 | Word3 | Word4 | Word5 | Word6 | Word7 | | + |
// | Y(12) |
// Word = word to be loaded into FORTRANSITIT variable. Must match the variable type where it is read in
// float (MMMMMMMM EE -> M=mantisa, EE=exponent, 1000000051 is 1.0)
// fixed (NNNNNNNNNN -> 000000030J is -302)
// if word is negative, last digit get X(11) overpunch
// If last digit of word has X(11) punch whole word is set as negative value
// If N is non numeric, a 0 is assumed
//
// storage in input block
// +-------------------+
// Word 1951: | <- Word1 -> |
// 1952: | <- Word2 -> |
// 1953: | <- Word3 -> |
// 1954: | <- Word4 -> |
// 1955: | <- Word5 -> |
// 1956: | <- Word6 -> |
// 1957: | <- Word7 -> |
// +-------------------+
// 1958: | | Not used
// 1959: | | Not used
// 1960: | | Not used
// +-------------------+
//
char buf[81];
int i;
uint16 c1,c2;
// convert card image punches to ascii buf for processing
// keep 026 fortran charset
for (i=0;i<80;i++) {
c1 = data->image[i];
c2 = data->hol_to_ascii[c1];
c2 = toupper(c2);
c2 = (strchr(mem_to_ascii, c2)) ? c2:' ';
if (c2 == '~') c2 = ' ';
buf[i] = (char) c2;
}
buf[80] = 0; // terminate string
if (buf[72] == '+') {
// read data card input for READ fortransit command
// re-read as 8 word per card
decode_8word_wiring(data, 0);
return;
} else if (buf[4] == '+') {
// it source statement
IOSync[0] = decode_alpha_word(&buf[42], 5); // Statement (5 chars)
IOSync[1] = decode_alpha_word(&buf[47], 5); // Statement (5 chars)
IOSync[2] = decode_alpha_word(&buf[52], 5); // Statement (5 chars)
IOSync[3] = decode_alpha_word(&buf[57], 5); // Statement (5 chars)
IOSync[4] = decode_alpha_word(&buf[62], 5); // Statement (5 chars)
IOSync[5] = decode_alpha_word(&buf[67], 5); // Statement (5 chars)
IOSync[6] = decode_num_word(&buf[0], 4, 1); // Statement Number (space is read as digit zero)
} else {
// fortran source statement
IOSync[0] = decode_alpha_word(&buf[6], 5); // Statement (5 chars)
IOSync[1] = decode_alpha_word(&buf[11], 5); // Statement (5 chars)
IOSync[2] = decode_alpha_word(&buf[16], 5); // Statement (5 chars)
IOSync[3] = decode_alpha_word(&buf[21], 5); // Statement (5 chars)
IOSync[4] = decode_alpha_word(&buf[26], 5); // Statement (5 chars)
IOSync[5] = decode_alpha_word(&buf[31], 5); // Statement (5 chars)
IOSync[9] = ( (buf[0] == 'C') ? (t_int64) 80 * D8 : 0 ) + // is a comment card
( ((buf[5] != ' ') && (buf[5] != 0)) ? (t_int64) 8 * D8 : 0 ) + // continuation line
( decode_num_word(&buf[1], 4, 1) ); // statement number
}
}
/*
* Device entry points for card reader.
*/
@@ -510,13 +640,17 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 addr)
uint32 wiring;
int i;
char cbuf[81];
int ncdr, ic;
/* 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);
// clear IO Sync buffer (where words read from cards will be stored)
for (i=0;i<10;i++) {
IOSync [i]=0;
IOSync_NegativeZeroFlag[i]=0;
}
/* Test ready */
if ((uptr->flags & UNIT_ATT) == 0) {
@@ -553,29 +687,40 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 addr)
cbuf[80] = 0; // terminate string
sim_debug(DEBUG_DETAIL, &cpu_dev, "Read Card: %s\n", sim_trim_endspc(cbuf));
// save read card in last read card buffer to be eventually printed
// by carddec echolast scp command
ncdr = uptr - &cdr_unit[1]; // ncdr is the card reader: 0 for cdr1, 1 for cdr2, 2 for cdr3
if ((ncdr >= 0) && (ncdr < 3)) { // safety check, not needed (should allways be true) but just to be sure
// advance read buffer last card
ReadHopperLast[ncdr] = (ReadHopperLast[ncdr] + 1) % MAX_CARDS_IN_READ_TAKE_HOPPER;
// save card in read card hopper buffer
ic = (ncdr * MAX_CARDS_IN_READ_TAKE_HOPPER + ReadHopperLast[ncdr]) * 80;
for (i=0; i<80; i++) ReadHopper[ic + i] = cbuf[i];
}
// uint16 data->image[] array that holds the actual punched rows on card
// using this codification:
//
// Row Name value in image[] comments
//
// Y 0x800 Hi Punch Y(12)
// X 0x400 Minus Punch X(11)
// 0 0x200 also called T (Ten, 10)
// 1 0x100
// 2 0x080
// 3 0x040
// 4 0x020
// 5 0x010
// 6 0x008
// 7 0x004
// 8 0x002
// 9 0x001
// Y 0x800 Hi Punch Y(12)
// X 0x400 Minus Punch X(11)
// 0 0x200 also called T (Ten, 10)
// 1 0x100
// 2 0x080
// 3 0x040
// 4 0x020
// 5 0x010
// 6 0x008
// 7 0x004
// 8 0x002
// 9 0x001
//
// If several columns are punched, the values are ORed: eg char A is represented as a punch
// on row Y and row 1, so it value in image array will be 0x800 | 0x100 -> 0x900
// check if it is a load card (Y(12) = HiPunch set on any column of card) signales it
if (decode_8word_wiring(data, -1)) {
if (decode_8word_wiring(data, 1)) {
uptr->u5 |= URCSTA_LOAD;
} else {
uptr->u5 &= ~URCSTA_LOAD;
@@ -583,27 +728,30 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 addr)
wiring = (uptr->flags & UNIT_CARD_WIRING);
// translate chars read from card and copy to drum memory words
// translate chars read from card and copy to memory words
// using the control panel wiring.
if (uptr->u5 & URCSTA_LOAD) {
// load card -> use 8 words per card encoding
decode_8word_wiring(data, addr);
decode_8word_wiring(data, 0);
if (uptr->u5 & URCSTA_SOAPSYMB) {
// requested to load soap symb info
decode_soap_symb_info(data, addr);
decode_soap_symb_info(data);
}
} else if (wiring == WIRING_SOAP) {
// decode soap card simulating soap control panel wiring for 533 (gasp!)
decode_soap_wiring(data, addr);
decode_soap_wiring(data);
} else if (wiring == WIRING_IS) {
// decode floating point interpretive system (bell interpreter) card
decode_is_wiring(data, addr);
decode_is_wiring(data);
} else if (wiring == WIRING_IT) {
// decode Carnegie Internal Translator compiler card
decode_it_wiring(data, addr);
decode_it_wiring(data);
} else if (wiring == WIRING_FORTRANSIT) {
// decode Fortransit translator card
decode_fortransit_wiring(data);
} else {
// default wiring: decode up to 8 numerical words per card. Can be a load card
decode_8word_wiring(data, addr);
decode_8word_wiring(data, 0);
}
uptr->u5 &= ~URCSTA_BUSY;
@@ -656,6 +804,7 @@ t_stat
cdr_attach(UNIT * uptr, CONST char *file)
{
t_stat r;
int ncdr, ic1, ic2, i;
if (uptr->flags & UNIT_ATT) // remove current deck in read hopper before attaching
sim_card_detach(uptr); // the new one
@@ -669,6 +818,17 @@ cdr_attach(UNIT * uptr, CONST char *file)
if (sim_switches & SWMASK ('L')) { /* Load Symbolic SOAP info? */
uptr->u5 |= URCSTA_SOAPSYMB;
}
// clear read card take hopper buffer
ncdr = uptr - &cdr_unit[1]; // ncdr is the card reader: 0 for cdr1, 1 for cdr2, 2 for cdr3
if ((ncdr >= 0) && (ncdr < 3)) { // safety check, not needed (should allways be true) but just to be sure
// reset last read card number
ReadHopperLast[ncdr] = 0;
// clear buffer
ic1 = (ncdr * MAX_CARDS_IN_READ_TAKE_HOPPER) * 80;
ic2 = ic1 + MAX_CARDS_IN_READ_TAKE_HOPPER * 80;
for (i=ic1; i<ic2; i++) ReadHopper[i] = 0;
}
return SCPE_OK;
}