summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/mb89352.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/mb89352.cpp')
-rw-r--r--src/devices/machine/mb89352.cpp671
1 files changed, 0 insertions, 671 deletions
diff --git a/src/devices/machine/mb89352.cpp b/src/devices/machine/mb89352.cpp
deleted file mode 100644
index 62b9adb78bb..00000000000
--- a/src/devices/machine/mb89352.cpp
+++ /dev/null
@@ -1,671 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Barry Rodewald
-/*
- * Fujitsu MB89352A SCSI Protocol Controller
- *
- * Should be compatible with the MB87030/31, and MB89351
- *
- * Used on the Sharp X68000 Super, X68000 XVI and X68030 (internal), and on SCSI expansion cards for any X680x0 (external)
- * Also used in Sega's Soreike Kokology 1/2 (drives CD-ROM)
- *
- * Registers (based on datasheet):
- *
- * 0: BDID (Bus Device ID)
- * bit = device ID (ie: bit 2 = device 2) (read)
- * bit 0 = ID1, bit 1 = ID2, bit 2 = ID4 (write)
- *
- * 1: SCTL (SPC Control)
- * (all read/write)
- * bit 0 = INT Enable
- * bit 1 = Reselect Enable
- * bit 2 = Select Enable
- * bit 3 = Parity Enable
- * bit 4 = Arbitration Phase Enable
- * bit 5 = Diag Mode
- * bit 6 = Control Reset
- * bit 7 = Reset and Disable
- *
- * 2: SCMD (Command)
- * bits 0-2 = Transfer Modifier (read)
- * bit 0 = Term Mode (write)
- * bit 2 = PRG Xfer (write)
- * bit 3 = Intercept Xfer (read/write)
- * bit 4 = RST Out (read/write)
- * bits 5-7 = Command code (read/write) (would have been nice if these codes were mentioned in the datasheet...)
- * 000 = Bus release
- * 001 = Selection
- * 010 = Reset ATN
- * 011 = Set ATN
- * 100 = Transfer
- * 101 = Transfer Pause
- * 110 = Reset ACK/REQ
- * 111 = Set ACK/REQ
- *
- * 3: Unused
- *
- * 4: INTS (Interrupt Sense)
- * on write, clear interrupt
- * on read:
- * bit 0 = Reset Condition
- * bit 1 = SPC Hard Error
- * bit 2 = Timeout
- * bit 3 = Service Required
- * bit 4 = Command Complete
- * bit 5 = Disconnect
- * bit 6 = Reselected
- * bit 7 = Selected
- *
- * 5: PSNS (Phase Sense) (read-only)
- * b7 b0
- * | REQ | ACK | ATN | SEL | BSY | MSG | C/D | I/O |
- * SDGC (SPC Diag. Control) (write-only)
- * bit 5 = Xfer Enable
- * bit 4 = Unused
- * all other bits are Diag. of the matching inputs above.
- *
- * 6: SSTS (SPC Status) (read-only)
- * bit 0 = DREG Empty
- * bit 1 = DREG Full
- * bit 2 = TC=0
- * bit 3 = SCSI RST
- * bit 4 = Xfer in progress
- * bit 5 = SPC BSY
- * bit 6 = Connected to Target
- * bit 7 = Connected to Initiator
- *
- * 7: SERR (SCSI Error Status) (read-only)
- * bit 1 = Short Transfer Period
- * bit 3 = TC Parity Error
- * bit 5 = Xfer Out (related to SDGC bit 5)
- * bits 6,7 = Data error (10 = undefined, 00 = no error, 01 and 11 = parity error)
- *
- * 8: PCTL (Phase Control)
- * (read/write)
- * bits 0-2 = transfer phase ( | MSG | C/D | I/O | )
- * bits 7 = Bus Free interrupt enable
- * other bits read 0
- *
- * 9: MBC (Modified Byte Counter)
- * (read-only)
- * bits 0-3 = MBC bits 0-3
- * other bits read 0
- *
- * A: DREG (Data Register)
- * 8-bit FIFO
- *
- * B: TEMP (Temporary Register)
- * on read, from SCSI
- * on write, to SCSI
- *
- * C, D, E: TCH, TCM, TCL (Transfer Counter High, Mid, Low)
- * 24-bit transfer counter
- *
- */
-
-#include "emu.h"
-#include "mb89352.h"
-
-// SCSI lines readable via PSNS register (reg 5)
-#define MB89352_LINE_REQ 0x80
-#define MB89352_LINE_ACK 0x40
-#define MB89352_LINE_ATN 0x20
-#define MB89352_LINE_SEL 0x10
-#define MB89352_LINE_BSY 0x08
-#define MB89352_LINE_MSG 0x04
-#define MB89352_LINE_CD 0x02
-#define MB89352_LINE_IO 0x01
-
-// INTS bits
-#define INTS_RESET 0x01
-#define INTS_HARD_ERROR 0x02
-#define INTS_TIMEOUT 0x04
-#define INTS_SERVICE_REQUIRED 0x08
-#define INTS_COMMAND_COMPLETE 0x10
-#define INTS_DISCONNECTED 0x20
-#define INTS_RESELECTION 0x40
-#define INTS_SELECTION 0x80
-
-// SSTS status bits
-#define SSTS_DREG_EMPTY 0x01
-#define SSTS_DREG_FULL 0x02
-#define SSTS_TC_ZERO 0x04
-#define SSTS_SCSI_RST 0x08
-#define SSTS_XFER_IN_PROGRESS 0x10
-#define SSTS_SPC_BSY 0x20
-#define SSTS_TARG_CONNECTED 0x40
-#define SSTS_INIT_CONNECTED 0x80
-
-// SERR error status bits
-#define SERR_OFFSET 0x01
-#define SERR_SHORT_XFR 0x02
-#define SERR_PHASE_ERR 0x04
-#define SERR_TC_PAR 0x08
-#define SERR_SPC_PAR 0x40
-#define SERR_SCSI_PAR 0x80
-
-
-/*
- * Device config
- */
-
-DEFINE_DEVICE_TYPE(MB89352A, mb89352_device, "mb89352", "Fujitsu MB89352A")
-
-
-/*
- * Device
- */
-
-mb89352_device::mb89352_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- legacy_scsi_host_adapter(mconfig, MB89352A, tag, owner, clock),
- m_irq_cb(*this),
- m_drq_cb(*this)
-{
-}
-
-void mb89352_device::device_start()
-{
- legacy_scsi_host_adapter::device_start();
-
- m_phase = SCSI_PHASE_BUS_FREE;
- m_target = 0;
- m_command_index = 0;
- m_line_status = 0x00;
- m_spc_status = 0x01; // presumably the data reg is empty to start with
- m_error_status = 0x00;
- m_transfer_count = 0;
- if(m_transfer_count == 0)
- m_spc_status |= SSTS_TC_ZERO;
- m_ints = 0x00;
-
- m_irq_cb.resolve_safe();
- m_drq_cb.resolve_safe();
-
- // allocate read timer
- m_transfer_timer = timer_alloc(TIMER_TRANSFER);
-}
-
-void mb89352_device::device_reset()
-{
- m_phase = SCSI_PHASE_BUS_FREE;
- m_target = 0;
- m_command_index = 0;
- m_line_status = 0x00;
- m_error_status = 0x00;
- m_transfer_count = 0;
- m_spc_status = 0x05; // presumably the data reg is empty to start with
- m_busfree_int_enable = 0;
-}
-
-void mb89352_device::device_stop()
-{
-}
-
-// get the length of a SCSI command based on it's command byte type
-int mb89352_device::get_scsi_cmd_len(uint8_t cbyte)
-{
- int group;
-
- group = (cbyte>>5) & 7;
-
- if (group == 0) return 6;
- if (group == 1 || group == 2) return 10;
- if (group == 5) return 12;
-
- fatalerror("MB89352: Unknown SCSI command group %d\n", group);
-
- // never executed
- //return 6;
-}
-
-void mb89352_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch(id)
- {
- case TIMER_TRANSFER:
- // TODO: check interrupts are actually enabled
- {
- m_drq_cb(1);
- }
- break;
- }
-}
-
-void mb89352_device::set_phase(int phase)
-{
- m_phase = phase;
- switch(phase)
- {
- case SCSI_PHASE_BUS_FREE:
- m_line_status = 0;
- m_spc_status &= ~SSTS_XFER_IN_PROGRESS;
- break;
- case SCSI_PHASE_COMMAND:
- m_line_status |= MB89352_LINE_REQ;
- m_line_status &= ~MB89352_LINE_ACK;
- m_line_status &= ~MB89352_LINE_MSG;
- m_line_status |= MB89352_LINE_CD;
- m_line_status &= ~MB89352_LINE_IO;
- break;
- case SCSI_PHASE_STATUS:
-// m_line_status |= MB89352_LINE_REQ;
-// m_line_status &= ~MB89352_LINE_ACK;
- m_line_status &= ~MB89352_LINE_MSG;
- m_line_status |= MB89352_LINE_CD;
- m_line_status |= MB89352_LINE_IO;
- break;
- case SCSI_PHASE_DATAIN:
-// m_line_status |= MB89352_LINE_REQ;
-// m_line_status &= ~MB89352_LINE_ACK;
- m_line_status &= ~MB89352_LINE_MSG;
- m_line_status &= ~MB89352_LINE_CD;
- m_line_status |= MB89352_LINE_IO;
- break;
- case SCSI_PHASE_DATAOUT:
-// m_line_status |= MB89352_LINE_REQ;
-// m_line_status &= ~MB89352_LINE_ACK;
- m_line_status &= ~MB89352_LINE_MSG;
- m_line_status &= ~MB89352_LINE_CD;
- m_line_status &= ~MB89352_LINE_IO;
- break;
- case SCSI_PHASE_MESSAGE_IN:
-// m_line_status |= MB89352_LINE_REQ;
-// m_line_status &= ~MB89352_LINE_ACK;
- m_line_status |= MB89352_LINE_MSG;
- m_line_status |= MB89352_LINE_CD;
- m_line_status |= MB89352_LINE_IO;
- break;
- case SCSI_PHASE_MESSAGE_OUT:
-// m_line_status |= MB89352_LINE_REQ;
-// m_line_status &= ~MB89352_LINE_ACK;
- m_line_status |= MB89352_LINE_MSG;
- m_line_status |= MB89352_LINE_CD;
- m_line_status &= ~MB89352_LINE_IO;
- break;
- }
- logerror("MB89352: phase set to %i\n",m_phase);
-}
-
-uint8_t mb89352_device::mb89352_r(offs_t offset)
-{
- uint8_t ret;
- switch(offset & 0x0f)
- {
- case 0x00: // BDID - Bus Device ID
- return (1 << m_bdid);
- case 0x01: // SCTL - SPC Control
- ret = 0x00;
- if(m_arbit_enable)
- ret |= 0x10;
- if(m_parity_enable)
- ret |= 0x08;
- if(m_sel_enable)
- ret |= 0x04;
- if(m_resel_enable)
- ret |= 0x02;
- if(m_int_enable)
- ret |= 0x01;
- return ret;
- case 0x02: // SCMD - Command
- return m_scmd;
- case 0x03: // Unused
- return 0xff;
- case 0x04: // INTS - Interrupt Sense
- return m_ints;
- case 0x05: // PSNS - Phase Sense
- return m_line_status; // active low -- but Human68k expects it to be zero?
- case 0x06: // SSTS - SPC Status
- return m_spc_status;
- case 0x07: // SERR - SPC Error Status
- /* #define SERR_SCSI_PAR 0x80
- #define SERR_SPC_PAR 0x40
- #define SERR_TC_PAR 0x08
- #define SERR_PHASE_ERR 0x04
- #define SERR_SHORT_XFR 0x02
- #define SERR_OFFSET 0x01*/
- return 0;
- case 0x08: // PCTL - Phase Control
- return ((m_busfree_int_enable) ? (m_line_status & 0x07) | 0x80 : (m_line_status & 0x07));
- case 0x0a: // DREG - Data register (for data transfers)
- if(m_spc_status & SSTS_XFER_IN_PROGRESS)
- {
- m_data = m_buffer[m_transfer_index % 512];
- m_transfer_index++;
- m_transfer_count--;
- if(m_transfer_index % 512 == 0)
- read_data(m_buffer, 512);
- if(m_transfer_count == 0)
- {
- // End of transfer
- m_spc_status &= ~SSTS_XFER_IN_PROGRESS;
- m_spc_status |= SSTS_DREG_EMPTY;
- m_ints |= INTS_COMMAND_COMPLETE;
- if(m_int_enable != 0)
- m_irq_cb(1);
- if(m_phase == SCSI_PHASE_MESSAGE_IN)
- set_phase(SCSI_PHASE_BUS_FREE);
- else if(m_phase == SCSI_PHASE_DATAIN)
- set_phase(SCSI_PHASE_STATUS);
- }
- }
- return m_data;
- case 0x0b: // TEMP - Temporary
- logerror("mb89352: read temporary register.\n");
- return m_temp;
- case 0x0c: // TCH - Transfer Counter High
- return (m_transfer_count & 0x00ff0000) >> 16;
- case 0x0d: // TCM - Transfer Counter Mid
- return (m_transfer_count & 0x0000ff00) >> 8;
- case 0x0e: // TCL - Transfer Counter Low
- return (m_transfer_count & 0x000000ff);
- default:
- logerror("mb89352: read from register %02x\n",offset & 0x0f);
- }
- return 0xff;
-}
-
-void mb89352_device::mb89352_w(offs_t offset, uint8_t data)
-{
- switch(offset & 0x0f)
- {
- case 0x00: // BDID - Bus Device ID
- m_bdid = data;
- m_spc_status &= ~SSTS_TARG_CONNECTED;
- m_spc_status |= SSTS_INIT_CONNECTED;
- logerror("mb89352: BDID set to %i\n",data);
- break;
- case 0x01: // SCTL - SPC Control
- if(data & 0x80) // reset and disable
- {
- device_reset();
- logerror("mb89352: SCTL: Reset and disable.\n");
- }
- if(data & 0x10)
- {
- m_arbit_enable = 1;
- logerror("mb89352: SCTL: Arbitration enabled.\n");
- }
- else
- m_arbit_enable = 0;
- if(data & 0x08)
- {
- m_parity_enable = 1;
- logerror("mb89352: SCTL: Parity enabled.\n");
- }
- else
- m_parity_enable = 0;
- if(data & 0x04)
- {
- m_sel_enable = 1;
- logerror("mb89352: SCTL: Selection enabled.\n");
- }
- else
- m_sel_enable = 0;
- if(data & 0x02)
- {
- m_resel_enable = 1;
- logerror("mb89352: SCTL: Reselection enabled.\n");
- }
- else
- m_resel_enable = 0;
- if(data & 0x01)
- {
- m_int_enable = 1;
- logerror("mb89352: SCTL: Interrupts enabled.\n");
- }
- else
- {
- m_int_enable = 0;
- logerror("mb89352: SCTL: Interrupts disabled.\n");
- }
- break;
- case 0x02: // SCMD - Command
- /* From NetBSD/x68k source
- #define SCMD_BUS_REL 0x00
- #define SCMD_SELECT 0x20
- #define SCMD_RST_ATN 0x40
- #define SCMD_SET_ATN 0x60
- #define SCMD_XFR 0x80
- #define SCMD_XFR_PAUSE 0xa0
- #define SCMD_RST_ACK 0xc0
- #define SCMD_SET_ACK 0xe0
- */
- m_scmd = data;
- switch((data & 0xe0) >> 5)
- {
- case 0x00:
- // Bus Free
- m_line_status = 0;
- m_spc_status &= ~SSTS_TARG_CONNECTED;
- m_spc_status &= ~SSTS_INIT_CONNECTED;
- m_spc_status &= ~SSTS_XFER_IN_PROGRESS;
- set_phase(SCSI_PHASE_BUS_FREE);
- if(m_busfree_int_enable)
- {
- if(m_int_enable != 0)
- m_irq_cb(1);
- }
- logerror("mb89352: SCMD: Bus free\n");
- break;
- case 0x01:
- // Selection
- m_target = m_temp;
- m_target &= ~(1 << m_bdid); // mask off the bit relating to initiator
- switch(m_target)
- {
- case 0x01: m_target = 0; break;
- case 0x02: m_target = 1; break;
- case 0x04: m_target = 2; break;
- case 0x08: m_target = 3; break;
- case 0x10: m_target = 4; break;
- case 0x20: m_target = 5; break;
- case 0x40: m_target = 6; break;
- case 0x80: m_target = 7; break;
- }
- if(m_sel_enable != 0)
- {
- //m_ints |= INTS_SELECTION;
- }
- select(m_target);
- set_phase(SCSI_PHASE_COMMAND); // straight to command phase, may need a delay between selection and command phases
- m_line_status |= MB89352_LINE_SEL;
- m_line_status |= MB89352_LINE_BSY;
- m_spc_status &= ~SSTS_TARG_CONNECTED;
- m_spc_status |= SSTS_INIT_CONNECTED;
- m_spc_status |= SSTS_SPC_BSY;
- m_ints |= INTS_COMMAND_COMPLETE;
- if(m_int_enable != 0)
- m_irq_cb(1);
- logerror("mb89352: SCMD: Selection (SCSI ID%i)\n",m_target);
- break;
- case 0x02: // Reset ATN
- m_line_status &= ~MB89352_LINE_ATN;
- logerror("mb89352: SCMD: Reset ATN\n");
- break;
- case 0x03: // Set ATN
- m_line_status |= MB89352_LINE_ATN;
- logerror("mb89352: SCMD: Set ATN\n");
- break;
- case 0x04: // Transfer
- m_transfer_index = 0;
- m_spc_status |= SSTS_XFER_IN_PROGRESS;
- if(m_phase == SCSI_PHASE_DATAIN) // if we are reading data...
- {
- m_spc_status &= ~SSTS_DREG_EMPTY; // DREG is no longer empty
- logerror("data-in\n");
- read_data(m_buffer, 512);
- }
- if(m_phase == SCSI_PHASE_MESSAGE_IN)
- {
- m_spc_status &= ~SSTS_DREG_EMPTY; // DREG is no longer empty
- m_data = 0;
- m_temp = 0x00;
- set_phase(SCSI_PHASE_BUS_FREE);
- logerror("message-in\n");
- m_spc_status &= ~SSTS_XFER_IN_PROGRESS;
- m_command_index = 0;
- }
- if(m_phase == SCSI_PHASE_COMMAND)
- {
- logerror("command-in\n");
- m_spc_status |= SSTS_SPC_BSY;
- }
- logerror("mb89352: SCMD: Start Transfer %02x\n",m_phase);
- break;
- case 0x05: // Transfer pause
- logerror("mb89352: SCMD: Pause Transfer\n");
- break;
- case 0x06: // reset REQ/ACK
- m_line_status &= ~MB89352_LINE_ACK;
- if(m_phase != SCSI_PHASE_BUS_FREE)
- {
- m_line_status |= MB89352_LINE_REQ;
- }
- else
- {
- m_spc_status &= ~SSTS_INIT_CONNECTED;
- m_spc_status &= ~SSTS_TARG_CONNECTED;
- m_spc_status &= ~SSTS_SPC_BSY;
- }
- logerror("mb89352: SCMD: Reset REQ/ACK\n");
- break;
- case 0x07: // set REQ/ACK
- m_line_status &= ~MB89352_LINE_REQ;
- m_line_status |= MB89352_LINE_ACK;
- logerror("mb89352: SCMD: Set REQ/ACK\n");
- if(m_phase == SCSI_PHASE_COMMAND)
- {
- m_command[m_command_index++] = m_temp; // temp register puts data onto the SCSI bus
- if(m_command_index >= get_scsi_cmd_len(m_command[0]))
- {
- int x;
- int phase;
- // execute SCSI command
- send_command(m_command, m_command_index);
- phase = get_phase();
- if(m_command[0] == 1) // Rezero Unit - not implemented in SCSI code
- set_phase(SCSI_PHASE_STATUS);
- else
- set_phase(phase);
- logerror("Command executed: ");
- //m_spc_status &= ~SSTS_SPC_BSY;
- //m_ints |= INTS_COMMAND_COMPLETE;
-
- for(x=0;x<m_command_index;x++)
- logerror(" %02x",m_command[x]);
- logerror("\n");
- }
- return;
- }
- if(m_phase == SCSI_PHASE_STATUS)
- {
- m_temp = get_status();
- set_phase(SCSI_PHASE_MESSAGE_IN);
- return;
- }
- if(m_phase == SCSI_PHASE_MESSAGE_IN)
- {
- m_temp = 0x00;
- set_phase(SCSI_PHASE_BUS_FREE);
- m_command_index = 0;
- return;
- }
- break;
- default:
- logerror("mb89352: SCMD: Unimplemented command %02x\n",(data & 0xe0) >> 5);
- break;
- }
- break;
- case 0x04: // INTS - Interrupt Sense
- m_ints &= ~data; // resets relevant status bits to zero
- m_irq_cb(0); // clear IRQ
- logerror("mb89352: Reset INTS status bits %02x\n",data);
- break;
- case 0x08: // PCTL - Phase control
- if((data & 0x80) == 0 && (m_phase == SCSI_PHASE_SELECT)) // if writing 0 to bit 7, selection phase is reset
- {
- m_ints &= ~INTS_SELECTION;
- m_target = 0;
- logerror("mb89352: PCTL selection cancelled\n");
- }
- // writing to the low 3 bits sets the phase
- if((m_phase & 0x07) != (data & 0x07))
- set_phase(data & 0x07);
- m_busfree_int_enable = data & 0x80;
- logerror("mb89352: PCTL write %02x\n",data);
- break;
- case 0x0a: // DREG - Data register
- if(m_phase == SCSI_PHASE_COMMAND)
- {
- m_command[m_command_index++] = data;
- if(m_command_index >= get_scsi_cmd_len(m_command[0]))
- {
- int x;
- int phase;
- // execute SCSI command
- send_command(m_command, m_command_index);
- phase = get_phase();
- if(m_command[0] == 1) // Rezero Unit - not implemented in SCSI code
- set_phase(SCSI_PHASE_STATUS);
- else
- set_phase(phase);
- logerror("Command executed: ");
- //m_ints |= INTS_COMMAND_COMPLETE;
-
- for(x=0;x<m_command_index;x++)
- logerror(" %02x",m_command[x]);
- logerror("\n");
- }
- return;
- }
- if(m_spc_status & SSTS_XFER_IN_PROGRESS)
- {
- m_buffer[m_transfer_index % 512] = data;
- m_spc_status |= SSTS_DREG_EMPTY; // DREG is empty once sent
- m_transfer_index++;
- m_transfer_count--;
- if(m_transfer_index % 512 == 0)
- write_data(m_buffer, 512);
- if(m_transfer_count == 0)
- {
- // End of transfer
- m_spc_status &= ~SSTS_XFER_IN_PROGRESS;
- m_spc_status |= SSTS_DREG_EMPTY;
- m_ints |= INTS_COMMAND_COMPLETE;
- if(m_int_enable != 0)
- m_irq_cb(1);
- set_phase(SCSI_PHASE_STATUS);
- }
- }
- break;
- case 0x0b: // TEMP - Temporary
- m_temp = data;
- logerror("mb89352: Write %02x to temporary register\n",data);
- break;
- case 0x0c: // TCH - Transfer Counter High
- m_transfer_count = (m_transfer_count & 0x0000ffff) | (data << 16);
- if(m_transfer_count == 0)
- m_spc_status |= SSTS_TC_ZERO;
- else
- m_spc_status &= ~SSTS_TC_ZERO;
- logerror("mb89352: TCH: Write %02x [%06x]\n",data,m_transfer_count);
- break;
- case 0x0d: // TCM - Transfer Counter Mid
- m_transfer_count = (m_transfer_count & 0x00ff00ff) | (data << 8);
- if(m_transfer_count == 0)
- m_spc_status |= SSTS_TC_ZERO;
- else
- m_spc_status &= ~SSTS_TC_ZERO;
- logerror("mb89352: TCM: Write %02x [%06x]\n",data,m_transfer_count);
- break;
- case 0x0e: // TCL - Transfer Counter Low
- m_transfer_count = (m_transfer_count & 0x00ffff00) | data;
- if(m_transfer_count == 0)
- m_spc_status |= SSTS_TC_ZERO;
- else
- m_spc_status &= ~SSTS_TC_ZERO;
- logerror("mb89352: TCL: Write %02x [%06x]\n",data,m_transfer_count);
- break;
- default:
- logerror("mb89352: write %02x to register %02x\n",data,offset & 0x0f);
- }
-}