1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-02-28 17:19:52 +00:00

IBM360: Updated so 2703 works as a 1050.

This commit is contained in:
Richard Cornwell
2020-05-15 20:17:31 -04:00
parent 541c9c98c5
commit 0385a7108c
3 changed files with 192 additions and 109 deletions

View File

@@ -905,6 +905,12 @@ int haltio(uint16 addr) {
return 0;
}
/* If channel active, tell it to terminate */
if (ccw_cmd[chan]) {
chan_byte[chan] = BUFF_CHNEND;
ccw_flags[chan] = 0;
}
/* Not executing a command, issue halt if available */
if (dibp->halt_io != NULL) {
/* Let device do it's thing */
@@ -918,9 +924,6 @@ int haltio(uint16 addr) {
return cc;
}
/* If channel active, tell it to terminate */
if (ccw_cmd[chan])
chan_byte[chan] = BUFF_CHNEND;
/* Store CSW and return 1. */
sim_debug(DEBUG_CMD, &cpu_dev, "HIOx %x %x cc=1\n", addr, chan);

View File

@@ -31,25 +31,30 @@
/* u3 */
#define CMD_RD 0x02 /* Read in data from com line */
#define CMD_WR 0x01 /* Write data to com line */
#define CMD_RD 0x02 /* Read in data from com line */
#define CMD_NOP 0x03 /* Nop command */
#define CMD_DIAL 0x29 /* Dial call */
#define CMD_BRK 0x0D /* Send break signal */
#define CMD_PREP 0x06 /* Wait for incoming data */
#define CMD_INH 0x0A /* Read data without timeout */
#define CMD_BRK 0x0D /* Send break signal */
#define CMD_SRCH 0x0E /* Wait for EOT character */
#define CMD_ENB 0x27 /* Enable line */
#define CMD_DIAL 0x29 /* Dial call */
#define CMD_DIS 0x2F /* Disable line */
/* u3 second byte */
#define RECV 0x0100 /* Recieving data */
#define SEND 0x0200 /* Sending data */
#define ENAB 0x0400 /* Line enabled */
#define POLL 0x0800 /* Waiting for connection */
#define INPUT 0x1000 /* Need to send BOT */
#define RECV 0x00100 /* Recieving data */
#define SEND 0x00200 /* Sending data */
#define ENAB 0x00400 /* Line enabled */
#define POLL 0x00800 /* Waiting for connection */
#define ADDR 0x01000 /* Address request recieved. */
#define INPUT 0x02000 /* Input ready */
#define ATTN 0x04000 /* Send attention signal */
#define ADDR9 0x08000 /* Address char 9 recieved */
#define BYPASS 0x10000 /* Don't echo output */
#define BREAK 0x20000 /* Return unit exception */
/* u5 */
/* u4 */
/* Sense byte 0 */
#define SNS_CMDREJ 0x80 /* Command reject */
#define SNS_INTVENT 0x40 /* Unit intervention required */
@@ -60,7 +65,13 @@
#define SNS_RECV 0x02 /* Receiving */
#define SNS_TIMEOUT 0x01 /* Timeout */
/* u5 */
/* Where we are reading from */
#define IPTR u5
/* u6 */
/* Pointer into buffer */
#define BPTR u6
uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ;
uint8 coml_haltio(UNIT *uptr);
@@ -71,7 +82,6 @@ t_stat com_scan(UNIT *uptr);
t_stat com_attach(UNIT *uptr, CONST char *);
t_stat com_detach(UNIT *uptr);
uint8 com_buf[NUM_UNITS_COM][256];
int com_ptr[NUM_UNITS_COM];
TMLN com_ldsc[NUM_UNITS_COM];
TMXR com_desc = { NUM_UNITS_COM, 0, 0, com_ldsc};
@@ -147,7 +157,7 @@ static const uint8 com_2741_in[128] = {
/* sp ! " # $ % & ' */
0x81, 0xD7, 0x00, 0x16, 0x57, 0x8B, 0x61, 0x8D, /* 40 - 77 */
/* ( ) * + , - . / */
0x93, 0x94, 0x00, 0xE1, 0x37, 0xC0, 0x00, 0x23,
0x93, 0x95, 0x90, 0xE1, 0x37, 0xC0, 0x76, 0x23,
/* 0 1 2 3 4 5 6 7 */
0x15, 0x02, 0x04, 0x07, 0x08, 0x0B, 0x0D, 0x0E,
/* 8 9 : ; < = > ? */
@@ -200,7 +210,7 @@ static const uint8 com_2741_out[256] = {
/* 8, 9, A, B, C, D, E, F, */
'd', 0xff, 0xff, 'e', 0xff, 'f', 'g', 0xff,
/* 0, 1, 2, 3, 4, 5, 6, 7, */
'h', 0xff, 0xff, 'i', 0xff, 0xff, 0xff, 0xff, /* 0x7x */
'h', 0xff, 0xff, 'i', 0xff, 0xff, '.', 0xff, /* 0x7x */
/* 8, 9, A, B, C, D, E, F, */
0xff, 0xff, 0x09, 0xff, 0xff, 0xff, 0xff, 0x7f,
/* 0, 1, 2, 3, 4, 5, 6, 7, */
@@ -266,7 +276,7 @@ uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
}
break;
}
if (uptr->u5 & 0xff)
if (uptr->u4 & 0xff)
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
return SNS_CHNEND|SNS_DEVEND;
}
@@ -295,7 +305,7 @@ uint8 coml_haltio(UNIT *uptr) {
case CMD_BRK: /* Send break signal */
case CMD_PREP: /* Wait for incoming data */
case CMD_SRCH: /* Wait for EOT character */
uptr->u3 &= ~0xff;
uptr->u3 &= ~(ADDR9|ADDR|0xff);
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
case CMD_ENB: /* Enable line */
@@ -323,7 +333,7 @@ t_stat coml_srv(UNIT * uptr)
break;
case 0x4:
ch = uptr->u5 & 0xff;
ch = uptr->u4 & 0xff;
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch);
chan_write_byte(addr, &ch) ;
uptr->u3 &= ~0xff;
@@ -331,47 +341,76 @@ t_stat coml_srv(UNIT * uptr)
break;
case CMD_DIAL: /* Dial call */
uptr->u5 = SNS_CMDREJ;
uptr->u4 = SNS_CMDREJ;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
case CMD_INH: /* Read data without timeout */
case CMD_RD: /* Read in data from com line */
uptr->u4 = 0;
if (uptr->u3 & ENAB) {
if (tmxr_rqln(&com_ldsc[unit]) > 0) {
int32 data = tmxr_getc_ln (&com_ldsc[unit]);
sim_debug(DEBUG_DATA, dptr, "COML: unit=%d read '%c'\n", unit, data);
if (data & SCPE_BREAK) {
uptr->u3 &= ~0xff;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
} else {
ch = sim_tt_inpcvt (data, TT_GET_MODE(uptr->flags) |
TTUF_KSR);
ch = com_2741_in[data & 0x7f];
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d read '%c'\n", unit, data & 0x7f);
if (chan_write_byte( addr, &ch)) {
uptr->u3 &= ~0xff;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
return SCPE_OK;
}
if (ch == 0x5b) {
ch = 0x1f;
(void)chan_write_byte( addr, &ch);
uptr->u3 &= ~0xff;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
return SCPE_OK;
}
ch = sim_tt_outcvt(data, TT_GET_MODE(uptr->flags) | TTUF_KSR);
tmxr_putc_ln( &com_ldsc[unit], ch);
}
if (com_ldsc[unit].conn == 0) {
uptr->u3 &= ~(0xff|BREAK|INPUT|ENAB|POLL);
uptr->u4 = SNS_INTVENT;
uptr->BPTR = 0;
uptr->IPTR = 0;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
return SCPE_OK;
}
if (uptr->u3 & ADDR) {
ch = 0x16;
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d addr %02x\n", unit, ch);
uptr->u3 &= ~ADDR;
if (chan_write_byte( addr, &ch)) {
uptr->u3 &= ~(ADDR9|0xff);
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
return SCPE_OK;
}
if (uptr->u3 & ADDR9) {
uptr->u3 &= ~(ADDR9|0xff);
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d addr9 %02x\n", unit, ch);
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
return SCPE_OK;
}
} else if (uptr->u3 & BREAK) {
uptr->u3 &= ~(0xff|BREAK|INPUT);
uptr->u4 = SNS_INTVENT;
uptr->BPTR = 0;
uptr->IPTR = 0;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
return SCPE_OK;
} else if (uptr->u3 & INPUT) {
if (uptr->BPTR == uptr->IPTR) {
uptr->u3 &= ~(0xff|INPUT);
uptr->BPTR = 0;
uptr->IPTR = 0;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
return SCPE_OK;
}
ch = com_buf[unit][uptr->IPTR++];
if (chan_write_byte( addr, &ch)) {
uptr->u3 &= ~(0xff|INPUT);
uptr->IPTR = 0;
uptr->BPTR = 0;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
return SCPE_OK;
}
}
sim_activate(uptr, 200);
}
break;
case CMD_WR: /* Write data to com line */
uptr->u4 = 0;
if (uptr->u3 & ENAB) {
if (com_ldsc[unit].conn == 0) {
uptr->u3 &= ~(0xff|BREAK|INPUT|ENAB|POLL);
uptr->u4 = SNS_INTVENT;
uptr->BPTR = 0;
uptr->IPTR = 0;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
return SCPE_OK;
}
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d write\n", unit);
if (chan_read_byte (addr, &ch)) {
uptr->u3 &= ~0xff;
@@ -379,13 +418,23 @@ t_stat coml_srv(UNIT * uptr)
} else {
int32 data;
data = com_2741_out[ch];
if (data != 0xff) {
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d send %02x %02x '%c'\n",
unit, ch, data, isprint(data)? data: '^');
if (ch == 0x1f) { /* Check for address character */
uptr->u3 |= ADDR;
} else if (ch == 0x16) {
uptr->u3 &= ~ADDR;
} else if (ch == 0xb8) { /* Bypass */
uptr->u3 |= BYPASS;
} else if (ch == 0x58) { /* Restore */
uptr->u3 &= ~(BYPASS|ADDR|ADDR9);
} else if ((uptr->u3 & ADDR) != 0 && ch == 0x13) {
uptr->u3 |= ADDR9;
} else if ((uptr->u3 & ADDR) == 0 && data != 0xff) {
data = sim_tt_outcvt(data, TT_GET_MODE(uptr->flags) |
TTUF_KSR);
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d send '%c'\n",
unit, isprint(data)? data: '^');
tmxr_putc_ln( &com_ldsc[unit], data);
if (ch == 0x5b)
if (ch == 0x5b)
tmxr_putc_ln( &com_ldsc[unit], '\r');
}
sim_activate(uptr, 20000);
@@ -399,16 +448,26 @@ t_stat coml_srv(UNIT * uptr)
case CMD_BRK: /* Send break signal */
uptr->u3 &= ~0xff;
uptr->u4 = 0;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
case CMD_PREP: /* Wait for incoming data */
uptr->u4 = 0;
if (uptr->u3 & ENAB) {
if (tmxr_rqln(&com_ldsc[unit]) > 0) {
if (com_ldsc[unit].conn == 0) {
uptr->u3 &= ~(0xff|BREAK|INPUT|ENAB|POLL);
uptr->u4 = SNS_INTVENT;
uptr->BPTR = 0;
uptr->IPTR = 0;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
return SCPE_OK;
}
uptr->u3 &= ~(ADDR|ADDR9);
if (uptr->u3 & (INPUT|BREAK)) {
uptr->u3 &= ~0xff;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
} else {
uptr->u3 |= INPUT;
sim_activate(uptr, 200);
}
} else {
@@ -419,12 +478,16 @@ t_stat coml_srv(UNIT * uptr)
case CMD_SRCH: /* Wait for EOT character */
uptr->u3 &= ~0xff;
uptr->u4 = 0;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
case CMD_ENB: /* Enable line */
uptr->u4 = 0;
if ((uptr->u3 & (POLL|ENAB)) == ENAB) {
uptr->u3 &= ~0xff;
uptr->BPTR = 0;
uptr->IPTR = 0;
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d enable connect\n", unit);
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
} else if ((uptr->u3 & POLL) == 0) {
@@ -436,6 +499,7 @@ t_stat coml_srv(UNIT * uptr)
break;
case CMD_DIS: /* Disable line */
uptr->u4 = 0;
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d disable\n", unit);
(void)tmxr_set_get_modem_bits(&com_ldsc[unit], 0, TMXR_MDM_DTR, NULL);
(void)tmxr_reset_ln(&com_ldsc[unit]);
@@ -444,57 +508,70 @@ t_stat coml_srv(UNIT * uptr)
break;
}
#if 0
r = sim_poll_kbd();
if (r & SCPE_KFLAG) {
ch = r & 0377;
if ((uptr->u3 & INPUT) == 0) {
/* Handle end of buffer */
switch (ch) {
case '\r':
case '\n':
sim_debug(DEBUG_DATA, &con_dev, "%d: ent\n", u);
uptr->u3 &= ~INPUT;
tmxr_putc_ln( &com_ldsc[unit], '\r');
tmxr_putc_ln( &com_ldsc[unit], '\n');
break;
case 0177:
case '\b':
if (com_ptr[unit] != 0) {
com_ptr[unit].inptr--;
tmxr_putc_ln( &com_ldsc[unit], '\b');
tmxr_putc_ln( &com_ldsc[unit], ' ');
tmxr_putc_ln( &com_ldsc[unit], '\b');
if (uptr->u3 & ENAB) {
if (cmd == CMD_RD || cmd == CMD_PREP) {
if (tmxr_rqln(&com_ldsc[unit]) > 0) {
int32 data = tmxr_getc_ln (&com_ldsc[unit]);
ch = com_2741_in[data & 0x7f];
sim_debug(DEBUG_DATA, dptr, "COML: unit=%d read '%c' %02x\n", unit, data, ch);
if (data & SCPE_BREAK) {
uptr->u3 |= BREAK;
return SCPE_OK;
}
break;
case 03: /* ^C */
case 025: /* ^U clear line */
for (i = com_ptr[unit]; i> 0; i--) {
tmxr_putc_ln( &com_ldsc[unit], '\b');
tmxr_putc_ln( &com_ldsc[unit], ' ');
tmxr_putc_ln( &com_ldsc[unit], '\b');
}
com_ptr[unit].inptr = 0;
break;
/* Handle end of buffer */
switch (data & 0x7f) {
case '\r':
case '\n':
com_buf[unit][uptr->BPTR++] = 0x5b;
com_buf[unit][uptr->BPTR++] = 0x1f;
uptr->u3 |= INPUT;
uptr->IPTR = 0;
tmxr_putc_ln( &com_ldsc[unit], '\r');
tmxr_putc_ln( &com_ldsc[unit], '\n');
break;
default:
sim_debug(DEBUG_DATA, &con_dev, "%d: key '%c'\n", u, ch);
if (com_ptr[unit] < 256) {
ch = com_2741_in[ch & 0x7f];
if (ch == 0xff) {
sim_putchar('\007');
break;
}
com_buf[unit][com_ptr[unit]++] = ch;
ch = com_2741_out[ch];
tmxr_putc_ln( &com_ldsc[unit], ch);
}
}
} else {
tmxr_putc_ln( &com_ldsc[unit], '\07');
case 0177:
case '\b':
if (uptr->BPTR != 0) {
uptr->BPTR--;
tmxr_putc_ln( &com_ldsc[unit], '\b');
tmxr_putc_ln( &com_ldsc[unit], ' ');
tmxr_putc_ln( &com_ldsc[unit], '\b');
}
break;
case 025: /* ^U clear line */
while(uptr->BPTR > 0) {
tmxr_putc_ln( &com_ldsc[unit], '\b');
tmxr_putc_ln( &com_ldsc[unit], ' ');
tmxr_putc_ln( &com_ldsc[unit], '\b');
uptr->BPTR--;
}
break;
case 03: /* ^C */
uptr->u3 |= BREAK;
break;
default:
if (uptr->BPTR < 253) {
if (ch == 0x00) {
sim_putchar('\007');
} else {
com_buf[unit][uptr->BPTR++] = ch;
if ((uptr->u3 & BYPASS) == 0)
tmxr_putc_ln( &com_ldsc[unit], data);
}
} else {
com_buf[unit][uptr->BPTR++] = 0x5b;
com_buf[unit][uptr->BPTR++] = 0x1f;
uptr->u3 |= INPUT;
uptr->BPTR &= 0xff;
}
}
}
}
}
#endif
return SCPE_OK;
}

View File

@@ -1446,12 +1446,12 @@ opr:
break;
ext_en = (src1 & 01) != 0;
if (ec_mode) {
irq_en = (src1 & 02) != 0;
if ((cpu_unit[0].flags & FEAT_370) != 0) {
if (src1 & 0xb8) {
storepsw(OPPSW, IRC_SPEC);
break;
}
irq_en = (src1 & 02) != 0;
per_en = ((src1 & 0x40) != 0);
dat_en = (src1 & 04) != 0;
sysmsk = irq_en ? (cregs[2] >> 16) : 0;
@@ -1460,6 +1460,7 @@ opr:
storepsw(OPPSW, IRC_SPEC);
else
dat_en = (src1 & 04) != 0;
irq_en = (src1 & 02) != 0;
sysmsk = irq_en ? (cregs[6] >> 16) : 0;
}
} else {
@@ -2794,7 +2795,6 @@ save_dbl:
if (dest < src1h)
src1++;
src1h = dest & ~0xfff;
//fprintf(stderr, "Store tod %08x %08x %d %08x %08x\r\n", tod_clock[0], tod_clock[1], (int)us, src1, src1h);
}
if (WriteFull(addr1, src1))
goto supress;
@@ -2830,9 +2830,7 @@ save_dbl:
if (sim_is_active(&cpu_unit[0])) {
double nus = sim_activate_time_usecs(&cpu_unit[0]);
timer_tics = (int)(nus);
//fprintf(stderr, "Set timer %08x %08x %g%d\r\n", cpu_timer[0], cpu_timer[1], nus,timer_tics);
}
//fprintf(stderr, "Set timer %08x %08x %d\r\n", cpu_timer[0], cpu_timer[1], timer_tics);
clk_irq = (cpu_timer[0] & MSIGN) != 0;
break;
case 0x9: /* STPT */
@@ -2847,7 +2845,6 @@ save_dbl:
src1--;
}
src1h = dest;
//fprintf(stderr, "Store timer %08x %08x %d %g %d %08x %08x\r\n", cpu_timer[0], cpu_timer[1], timer_tics, nus, tics, src1, src1h );
}
if (WriteFull(addr1, src1))
goto supress;
@@ -2875,7 +2872,6 @@ save_dbl:
}
for (temp = 0; temp < 256; temp++)
tlb[temp] = 0;
//fprintf(stderr, "purge tlb\r\n");
break;
case 0x10: /* SPX */
storepsw(OPPSW, IRC_OPR);
@@ -2902,6 +2898,7 @@ save_dbl:
goto supress;
}
break;
case OP_STNSM:
if ((cpu_unit[0].flags & FEAT_370) != 0) {
if (flags & PROBLEM) {
@@ -2946,6 +2943,7 @@ save_dbl:
goto supress;
}
break;
case OP_STOSM:
if ((cpu_unit[0].flags & FEAT_370) != 0) {
if (flags & PROBLEM) {
@@ -2990,6 +2988,7 @@ save_dbl:
goto supress;
}
break;
case OP_SIGP:
if ((cpu_unit[0].flags & FEAT_370) != 0) {
if (flags & PROBLEM) {
@@ -2999,6 +2998,7 @@ save_dbl:
}
storepsw(OPPSW, IRC_OPR);
goto supress;
case OP_MC:
if ((cpu_unit[0].flags & FEAT_370) != 0) {
if ((reg & 0xf0) != 0) {
@@ -3032,9 +3032,9 @@ save_dbl:
if (ReadFull(addr1, &dest))
goto supress;
cregs[reg1] = dest;
sim_debug(DEBUG_INST, &cpu_dev,"Loading: CR %x %06x %08x IC=%08x %x\n\r",
reg1, addr1, dest, PC, reg);
//fprintf(stderr, "Loading: CR %x %06x %08x IC=%08x %x\n\r", reg1, addr1, dest, PC, reg);
sim_debug(DEBUG_INST, &cpu_dev,
"Loading: CR %x %06x %08x IC=%08x %x\n\r",
reg1, addr1, dest, PC, reg);
switch (reg1) {
case 0x0: /* General controll register */
/* CR0 values
@@ -3047,7 +3047,7 @@ save_dbl:
page_shift = 0;
seg_shift = 0;
switch((dest >> 22) & 03) {
default: /* Generate translation exception */
default: /* Generate translation exception */
case 1: /* 2K pages */
page_shift = 11;
page_mask = 0x7ff;
@@ -3186,6 +3186,7 @@ save_dbl:
}
}
break;
case OP_SRP:
if ((cpu_unit[0].flags & FEAT_370) == 0) {
storepsw(OPPSW, IRC_OPR);
@@ -3197,6 +3198,7 @@ save_dbl:
dec_srp(op, addr1, reg1, addr2, reg & 0xf);
}
break;
case OP_MVCL:
if ((cpu_unit[0].flags & FEAT_370) == 0) {
storepsw(OPPSW, IRC_OPR);
@@ -3256,6 +3258,7 @@ save_dbl:
cc = 1;
}
break;
case OP_CLCL:
if ((cpu_unit[0].flags & FEAT_370) == 0) {
storepsw(OPPSW, IRC_OPR);