1
0
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:
Richard Cornwell 2017-12-29 23:22:57 -05:00
parent 8cb1a59be4
commit 082a83d0ed
4 changed files with 136 additions and 82 deletions

View File

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

View File

@ -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];

View File

@ -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);

View File

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