MFP, RTC & anything else

From Atari Wiki
Revision as of 09:08, 27 July 2026 by Exxos (talk | contribs)
Jump to navigation Jump to search

===========#==#=======#===============================================#===== ----------------------|Realtime Clock Chip, Non Volatile Memory |----- ===========#==#=======#===============================================#=====
$FFFF8961.B|RW|NVM_CTL|Register Select |TT,F
$FFFF8961 and $FFFF8963 Real Time Clock / NVRAM $FFFF8961 Address register: write the location to access $FFFF8963 Data register: read or write that location TT and Falcon. The NVRAM holds 50 bytes of user settings (language, keyboard, boot preferences) plus the real time clock registers, in a battery backed MC146818 compatible part. Access is indirect: write an address to $FFFF8961, then read or write $FFFF8963. EmuTOS bios/nvram.c wraps this in the NVMaccess XBIOS call rather than exposing the registers. On the Falcon the fitted part is a DS1287 (MC146818 compatible). Internal register map, per the F030/CT60 listing: 0 current second 1 alarm second 2 current minute 3 alarm minute 4 current hour 5 alarm hour 6 day of week (1 = Sunday) 7 day of month 8 month 9 year (two digits) A bit 7: 1 = time update in progress, do not read the time and date registers while set B bit 7: 1 = write protect time and date bit 6: 1 = enable alarm interrupt bit 5: 1 = interrupt after time updated bit 2: 1 = binary format, 0 = BCD bit 1: 1 = 24 hour format, 0 = 12 hour bit 0: 1 = summer time, 0 = winter time C bit 6: ? bit 5: 1 = alarm is ringing bit 4: 1 = date has updated read this register on interrupt to find the source D bit 7: 1 = BATTERY DEAD, clock contents invalid From the Atari Compendium; DS1287 register map from the F030/CT60 listing, matching the standard MC146818 layout.
$FFFF8963.B|RW|NVM_DAT|Data of selected Register |TT,F
$FFFF8964.B|RW| - |Add-on control, not present on stock hardware |*
$FFFF8964, $FFFF896A, $FFFF896C, $FFFF8970 Add-on control Not present on stock Atari hardware. These addresses sit in the gap above the TT and Falcon real time clock registers and below the reserved area at $FFFF8A00. Known to be used by: $FFFF8964 FLASHY CLOCK $FFFF896A SEC BOOSTER $FFFF896C FLASHY CLOCK $FFFF8970 FLASHY CLOCK FLASHY CLOCK also uses $FFFF89F0 and $FFFF89F2 for its real time clock, and $FFFFFFFF as a control register. Extended bit information is not currently available for these registers. The addresses are documented; what each bit does is not. No conflict found: neither EmuTOS nor Hatari references any address in the $FFFF8964 to $FFFF8970 range.
$FFFF896A.B|RW| - |Add-on control, not present on stock hardware |* $FFFF896C.B|RW| - |Add-on control, not present on stock hardware |* $FFFF8970.B|RW| - |Add-on control, not present on stock hardware |*
$FFFF89F0.B|RW| - |Add-on real time clock |*
$FFFF89F0 and $FFFF89F2 Add-on real time clock Not present on stock Atari hardware. Known to be used by: FLASHY CLOCK. Extended bit information is not currently available for these registers. No conflict found: neither EmuTOS nor Hatari references either address.
$FFFF89F2.B|RW| - |Add-on real time clock |* ===========#==#=======#===============================================#===== ----------------------|DMA SCC |----- ===========#==#=======#===============================================#===== $FFFF8C01.B|RW|SCC_DA0|DMA Address Pointer (Highest byte) |TT $FFFF8C03.B|RW|SCC_DA1|DMA Address Pointer (High byte) |TT $FFFF8C05.B|RW|SCC_DA2|DMA Address Pointer (Low byte) |TT $FFFF8C07.B|RW|SCC_DA3|DMA Address Pointer (Lowest byte) |TT $FFFF8C09.B|RW|SCC_BC0|DMA Byte Counter (Highest byte) |TT $FFFF8C0B.B|RW|SCC_BC1|DMA Byte Counter (High byte) |TT $FFFF8C0D.B|RW|SCC_BC2|DMA Byte Counter (Low byte) |TT $FFFF8C0F.B|RW|SCC_BC3|DMA Byte Counter (Lowest byte) |TT $FFFF8C10.W|Rw|SCC_RD0|Rest data (High Word) |TT $FFFF8C12.W|Rw|SCC_RD1|Rest data (Low Word) |TT $FFFF8C14.W|Rw|SCC_CTL|DMA SCC Control Register %________ BZ____DW |TT | | | Bus Error 0:no,1:yes-----------------+| || |TT | | | Byte Counter Zero 0:no,1:yes----------+ || |TT | | | DMA 0:off,1:on-----------------------------+| |TT | | | 0:DMA read,1:DMA write----------------------+ |TT ===========#==#=======#===============================================#===== ----------------------|SCC Y8530 - Serial Communication Controller |----- ===========#==#=======#===============================================#=====
$FFFF8C81.B|RW|SCA_CTL|Channel A Control (select/read/write Register) |SCC
$FFFF8C81 to $FFFF8C87 SCC 8530 Serial Controller $FFFF8C81 Channel A control $FFFF8C83 Channel A data $FFFF8C85 Channel B control $FFFF8C87 Channel B data The 8530 has far more internal registers than the four addresses above suggest. Access is indirect: write a register number to the control address, then read or write the control address again to reach that register. Register 0 is reached directly without a preceding select. The data addresses map to internal register 8. INTERNAL REGISTER MAP (Z8530 datasheet, implemented in full by Hatari src/scc.c): Write registers: WR0 register select / command (CRC reset, reset ext/status interrupts, error reset, and so on) WR1 interrupt and data transfer mode enables WR2 interrupt vector base (one per chip, shared A and B) WR3 receiver parameters: bit 0 RX enable, bits 7-6 bits per character (00=5, 10=6, 01=7, 11=8) WR4 bit 0 parity enable, bit 1 even parity, bits 3-2 stop bits (00=sync, 01=1, 10=1.5, 11=2), bits 7-6 clock mode (x1, x16, x32, x64) WR5 transmitter parameters: bit 1 RTS, bit 3 TX enable, bit 4 send break, bits 6-5 TX bits per character, bit 7 DTR WR6 sync character / SDLC address WR7 sync character / SDLC flag (WR7' extensions reachable via WR15 bit 0 on the 85C30) WR8 transmit data buffer (same as the data address) WR9 master interrupt control and chip reset: bit 0 vector includes status, bit 1 no vector, bit 3 master int enable, bits 7-6 reset commands WR10 misc TX/RX control (encoding: NRZ, NRZI, FM) WR11 clock source selection for RX/TX WR12 baud rate generator time constant, low byte WR13 baud rate generator time constant, high byte WR14 misc control: bit 0 BRG enable, bit 1 BRG source, bits 7-5 DPLL commands WR15 external/status interrupt enables: bit 1 zero count, bit 3 DCD, bit 4 sync/hunt, bit 5 CTS, bit 6 TX underrun/EOM, bit 7 break/abort Read registers: RR0 status: bit 0 RX character available, bit 2 TX buffer empty, bit 3 DCD, bit 4 sync/hunt, bit 5 CTS, bit 6 TX underrun/EOM, bit 7 break/abort RR1 special receive condition status (parity, overrun, framing errors) RR2 interrupt vector (channel B read returns it modified by the interrupt source) RR3 interrupt pending bits (channel A only) RR8 receive data buffer (same as the data address) RR10 loop/clock status RR12 BRG time constant low readback RR13 BRG time constant high readback RR15 external/status interrupt enable readback Baud rate: on the Atari the SCC PCLK is 8.053976MHz (the Falcon and TT feed the same master clock), and channel B's receive/transmit clock TRxCB can instead be driven from MFP Timer C, which is why that timer is reserved on the TT. Baud = PCLK / (2 x (time constant + 2) x clock mode divisor) when the BRG runs from PCLK. Port assignment on the Atari machines: channel A drives the LAN connector or Serial 2 (selected by YM port A bit 7 on the TT and Falcon), channel B drives the modem/serial port. The SCC generates interrupts through the vector table at $00000180 to $000001BC. That table is SPARSE: only every other longword is a real vector, alternating with an unused slot. See the System variables and low RAM page. Register map from the Zilog Z8530/85C30 datasheet; register behaviour cross-checked against the define tables and handlers in Hatari src/scc.c, which implements WR0-WR15 and RR0-RR15 for the Atari machines. TT, Mega STE and Falcon.
$FFFF8C83.B|RW|SCA_DAT|Channel A Data (read/write Register 8) |SCC $FFFF8C85.B|RW|SCB_CTL|Channel B Control (select/read/write Register) |SCC $FFFF8C87.B|RW|SCB_DAT|Channel B Data (read/write Register 8) |SCC ===========#==#=======#===============================================#===== ----------------------|VME Bus |----- ===========#==#=======#===============================================#===== $FFFF8E01.B|RW|VME_MR0|VME Mask Register 0 %EMSV_HS_ |TT,ME | | | Enable bits for the same interrupt sources as |TT,ME | | | VME_SR0 below, same bit positions, 1=enabled. |TT,ME | | | Cleared to $00 on reset; TOS sets $14 (HBL + |TT,ME | | | VBL). Per Hatari src/scu_vme.c. |TT,ME $FFFF8E03.B|RW|VME_SR0|VME Status Register 0 %EMSV_HS_ |TT,ME | | | Error 0:no,1:yes---------------------+||| || |TT,ME | | | MFP-----------------------------------+|| || |TT,ME | | | SCC------------------------------------+| || |TT,ME | | | VBL-------------------------------------+ || |TT,ME | | | HBL---------------------------------------+| |TT,ME | | | Software Interrupt-------------------------+ |TT,ME $FFFF8E05.B|RW|VME_IN0|Force Interrupt on Level 1 %_______F |TT,ME $FFFF8E07.B|RW|VME_IN1|Force Interrupt on Level 3 %_______F |TT,ME $FFFF8E09.B|RW|SCU_GP1|SCU General Purpose Register 1 |TT,ME | | | Verified: EmuTOS bios/machine.h (SCU_GPR1 | | | | 0xffff8e09) and Atari TOS 3.06 bios/startup.S,| | | | which uses bit 0 as a memory-config-valid | | | | flag. | $FFFF8E0B.B|RW|SCU_GP2|SCU General Purpose Register 2 |TT,ME | | | UNVERIFIED: Atari Compendium only. GPR1 next | | | | door is confirmed twice, so this is very | | | | likely real, but no source touches it. | | | | Both GP registers are plain byte latches with | | | | no assigned bits: cleared on cold boot only, | | | | they keep their contents over a warm boot | | | | (Hatari src/scu_vme.c). | $FFFF8E0D.B|RW|VME_MR1|VME Mask Register 1 %7654321_ |TT,ME | | | Enable bits for VME bus interrupts 1-7, same |TT,ME | | | positions as VME_SR1 below, 1=enabled. Bit 0 |TT,ME | | | unused. Cleared to $00 on reset; TOS sets $60 |TT,ME | | | (IRQ6=MFP + IRQ5=SCC). Per Hatari |TT,ME | | | src/scu_vme.c. |TT,ME $FFFF8E0F.B|RW|VME_SR1|VME Status Register 1 %7654321_ |TT,ME | | | VME Interrupt 1-7 0:on,1:off---------+++++++ | ===========#==#=======#===============================================#===== $FFFF8E21.B|RW|M_E_CAC|Mega STe Cache/Processor Control %______SC |ME | | | cpu Speed 0:8MHz,1:16MHz-------------------+| |ME | | | Cache 0:disabled,1:enabled------------------+ |ME | | | $FF 16MHz with cache |ME | | | $FE 16MHz, cache off |ME | | | $F4 8MHz |ME | | | The cache only works at 16MHz: setting bit 0 | | | | with bit 1 clear reads back with bit 0 forced | | | | to 0 (write $FD, read $FC). Per Hatari | | | | src/ioMemTabSTE.c. | | | | CORRECTED: was listed at $FFFF8E0F, which | | | | belongs to VME_SR1. Verified at $FFFF8E21 by | | | | Atari TOS 3.06 bios/startup.S: ori.b | | | | #3,($ffff8e21).w with the comment "turn on | | | | 16MHz and cache". Value table from the Atari | | | | Compendium. | ===========#==#=======#===============================================#===== ----------------------|Paddle Ports |----- ===========#==#=======#===============================================#=====
$FFFF9200.W|RW|PAD_BUT|Paddle/Joy Buttons %xxxxxxxx ____3210 |STE,F | | | Switches--------------------++++++++ |,TT | | | On Falcon at U47: MSB on the right, closed=0 |
$FFFF9200 PAD_BUT Joypad fire buttons / DIP switches Low nibble, read: fire buttons, per the F030/CT60 listing: Bit 3 Option / F3 Bit 2 F2 Bit 1 F1 Bit 0 Pause / F0 High byte: on the Mega STE and Falcon this byte also returns the state of the 8 configuration DIP switches on the motherboard (Falcon: U47, most significant bit on the right, closed = 0). Hatari src/joy.c implements this. ACCESS QUIRK: on the STE and Mega STE this register can only be read as a WORD at $FFFF9200; a byte access at $FFFF9200 does not work, though $FFFF9201 can be read as a byte. Hatari src/joy.c implements the restriction.
$FFFF9202.W|RW|PAD_MOV|Paddle/Joy Move (R) / Read Mask (W) |STE,F
$FFFF9202 PAD_MOV Joystick inputs (read) / read mask (write) Write: the read mask; a 0 bit selects the corresponding pin group for reading. Read: the joystick input pins, per the F030/CT60 listing: Bit 15 Controller 1 pin 14 Bit 7 Controller 1 pin 4 Bit 14 Controller 1 pin 13 Bit 6 Controller 1 pin 3 Bit 13 Controller 1 pin 12 Bit 5 Controller 1 pin 2 Bit 12 Controller 1 pin 11 Bit 4 Controller 1 pin 1 Bit 11 Controller 0 pin 14 Bit 3 Controller 0 pin 4 Bit 10 Controller 0 pin 13 Bit 2 Controller 0 pin 3 / Bit 9 Controller 0 pin 12 Paddle 1 trigger Bit 8 Controller 0 pin 11 Bit 1 Controller 0 pin 2 / Paddle 0 trigger Bit 0 Controller 0 pin 1 The enhanced joystick ports carry the four directions on pins 1-4 and the extra joypad lines on pins 11-14.
$FFFF9210.W|RW|PAD_PD0|Pad0 Position / X Paddle 0 |STE,F
$FFFF9210 to $FFFF9216 Paddle position counters Four word registers, low byte holds the position. NAMING: this page has called them Pad0 to Pad3 Position. The F030/CT60 listing names them X Paddle 0 ($9210), Y Paddle 0 ($9212), X Paddle 1 ($9214) and Y Paddle 1 ($9216): two paddle controllers, each with an X and a Y axis. The two descriptions are different readings of the same four registers; the paddle pairing follows the trigger bits at $FFFF9202 (paddle 0 and 1), so the X/Y naming is likely the intended one. Not settled by Hatari, EmuTOS or TOS source, none of which touch these registers.
$FFFF9212.W|RW|PAD_PD1|Pad1 Position / Y Paddle 0 |STE,F $FFFF9214.W|RW|PAD_PD2|Pad2 Position / X Paddle 1 |STE,F $FFFF9216.W|RW|PAD_PD3|Pad3 Position / Y Paddle 1 |STE,F $FFFF9220.W|RW|PAD_LPX|Lightpen X |STE,F $FFFF9222.W|RW|PAD_LPY|Lightpen Y |STE,F ===========#==#=======#===============================================#===== ----------------------|DSP 56001 Host - Digital Signal Processor |----- ===========#==#=======#===============================================#=====
$FFFFA200.B|RW|DSP_ICR|Interrupt Control Register (%IMMHH_TR) |DSP
$FFFFA200 DSP_ICR Interrupt Control Register (DSP X:$FFE9) Bit 7 INIT setting this forces initialisation of the host interface Bits 6-5 DMA mode control: 00 interrupt mode, DMA off 01 24 bit DMA mode 10 16 bit DMA mode 11 8 bit DMA mode Bit 4 HF1 host flag 1 Bit 3 HF0 host flag 0 Bit 2 unused Bits 1-0 Data transfer mode The host flags are general purpose signalling bits readable by the DSP; they carry no fixed meaning in hardware. Falcon only. From the Atari Compendium.
$FFFFA201.B|RW|DSP_CVR|Command Vector Register (%I__VVVVV) |DSP
$FFFFA201 DSP_CVR Command Vector Register (DSP X:$FFE9) Bit 7 Host command bit Bits 6-5 unused Bits 4-0 Host vector, 0 to 31 Writing a vector with the command bit set causes the DSP to take an interrupt to that vector, which is how the host asks the DSP to run a routine. Falcon only. From the Atari Compendium.
$FFFFA202.B|RW|DSP_ISR|Interrupt Status Register (%ID_HHETR) |DSP
$FFFFA202 and $FFFFA203 DSP Status and Vector $FFFFA202 Interrupt Status Register (DSP X:$FFE8) $FFFFA203 Interrupt Vector Register The status register reports the state of the host interface, including whether the transmit register is empty and the receive register is full, plus the two host flags coming back from the DSP. The vector register holds the 680x0 exception vector number used when the DSP raises an interrupt to the host. The wiki summary line gives the status register bit pattern as %ID_HHETR: I = interrupt, D = DMA, HH = host flags, E = transmit empty, T = transmit, R = receive. Falcon only. The Atari Compendium names both registers but gives no bit breakdown for the status register.
$FFFFA203.B|RW|DSP_IVR|Interrupt Vector Register (Vector Number) |DSP
$FFFFA204.B|RW|DSP_TR0|Transfer Highest Byte (DSP56003 32bit) |DSP32
$FFFFA204 to $FFFFA207 DSP Transfer Registers $FFFFA204 Transfer byte, highest (DSP56003 32 bit only) $FFFFA205 Transfer byte, high $FFFFA206 Transfer byte, middle $FFFFA207 Transfer byte, low The DSP56001 fitted to the Falcon is a 24 bit part, so only the low three bytes are used. $FFFFA204 exists for the 32 bit DSP56003, which the Falcon does not have. Reading or writing $FFFFA207 is what actually triggers the transfer; the other bytes are staged first. Falcon only.
$FFFFA205.B|RW|DSP_TR1|Transfer Hi |DSP $FFFFA206.B|RW|DSP_TR2|Transfer Mi |DSP $FFFFA207.B|RW|DSP_TR3|Transfer Lo |DSP ===========#==#=======#===============================================#===== ----------------------|MFP 68901 - Multi Function Peripheral |----- ===========#==#=======#===============================================#=====
$FFFFFA01.B|RW|MFP_PDR|Parallel Port Data Register %SRFKBRDC |
$FFFFFA01 MFP_PDR General Purpose I/O Port Bit 7 Monochrome monitor detect Bit 6 RS-232 ring indicator Bit 5 FDC / HDC interrupt Bit 4 Keyboard / MIDI interrupt Bit 3 Blitter done Bit 2 RS-232 clear to send Bit 1 RS-232 carrier detect Bit 0 Centronics busy All eight are inputs on a standard ST, set by the data direction register at $FFFFFA05. Bit 5 is the one to poll for floppy and hard disk completion: read the byte, mask with $20, and a result of ZERO means the controller has interrupted. This is what TOS itself does. Bit 7 is how machines before the Falcon detect a monochrome monitor. The Falcon uses $FFFF8006 instead. FALCON WIRING DIFFERS: on the Falcon two GPIP pins carry different signals (per the F030/CT60 listing): Bit 2 MIDI ACIA interrupt (ST: RS-232 clear to send) Bit 3 DSP connector interrupt (ST: Blitter done) The corresponding interrupt vectors move with them: on the Falcon vector $108 is the MIDI ACIA and $10C the DSP connector, where the ST has RS-232 CTS and Blitter done. Both assignments are correct for their machine. From the Atari Compendium.
$FFFFFA03.B|RW|MFP_AER|Active Edge Register %SRFKBRDC | | | | Interrupt on 0:High-Low,1:Low-High |||||||| |!F | | | Interrupt on 0:Low-High,1:High-Low |||||||| |F
$FFFFFA03 MFP_AER Active Edge Register One bit per GPIO pin, same order as $FFFFFA01: Bit 7 Monochrome monitor detect Bit 6 RS-232 ring indicator Bit 5 FDC / HDC interrupt Bit 4 Keyboard / MIDI interrupt Bit 3 Blitter done Bit 2 RS-232 clear to send Bit 1 RS-232 carrier detect Bit 0 Centronics busy Selects which edge on that pin causes an interrupt: On the ST and STE: 0 = high to low, 1 = low to high On the Falcon: 0 = low to high, 1 = high to low The polarity is inverted on the Falcon, which is why the wiki summary carries two lines for this register with !F and F tags. Note: on a Falcon the MFP is not actually used for serial communications, so the RS-232 bits are not meaningful there. From the Atari Compendium.
$FFFFFA05.B|RW|MFP_DIR|Data-direction %SRFKBRDC | | | | I/O-7 Mono Detect/Sound--------------+||||||| | | | | I/O-6 RS232 Ring Indicator------------+|||||| | | | | I/O-5 FDC/HDC--------------------------+||||| | | | | I/O-4 IKBD/MIDI-------------------------+|||| | | | | I/O-3 Blitter Done-----------------------+||| | | | | I/O-2 RS232 CTS---------------------------+|| | | | | I/O-1 RS232 DCD----------------------------+| | | | | I/O-0 Centronics Busy-----------------------+ |
$FFFFFA05 MFP_DIR Data Direction Register One bit per GPIO pin, same order as $FFFFFA01. Each bit is individually programmed: 0 = input, 1 = output. On a standard ST all eight pins are inputs, so this register reads as zero. Changing it without knowing what is wired to the pin can drive a line that something else is also driving. From the Atari Compendium.
$FFFFFA07.B|RW|MFP_IEA|Interrupt Enable A %76AbebeB |
$FFFFFA07 MFP_IEA Interrupt Enable Register A Bit 7 Monochrome monitor detect Bit 6 RS-232 ring indicator Bit 5 Timer A (STE and TT sound) Bit 4 Receive buffer full Bit 3 Receive error Bit 2 Transmit buffer empty Bit 1 Transmit error Bit 0 Timer B Setting a bit enables that interrupt source. The same bit layout applies to all four register A pairs: $FFFFFA07 Interrupt Enable A $FFFFFA0B Interrupt Pending A $FFFFFA0F Interrupt In-Service A $FFFFFA13 Interrupt Mask A Enable decides whether the source can interrupt at all; mask decides whether an enabled and pending interrupt is passed to the processor. Pending is set by the hardware and cleared by writing a ZERO to that bit, not a one. On a Falcon the MFP is not used for serial communications. From the Atari Compendium.
$FFFFFA09.B|RW|MFP_IEB|Interrupt Enable B %54CD3210 |
$FFFFFA09 MFP_IEB Interrupt Enable Register B Bit 7 FDC / HDC Bit 6 Keyboard / MIDI Bit 5 Timer C (200 Hz system clock) Bit 4 Timer D (USART baud rate) Bit 3 Blitter done Bit 2 RS-232 clear to send Bit 1 RS-232 carrier detect Bit 0 Centronics busy The same bit layout applies to all four register B pairs: $FFFFFA09 Interrupt Enable B $FFFFFA0D Interrupt Pending B $FFFFFA11 Interrupt In-Service B $FFFFFA15 Interrupt Mask B Timer C at bit 5 is the one driving the 200 Hz system clock counter at $000004BA and the VBL queue. Disabling it stops large parts of TOS working. From the Atari Compendium.
$FFFFFA0B.B|RW|MFP_IPA|Interrupt Pending A %76AbebeB | $FFFFFA0D.B|RW|MFP_IPB|Interrupt Pending B %54CD3210 | $FFFFFA0F.B|RW|MFP_ISA|Interrupt In-Service A %76AbebeB | $FFFFFA11.B|RW|MFP_ISB|Interrupt In-Service B %54CD3210 | $FFFFFA13.B|RW|MFP_IMA|Interrupt Mask A %76AbebeB | | | | I/O 7 Mono Detect/Sound--------------+||||||| | | | | I/O 6 RS232 Ring----------------------+|||||| | | | | Timer A--------------------------------+||||| | | | | Receive Buffer full---------------------+|||| | | | | Receive Error----------------------------+||| | | | | Transmit Buffer empty---------------------+|| | | | | Transmit Error-----------------------------+| | | | | Timer B-------------------------------------+ | $FFFFFA15.B|RW|MFP_IMB|Interrupt Mask B %54CD3210 | | | | I/O 5 FDC/HDC------------------------+||||||| | | | | I/O 4 IKBD/MIDI-----------------------+|||||| | | | | Timer C--------------------------------+||||| | | | | Timer D---------------------------------+|||| | | | | I/O 3 Blitter Done-----------------------+||| | | | | I/O 2 RS232 CTS---------------------------+|| | | | | I/O 1 RS232 DCD----------------------------+| | | | | I/O 0 Centronics Busy-----------------------+ |
$FFFFFA17.B|RW|MFP_VCR|Vector Register %xxxxI___ |0100 | | | End of Interrupt 0:software, 1:auto------+ |1000 | | | VCR should contain------------------%0100?000 |*
$FFFFFA17 MFP_VCR Vector Register Bits 7-4 Interrupt vector base, upper nibble Bit 3 End of interrupt mode: 1 = software end of interrupt 0 = automatic end of interrupt Bits 2-0 Supplied by the MFP as the interrupt number On the Atari the base is set to $40, so MFP interrupts use vectors $40 to $4F, which are addresses $00000100 to $0000013C in the exception vector table. In software end of interrupt mode the handler must clear the corresponding bit in the in-service register itself, otherwise no further interrupt of that or lower priority is delivered. The wiki summary notes the register should contain %0100?000. From the Atari Compendium.
$FFFFFA19.B|RW|MFP_TAC|Timer A Control %____EAAA |
$FFFFFA19 and $FFFFFA1B Timer A and Timer B Control Bits 3-0 (Timer A) and bits 3-0 (Timer B): 0000 Timer stop 0001 Delay mode, divide by 4 0010 Delay mode, divide by 10 0011 Delay mode, divide by 16 0100 Delay mode, divide by 50 0101 Delay mode, divide by 64 0110 Delay mode, divide by 100 0111 Delay mode, divide by 200 1000 Event count mode 1xxx Pulse extension mode, divider as above The MFP clock is 2.4576 MHz. With a divide by 10 prescale the timer ticks at 245.76 kHz, a period of about 4.069 microseconds, which is the usual choice for measuring short intervals. Timer A is normally free on an STF and is the usual pick for user timing. On an STE and TT it is used for DMA sound, so save and restore the control register there. Event count mode counts pulses on a GPIO pin rather than the internal clock, which is how the Timer B display-line counting trick works. From the Atari Compendium.
$FFFFFA1B.B|RW|MFP_TBC|Timer B Control %____EBBB | | | | Event Count Mode-------------------------1000 | | | | Pulse Extension--------------------------1xxx | | | | Delay------------------------------------0xxx |
$FFFFFA1D.B|RW|MFP_TDC|Timer C+D Control %_CCC_DDD | | | | Timer C Control-----------------------+++ ||| | | | | Timer D Control---------------------------+++ | | | | Stop Timer--------------------------------000 | | | | Delay,Clockdivide 4 3200Hz--------------001 | | | | Delay,Clockdivide 10 1280Hz--------------010 | | | | Delay,Clockdivide 16 800Hz--------------011 | | | | Delay,Clockdivide 50 256Hz--------------100 | | | | Delay,Clockdivide 64 200Hz--------------101 | | | | Delay,Clockdivide 100 128Hz--------------110 | | | | Delay,Clockdivide 200 64Hz--------------111 |
$FFFFFA1D MFP_TDC Timer C and D Control Bits 6-4 Timer C control Bits 2-0 Timer D control Bits 7 and 3 unused Both fields use the same encoding: 000 Timer stop 001 Delay mode, divide by 4 010 Delay mode, divide by 10 011 Delay mode, divide by 16 100 Delay mode, divide by 50 101 Delay mode, divide by 64 110 Delay mode, divide by 100 111 Delay mode, divide by 200 Timers C and D have no event count or pulse extension mode, which is why they take three bits rather than four. Timer C drives the 200 Hz system clock. Timer D is the USART baud rate generator. Neither should be stopped by application code. From the Atari Compendium.
$FFFFFA1F.B|RW|MFP_TAD|Timer A Data |
$FFFFFA1F to $FFFFFA25 Timer Data Registers $FFFFFA1F Timer A data $FFFFFA21 Timer B data $FFFFFA23 Timer C data $FFFFFA25 Timer D data Writing loads the timer's reload value. Reading returns the current count, which decrements from the reload value toward zero at the rate set by the prescale in the control register. When the count reaches zero the timer raises its interrupt and reloads automatically. A written value of 0 means 256. Reading a running timer is how short intervals are measured: note the value, do the work, read again and subtract. From the Atari Compendium.
$FFFFFA21.B|RW|MFP_TBD|Timer B Data | $FFFFFA23.B|RW|MFP_TCD|Timer C Data | $FFFFFA25.B|RW|MFP_TDD|Timer D Data |
$FFFFFA27.B|RW|MFP_SYC|Synchronous Character |
$FFFFFA27 MFP_SYC Synchronous Character Register Holds the character the USART searches for when running in synchronous mode, selected by the stop bit field in the USART control register at $FFFFFA29 being set to 00. Not used on a standard Atari, which runs the RS-232 port asynchronously.
$FFFFFA29.B|RW|MFP_UCR|Usart Control %DBBSSPE_ | | | | Divider 0:div1(sync),1:div16---------+|||||| | | | | Databits 00:8,01:7,10:6,11:5----------++|||| | | | | 00:sync,01:1stop,10:1.5stop,11:2stop----++|| | | | | Parity 0:off,1:on-------------------------+| | | | | Parity 0:odd,1:even------------------------+ |
$FFFFFA29 MFP_UCR USART Control Register Bit 7 Clock divide: if set, divide by 16 Bits 6-5 Data bits: 00 = 8 bits 01 = 7 bits 10 = 6 bits 11 = 5 bits Bits 4-3 Start and stop bits: 00 = synchronous 01 = 1 start, 1 stop 10 = 1 start, 1.5 stop 11 = 1 start, 2 stop Bit 2 Parity enable: if clear, parity is ignored Bit 1 Parity: 1 = even, 0 = odd Bit 0 unused Note the wiki summary line labels bits 4-3 as stop bits only; the Compendium describes them as the combined start and stop configuration. From the Atari Compendium.
$FFFFFA2B.B|RW|MFP_RES|Receiver Status %BOPFSCPR | | | | Buffer full--------------------------+||||||| | | | | Overrun Error-------------------------+|||||| | | | | Parity Error---------------------------+||||| | | | | Frame Error-----------------------------+|||| | | | | SCR found/Break--------------------------+||| | | | | SCR received/Startbit detected------------+|| | | | | Synchronous Strip Enable-------------------+| | | | | Receiver Enable-----------------------------+ |
$FFFFFA2B MFP_RES Receiver Status Register Bit 7 Buffer full Bit 6 Overrun error Bit 5 Parity error Bit 4 Frame error Bit 3 Search / break detected Bit 2 Match / character in progress Bit 1 Synchronous strip enable Bit 0 Receiver enable Bit 0 must be set before anything is received. Bits 7-4 are status and are cleared by reading the data register. From the Atari Compendium.
$FFFFFA2D.B|RW|MFP_TRS|Transmitter Status %BUAEBHLT | | | | Buffer Empty-------------------------+||||||| | | | | Underrun Error (char sent)------------+|||||| | | | | Auto Turnaround------------------------+||||| | | | | EOT End of Transmission-----------------+|||| | | | | Break------------------------------------+||| | | | | 00:High,01:Low,10:High,11:loopback,High---++| | | | | Transmitter Enable--------------------------+ |
$FFFFFA2D MFP_TRS Transmitter Status Register Bit 7 Buffer empty Bit 6 Underrun error Bit 5 Auto turnaround Bit 4 End of transmission Bit 3 Break Bit 2 High bit Bit 1 Low bit Bit 0 Transmitter enable Bits 2-1 together set the idle state of the transmit line: 00 = high, 01 = low, 10 = high, 11 = loopback, high Bit 0 must be set before anything is sent. Wait for bit 7 to be set before writing the next byte to $FFFFFA2F. From the Atari Compendium.
$FFFFFA2F.B|RW|MFP_UAD|Usart Data | ===========#==#=======#===============================================#===== ----------------------|FPC - Floating Point Coprocessor |----- ===========#==#=======#===============================================#=====
$FFFFFA40.W|RW|FPC_STA|Status (Response) Register |ME
$FFFFFA40 to $FFFFFA5C MC68881 Floating Point Coprocessor interface (Mega STE) These are not ordinary control registers: they are the MC68881's Coprocessor Interface Registers (CIR), memory mapped because the Mega STE's 68000 has no coprocessor instructions of its own. Software drives the FPU by writing a command to $FFFFFA4A, polling this Status register for the FPU's response, and moving operands through $FFFFFA50. Each register in the block has its own entry below. $FFFFFA40 FPC_STA Status (Response) CIR Read to find out what the coprocessor wants next. The value is a RESPONSE PRIMITIVE, not a set of independent status bits: Bit 15 CA, come again. Set means the main processor must read this register again after servicing the current primitive. Bit 14 PC, pass program counter. The instruction address must be sent to $FFFFFA58. Bit 13 DR, direction. 0 = main processor to coprocessor, 1 = coprocessor to main processor, for the transfer this primitive requests. Bits 12-8 primitive type: null (busy or done), transfer operation word, transfer single or multiple operands, evaluate effective address, transfer status/condition, take pre- or post-instruction exception. Bits 7-0 parameter: for transfer primitives, the number of bytes to move; for exception primitives, the vector number to take. A null primitive with CA clear means the operation is finished. A null primitive with CA set means the FPU is still busy, so keep polling. The full primitive encoding table is in the MC68881/68882 User's Manual, section 7 (coprocessor interface); it is a protocol rather than a fixed bit map, so only the framing bits above are reproduced here. SOURCING NOTE: none of the listings in the audit set (Hollis v7.0, which marks the whole block "???", the Hohwiller listing, the Compendium, FALREG or the Aura documents) carries any detail for these registers, and neither Hatari nor EmuTOS implements the Mega STE FPU interface. The addresses and names on this page match the standard Motorola CIR map exactly, which is what confirms them; the per-register descriptions below come from that map. Where a value can be checked against code it has been: the state frame format words on $FFFFFA44 are confirmed in Hatari src/cpu/fpp.c. The SFP004 accessory used the same CIR-mapped scheme at $FFFFFA40 on the Mega ST, which is why some listings tag this block Mega ST as well.
$FFFFFA42.W|RW|FPC_CTL|Control Register %______XA |ME | | | eXception acknowledge----------------------+| |ME | | | Abort the current operation-----------------+ |ME
$FFFFFA44.W|RW|FPC_SAV|Save Register (state frame format word) |ME
$FFFFFA44 FPC_SAV Save CIR Read to begin an FSAVE. Returns the state frame format word, which tells the main processor what kind of internal state the FPU has and how many bytes must be copied out: $0000 NULL frame, no context to save (FPU reset or idle with nothing pending). Nothing further to read. version:$18 IDLE frame, MC68881. High byte is the FPU version number, low byte the frame size in bytes minus four. version:$38 IDLE frame, MC68882 (larger internal state). other BUSY frame, mid-instruction state. Frame sizes confirmed in Hatari src/cpu/fpp.c, which writes $1C for a 68881 and $3C for a 68882 (frame size, with the size-minus-four value going into the format word) and treats format word $00 as the null frame. Reading this register also suspends the FPU, which is the whole point of FSAVE: it freezes the coprocessor so the operating system can context switch.
$FFFFFA46.W|RW|FPC_RES|Restore Register |ME
$FFFFFA46 FPC_RES Restore CIR Write the state frame format word here to begin an FRESTORE, then write back the frame body. Same format word encoding as the Save register above. Writing $0000 (the null frame) resets the coprocessor to the idle state and discards any saved context, which is how TOS and most FPU drivers initialise the part. Writing a format word the FPU does not recognise makes it signal a format error, which the main processor reports as an F-line or format exception.
$FFFFFA48.W|RW|FPC_OPW|Operation Word Register |ME
$FFFFFA48 FPC_OPW Operation Word CIR The main processor writes the F-line instruction's FIRST word (the operation word, $F2xx for coprocessor ID 1) here when the FPU asks for it with a "transfer operation word" response primitive. The FPU needs it to work out the addressing mode the instruction used. Not used for every instruction: only when the response primitive in the Status register requests it.
$FFFFFA4A.W|RW|FPC_CMD|Command Register |ME
$FFFFFA4A FPC_CMD Command CIR Writing the command word here STARTS an operation. It takes the second word of the F-line instruction, which encodes the FPU operation, source and destination registers and data format (for example FADD, FMUL, FMOVE with an extended, double, single, packed or integer operand). After the write, poll the Status register at $FFFFFA40 for the FPU's response primitive, which says what to do next: transfer an operand through $FFFFFA50, transfer the operation word, take an exception, or nothing further (operation complete). This is the register the whole interface revolves around: no write here, no FPU activity.
$FFFFFA4C.W|RW| - |Reserved |ME
$FFFFFA4E.W|RW|FPC_CCR|Condition Code Register |ME
$FFFFFA4E FPC_CCR Condition CIR Used by the conditional instructions FBcc, FScc, FDBcc and FTRAPcc. The main processor writes the condition predicate (the low 6 bits of the instruction's condition field, giving the 32 IEEE conditions plus the unordered variants) and the FPU evaluates it against the current floating point condition codes. The result comes back through the Status register as a "take branch / do not take branch" response primitive, not as a bit in this register. The main processor then acts on the branch itself, since the FPU has no program counter. A NaN operand makes the unordered conditions true and can raise the BSUN exception, which is why the predicate matters rather than a simple true/false test.
$FFFFFA50.L|RW|FPC_OPR|Operand Register |ME
$FFFFFA50 FPC_OPR Operand CIR The 32 bit data port. Every operand and result passes through here, a longword at a time, in the direction and count the response primitive in the Status register specifies: single precision 1 longword double precision 2 longwords extended precision 3 longwords packed decimal 3 longwords integer 1 longword (byte and word operands are sign extended into it) Transfers must be done in the order and quantity requested; reading or writing more longwords than the primitive asked for confuses the interface protocol. This is the only register in the block that is a longword port rather than a control word.
$FFFFFA54.W|RW|FPC_SEL|Register Select |ME
$FFFFFA54 FPC_SEL Register Select CIR Read after a "transfer multiple registers" response primitive (FMOVEM). Returns a bit mask, one bit per floating point data register FP0 to FP7, saying which registers the main processor must move through the Operand register and in which order. For the control register form of FMOVEM the mask instead selects among FPCR, FPSR and FPIAR. Only meaningful immediately after the primitive that requests it; reading it at any other time returns nothing useful.
$FFFFFA56.W|RW| - |Reserved |ME
$FFFFFA58.L|RW|FPC_IAR|Instruction Address Register |ME
$FFFFFA58 FPC_IAR Instruction Address CIR The main processor writes the ADDRESS of the F-line instruction currently being executed, when the FPU requests it with a "transfer instruction address" response primitive. The FPU keeps it in FPIAR so that an exception handler can find the instruction that faulted. Without it the FPU would have no way to report where an error happened, since it never sees the program counter.
$FFFFFA5C.L|RW|FPC_OAR|Operand Address Register |ME
$FFFFFA5C FPC_OAR Operand Address CIR Carries the effective ADDRESS of a memory operand, rather than the data itself. Used by the "evaluate effective address and transfer data" and "take pre-instruction exception" response primitives, so the FPU can tell the main processor where to fetch from or store to, and so that an exception frame can record the faulting operand address. Written by the main processor when the primitive asks for it; read back when the FPU supplies an address.
===========#==#=======#===============================================#===== ----------------------|MFP 68901 number 2 |----- ===========#==#=======#===============================================#=====
$FFFFFA81.B|RW|MF2_PDR|Parallel Port Data Register (GPIP) %SRD_ISGG |TT
$FFFFFA81 MF2_PDR Second MFP GPIP (TT) The TT's second MC68901. The register set and every bit layout are identical to the first MFP at $FFFFFA01 onwards, on the same odd-address spacing; see the entries there for the bit detail of the AER, DDR, interrupt, timer and USART registers. Only the GPIP pin wiring differs: Bit 7 SCSI controller interrupt (NCR 5380) Bit 6 RTC interrupt (MC146818A) Bit 5 SCSI DMAC interrupt Bit 4 Reserved Bit 3 RS-232 Ring Indicator (SCC channel B) Bit 2 SCC-DMA controller interrupt Bit 1 General purpose input GPI 1 Bit 0 General purpose input GPI 0 The pin map follows the second MFP vector table at $00000140 to $0000017C (see the System variables page) and the Atari Compendium's TT MFP list. Bits 7 and 5 are confirmed in EmuTOS bios/scsi.c, which polls TT_MFP gpip bit 7 for the 5380 interrupt and bit 5 for the SCSI DMAC interrupt. This MFP's interrupts use their own block of 16 vectors: TOS programs the MF2 vector register with base $50, so vector numbers $50-$5F land at addresses $00000140 to $0000017C.
$FFFFFA83.B|RW|MF2_AER|Active Edge Register |TT $FFFFFA85.B|RW|MF2_DDR|Data Direction Register |TT $FFFFFA87.B|RW|MF2_IEA|Interrupt Enable A |TT $FFFFFA89.B|RW|MF2_IEB|Interrupt Enable B |TT $FFFFFA8B.B|RW|MF2_IPA|Interrupt Pending A |TT $FFFFFA8D.B|RW|MF2_IPB|Interrupt Pending B |TT $FFFFFA8F.B|RW|MF2_ISA|Interrupt In-Service A |TT $FFFFFA91.B|RW|MF2_ISB|Interrupt In-Service B |TT $FFFFFA93.B|RW|MF2_IMA|Interrupt Mask A |TT $FFFFFA95.B|RW|MF2_IMB|Interrupt Mask B |TT $FFFFFA97.B|RW|MF2_VCR|Vector Register |TT $FFFFFA99.B|RW|MF2_TAC|Timer A Control |TT $FFFFFA9B.B|RW|MF2_TBC|Timer B Control |TT $FFFFFA9D.B|RW|MF2_TDC|Timer C+D Control |TT $FFFFFA9F.B|RW|MF2_TAD|Timer A Data |TT $FFFFFAA1.B|RW|MF2_TBD|Timer B Data |TT $FFFFFAA3.B|RW|MF2_TCD|Timer C Data |TT $FFFFFAA5.B|RW|MF2_TDD|Timer D Data |TT $FFFFFAA7.B|RW|MF2_SCR|Synchronous Character Register |TT $FFFFFAA9.B|RW|MF2_UCR|USART Control Register |TT $FFFFFAAB.B|RW|MF2_RSR|Receiver Status Register |TT $FFFFFAAD.B|RW|MF2_TSR|Transmitter Status Register |TT $FFFFFAAF.B|RW|MF2_UAD|USART Data Register |TT ===========#==#=======#===============================================#===== ----------------------|ACIA 6850 (Midi/Keyboard) |----- ===========#==#=======#===============================================#=====
$FFFFFC00.B|R-|KBD_CTL|IKBD Status %IPOFCDTR |
$FFFFFC00 KBD_CTL IKBD ACIA Status (read) / Control (write) READ - status: Bit 7 Interrupt request Bit 6 Parity error Bit 5 Receiver overrun Bit 4 Frame error Bit 3 Clear to send Bit 2 Data carrier detect Bit 1 Transmit data register full Bit 0 Receive data register full WRITE - control: Bit 7 Enable receive interrupts Bits 6-5 Transmitter interrupt configuration: 00 RTS low, interrupts disabled 01 RTS low, interrupts enabled 10 RTS high, interrupts disabled 11 RTS low, interrupts disabled, send break Bits 4-2 Word format, data bits - parity - stop bits: 000 7-E-2 001 7-O-2 010 7-E-1 011 7-O-1 100 8-N-2 101 8-N-1 110 8-E-1 111 8-O-1 Bits 1-0 Clock divide: 00 divide by 1 (500000 cps) 01 divide by 16 (31250 cps, MIDI standard) 10 divide by 64 (7812.5 cps, IKBD) 11 master reset The IKBD is set to $96: 7 bits, no parity, 1 stop, divide by 64, RTS low, receive interrupts on. The MIDI ACIA at $FFFFFC04 uses the same register layout and is set to $95, the same but divide by 16. From the Atari Compendium.
" |-W|KBD_CTL|IKBD Control %ITTBSPDD | | | | 7N1,7812.5,RTS low,Rec on,Send off= %10010110 |* $FFFFFC02.B|RW|KBD_DAT|IKBD Data | $FFFFFC04.B|R-|MID_CTL|MIDI Status %IPOFCDTR | | | | Interrupt Request--------------------+||||||| | | | | Parity Error--------------------------+|||||| | | | | Receiver Overrun-----------------------+||||| | | | | Frame Error-----------------------------+|||| | | | | CTS Clear to Send------------------------+||| | | | | DCD Data Carrier Detect-------------------+|| | | | | Transmitter Data Register full-------------+| | | | | Receiver Data Register full-----------------+ | " |-W|MID_CTL|MIDI Control %ITTBSPDD | | | | 7N1,31250,RTS low,Rec on,Send off = %10010101 |* | | | Interrupt 0:off,1:on-----------------+||||||| | | | | RTS low, TransmitIRQ off--------------00||||| | | | | RTS low, TransmitIRQ on---------------01||||| | | | | RTS high,TransmitIRQ off--------------10||||| | | | | RTS low, TransmitIRQ off,send break---11||||| | | | | 8 Databits,2 Stopbits,Parity even-------000|| | | | | 8 Databits,2 Stopbits,Parity odd--------001|| | | | | 8 Databits,1 Stopbits,Parity even-------010|| | | | | 8 Databits,1 Stopbits,Parity odd--------011|| | | | | 7 Databits,2 Stopbits,Parity off--------100|| | | | | 7 Databits,1 Stopbits,Parity off--------101|| | | | | 7 Databits,1 Stopbits,Parity even-------110|| | | | | 7 Databits,1 Stopbits,Parity odd--------111|| | | | | Clockdivide 1 - 500000.0cps---------------00 | | | | Clockdivide 16 - 31250.0cps (MIDI Std)----01 | | | | Clockdivide 64 - 7812.5cps (IKBD!)-------10 | | | | Master Reset-------------------------------11 | $FFFFFC06.B|RW|MID_DAT|MIDI Data | ===========#==#=======#===============================================#===== ----------------------|RP5C15 Real Time Clock |----- ===========#==#=======#===============================================#=====
$FFFFFC21.B|RW| - |Seconds mod 10 %____xxxx |MST
$FFFFFC21 to $FFFFFC39 RP5C15 Clock Registers, Bank 0 and Bank 1 IMPORTANT: this chip has TWO banks of registers at the same addresses. Bit 0 of the mode register at $FFFFFC3B selects which bank is visible. The wiki listing documents only Bank 0. Address Bank 0 Bank 1 $FFFFFC21 Seconds ones (0-9) Clock output frequency $FFFFFC23 Seconds tens (0-5) Reset seconds (see below) $FFFFFC25 Minutes ones (0-9) Alarm minutes ones $FFFFFC27 Minutes tens (0-5) Alarm minutes tens $FFFFFC29 Hours ones (0-9) Alarm hours ones $FFFFFC2B Hours tens (0-2) Alarm hours tens $FFFFFC2D Day of week (0-6) Alarm day of week $FFFFFC2F Date ones (0-9) Alarm date ones $FFFFFC31 Date tens (0-3) Alarm date tens $FFFFFC33 Month ones (0-9) not used $FFFFFC35 Month tens (0-1) 12/24 hour select $FFFFFC37 Year ones (0-9) Leap year register (0-3) $FFFFFC39 Year tens (0-9) not used All values are BCD digits, one digit per register, low nibble only. Bank 0 notes: Day of week: 0 = Sunday. Hours tens in 12 hour mode is 0-1, with bit 1 set for PM. Year is stored as (year - 1980). Bank 1 notes: $FFFFFC21 clock output frequency: 0 = open collector CLKOUT 4 = 16 Hz 1 = 16384 Hz 5 = 1 Hz 2 = 1024 Hz 6 = 1/60 Hz 3 = 128 Hz 7 = open collector CLKOUT $FFFFFC23: setting bit 0 resets the seconds register to zero, and if seconds were between 30 and 59 it also increments the minutes register. This is the "round to nearest minute" function. $FFFFFC35: bit 1 set = 24 hour mode, clear = 12 hour mode. $FFFFFC37 leap year register: 0 = this is a leap year. Mega ST only. From the Atari Compendium.
$FFFFFC23.B|RW| - |Seconds div 10 %____xxxx |MST $FFFFFC25.B|RW| - |Minutes mod 10 %____xxxx |MST $FFFFFC27.B|RW| - |Minutes div 10 %____xxxx |MST $FFFFFC29.B|RW| - |Hours mod 10 %____xxxx |MST $FFFFFC2B.B|RW| - |Hours div 10 %____xxxx |MST $FFFFFC2D.B|RW| - |Weekday %____xxxx |MST $FFFFFC2F.B|RW| - |Day mod 10 %____xxxx |MST $FFFFFC31.B|RW| - |Day div 10 %____xxxx |MST $FFFFFC33.B|RW| - |Month mod 10 %____xxxx |MST $FFFFFC35.B|RW| - |Month div 10 %____xxxx |MST $FFFFFC37.B|RW| - |Year mod 10 %____xxxx |MST $FFFFFC39.B|RW| - |Year div 10 %____xxxx |MST
$FFFFFC3B.B|RW| - |Clock mode %____xxxx |MST
$FFFFFC3B Mode Register Bit 3 Timer enable: 0 = clock stopped Bit 2 Alarm enable: 0 = alarm off Bits 1-0 Bank select Bit 0 is the one that matters: it chooses whether the register block at $FFFFFC21 to $FFFFFC39 shows Bank 0 (the clock) or Bank 1 (the alarm and configuration). See $FFFFFC21. Stopping the clock with bit 3 is how a consistent multi register read is done, since the counters would otherwise roll over mid read. Mega ST only. From the Atari Compendium.
$FFFFFC3D.B|RW| - |Clock test %____xxxx |MST
$FFFFFC3D Test Register Lower nibble must read as zero for the chip to be considered working correctly. Used for factory test. Mega ST only. From the Atari Compendium.
$FFFFFC3F.B|RW| - |Clock reset %____xxxx |MST
$FFFFFC3F Reset Register Bit 3 1 Hz alarm pulse: 0 = enabled Bit 2 16 Hz alarm pulse: 0 = enabled Bit 1 Alarm reset: 1 = reset the alarm registers Bit 0 Clock reset: 1 = reset the clock registers Writing the reset bits clears the corresponding register bank to zero. Mega ST only. From the Atari Compendium.
===========#==#=======#===============================================#===== ----------------------|Add-on and expansion area |----- ===========#==#=======#===============================================#=====
$FFFFFE00.W|RW| - |Add-on control / MonSTer register |*
$FFFFFE00 and $FFFFFE0E Add-on control Not present on stock Atari hardware. Known to be used by: SEC BOOSTER. CONFLICT: EmuTOS uses this same address block for the MonSTer expansion board. From EmuTOS source: bios/machine.h MONSTER_REG $FFFFFE00 bios/clock.c MONSTER_I2C_DIR $FFFFFE02 bios/clock.c MONSTER_I2C_SCL $FFFFFE04 bios/clock.c MONSTER_I2C_SDA $FFFFFE06 MonSTer's main register is at exactly the same address as the first SEC BOOSTER control register, and its I2C bus lines occupy $FFFFFE02 to $FFFFFE06 immediately above. EmuTOS only touches these when built with CONF_WITH_MONSTER enabled, which is off by default. A stock EmuTOS build will not write here. A MonSTer-enabled build will. Anyone fitting both boards, or running a MonSTer-enabled EmuTOS alongside a SEC BOOSTER, should expect trouble. EmuTOS also carries CONF_WITH_MAGNUM and CONF_WITH_NOVA for two further add-on boards; their address usage has not yet been checked against this listing. Extended bit information is not currently available for the SEC BOOSTER side of these registers.
$FFFFFE0E.W|RW| - |Add-on control |* ===========#==#=======#===============================================#===== $FFFFFF82.W|R-| - |Unknown status register |F | | | CHECK: purpose unknown. The Aura FALC3.TXT | | | | listing records it as two new Falcon read | | | | registers, $FFFFFF82 reading $1C and | | | | $FFFFFF83 reading $00, with no function | | | | identified. Not referenced by Hatari, EmuTOS | | | | or TOS source. | ===========#==#=======#===============================================#=====
$FFFF820D.B|RW|VDL_VBL|Video Base Lo %xxxxxxx_ |STE,F ----+---- | +- ---+--- ------------------+---------------------------- --+-- | | | | | | | | | | | Computer Type---------------+ | | | | +---Description | | | +--------------------------Label | | +--------------------------------Read/Write Access | +----------------------------------Type (Byte,Word,Long) +----------------------------------------Address (extended to 32 Bit) Computer Type: * |Software defined Standard !xxx|all except xxx 0x0 |MC680x0 only 0x0+|MC680x0 or higher BLT |Standard on TT,STE,ME,F (Blitter) SCC |Standard on TT,ME,F VME |Standard on TT,ME ST |Atari ST (260/520/1040) STE |Atari STE (520/1040) TT |Atari TT MST |Atari Mega ST (1/2) ME |Atari Mega STE F |Atari Falcon Read/Write Access: R/-|Read only (read register) -/W|Write only (write register) R/?|Read access allowed ?/W|Write access allowed r/?|Read access allowed but not sensible ?/w|Write access allowed but not sensible Source precedence when documents disagree: 1. Live TOS source (th-otto/tos1x, th-otto/tos3x) and EmuTOS source. Executable and hardware-validated; TOS is Atari's own code. 2. The Atari Compendium. Broad and careful, but not perfect. 3. Everything else, including this wiki's own history and the Dan Hollis hardware register listing. Entries marked UNVERIFIED rest on a single source only.





Back to Memory Map for Atari ST,STE,TT and Falcon