mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-21 18:15:04 +00:00
IBM360: Misc changes to get system working better.
Cleaned up channel handling to properly buffer words.
End of file handling on DASD records.
Added instruction tracing to debug log.
This commit is contained in:
parent
8cb1a59be4
commit
082a83d0ed
@ -141,6 +141,10 @@ find_subchan(uint16 device) {
|
||||
return ((device - subchannels)>>4) & 0xf;
|
||||
}
|
||||
|
||||
/* Read a full word into memory.
|
||||
* Return 1 if fail.
|
||||
* Return 0 if success.
|
||||
*/
|
||||
int
|
||||
readfull(int chan, uint32 addr, uint32 *word) {
|
||||
int sk, k;
|
||||
@ -166,27 +170,94 @@ readfull(int chan, uint32 addr, uint32 *word) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int writefull(int chan, uint32 addr, uint32 *word) {
|
||||
/* Read a word into the channel buffer.
|
||||
* Return 1 if fail.
|
||||
* Return 0 if success.
|
||||
*/
|
||||
int
|
||||
readbuff(int chan) {
|
||||
int sk, k;
|
||||
uint32 addr = ccw_addr[chan];
|
||||
if ((addr & AMASK) > MEMSIZE) {
|
||||
chan_status[chan] |= STATUS_PCHK;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
sk = (addr >> 24) & 0xff;
|
||||
if (sk != 0) {
|
||||
if ((cpu_dev.flags & PROTECT) == 0) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
k = key[(addr & 0xfffc00) >> 10];
|
||||
if ((k & 0x8) != 0 && (k & 0xf0) != sk) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
M[addr] = *word;
|
||||
chan_buf[chan] = M[addr];
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "Channel write %02x %06x %08x %08x '",
|
||||
chan, ccw_addr[chan] & 0xFFFFFC, chan_buf[chan], ccw_count[chan]);
|
||||
for(k = 24; k >= 0; k -= 8) {
|
||||
char ch = ebcdic_to_ascii[(chan_buf[chan] >> k) & 0xFF];
|
||||
if (ch < 0x20 || ch == 0xff)
|
||||
ch = '.';
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "%c", ch);
|
||||
}
|
||||
|
||||
sim_debug(DEBUG_DATA, & cpu_dev, "'\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write channel buffer to memory.
|
||||
* Return 1 if fail.
|
||||
* Return 0 if success.
|
||||
*/
|
||||
int
|
||||
writebuff(int chan) {
|
||||
int sk, k;
|
||||
uint32 addr = ccw_addr[chan];
|
||||
if ((addr & AMASK) > MEMSIZE) {
|
||||
chan_status[chan] |= STATUS_PCHK;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
sk = (addr >> 24) & 0xff;
|
||||
if (sk != 0) {
|
||||
if ((cpu_dev.flags & PROTECT) == 0) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
k = key[(addr & 0xfffc00) >> 10];
|
||||
if ((k & 0x8) != 0 && (k & 0xf0) != sk) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
M[addr] = chan_buf[chan];
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "Channel readf %02x %06x %08x %08x '",
|
||||
chan, ccw_addr[chan] & 0xFFFFFC, chan_buf[chan], ccw_count[chan]);
|
||||
for(k = 24; k >= 0; k -= 8) {
|
||||
char ch = ebcdic_to_ascii[(chan_buf[chan] >> k) & 0xFF];
|
||||
if (ch < 0x20 || ch == 0xff)
|
||||
ch = '.';
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "%c", ch);
|
||||
}
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "'\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -314,21 +385,8 @@ chan_read_byte(uint16 addr, uint8 *data) {
|
||||
}
|
||||
}
|
||||
if (chan_byte[chan] == BUFF_EMPTY) {
|
||||
if (readfull(chan, ccw_addr[chan], &chan_buf[chan])) {
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
if (readbuff(chan))
|
||||
return 1;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "Channel write %02x %06x %08x %08x '",
|
||||
chan, ccw_addr[chan], chan_buf[chan], ccw_count[chan]);
|
||||
for(k = 24; k >= 0; k -= 8) {
|
||||
char ch = ebcdic_to_ascii[(chan_buf[chan] >> k) & 0xFF];
|
||||
if (ch < 0x20 || ch == 0xff)
|
||||
ch = '.';
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "%c", ch);
|
||||
}
|
||||
|
||||
sim_debug(DEBUG_DATA, & cpu_dev, "'\n");
|
||||
chan_byte[chan] = ccw_addr[chan] & 0x3;
|
||||
ccw_addr[chan] += 4 - chan_byte[chan];
|
||||
}
|
||||
@ -356,12 +414,16 @@ chan_write_byte(uint16 addr, uint8 *data) {
|
||||
if ((ccw_cmd[chan] & 0x1) != 0) {
|
||||
return 1;
|
||||
}
|
||||
if (chan_byte[chan] == BUFF_CHNEND) {
|
||||
if ((ccw_flags[chan] & FLAG_SLI) == 0) {
|
||||
chan_status[chan] |= STATUS_LENGTH;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (ccw_count[chan] == 0) {
|
||||
if (chan_byte[chan] != BUFF_CHNEND) {
|
||||
if (writefull(chan, ccw_addr[chan], &chan_buf[chan])) {
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
if (chan_byte[chan] & BUFF_DIRTY) {
|
||||
if (writebuff(chan))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((ccw_flags[chan] & FLAG_CD) == 0) {
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
@ -375,42 +437,18 @@ chan_write_byte(uint16 addr, uint8 *data) {
|
||||
if (load_ccw(chan, 1))
|
||||
return 1;
|
||||
}
|
||||
if (chan_byte[chan] == BUFF_CHNEND) {
|
||||
if ((ccw_flags[chan] & FLAG_SLI) == 0) {
|
||||
chan_status[chan] |= STATUS_LENGTH;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (ccw_flags[chan] & FLAG_SKIP) {
|
||||
ccw_count[chan]--;
|
||||
chan_byte[chan] = BUFF_EMPTY;
|
||||
if ((ccw_cmd[chan] & 0xf) == CMD_RDBWD)
|
||||
ccw_addr[chan]--;
|
||||
else
|
||||
ccw_addr[chan]++;
|
||||
// if (ccw_count[chan] == 0) {
|
||||
// if (ccw_flags[chan] & FLAG_CD)
|
||||
// return load_ccw(chan, 1);
|
||||
// else
|
||||
// chan_byte[chan] = BUFF_CHNEND;
|
||||
// return 1;
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
if (chan_byte[chan] == (BUFF_EMPTY|BUFF_DIRTY)) {
|
||||
if (writefull(chan, ccw_addr[chan], &chan_buf[chan])) {
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
if (writebuff(chan))
|
||||
return 1;
|
||||
}
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "Channel read %02x %06x %08x %08x '",
|
||||
chan, ccw_addr[chan], chan_buf[chan], ccw_count[chan]);
|
||||
for(k = 24; k >= 0; k -= 8) {
|
||||
char ch = ebcdic_to_ascii[(chan_buf[chan] >> k) & 0xFF];
|
||||
if (ch < 0x20 || ch == 0xff)
|
||||
ch = '.';
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "%c", ch);
|
||||
}
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "'\n");
|
||||
if ((ccw_cmd[chan] & 0xf) == CMD_RDBWD)
|
||||
ccw_addr[chan] -= 1 + (ccw_addr[chan] & 0x3);
|
||||
else
|
||||
@ -418,11 +456,8 @@ chan_write_byte(uint16 addr, uint8 *data) {
|
||||
chan_byte[chan] = BUFF_EMPTY;
|
||||
}
|
||||
if (chan_byte[chan] == BUFF_EMPTY) {
|
||||
if (readfull(chan, ccw_addr[chan], &chan_buf[chan])) {
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
if (readbuff(chan))
|
||||
return 1;
|
||||
}
|
||||
chan_byte[chan] = ccw_addr[chan] & 0x3;
|
||||
}
|
||||
ccw_count[chan]--;
|
||||
@ -464,21 +499,12 @@ chan_end(uint16 addr, uint8 flags) {
|
||||
if (chan < 0)
|
||||
return;
|
||||
|
||||
if (chan_byte[chan] & BUFF_DIRTY) {
|
||||
int k;
|
||||
writefull(chan, ccw_addr[chan], &chan_buf[chan]);
|
||||
chan_byte[chan] = BUFF_EMPTY;
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "Channel read %02x %06x %08x %08x '",
|
||||
chan, ccw_addr[chan], chan_buf[chan], ccw_count[chan]);
|
||||
for(k = 24; k >= 0; k -= 8) {
|
||||
char ch = ebcdic_to_ascii[(chan_buf[chan] >> k) & 0xFF];
|
||||
if (ch < 0x20 || ch == 0xff)
|
||||
ch = '.';
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "%c", ch);
|
||||
}
|
||||
sim_debug(DEBUG_DATA, &cpu_dev, "'\n");
|
||||
}
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end(%x, %x) %x\n", addr, flags, ccw_count[chan]);
|
||||
if (chan_byte[chan] & BUFF_DIRTY) {
|
||||
if (writebuff(chan))
|
||||
return;
|
||||
chan_byte[chan] = BUFF_EMPTY;
|
||||
}
|
||||
chan_status[chan] |= STATUS_CEND;
|
||||
chan_status[chan] |= ((uint16)flags) << 8;
|
||||
ccw_cmd[chan] = 0;
|
||||
@ -494,15 +520,15 @@ chan_end(uint16 addr, uint8 flags) {
|
||||
if (chan_status[chan] & (STATUS_DEND|STATUS_CEND)) {
|
||||
chan_byte[chan] = BUFF_NEWCMD;
|
||||
|
||||
while ((ccw_flags[chan] & FLAG_CD)) {
|
||||
while ((ccw_flags[chan] & FLAG_CD)) {
|
||||
if (load_ccw(chan, 1))
|
||||
break;
|
||||
if (ccw_count[chan] != 0 && (ccw_flags[chan] & FLAG_SLI) == 0) {
|
||||
if ((ccw_flags[chan] & FLAG_SLI) == 0) {
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end length\n");
|
||||
chan_status[chan] |= STATUS_LENGTH;
|
||||
ccw_flags[chan] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
irq_pend = 1;
|
||||
@ -629,10 +655,6 @@ int haltio(uint16 addr) {
|
||||
}
|
||||
if (dibp->halt_io != NULL)
|
||||
chan_status[chan] = dibp->halt_io(uptr) << 8;
|
||||
// if (chan_status[chan] & (STATUS_ATTN|STATUS_PCI|STATUS_EXPT|STATUS_CHECK|
|
||||
// STATUS_PROT|STATUS_CDATA|STATUS_CCNTL|STATUS_INTER|
|
||||
// STATUS_CHAIN))
|
||||
// return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -351,9 +351,10 @@ int WriteFull(uint32 addr, uint32 data) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if ((addr & 0xfffff0) == 0xc90 && data == 0x40404040) {
|
||||
// fprintf(stderr, "Error word\n\r");
|
||||
// }
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "wr fu %08x %08x ", addr, data);
|
||||
if ((addr & 0xfffffc) == 0x03c80) {
|
||||
fprintf(stderr, "Error word\n\r");
|
||||
}
|
||||
|
||||
offset = addr & 0x3;
|
||||
addr >>= 2;
|
||||
@ -420,7 +421,8 @@ int WriteByte(uint32 addr, uint32 data) {
|
||||
storepsw(OPPSW, IRC_ADDR);
|
||||
return 1;
|
||||
}
|
||||
if ((addr & 0xfffff0) == 0xc90 && data == 0x40) {
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "wr by %08x %02x ", addr, data);
|
||||
if ((addr & 0xfffffc) == 0x03c80) {
|
||||
fprintf(stderr, "Error byte\n\r");
|
||||
}
|
||||
|
||||
@ -462,9 +464,10 @@ int WriteHalf(uint32 addr, uint32 data) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if ((addr & 0xfffff0) == 0xc90 && data == 0x4040) {
|
||||
// fprintf(stderr, "Error half\n\r");
|
||||
// }
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "wr hf %08x %04x ", addr, data);
|
||||
if ((addr & 0xfffffc) == 0x03c80) {
|
||||
fprintf(stderr, "Error half\n\r");
|
||||
}
|
||||
offset = addr & 0x3;
|
||||
addr >>= 2;
|
||||
|
||||
@ -607,6 +610,8 @@ wait_loop:
|
||||
ilc = 1;
|
||||
if (hst_lnt)
|
||||
hst[hst_p].inst[0] = src1;
|
||||
if ((PC & 0xFFFFF0) != 0xBA0)
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "%08x %04x ", PC, src1 & 0xFFFF);
|
||||
PC += 2;
|
||||
pmsk &= ~ILMASK;
|
||||
reg = (uint8)(src1 & 0xff);
|
||||
@ -622,6 +627,8 @@ wait_loop:
|
||||
PC += 2;
|
||||
if (hst_lnt)
|
||||
hst[hst_p].inst[1] = addr1;
|
||||
if ((PC & 0xFFFFF0) != 0xBA0)
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "%04x ", addr1 & 0xFFFF);
|
||||
/* Check if SS */
|
||||
if ((op & 0xc0) == 0xc0) {
|
||||
pmsk += 0x40;
|
||||
@ -631,9 +638,13 @@ wait_loop:
|
||||
ilc = 3;
|
||||
if (hst_lnt)
|
||||
hst[hst_p].inst[2] = addr2;
|
||||
if ((PC & 0xFFFFF0) != 0xBA0)
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "%04x ", addr2 & 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
if ((PC & 0xFFFFF0) != 0xBA0)
|
||||
sim_debug(DEBUG_INST, &cpu_dev, " -> ");
|
||||
/* Add in history here */
|
||||
opr:
|
||||
if (op & 0xc0) {
|
||||
@ -716,6 +727,8 @@ opr:
|
||||
hst[hst_p].src2 = src2;
|
||||
}
|
||||
|
||||
if ((PC & 0xFFFFF0) != 0xBA0)
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "%08x %08x - %08x %08x\n", addr1, addr2, src1, src2);
|
||||
/* Preform opcode */
|
||||
switch (op) {
|
||||
case OP_SPM:
|
||||
@ -1382,6 +1395,8 @@ save_dbl:
|
||||
} else {
|
||||
dest = src1;
|
||||
}
|
||||
if ((PC & 0xFFFFF0) != 0xBA0)
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "%02x ", dest);
|
||||
//fprintf(stderr, " %x -> %x", src1, dest);
|
||||
if (WriteByte(addr1, dest))
|
||||
break;
|
||||
@ -1390,6 +1405,7 @@ save_dbl:
|
||||
reg--;
|
||||
} while (reg != 0xff);
|
||||
//fprintf(stderr, "\n\r");
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "\n");
|
||||
break;
|
||||
|
||||
case OP_CLC:
|
||||
@ -1990,6 +2006,13 @@ save_dbl:
|
||||
hst[hst_p].cc = cc;
|
||||
}
|
||||
|
||||
if ((PC & 0xFFFFF0) != 0xBA0) {
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "R0=%08x R1=%08x R2=%08x R3=%08x ", regs[0], regs[1], regs[2], regs[3]);
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "R4=%08x R5=%08x R6=%08x R7=%08x\n", regs[4], regs[5], regs[6], regs[7]);
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "R8=%08x R9=%08x RA=%08x RB=%08x ", regs[8], regs[9], regs[10], regs[11]);
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "RC=%08x RD=%08x RE=%08x RF=%08x\n", regs[12], regs[13], regs[14], regs[15]);
|
||||
}
|
||||
|
||||
if (irqaddr != 0) {
|
||||
supress:
|
||||
src1 = M[irqaddr>>2];
|
||||
|
||||
@ -1007,7 +1007,7 @@ index:
|
||||
|
||||
case DK_RD_CKD: /* Read count, key and data */
|
||||
/* Wait for any count */
|
||||
if (count == 0 && state == DK_POS_CNT) {
|
||||
if (count == 0 && state == DK_POS_CNT && data->rec != 0) {
|
||||
uptr->u3 |= DK_PARAM;
|
||||
uptr->u3 &= ~DK_INDEX;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RD CKD unit=%d %d k=%d d=%d %02x %04x\n",
|
||||
@ -1040,9 +1040,9 @@ index:
|
||||
rd:
|
||||
if (uptr->u3 & DK_PARAM) {
|
||||
/* Check for end of file */
|
||||
if (state == DK_POS_DATA && count == 0 && data->dlen == 0) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RD EOF unit=%d %x %d %d\n",
|
||||
unit, state, count, data->rec);
|
||||
if (state == DK_POS_DATA && data->dlen == 0) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RD EOF unit=%d %x %d %d d=%d\n",
|
||||
unit, state, count, data->rec, data->dlen);
|
||||
uptr->u3 &= ~(0xff|DK_PARAM);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
break;
|
||||
@ -1230,6 +1230,14 @@ wrckd:
|
||||
uptr->u3 &= ~(0xff|DK_PARAM);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
break;
|
||||
} else if ((cmd == DK_WR_KD || cmd == DK_WR_D) && state == DK_POS_DATA
|
||||
&& data->dlen == 0) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "WR EOF unit=%d %x %d %d d=%d\n",
|
||||
unit, state, count, data->rec, data->dlen);
|
||||
uptr->u3 &= ~(0xff|DK_PARAM);
|
||||
uptr->u6 = cmd;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
break;
|
||||
} else if (state == DK_POS_DATA && data->count == data->dlen) {
|
||||
uptr->u6 = cmd;
|
||||
uptr->u3 &= ~(0xff|DK_PARAM);
|
||||
|
||||
@ -85,6 +85,7 @@ DEBTAB dev_debug[] = {
|
||||
{"DETAIL", DEBUG_DETAIL, "Show details about device"},
|
||||
{"EXP", DEBUG_EXP, "Show exception information"},
|
||||
{"POS", DEBUG_POS, "Dasd positioning information"},
|
||||
{"INST", DEBUG_INST, "Show instruction execution"},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user