mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-23 02:47:57 +00:00
IBM360: Code cleanup.
This commit is contained in:
parent
b5837f5b49
commit
ea936a5c89
@ -1,6 +1,6 @@
|
||||
/* ibm360_cdp.c: IBM 360 Card Punch
|
||||
|
||||
Copyright (c) 2017, Richard Cornwell
|
||||
Copyright (c) 2017-2020, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -48,6 +48,9 @@
|
||||
#define CDP_WR 0x01 /* Punch command */
|
||||
#define CDP_CARD 0x100 /* Unit has card in buffer */
|
||||
|
||||
/* Upper 11 bits of u3 hold the device address */
|
||||
|
||||
/* u4 holds current column, */
|
||||
|
||||
/* in u5 packs sense byte 0,1 and 3 */
|
||||
/* Sense byte 0 */
|
||||
@ -60,6 +63,10 @@
|
||||
#define SNS_SEQUENCE 0x02 /* Unusual sequence */
|
||||
#define SNS_CHN9 0x01 /* Channel 9 on printer */
|
||||
|
||||
#define CMD u3
|
||||
#define COL u4
|
||||
#define SNS u5
|
||||
|
||||
|
||||
|
||||
/* std devices. data structures
|
||||
@ -122,7 +129,7 @@ uint8 cdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
|
||||
if ((uptr->u3 & (CDP_CARD|CDP_CMDMSK)) != 0) {
|
||||
if ((uptr->CMD & (CDP_CARD|CDP_CMDMSK)) != 0) {
|
||||
if ((uptr->flags & UNIT_ATT) != 0)
|
||||
return SNS_BSY;
|
||||
return SNS_DEVEND|SNS_UNITCHK;
|
||||
@ -131,16 +138,16 @@ uint8 cdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %x\n", unit, cmd);
|
||||
switch (cmd & 0x7) {
|
||||
case 1: /* Write command */
|
||||
uptr->u3 &= ~(CDP_CMDMSK);
|
||||
uptr->u3 |= (cmd & CDP_CMDMSK);
|
||||
uptr->CMD &= ~(CDP_CMDMSK);
|
||||
uptr->CMD |= (cmd & CDP_CMDMSK);
|
||||
sim_activate(uptr, 10); /* Start unit off */
|
||||
uptr->u4 = 0;
|
||||
uptr->u5 = 0;
|
||||
uptr->COL = 0;
|
||||
uptr->SNS = 0;
|
||||
return 0;
|
||||
|
||||
case 3:
|
||||
if (cmd != 0x3) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
@ -149,16 +156,16 @@ uint8 cdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
break;
|
||||
|
||||
case 4: /* Sense */
|
||||
uptr->u3 &= ~(CDP_CMDMSK);
|
||||
uptr->u3 |= (cmd & CDP_CMDMSK);
|
||||
uptr->CMD &= ~(CDP_CMDMSK);
|
||||
uptr->CMD |= (cmd & CDP_CMDMSK);
|
||||
sim_activate(uptr, 10);
|
||||
return 0;
|
||||
|
||||
default: /* invalid command */
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
break;
|
||||
}
|
||||
if (uptr->u5 & 0xff)
|
||||
if (uptr->SNS & 0xff)
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
}
|
||||
@ -169,19 +176,19 @@ t_stat
|
||||
cdp_srv(UNIT *uptr) {
|
||||
int u = uptr-cdp_unit;
|
||||
uint16 *image = (uint16 *)(uptr->up7);
|
||||
uint16 addr = GET_UADDR(uptr->u3);
|
||||
uint16 addr = GET_UADDR(uptr->CMD);
|
||||
|
||||
/* Handle sense */
|
||||
if ((uptr->u3 & CDP_CMDMSK) == 0x4) {
|
||||
uint8 ch = uptr->u5;
|
||||
if ((uptr->CMD & CDP_CMDMSK) == 0x4) {
|
||||
uint8 ch = uptr->SNS;
|
||||
chan_write_byte(addr, &ch);
|
||||
chan_end(addr, SNS_DEVEND|SNS_CHNEND);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (uptr->u3 & CDP_CARD) {
|
||||
if (uptr->CMD & CDP_CARD) {
|
||||
/* Done waiting, punch card */
|
||||
uptr->u3 &= ~CDP_CARD;
|
||||
uptr->CMD &= ~CDP_CARD;
|
||||
sim_debug(DEBUG_DETAIL, &cdp_dev, "unit=%d:punch\n", u);
|
||||
switch(sim_punch_card(uptr, image)) {
|
||||
/* If we get here, something is wrong */
|
||||
@ -197,20 +204,20 @@ cdp_srv(UNIT *uptr) {
|
||||
}
|
||||
|
||||
/* Copy next column over */
|
||||
if (uptr->u4 < 80) {
|
||||
if (uptr->COL < 80) {
|
||||
uint8 ch = 0;
|
||||
|
||||
if (chan_read_byte(addr, &ch)) {
|
||||
uptr->u3 |= CDP_CARD;
|
||||
uptr->CMD |= CDP_CARD;
|
||||
} else {
|
||||
sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o\n", u, ch);
|
||||
image[uptr->u4++] = sim_ebcdic_to_hol(ch);
|
||||
if (uptr->u4 == 80) {
|
||||
uptr->u3 |= CDP_CARD;
|
||||
image[uptr->COL++] = sim_ebcdic_to_hol(ch);
|
||||
if (uptr->COL == 80) {
|
||||
uptr->CMD |= CDP_CARD;
|
||||
}
|
||||
}
|
||||
if (uptr->u3 & CDP_CARD) {
|
||||
uptr->u3 &= ~(CDP_CMDMSK);
|
||||
if (uptr->CMD & CDP_CARD) {
|
||||
uptr->CMD &= ~(CDP_CMDMSK);
|
||||
chan_end(addr, SNS_CHNEND);
|
||||
sim_activate(uptr, 10000);
|
||||
} else
|
||||
@ -229,7 +236,7 @@ cdp_attach(UNIT * uptr, CONST char *file)
|
||||
return r;
|
||||
if (uptr->up7 == 0) {
|
||||
uptr->up7 = calloc(80, sizeof(uint16));
|
||||
uptr->u5 = 0;
|
||||
uptr->SNS = 0;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
@ -239,7 +246,7 @@ cdp_detach(UNIT * uptr)
|
||||
{
|
||||
uint16 *image = (uint16 *)(uptr->up7);
|
||||
|
||||
if (uptr->u5 & CDP_CARD)
|
||||
if (uptr->SNS & CDP_CARD)
|
||||
sim_punch_card(uptr, image);
|
||||
if (uptr->up7 != 0)
|
||||
free(uptr->up7);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* ibm360_cdr.c: IBM 360 Card Reader.
|
||||
|
||||
Copyright (c) 2017, Richard Cornwell
|
||||
Copyright (c) 2017-2020, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -48,6 +48,9 @@
|
||||
#define CDP_WR 0x09 /* Punch command */
|
||||
#define CDR_CARD 0x100 /* Unit has card in buffer */
|
||||
|
||||
/* Upper 11 bits of u3 hold the device address */
|
||||
|
||||
/* u4 holds current column, */
|
||||
|
||||
/* in u5 packs sense byte 0,1 and 3 */
|
||||
/* Sense byte 0 */
|
||||
@ -60,6 +63,9 @@
|
||||
#define SNS_SEQUENCE 0x02 /* Unusual sequence */
|
||||
#define SNS_CHN9 0x01 /* Channel 9 on printer */
|
||||
|
||||
#define CMD u3
|
||||
#define COL u4
|
||||
#define SNS u5
|
||||
|
||||
|
||||
/* std devices. data structures
|
||||
@ -71,8 +77,6 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
uint8 cdr_startcmd(UNIT *, uint16, uint8);
|
||||
t_stat cdr_boot(int32, DEVICE *);
|
||||
t_stat cdr_srv(UNIT *);
|
||||
@ -117,7 +121,7 @@ uint8 cdr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
|
||||
if ((uptr->u3 & CDR_CMDMSK) != 0) {
|
||||
if ((uptr->CMD & CDR_CMDMSK) != 0) {
|
||||
if ((uptr->flags & UNIT_ATT) != 0)
|
||||
return SNS_BSY;
|
||||
return SNS_DEVEND;
|
||||
@ -126,36 +130,36 @@ uint8 cdr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %x\n", unit, cmd);
|
||||
if (cmd != 4 && sim_card_eof(uptr) == 1) {
|
||||
uint16 *image = (uint16 *)(uptr->up7);
|
||||
uptr->u5 = SNS_INTVENT;
|
||||
uptr->SNS = SNS_INTVENT;
|
||||
sim_read_card(uptr, image); /* Read in the EOF */
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
if (cmd != 4 && (uptr->flags & UNIT_ATT) == 0) {
|
||||
uptr->u5 = SNS_INTVENT;
|
||||
uptr->SNS = SNS_INTVENT;
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
switch (cmd & 0x7) {
|
||||
case 2: /* Read command */
|
||||
if ((cmd & 0xc0) != 0xc0)
|
||||
uptr->u3 &= ~CDR_CARD;
|
||||
uptr->u3 &= ~(CDR_CMDMSK);
|
||||
uptr->u3 |= (cmd & CDR_CMDMSK);
|
||||
uptr->CMD &= ~CDR_CARD;
|
||||
uptr->CMD &= ~(CDR_CMDMSK);
|
||||
uptr->CMD |= (cmd & CDR_CMDMSK);
|
||||
sim_activate(uptr, 1000); /* Start unit off */
|
||||
uptr->u4 = 0;
|
||||
uptr->u5 = 0;
|
||||
uptr->COL = 0;
|
||||
uptr->SNS = 0;
|
||||
return 0;
|
||||
|
||||
case 3: /* Control */
|
||||
uptr->u5 = 0;
|
||||
uptr->u3 &= ~(CDR_CMDMSK|CDR_CARD);
|
||||
uptr->SNS = 0;
|
||||
uptr->CMD &= ~(CDR_CMDMSK|CDR_CARD);
|
||||
if (cmd == 0x3)
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
if ((cmd & 0x30) != 0x20 || (cmd & 0xc0) == 0xc0) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
uptr->u3 |= (cmd & CDR_CMDMSK);
|
||||
uptr->u4 = 0;
|
||||
uptr->CMD |= (cmd & CDR_CMDMSK);
|
||||
uptr->COL = 0;
|
||||
sim_activate(uptr, 1000); /* Start unit off */
|
||||
return 0;
|
||||
|
||||
@ -163,17 +167,17 @@ uint8 cdr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
break;
|
||||
|
||||
case 4: /* Sense */
|
||||
uptr->u3 &= ~(CDR_CMDMSK);
|
||||
uptr->u3 |= (cmd & CDR_CMDMSK);
|
||||
uptr->CMD &= ~(CDR_CMDMSK);
|
||||
uptr->CMD |= (cmd & CDR_CMDMSK);
|
||||
sim_activate(uptr, 10);
|
||||
return 0;
|
||||
|
||||
default: /* invalid command */
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uptr->u5)
|
||||
if (uptr->SNS)
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
}
|
||||
@ -181,38 +185,38 @@ uint8 cdr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
/* Handle transfer of data for card reader */
|
||||
t_stat
|
||||
cdr_srv(UNIT *uptr) {
|
||||
int addr = GET_UADDR(uptr->u3);
|
||||
int addr = GET_UADDR(uptr->CMD);
|
||||
uint16 *image = (uint16 *)(uptr->up7);
|
||||
|
||||
if ((uptr->u3 & CDR_CMDMSK) == CHN_SNS) {
|
||||
uint8 ch = uptr->u5;
|
||||
if ((uptr->CMD & CDR_CMDMSK) == CHN_SNS) {
|
||||
uint8 ch = uptr->SNS;
|
||||
if (ch == 0 && (uptr->flags & UNIT_ATT) == 0)
|
||||
ch = SNS_INTVENT;
|
||||
chan_write_byte(addr, &ch);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
uptr->u3 &= ~(CDR_CMDMSK);
|
||||
uptr->CMD &= ~(CDR_CMDMSK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Check if new card requested. */
|
||||
if ((uptr->u3 & CDR_CARD) == 0) {
|
||||
if ((uptr->CMD & CDR_CARD) == 0) {
|
||||
switch(sim_read_card(uptr, image)) {
|
||||
case CDSE_EMPTY:
|
||||
uptr->u5 = SNS_INTVENT;
|
||||
uptr->SNS = SNS_INTVENT;
|
||||
case CDSE_EOF:
|
||||
uptr->u3 &= ~CDR_CMDMSK;
|
||||
uptr->CMD &= ~CDR_CMDMSK;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
return SCPE_OK;
|
||||
case CDSE_ERROR:
|
||||
uptr->u5 = SNS_INTVENT;
|
||||
uptr->u3 &= ~CDR_CMDMSK;
|
||||
uptr->SNS = SNS_INTVENT;
|
||||
uptr->CMD &= ~CDR_CMDMSK;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
case CDSE_OK:
|
||||
uptr->u3 |= CDR_CARD;
|
||||
if ((uptr->u3 & CDR_CMDMSK) == CDR_FEED) {
|
||||
uptr->CMD |= CDR_CARD;
|
||||
if ((uptr->CMD & CDR_CMDMSK) == CDR_FEED) {
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
uptr->u3 &= ~(CDR_CMDMSK);
|
||||
uptr->CMD &= ~(CDR_CMDMSK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
break;
|
||||
@ -220,29 +224,29 @@ cdr_srv(UNIT *uptr) {
|
||||
}
|
||||
|
||||
/* Copy next column over */
|
||||
if ((uptr->u3 & CDR_CMDMSK) == CDR_RD) {
|
||||
if ((uptr->CMD & CDR_CMDMSK) == CDR_RD) {
|
||||
int u = uptr-cdr_unit;
|
||||
uint16 xlat;
|
||||
uint8 ch = 0;
|
||||
|
||||
xlat = sim_hol_to_ebcdic(image[uptr->u4]);
|
||||
xlat = sim_hol_to_ebcdic(image[uptr->COL]);
|
||||
|
||||
if (xlat == 0x100) {
|
||||
uptr->u5 |= SNS_DATCHK;
|
||||
uptr->SNS |= SNS_DATCHK;
|
||||
ch = 0x00;
|
||||
} else
|
||||
ch = (uint8)(xlat&0xff);
|
||||
if (chan_write_byte(addr, &ch)) {
|
||||
uptr->u3 &= ~(CDR_CMDMSK);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|(uptr->u5 ? SNS_UNITCHK:0));
|
||||
uptr->CMD &= ~(CDR_CMDMSK);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|(uptr->SNS ? SNS_UNITCHK:0));
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
uptr->u4++;
|
||||
uptr->COL++;
|
||||
sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %02o\n", u, ch);
|
||||
}
|
||||
if (uptr->u4 == 80) {
|
||||
uptr->u3 &= ~(CDR_CMDMSK);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|(uptr->u5 ? SNS_UNITCHK:0));
|
||||
if (uptr->COL == 80) {
|
||||
uptr->CMD &= ~(CDR_CMDMSK);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|(uptr->SNS ? SNS_UNITCHK:0));
|
||||
}
|
||||
sim_activate(uptr, 10);
|
||||
}
|
||||
@ -257,13 +261,13 @@ cdr_boot(int32 unit_num, DEVICE * dptr)
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
return chan_boot(GET_UADDR(uptr->u3), dptr);
|
||||
return chan_boot(GET_UADDR(uptr->CMD), dptr);
|
||||
}
|
||||
|
||||
t_stat
|
||||
cdr_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
int addr = GET_UADDR(uptr->u3);
|
||||
int addr = GET_UADDR(uptr->CMD);
|
||||
t_stat r;
|
||||
|
||||
if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
|
||||
@ -271,8 +275,8 @@ cdr_attach(UNIT * uptr, CONST char *file)
|
||||
if (uptr->up7 == 0)
|
||||
uptr->up7 = malloc(sizeof(uint16)*80);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
uptr->u3 &= ~(CDR_CARD);
|
||||
uptr->u4 = 0;
|
||||
uptr->CMD &= ~(CDR_CARD);
|
||||
uptr->COL = 0;
|
||||
uptr->u6 = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
@ -283,7 +287,7 @@ cdr_detach(UNIT * uptr)
|
||||
if (uptr->up7 != 0)
|
||||
free(uptr->up7);
|
||||
uptr->up7 = 0;
|
||||
uptr->u5 = 0;
|
||||
uptr->SNS = 0;
|
||||
return sim_card_detach(uptr);
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* ibm360_chan.c: IBM 360 Channel functions.
|
||||
|
||||
Copyright (c) 2017, Richard Cornwell
|
||||
Copyright (c) 2017-2020, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* ibm360_com.c: IBM 360 2703 communications controller
|
||||
|
||||
Copyright (c) 2017, Richard Cornwell
|
||||
Copyright (c) 2017-2020, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -54,7 +54,12 @@
|
||||
#define BYPASS 0x10000 /* Don't echo output */
|
||||
#define BREAK 0x20000 /* Return unit exception */
|
||||
|
||||
/* Upper 11 bits of u3 hold the device address */
|
||||
|
||||
/* u4 */
|
||||
/* Where we are reading from */
|
||||
|
||||
/* u5 */
|
||||
/* Sense byte 0 */
|
||||
#define SNS_CMDREJ 0x80 /* Command reject */
|
||||
#define SNS_INTVENT 0x40 /* Unit intervention required */
|
||||
@ -65,12 +70,12 @@
|
||||
#define SNS_RECV 0x02 /* Receiving */
|
||||
#define SNS_TIMEOUT 0x01 /* Timeout */
|
||||
|
||||
/* u5 */
|
||||
/* Where we are reading from */
|
||||
#define IPTR u5
|
||||
|
||||
/* u6 */
|
||||
/* Pointer into buffer */
|
||||
|
||||
#define CMD u3
|
||||
#define IPTR u4
|
||||
#define SNS u5
|
||||
#define BPTR u6
|
||||
|
||||
uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ;
|
||||
@ -248,12 +253,12 @@ static const uint8 com_2741_out[256] = {
|
||||
};
|
||||
|
||||
uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
uint16 addr = GET_UADDR(uptr->u3);
|
||||
uint16 addr = GET_UADDR(uptr->CMD);
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %x\n", unit, cmd);
|
||||
if ((uptr->u3 & 0xff) != 0) {
|
||||
if ((uptr->CMD & 0xff) != 0) {
|
||||
return SNS_BSY;
|
||||
}
|
||||
|
||||
@ -264,29 +269,29 @@ uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
case 0x2: /* Read command */
|
||||
case 0x1: /* Write command */
|
||||
uptr->u3 |= cmd;
|
||||
uptr->u4 = 0;
|
||||
uptr->CMD |= cmd;
|
||||
uptr->SNS = 0;
|
||||
sim_activate(uptr, 200);
|
||||
return 0;
|
||||
|
||||
case 0x0: /* Status */
|
||||
if (cmd == 0x4) { /* Sense */
|
||||
uptr->u3 |= cmd;
|
||||
uptr->CMD |= cmd;
|
||||
sim_activate(uptr, 200);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (uptr->u4 & 0xff)
|
||||
if (uptr->SNS & 0xff)
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
}
|
||||
|
||||
uint8 coml_haltio(UNIT *uptr) {
|
||||
uint16 addr = GET_UADDR(uptr->u3);
|
||||
uint16 addr = GET_UADDR(uptr->CMD);
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
int cmd = uptr->u3 & 0xff;
|
||||
int cmd = uptr->CMD & 0xff;
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr, "HLTIO unit=%d %x\n", unit, cmd);
|
||||
if ((com_unit[0].flags & UNIT_ATT) == 0) /* attached? */
|
||||
@ -306,14 +311,14 @@ 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 &= ~(ADDR9|ADDR|0xff);
|
||||
uptr->CMD &= ~(ADDR9|ADDR|0xff);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
case CMD_ENB: /* Enable line */
|
||||
/* Terminate the operation */
|
||||
(void)tmxr_set_get_modem_bits(&com_ldsc[unit], 0, TMXR_MDM_DTR, NULL);
|
||||
(void)tmxr_reset_ln(&com_ldsc[unit]);
|
||||
uptr->u3 &= ~0xffff;
|
||||
uptr->CMD &= ~0xffff;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
@ -322,10 +327,10 @@ uint8 coml_haltio(UNIT *uptr) {
|
||||
/* Handle per unit commands */
|
||||
t_stat coml_srv(UNIT * uptr)
|
||||
{
|
||||
uint16 addr = GET_UADDR(uptr->u3);
|
||||
uint16 addr = GET_UADDR(uptr->CMD);
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
int cmd = uptr->u3 & 0xff;
|
||||
int cmd = uptr->CMD & 0xff;
|
||||
uint8 ch;
|
||||
|
||||
|
||||
@ -334,55 +339,55 @@ t_stat coml_srv(UNIT * uptr)
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
ch = uptr->u4 & 0xff;
|
||||
ch = uptr->SNS & 0xff;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch);
|
||||
chan_write_byte(addr, &ch) ;
|
||||
uptr->u3 &= ~0xff;
|
||||
uptr->CMD &= ~0xff;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
|
||||
case CMD_DIAL: /* Dial call */
|
||||
uptr->u4 = SNS_CMDREJ;
|
||||
uptr->SNS = 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) {
|
||||
uptr->SNS = 0;
|
||||
if (uptr->CMD & ENAB) {
|
||||
if (com_ldsc[unit].conn == 0) {
|
||||
uptr->u3 &= ~(0xff|BREAK|INPUT|ENAB|POLL);
|
||||
uptr->u4 = SNS_INTVENT;
|
||||
uptr->CMD &= ~(0xff|BREAK|INPUT|ENAB|POLL);
|
||||
uptr->SNS = SNS_INTVENT;
|
||||
uptr->BPTR = 0;
|
||||
uptr->IPTR = 0;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (uptr->u3 & ADDR) {
|
||||
if (uptr->CMD & ADDR) {
|
||||
ch = 0x16;
|
||||
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d addr %02x\n", unit, ch);
|
||||
uptr->u3 &= ~ADDR;
|
||||
uptr->CMD &= ~ADDR;
|
||||
if (chan_write_byte( addr, &ch)) {
|
||||
uptr->u3 &= ~(ADDR9|0xff);
|
||||
uptr->CMD &= ~(ADDR9|0xff);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (uptr->u3 & ADDR9) {
|
||||
uptr->u3 &= ~(ADDR9|0xff);
|
||||
if (uptr->CMD & ADDR9) {
|
||||
uptr->CMD &= ~(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;
|
||||
} else if (uptr->CMD & BREAK) {
|
||||
uptr->CMD &= ~(0xff|BREAK|INPUT);
|
||||
uptr->SNS = 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) {
|
||||
} else if (uptr->CMD & INPUT) {
|
||||
if (uptr->BPTR == uptr->IPTR) {
|
||||
uptr->u3 &= ~(0xff|INPUT);
|
||||
uptr->CMD &= ~(0xff|INPUT);
|
||||
uptr->BPTR = 0;
|
||||
uptr->IPTR = 0;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
@ -390,7 +395,7 @@ t_stat coml_srv(UNIT * uptr)
|
||||
}
|
||||
ch = com_buf[unit][uptr->IPTR++];
|
||||
if (chan_write_byte( addr, &ch)) {
|
||||
uptr->u3 &= ~(0xff|INPUT);
|
||||
uptr->CMD &= ~(0xff|INPUT);
|
||||
uptr->IPTR = 0;
|
||||
uptr->BPTR = 0;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
@ -402,11 +407,11 @@ t_stat coml_srv(UNIT * uptr)
|
||||
break;
|
||||
|
||||
case CMD_WR: /* Write data to com line */
|
||||
uptr->u4 = 0;
|
||||
if (uptr->u3 & ENAB) {
|
||||
uptr->SNS = 0;
|
||||
if (uptr->CMD & ENAB) {
|
||||
if (com_ldsc[unit].conn == 0) {
|
||||
uptr->u3 &= ~(0xff|BREAK|INPUT|ENAB|POLL);
|
||||
uptr->u4 = SNS_INTVENT;
|
||||
uptr->CMD &= ~(0xff|BREAK|INPUT|ENAB|POLL);
|
||||
uptr->SNS = SNS_INTVENT;
|
||||
uptr->BPTR = 0;
|
||||
uptr->IPTR = 0;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
@ -414,7 +419,7 @@ t_stat coml_srv(UNIT * uptr)
|
||||
}
|
||||
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d write\n", unit);
|
||||
if (chan_read_byte (addr, &ch)) {
|
||||
uptr->u3 &= ~0xff;
|
||||
uptr->CMD &= ~0xff;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
} else {
|
||||
int32 data;
|
||||
@ -422,16 +427,16 @@ t_stat coml_srv(UNIT * uptr)
|
||||
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;
|
||||
uptr->CMD |= ADDR;
|
||||
} else if (ch == 0x16) {
|
||||
uptr->u3 &= ~ADDR;
|
||||
uptr->CMD &= ~ADDR;
|
||||
} else if (ch == 0xb8) { /* Bypass */
|
||||
uptr->u3 |= BYPASS;
|
||||
uptr->CMD |= 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) {
|
||||
uptr->CMD &= ~(BYPASS|ADDR|ADDR9);
|
||||
} else if ((uptr->CMD & ADDR) != 0 && ch == 0x13) {
|
||||
uptr->CMD |= ADDR9;
|
||||
} else if ((uptr->CMD & ADDR) == 0 && data != 0xff) {
|
||||
data = sim_tt_outcvt(data, TT_GET_MODE(uptr->flags) |
|
||||
TTUF_KSR);
|
||||
tmxr_putc_ln( &com_ldsc[unit], data);
|
||||
@ -442,81 +447,81 @@ t_stat coml_srv(UNIT * uptr)
|
||||
}
|
||||
} else {
|
||||
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d write error\n", unit);
|
||||
uptr->u3 &= ~0xff;
|
||||
uptr->CMD &= ~0xff;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_BRK: /* Send break signal */
|
||||
uptr->u3 &= ~0xff;
|
||||
uptr->u4 = 0;
|
||||
uptr->CMD &= ~0xff;
|
||||
uptr->SNS = 0;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
|
||||
case CMD_PREP: /* Wait for incoming data */
|
||||
uptr->u4 = 0;
|
||||
if (uptr->u3 & ENAB) {
|
||||
uptr->SNS = 0;
|
||||
if (uptr->CMD & ENAB) {
|
||||
if (com_ldsc[unit].conn == 0) {
|
||||
uptr->u3 &= ~(0xff|BREAK|INPUT|ENAB|POLL);
|
||||
uptr->u4 = SNS_INTVENT;
|
||||
uptr->CMD &= ~(0xff|BREAK|INPUT|ENAB|POLL);
|
||||
uptr->SNS = 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;
|
||||
uptr->CMD &= ~(ADDR|ADDR9);
|
||||
if (uptr->CMD & (INPUT|BREAK)) {
|
||||
uptr->CMD &= ~0xff;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
} else {
|
||||
sim_activate(uptr, 200);
|
||||
}
|
||||
} else {
|
||||
uptr->u3 &= ~0xff;
|
||||
uptr->CMD &= ~0xff;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_SRCH: /* Wait for EOT character */
|
||||
uptr->u3 &= ~0xff;
|
||||
uptr->u4 = 0;
|
||||
uptr->CMD &= ~0xff;
|
||||
uptr->SNS = 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->SNS = 0;
|
||||
if ((uptr->CMD & (POLL|ENAB)) == ENAB) {
|
||||
uptr->CMD &= ~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) {
|
||||
} else if ((uptr->CMD & POLL) == 0) {
|
||||
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d enable\n", unit);
|
||||
(void)tmxr_set_get_modem_bits(&com_ldsc[unit], TMXR_MDM_DTR,
|
||||
0, NULL);
|
||||
uptr->u3 |= POLL;
|
||||
uptr->CMD |= POLL;
|
||||
}
|
||||
break;
|
||||
|
||||
case CMD_DIS: /* Disable line */
|
||||
uptr->u4 = 0;
|
||||
uptr->SNS = 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]);
|
||||
uptr->u3 &= ~(0xff|POLL|ENAB) ;
|
||||
uptr->CMD &= ~(0xff|POLL|ENAB) ;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
}
|
||||
|
||||
if (uptr->u3 & ENAB) {
|
||||
if (uptr->CMD & 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;
|
||||
uptr->CMD |= BREAK;
|
||||
return SCPE_OK;
|
||||
}
|
||||
/* Handle end of buffer */
|
||||
@ -525,7 +530,7 @@ t_stat coml_srv(UNIT * uptr)
|
||||
case '\n':
|
||||
com_buf[unit][uptr->BPTR++] = 0x5b;
|
||||
com_buf[unit][uptr->BPTR++] = 0x1f;
|
||||
uptr->u3 |= INPUT;
|
||||
uptr->CMD |= INPUT;
|
||||
uptr->IPTR = 0;
|
||||
tmxr_putc_ln( &com_ldsc[unit], '\r');
|
||||
tmxr_putc_ln( &com_ldsc[unit], '\n');
|
||||
@ -551,7 +556,7 @@ t_stat coml_srv(UNIT * uptr)
|
||||
break;
|
||||
|
||||
case 03: /* ^C */
|
||||
uptr->u3 |= BREAK;
|
||||
uptr->CMD |= BREAK;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -560,13 +565,13 @@ t_stat coml_srv(UNIT * uptr)
|
||||
sim_putchar('\007');
|
||||
} else {
|
||||
com_buf[unit][uptr->BPTR++] = ch;
|
||||
if ((uptr->u3 & BYPASS) == 0)
|
||||
if ((uptr->CMD & 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->CMD |= INPUT;
|
||||
uptr->BPTR &= 0xff;
|
||||
}
|
||||
}
|
||||
@ -590,16 +595,16 @@ t_stat com_scan(UNIT * uptr)
|
||||
if (ln >= 0) { /* got one? rcv enb*/
|
||||
line = &coml_unit[ln];
|
||||
sim_debug(DEBUG_DETAIL, &com_dev, "COM line connect %d\n", ln);
|
||||
if (line->u3 & ENAB) /* Already connected */
|
||||
if (line->CMD & ENAB) /* Already connected */
|
||||
return SCPE_OK;
|
||||
if ((line->u3 & POLL) == 0) { /* Check if not polling */
|
||||
if ((line->CMD & POLL) == 0) { /* Check if not polling */
|
||||
(void)tmxr_set_get_modem_bits(&com_ldsc[ln], 0,
|
||||
TMXR_MDM_DTR, NULL);
|
||||
(void)tmxr_reset_ln(&com_ldsc[ln]);
|
||||
} else {
|
||||
com_ldsc[ln].rcve = 1; /* Mark as ok */
|
||||
line->u3 &= ~POLL;
|
||||
line->u3 |= ENAB;
|
||||
line->CMD &= ~POLL;
|
||||
line->CMD |= ENAB;
|
||||
sim_debug(DEBUG_DETAIL, &com_dev, "COM line connect %d\n", ln);
|
||||
sim_activate(line, 200);
|
||||
}
|
||||
@ -634,7 +639,7 @@ com_attach(UNIT * uptr, CONST char *cptr)
|
||||
// (void)tmxr_set_line_modem_control(&com_ldsc[i], TRUE);
|
||||
// (void)tmxr_set_get_modem_bits(&com_ldsc[i], 0, TMXR_MDM_DTR, NULL);
|
||||
// (void)tmxr_reset_ln(&com_ldsc[i]);
|
||||
coml_unit[i].u3 &= ~0xffff;
|
||||
coml_unit[i].CMD &= ~0xffff;
|
||||
}
|
||||
sim_activate(uptr, tmxr_poll);
|
||||
return SCPE_OK;
|
||||
@ -649,7 +654,7 @@ com_detach(UNIT * uptr)
|
||||
for (i = 0; i< com_desc.lines; i++) {
|
||||
(void)tmxr_set_get_modem_bits(&com_ldsc[i], 0, TMXR_MDM_DTR, NULL);
|
||||
(void)tmxr_reset_ln(&com_ldsc[i]);
|
||||
coml_unit[i].u3 &= ~0xffff;
|
||||
coml_unit[i].CMD &= ~0xffff;
|
||||
}
|
||||
sim_cancel(uptr);
|
||||
r = tmxr_detach(&com_desc, uptr);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* ibm360_con.c: IBM 360 Inquiry console.
|
||||
|
||||
Copyright (c) 2017, Richard Cornwell
|
||||
Copyright (c) 2017-2020, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -49,6 +49,8 @@
|
||||
#define CON_REQ 0x400 /* Request key pressed */
|
||||
#define CON_OUTPUT 0x800 /* Output characters since R */
|
||||
|
||||
/* Upper 11 bits of u3 hold the device address */
|
||||
|
||||
/* Input buffer pointer held in u4 */
|
||||
|
||||
/* in u5 packs sense byte 0,1 and 3 */
|
||||
@ -56,7 +58,9 @@
|
||||
#define SNS_CMDREJ 0x80 /* Command reject */
|
||||
#define SNS_INTVENT 0x40 /* Unit intervention required */
|
||||
|
||||
|
||||
#define CMD u3
|
||||
#define IPTR u4
|
||||
#define SNS u5
|
||||
|
||||
/* std devices. data structures
|
||||
|
||||
@ -110,81 +114,81 @@ void
|
||||
con_ini(UNIT *uptr, t_bool f) {
|
||||
int u = (uptr - con_unit);
|
||||
con_data[u].inptr = 0;
|
||||
uptr->u3 &= ~CON_MSK;
|
||||
uptr->u5 = 0;
|
||||
uptr->CMD &= ~CON_MSK;
|
||||
uptr->SNS = 0;
|
||||
sim_activate(uptr, 1000);
|
||||
}
|
||||
|
||||
uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
int u = (uptr - con_unit);
|
||||
|
||||
if ((uptr->u3 & CON_MSK) != 0)
|
||||
if ((uptr->CMD & CON_MSK) != 0)
|
||||
return SNS_BSY;
|
||||
|
||||
if ((cmd & 0xf0) != 0) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
|
||||
switch (cmd & 0x7) {
|
||||
case 2: /* Read command */
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd RD\n", u);
|
||||
if (uptr->u3 & CON_REQ) {
|
||||
if (uptr->CMD & CON_REQ) {
|
||||
return SNS_ATTN|SNS_BSY;
|
||||
}
|
||||
|
||||
if ((uptr->u3 & CON_INPUT) == 0 &&
|
||||
(con_data[u].inptr == 0 || uptr->u3 & CON_CR)) {
|
||||
if ((uptr->CMD & CON_INPUT) == 0 &&
|
||||
(con_data[u].inptr == 0 || uptr->CMD & CON_CR)) {
|
||||
/* Activate input so we can get response */
|
||||
if ((uptr->u3 & CON_OUTPUT) != 0) {
|
||||
if ((uptr->CMD & CON_OUTPUT) != 0) {
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
uptr->u3 &= ~CON_OUTPUT;
|
||||
uptr->CMD &= ~CON_OUTPUT;
|
||||
}
|
||||
sim_putchar('I');
|
||||
sim_putchar(' ');
|
||||
}
|
||||
uptr->u4 = 0;
|
||||
uptr->u3 |= cmd & CON_MSK;
|
||||
uptr->u5 = 0;
|
||||
uptr->IPTR = 0;
|
||||
uptr->CMD |= cmd & CON_MSK;
|
||||
uptr->SNS = 0;
|
||||
return 0;
|
||||
|
||||
case 1: /* Write command */
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd WR\n", u);
|
||||
if (uptr->u3 & CON_REQ) {
|
||||
if (uptr->CMD & CON_REQ) {
|
||||
return SNS_ATTN|SNS_BSY;
|
||||
}
|
||||
uptr->u3 |= cmd & CON_MSK;
|
||||
uptr->u5 = 0;
|
||||
if (uptr->u3 & CON_CR) {
|
||||
uptr->CMD |= cmd & CON_MSK;
|
||||
uptr->SNS = 0;
|
||||
if (uptr->CMD & CON_CR) {
|
||||
sim_putchar('R');
|
||||
sim_putchar(' ');
|
||||
uptr->u3 &= ~CON_CR;
|
||||
uptr->u3 |= CON_OUTPUT;
|
||||
uptr->CMD &= ~CON_CR;
|
||||
uptr->CMD |= CON_OUTPUT;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case 3: /* Control */
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd NOP\n", u);
|
||||
if (uptr->u3 & CON_REQ) {
|
||||
if (uptr->CMD & CON_REQ) {
|
||||
return SNS_ATTN|SNS_BSY;
|
||||
}
|
||||
uptr->u5 = 0;
|
||||
uptr->SNS = 0;
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
|
||||
case 0: /* Status */
|
||||
break;
|
||||
|
||||
case 4: /* Sense */
|
||||
uptr->u3 |= cmd & CON_MSK;
|
||||
uptr->CMD |= cmd & CON_MSK;
|
||||
return 0;
|
||||
|
||||
default: /* invalid command */
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uptr->u5)
|
||||
if (uptr->SNS)
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
}
|
||||
@ -192,9 +196,9 @@ uint8 con_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
/* Handle transfer of data for printer */
|
||||
t_stat
|
||||
con_srv(UNIT *uptr) {
|
||||
uint16 addr = GET_UADDR(uptr->u3);
|
||||
uint16 addr = GET_UADDR(uptr->CMD);
|
||||
int u = (uptr - con_unit);
|
||||
int cmd = uptr->u3 & CON_MSK;
|
||||
int cmd = uptr->CMD & CON_MSK;
|
||||
t_stat r = SCPE_ARG; /* Force error if not set */
|
||||
uint8 ch;
|
||||
int i;
|
||||
@ -203,12 +207,12 @@ con_srv(UNIT *uptr) {
|
||||
|
||||
switch (cmd) {
|
||||
case 4: /* Sense */
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd SNS %02x\n", u, uptr->u5);
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd SNS %02x\n", u, uptr->SNS);
|
||||
/* Check if request pending */
|
||||
ch = uptr->u5;
|
||||
ch = uptr->SNS;
|
||||
chan_write_byte(addr, &ch);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
uptr->u3 &= ~(CON_MSK);
|
||||
uptr->CMD &= ~(CON_MSK);
|
||||
break;
|
||||
|
||||
case CON_WR:
|
||||
@ -217,58 +221,58 @@ con_srv(UNIT *uptr) {
|
||||
if (cmd == CON_ACR) {
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
uptr->u3 |= CON_CR;
|
||||
uptr->u3 &= ~CON_OUTPUT;
|
||||
uptr->CMD |= CON_CR;
|
||||
uptr->CMD &= ~CON_OUTPUT;
|
||||
}
|
||||
uptr->u3 &= ~CON_MSK;
|
||||
uptr->CMD &= ~CON_MSK;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
delay = 40000;
|
||||
} else {
|
||||
if (ch == 0x15) {
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
uptr->u3 |= CON_CR;
|
||||
uptr->u3 &= ~CON_OUTPUT;
|
||||
uptr->CMD |= CON_CR;
|
||||
uptr->CMD &= ~CON_OUTPUT;
|
||||
} else {
|
||||
ch = ebcdic_to_ascii[ch];
|
||||
if (ch != 0) {
|
||||
if (!isprint(ch))
|
||||
ch = '_';
|
||||
sim_putchar(ch);
|
||||
uptr->u3 &= ~CON_OUTPUT;
|
||||
uptr->CMD &= ~CON_OUTPUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CON_RD:
|
||||
if (uptr->u3 & CON_INPUT) {
|
||||
uptr->u3 &= ~CON_REQ;
|
||||
if (uptr->CMD & CON_INPUT) {
|
||||
uptr->CMD &= ~CON_REQ;
|
||||
if (con_data[u].inptr == 0) {
|
||||
uptr->u3 &= ~CON_INPUT;
|
||||
uptr->CMD &= ~CON_INPUT;
|
||||
con_data[u].inptr = 0;
|
||||
cmd = 0;
|
||||
uptr->u3 &= ~(CON_MSK);
|
||||
uptr->CMD &= ~(CON_MSK);
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: devend\n", u);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
}
|
||||
|
||||
ch = con_data[u].ibuff[uptr->u4++];
|
||||
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)) {
|
||||
uptr->u3 &= ~CON_INPUT;
|
||||
uptr->CMD &= ~CON_INPUT;
|
||||
con_data[u].inptr = 0;
|
||||
cmd = 0;
|
||||
uptr->u3 &= ~(CON_MSK);
|
||||
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->u4 == con_data[u].inptr) {
|
||||
uptr->u3 &= ~CON_INPUT;
|
||||
if (uptr->IPTR == con_data[u].inptr) {
|
||||
uptr->CMD &= ~CON_INPUT;
|
||||
con_data[u].inptr = 0;
|
||||
cmd = 0;
|
||||
uptr->u3 &= ~(CON_MSK);
|
||||
uptr->CMD &= ~(CON_MSK);
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: devend\n", u);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
}
|
||||
@ -280,22 +284,22 @@ con_srv(UNIT *uptr) {
|
||||
r = sim_poll_kbd();
|
||||
if (r & SCPE_KFLAG) {
|
||||
ch = r & 0377;
|
||||
if ((uptr->u3 & CON_INPUT) == 0) {
|
||||
if ((uptr->CMD & CON_INPUT) == 0) {
|
||||
/* Handle end of buffer */
|
||||
switch (ch) {
|
||||
case '\r':
|
||||
case '\n':
|
||||
sim_debug(DEBUG_DATA, &con_dev, "%d: ent\n", u);
|
||||
uptr->u3 |= CON_INPUT;
|
||||
uptr->u3 |= CON_CR;
|
||||
uptr->u3 &= ~CON_OUTPUT;
|
||||
uptr->CMD |= CON_INPUT;
|
||||
uptr->CMD |= CON_CR;
|
||||
uptr->CMD &= ~CON_OUTPUT;
|
||||
sim_putchar('\r');
|
||||
sim_putchar('\n');
|
||||
/* Fall through */
|
||||
|
||||
case 033: /* request key */
|
||||
if (cmd != CON_RD) {
|
||||
uptr->u3 |= CON_REQ;
|
||||
uptr->CMD |= CON_REQ;
|
||||
}
|
||||
break;
|
||||
case 0177:
|
||||
@ -337,7 +341,7 @@ con_srv(UNIT *uptr) {
|
||||
} else {
|
||||
if (cmd == CON_RD && ch == 03) { /* Cancel */
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
uptr->u3 &= ~CON_INPUT;
|
||||
uptr->CMD &= ~CON_INPUT;
|
||||
con_data[u].inptr = 0;
|
||||
cmd = 0;
|
||||
} else {
|
||||
@ -346,10 +350,10 @@ con_srv(UNIT *uptr) {
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == 0 && uptr->u3 & CON_REQ) {
|
||||
if (cmd == 0 && uptr->CMD & CON_REQ) {
|
||||
sim_debug(DEBUG_CMD, &con_dev, "%d: setattn %x\n", u, addr);
|
||||
set_devattn(addr, SNS_ATTN);
|
||||
uptr->u3 &= ~CON_REQ;
|
||||
uptr->CMD &= ~CON_REQ;
|
||||
}
|
||||
sim_activate(uptr, delay);
|
||||
return SCPE_OK;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* ibm360_cpu.c: ibm 360 cpu simulator.
|
||||
|
||||
Copyright (c) 2019, Richard Cornwell
|
||||
Copyright (c) 2019-2020, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/* ibm360_defs.h: IBM 360 simulator definitions
|
||||
|
||||
Copyright (c) 2017, Richard Cornwell
|
||||
Copyright (c) 2017-2020, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -86,12 +86,8 @@ typedef struct dib {
|
||||
|
||||
} DIB;
|
||||
|
||||
#define DEV_V_ADDR DEV_V_UF /* Pointer to device address */
|
||||
#define DEV_ADDR_MASK (0x7ff << DEV_V_ADDR)
|
||||
#define DEV_V_UADDR (DEV_V_UF + 10) /* Device address in Unit */
|
||||
#define DEV_UADDR (1 << DEV_V_UADDR)
|
||||
#define GET_DADDR(x) (0x7ff & ((x) >> DEV_V_ADDR))
|
||||
#define DEV_ADDR(x) ((x) << DEV_V_ADDR)
|
||||
|
||||
#define UNIT_V_ADDR 20
|
||||
#define UNIT_ADDR_MASK (0x7ff << UNIT_V_ADDR)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* ibm360_lpr.c: IBM 360 Line Printer
|
||||
|
||||
Copyright (c) 2017, Richard Cornwell
|
||||
Copyright (c) 2017-2020, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -48,6 +48,8 @@
|
||||
#define LPR_CMDMSK 0xff /* Mask command part. */
|
||||
#define LPR_FULL 0x100 /* Buffer full */
|
||||
|
||||
/* Upper 11 bits of u3 hold the device address */
|
||||
|
||||
/* u4 holds current line */
|
||||
/* in u5 packs sense byte 0,1 and 3 */
|
||||
/* Sense byte 0 */
|
||||
@ -61,6 +63,11 @@
|
||||
#define SNS_CHN9 0x01 /* Channel 9 on printer */
|
||||
/* u6 hold buffer position */
|
||||
|
||||
#define CMD u3
|
||||
#define LINE u4
|
||||
#define SNS u5
|
||||
#define POS u6
|
||||
|
||||
|
||||
/* std devices. data structures
|
||||
|
||||
@ -138,7 +145,7 @@ lpr_setlpp(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
if (i < 20 || i > 100)
|
||||
return SCPE_ARG;
|
||||
uptr->capac = i;
|
||||
uptr->u4 = 0;
|
||||
uptr->LINE = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@ -163,7 +170,7 @@ print_line(UNIT * uptr)
|
||||
memset(out, ' ', sizeof(out));
|
||||
|
||||
/* Scan each column */
|
||||
for (i = 0; i < uptr->u6; i++) {
|
||||
for (i = 0; i < uptr->POS; i++) {
|
||||
int ch = lpr_data[u].lbuff[i];
|
||||
|
||||
ch = ebcdic_to_ascii[ch];
|
||||
@ -182,9 +189,9 @@ print_line(UNIT * uptr)
|
||||
sim_fwrite(&out, 1, i, uptr->fileref);
|
||||
uptr->pos += i;
|
||||
sim_debug(DEBUG_DETAIL, &lpr_dev, "%s", out);
|
||||
uptr->u4++;
|
||||
if ((t_addr)uptr->u4 > uptr->capac) {
|
||||
uptr->u4 = 1;
|
||||
uptr->LINE++;
|
||||
if ((t_addr)uptr->LINE > uptr->capac) {
|
||||
uptr->LINE = 1;
|
||||
}
|
||||
|
||||
memset(&lpr_data[u].lbuff[0], 0, 144);
|
||||
@ -193,7 +200,7 @@ print_line(UNIT * uptr)
|
||||
|
||||
uint8 lpr_startcmd(UNIT * uptr, uint16 chan, uint8 cmd)
|
||||
{
|
||||
if ((uptr->u3 & LPR_CMDMSK) != 0) {
|
||||
if ((uptr->CMD & LPR_CMDMSK) != 0) {
|
||||
if ((uptr->flags & UNIT_ATT) != 0)
|
||||
return SNS_BSY;
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
@ -203,35 +210,35 @@ uint8 lpr_startcmd(UNIT * uptr, uint16 chan, uint8 cmd)
|
||||
|
||||
switch (cmd & 0x3) {
|
||||
case 1: /* Write command */
|
||||
uptr->u3 &= ~(LPR_CMDMSK);
|
||||
uptr->u3 |= (cmd & LPR_CMDMSK);
|
||||
uptr->CMD &= ~(LPR_CMDMSK);
|
||||
uptr->CMD |= (cmd & LPR_CMDMSK);
|
||||
sim_activate(uptr, 10); /* Start unit off */
|
||||
uptr->u5 = 0;
|
||||
uptr->u6 = 0;
|
||||
uptr->SNS = 0;
|
||||
uptr->POS = 0;
|
||||
return 0;
|
||||
|
||||
case 3: /* Carrage control */
|
||||
uptr->u3 &= ~(LPR_CMDMSK);
|
||||
uptr->u3 |= (cmd & LPR_CMDMSK);
|
||||
uptr->CMD &= ~(LPR_CMDMSK);
|
||||
uptr->CMD |= (cmd & LPR_CMDMSK);
|
||||
sim_activate(uptr, 10); /* Start unit off */
|
||||
uptr->u5 = 0;
|
||||
uptr->u6 = 0;
|
||||
uptr->SNS = 0;
|
||||
uptr->POS = 0;
|
||||
return SNS_CHNEND;
|
||||
|
||||
case 0: /* Status */
|
||||
if (cmd == 0x4) { /* Sense */
|
||||
uptr->u3 &= ~(LPR_CMDMSK);
|
||||
uptr->u3 |= (cmd & LPR_CMDMSK);
|
||||
uptr->CMD &= ~(LPR_CMDMSK);
|
||||
uptr->CMD |= (cmd & LPR_CMDMSK);
|
||||
sim_activate(uptr, 10); /* Start unit off */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* invalid command */
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
break;
|
||||
}
|
||||
if (uptr->u5 & 0xff)
|
||||
if (uptr->SNS & 0xff)
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
}
|
||||
@ -239,43 +246,43 @@ uint8 lpr_startcmd(UNIT * uptr, uint16 chan, uint8 cmd)
|
||||
/* Handle transfer of data for printer */
|
||||
t_stat
|
||||
lpr_srv(UNIT *uptr) {
|
||||
int addr = GET_UADDR(uptr->u3);
|
||||
int addr = GET_UADDR(uptr->CMD);
|
||||
int u = (uptr - lpr_unit);
|
||||
int cmd = (uptr->u3 & 0x7);
|
||||
int cmd = (uptr->CMD & 0x7);
|
||||
|
||||
if (cmd == 4) {
|
||||
uint8 ch = uptr->u5;
|
||||
uptr->u3 &= ~(LPR_CMDMSK);
|
||||
uint8 ch = uptr->SNS;
|
||||
uptr->CMD &= ~(LPR_CMDMSK);
|
||||
chan_write_byte(addr, &ch);
|
||||
chan_end(addr, SNS_DEVEND|SNS_CHNEND);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if (cmd == 7) {
|
||||
uptr->u3 &= ~(LPR_FULL|LPR_CMDMSK);
|
||||
uptr->u6 = 0;
|
||||
uptr->CMD &= ~(LPR_FULL|LPR_CMDMSK);
|
||||
uptr->POS = 0;
|
||||
chan_end(addr, SNS_DEVEND|SNS_CHNEND);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
if ((uptr->u3 & LPR_FULL) || cmd == 0x3) {
|
||||
if ((uptr->CMD & LPR_FULL) || cmd == 0x3) {
|
||||
print_line(uptr);
|
||||
uptr->u3 &= ~(LPR_FULL|LPR_CMDMSK);
|
||||
uptr->u6 = 0;
|
||||
uptr->CMD &= ~(LPR_FULL|LPR_CMDMSK);
|
||||
uptr->POS = 0;
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Copy next column over */
|
||||
if (cmd == 1 && (uptr->u3 & LPR_FULL) == 0) {
|
||||
if(chan_read_byte(addr, &lpr_data[u].lbuff[uptr->u6])) {
|
||||
uptr->u3 |= LPR_FULL;
|
||||
if (cmd == 1 && (uptr->CMD & LPR_FULL) == 0) {
|
||||
if(chan_read_byte(addr, &lpr_data[u].lbuff[uptr->POS])) {
|
||||
uptr->CMD |= LPR_FULL;
|
||||
} else {
|
||||
sim_activate(uptr, 20);
|
||||
uptr->u6++;
|
||||
uptr->POS++;
|
||||
}
|
||||
if (uptr->u3 & LPR_FULL || uptr->u6 > 132) {
|
||||
uptr->u3 |= LPR_FULL;
|
||||
if (uptr->CMD & LPR_FULL || uptr->POS > 132) {
|
||||
uptr->CMD |= LPR_FULL;
|
||||
chan_end(addr, SNS_CHNEND);
|
||||
sim_activate(uptr, 5000);
|
||||
}
|
||||
@ -285,9 +292,9 @@ lpr_srv(UNIT *uptr) {
|
||||
|
||||
void
|
||||
lpr_ini(UNIT *uptr, t_bool f) {
|
||||
uptr->u3 &= ~(LPR_FULL|LPR_CMDMSK);
|
||||
uptr->u4 = 0;
|
||||
uptr->u5 = 0;
|
||||
uptr->CMD &= ~(LPR_FULL|LPR_CMDMSK);
|
||||
uptr->LINE = 0;
|
||||
uptr->SNS = 0;
|
||||
}
|
||||
|
||||
t_stat
|
||||
@ -298,17 +305,17 @@ lpr_attach(UNIT * uptr, CONST char *file)
|
||||
sim_switches |= SWMASK ('A'); /* Position to EOF */
|
||||
if ((r = attach_unit(uptr, file)) != SCPE_OK)
|
||||
return r;
|
||||
uptr->u3 &= ~(LPR_FULL|LPR_CMDMSK);
|
||||
uptr->u4 = 0;
|
||||
uptr->u5 = 0;
|
||||
set_devattn(GET_UADDR(uptr->u3), SNS_DEVEND);
|
||||
uptr->CMD &= ~(LPR_FULL|LPR_CMDMSK);
|
||||
uptr->LINE = 0;
|
||||
uptr->SNS = 0;
|
||||
set_devattn(GET_UADDR(uptr->CMD), SNS_DEVEND);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
lpr_detach(UNIT * uptr)
|
||||
{
|
||||
if (uptr->u3 & LPR_FULL)
|
||||
if (uptr->CMD & LPR_FULL)
|
||||
print_line(uptr);
|
||||
return detach_unit(uptr);
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* ibm360_mt.c: IBM 360 2400 Magnetic tape controller
|
||||
|
||||
Copyright (c) 2017, Richard Cornwell
|
||||
Copyright (c) 2017-2020, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -87,6 +87,8 @@
|
||||
#define MT_CONV 0x4000 /* Data converter on ignored 9 track */
|
||||
#define MT_BUSY 0x8000 /* Flag to send a CUE */
|
||||
|
||||
/* Upper 11 bits of u3 hold the device address */
|
||||
|
||||
/* in u4 is current buffer position */
|
||||
|
||||
/* in u5 packs sense byte 0,1 and 3 */
|
||||
@ -133,6 +135,11 @@
|
||||
#define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF)
|
||||
#define CLR_BUF(u) u->hwmark = 0xFFFFFFFF
|
||||
|
||||
#define CMD u3
|
||||
#define POS u4
|
||||
#define SNS u5
|
||||
#define CPOS u6
|
||||
|
||||
uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ;
|
||||
t_stat mt_srv(UNIT *);
|
||||
t_stat mt_boot(int32, DEVICE *);
|
||||
@ -225,11 +232,11 @@ uint8 bcd_to_ebcdic[64] = {
|
||||
|
||||
|
||||
uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
uint16 addr = GET_UADDR(uptr->u3);
|
||||
uint16 addr = GET_UADDR(uptr->CMD);
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
|
||||
if (mt_busy[GET_DEV_BUF(dptr->flags)] != 0 || (uptr->u3 & MT_CMDMSK) != 0) {
|
||||
if (mt_busy[GET_DEV_BUF(dptr->flags)] != 0 || (uptr->CMD & MT_CMDMSK) != 0) {
|
||||
sim_debug(DEBUG_CMD, dptr, "CMD busy unit=%d %x\n", unit, cmd);
|
||||
uptr->flags |= MT_BUSY; /* Flag we need to send CUE */
|
||||
return SNS_BSY;
|
||||
@ -243,23 +250,23 @@ uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
case 0x1: /* Write command */
|
||||
case 0x2: /* Read command */
|
||||
case 0xc: /* Read backward */
|
||||
uptr->u5 = 0;
|
||||
uptr->u5 |= SNS_TUASTA << 8;
|
||||
uptr->SNS = 0;
|
||||
uptr->SNS |= SNS_TUASTA << 8;
|
||||
if ((uptr->flags & MTUF_9TR) == 0)
|
||||
uptr->u5 |= (SNS_7TRACK << 8);
|
||||
uptr->SNS |= (SNS_7TRACK << 8);
|
||||
if (sim_tape_wrp(uptr))
|
||||
uptr->u5 |= (SNS_WRP << 8);
|
||||
uptr->SNS |= (SNS_WRP << 8);
|
||||
if (sim_tape_bot(uptr))
|
||||
uptr->u5 |= (SNS_LOAD << 8);
|
||||
uptr->SNS |= (SNS_LOAD << 8);
|
||||
/* Fall through */
|
||||
|
||||
case 0x4: /* Sense */
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->u3 |= cmd & MT_CMDMSK;
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
uptr->CMD |= cmd & MT_CMDMSK;
|
||||
sim_activate(uptr, 1000); /* Start unit off */
|
||||
CLR_BUF(uptr);
|
||||
uptr->u4 = 0;
|
||||
uptr->u6 = 0;
|
||||
uptr->POS = 0;
|
||||
uptr->CPOS = 0;
|
||||
mt_busy[GET_DEV_BUF(dptr->flags)] = 1;
|
||||
if ((cmd & 0x7) == 0x7) /* Quick end channel on control */
|
||||
return SNS_CHNEND;
|
||||
@ -268,13 +275,13 @@ uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
case 0x3: /* Control */
|
||||
case 0xb: /* Control */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
||||
uptr->u5 |= SNS_INTVENT;
|
||||
uptr->SNS |= SNS_INTVENT;
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
if ((uptr->flags & MTUF_9TR) == 0) {
|
||||
uptr->u5 |= (SNS_7TRACK << 8);
|
||||
uptr->SNS |= (SNS_7TRACK << 8);
|
||||
if ((cmd & 0xc0) == 0xc0) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
}
|
||||
switch((cmd >> 3) & 07) {
|
||||
@ -283,44 +290,44 @@ uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
case 3:
|
||||
return SNS_CHNEND|SNS_DEVEND ;
|
||||
case 2: /* Reset condition */
|
||||
uptr->u3 &= ~(MT_ODD|MT_TRANS|MT_CONV|MT_MDEN_MSK);
|
||||
uptr->u3 |= (cmd & MT_MDEN_MSK) | MT_ODD | MT_CONV;
|
||||
uptr->CMD &= ~(MT_ODD|MT_TRANS|MT_CONV|MT_MDEN_MSK);
|
||||
uptr->CMD |= (cmd & MT_MDEN_MSK) | MT_ODD | MT_CONV;
|
||||
break;
|
||||
case 4:
|
||||
uptr->u3 &= ~(MT_ODD|MT_TRANS|MT_CONV|MT_MDEN_MSK);
|
||||
uptr->u3 |= (cmd & MT_MDEN_MSK);
|
||||
uptr->CMD &= ~(MT_ODD|MT_TRANS|MT_CONV|MT_MDEN_MSK);
|
||||
uptr->CMD |= (cmd & MT_MDEN_MSK);
|
||||
break;
|
||||
case 5:
|
||||
uptr->u3 &= ~(MT_ODD|MT_TRANS|MT_CONV|MT_MDEN_MSK);
|
||||
uptr->u3 |= (cmd & MT_MDEN_MSK) | MT_TRANS;
|
||||
uptr->CMD &= ~(MT_ODD|MT_TRANS|MT_CONV|MT_MDEN_MSK);
|
||||
uptr->CMD |= (cmd & MT_MDEN_MSK) | MT_TRANS;
|
||||
break;
|
||||
case 6:
|
||||
uptr->u3 &= ~(MT_ODD|MT_TRANS|MT_CONV|MT_MDEN_MSK);
|
||||
uptr->u3 |= (cmd & MT_MDEN_MSK) | MT_ODD;
|
||||
uptr->CMD &= ~(MT_ODD|MT_TRANS|MT_CONV|MT_MDEN_MSK);
|
||||
uptr->CMD |= (cmd & MT_MDEN_MSK) | MT_ODD;
|
||||
break;
|
||||
case 7:
|
||||
uptr->u3 &= ~(MT_ODD|MT_TRANS|MT_CONV|MT_MDEN_MSK);
|
||||
uptr->u3 |= (cmd & MT_MDEN_MSK) | MT_ODD | MT_TRANS;
|
||||
uptr->CMD &= ~(MT_ODD|MT_TRANS|MT_CONV|MT_MDEN_MSK);
|
||||
uptr->CMD |= (cmd & MT_MDEN_MSK) | MT_ODD | MT_TRANS;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
uptr->u3 &= ~MT_MDEN_MSK;
|
||||
uptr->CMD &= ~MT_MDEN_MSK;
|
||||
if (cmd & 0x8)
|
||||
uptr->u3 |= MT_MDEN_800;
|
||||
uptr->CMD |= MT_MDEN_800;
|
||||
else
|
||||
uptr->u3 |= MT_MDEN_1600;
|
||||
uptr->CMD |= MT_MDEN_1600;
|
||||
}
|
||||
uptr->u5 = 0;
|
||||
uptr->SNS = 0;
|
||||
break;
|
||||
|
||||
case 0x0: /* Status */
|
||||
break;
|
||||
|
||||
default: /* invalid command */
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
break;
|
||||
}
|
||||
if (uptr->u5 & 0xff)
|
||||
if (uptr->SNS & 0xff)
|
||||
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
|
||||
return SNS_CHNEND|SNS_DEVEND;
|
||||
}
|
||||
@ -355,7 +362,7 @@ t_stat mt_error(UNIT * uptr, uint16 addr, t_stat r, DEVICE * dptr)
|
||||
break;
|
||||
case MTSE_EOM: /* end of medium */
|
||||
sim_debug(DEBUG_EXP, dptr, "EOT ");
|
||||
uptr->u5 = SNS_EQUCHK;
|
||||
uptr->SNS = SNS_EQUCHK;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
return SCPE_OK;
|
||||
}
|
||||
@ -366,10 +373,10 @@ t_stat mt_error(UNIT * uptr, uint16 addr, t_stat r, DEVICE * dptr)
|
||||
/* Handle processing of tape requests. */
|
||||
t_stat mt_srv(UNIT * uptr)
|
||||
{
|
||||
uint16 addr = GET_UADDR(uptr->u3);
|
||||
uint16 addr = GET_UADDR(uptr->CMD);
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
int unit = (uptr - dptr->units);
|
||||
int cmd = uptr->u3 & MT_CMDMSK;
|
||||
int cmd = uptr->CMD & MT_CMDMSK;
|
||||
int bufnum = GET_DEV_BUF(dptr->flags);
|
||||
t_mtrlnt reclen;
|
||||
t_stat r = SCPE_ARG; /* Force error if not set */
|
||||
@ -377,9 +384,9 @@ t_stat mt_srv(UNIT * uptr)
|
||||
int mode = 0;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
||||
uptr->u5 |= SNS_INTVENT;
|
||||
uptr->SNS |= SNS_INTVENT;
|
||||
if (cmd != MT_SENSE) {
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
@ -392,30 +399,30 @@ t_stat mt_srv(UNIT * uptr)
|
||||
break;
|
||||
|
||||
case MT_SENSE:
|
||||
ch = uptr->u5 & 0xff;
|
||||
ch = uptr->SNS & 0xff;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch);
|
||||
chan_write_byte(addr, &ch) ;
|
||||
ch = (uptr->u5 >> 8) & 0xff;
|
||||
ch = (uptr->SNS >> 8) & 0xff;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 2 %x\n", unit, ch);
|
||||
chan_write_byte(addr, &ch) ;
|
||||
ch = 0xc0;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 3 %x\n", unit, ch);
|
||||
chan_write_byte(addr, &ch) ;
|
||||
ch = (uptr->u5 >> 16) & 0xff;
|
||||
ch = (uptr->SNS >> 16) & 0xff;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch);
|
||||
chan_write_byte(addr, &ch) ;
|
||||
ch = 0;
|
||||
chan_write_byte(addr, &ch) ;
|
||||
chan_write_byte(addr, &ch);
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
|
||||
case MT_READ:
|
||||
|
||||
if (uptr->u3 & MT_READDONE) {
|
||||
uptr->u3 &= ~(MT_CMDMSK|MT_READDONE);
|
||||
if (uptr->CMD & MT_READDONE) {
|
||||
uptr->CMD &= ~(MT_CMDMSK|MT_READDONE);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
@ -427,44 +434,44 @@ t_stat mt_srv(UNIT * uptr)
|
||||
if ((r = sim_tape_rdrecf(uptr, &mt_buffer[bufnum][0], &reclen,
|
||||
BUFFSIZE)) != MTSE_OK) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, " error %d\n", r);
|
||||
uptr->u3 &= ~(MT_CMDMSK|MT_READDONE);
|
||||
uptr->CMD &= ~(MT_CMDMSK|MT_READDONE);
|
||||
return mt_error(uptr, addr, r, dptr);
|
||||
}
|
||||
uptr->u4 = 0;
|
||||
uptr->POS = 0;
|
||||
uptr->hwmark = reclen;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Block %d chars\n", reclen);
|
||||
}
|
||||
|
||||
ch = mt_buffer[bufnum][uptr->u4++];
|
||||
ch = mt_buffer[bufnum][uptr->POS++];
|
||||
/* if we are a 7track tape, handle conversion */
|
||||
if ((uptr->flags & MTUF_9TR) == 0) {
|
||||
mode = (uptr->u3 & MT_ODD) ? 0 : 0100;
|
||||
mode = (uptr->CMD & MT_ODD) ? 0 : 0100;
|
||||
if ((parity_table[ch & 077] ^ (ch & 0100) ^ mode) == 0) {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Parity error unit=%d %d %03o\n",
|
||||
unit, uptr->u4-1, ch);
|
||||
uptr->u5 |= (SNS_VRC << 16) | SNS_DATCHK;
|
||||
unit, uptr->POS-1, ch);
|
||||
uptr->SNS |= (SNS_VRC << 16) | SNS_DATCHK;
|
||||
}
|
||||
ch &= 077;
|
||||
if (uptr->u3 & MT_TRANS)
|
||||
if (uptr->CMD & MT_TRANS)
|
||||
ch = bcd_to_ebcdic[ch];
|
||||
if (uptr->u3 & MT_CONV) {
|
||||
if (uptr->CMD & MT_CONV) {
|
||||
sim_debug(DEBUG_DATA, dptr, "Read raw data unit=%d %d %02x %02x\n",
|
||||
unit, uptr->u4, ch, uptr->u6);
|
||||
if (uptr->u6 == 0 && (t_addr)uptr->u4 < uptr->hwmark) {
|
||||
uptr->u6 = MT_CONV1 | ch;
|
||||
unit, uptr->POS, ch, uptr->CPOS);
|
||||
if (uptr->CPOS == 0 && (t_addr)uptr->POS < uptr->hwmark) {
|
||||
uptr->CPOS = MT_CONV1 | ch;
|
||||
sim_activate(uptr, 20);
|
||||
return SCPE_OK;
|
||||
} else if ((uptr->u6 & 0xc0) == MT_CONV1) {
|
||||
int t = uptr->u6 & 0x3F;
|
||||
uptr->u6 = MT_CONV2 | ch;
|
||||
} else if ((uptr->CPOS & 0xc0) == MT_CONV1) {
|
||||
int t = uptr->CPOS & 0x3F;
|
||||
uptr->CPOS = MT_CONV2 | ch;
|
||||
ch = (t << 2) | ((ch >> 4) & 03);
|
||||
} else if ((uptr->u6 & 0xc0) == MT_CONV2) {
|
||||
int t = uptr->u6 & 0xf;
|
||||
uptr->u6 = MT_CONV3 | ch;
|
||||
} else if ((uptr->CPOS & 0xc0) == MT_CONV2) {
|
||||
int t = uptr->CPOS & 0xf;
|
||||
uptr->CPOS = MT_CONV3 | ch;
|
||||
ch = (t << 4) | ((ch >> 2) & 0xf);
|
||||
} else if ((uptr->u6 & 0xc0) == MT_CONV3) {
|
||||
ch |= ((uptr->u6 & 0x3) << 6);
|
||||
uptr->u6 = 0;
|
||||
} else if ((uptr->CPOS & 0xc0) == MT_CONV3) {
|
||||
ch |= ((uptr->CPOS & 0x3) << 6);
|
||||
uptr->CPOS = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -473,22 +480,22 @@ t_stat mt_srv(UNIT * uptr)
|
||||
if (chan_write_byte(addr, &ch)) {
|
||||
sim_debug(DEBUG_DATA, dptr, "Read unit=%d EOR\n\r", unit);
|
||||
/* If not read whole record, skip till end */
|
||||
if ((t_addr)uptr->u4 < uptr->hwmark) {
|
||||
if ((t_addr)uptr->POS < uptr->hwmark) {
|
||||
/* Send dummy character to force SLI */
|
||||
chan_write_byte(addr, &ch);
|
||||
sim_activate(uptr, (uptr->hwmark-uptr->u4) * 20);
|
||||
uptr->u3 |= MT_READDONE;
|
||||
sim_activate(uptr, (uptr->hwmark-uptr->POS) * 20);
|
||||
uptr->CMD |= MT_READDONE;
|
||||
break;
|
||||
}
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
chan_end(addr, SNS_DEVEND);
|
||||
} else {
|
||||
sim_debug(DEBUG_DATA, dptr, "Read data unit=%d %d %02x\n\r",
|
||||
unit, uptr->u4, ch);
|
||||
if ((t_addr)uptr->u4 >= uptr->hwmark) { /* In IRG */
|
||||
unit, uptr->POS, ch);
|
||||
if ((t_addr)uptr->POS >= uptr->hwmark) { /* In IRG */
|
||||
/* Handle end of record */
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
} else
|
||||
@ -500,8 +507,8 @@ t_stat mt_srv(UNIT * uptr)
|
||||
case MT_WRITE:
|
||||
/* Check if write protected */
|
||||
if (sim_tape_wrp(uptr)) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
break;
|
||||
@ -509,52 +516,52 @@ t_stat mt_srv(UNIT * uptr)
|
||||
|
||||
/* Grab data until channel has no more */
|
||||
if (chan_read_byte(addr, &ch)) {
|
||||
if (uptr->u4 > 0) { /* Only if data in record */
|
||||
if (uptr->POS > 0) { /* Only if data in record */
|
||||
reclen = uptr->hwmark;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Write unit=%d Block %d chars\n",
|
||||
unit, reclen);
|
||||
r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen);
|
||||
uptr->u4 = 0;
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->POS = 0;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_error(uptr, addr, r, dptr); /* Record errors */
|
||||
} else {
|
||||
uptr->u5 |= SNS_WCZERO; /* Write with no data */
|
||||
uptr->SNS |= SNS_WCZERO; /* Write with no data */
|
||||
}
|
||||
} else {
|
||||
if ((uptr->flags & MTUF_9TR) == 0) {
|
||||
mode = (uptr->u3 & MT_ODD) ? 0 : 0100;
|
||||
if (uptr->u3 & MT_TRANS)
|
||||
mode = (uptr->CMD & MT_ODD) ? 0 : 0100;
|
||||
if (uptr->CMD & MT_TRANS)
|
||||
ch = (ch & 0xf) | ((ch & 0x30) ^ 0x30);
|
||||
if (uptr->u3 & MT_CONV) {
|
||||
if (uptr->u6 == 0) {
|
||||
uptr->u6 = MT_CONV1 | (ch & 0x3);
|
||||
if (uptr->CMD & MT_CONV) {
|
||||
if (uptr->CPOS == 0) {
|
||||
uptr->CPOS = MT_CONV1 | (ch & 0x3);
|
||||
ch >>= 2;
|
||||
} else if ((uptr->u6 & 0xc0) == MT_CONV1) {
|
||||
int t = uptr->u6 & 0x3;
|
||||
uptr->u6 = MT_CONV2 | (ch & 0xf);
|
||||
} else if ((uptr->CPOS & 0xc0) == MT_CONV1) {
|
||||
int t = uptr->CPOS & 0x3;
|
||||
uptr->CPOS = MT_CONV2 | (ch & 0xf);
|
||||
ch = (t << 4) | ((ch >> 4) & 0xf);
|
||||
} else if ((uptr->u6 & 0xc0) == MT_CONV2) {
|
||||
int t = uptr->u6 & 0xf;
|
||||
} else if ((uptr->CPOS & 0xc0) == MT_CONV2) {
|
||||
int t = uptr->CPOS & 0xf;
|
||||
ch = (t << 2) | ((ch >> 6) & 0x3);
|
||||
ch ^= parity_table[ch & 077] ^ mode;
|
||||
mt_buffer[bufnum][uptr->u4++] = ch;
|
||||
uptr->u6 = 0;
|
||||
mt_buffer[bufnum][uptr->POS++] = ch;
|
||||
uptr->CPOS = 0;
|
||||
}
|
||||
}
|
||||
ch &= 077;
|
||||
ch |= parity_table[ch] ^ mode;
|
||||
}
|
||||
mt_buffer[bufnum][uptr->u4++] = ch;
|
||||
mt_buffer[bufnum][uptr->POS++] = ch;
|
||||
sim_debug(DEBUG_DATA, dptr, "Write data unit=%d %d %02o\n\r",
|
||||
unit, uptr->u4, ch);
|
||||
uptr->hwmark = uptr->u4;
|
||||
unit, uptr->POS, ch);
|
||||
uptr->hwmark = uptr->POS;
|
||||
}
|
||||
sim_activate(uptr, 20);
|
||||
break;
|
||||
|
||||
case MT_RDBK:
|
||||
if (uptr->u3 & MT_READDONE) {
|
||||
uptr->u3 &= ~(MT_CMDMSK|MT_READDONE);
|
||||
if (uptr->CMD & MT_READDONE) {
|
||||
uptr->CMD &= ~(MT_CMDMSK|MT_READDONE);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
return SCPE_OK;
|
||||
@ -563,7 +570,7 @@ t_stat mt_srv(UNIT * uptr)
|
||||
/* If at end of record, fill buffer */
|
||||
if (BUF_EMPTY(uptr)) {
|
||||
if (sim_tape_bot(uptr)) {
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
@ -571,39 +578,39 @@ t_stat mt_srv(UNIT * uptr)
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Read backward unit=%d ", unit);
|
||||
if ((r = sim_tape_rdrecr(uptr, &mt_buffer[bufnum][0], &reclen,
|
||||
BUFFSIZE)) != MTSE_OK) {
|
||||
uptr->u3 &= ~(MT_CMDMSK|MT_READDONE);
|
||||
uptr->CMD &= ~(MT_CMDMSK|MT_READDONE);
|
||||
return mt_error(uptr, addr, r, dptr);
|
||||
}
|
||||
uptr->u4 = reclen;
|
||||
uptr->POS = reclen;
|
||||
uptr->hwmark = reclen;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Binary Block %d chars\n", reclen);
|
||||
}
|
||||
|
||||
ch = mt_buffer[bufnum][--uptr->u4];
|
||||
ch = mt_buffer[bufnum][--uptr->POS];
|
||||
if ((uptr->flags & MTUF_9TR) == 0) {
|
||||
mode = (uptr->u3 & MT_ODD) ? 0 : 0100;
|
||||
mode = (uptr->CMD & MT_ODD) ? 0 : 0100;
|
||||
ch &= 077;
|
||||
if ((parity_table[ch & 077] ^ (ch & 0100) ^ mode) == 0) {
|
||||
uptr->u5 |= (SNS_VRC << 16) | SNS_DATCHK;
|
||||
uptr->SNS |= (SNS_VRC << 16) | SNS_DATCHK;
|
||||
}
|
||||
if (uptr->u3 & MT_TRANS)
|
||||
if (uptr->CMD & MT_TRANS)
|
||||
ch = bcd_to_ebcdic[ch];
|
||||
if (uptr->u3 & MT_CONV) {
|
||||
if (uptr->u6 == 0 && (t_addr)uptr->u4 < uptr->hwmark) {
|
||||
uptr->u6 = MT_CONV1 | ch;
|
||||
if (uptr->CMD & MT_CONV) {
|
||||
if (uptr->CPOS == 0 && (t_addr)uptr->POS < uptr->hwmark) {
|
||||
uptr->CPOS = MT_CONV1 | ch;
|
||||
sim_activate(uptr, 20);
|
||||
return SCPE_OK;
|
||||
} else if ((uptr->u6 & 0xc0) == MT_CONV1) {
|
||||
int t = uptr->u6 & 0x3F;
|
||||
uptr->u6 = MT_CONV2 | ch;
|
||||
} else if ((uptr->CPOS & 0xc0) == MT_CONV1) {
|
||||
int t = uptr->CPOS & 0x3F;
|
||||
uptr->CPOS = MT_CONV2 | ch;
|
||||
ch = t | ((ch << 6) & 0xc0);
|
||||
} else if ((uptr->u6 & 0xc0) == MT_CONV2) {
|
||||
int t = uptr->u6 & 0x3C;
|
||||
uptr->u6 = MT_CONV3 | ch;
|
||||
} else if ((uptr->CPOS & 0xc0) == MT_CONV2) {
|
||||
int t = uptr->CPOS & 0x3C;
|
||||
uptr->CPOS = MT_CONV3 | ch;
|
||||
ch = (t >> 2) | ((ch << 4) & 0xf0);
|
||||
} else if ((uptr->u6 & 0xc0) == MT_CONV3) {
|
||||
ch |= ((uptr->u6 & 0x30) >> 4);
|
||||
uptr->u6 = 0;
|
||||
} else if ((uptr->CPOS & 0xc0) == MT_CONV3) {
|
||||
ch |= ((uptr->CPOS & 0x30) >> 4);
|
||||
uptr->CPOS = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -611,19 +618,19 @@ t_stat mt_srv(UNIT * uptr)
|
||||
if (chan_write_byte(addr, &ch)) {
|
||||
sim_debug(DEBUG_DATA, dptr, "Read unit=%d EOR\n\r", unit);
|
||||
/* If not read whole record, skip till end */
|
||||
if (uptr->u4 >= 0) {
|
||||
sim_activate(uptr, (uptr->u4) * 20);
|
||||
uptr->u3 |= MT_READDONE;
|
||||
if (uptr->POS >= 0) {
|
||||
sim_activate(uptr, (uptr->POS) * 20);
|
||||
uptr->CMD |= MT_READDONE;
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
} else {
|
||||
sim_debug(DEBUG_DATA, dptr, "Read data unit=%d %d %02o\n\r",
|
||||
unit, uptr->u4, ch);
|
||||
if (uptr->u4 == 0) { /* In IRG */
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
unit, uptr->POS, ch);
|
||||
if (uptr->POS == 0) { /* In IRG */
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
} else
|
||||
@ -634,19 +641,19 @@ t_stat mt_srv(UNIT * uptr)
|
||||
case 0xf:
|
||||
switch (cmd) {
|
||||
case MT_WTM:
|
||||
if (uptr->u4 == 0) {
|
||||
if (uptr->POS == 0) {
|
||||
if (sim_tape_wrp(uptr)) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->u4 ++;
|
||||
uptr->POS ++;
|
||||
sim_activate(uptr, 500);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d\n", unit);
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
r = sim_tape_wrtmk(uptr);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
@ -654,24 +661,24 @@ t_stat mt_srv(UNIT * uptr)
|
||||
break;
|
||||
|
||||
case MT_BSR:
|
||||
switch (uptr->u4 ) {
|
||||
switch (uptr->POS ) {
|
||||
case 0:
|
||||
if (sim_tape_bot(uptr)) {
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
}
|
||||
uptr->u4 ++;
|
||||
uptr->POS ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
uptr->u4++;
|
||||
uptr->POS++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
/* We don't set EOF on BSR */
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4++;
|
||||
uptr->POS++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
@ -680,12 +687,12 @@ t_stat mt_srv(UNIT * uptr)
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITEXP);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
@ -693,38 +700,38 @@ t_stat mt_srv(UNIT * uptr)
|
||||
break;
|
||||
|
||||
case MT_BSF:
|
||||
switch(uptr->u4) {
|
||||
switch(uptr->POS) {
|
||||
case 0:
|
||||
if (sim_tape_bot(uptr)) {
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
break;
|
||||
}
|
||||
uptr->u4 ++;
|
||||
uptr->POS ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Backspace file unit=%d\n", unit);
|
||||
r = sim_tape_sprecr(uptr, &reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4++;
|
||||
uptr->POS++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else if (r == MTSE_BOT) {
|
||||
uptr->u4+= 2;
|
||||
uptr->POS+= 2;
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
sim_activate(uptr, 10 + (10 * reclen));
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
@ -732,21 +739,21 @@ t_stat mt_srv(UNIT * uptr)
|
||||
break;
|
||||
|
||||
case MT_FSR:
|
||||
switch(uptr->u4) {
|
||||
switch(uptr->POS) {
|
||||
case 0:
|
||||
uptr->u4 ++;
|
||||
uptr->POS ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
uptr->u4++;
|
||||
uptr->POS++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4 = 3;
|
||||
uptr->POS = 3;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else if (r == MTSE_EOM) {
|
||||
uptr->u4 = 4;
|
||||
uptr->POS = 4;
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
|
||||
@ -754,17 +761,17 @@ t_stat mt_srv(UNIT * uptr)
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITEXP);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
case 4:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
@ -772,20 +779,20 @@ t_stat mt_srv(UNIT * uptr)
|
||||
break;
|
||||
|
||||
case MT_FSF:
|
||||
switch(uptr->u4) {
|
||||
switch(uptr->POS) {
|
||||
case 0:
|
||||
uptr->u4 ++;
|
||||
uptr->POS ++;
|
||||
sim_activate(uptr, 500);
|
||||
break;
|
||||
case 1:
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit);
|
||||
r = sim_tape_sprecf(uptr, &reclen);
|
||||
if (r == MTSE_TMK) {
|
||||
uptr->u4++;
|
||||
uptr->POS++;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
|
||||
sim_activate(uptr, 50);
|
||||
} else if (r == MTSE_EOM) {
|
||||
uptr->u4+= 2;
|
||||
uptr->POS+= 2;
|
||||
sim_activate(uptr, 50);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
|
||||
@ -793,13 +800,13 @@ t_stat mt_srv(UNIT * uptr)
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Skip done unit=%d\n", unit);
|
||||
break;
|
||||
case 3:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
break;
|
||||
@ -807,15 +814,15 @@ t_stat mt_srv(UNIT * uptr)
|
||||
break;
|
||||
|
||||
case MT_ERG:
|
||||
switch (uptr->u4) {
|
||||
switch (uptr->POS) {
|
||||
case 0:
|
||||
if (sim_tape_wrp(uptr)) {
|
||||
uptr->u5 |= SNS_CMDREJ;
|
||||
uptr->u3 &= ~MT_CMDMSK;
|
||||
uptr->SNS |= SNS_CMDREJ;
|
||||
uptr->CMD &= ~MT_CMDMSK;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
set_devattn(addr, SNS_DEVEND|SNS_UNITCHK);
|
||||
} else {
|
||||
uptr->u4 ++;
|
||||
uptr->POS ++;
|
||||
sim_activate(uptr, 500);
|
||||
}
|
||||
break;
|
||||
@ -823,36 +830,36 @@ t_stat mt_srv(UNIT * uptr)
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Erase unit=%d\n", unit);
|
||||
r = sim_tape_wrgap(uptr, 35);
|
||||
sim_activate(uptr, 5000);
|
||||
uptr->u4++;
|
||||
uptr->POS++;
|
||||
break;
|
||||
case 2:
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_REW:
|
||||
if (uptr->u4 == 0) {
|
||||
uptr->u4 ++;
|
||||
if (uptr->POS == 0) {
|
||||
uptr->POS ++;
|
||||
sim_activate(uptr, 30000);
|
||||
mt_busy[bufnum] &= ~1;
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d\n", unit);
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
r = sim_tape_rewind(uptr);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
}
|
||||
break;
|
||||
|
||||
case MT_RUN:
|
||||
if (uptr->u4 == 0) {
|
||||
uptr->u4 ++;
|
||||
if (uptr->POS == 0) {
|
||||
uptr->POS ++;
|
||||
mt_busy[bufnum] &= ~1;
|
||||
sim_activate(uptr, 30000);
|
||||
} else {
|
||||
sim_debug(DEBUG_DETAIL, dptr, "Unload unit=%d\n", unit);
|
||||
uptr->u3 &= ~(MT_CMDMSK);
|
||||
uptr->CMD &= ~(MT_CMDMSK);
|
||||
r = sim_tape_detach(uptr);
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
}
|
||||
@ -867,9 +874,9 @@ mt_ini(UNIT * uptr, t_bool f)
|
||||
{
|
||||
DEVICE *dptr = find_dev_from_unit(uptr);
|
||||
|
||||
uptr->u3 &= UNIT_ADDR_MASK;
|
||||
uptr->CMD &= UNIT_ADDR_MASK;
|
||||
if ((uptr->flags & MTUF_9TR) == 0)
|
||||
uptr->u3 |= MT_ODD|MT_CONV|MT_MDEN_800;
|
||||
uptr->CMD |= MT_ODD|MT_CONV|MT_MDEN_800;
|
||||
mt_busy[GET_DEV_BUF(dptr->flags)] = 0;
|
||||
}
|
||||
|
||||
@ -882,24 +889,24 @@ mt_reset(DEVICE * dptr)
|
||||
t_stat
|
||||
mt_attach(UNIT * uptr, CONST char *file)
|
||||
{
|
||||
uint16 addr = GET_UADDR(uptr->u3);
|
||||
uint16 addr = GET_UADDR(uptr->CMD);
|
||||
t_stat r;
|
||||
|
||||
if ((r = sim_tape_attach_ex(uptr, file, 0, 0)) != SCPE_OK)
|
||||
return r;
|
||||
set_devattn(addr, SNS_DEVEND);
|
||||
uptr->u3 &= UNIT_ADDR_MASK;
|
||||
uptr->u4 = 0;
|
||||
uptr->u5 = 0;
|
||||
uptr->CMD &= UNIT_ADDR_MASK;
|
||||
uptr->POS = 0;
|
||||
uptr->SNS = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat
|
||||
mt_detach(UNIT * uptr)
|
||||
{
|
||||
uptr->u3 &= UNIT_ADDR_MASK;
|
||||
uptr->u4 = 0;
|
||||
uptr->u5 = 0;
|
||||
uptr->CMD &= UNIT_ADDR_MASK;
|
||||
uptr->POS = 0;
|
||||
uptr->SNS = 0;
|
||||
return sim_tape_detach(uptr);
|
||||
}
|
||||
|
||||
@ -911,10 +918,10 @@ mt_boot(int32 unit_num, DEVICE * dptr)
|
||||
if ((uptr->flags & UNIT_ATT) == 0)
|
||||
return SCPE_UNATT; /* attached? */
|
||||
if ((uptr->flags & MTUF_9TR) == 0) {
|
||||
uptr->u3 &= UNIT_ADDR_MASK;
|
||||
uptr->u3 |= MT_ODD|MT_CONV|MT_MDEN_800;
|
||||
uptr->CMD &= UNIT_ADDR_MASK;
|
||||
uptr->CMD |= MT_ODD|MT_CONV|MT_MDEN_800;
|
||||
}
|
||||
return chan_boot(GET_UADDR(uptr->u3), dptr);
|
||||
return chan_boot(GET_UADDR(uptr->CMD), dptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* ibm360_sys.c: IBM 360 Simulator system interface.
|
||||
|
||||
Copyright (c) 2017, Richard Cornwell
|
||||
Copyright (c) 2017-2020, Richard Cornwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user