summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine/hecdisk2.c
blob: e9650371d59473ef04e4fd412019436cf65eefeb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*******************************************************/
/************ HECDISK2.C  in machine  ******************/
/*******************************************************/

/* Lecteur de disquette DISK II pour les machines :
        Hector HRX
        Hector MX40c
        Hector MX80c

        JJStacino  jj.stacino@aliceadsl.fr

    15/02/2010 : Start of the disc2 project! JJStacino
    26/09/2010 : first sending with bug2 (the first "dir" command finih with a crash of the Z80 disc II proc) JJStacino
    01/11/2010 : first time ending boot sequence, probleme on the CP/M lauch JJStacino
    20/11/2010 : synchronization between uPD765 and Z80 are now OK, CP/M runnig! JJStacino
    28/11/2010 : Found at Bratislava that the disk writing with TRANS X: is NOT WORKING (the exchange Hector=>Disc2 ok)
*/

#include "emu.h"

#include "sound/wave.h"         /* for K7 sound*/
#include "sound/discrete.h"     /* for 1 Bit sound*/
#include "machine/upd765.h"     /* for floppy disc controller */
#include "formats/hect_dsk.h"
#include "cpu/z80/z80.h"

#include "includes/hec2hrp.h"

/* Callback uPD request */

/* How uPD765 works:
        * First we send at uPD the string of command (p.e. 9 bytes for read starting by 0x46) on port 60h
                between each byte, check the authorization of the uPD by reading the status register
        * When the command is finish, the data arrive with DMA interrupt, then:
                If read: in port 70 to retrieve the data,
                If write: in port 70 send the data
        * When all data had been send the uPD launch an INT
        * The Z80 Disc2 writes in FF12 a flag
        * if the flag is set, end of DMA function,
        * At this point the Z80 can read the RESULT in port 61h
*/

/*****************************************************************************/
/****  Management of the interrupts (NMI and INT)between uPD765 and Z80 ******/
/*****************************************************************************/

/* upd765 INT is connected to interrupt of Z80 within a RNMI hardware authorization */
WRITE_LINE_MEMBER( hec2hrp_state::disc2_fdc_interrupt )
{
	m_IRQ_current_state = state;
	m_disc2cpu->set_input_line(INPUT_LINE_IRQ0, state && m_hector_disc2_RNMI ? ASSERT_LINE : CLEAR_LINE);
}

/* upd765 DRQ is connected to NMI of Z80 within a RNMI hardware authorization */
WRITE_LINE_MEMBER( hec2hrp_state::disc2_fdc_dma_irq )
{
	m_NMI_current_state = state;
	m_disc2cpu->set_input_line(INPUT_LINE_NMI,  state && m_hector_disc2_RNMI ? ASSERT_LINE : CLEAR_LINE);
}

// RESET the disc2 Unit !
void hec2hrp_state::hector_disc2_reset()
{
	// Initialization Disc2 unit
	m_disc2cpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE);
	machine().device<upd765a_device>("upd765")->reset();
	// Select ROM memory to cold restart
	membank("bank3")->set_entry(DISCII_BANK_ROM);

	// Clear the Hardware's buffers
	m_hector_disc2_data_r_ready=0x0; /* =ff when PC2 = true and data in read buffer (state->m_hector_disc2_data_read) */
	m_hector_disc2_data_w_ready=0x0; /* =ff when Disc 2 Port 40 had send a data in write buffer (state->m_hector_disc2_data_write) */
	m_hector_disc2_data_read=0;      /* Data send by Hector to Disc 2 when PC2=true */
	m_hector_disc2_data_write=0;     /* Data send by Disc 2 to Hector when Write Port I/O 40 */
	m_hector_disc2_RNMI = 0;         /* State of I/O 50 D5 = authorization for INT / NMI */
	m_IRQ_current_state=0;           /* Clear the IRQ active request */
	m_NMI_current_state=0;           /* Clear the DMA active request */
}

/*****************************************************************************/
/********************  Port handling of the Z80 Disc II unit *****************/
/*****************************************************************************/
READ8_MEMBER( hec2hrp_state::hector_disc2_io00_port_r)
{
	/* Switch Disc 2 to RAM to let full RAM acces */
	membank("bank3")->set_entry(DISCII_BANK_RAM);
	return 0;
}
WRITE8_MEMBER( hec2hrp_state::hector_disc2_io00_port_w)
{
	/* Switch Disc 2 to RAM to let full RAM acces */
	membank("bank3")->set_entry(DISCII_BANK_RAM);
}
READ8_MEMBER( hec2hrp_state::hector_disc2_io20_port_r)
{
	// You can implemente the 8251 chip communication here !
	return 0;
}
WRITE8_MEMBER( hec2hrp_state::hector_disc2_io20_port_w)
{
	// You can implemente the 8251 chip communication here !
}
READ8_MEMBER( hec2hrp_state::hector_disc2_io30_port_r)
{
	return m_hector_disc2_data_r_ready;
}
WRITE8_MEMBER( hec2hrp_state::hector_disc2_io30_port_w)
{
	// Nothing here !
}

READ8_MEMBER( hec2hrp_state::hector_disc2_io40_port_r)
{
	/* Read data send by Hector, by Disc2*/
	m_hector_disc2_data_r_ready = 0x00;  /* Clear memory info read ready*/
	return m_hector_disc2_data_read;     /* send the data !*/
}

WRITE8_MEMBER( hec2hrp_state::hector_disc2_io40_port_w)   /* Write data send by Disc2, to Hector*/
{
	m_hector_disc2_data_write = data;        /* Memorization data*/
	m_hector_disc2_data_w_ready = 0x80;  /* Memorization data write ready in D7*/
}

READ8_MEMBER( hec2hrp_state::hector_disc2_io50_port_r)    /*Read memory info write ready*/
{
	return m_hector_disc2_data_w_ready;
}

WRITE8_MEMBER( hec2hrp_state::hector_disc2_io50_port_w) /* I/O Port to the stuff of Disc2*/
{
	upd765a_device *fdc = machine().device<upd765a_device>("upd765");

	/* FDC Motor Control - Bit 0/1 defines the state of the FDD 0/1 motor */
	machine().device<floppy_connector>("upd765:0")->get_device()->mon_w(BIT(data, 0));    // Moteur floppy A:
	machine().device<floppy_connector>("upd765:1")->get_device()->mon_w(BIT(data, 1));    // Moteur floppy B:

	/* Write bit TC uPD765 on D4 of port I/O 50 */
	fdc->tc_w(BIT(data, 4));


	/* Authorization interrupt and NMI with RNMI signal*/
	m_hector_disc2_RNMI = BIT(data, 5);
	m_disc2cpu->set_input_line(INPUT_LINE_IRQ0, m_IRQ_current_state && m_hector_disc2_RNMI ? ASSERT_LINE : CLEAR_LINE);
	m_disc2cpu->set_input_line(INPUT_LINE_NMI,  m_NMI_current_state && m_hector_disc2_RNMI ? ASSERT_LINE : CLEAR_LINE);
}