1 // license:BSD-3-Clause
2 // copyright-holders:Jonathan Gevaryahu
3 /* Xerox NoteTaker, 1978
4 * Driver by Jonathan Gevaryahu
5
6 * Notetaker Team At Xerox PARC 1976-1981:
7 Alan Kay - Team Lead
8 Bruce Horn - BIOS code and NoteTaker Hardware/Electronics Design (Ethernet, others)
9 Ted Kaehler - SmallTalk-76 code porting[2] and more ( http://tedkaehler.weather-dimensions.com/us/ted/index.html )
10 Dan Ingalls - Later BitBlt engine and SmallTalk-76 kernel and more[3]
11 Doug Fairbairn - NoteTaker Hardware/Electronics Design (EmulatorP, IOP, ADC, Alto Debug/Test Interface)
12 ( http://www.computerhistory.org/atchm/author/dfairbairn/ )
13 Ed Wakida - NoteTaker Hardware/Electronics Design (Tablet/Touch interface)
14 Bob Nishimura - NoteTaker Hardware/Electronics Design (PSU/Cabling/Machining/Battery)
15 James "Jim" Leung - NoteTaker Hardware/Electronics Design (Alto Debug/Test Interface)
16 Ron Freeman - NoteTaker Hardware/Electronics Design (Keyboard, Disk/Display)
17 Ben Sato - NoteTaker Hardware/Electronics Design (Memory/Timing, ECC)
18 B. Wang - NoteTaker Hardware/Electronics Design (Keyboard)
19 Larry Tesler - NoteTaker Hardware/Electronics Design (Ethernet, others)
20 Dale Mann - NoteTaker Hardware/Electronics Design (Ethernet, Circuit Assembly)
21 Lawrence "Larry" D. Stewart - NoteTaker Hardware/Electronics Design (Mouse)
22 Jim Althoff - Smalltalk-78 and Smalltalk-80
23 Adele Goldberg - Smalltalk team
24 Diana Merry-Shapiro - Original BitBlt from Smalltalk-72
25 Dave Robson - Smalltalk team
26 Ted Strollo - IC/VLSI design (MPC580 cell library)
27 Bert Sutherland - Manager of Systems Science Laboratory (SSL)
28 Terri Doughty - Administration, Editing
29 Chris Jeffers - Smalltalk music
30 <there are probably others I've missed>
31
32 * History of the machine can be found at http://freudenbergs.de/bert/publications/Ingalls-2014-Smalltalk78.pdf
33
34 * The notetaker has an 8-slot backplane, with the following cards in it:
35 * I/O Processor card (8086@8Mhz, 8259pic, 4k ROM, Keyboard UART, DAC1200 (multiplexed to 2 channels))
36 * Emulation Processor card (8086@5Mhz, 8259pic, 8k of local RAM with Parity check logic)
37 * Disk/Display card (WD1791 FDC, CRT5027 CRTC, EIA UART, AD571 ADC, 8->1 Analog Multiplexer)
38 * Memory Control Module \_ (bus control, buffering, refresh, Parity/ECC/Syndrome logic lives on these boards)
39 * Memory Data Module /
40 * Memory Storage Module x2 (the 4116 DRAMs live on these boards)
41 * Battery Module *OR* debugger module type A or B (debugger module has an
42 i8255 on it for alto<->notetaker comms, and allows alto to halt the cpus
43 [type A and B can debug either the emulator cpu or the iop respectively]
44 and dump registers to alto screen, etc)
45
46 * In 1980-1981 an Ethernet card with another 8086 on it was developed, but
47 it is unclear if this was ever fully functional, or if smalltalk-78
48 could even use it.
49
50 * Prototypes only, 10 units[2] manufactured 1978-1980
51 Known surviving units:
52 * One at CHM (missing? mouse, no media, has BIOP-2.0 roms)
53 * One at Xerox Museum at PARC (with mouse and 2? floppies, floppies were not imaged to the best of my knowledge, unknown roms)
54 * Rumor has it at least a few of the remaining units survived beyond these two.
55
56 * The NoteTaker used the BitBlt graphical operation (from SmallTalk-76) to do most graphical functions, in order to fit the SmallTalk code and programs within 256K of RAM[2]. The actual BitBlt code lives in ROM[3].
57
58 * As far as I am aware, no media (world disks/boot disks) for the NoteTaker have survived (except maybe the two disks at Xerox Museum at PARC), but an incomplete dump of the Smalltalk-76 'world' which was used to bootstrap Smalltalk-78 originally did survive on the Alto disks at CHM
59
60 * We are missing the dump for the i8748 Keyboard MCU which does row-column scanning and mouse quadrature reading, and talks to the main system via serial
61
62 * see http://bitsavers.informatik.uni-stuttgart.de/pdf/xerox/notetaker for additional information
63 * see http://xeroxalto.computerhistory.org/Filene/Smalltalk-76/ for the smalltalk-76 dump
64 * see http://xeroxalto.computerhistory.org/Indigo/BasicDisks/Smalltalk14.bfs!1_/ for more notetaker/smalltalk related files, including SmallTalk-80 files based on the notetaker smalltalk-78
65
66 References:
67 * [1] http://freudenbergs.de/bert/publications/Ingalls-2014-Smalltalk78.pdf
68 * [2] "Smalltalk and Object Orientation: An Introduction" By John Hunt, pages 45-46 [ISBN 978-3-540-76115-0]
69 * [3] http://bitsavers.trailing-edge.com/pdf/xerox/notetaker/memos/19790620_Z-IOP_1.5_ls.pdf
70 * [4] http://xeroxalto.computerhistory.org/Filene/Smalltalk-76/
71 * [5] http://bitsavers.trailing-edge.com/pdf/xerox/notetaker/memos/19790118_NoteTaker_System_Manual.pdf
72
73 TODO: everything below.
74 * Get smalltalk-78 loaded as a rom and forced into ram on startup, since no boot disks have survived (or if any survived, they are not dumped)
75 * Hack together a functional boot disk using the recovered EP bootloader and smalltalk engine code from the alto disks.
76 * Harris 6402 keyboard UART (within keyboard, next to MCU)
77 * The harris 6402 UART is pin compatible with WD TR1865 UART, as well as the AY-3-1015A/D
78 (These are 5v-only versions of the older WD TR1602 and AY-5-1013 parts which used 5v and 12v)
79 * HLE for the missing i8748[5] MCU in the keyboard which reads the mouse quadratures and buttons and talks serially to the Keyboard UART
80 * floppy controller wd1791 and its interrupt
81 According to [3] and [5] the format is double density/MFM, 128 bytes per sector, 16 sectors per track, 1 or 2 sided, for 170K or 340K per disk. Drive spins at 300RPM.
82 * hook up the DiskInt from the wd1791 either using m_fdc->intrq_r() polling or using device lines (latter is a much better idea)
83
84 WIP:
85 * crt5027 video controller - the iop side is hooked up, screen drawing 'works' but is scrambled due to not emulating the clock chain halting and clock changing yet. The crt5027 core also needs the odd/even interrupt hooked up, and proper interlace support as well as clock change/screen resize support (down to DC/no clock, which I guess should be a 1x1 single black pixel!)
86 * pic8259 interrupt controller - this is attached as a device, but only the vblank interrupt is hooked to it yet.
87 * Harris 6402 serial/EIA UART - connected to iop, other end isn't connected anywhere, interrupt is not connected
88 * Harris 6402 keyboard UART (within notetaker) - connected to iop, other end isn't connected anywhere, interrupt is not connected
89 * The DAC, its FIFO and its timer are hooked up and the v2.0 bios beeps, but the stereo latches are not hooked up at all, DAC is treated as mono for now
90
91 DONE:
92 * i/o cpu i/o area needs the memory map worked out per the schematics - done
93 * figure out the correct memory maps for the 256kB of shared ram, and what part of ram constitutes the framebuffer - done
94 - 256k of shared ram maps at 00000-3ffff for both cpus with special mem regs at fffec,fffee. the ram mirrors 4 times on the emulatorcpu only, iop the 40000-fffff area is open bus.
95 - framebuffer, at least for bios 1.5, lives from 0x4000-0xd5ff, exactly 640x480 pixels 1bpp, interlaced (even? plane is at 4000-8aff, odd? plane is at 8b00-d5ff); however the starting address of the framebuffer is configurable to any address within the 0x0000-0x1ffff range? (this exact range is unclear)
96 * figure out how the emulation-cpu boots and where its 8k of local ram maps to - done
97 - both cpus boot, reset and system int controls are accessed at fffea from either cpu; emulatorcpu's 8k of ram lives at the beginning of its address space, but can be disabled in favor of mainram at the same addresses
98 * 82s147 DISKSEP PROM regenerated from original BCPL code
99 * SETMEMREQ PROM retyped from binary listing
100 * TIMING PROM retyped from binary listing
101 */
102
103 #include "emu.h"
104 #include "cpu/i86/i86.h"
105 #include "imagedev/floppy.h"
106 #include "machine/ay31015.h"
107 #include "machine/clock.h"
108 #include "machine/pic8259.h"
109 #include "machine/wd_fdc.h"
110 #include "sound/dac.h"
111 #include "video/tms9927.h"
112 #include "emupal.h"
113 #include "screen.h"
114 #include "speaker.h"
115
116
117 class notetaker_state : public driver_device
118 {
119 public:
notetaker_state(const machine_config & mconfig,device_type type,const char * tag)120 notetaker_state(const machine_config &mconfig, device_type type, const char *tag) :
121 driver_device(mconfig, type, tag) ,
122 m_iop_cpu(*this, "iop_cpu"),
123 m_iop_pic(*this, "iop_pic8259"),
124 m_ep_cpu(*this, "ep_cpu"),
125 m_ep_pic(*this, "ep_pic8259"),
126 m_kbduart(*this, "kbduart"),
127 m_eiauart(*this, "eiauart"),
128 m_crtc(*this, "crt5027"),
129 m_dac(*this, "dac"),
130 m_fdc(*this, "wd1791"),
131 m_floppy0(*this, "wd1791:0"),
132 m_floppy(nullptr)
133 {
134 }
135
136 void notetakr(machine_config &config);
137
138 void init_notetakr();
139
140 private:
141 enum
142 {
143 TIMER_FIFOCLK,
144 };
145
146 // devices
147 required_device<cpu_device> m_iop_cpu;
148 required_device<pic8259_device> m_iop_pic;
149 required_device<cpu_device> m_ep_cpu;
150 required_device<pic8259_device> m_ep_pic;
151 required_device<ay31015_device> m_kbduart;
152 required_device<ay31015_device> m_eiauart;
153 required_device<crt5027_device> m_crtc;
154 required_device<dac_word_interface> m_dac;
155 required_device<fd1791_device> m_fdc;
156 required_device<floppy_connector> m_floppy0;
157 floppy_image_device *m_floppy;
158
159 std::unique_ptr<uint16_t[]> m_mainram;
160
161 //declarations
162 // screen
163 uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
164 // basic io
165 void IPConReg_w(uint16_t data);
166 void EPConReg_w(uint16_t data);
167 void FIFOReg_w(uint16_t data);
168 void FIFOBus_w(uint16_t data);
169 void DiskReg_w(uint16_t data);
170 void LoadDispAddr_w(uint16_t data);
171
172 // uarts
173 uint16_t ReadOPStatus_r();
174 void LoadKeyCtlReg_w(uint16_t data);
175 void KeyDataReset_w(uint16_t data);
176 void KeyChipReset_w(uint16_t data);
177 uint16_t ReadEIAStatus_r();
178 void LoadEIACtlReg_w(uint16_t data);
179 void EIADataReset_w(uint16_t data);
180 void EIAChipReset_w(uint16_t data);
181 // mem map stuff
182 uint16_t iop_r(offs_t offset);
183 void iop_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
184 uint16_t ep_mainram_r(offs_t offset, uint16_t mem_mask);
185 void ep_mainram_w(offs_t offset, uint16_t data, uint16_t mem_mask);
186 //variables
187 // IPConReg
188 uint8_t m_BootSeqDone;
189 uint8_t m_ProcLock;
190 uint8_t m_CharCtr;
191 uint8_t m_DisableROM;
192 uint8_t m_CorrOn_q;
193 uint8_t m_LedInd6;
194 uint8_t m_LedInd7;
195 uint8_t m_LedInd8;
196 // FIFOReg
197 uint8_t m_TabletYOn;
198 uint8_t m_TabletXOn;
199 uint8_t m_FrSel2;
200 uint8_t m_FrSel1;
201 uint8_t m_FrSel0;
202 uint8_t m_SHConB;
203 uint8_t m_SHConA;
204 uint8_t m_SetSH;
205 // DiskReg
206 uint8_t m_ADCSpd0;
207 uint8_t m_ADCSpd1;
208 uint8_t m_StopWordClock_q;
209 uint8_t m_ClrDiskCont_q;
210 uint8_t m_ProgBitClk1;
211 uint8_t m_ProgBitClk2;
212 uint8_t m_ProgBitClk3;
213 uint8_t m_AnSel4;
214 uint8_t m_AnSel2;
215 uint8_t m_AnSel1;
216 uint8_t m_DriveSel1;
217 uint8_t m_DriveSel2;
218 uint8_t m_DriveSel3;
219 uint8_t m_SideSelect;
220 uint8_t m_Disk5VOn;
221 uint8_t m_Disk12VOn;
222 // output fifo, for DAC
223 uint16_t m_outfifo[16]; // technically three 74LS225 5bit*16stage FIFO chips, arranged as a 16 stage, 12-bit wide fifo (one bit unused per chip)
224 uint8_t m_outfifo_count;
225 uint8_t m_outfifo_tail_ptr;
226 uint8_t m_outfifo_head_ptr;
227 // fifo timer
228 emu_timer *m_FIFO_timer;
229 TIMER_CALLBACK_MEMBER(timer_fifoclk);
230 // framebuffer display starting address
231 uint16_t m_DispAddr;
232
233 // separate cpu resets
234 void iop_reset();
235 void ep_reset();
236
237 // overrides
238 virtual void machine_start() override;
239 virtual void machine_reset() override;
240
241 void iop_io(address_map &map);
242 void iop_mem(address_map &map);
243 void ep_io(address_map &map);
244 void ep_mem(address_map &map);
245
246 virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
247 };
248
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)249 void notetaker_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
250 {
251 switch (id)
252 {
253 case TIMER_FIFOCLK:
254 timer_fifoclk(ptr, param);
255 break;
256 default:
257 throw emu_fatalerror("Unknown id in notetaker_state::device_timer");
258 }
259 }
260
TIMER_CALLBACK_MEMBER(notetaker_state::timer_fifoclk)261 TIMER_CALLBACK_MEMBER(notetaker_state::timer_fifoclk)
262 {
263 uint16_t data;
264 //pop a value off the fifo and send it to the dac.
265 #ifdef FIFO_VERBOSE
266 if (m_outfifo_count == 0) logerror("output fifo is EMPTY! repeating previous sample!\n");
267 #endif
268 data = m_outfifo[m_outfifo_tail_ptr];
269 // if fifo is empty (tail ptr == head ptr), do not increment the tail ptr, otherwise do.
270 if (m_outfifo_count > 0)
271 {
272 m_outfifo_tail_ptr++;
273 m_outfifo_count--;
274 }
275 m_outfifo_tail_ptr&=0xF;
276 m_dac->write(data);
277 m_FIFO_timer->adjust(attotime::from_hz(((960_kHz_XTAL/10)/4)/((m_FrSel0<<3)+(m_FrSel1<<2)+(m_FrSel2<<1)+1)));
278 }
279
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)280 uint32_t notetaker_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
281 {
282 // have to figure out what resolution we're drawing to here and draw appropriately to screen
283 // code borrowed/stolen from video/mac.cpp
284 uint32_t const video_base = (m_DispAddr << 3) & 0x1ffff;
285 #ifdef DEBUG_VIDEO
286 logerror("Video Base = 0x%05x\n", video_base);
287 #endif
288 uint16_t const *video_ram_field1 = &m_mainram[video_base / 2];
289 uint16_t const *video_ram_field2 = &m_mainram[(video_base + 0x4b00) / 2];
290
291 for (int y = 0; y < 480; y++)
292 {
293 uint16_t *const line = &bitmap.pix(y);
294
295 for (int x = 0; x < 640; x += 16)
296 {
297 uint16_t const word = *((y & 1) ? video_ram_field2 : video_ram_field1)++;
298 for (int b = 0; b < 16; b++)
299 {
300 line[x + b] = BIT(word, 15 - b);
301 }
302 }
303 }
304 return 0;
305 }
306
IPConReg_w(uint16_t data)307 void notetaker_state::IPConReg_w(uint16_t data)
308 {
309 m_BootSeqDone = BIT(data, 7);
310 m_ProcLock = BIT(data, 6); // bus lock for this processor (hold other processor in wait state)
311 m_CharCtr = BIT(data, 5); // battery charge control (incorrectly called 'Char counter' in source code)
312 m_DisableROM = BIT(data, 4); // disable rom at 0000-0fff
313 m_CorrOn_q = BIT(data, 3); // CorrectionOn (ECC correction enabled); also LedInd5
314 m_LedInd6 = BIT(data, 2);
315 m_LedInd7 = BIT(data, 1);
316 m_LedInd8 = BIT(data, 0);
317 popmessage("LEDS: CR1: %d, CR2: %d, CR3: %d, CR4: %d", BIT(data, 2), BIT(data, 3), BIT(data, 1), BIT(data, 0)); // cr1 and 2 are in the reverse order as expected, according to the schematic
318 }
319
320 /* handlers for the two system hd6402s (ay-5-1013 equivalent) */
321 /* * Keyboard hd6402 */
ReadOPStatus_r()322 uint16_t notetaker_state::ReadOPStatus_r() // 74ls368 hex inverter at #l7 provides 4 bits, inverted
323 {
324 uint16_t data = 0xFFF0;
325 data |= (m_outfifo_count >= 1) ? 0 : 0x08; // m_FIFOOutRdy is true if the fifo has at least 1 word in it, false otherwise
326 data |= (m_outfifo_count < 16) ? 0 : 0x04; // m_FIFOInRdy is true if the fifo has less than 16 words in it, false otherwise
327 // note /SWE is permanently enabled, so we don't enable it here for HD6402 reading
328 data |= m_kbduart->dav_r( ) ? 0 : 0x02; // DR - pin 19
329 data |= m_kbduart->tbmt_r() ? 0 : 0x01; // TBRE - pin 22
330 #ifdef DEBUG_READOPSTATUS
331 logerror("ReadOPStatus read, returning %04x\n", data);
332 #endif
333 return data;
334 }
335
LoadKeyCtlReg_w(uint16_t data)336 void notetaker_state::LoadKeyCtlReg_w(uint16_t data)
337 {
338 m_kbduart->write_cs(0);
339 m_kbduart->write_np(BIT(data, 4)); // PI - pin 35
340 m_kbduart->write_tsb(BIT(data, 3)); // SBS - pin 36
341 m_kbduart->write_nb2(BIT(data, 2)); // CLS2 - pin 37
342 m_kbduart->write_nb1(BIT(data, 1)); // CLS1 - pin 38
343 m_kbduart->write_eps(BIT(data, 0)); // EPE - pin 39
344 m_kbduart->write_cs(1);
345 }
346
KeyDataReset_w(uint16_t data)347 void notetaker_state::KeyDataReset_w(uint16_t data)
348 {
349 m_kbduart->write_rdav(0); // DDR - pin 18
350 m_kbduart->write_rdav(1); // ''
351 }
352
KeyChipReset_w(uint16_t data)353 void notetaker_state::KeyChipReset_w(uint16_t data)
354 {
355 m_kbduart->write_xr(0); // MR - pin 21
356 m_kbduart->write_xr(1); // ''
357 }
358
359 /* FIFO (DAC) Stuff and ADC stuff */
FIFOReg_w(uint16_t data)360 void notetaker_state::FIFOReg_w(uint16_t data)
361 {
362 m_SetSH = (data&0x8000)?1:0;
363 m_SHConA = (data&0x4000)?1:0;
364 m_SHConB = (data&0x2000)?1:0;
365 m_FrSel0 = (data&0x1000)?1:0;
366 m_FrSel1 = (data&0x0800)?1:0;
367 m_FrSel2 = (data&0x0400)?1:0;
368 m_TabletXOn = (data&0x0200)?1:0;
369 m_TabletYOn = (data&0x0100)?1:0;
370 m_FIFO_timer->adjust(attotime::from_hz(((960_kHz_XTAL/10)/4)/((m_FrSel0<<3)+(m_FrSel1<<2)+(m_FrSel2<<1)+1)));
371 /* FIFO timer is clocked by 960khz divided by 10 (74ls162 decade counter),
372 divided by 4 (mc14568B with divider 1 pins set to 4), divided by
373 1,3,5,7,9,11,13,15 (or 0,2,4,6,8,10,12,14?)
374 */
375 // todo: handle tablet and sample/hold stuff as well
376 logerror("Write to 0x60 FIFOReg_w of %04x; fifo timer set to %d hz\n", data, ((((960'000)/10)/4)/((m_FrSel0<<3)+(m_FrSel1<<2)+(m_FrSel2<<1)+1)));
377 }
378
FIFOBus_w(uint16_t data)379 void notetaker_state::FIFOBus_w(uint16_t data)
380 {
381 if (m_outfifo_count == 16)
382 {
383 #ifdef SPC_LOG_DSP
384 logerror("outfifo was full, write ignored!\n");
385 #endif
386 return;
387 }
388 m_outfifo[m_outfifo_head_ptr] = data >> 4;
389 m_outfifo_head_ptr++;
390 m_outfifo_count++;
391 m_outfifo_head_ptr&=0xF;
392 }
393
DiskReg_w(uint16_t data)394 void notetaker_state::DiskReg_w(uint16_t data)
395 {
396 /* See http://bitsavers.trailing-edge.com/pdf/xerox/notetaker/memos/19781023_More_NoteTaker_IO_Information.pdf
397 but note that bit 12 (called bit 3 in documentation) was changed between
398 oct 1978 and 1979 to reset the disk controller digital-PLL as
399 ClrDiskCont' rather than acting as ProgBitClk0, which is permanently
400 wired high instead, meaning only the 4.5Mhz - 18Mhz dot clocks are
401 available for the CRTC. */
402 m_ADCSpd0 = (data&0x8000)?1:0;
403 m_ADCSpd1 = (data&0x4000)?1:0;
404 m_StopWordClock_q = (data&0x2000)?1:0;
405 //if ((!(m_ClrDiskCont_q)) && (data&0x1000)) m_floppy->device_reset(); // reset on rising edge
406 m_ClrDiskCont_q = (data&0x1000)?1:0; // originally ProgBitClk0, but co-opted later to reset the FDC's external PLL
407 m_ProgBitClk1 = (data&0x0800)?1:0;
408 m_ProgBitClk2 = (data&0x0400)?1:0;
409 m_ProgBitClk3 = (data&0x0200)?1:0;
410 m_AnSel4 = (data&0x0100)?1:0;
411 m_AnSel2 = (data&0x80)?1:0;
412 m_AnSel1 = (data&0x40)?1:0;
413 m_DriveSel1 = (data&0x20)?1:0;
414 m_DriveSel2 = (data&0x10)?1:0; // drive 2 not present on hardware, but could work if present
415 m_DriveSel3 = (data&0x08)?1:0; // drive 3 not present on hardware, but could work if present
416 m_SideSelect = (data&0x04)?1:0;
417 m_Disk5VOn = (data&0x02)?1:0;
418 m_Disk12VOn = (data&0x01)?1:0;
419
420 // ADC stuff
421 //TODO
422
423 // FDC stuff
424 // first handle the motor stuff; we'll clobber whatever was in m_floppy, then reset it to what it should be
425 m_floppy = m_floppy0->get_device();
426 // Disk5VOn and 12VOn can be thought of as a crude MotorOn signal as the motor won't run with either? of them missing.
427 // However, a tech note involves adding a patch so that MotorOn is only activated if the drive is actually selected.
428 m_floppy->mon_w(!(m_Disk5VOn && m_Disk12VOn && m_DriveSel1));
429 //m_floppy = m_floppy1->get_device();
430 //m_floppy->mon_w(!(m_Disk5VOn && m_Disk12VOn && m_DriveSel2)); // Disk5VOn and 12VOn can be thought of as a crude MotorOn signal as the motor won't run with either? of them missing.
431 //m_floppy = m_floppy2->get_device();
432 //m_floppy->mon_w(!(m_Disk5VOn && m_Disk12VOn && m_DriveSel3)); // Disk5VOn and 12VOn can be thought of as a crude MotorOn signal as the motor won't run with either? of them missing.
433 // now restore m_floppy state to what it should be
434 if (m_DriveSel1) m_floppy = m_floppy0->get_device();
435 //else if (m_DriveSel2) m_floppy = m_floppy1->get_device();
436 //else if (m_DriveSel3) m_floppy = m_floppy2->get_device();
437 else m_floppy = nullptr;
438 m_fdc->set_floppy(m_floppy); // select the floppy
439 if (m_floppy)
440 {
441 m_floppy->ss_w(m_SideSelect);
442 }
443
444 // CRTC clock rate stuff
445 //TODO
446 }
447
LoadDispAddr_w(uint16_t data)448 void notetaker_state::LoadDispAddr_w(uint16_t data)
449 {
450 m_DispAddr = data;
451 // for future low level emulation: clear the current counter position here as well, as well as empty/reset the display fifo, and the setmemrq state.
452 }
453
454 /* EIA hd6402 */
ReadEIAStatus_r()455 uint16_t notetaker_state::ReadEIAStatus_r() // 74ls368 hex inverter at #f1 provides 2 bits, inverted
456 {
457 uint16_t data = 0xFFFC;
458 // note /SWE is permanently enabled, so we don't enable it here for HD6402 reading
459 data |= m_eiauart->dav_r( ) ? 0 : 0x02; // DR - pin 19
460 data |= m_eiauart->tbmt_r() ? 0 : 0x01; // TBRE - pin 22
461 return data;
462 }
463
LoadEIACtlReg_w(uint16_t data)464 void notetaker_state::LoadEIACtlReg_w(uint16_t data)
465 {
466 m_eiauart->write_cs(0);
467 m_eiauart->write_np(BIT(data, 4)); // PI - pin 35
468 m_eiauart->write_tsb(BIT(data, 3)); // SBS - pin 36
469 m_eiauart->write_nb2(BIT(data, 2)); // CLS2 - pin 37
470 m_eiauart->write_nb1(BIT(data, 1)); // CLS1 - pin 38
471 m_eiauart->write_eps(BIT(data, 0)); // EPE - pin 39
472 m_eiauart->write_cs(1);
473 }
474
EIADataReset_w(uint16_t data)475 void notetaker_state::EIADataReset_w(uint16_t data)
476 {
477 m_eiauart->write_rdav(0); // DDR - pin 18
478 m_eiauart->write_rdav(1); // ''
479 }
480
EIAChipReset_w(uint16_t data)481 void notetaker_state::EIAChipReset_w(uint16_t data)
482 {
483 m_eiauart->write_xr(0); // MR - pin 21
484 m_eiauart->write_xr(1); // ''
485 }
486
487
488 /* These next two members are memory map related for the iop */
iop_r(offs_t offset)489 uint16_t notetaker_state::iop_r(offs_t offset)
490 {
491 uint16_t *rom = (uint16_t *)(memregion("iop")->base());
492 rom += 0x7f800;
493 uint16_t *ram = m_mainram.get();
494 if ( (m_BootSeqDone == 0) || ((m_DisableROM == 0) && ((offset&0x7F800) == 0)) )
495 {
496 rom += (offset&0x7FF);
497 return *rom;
498 }
499 else
500 {
501 // are we in the FFFE8-FFFEF area where the parity/int/reset/etc stuff lives?
502 if (offset >= 0x7fff4) { logerror("attempt to read processor control regs at %d\n", offset<<1); return 0xFFFF; }
503 ram += offset;
504 return *ram;
505 }
506 }
507
iop_w(offs_t offset,uint16_t data,uint16_t mem_mask)508 void notetaker_state::iop_w(offs_t offset, uint16_t data, uint16_t mem_mask)
509 {
510 //uint16_t tempword;
511 uint16_t *ram = m_mainram.get();
512 if ( (m_BootSeqDone == 0) || ((m_DisableROM == 0) && ((offset&0x7F800) == 0)) )
513 {
514 logerror("attempt to write %04X to ROM-mapped area at %06X ignored\n", data, offset<<1);
515 return;
516 }
517 // are we in the FFFE8-FFFEF area where the parity/int/reset/etc stuff lives?
518 if (offset >= 0x7fff4) { logerror("attempt to write processor control regs at %d with %02X ignored\n", offset<<1, data); }
519 COMBINE_DATA(&ram[offset]);
520 }
521
522 /* Address map comes from http://bitsavers.informatik.uni-stuttgart.de/pdf/xerox/notetaker/schematics/19790423_Notetaker_IO_Processor.pdf
523 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 BootSeqDone DisableROM
524 mode 0: (to get the boot vector and for maybe 1 or 2 instructions afterward)
525 x x x x x x x x * * * * * * * * * * * * 0 x R ROM (writes are open bus)
526 mode 1: (during most of boot)
527 0 0 0 0 0 0 0 0 * * * * * * * * * * * * 1 0 R ROM (writes are open bus)
528 0 0 0 0 0 0 0 1 * * * * * * * * * * * * 1 0 RW RAM
529 0 0 0 0 0 0 1 * * * * * * * * * * * * * 1 0 RW RAM
530 <anything not all zeroes>x x x x x x x x x x x x x x 1 0 . Open Bus
531 mode 2: (during load of the emulatorcpu's firmware to the first 8k of shared ram which is on the emulatorcpu board)
532 0 0 * * * * * * * * * * * * * * * * * * 1 1 RW RAM
533 <anything not all zeroes>x x x x x x x x x x x x x x 1 1 . Open Bus
534 EXCEPT for the following, decoded by the memory address logic board:
535 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 x 1 x . Open Bus
536 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 x 1 x W FFFEA (Multiprocessor Control (reset/int/boot for each proc; data bits 3,2,1,0 = 0010 means IP, bits 3210 = 0111 means EP; all others ignored.))
537 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 x 1 x R FFFEC (Syndrome bits (gnd bit 15, parity bit 14, exp (ECC) bits 13-8, bits 7-0 are 'other' (?maybe highest address bits?)
538 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 x 1 x R FFFEE (Parity Error Address: row bits 15-8, column bits 7-0; reading this acknowledges a parity interrupt)
539
540 More or less:
541 BootSeqDone is 0, DisableROM is ignored, mem map is 0x00000-0xfffff reading is the 0x1000-long ROM, repeated every 0x1000 bytes. writing goes nowhere.
542 BootSeqDone is 1, DisableROM is 0, mem map is 0x00000-0x00fff reading is the 0x1000-long ROM, remainder of memory map goes to RAM or open bus. writing the ROM area goes nowhere, writing RAM goes to RAM.
543 BootSeqDone is 1, DisableROM is 1, mem map is entirely RAM or open bus for both reading and writing.
544 */
545
iop_mem(address_map & map)546 void notetaker_state::iop_mem(address_map &map)
547 {
548 /*
549 map(0x00000, 0x00fff).rom().region("iop", 0xff000); // rom is here if either BootSeqDone OR DisableROM are zero. the 1.5 source code and the schematics implies writes here are ignored while rom is enabled; if disablerom is 1 this goes to mainram
550 map(0x01000, 0x3ffff).ram().share("mainram"); // 256k of ram (less 8k), shared between both processors. rom goes here if bootseqdone is 0
551 // note 4000-d5ff is the framebuffer for the screen, in two sets of fields for odd/even interlace?
552 map(0xff000, 0xfffe7).rom().region("iop", 0xff000); // rom is only banked in here if bootseqdone is 0, so the reset vector is in the proper place. otherwise the memory control regs live at fffe8-fffef
553 //map(0xfffea, 0xfffeb).w(FUNC(notetaker_state::cpuCtl_w));
554 //map(0xfffec, 0xfffed).r(FUNC(notetaker_state::parityErrHi_r));
555 //map(0xfffee, 0xfffef).r(this. FUNC(notetaker_state::parityErrLo_r));
556 map(0xffff0, 0xfffff).rom().region("iop", 0xffff0);
557 */
558 map(0x00000, 0xfffff).rw(FUNC(notetaker_state::iop_r), FUNC(notetaker_state::iop_w)); // bypass MAME's memory map system as we need finer grained control
559 }
560
561 /* iop memory map comes from http://bitsavers.informatik.uni-stuttgart.de/pdf/xerox/notetaker/memos/19790605_Definition_of_8086_Ports.pdf
562 and from the schematic at http://bitsavers.informatik.uni-stuttgart.de/pdf/xerox/notetaker/schematics/19790423_Notetaker_IO_Processor.pdf
563 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
564 x x x x 0 x x x x x x 0 0 0 0 x x x * . RW IntCon (PIC8259)
565 x x x x 0 x x x x x x 0 0 0 1 x x x x . W IPConReg
566 x x x x 0 x x x x x x 0 0 1 0 x 0 0 0 . . KbdInt:Open Bus
567 x x x x 0 x x x x x x 0 0 1 0 x 0 0 1 . R KbdInt:ReadKeyData
568 x x x x 0 x x x x x x 0 0 1 0 x 0 1 0 . R KbdInt:ReadOPStatus
569 x x x x 0 x x x x x x 0 0 1 0 x 0 1 1 . . KbdInt:Open Bus
570 x x x x 0 x x x x x x 0 0 1 0 x 1 0 0 . W KbdInt:LoadKeyCtlReg
571 x x x x 0 x x x x x x 0 0 1 0 x 1 0 1 . W KbdInt:LoadKeyData
572 x x x x 0 x x x x x x 0 0 1 0 x 1 1 0 . W KbdInt:KeyDataReset
573 x x x x 0 x x x x x x 0 0 1 0 x 1 1 1 . W KbdInt:KeyChipReset
574 x x x x 0 x x x x x x 0 0 1 1 x x x x . W FIFOReg
575 x x x x 0 x x x x x x 0 1 0 0 x x x x . . Open Bus(originally ReadOpStatus)
576 x x x x 0 x x x x x x 0 1 0 1 x x * * . RW SelPIA (debugger board 8255 PIA)[Open Bus on normal units]
577 x x x x 0 x x x x x x 0 1 1 0 x x x x . W FIFOBus
578 x x x x 0 x x x x x x 0 1 1 1 x x x x . . Open Bus
579 x x x x 0 x x x x x x 1 0 0 0 x x x x . RW SelDiskReg
580 x x x x 0 x x x x x x 1 0 0 1 x x * * . RW SelDiskInt
581 x x x x 0 x x x x x x 1 0 1 0 * * * * . W SelCrtInt
582 x x x x 0 x x x x x x 1 0 1 1 x x x x . W LoadDispAddr
583 x x x x 0 x x x x x x 1 1 0 0 x x x x . . Open Bus(originally ReadEIAStatus)
584 x x x x 0 x x x x x x 1 1 0 1 x 0 0 0 . R SelEIA:ReadEIAStatus
585 x x x x 0 x x x x x x 1 1 0 1 x 0 0 1 . R SelEIA:ReadEIAData
586 x x x x 0 x x x x x x 1 1 0 1 x 0 1 0 . . SelEIA:Open Bus
587 x x x x 0 x x x x x x 1 1 0 1 x 0 1 1 . . SelEIA:Open Bus
588 x x x x 0 x x x x x x 1 1 0 1 x 1 0 0 . W SelEIA:LoadEIACtlReg
589 x x x x 0 x x x x x x 1 1 0 1 x 1 0 1 . W SelEIA:LoadEIAData
590 x x x x 0 x x x x x x 1 1 0 1 x 1 1 0 . W SelEIA:EIADataReset
591 x x x x 0 x x x x x x 1 1 0 1 x 1 1 1 . W SelEIA:EIAChipReset
592 x x x x 0 x x x x x x 1 1 1 0 x x x x . R SelADCHi
593 x x x x 0 x x x x x x 1 1 1 1 x x x x . W CRTSwitch
594 */
iop_io(address_map & map)595 void notetaker_state::iop_io(address_map &map)
596 {
597 map.unmap_value_high();
598 map(0x00, 0x03).mirror(0x7e1c).rw(m_iop_pic, FUNC(pic8259_device::read), FUNC(pic8259_device::write)).umask16(0x00ff);
599 map(0x20, 0x21).mirror(0x7e1e).w(FUNC(notetaker_state::IPConReg_w)); // I/O processor (rom mapping, etc) control register
600 map(0x42, 0x42).mirror(0x7e10).r(m_kbduart, FUNC(ay31015_device::receive)); // read keyboard data
601 map(0x44, 0x45).mirror(0x7e10).r(FUNC(notetaker_state::ReadOPStatus_r)); // read keyboard fifo state
602 map(0x48, 0x49).mirror(0x7e10).w(FUNC(notetaker_state::LoadKeyCtlReg_w)); // kbd uart control register
603 map(0x4a, 0x4a).mirror(0x7e10).w(m_kbduart, FUNC(ay31015_device::transmit)); // kbd uart data register
604 map(0x4c, 0x4d).mirror(0x7e10).w(FUNC(notetaker_state::KeyDataReset_w)); // kbd uart ddr switch (data reset)
605 map(0x4e, 0x4f).mirror(0x7e10).w(FUNC(notetaker_state::KeyChipReset_w)); // kbd uart reset
606 map(0x60, 0x61).mirror(0x7e1e).w(FUNC(notetaker_state::FIFOReg_w)); // DAC sample and hold and frequency setup
607 //map(0xa0, 0xa1).mirror(0x7e18).rw("debug8255", FUNC(8255_device::read), FUNC(8255_device::write)); // debugger board 8255
608 map(0xc0, 0xc1).mirror(0x7e1e).w(FUNC(notetaker_state::FIFOBus_w)); // DAC data write to FIFO
609 map(0x100, 0x101).mirror(0x7e1e).w(FUNC(notetaker_state::DiskReg_w)); // I/O register (adc speed, crtc pixel clock and clock enable, +5 and +12v relays for floppy, etc)
610 map(0x120, 0x127).mirror(0x7e18).rw(m_fdc, FUNC(fd1791_device::read), FUNC(fd1791_device::write)).umask16(0x00ff); // floppy controller
611 map(0x140, 0x15f).mirror(0x7e00).rw(m_crtc, FUNC(crt5027_device::read), FUNC(crt5027_device::write)).umask16(0x00ff); // crt controller
612 map(0x160, 0x161).mirror(0x7e1e).w(FUNC(notetaker_state::LoadDispAddr_w)); // loads the start address for the display framebuffer
613 map(0x1a0, 0x1a1).mirror(0x7e10).r(FUNC(notetaker_state::ReadEIAStatus_r)); // read eia fifo state
614 map(0x1a2, 0x1a2).mirror(0x7e10).r(m_eiauart, FUNC(ay31015_device::receive)); // read eia data
615 map(0x1a8, 0x1a9).mirror(0x7e10).w(FUNC(notetaker_state::LoadEIACtlReg_w)); // eia uart control register
616 map(0x1aa, 0x1aa).mirror(0x7e10).w(m_eiauart, FUNC(ay31015_device::transmit)); // eia uart data register
617 map(0x1ac, 0x1ad).mirror(0x7e10).w(FUNC(notetaker_state::EIADataReset_w)); // eia uart ddr switch (data reset)
618 map(0x1ae, 0x1af).mirror(0x7e10).w(FUNC(notetaker_state::EIAChipReset_w)); // eia uart reset
619 //map(0x1c0, 0x1c1).mirror(0x7e1e).r(FUNC(notetaker_state::SelADCHi_r)); // ADC read
620 //map(0x1e0, 0x1e1).mirror(0x7e1e).r(FUNC(notetaker_state::CRTSwitch_w)); // CRT power enable?
621 }
622
623 /* iop_pic8259 interrupts:
624 irq0 parity error (parity error syndrome data will be in fffdx/fffex) - currently ignored
625 irq1 IPSysInt (interrupt triggered by the emulator cpu)
626 irq2 DiskInt (interrupt triggered by the IRQ or DRQ pins from the WD1791)
627 irq3 EIAInt (interrupt triggered by the datareceived pin from the eiauart)
628 irq4 OddInt (interrupt triggered by the O/E Odd/Even pin from the crt5027)
629 irq5 ADCInt (interrupt triggered at the ADCSpd rate interrupt from 74c161 counter on the disk/display module to indicate adc conversion finished)
630 irq6 KbdInt (interrupt triggered by the datareceived pin from the kbduart)
631 irq7 VSync (interrupt from the VSYN VSync pin from the crt5027)
632 */
633
634 /* writes during boot of io roms v2.0:
635 0x88 to port 0x020 (PCR; BootSeqDone(1), processor not locked(0), battery charger off(0), rom not disabled(0) correction off&cr4 off(1), cr3 on(0), cr2 on(0), cr1 on (0);)
636 0x0002 to port 0x100 (IOR write: enable 5v only relay control)
637 0x0003 to port 0x100 (IOR write: in addition to above, enable 12v relay control)
638 <dram memory 0x00000-0x3ffff is zeroed here>
639 0x13 to port 0x000 PIC (ICW1, 8085 vector 0b000[ignored], edge trigger mode, interval of 8, single mode (no cascade/ICW3), ICW4 needed )
640 0x08 to port 0x002 PIC (ICW2, T7-T3 = 0b00001)
641 0x0D to port 0x002 PIC (ICW4, SFNM OFF, Buffered Mode MASTER, Normal EOI, 8086 mode)
642 0xff to port 0x002 PIC (OCW1, All Ints Masked (disabled/suppressed))
643 0x0000 to port 0x04e (reset keyboard fifo/controller)
644 0x0000 to port 0x1ae (reset UART)
645 0x0016 to port 0x048 (kbd control reg write)
646 0x0005 to port 0x1a8 (UART control reg write)
647 0x5f to port 0x140 (reg0 95 horizontal lines) \
648 0xf2 to port 0x142 (reg1 interlaced, hswidth=0xE, hsdelay=2) \
649 0x7d to port 0x144 (reg2 16 scans/row, 5 chars/datarow) \
650 0x1d to port 0x146 (reg3 0 skew bits, 0x1D datarows/frame) \_ set up CRTC
651 0x04 to port 0x148 (reg4 4 scan lines/frame) /
652 0x10 to port 0x14a (reg5 0x10 vdatastart) /
653 0x00 to port 0x154 (reset the crtc) /
654 0x1e to port 0x15a (reg8 load cursor line address = 0x1e) /
655 0x0a03 to port 0x100 (IOR write: set bit clock to 12Mhz)
656 0x2a03 to port 0x100 (IOR write: enable crtc clock chain)
657 0x00 to port 0x15c (fire off crtc timing chain)
658 read from 0x0002 (byte wide) (IMR, read interrupt mask, will be 0xFF from above)
659 0xaf to port 0x002 PIC (mask out with 0xEF and 0xBF to unnmask interrupts IR4(OddInt) and IR6(KbdInt), and write back to IMR)
660 0x0400 to 0x060 (select DAC fifo frequency 2)
661 read from 0x44 (byte wide) to check input fifo status
662 ... more stuff here missing relating to making the beep tone through fifo
663 (around pc=6b6) read keyboard uart until mouse button is clicked (WaitNoBug)
664 (around pc=6bc) read keyboard uart until mouse button is released (WaitBug)
665 0x2a23 to port 0x100 (select drive 1)
666 0x2a23 to port 0x100 (select drive 1)
667 0x3a23 to port 0x100 (unset disk separator clear (allow disk head reading))
668 0x3a27 to port 0x100 (select disk side 1)
669 0x3a07 to port 0x100 (unselect all drives)
670
671 */
672
673
674
675 /* Emulator CPU */
676
EPConReg_w(uint16_t data)677 void notetaker_state::EPConReg_w(uint16_t data)
678 {
679 /*m_EP_LED1 = m_EP_ParityError; // if parity checking is enabled AND the last access was to the low 8k AND there was a parity error, the parity error latch is latched here. It triggers an interrupt.
680 m_EP_LED2 = (data&0x40)?1:0;
681 m_EP_LED3 = (data&0x20)?1:0;
682 m_EP_LED4 = (data&0x10)?1:0;
683 m_EP_LED_SelROM_q = (data&0x08)?1:0; // this doesn't appear to be hooked anywhere, andjust drives an LED
684 // originally, SelROM_q enabled two 2716 EPROMS, later 82s137 PROMS to map code to the FFC00-FFFFF area but this was dropped in the 1979 design revision in favor of having the IOP write the boot vectors for the EP to the shared ram instead. See below for how the top two address bits are disconnected to allow this to work with the way the shared ram is mapped.
685 m_EP_ProcLock = (data&0x04)?1:0; // bus lock for this processor (hold other processor in wait state)
686 m_EP_SetParity_q = (data&0x02)?1:0; // enable parity checking on local ram if low
687 m_EP_DisLMem_q = (data&0x01)?1:0; // if low, the low 8k of local memory is disabled and accesses the shared memory instead.
688 popmessage("EP LEDS: CR1: %d, CR2: %d, CR3: %d, CR4: %d", (data&0x80)>>2, (data&0x40)>>3, (data&0x20)>>1, (data&0x10));*/
689 }
690
691 /*
692 Emulator cpu mem map:
693 (The top two address bits are disconnected, to allow the ram board, which maps itself only at 00000-3ffff, to appear at "ffff0" to the ep processor when /reset is de-asserted by the iop)
694 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 DisLMem_q
695 x x 0 0 0 0 0 * * * * * * * * * * * * * 0 RW Local (fast) RAM
696 x x 0 0 0 0 0 * * * * * * * * * * * * * 1 RW System/Shared RAM
697 <anything not all zeroes > * * * * * * * * * * * * * x RW System/Shared RAM
698 EXCEPT for the following, decoded by the EP board and superseding above:
699 x x 1 1 1 1 1 1 1 1 1 1 1 1 0 x x x x x x RW FFFC0-FFFDF (trigger ILLINST interrupt on EP, data ignored?)
700 And the following, decoded by the memory address logic board:
701 x x 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 x x . Open Bus
702 x x 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 x x W FFFEA (Multiprocessor Control (reset(bit 6)/int(bit 5)/boot(bit 4) for each processor; data bits 3,2,1,0 are 'processor address'; 0010 means IP, 0111 means EP; all others ignored.))
703 x x 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 x x R FFFEC (Syndrome bits (gnd bit 15, parity bit 14, exp(syndrome) bits 13-8, bits 7-0 are the highest address bits)
704 x x 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 x x R FFFEE (Parity Error Address: row bits 15-8, column bits 7-0; reading this also acknowledges a parity interrupt)
705 */
706
ep_mainram_r(offs_t offset,u16 mem_mask)707 uint16_t notetaker_state::ep_mainram_r(offs_t offset, u16 mem_mask)
708 {
709 return m_mainram[offset + 0x2000/2];
710 }
711
ep_mainram_w(offs_t offset,u16 data,u16 mem_mask)712 void notetaker_state::ep_mainram_w(offs_t offset, u16 data, u16 mem_mask)
713 {
714 COMBINE_DATA(&m_mainram[offset + 0x2000/2]);
715 }
716
ep_mem(address_map & map)717 void notetaker_state::ep_mem(address_map &map)
718 {
719 map(0x00000, 0x01fff).mirror(0xc0000).ram(); // actually a banked block of ram, 8kb (4kw)
720 map(0x02000, 0x3ffff).mirror(0xc0000).rw(FUNC(notetaker_state::ep_mainram_r), FUNC(notetaker_state::ep_mainram_w)); // 256k of ram (less 8k), shared between both processors, mirrored 4 times
721 //map(0xfffc0, 0xfffdf).mirror(0xc0000).rw(FUNC(notetaker_state::proc_illinst_r), FUNC(notetaker_state::proc_illinst_w));
722 //map(0xfffe0, 0xfffef).mirror(0xc0000).rw(FUNC(notetaker_state::proc_control_r), FUNC(notetaker_state::proc_control_w));
723 }
724
725 /* note everything in the emulatorcpu's io range is incompletely decoded; so if
726 0x1800 is accessed it will write to both the debug 8255 AND the pic8259!
727 I'm not sure the code abuses this or not, but it might do so to both write
728 registers and clear parity at once, or something similar. */
729 /*
730 Emulator cpu i/o map:
731 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0 DisLMem_q
732 x x x x x x x x 1 x x x x x x x x x * x x RW 8259
733 x x x x x x x 1 x x x x x x x x x * * x x RW EP debugger 8255, same exact interface on both cpu and alto side as the IOP debugger 8255
734 x x x x x x 1 x x x x x x x x x x x x x x W EPConReg
735 x x x x x 1 x x x x x x x x x x x x x x x W Writing anything here clears the parity error latch
736 */
737
ep_io(address_map & map)738 void notetaker_state::ep_io(address_map &map)
739 {
740 map.unmap_value_high();
741 map(0x800, 0x803).mirror(0x07fc).rw(m_ep_pic, FUNC(pic8259_device::read), FUNC(pic8259_device::write)).umask16(0x00ff);
742 //map(0x1000, 0x1001).mirror(0x07fe).rw("debug8255", FUNC(8255_device::read), FUNC(8255_device::write)); // debugger board 8255, is this the same one as the iop accesses? or are these two 8255s on separate cards?
743 map(0x2000, 0x2001).mirror(0x07fe).w(FUNC(notetaker_state::EPConReg_w)); // emu processor control reg & leds
744 //map(0x4000, 0x4001).mirror(0x07fe).w(FUNC(notetaker_state::EmuClearParity_w)); // writes here clear the local 8k-ram parity error register
745 }
746
747 /* Input ports */
748
749 /* Floppy Image Interface */
notetaker_floppies(device_slot_interface & device)750 static void notetaker_floppies(device_slot_interface &device)
751 {
752 device.option_add("525dd", FLOPPY_525_DD);
753 }
754
755 /* Machine Start; allocate timers and savestate stuff */
machine_start()756 void notetaker_state::machine_start()
757 {
758 // allocate RAM
759 m_mainram = make_unique_clear<uint16_t[]>(0x100000/2);
760 // allocate the DAC timer, and set it to fire NEVER. We'll set it up properly in IPReset.
761 m_FIFO_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(notetaker_state::timer_fifoclk),this));
762 m_FIFO_timer->adjust(attotime::never);
763 // FDC: /DDEN is tied permanently LOW so MFM mode is ALWAYS ON
764 m_fdc->dden_w(0);
765 // Keyboard UART: /SWE is tied permanently LOW
766 m_kbduart->write_swe(0); // status word outputs are permanently enabled (pin 16 SFD(SWE) tied low, active)
767 // EIA UART: /SWE is tied permanently LOW
768 m_eiauart->write_swe(0); // status word outputs are permanently enabled (pin 16 SFD(SWE) tied low, active)
769 // savestate stuff
770 // TODO: add me!
771 }
772
773 /* Machine Reset; this emulates the full system reset, triggered by ExtReset' (cardcage pin <50>) or the PowerOnReset' circuit */
machine_reset()774 void notetaker_state::machine_reset()
775 {
776 iop_reset();
777 ep_reset();
778 }
779
780 /* IP Reset; this emulates the IPReset' signal */
iop_reset()781 void notetaker_state::iop_reset()
782 {
783 // reset the Keyboard UART
784 m_kbduart->write_xr(0); // MR - pin 21
785 m_kbduart->write_xr(1); // ''
786 // reset the EIA UART
787 m_eiauart->write_xr(0); // MR - pin 21
788 m_eiauart->write_xr(1); // ''
789 // reset the IPConReg ls273 latch at #f1
790 IPConReg_w(0x0000);
791 // Clear the DAC FIFO
792 for (int i=0; i<16; i++) m_outfifo[i] = 0;
793 m_outfifo_count = m_outfifo_tail_ptr = m_outfifo_head_ptr = 0;
794 // reset the FIFOReg latch at #h9
795 FIFOReg_w(0x0000);
796 // reset the DiskReg latches at #c4 and #b4 on the disk/display/eia controller board
797 DiskReg_w(0x0000);
798 // reset the framebuffer display address counter:
799 m_DispAddr = 0;
800 }
801
802 /* EP Reset; this emulates the EPReset' signal */
ep_reset()803 void notetaker_state::ep_reset()
804 {
805 //TODO: force ep into reset and hold it there, until the iop releases it. there's 6 'state' bits controllable by the memory mapped cpu control reg, which need to be reset for epcpu and iocpu separately
806 }
807
808 /* Input ports */
INPUT_PORTS_START(notetakr)809 static INPUT_PORTS_START( notetakr )
810 INPUT_PORTS_END
811
812 void notetaker_state::notetakr(machine_config &config)
813 {
814 /* basic machine hardware */
815 /* IO CPU: 8086@8MHz */
816 I8086(config, m_iop_cpu, 24_MHz_XTAL / 3); /* iD8086-2 @ E4A; 24Mhz crystal divided down to 8Mhz by i8284 clock generator */
817 m_iop_cpu->set_addrmap(AS_PROGRAM, ¬etaker_state::iop_mem);
818 m_iop_cpu->set_addrmap(AS_IO, ¬etaker_state::iop_io);
819 m_iop_cpu->set_irq_acknowledge_callback("iop_pic8259", FUNC(pic8259_device::inta_cb));
820
821 PIC8259(config, m_iop_pic, 0); // iP8259A-2 @ E6
822 m_iop_pic->out_int_callback().set_inputline(m_iop_cpu, 0);
823
824 /* Emulator CPU: 8086@5MHz */
825 I8086(config, m_ep_cpu, 15_MHz_XTAL / 3);
826 m_ep_cpu->set_disable(); // TODO: implement the cpu control bits so this doesn't execute garbage/zeroes before its firmware gets loaded
827 m_ep_cpu->set_addrmap(AS_PROGRAM, ¬etaker_state::ep_mem);
828 m_ep_cpu->set_addrmap(AS_IO, ¬etaker_state::ep_io);
829 m_ep_cpu->set_irq_acknowledge_callback("ep_pic8259", FUNC(pic8259_device::inta_cb));
830
831 PIC8259(config, m_ep_pic, 0); // iP8259A-2 @ E6
832 m_ep_pic->out_int_callback().set_inputline(m_ep_cpu, 0);
833
834 /* video hardware */
835 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
836 screen.set_refresh_hz(60.975);
837 screen.set_vblank_time(ATTOSECONDS_IN_USEC(250));
838 screen.set_screen_update(FUNC(notetaker_state::screen_update));
839 screen.set_size(640, 480);
840 screen.set_visarea(0, 640-1, 0, 480-1);
841 screen.set_palette("palette");
842
843 PALETTE(config, "palette", palette_device::MONOCHROME);
844
845 /* Devices */
846 CRT5027(config, m_crtc, (36_MHz_XTAL / 4) / 8); // See below
847 /* the clock for the crt5027 is configurable rate; 36MHz xtal divided by 1*,
848 2, 3, 4, 5, 6, 7, or 8 (* because this is a 74s163 this setting probably
849 means divide by 1; documentation at
850 http://bitsavers.trailing-edge.com/pdf/xerox/notetaker/memos/19790605_Definition_of_8086_Ports.pdf
851 claims it is 1.5, which makes no sense) and secondarily divided by 8
852 (again by two to load the 16 bit output shifters after this).
853 on reset, bitclk is 000 so divider is (36mhz/8)/8; during boot it is
854 written with 101, changing the divider to (36mhz/4)/8 */
855 // TODO: for now, we just hack it to the latter setting from start; this should be handled correctly in iop_reset();
856 m_crtc->set_char_width(8); //(8 pixels per column/halfword, 16 pixels per fullword)
857 // TODO: below is HACKED to trigger the odd/even int ir4 instead of vblank int ir7 since ir4 is required for anything to be drawn to screen! hence with the hack this interrupt triggers twice as often as it should
858 m_crtc->vsyn_callback().set(m_iop_pic, FUNC(pic8259_device::ir4_w)); // note this triggers interrupts on both the iop (ir7) and emulatorcpu (ir4)
859 m_crtc->set_screen("screen");
860
861 AY31015(config, m_kbduart); // HD6402, == AY-3-1015D
862 m_kbduart->write_dav_callback().set(m_iop_pic, FUNC(pic8259_device::ir6_w)); // DataRecvd = KbdInt
863
864 clock_device &kbdclock(CLOCK(config, "kbdclock", 960_kHz_XTAL)); // hard-wired to 960KHz xtal #f11 (60000 baud, 16 clocks per baud)
865 kbdclock.signal_handler().set(m_kbduart, FUNC(ay31015_device::write_rcp));
866 kbdclock.signal_handler().append(m_kbduart, FUNC(ay31015_device::write_tcp));
867
868 AY31015(config, m_eiauart); // HD6402, == AY-3-1015D
869 m_eiauart->write_dav_callback().set(m_iop_pic, FUNC(pic8259_device::ir3_w)); // EIADataReady = EIAInt
870
871 clock_device &eiaclock(CLOCK(config, "eiaclock", ((960_kHz_XTAL/10)/4)/5)); // hard-wired through an mc14568b divider set to divide by 4, the result set to divide by 5; this resulting 4800hz signal being 300 baud (16 clocks per baud)
872 eiaclock.signal_handler().set(m_eiauart, FUNC(ay31015_device::write_rcp));
873 eiaclock.signal_handler().append(m_eiauart, FUNC(ay31015_device::write_tcp));
874
875 /* Floppy */
876 FD1791(config, m_fdc, (((24_MHz_XTAL/3)/2)/2)); // 2mhz, from 24mhz ip clock divided by 6 via 8284, an additional 2 by LS161 at #e1 on display/floppy board
877 FLOPPY_CONNECTOR(config, "wd1791:0", notetaker_floppies, "525dd", floppy_image_device::default_floppy_formats);
878
879 /* sound hardware */
880 SPEAKER(config, "lspeaker").front_left();
881 SPEAKER(config, "rspeaker").front_right();
882 // TODO: hook DAC up to two HA2425 (sample and hold) chips and hook those up to the speakers
883 DAC1200(config, m_dac, 0).add_route(ALL_OUTPUTS, "lspeaker", 0.5).add_route(ALL_OUTPUTS, "rspeaker", 0.5); // unknown DAC
884 }
885
init_notetakr()886 void notetaker_state::init_notetakr()
887 {
888 // descramble the rom; the whole thing is a gigantic scrambled mess either to ease
889 // interfacing with older xerox technologies which used A0 and D0 as the MSB bits
890 // or maybe because someone screwed up somewhere along the line. we may never know.
891 // see http://bitsavers.informatik.uni-stuttgart.de/pdf/xerox/notetaker/schematics/19790423_Notetaker_IO_Processor.pdf pages 12 and onward
892 uint16_t *romsrc = (uint16_t *)(memregion("iopload")->base());
893 uint16_t *romdst = (uint16_t *)(memregion("iop")->base());
894 // leave the src pointer alone, since we've only used a 0x1000 long address space
895 romdst += 0x7f800; // set the dest pointer to 0xff000 (>>1 because 16 bits data)
896 for (int i = 0; i < 0x800; i++)
897 {
898 uint16_t wordtemp = bitswap<16>(*romsrc, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); // data bus is completely reversed
899 uint16_t addrtemp = bitswap<11>(i, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // address bus is completely reversed; 11-15 should always be zero
900 uint16_t *temppointer = romdst+(addrtemp&0x7FF);
901 *temppointer = wordtemp;
902 romsrc++;
903 }
904 }
905
906 /* ROM definition */
907 /*
908 The notetaker, over its lifetime from 1978 to 1981, had three different classes of IOP roms, with multiple versions of each one.
909 These were:
910 BIOP - "Bootable", standalone "user" unit, running smalltalk-78 off of a boot disk, either single or double density; early notetakers used an fd1791 while later ones used a wd1791.
911 XIOP - "eXercizer" intended for initial testing of each NoteTaker system as assembled; only usable running tethered to a Xerox Alto running notex (notex.cm) as a hardware scripting language for system testing
912 MIOP - only bootable tethered to a Xerox Alto via a debug card, running smalltalk on the NoteTaker, but not booted off of the floppy disk.
913 The 'Z-iop' firmware 1.5 below seems to be a BIOP firmware.
914 */
915
916 ROM_START( notetakr )
917 ROM_REGION( 0x1000, "iopload", ROMREGION_ERASEFF ) // load roms here before descrambling
918 ROM_SYSTEM_BIOS( 0, "v2.00", "Bootable IO Monitor v2.00" ) // dumped from Notetaker
919 ROMX_LOAD( "biop__2.00_hi.b2716.h1", 0x0000, 0x0800, CRC(1119691d) SHA1(4c20b595b554e6f5489ab2c3fb364b4a052f05e3), ROM_SKIP(1) | ROM_BIOS(0))
920 ROMX_LOAD( "biop__2.00_lo.b2716.g1", 0x0001, 0x0800, CRC(b72aa4c7) SHA1(85dab2399f906c7695dc92e7c18f32e2303c5892), ROM_SKIP(1) | ROM_BIOS(0))
921 ROM_SYSTEM_BIOS( 1, "v1.50", "Bootable IO Monitor v1.50" ) // typed from the source listing at http://bitsavers.trailing-edge.com/pdf/xerox/notetaker/memos/19790620_Z-IOP_1.5_ls.pdf and scrambled
922 ROMX_LOAD( "z-iop_1.50_hi.h1", 0x0000, 0x0800, CRC(122ffb5b) SHA1(b957fe24620e1aa98b3158dbcf459937dbd54bac), ROM_SKIP(1) | ROM_BIOS(1))
923 ROMX_LOAD( "z-iop_1.50_lo.g1", 0x0001, 0x0800, CRC(2cb79a67) SHA1(692aafd2aeea27533f6288dbb1cb8678ea08fade), ROM_SKIP(1) | ROM_BIOS(1))
924 ROM_REGION( 0x100000, "iop", ROMREGION_ERASEFF ) // area for descrambled roms
925 // main ram, on 2 cards with parity/ecc/syndrome/timing/bus arbitration on another 2 cards
926 ROM_REGION( 0x400, "kbmcu", ROMREGION_ERASEFF )
927 ROM_LOAD( "keyboard.i8748.a10a", 0x000, 0x400, NO_DUMP ) // keyboard mcu which handles key scanning as well as reading the mouse quadratures, and issues state responses if requested by the iop
928 ROM_REGION( 0x500, "proms", ROMREGION_ERASEFF )
929 /* disk data separator prom from the disk/display module board:
930 there are two different versions of this prom, both generated by BCPL programs,
931 one from mid 1978 (Single density only? seems very buggy and might not even work)
932 and one from 1979 (which should work and appears here).
933 Note that the bit order for the state counter (data bits 6,5,4,3) may be
934 reversed vs the real machine, but since the prom address bus is the only
935 thing that ever sees the prom data bus, this prom will work even if the
936 bit order for those bits is backwards.
937 */
938 ROM_LOAD( "disksep.82s147.a4", 0x000, 0x200, CRC(38363714) SHA1(c995d2702573f5afb5fc919150d3a5661013f999) ) // 1979 version
939 ROM_LOAD( "timingprom.82s147.b1", 0x200, 0x200, CRC(3003b50a) SHA1(77d9ffe4716c2297708b8e5ebce7f930619c3cc3) ) // memory cas/ras/write state machine prom from the memory address logic board; the contents of this are listed in http://www.bitsavers.org/pdf/xerox/notetaker/schematics/19781027_Memory_Address_Timing.pdf
940 ROM_LOAD( "memreqprom.82s126.d9", 0x400, 0x100, CRC(56b2be8b) SHA1(5df0579ed8afeb59113700be6f2982ef85f64b44) ) // SETMEMRQ memory timing prom from the disk/display module board; The equations for this one are actually listed on the schematic and the prom dump can be generated from these:
941 /*
942 SetMemRq:
943 Address:
944 76543210
945 |||||||\- WCtr.0 (MSB)
946 ||||||\-- WCtr.1
947 |||||\--- WCtr.2
948 ||||\---- WCtr.3 (LSB)
949 |||\----- RCtr.0 (MSB)
950 ||\------ RCtr.1
951 |\------- RCtr.2
952 \-------- RCtr.3 (LSB)
953
954 The schematic has an error here, showing the SetMemRq_q output coming from data bit 0, in reality based on the listing it comes from data bit 3
955 Data:
956 3210
957 |\\\- N/C (always zero)
958 \---- SetMemRq_q
959
960 Equation: SETMEMRQ == (
961 ((Rctr == 0) && ((Wctr == 0)||(Wctr == 4)||(Wctr == 8)))
962 ||((Rctr == 4) && ((Wctr == 4)||(Wctr == 8)||(Wctr == 12)))
963 ||((Rctr == 8) && ((Wctr == 8)||(Wctr == 12)||(Wctr == 0)))
964 ||((Rctr == 12) && ((Wctr == 12)||(Wctr == 0)||(Wctr == 4)))
965 )
966 The PROM output is SetMemRq_q and is inverted compared to the equation above.
967 */
968 ROM_END
969
970 /* Driver */
971
972 // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
973 COMP( 1978, notetakr, 0, 0, notetakr, notetakr, notetaker_state, init_notetakr, "Xerox", "NoteTaker", MACHINE_IS_SKELETON)
974
975