====== Apple IIc Plus MIG Chip ====== The MIG is a custom chip in the Apple IIc Plus that provides signals for accessing 3.5%%"%% disk drives and access to a 2K static RAM chip mainly used to buffer 3.5%%"%% sector data for reading and writing. The RAM is also used for the accelerator. **2018-06-04 update:** Work by [[http://leon.bottou.org/start|Léon Bottou]] has significantly increased understanding of the MIG chip. See his comments [[https://github.com/mgcaret/rom4x/issues/8|here]] and [[https://github.com/leonbottou/kegs-universal|working emulation]] (also [[https://github.com/leonbottou/gsplus-universal|this]]) of the MIG. **2018-08-01 update:** Based on the work Léon and I have done, [[https://github.com/rb6502|R. Belmont]] has implemented MIG emulation in [[https://github.com/mamedev/mame|MAME]] and the Apple IIc Plus emulation is now [[https://github.com/mamedev/mame/commit/31aaae7491ea4233de75456af178054e650f4344|working]] (also see [[https://github.com/mamedev/mame/commit/7bd14bedf6fd824853c406248dd4a36db17ecb7b|here]]). ===== Functional Description ===== The MIG is an interface chip that allows a 1 MHz 6502-based system to utilize Apple's "dumb" 800K 3.5%%"%% disk drives (1.44 MB drives also work, but only at 800K). It does so by providing the additional signals required to control the drives (HDSEL and 3.5DRIVE) and mediating access to a 2K SRAM that can be used to buffer data coming from the IWM at the fast (2 us) bit-cell rate that the 800K drives use. In addition to allowing four (two each 3.5%%"%% and 5.25%%"%%) "dumb" external drives to be connected, the MIG allows for one "internal" disk drive by accepting a drive enable line input on ENB2X (drive 2 in the IIc Plus) and switching it between two output pins, ENB2 and INTEN, of which the former goes to the external disk port, and the latter to the internal drive. When the MIG is held in RESET and immediately after it is released, its state is such that the 3.5" control signals are not enabled and the switched drive select is routed to the external disk. The end result in the IIc Plus is that when the IWM is accessed in this state, any 5.25%%"%% drives connected to the external disk port are addressed. In the IIc Plus, the internal 3.5%%"%% drive does not need the 3.5DRIVE signal asserted in order to operate. ===== MIG Chip ===== ==== Pins/Signals ==== According to the Apple IIc Technical Reference 2nd Ed., the MIG has the following signals. Note that the descriptions in the manual are not entirely accurate. For example, the description of EN2X is "input that indicates an access to address $C0nx is occuring..." In fact, this pin is connected to the drive 2 enable line of the IWM. ^ Pin(s) ^ Signal ((* = active low)) ^ Description ^ | 1 | IOSEL* | "Tied to RESET* (pin 14)" (schematic verifies this) | | 2-7 | A5-A11 | System address bits 5-11 | | 8 | BUSEN* | "Output that indicates valid access to MIG address space" | | 9 | R/W | System bus read/write control line | | 10 | PH1 | System clock | | 11 | EN2X* | Input from IWM drive 2 select (pin 19). \\ Routed to ENB2* when external drives are selected (W $CCC0), to INTEN* when internal drive is selected (W $CC80) | | 12 | VSS | | | 13 | ROMEN1* | "Input that indicates an accesses to lower ROM bank space $C100-$DFFF is occurring" | | 14 | RESET* | "System reset or ROM address 14" \\ Léon realized that this literally means that ROM address 14 is tied to the RESET line on the MIG (can be seen in the schematic). This means the MIG is held reset whenever the ROM is in the main bank, and why my prior oscilloscope testing only revealed short pulses on the MIG outputs: because I switched back to the main bank immediately in order to exit the code. | | 15 | IWMRES | "Latched output bit to reset IWM" \\ Set (or pulsed?) by W $CC40 ((https://github.com/leonbottou/kegs-universal/blob/master/src/moremem.c#L333)) (Does $CC00 do anything). | | 16 | INTEN* | "Latched output bit to enable internal drive" \\ See EN2X* above. ((https://github.com/leonbottou/kegs-universal/blob/master/src/moremem.c#L333)) | | 17 | ENB2 | Connected to drive 2 enable on pin 9 of disk port. | | 18 | 3.5DRIVE* | "Latched output bit to select 5.25 in. or 3.5 in. drives" - This is routed to the external connector only. \\ Set by W $CE60 access, reset by W $CE40 access. ((https://github.com/leonbottou/kegs-universal/blob/master/src/moremem.c#L309))| | 19 | HDSEL | "Latched output bit used for 3.5 in. drives" (often called head select, is general purpose output) \\ Set by R $CE60 access, reset by R $CE40 access. ((https://github.com/leonbottou/kegs-universal/blob/master/src/moremem.c#L309)) | | 20 | ROMEN2* | "ROM enable output line, follows ROMEN1*" - used to pass through ROM chip select. | | 21 | RAMEN* | "RAM enable output line to 2 KB RAM buffer" - used to for MIG RAM chip select. | | 25 | VDD | | | 28-26,24-22 | RAMA5-RAMA10 | RAM buffer address bit 5-10 - output to the MIG RAM lines. | ==== Analysis ==== Key points about the MIG based on the above and the schematic: - It doesn't decode the lower 5 bits of the address bus. Thus the MIG address space must be broken down into 32-byte chunks. - RAMA5-RAMA10 combined with the lower 5 bits of the address bus are used to address the 2K SRAM. - It doesn't decode A12-A15, so on a 16-bit bus its address space must repeat every $1000 bytes without other selection logic. This logic is the ROMEN1* signal. This explains why the MIG appears at both $CE00 and $DE00. - It doesn't have pins for the data bus at all. Therefore it cannot possibly directly provide state information. However it could provide it indirectly by selectively not enabling the RAM chip select during a read or write. - Since the MIG RAM window appears at $xE00-$xFFF, the MIG considers itself selected when A11-A5 = 111xxxx, in this case it does not pass ROMEN1* to ROMEN2*. It cannot drive the data bus (no data lines) therefore it can only perform an action or assert RAMEN* to select the 2K SRAM. - It also responds in the $CC00-$CCFF range. - The MIG is held in reset when the main ROM is active. ===== MIG Address Space ==== Access/control of the MIG is via a $800-byte window starting at $C800 when the aux firmware bank is selected. The window is repeated at $D800 (I/O select is mediated by the lower half ROM select), but is not usable unless the accelerator is disabled. The lower $600 bytes of this space is shared with the ROM, and the upper $200 bytes is used for the MIG RAM window and other control functions. ==== MIG Control ==== Almost all of these addresses accessed in the ROM are via writes (except for an LDA $CCC0 in routine at $E9C5), implying that R/*W is must be low. ^ Address(s) ^ Use ^ | $C840 | routine at $EF02 | | $C880 | routine at $EF02 | | $C8C0 | routine at $EF02 | | $CC40 | (probably) /IWMRES | | $CC80 | Assert /INTEN (drive 2 select goes to internal disk) | | $CCC0 | De-assert /INTEN (drive 2 select goes to external disks) | The docs say /IWMRES is latched, so would expect a $CC00/$CC40 combo, but no evidence for that. ==== MIG RAM / Control ==== These lines respond to read or write, sometimes with different behavior. ^ Address(s) ^ R/W ^ Use ^ | $CE00 - $CE1F | R+W | MIG RAM window | | $CE20 - $CE3F | R+W | MIG RAM window and increment RAM window page (after read/write) | | $CE40 - $CE5F | R | Reset HDSEL ((https://github.com/leonbottou/kegs-universal/blob/master/src/moremem.c#L309)). | | $CE40 - $CE5F | W | Assert /3.5DRIVE (reset low) ((https://github.com/leonbottou/kegs-universal/blob/master/src/moremem.c#L309)). | | $CE60 - $CE7F | R | Set HDSEL ((https://github.com/leonbottou/kegs-universal/blob/master/src/moremem.c#L309)). | | $CE60 - $CE7F | W | De-assert /3.5DRIVE (set high) ((https://github.com/leonbottou/kegs-universal/blob/master/src/moremem.c#L309)). | | $CE80 - $CE9F | | Affects signal on ENB2, firmware does not appear to use | | $CEA0 - $CEBF | R/W | Set RAM window page 0 | | $CEE0 - $CEFF | | Firmware does not address this range | | $CF00 - $CFFF | | Firmware does not address this range | The address space for the MIG is repeated at $DE00-$DFFF but this is unusable because the Apple IIc Plus accelerator treats this space as ROM, whereas the $CE00-$CFFF window is treated as the I/O space and not cached. ==== MIG RAM ==== The visible 32-byte page of the RAM window is selected as follows: * Access $CE00-$CE1F: access RAM * Access $CE20-$CE3F: Access RAM and increment page * Access $CEA0: Set page 0 The following page usages have been noted: ^ Page(s) ^ Byte ^ Use ^ ^ $00 | | Used by SmartPort firmware. | | $00 | $00-$02 | 3.5: current track position of units 0-2. | | $00 | $03-$07 | 3.5 R/W: Trk/Sec/Head/Format/Checksum of address field requested block. \\ $05 b5=Head, b0=track high bit. \\ $06 b5=sides, b0-4=interleave. | | $00 | $08 | 3.5 R/W: sector number translated to disk nibble. | | $00 | $08-$09 | 5.25 R/W: requested sector and track. | | $00 | $09-$0C | 3.5 R/W: sector address data for sector header just read.| | $00 | $0D | 3.5 R: if address checksum fails, computed checksum is put here. | | $00 | $0E | Used to save unit looked up from $14+ (3.5) or Disk II drive # (b6 will be set). | | $00 | $0F | Holds number of detected 3.5 drives+smartport devices | | $00 | $10 | 3.5: System interleave, always $04. | | $00 | $11 | Used to save/restore language card state. | | $00 | $12-$13 | Used for indirect jump by SmartPort firmware. | | $00 | $14-$1B | Used to hold valid smartport device numbers, b7 = "dumb" 3.5" drive. | ^ $00-$2A | $1C-$1F | Used by the [[mg_notes:apple_iic:secret_iicplus_smartport|Disk II SmartPort]] firmware for prenibble/denibble. | ^ $01 | | Used by SmartPort firmware. | | $01 | $00-$0F | 3.5 Format: sector numbers to be written out | | $01 | $10 | 3.5 firmware: previous disk format (sides+interleave) | | $01 | $11 | 3.5 Format: number of sectors in track being formatted | ^ $02 | $00-$09 | Used by the [[accelerator|accelerator]] firmware. | ^ $03-$18 | | 3.5 Read/Write: 704-byte GCR-coded sector buffer. | ^ $03-$03+n | $09-$0D | 3.5 Format: Precomputed track/sector/side/format/checksum for track of n sectors. | ^ $2B-$3D | | Maybe unused. Not confirmed. | ^ $3E-$3F | | Used by SmartPort firmware to save/restore zero page $39-$5E (38 bytes). | The contents of the MIG RAM can be viewed using my [[https://github.com/mgcaret/mig.insp|MIG Inspector]]. ==== MIG I/O ==== TBD.