My Apollo workstations

The story: 1999-10-28

I got the Apollos from Greg Roberts, ZS1BI. They were used at the Observatory before becoming obsolete.


The 4-plane color graphics controller has the following features:
• High-resolution 1024-pixel x 800-line x 4-plane display
• 16 simultaneous colors selectable from a palette of 4096
• Flicker-free, 60-Hz noninterlaced screen refresh
• Small physical size and low power requirements
• Dual-port, 512-KB image memory using high-density dynamic RAMs
• High-speed image and main memory BL Ts facilitated by specialized gate arrays
• Support for the DN3000 6-MHz AT bus

1280 X 1024 Monochrome Graphics Controllers

Two monochrome graphics controllers are available for the Domain System. The DN3000 controller
(008157) is designed for use in a 6-MHz AT-bus environment; the DN4000 controller (010735) is
designed for use in an 8-MHz AT-bus environment. Both controllers have the following features:
• High-resolution 1280-pixel x 1024-line display
• Flicker-free, 64-Hz noninterlaced screen refresh
• Low power requirements
• 256-KB image memory using high-density dynamic Dual-Ported Video RAMs
• High-speed image and main memory Block Transfers (BL T) facilitated by a specialized gate array

DN3000 Memory Map

The DN3000 and DN4000 memory map is in the Domain Series 3000 / Series 4000 Technical Reference Manual available from Bitsavers.

DN3500 Memory Map

The best source I've found for the DN3500 memory map is in the MAME sources, file /src/mame/drivers/apollo.cpp.

(Yes, this is work in progress. Thanks for asking :-)

		map(0x000000, 0x00ffff).rom(); /* boot ROM  */
		map(0x000000, 0x00ffff).w(FUNC(apollo_state::apollo_rom_w));
		map(0x010000, 0x0100ff).rw(FUNC(apollo_state::apollo_csr_status_register_r), FUNC(apollo_state::apollo_csr_status_register_w));
		map(0x010100, 0x0101ff).rw(FUNC(apollo_state::apollo_csr_control_register_r), FUNC(apollo_state::apollo_csr_control_register_w));
		map(0x010200, 0x0102ff).rw(FUNC(apollo_state::cache_status_register_r), FUNC(apollo_state::cache_control_register_w));
		map(0x010300, 0x0103ff).rw(FUNC(apollo_state::task_alias_register_r), FUNC(apollo_state::task_alias_register_w));
		map(0x010400, 0x0104ff).rw(m_sio, FUNC(apollo_sio::read), FUNC(apollo_sio::write));
		map(0x010500, 0x0105ff).rw(m_sio2, FUNC(apollo_sio::read), FUNC(apollo_sio::write));
		map(0x010800, 0x0108ff).rw(m_ptm, FUNC(ptm6840_device::read), FUNC(ptm6840_device::write)).umask32(0x00ff00ff);
		map(0x010900, 0x0109ff).rw(FUNC(apollo_state::apollo_rtc_r), FUNC(apollo_state::apollo_rtc_w));
		map(0x010c00, 0x010cff).rw(FUNC(apollo_state::/*"dma1",*/apollo_dma_1_r), FUNC(apollo_state::apollo_dma_1_w));
		map(0x010d00, 0x010dff).rw(FUNC(apollo_state::/*"dma2",*/apollo_dma_2_r), FUNC(apollo_state::apollo_dma_2_w));
		map(0x011000, 0x0110ff).rw(m_pic8259_master, FUNC(pic8259_device::read), FUNC(pic8259_device::write));
		map(0x011100, 0x0111ff).rw(m_pic8259_slave, FUNC(pic8259_device::read), FUNC(pic8259_device::write));
		map(0x011200, 0x0112ff).rw(m_node_id, FUNC(apollo_ni::read), FUNC(apollo_ni::write));
		map(0x011300, 0x0113ff).rw(FUNC(apollo_state::latch_page_on_parity_error_register_r), FUNC(apollo_state::latch_page_on_parity_error_register_w));
		map(0x011600, 0x0116ff).rw(FUNC(apollo_state::master_req_register_r), FUNC(apollo_state::master_req_register_w));

		map(0x016400, 0x0164ff).rw(FUNC(apollo_state::selective_clear_locations_r), FUNC(apollo_state::selective_clear_locations_w));
		map(0x017000, 0x017fff).rw(FUNC(apollo_state::apollo_address_translation_map_r), FUNC(apollo_state::apollo_address_translation_map_w));

// ISA/AT Bus notes
// I/O space: to get the Apollo address = take the PC I/O address, keep the low 3 bits how they are, and shift the rest left 7, inserting zeros.
// then add 0x40000 for the I/O base.
// example: 3c503 Ethernet is at I/O 300h on PC, which is (%1100000000 -> 1 1000 0000 0000 0000) + 0x40000 = 0x58000
// 0x5e800 - 0x4000 = 1e800 ->1 1110 1000 0000 0000 -> 11 1101 0000 = 3d0
// Memory space: addresses from 0x80000 to 0xffffff are supported, including the possibility of stock PC MDA at a0000

#define ATBUS_IO_BASE       0x040000
#define ATBUS_IO_END        0x05ffff
#define ATBUS_MEMORY_BASE   0x080000
#define ATBUS_MEMORY_END    0xffffff

		map(ATBUS_IO_BASE, ATBUS_IO_END).rw(FUNC(apollo_state::apollo_atbus_io_r), FUNC(apollo_state::apollo_atbus_io_w));
		map(ATBUS_MEMORY_BASE, ATBUS_MEMORY_END).rw(FUNC(apollo_state::apollo_atbus_memory_r), FUNC(apollo_state::apollo_atbus_memory_w));

#if DN3500_RAM_SIZE == 8
#define DN3500_RAM_BASE     0x1000000
#define DN3500_RAM_END      0x17fffff
#define DN3500_RAM_CONFIG_BYTE  0x64 // 4-4-0-0
#elif DN3500_RAM_SIZE == 16
#define DN3500_RAM_BASE     0x1000000
#define DN3500_RAM_END      0x1ffffff
#define DN3500_RAM_CONFIG_BYTE 0x60 // 4-4-4-4
#else /* DN3500_RAM_SIZE == 32 */
#define DN3500_RAM_BASE     0x1000000
#define DN3500_RAM_END      0x3ffffff
#define DN3500_RAM_CONFIG_BYTE 0x20 // 8-8-8-8

		// FIXME: must match with RAM size in driver/apollo_sio.c
		// map(DN3500_RAM_BASE, DN3500_RAM_END).ram(); /* 8MB RAM */
		map(DN3500_RAM_BASE, DN3500_RAM_END).ram().w(FUNC(apollo_state::ram_with_parity_w)).share(RAM_TAG);

		map(0x05d800, 0x05dc07).rw(m_graphics, FUNC(apollo_graphics_15i::apollo_mcr_r), FUNC(apollo_graphics_15i::apollo_mcr_w));
		map(0xfa0000, 0xfdffff).rw(m_graphics, FUNC(apollo_graphics_15i::apollo_mgm_r), FUNC(apollo_graphics_15i::apollo_mgm_w));

		map(0x05e800, 0x05ec07).rw(m_graphics, FUNC(apollo_graphics_15i::apollo_ccr_r), FUNC(apollo_graphics_15i::apollo_ccr_w));
		map(0x0a0000, 0x0bffff).rw(m_graphics, FUNC(apollo_graphics_15i::apollo_cgm_r), FUNC(apollo_graphics_15i::apollo_cgm_w));

SIO is a Signetics 2681 Duart. Timer is 6840. Clock is 146818. PIC is 8259A. DMA controller is 8237A.

Rom images

BOOT    J10
08475   03
Domain 3000 ROM
27256 (32K)
12191  7
Domain 3500 ROM
27512 (64K)


I have the following original tapes


[Image] Hit Count
hits since 1999-11-01.

Back to Wouter's CCC Page (This page last modified 2020-02-19)