diff --git a/IBM360/ibm360_chan.c b/IBM360/ibm360_chan.c index e4e0378..52485aa 100644 --- a/IBM360/ibm360_chan.c +++ b/IBM360/ibm360_chan.c @@ -447,6 +447,13 @@ chan_read_byte(uint16 addr, uint8 *data) { byte = (chan_buf[chan] >> (8 * (3 - (chan_byte[chan] & 0x3)))) & 0xff; chan_byte[chan]++; *data = byte; + /* If count is zero and chainging load in new CCW */ + if (ccw_count[chan] == 0 && (ccw_flags[chan] & FLAG_CD) != 0) { + chan_byte[chan] = BUFF_EMPTY; + /* Try and grab next CCW */ + if (load_ccw(chan, 1)) + return 1; + } return 0; } @@ -585,6 +592,16 @@ chan_write_byte(uint16 addr, uint8 *data) { } else chan_byte[chan]++; chan_byte[chan] |= BUFF_DIRTY; + /* If count is zero and chainging load in new CCW */ + if (ccw_count[chan] == 0 && (ccw_flags[chan] & FLAG_CD) != 0) { + /* Flush buffer */ + if (writebuff(chan)) + return 1; + chan_byte[chan] = BUFF_EMPTY; + /* Try and grab next CCW */ + if (load_ccw(chan, 1)) + return 1; + } return 0; } diff --git a/IBM360/ibm360_con.c b/IBM360/ibm360_con.c index 7e9b160..a06cce6 100644 --- a/IBM360/ibm360_con.c +++ b/IBM360/ibm360_con.c @@ -79,6 +79,7 @@ struct _con_data con_data[NUM_DEVS_CON]; uint8 con_startcmd(UNIT *, uint16, uint8); +uint8 con_haltio(UNIT *); void con_ini(UNIT *, t_bool); t_stat con_srv(UNIT *); t_stat con_attach(UNIT *, char *); @@ -96,7 +97,7 @@ MTAB con_mod[] = { {0} }; -struct dib con_dib = { 0xFF, 1, NULL, con_startcmd, NULL, con_unit, con_ini}; +struct dib con_dib = { 0xFF, 1, NULL, con_startcmd, con_haltio, con_unit, con_ini}; DEVICE con_dev = { "INQ", con_unit, NULL, con_mod, @@ -195,6 +196,35 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { return SNS_CHNEND|SNS_DEVEND; } +/* + * Handle halt I/O instruction by stoping running command. + */ +uint8 con_haltio(UNIT *uptr) { + uint16 addr = GET_UADDR(uptr->CMD); + DEVICE *dptr = find_dev_from_unit(uptr); + int u = (uptr - con_unit); + int cmd = uptr->CMD & 0xff; + + sim_debug(DEBUG_CMD, dptr, "HLTIO inq %x\n", cmd); + + switch (cmd) { + case 0: + case 0x4: + /* Short commands nothing to do */ + break; + + case CON_WR: + case CON_ACR: + case CON_RD: + uptr->CMD &= ~(CON_MSK|CON_INPUT); + con_data[u].inptr = 0; + chan_end(addr, SNS_CHNEND|SNS_DEVEND); + break; + } + return 1; +} + + /* Handle transfer of data for printer */ t_stat con_srv(UNIT *uptr) { @@ -250,7 +280,8 @@ con_srv(UNIT *uptr) { case CON_RD: if (uptr->CMD & CON_INPUT) { uptr->CMD &= ~CON_REQ; - if (con_data[u].inptr == 0) { + /* Check for empty line, or end of data */ + if (con_data[u].inptr == 0 || uptr->IPTR == con_data[u].inptr) { uptr->CMD &= ~CON_INPUT; con_data[u].inptr = 0; cmd = 0; @@ -260,6 +291,7 @@ con_srv(UNIT *uptr) { break; } + /* Grab next character and send it to CPU */ ch = con_data[u].ibuff[uptr->IPTR++]; sim_debug(DEBUG_CMD, &con_dev, "%d: rd %02x\n", u, ch); if (chan_write_byte(addr, &ch)) { @@ -269,15 +301,6 @@ con_srv(UNIT *uptr) { uptr->CMD &= ~(CON_MSK); sim_debug(DEBUG_CMD, &con_dev, "%d: devend input\n", u); chan_end(addr, SNS_CHNEND|SNS_DEVEND); - } else { - if (uptr->IPTR == con_data[u].inptr) { - uptr->CMD &= ~CON_INPUT; - con_data[u].inptr = 0; - cmd = 0; - uptr->CMD &= ~(CON_MSK); - sim_debug(DEBUG_CMD, &con_dev, "%d: devend\n", u); - chan_end(addr, SNS_CHNEND|SNS_DEVEND); - } } } break; diff --git a/IBM360/ibm360_cpu.c b/IBM360/ibm360_cpu.c index 4a1fe28..d4a90bd 100644 --- a/IBM360/ibm360_cpu.c +++ b/IBM360/ibm360_cpu.c @@ -2276,7 +2276,7 @@ save_dbl: seg_addr = dest & AMASK; seg_len = (((dest >> 24) & 0xff) + 1) << 4; break; - case 0x6: /* Masks */ + case 0x4: /* Extended mask */ cregs[reg] &= 0xfefe0000; if (dest & 0xfe000000) cregs[reg] |= 0x1000000; @@ -2288,7 +2288,7 @@ save_dbl: irq_pend = 1; } break; - case 0x4: /* Extended mask */ + case 0x6: /* Masks */ ec_mode = (dest & 0x00800000) != 0; if (ec_mode && irq_en) { sysmsk = (cregs[6] >> 16) & 0xfe00;