1 /*  mp-b2.c: SWTP SS-50/SS-30 MP-B2 Mother Board
2 
3     Copyright (c) 2011, William A. Beech
4 
5     Permission is hereby granted, free of charge, to any person obtaining a
6     copy of this software and associated documentation files (the "Software"),
7     to deal in the Software without restriction, including without limitation
8     the rights to use, copy, modify, merge, publish, distribute, sublicense,
9     and/or sell copies of the Software, and to permit persons to whom the
10     Software is furnished to do so, subject to the following conditions:
11 
12     The above copyright notice and this permission notice shall be included in
13     all copies or substantial portions of the Software.
14 
15     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18     WILLIAM A. BEECH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19     IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20     CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22     Except as contained in this notice, the name of William A. Beech shall not be
23     used in advertising or otherwise to promote the sale, use or other dealings
24     in this Software without prior written authorization from William A. Beech.
25 */
26 
27 #include <stdio.h>
28 #include "swtp_defs.h"
29 
30 #define UNIT_V_RAM_0000   (UNIT_V_UF)   /* MP-8M board 0 enable */
31 #define UNIT_RAM_0000     (1 << UNIT_V_RAM_0000)
32 #define UNIT_V_RAM_2000   (UNIT_V_UF+1) /* MP-8M board 1 enable */
33 #define UNIT_RAM_2000     (1 << UNIT_V_RAM_2000)
34 #define UNIT_V_RAM_4000   (UNIT_V_UF+2) /* MP-8M board 2 enable */
35 #define UNIT_RAM_4000     (1 << UNIT_V_RAM_4000)
36 #define UNIT_V_RAM_6000   (UNIT_V_UF+3) /* MP-8M board 3 enable */
37 #define UNIT_RAM_6000     (1 << UNIT_V_RAM_6000)
38 #define UNIT_V_RAM_A000   (UNIT_V_UF+4) /* MP-8M board 4 enable */
39 #define UNIT_RAM_A000     (1 << UNIT_V_RAM_A000)
40 #define UNIT_V_RAM_C000   (UNIT_V_UF+5) /* MP-8M board 5 enable */
41 #define UNIT_RAM_C000     (1 << UNIT_V_RAM_C000)
42 
43 /* function prototypes */
44 
45 /* empty I/O device routine */
46 int32 nulldev(int32 io, int32 data);
47 
48 /* SS-50 bus routines */
49 int32 MB_get_mbyte(int32 addr);
50 int32 MB_get_mword(int32 addr);
51 void MB_put_mbyte(int32 addr, int32 val);
52 void MB_put_mword(int32 addr, int32 val);
53 
54 /* MP-8M bus routines */
55 extern int32 mp_8m_get_mbyte(int32 addr);
56 extern void mp_8m_put_mbyte(int32 addr, int32 val);
57 
58 /* SS-50 I/O address space functions */
59 
60 /* MP-S serial I/O routines */
61 extern int32 sio0s(int32 io, int32 data);
62 extern int32 sio0d(int32 io, int32 data);
63 extern int32 sio1s(int32 io, int32 data);
64 extern int32 sio1d(int32 io, int32 data);
65 
66 /* DC-4 FDC I/O routines */
67 extern int32 fdcdrv(int32 io, int32 data);
68 extern int32 fdccmd(int32 io, int32 data);
69 extern int32 fdctrk(int32 io, int32 data);
70 extern int32 fdcsec(int32 io, int32 data);
71 extern int32 fdcdata(int32 io, int32 data);
72 
73 /* This is the I/O configuration table.  There are 32 possible
74 device addresses, if a device is plugged into a port it's routine
75 address is here, 'nulldev' means no device is available
76 */
77 
78 struct idev {
79         int32 (*routine)();
80 };
81 
82 struct idev dev_table[32] = {
83         {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /*Port 0 8000-8003 */
84         {&sio0s},   {&sio0d},   {&sio1s},   {&sio1d},   /*Port 1 8004-8007 */
85 /* sio1x routines just return the last value read on the matching
86    sio0x routine.  SWTBUG tests for the MP-C with most port reads! */
87         {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /*Port 2 8008-800B*/
88         {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /*Port 3 800C-800F*/
89         {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /*Port 4 8010-8013*/
90         {&fdcdrv},  {&nulldev}, {&nulldev}, {&nulldev}, /*Port 5 8014-8017*/
91         {&fdccmd},  {&fdctrk},  {&fdcsec},  {&fdcdata}, /*Port 6 8018-801B*/
92         {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}  /*Port 7 801C-801F*/
93 };
94 
95 /* dummy i/o device */
96 
nulldev(int32 io,int32 data)97 int32 nulldev(int32 io, int32 data)
98 {
99     if (io == 0)
100         return (0xFF);
101     return 0;
102 }
103 
104 /* Mother Board data structures
105 
106     MB_dev        Mother Board device descriptor
107     MB_unit       Mother Board unit descriptor
108     MB_reg        Mother Board register list
109     MB_mod        Mother Board modifiers list
110 */
111 
112 UNIT MB_unit = {
113     UDATA (NULL, 0, 0)
114 };
115 
116 REG MB_reg[] = {
117     { NULL }
118 };
119 
120 MTAB MB_mod[] = {
121     { UNIT_RAM_0000, UNIT_RAM_0000, "BD0 On", "BD0", NULL },
122     { UNIT_RAM_0000, 0, "BD0 Off", "NOBD0", NULL },
123     { UNIT_RAM_2000, UNIT_RAM_2000, "BD1 On", "BD1", NULL },
124     { UNIT_RAM_2000, 0, "BD1 Off", "NOBD1", NULL },
125     { UNIT_RAM_4000, UNIT_RAM_4000, "BD2 On", "BD2", NULL },
126     { UNIT_RAM_4000, 0, "BD2 Off", "NOBD2", NULL },
127     { UNIT_RAM_6000, UNIT_RAM_6000, "BD3 On", "BD3", NULL },
128     { UNIT_RAM_6000, 0, "BD3 Off", "NOBD3", NULL },
129     { UNIT_RAM_A000, UNIT_RAM_A000, "BD4 On", "BD4", NULL },
130     { UNIT_RAM_A000, 0, "BD4 Off", "NOBD4", NULL },
131     { UNIT_RAM_C000, UNIT_RAM_C000, "BD5 On", "BD5", NULL },
132     { UNIT_RAM_C000, 0, "BD5 Off", "NOBD5", NULL },
133     { 0 }
134 };
135 
136 DEBTAB MB_debug[] = {
137     { "ALL", DEBUG_all },
138     { "FLOW", DEBUG_flow },
139     { "READ", DEBUG_read },
140     { "WRITE", DEBUG_write },
141     { "LEV1", DEBUG_level1 },
142     { "LEV2", DEBUG_level2 },
143     { NULL }
144 };
145 
146 DEVICE MB_dev = {
147     "MP-B2",                            //name
148     &MB_unit,                           //units
149     MB_reg,                             //registers
150     MB_mod,                             //modifiers
151     1,                                  //numunits
152     16,                                 //aradix
153     16,                                 //awidth
154     1,                                  //aincr
155     16,                                 //dradix
156     8,                                  //dwidth
157     NULL,                               //examine
158     NULL,                               //deposit
159     NULL,                               //reset
160     NULL,                               //boot
161     NULL,                               //attach
162     NULL,                               //detach
163     NULL,                               //ctxt
164     DEV_DEBUG,                          //flags
165     0,                                  //dctrl
166     MB_debug,                           /* debflags */
167     NULL,                               //msize
168     NULL                                //lname
169 };
170 
171 /*  get a byte from memory */
172 
MB_get_mbyte(int32 addr)173 int32 MB_get_mbyte(int32 addr)
174 {
175     int32 val;
176 
177     if (MB_dev.dctrl & DEBUG_read)
178         printf("MB_get_mbyte: addr=%04X\n", addr);
179     switch(addr & 0xF000) {
180         case 0x0000:
181         case 0x1000:
182             if (MB_unit.flags & UNIT_RAM_0000) {
183                 val = mp_8m_get_mbyte(addr) & 0xFF;
184                 if (MB_dev.dctrl & DEBUG_read)
185                     printf("MB_get_mbyte: mp_8m val=%02X\n", val);
186                 return val;
187             } else
188                 return 0xFF;
189         case 0x2000:
190         case 0x3000:
191             if (MB_unit.flags & UNIT_RAM_2000) {
192                 val = mp_8m_get_mbyte(addr) & 0xFF;
193                 if (MB_dev.dctrl & DEBUG_read)
194                     printf("MB_get_mbyte: mp_8m val=%02X\n", val);
195                 return val;
196             } else
197                 return 0xFF;
198         case 0x4000:
199         case 0x5000:
200             if (MB_unit.flags & UNIT_RAM_4000) {
201                 val = mp_8m_get_mbyte(addr) & 0xFF;
202                 if (MB_dev.dctrl & DEBUG_read)
203                     printf("MB_get_mbyte: mp_8m val=%02X\n", val);
204                 return val;
205             } else
206                 return 0xFF;
207         case 0x6000:
208         case 0x7000:
209             if (MB_unit.flags & UNIT_RAM_6000) {
210                 val = mp_8m_get_mbyte(addr) & 0xFF;
211                 if (MB_dev.dctrl & DEBUG_read)
212                     printf("MB_get_mbyte: mp_8m val=%02X\n", val);
213                 return val;
214             } else
215                 return 0xFF;
216         case 0x8000:
217             val = (dev_table[addr - 0x8000].routine(0, 0)) & 0xFF;
218             if (MB_dev.dctrl & DEBUG_read)
219                 printf("MB_get_mbyte: I/O addr=%04X val=%02X\n", addr, val);
220             return val;
221         case 0xA000:
222         case 0xB000:
223             if (MB_unit.flags & UNIT_RAM_A000) {
224                 val = mp_8m_get_mbyte(addr) & 0xFF;
225                 if (MB_dev.dctrl & DEBUG_read)
226                     printf("MB_get_mbyte: mp_8m val=%02X\n", val);
227                 return val;
228             } else
229                 return 0xFF;
230         case 0xC000:
231         case 0xD000:
232             if (MB_unit.flags & UNIT_RAM_C000) {
233                 val = mp_8m_get_mbyte(addr) & 0xFF;
234                 if (MB_dev.dctrl & DEBUG_read)
235                     printf("MB_get_mbyte: mp_8m val=%02X\n", val);
236                 return val;
237             } else
238                 return 0xFF;
239         default:
240             return 0xFF;
241     }
242 }
243 
244 /*  get a word from memory */
245 
MB_get_mword(int32 addr)246 int32 MB_get_mword(int32 addr)
247 {
248     int32 val;
249 
250 
251     if (MB_dev.dctrl & DEBUG_read)
252         printf("MB_get_mword: addr=%04X\n", addr);
253     val = (MB_get_mbyte(addr) << 8);
254     val |= MB_get_mbyte(addr+1);
255     val &= 0xFFFF;
256     if (MB_dev.dctrl & DEBUG_read)
257         printf("MB_get_mword: val=%04X\n", val);
258     return val;
259 }
260 
261 /*  put a byte to memory */
262 
MB_put_mbyte(int32 addr,int32 val)263 void MB_put_mbyte(int32 addr, int32 val)
264 {
265     if (MB_dev.dctrl & DEBUG_write)
266         printf("MB_put_mbyte: addr=%04X, val=%02X\n", addr, val);
267     switch(addr & 0xF000) {
268         case 0x0000:
269         case 0x1000:
270             if (MB_unit.flags & UNIT_RAM_0000) {
271                 mp_8m_put_mbyte(addr, val);
272                 return;
273             }
274         case 0x2000:
275         case 0x3000:
276             if (MB_unit.flags & UNIT_RAM_2000) {
277                 mp_8m_put_mbyte(addr, val);
278                 return;
279             }
280         case 0x4000:
281         case 0x5000:
282             if (MB_unit.flags & UNIT_RAM_4000) {
283                 mp_8m_put_mbyte(addr, val);
284                 return;
285             }
286         case 0x6000:
287         case 0x7000:
288             if (MB_unit.flags & UNIT_RAM_6000) {
289                 mp_8m_put_mbyte(addr, val);
290                 return;
291             }
292         case 0x8000:
293             dev_table[addr - 0x8000].routine(1, val);
294             return;
295         case 0xA000:
296         case 0xB000:
297             if (MB_unit.flags & UNIT_RAM_A000) {
298                 mp_8m_put_mbyte(addr, val);
299                 return;
300             }
301         case 0xC000:
302         case 0xD000:
303             if (MB_unit.flags & UNIT_RAM_C000) {
304                 mp_8m_put_mbyte(addr, val);
305                 return;
306             }
307         default:
308             return;
309     }
310 }
311 
312 /*  put a word to memory */
313 
MB_put_mword(int32 addr,int32 val)314 void MB_put_mword(int32 addr, int32 val)
315 {
316     if (MB_dev.dctrl & DEBUG_write)
317         printf("MB_ptt_mword: addr=%04X, val=%04X\n", addr, val);
318     MB_put_mbyte(addr, val >> 8);
319     MB_put_mbyte(addr+1, val);
320 }
321 
322 /* end of mp-b2.c */
323