| Previous | 199869 Revisions | Next |
| r26307 Wednesday 20th November, 2013 at 16:00:40 UTC by Jürgen Buchmüller |
|---|
| The big split: move all function blocks to their own header files. |
| [/branches/alto2/src/emu/cpu] | cpu.mak |
| [/branches/alto2/src/emu/cpu/alto2] | a2curt.c a2curt.h* a2dht.c a2dht.h* a2disk.c a2disk.h* a2disp.c a2disp.h* a2dvt.c a2dvt.h* a2dwt.c a2dwt.h* a2emu.c a2emu.h* a2ether.c a2ether.h* a2hw.c a2hw.h a2jkff.h* a2kbd.c a2kbd.h* a2ksec.c a2ksec.h* a2kwd.c a2kwd.h* a2mem.c a2mem.h* a2mouse.c a2mouse.h* a2mrt.c a2mrt.h* a2part.c a2part.h* a2ram.c a2ram.h* a2roms.c a2roms.h alto2cpu.c alto2cpu.h alto2dsm.c |
| [/branches/alto2/src/emu/imagedev] | diablo.c diablo.h |
| [/branches/alto2/src/emu/machine] | diablo_hd.c diablo_hd.h |
| [/branches/alto2/src/mess/drivers] | alto2.c |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII Dual J/K flip-flop 74109 emulation | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifndef _A2JKFF_H_ | |
| 11 | #define _A2JKFF_H_ | |
| 12 | ||
| 13 | /** | |
| 14 | * @brief enumeration of the inputs and outputs of a JK flip-flop type 74109 | |
| 15 | * <PRE> | |
| 16 | * 74109 | |
| 17 | * Dual J-/K flip-flops with set and reset. | |
| 18 | * | |
| 19 | * +----------+ +-----------------------------+ | |
| 20 | * /1RST |1 +--+ 16| VCC | J |/K |CLK|/SET|/RST| Q |/Q | | |
| 21 | * 1J |2 15| /2RST |---+---+---+----+----+---+---| | |
| 22 | * /1K |3 14| 2J | X | X | X | 0 | 0 | 1 | 1 | | |
| 23 | * 1CLK |4 74 13| /2K | X | X | X | 0 | 1 | 1 | 0 | | |
| 24 | * /1SET |5 109 12| 2CLK | X | X | X | 1 | 0 | 0 | 1 | | |
| 25 | * 1Q |6 11| /2SET | 0 | 0 | / | 1 | 1 | 0 | 1 | | |
| 26 | * /1Q |7 10| 2Q | 0 | 1 | / | 1 | 1 | - | - | | |
| 27 | * GND |8 9| /2Q | 1 | 0 | / | 1 | 1 |/Q | Q | | |
| 28 | * +----------+ | 1 | 1 | / | 1 | 1 | 1 | 0 | | |
| 29 | * | X | X |!/ | 1 | 1 | - | - | | |
| 30 | * +-----------------------------+ | |
| 31 | * | |
| 32 | * [This information is part of the GIICM] | |
| 33 | * </PRE> | |
| 34 | */ | |
| 35 | typedef enum { | |
| 36 | JKFF_0, //!< no inputs or outputs | |
| 37 | JKFF_CLK = (1 << 0), //!< clock signal | |
| 38 | JKFF_J = (1 << 1), //!< J input | |
| 39 | JKFF_K = (1 << 2), //!< K' input | |
| 40 | JKFF_S = (1 << 3), //!< S' input | |
| 41 | JKFF_C = (1 << 4), //!< C' input | |
| 42 | JKFF_Q = (1 << 5), //!< Q output | |
| 43 | JKFF_Q0 = (1 << 6) //!< Q' output | |
| 44 | } jkff_t; | |
| 45 | ||
| 46 | #endif // A2JKFF_H |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r26306 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII RAM PROM loading and decoding | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 1 | 10 | #ifndef _CPU_A2ROMS_H_ |
| 2 | 11 | #define _CPU_A2ROMS_H_ |
| 3 | 12 |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII disk sector task | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII disk sector task (KSEC) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2KSEC_H_ | |
| 14 | #define _A2KSEC_H_ | |
| 15 | //! BUS source for disk sector task | |
| 16 | enum { | |
| 17 | bs_ksec_read_kstat = bs_task_3, //!< bus source: read disk status register | |
| 18 | bs_ksec_read_kdata = bs_task_4 //!< bus source: read disk data register | |
| 19 | }; | |
| 20 | ||
| 21 | //! F1 functions for disk sector task | |
| 22 | enum { | |
| 23 | //!< f1 10: undefined | |
| 24 | f1_ksec_strobe = f1_task_11, //!< f1 11: strobe | |
| 25 | f1_ksec_load_kstat = f1_task_12, //!< f1 12: load kstat register | |
| 26 | f1_ksec_increcno = f1_task_13, //!< f1 13: increment record number | |
| 27 | f1_ksec_clrstat = f1_task_14, //!< f1 14: clear status register | |
| 28 | f1_ksec_load_kcom = f1_task_15, //!< f1 15: load kcom register | |
| 29 | f1_ksec_load_kadr = f1_task_16, //!< f1 16: load kadr register | |
| 30 | f1_ksec_load_kdata = f1_task_17 //!< f1 17: load kdata register | |
| 31 | }; | |
| 32 | ||
| 33 | //! F2 functions for disk sector task | |
| 34 | enum { | |
| 35 | f2_ksec_init = f2_task_10, //!< f2 10: branches NEXT[5-9] on WDTASKACT && WDINIT | |
| 36 | f2_ksec_rwc = f2_task_11, //!< f2 11: branches NEXT[8-9] on READ/WRITE/CHECK for record | |
| 37 | f2_ksec_recno = f2_task_12, //!< f2 12: branches NEXT[8-9] on RECNO[0-1] | |
| 38 | f2_ksec_xfrdat = f2_task_13, //!< f2 13: branches NEXT[9] on !SEEKONLY | |
| 39 | f2_ksec_swrnrdy = f2_task_14, //!< f2 14: branches NEXT[9] on !SWRDY | |
| 40 | f2_ksec_nfer = f2_task_15, //!< f2 15: branches NEXT[9] on !KFER | |
| 41 | f2_ksec_strobon = f2_task_16, //!< f2 16: branches NEXT[9] on STROBE | |
| 42 | //!< f2 17: undefined | |
| 43 | }; | |
| 44 | ||
| 45 | void f1_early_ksec_block(void); //!< block ksec task | |
| 46 | void init_ksec(int task); //!< 004 initialize disk sector task | |
| 47 | void exit_ksec(); | |
| 48 | #endif // _A2KSEC_H_ | |
| 49 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII display vertical task | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII display vertical task (DVT) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2DVT_H_ | |
| 14 | #define _A2DVT_H_ | |
| 15 | ||
| 16 | //! F2 functions for display vertical task | |
| 17 | enum { | |
| 18 | f2_dvt_evenfield = f2_task_10 //!< f2 10: load even field | |
| 19 | }; | |
| 20 | ||
| 21 | void f1_early_dvt_block(); //!< F1 func: disable the display word task | |
| 22 | void activate_dvt(); //!< called by the CPU when the display vertical task becomes active | |
| 23 | void init_dvt(int task); //!< 014 initialize display vertical task | |
| 24 | void exit_dvt(); //!< deinitialize display vertical task | |
| 25 | #endif // _A2DVT_H_ | |
| 26 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII memory refresh task | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /********************************************************** |
| 2 | * | |
| 2 | * Xerox AltoII disassembler | |
| 3 | 3 | * |
| 4 | * Copyright | |
| 4 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 5 | 5 | * |
| 6 | 6 | * Licenses: MAME, GPLv2 |
| 7 | 7 | **********************************************************/ |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII parity task | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII memory refresh task (MRT) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2MRT_H_ | |
| 14 | #define _A2MRT_H_ | |
| 15 | void f1_early_mrt_block(); //!< F1 func: block the display word task | |
| 16 | void activate_mrt(); //!< called by the CPU when MRT becomes active | |
| 17 | void init_mrt(int task); //!< 010 initialize memory refresh task | |
| 18 | void exit_mrt(); //!< deinitialize memory refresh task | |
| 19 | #endif // _A2MRT_H_ | |
| 20 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII parity task (PART) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2PART_H_ | |
| 14 | #define _A2PART_H_ | |
| 15 | void activate_part(); | |
| 16 | void init_part(int task); //!< 015 initialize parity task | |
| 17 | void exit_part(); //!< deinitialize parity task | |
| 18 | #endif // _A2PART_H_ | |
| 19 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII memory interface | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII RAM related functions | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII memory block (MEM) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #define ALTO2_RAM_SIZE 0200000 //!< size of main memory in words | |
| 13 | #define ALTO2_IO_PAGE_BASE 0177000 //!< base address of the memory mapped io range | |
| 14 | #define ALTO2_IO_PAGE_SIZE 0001000 //!< size of the memory mapped io range | |
| 15 | ||
| 16 | #else // ALTO2_DEFINE_CONSTANTS | |
| 17 | #ifndef _A2MEM_H_ | |
| 18 | #define _A2MEM_H_ | |
| 19 | //! memory access mode | |
| 20 | enum { | |
| 21 | ALTO2_MEM_NONE, | |
| 22 | ALTO2_MEM_ODD = (1 << 0), | |
| 23 | ALTO2_MEM_RAM = (1 << 1), | |
| 24 | ALTO2_MEM_NIRVANA = (1 << 2) | |
| 25 | }; | |
| 26 | ||
| 27 | struct { | |
| 28 | UINT32* ram; //!< main memory organized as double-words | |
| 29 | UINT8* hpb; //!< Hamming Code bits (6) and Parity bits (1) per double word | |
| 30 | UINT32 mar; //!< memory address register | |
| 31 | UINT32 rmdd; //!< read memory data double-word | |
| 32 | UINT32 wmdd; //!< write memory data double-word | |
| 33 | UINT16 md; //!< memory data register | |
| 34 | UINT64 cycle; //!< cycle when the memory address register was loaded | |
| 35 | ||
| 36 | /** | |
| 37 | * @brief memory access under the way if non-zero | |
| 38 | * 0: no memory access (MEM_NONE) | |
| 39 | * 1: invalid | |
| 40 | * 2: memory access even word (MEM_RAM) | |
| 41 | * 3: memory access odd word (MEM_RAM | MEM_ODD) | |
| 42 | * 4: refresh even word (MEM_REFRESH) | |
| 43 | * 5: refresh odd word (MEM_REFRESH | MEM_ODD) | |
| 44 | */ | |
| 45 | int access; | |
| 46 | int error; //!< non-zero after a memory error was detected | |
| 47 | int mear; //!< memory error address register | |
| 48 | UINT16 mesr; //!< memory error status register | |
| 49 | UINT16 mecr; //!< memory error control register | |
| 50 | } m_mem; | |
| 51 | ||
| 52 | /** | |
| 53 | * @brief check if memory address register load is yet possible | |
| 54 | * suspend if accessing RAM and previous MAR<- was less than 5 cycles ago | |
| 55 | * | |
| 56 | * 1. MAR<- ANY | |
| 57 | * 2. REQUIRED | |
| 58 | * 3. MD<- whatever | |
| 59 | * 4. SUSPEND | |
| 60 | * 5. SUSPEND | |
| 61 | * 6. MAR<- ANY | |
| 62 | * | |
| 63 | * @return false, if memory address can be loaded | |
| 64 | */ | |
| 65 | inline bool check_mem_load_mar_stall(UINT8 rsel) { | |
| 66 | if (ALTO2_MEM_NONE == m_mem.access) | |
| 67 | return false; | |
| 68 | return cycle() < m_mem.cycle+5; | |
| 69 | } | |
| 70 | ||
| 71 | /** | |
| 72 | * @brief check if memory read is yet possible | |
| 73 | * MAR<- = cycle #1, earliest read at cycle #5, i.e. + 4 | |
| 74 | * | |
| 75 | * 1. MAR<- ANY | |
| 76 | * 2. REQUIRED | |
| 77 | * 3. SUSPEND | |
| 78 | * 4. SUSPEND | |
| 79 | * 5. whereever <-MD | |
| 80 | * | |
| 81 | * @return false, if memory can be read without wait cycle | |
| 82 | */ | |
| 83 | inline bool check_mem_read_stall() { | |
| 84 | if (ALTO2_MEM_NONE == m_mem.access) | |
| 85 | return false; | |
| 86 | return cycle() < m_mem.cycle+4; | |
| 87 | } | |
| 88 | ||
| 89 | /** | |
| 90 | * @brief check if memory write is yet possible | |
| 91 | * MAR<- = cycle #1, earliest write at cycle #3, i.e. + 2 | |
| 92 | * | |
| 93 | * 1. MAR<- ANY | |
| 94 | * 2. REQUIRED | |
| 95 | * 3. OPTIONAL | |
| 96 | * 4. MD<- whatever | |
| 97 | * | |
| 98 | * @return false, if memory can be written without wait cycle | |
| 99 | */ | |
| 100 | inline bool check_mem_write_stall() { | |
| 101 | if (ALTO2_MEM_NONE == m_mem.access) | |
| 102 | return false; | |
| 103 | return cycle() < m_mem.cycle+2; | |
| 104 | } | |
| 105 | ||
| 106 | //! memory error address register read | |
| 107 | DECLARE_READ16_MEMBER( mear_r ); | |
| 108 | ||
| 109 | //! memory error status register read | |
| 110 | DECLARE_READ16_MEMBER( mesr_r ); | |
| 111 | ||
| 112 | //! memory error status register write (clear) | |
| 113 | DECLARE_WRITE16_MEMBER( mesr_w ); | |
| 114 | ||
| 115 | //! memory error control register read | |
| 116 | DECLARE_READ16_MEMBER( mecr_r ); | |
| 117 | ||
| 118 | //! memory error control register write | |
| 119 | DECLARE_WRITE16_MEMBER( mecr_w ); | |
| 120 | ||
| 121 | //! read or write a memory double-word and caluclate its Hamming code | |
| 122 | UINT32 hamming_code(int write, UINT32 dw_addr, UINT32 dw_data); | |
| 123 | ||
| 124 | //! load the memory address register with some value | |
| 125 | void load_mar(UINT8 rsel, UINT32 addr); | |
| 126 | ||
| 127 | //! read memory or memory mapped I/O from the address in mar to md | |
| 128 | UINT16 read_mem(); | |
| 129 | ||
| 130 | //! write memory or memory mapped I/O from md to the address in mar | |
| 131 | void write_mem(UINT16 data); | |
| 132 | ||
| 133 | //! debugger interface to read memory | |
| 134 | UINT16 debug_read_mem(UINT32 addr); | |
| 135 | ||
| 136 | //! debugger interface to write memory | |
| 137 | void debug_write_mem(UINT32 addr, UINT16 data); | |
| 138 | ||
| 139 | #if ALTO2_DEBUG | |
| 140 | void watch_write(UINT32 addr, UINT32 data); | |
| 141 | void watch_read(UINT32 addr, UINT32 data); | |
| 142 | #endif | |
| 143 | ||
| 144 | void init_memory(); //!< initialize the memory system | |
| 145 | void exit_memory(); //!< deinitialize the memory system | |
| 146 | #endif // _A2MEM_H_ | |
| 147 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII RAM related tasks | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2RAM_H_ | |
| 14 | #define _A2RAM_H_ | |
| 15 | //! BUS source for RAM related tasks | |
| 16 | enum { | |
| 17 | bs_ram_read_slocation= bs_task_3, //!< ram related: read S register | |
| 18 | bs_ram_load_slocation= bs_task_4 //!< ram related: load S register | |
| 19 | }; | |
| 20 | ||
| 21 | //!< F1 functions for RAM related tasks | |
| 22 | enum { | |
| 23 | f1_ram_swmode = f1_task_10, //!< f1 10: switch mode to CROM/CRAM in same page | |
| 24 | f1_ram_wrtram = f1_task_11, //!< f1 11: start WRTRAM cycle | |
| 25 | f1_ram_rdram = f1_task_12, //!< f1 12: start RDRAM cycle | |
| 26 | #if (ALTO2_UCODE_RAM_PAGES == 3) | |
| 27 | f1_ram_load_rmr = f1_task_13, //!< f1 13: load the reset mode register | |
| 28 | #else // ALTO2_UCODE_RAM_PAGES != 3 | |
| 29 | f1_ram_load_srb = f1_task_13 //!< f1 14: load the S register bank from BUS[12-14] | |
| 30 | #endif | |
| 31 | }; | |
| 32 | ||
| 33 | void bs_early_read_sreg(); //!< bus source: drive bus by S register or M (MYL), if rsel is = 0 | |
| 34 | void bs_early_load_sreg(); //!< bus source: load S register puts garbage on the bus | |
| 35 | void bs_late_load_sreg(); //!< bus source: load S register from M | |
| 36 | void branch_ROM(const char *from, int page); //!< branch to ROM page | |
| 37 | void branch_RAM(const char *from, int page); //!< branch to RAM page | |
| 38 | void f1_late_swmode(); //!< F1 func: switch to micro program counter BUS[6-15] in other bank | |
| 39 | void f1_late_wrtram(); //!< F1 func: start WRTRAM cycle | |
| 40 | void f1_late_rdram(); //!< F1 func: start RDRAM cycle | |
| 41 | #if (ALTO2_UCODE_RAM_PAGES == 3) | |
| 42 | void f1_late_load_rmr(); //!< F1 func: load the reset mode register | |
| 43 | #else // ALTO2_UCODE_RAM_PAGES != 3 | |
| 44 | void f1_late_load_srb(); //!< F1 func: load the S register bank from BUS[12-14] | |
| 45 | #endif | |
| 46 | void init_ram(int task); //!< called by RAM related tasks | |
| 47 | void exit_ram(); | |
| 48 | #endif // A2RAM_H | |
| 49 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII disk word task | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII emulator task | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII mouse interface | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII disk word task (KWD) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2KWD_H_ | |
| 14 | #define _A2KWD_H_ | |
| 15 | ||
| 16 | //! BUS source for disk word task | |
| 17 | enum { | |
| 18 | bs_kwd_read_kstat = bs_task_3, //!< bus source: read disk status register | |
| 19 | bs_kwd_read_kdata = bs_task_4 //!< bus source: read disk data register | |
| 20 | }; | |
| 21 | ||
| 22 | //! F1 functions for disk word task | |
| 23 | enum { | |
| 24 | //!< f1 10: undefined | |
| 25 | f1_kwd_strobe = f1_task_11, //!< f1 11: strobe | |
| 26 | f1_kwd_load_kstat = f1_task_12, //!< f1 12: load kstat register | |
| 27 | f1_kwd_increcno = f1_task_13, //!< f1 13: increment record number | |
| 28 | f1_kwd_clrstat = f1_task_14, //!< f1 14: clear status register | |
| 29 | f1_kwd_load_kcom = f1_task_15, //!< f1 15: load kcom register | |
| 30 | f1_kwd_load_kadr = f1_task_16, //!< f1 16: load kadr register | |
| 31 | f1_kwd_load_kdata = f1_task_17, //!< f1 17: load kdata register | |
| 32 | }; | |
| 33 | ||
| 34 | //! F2 functions for disk word task | |
| 35 | enum { | |
| 36 | f2_kwd_init = f2_task_10, //!< f2 10: branches NEXT[5-9] on WDTASKACT && WDINIT | |
| 37 | f2_kwd_rwc = f2_task_11, //!< f2 11: branches NEXT[8-9] on READ/WRITE/CHECK for record | |
| 38 | f2_kwd_recno = f2_task_12, //!< f2 12: branches NEXT[8-9] on RECNO[0-1] | |
| 39 | f2_kwd_xfrdat = f2_task_13, //!< f2 13: branches NEXT[9] on !SEEKONLY | |
| 40 | f2_kwd_swrnrdy = f2_task_14, //!< f2 14: branches NEXT[9] on !SWRDY | |
| 41 | f2_kwd_nfer = f2_task_15, //!< f2 15: branches NEXT[9] on !KFER | |
| 42 | f2_kwd_strobon = f2_task_16, //!< f2 16: branches NEXT[9] on STROBE | |
| 43 | //!< f2 17: undefined | |
| 44 | }; | |
| 45 | ||
| 46 | void f1_early_kwd_block(); //!< F1 func: disable the disk word task | |
| 47 | void init_kwd(int task); //!< initialize disk word task | |
| 48 | void exit_kwd(); //!< deinitialize disk word task | |
| 49 | #endif // _A2KWD_H_ | |
| 50 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII disk interface | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII emulator task (EMU) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2EMU_H_ | |
| 14 | #define _A2EMU_H_ | |
| 15 | ||
| 16 | //! BUS source for emulator task | |
| 17 | enum { | |
| 18 | bs_emu_read_sreg = bs_task_3, //!< bus source: read S register | |
| 19 | bs_emu_load_sreg = bs_task_4 //!< bus source: load S register from BUS | |
| 20 | }; | |
| 21 | ||
| 22 | //! F1 functions for emulator task | |
| 23 | enum { | |
| 24 | f1_emu_swmode = f1_task_10, //!< f1 (1000): switch mode; branch to ROM/RAM microcode | |
| 25 | f1_emu_wrtram = f1_task_11, //!< f1 (1001): write microcode RAM cycle | |
| 26 | f1_emu_rdram = f1_task_12, //!< f1 (1010): read microcode RAM cycle | |
| 27 | f1_emu_load_rmr = f1_task_13, //!< f1 (1011): load reset mode register | |
| 28 | //!< f1 (1100): undefined | |
| 29 | f1_emu_load_esrb = f1_task_15, //!< f1 (1101): load extended S register bank | |
| 30 | f1_emu_rsnf = f1_task_16, //!< f1 (1110): read serial number (Ethernet ID) | |
| 31 | f1_emu_startf = f1_task_17 //!< f1 (1111): start I/O hardware (Ethernet) | |
| 32 | }; | |
| 33 | ||
| 34 | //! F2 functions for emulator task | |
| 35 | enum { | |
| 36 | f2_emu_busodd = f2_task_10, //!< f2 (1000): branch on bus odd | |
| 37 | f2_emu_magic = f2_task_11, //!< f2 (1001): magic shifter (MRSH 1: shifter[15]=T[0], MLSH 1: shifter[015]) | |
| 38 | f2_emu_load_dns = f2_task_12, //!< f2 (1010): do novel shift (RSH 1: shifter[15]=XC, LSH 1: shifer[0]=XC) | |
| 39 | f2_emu_acdest = f2_task_13, //!< f2 (1011): destination accu | |
| 40 | f2_emu_load_ir = f2_task_14, //!< f2 (1100): load instruction register and branch | |
| 41 | f2_emu_idisp = f2_task_15, //!< f2 (1101): load instruction displacement and branch | |
| 42 | f2_emu_acsource = f2_task_16 //!< f2 (1110): source accu | |
| 43 | //!< f2 (1111): undefined | |
| 44 | }; | |
| 45 | ||
| 46 | struct { | |
| 47 | UINT16 ir; //!< emulator instruction register | |
| 48 | UINT8 skip; //!< emulator skip | |
| 49 | UINT8 cy; //!< emulator carry | |
| 50 | } m_emu; | |
| 51 | void bs_early_emu_disp(); //!< bus source: drive bus by IR[8-15], possibly sign extended | |
| 52 | void f1_early_emu_block(); //!< F1 func: block task | |
| 53 | void f1_late_emu_load_rmr(); //!< F1 func: load the reset mode register | |
| 54 | void f1_late_emu_load_esrb(); //!< F1 func: load the extended S register bank from BUS[12-14] | |
| 55 | void f1_early_rsnf(); //!< F1 func: drive the bus from the Ethernet node ID | |
| 56 | void f1_early_startf(); //!< F1 func: defines commands for for I/O hardware, including Ethernet | |
| 57 | void f2_late_busodd(); //!< F2 func: branch on odd bus | |
| 58 | void f2_late_magic(); //!< F2 func: shift and use T | |
| 59 | void f2_early_load_dns(); //!< F2 func: modify RESELECT with DstAC = (3 - IR[3-4]) | |
| 60 | void f2_late_load_dns(); //!< F2 func: do novel shifts | |
| 61 | void f2_early_acdest(); //!< F2 func: modify RSELECT with DstAC = (3 - IR[3-4]) | |
| 62 | void bitblt_info(); //!< debug bitblt opcode | |
| 63 | void f2_late_load_ir(); //!< F2 func: load instruction register IR and branch on IR[0,5-7] | |
| 64 | void f2_late_idisp(); //!< F2 func: branch on: arithmetic IR_SH, others PROM ctl2k_u3[IR[1-7]] | |
| 65 | void f2_early_acsource(); //!< F2 func: modify RSELECT with SrcAC = (3 - IR[1-2]) | |
| 66 | void f2_late_acsource(); //!< F2 func: branch on arithmetic IR_SH, others PROM ctl2k_u3[IR[1-7]] | |
| 67 | void init_emu(int task); //!< 000 initialize emulator task | |
| 68 | void exit_emu(); //!< deinitialize emulator task | |
| 69 | #endif // _A2EMU_H_ | |
| 70 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII mouse hardware (MOUSE) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2MOUSE_H_ | |
| 14 | #define _A2MOUSE_H_ | |
| 15 | /** | |
| 16 | * @brief PROM madr.a32 contains a lookup table to translate mouse motions | |
| 17 | * | |
| 18 | * <PRE> | |
| 19 | * The 4 mouse motion signals MX1, MX2, MY1, and MY2 are connected | |
| 20 | * to a 256x4 PROM's (3601, SN74387) address lines A0, A2, A4, and A6. | |
| 21 | * The previous (latched) state of the 4 signals is connected to the | |
| 22 | * address lines A1, A3, A5, and A7. | |
| 23 | * | |
| 24 | * SN74387 | |
| 25 | * +---+--+---+ | |
| 26 | * | +--+ | | |
| 27 | * MY2 A6 -|1 16|- Vcc | |
| 28 | * | | | |
| 29 | * LMY1 A5 -|2 15|- A7 LMY2 | |
| 30 | * | | | |
| 31 | * MY1 A4 -|3 14|- FE1' 0 | |
| 32 | * | | | |
| 33 | * LMX2 A3 -|4 13|- FE2' 0 | |
| 34 | * | | | |
| 35 | * MX1 A0 -|5 12|- D0 BUS[12] | |
| 36 | * | | | |
| 37 | * LMX1 A1 -|6 11|- D1 BUS[13] | |
| 38 | * | | | |
| 39 | * MX2 A2 -|7 10|- D2 BUS[14] | |
| 40 | * | | | |
| 41 | * GND -|8 9|- D3 BUS[15] | |
| 42 | * | | | |
| 43 | * +----------+ | |
| 44 | * | |
| 45 | * A motion to the west will first toggle MX2, then MX1. | |
| 46 | * sequence: 04 -> 0d -> 0b -> 02 | |
| 47 | * A motion to the east will first toggle MX1, then MX2. | |
| 48 | * sequence: 01 -> 07 -> 0e -> 08 | |
| 49 | * | |
| 50 | * A motion to the north will first toggle MY2, then MY1. | |
| 51 | * sequence: 40 -> d0 -> b0 -> 20 | |
| 52 | * A motion to the south will first toggle MY1, then MY2. | |
| 53 | * sequence: 10 -> 70 -> e0 -> 80 | |
| 54 | * </PRE> | |
| 55 | */ | |
| 56 | UINT8* m_madr_a32; | |
| 57 | ||
| 58 | //! mouse context | |
| 59 | struct { | |
| 60 | int x; //!< current X coordinate | |
| 61 | int y; //!< current Y coordinate | |
| 62 | int dx; //!< destination X coordinate (real mouse X) | |
| 63 | int dy; //!< destination Y coordinate (real mouse Y) | |
| 64 | UINT8 latch; //!< current latch value | |
| 65 | UINT8 phase; //!< current read latch phase | |
| 66 | } m_mouse; | |
| 67 | ||
| 68 | UINT16 mouse_read(); //!< return the mouse motion flags | |
| 69 | void init_mouse(); //!< initialize the mouse context to useful values | |
| 70 | void exit_mouse(); //!< deinitialize the mouse | |
| 71 | #endif // _A2MOUSE_H_ | |
| 72 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII display word task | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
| 28 | 28 | /** |
| 29 | 29 | * @brief f2_load_ddr late: load the display data register |
| 30 | 30 | */ |
| 31 | void alto2_cpu_device::f2_dwt_load_ddr | |
| 31 | void alto2_cpu_device::f2_late_dwt_load_ddr() | |
| 32 | 32 | { |
| 33 | 33 | LOG((LOG_DWT,2," DDR← BUS (%#o)\n", m_bus)); |
| 34 | 34 | m_dsp.fifo[m_dsp.fifo_wr] = m_bus; |
| r26306 | r26307 | |
| 43 | 43 | void alto2_cpu_device::init_dwt(int task) |
| 44 | 44 | { |
| 45 | 45 | set_f1(task, f1_block, &alto2_cpu_device::f1_early_dwt_block, 0); |
| 46 | set_f2(task, f2_dwt_load_ddr, 0, &alto2_cpu_device::f2_dwt_load_ddr | |
| 46 | set_f2(task, f2_dwt_load_ddr, 0, &alto2_cpu_device::f2_late_dwt_load_ddr); | |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | 49 | void alto2_cpu_device::exit_dwt() |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII display interface | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
| 153 | 153 | //! update the internal bitmap to the MAME bitmap.pix16 |
| 154 | 154 | void alto2_cpu_device::update_bitmap_word(int x, int y, UINT16 word) |
| 155 | 155 | { |
| 156 | UINT16* pix = &m_ | |
| 156 | UINT16* pix = &m_bitmap->pix16(y) + x; | |
| 157 | 157 | *pix++ = (word & 0100000) ? BLACK : WHITE; |
| 158 | 158 | *pix++ = (word & 0040000) ? BLACK : WHITE; |
| 159 | 159 | *pix++ = (word & 0020000) ? BLACK : WHITE; |
| r26306 | r26307 | |
| 213 | 213 | void alto2_cpu_device::unload_word() |
| 214 | 214 | { |
| 215 | 215 | int x = m_unload_word; |
| 216 | int y = ((m_dsp.hlc - m_dsp.vblank) & ~(1024|1)) | |
| 216 | int y = ((m_dsp.hlc - m_dsp.vblank) & ~(1024|1)) | HLC1024; | |
| 217 | 217 | UINT16* scanline = m_dsp.scanline[y]; |
| 218 | 218 | |
| 219 | 219 | UINT32 word = m_dsp.inverse; |
| r26306 | r26307 | |
| 451 | 451 | { |
| 452 | 452 | memset(&m_dsp, 0, sizeof(m_dsp)); |
| 453 | 453 | // allocate the 16bpp bitmap |
| 454 | m_displ_bitmap = auto_bitmap_ind16_alloc(machine(), ALTO2_DISPLAY_WIDTH, ALTO2_DISPLAY_HEIGHT); | |
| 455 | LOG((LOG_DISPL,0," m_bitmap=%p\n", m_displ_bitmap)); | |
| 454 | m_bitmap = auto_bitmap_ind16_alloc(machine(), ALTO2_DISPLAY_TOTAL_WIDTH, ALTO2_DISPLAY_TOTAL_HEIGHT); | |
| 455 | LOG((LOG_DISPL,0," m_bitmap=%p\n", m_bitmap)); | |
| 456 | 456 | m_dsp.hlc = ALTO2_DISPLAY_HLC_START; |
| 457 | m_dsp.raw_bitmap = auto_alloc_array(machine(), UINT16, ALTO2_DISPLAY_HEIGHT * ALTO2_DISPLAY_SCANLINE_WORDS); | |
| 458 | m_dsp.scanline = auto_alloc_array(machine(), UINT16*, ALTO2_DISPLAY_HEIGHT); | |
| 459 | for (int y = 0; y < ALTO2_DISPLAY_HEIGHT; y++) { | |
| 457 | m_dsp.raw_bitmap = auto_alloc_array(machine(), UINT16, ALTO2_DISPLAY_TOTAL_HEIGHT * ALTO2_DISPLAY_SCANLINE_WORDS); | |
| 458 | m_dsp.scanline = auto_alloc_array(machine(), UINT16*, ALTO2_DISPLAY_TOTAL_HEIGHT); | |
| 459 | for (int y = 0; y < ALTO2_DISPLAY_TOTAL_HEIGHT; y++) { | |
| 460 | 460 | UINT16* scanline = m_dsp.raw_bitmap + y * ALTO2_DISPLAY_SCANLINE_WORDS; |
| 461 | 461 | m_dsp.scanline[y] = scanline; |
| 462 | 462 | } |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII disk controller block | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2DISK_H_ | |
| 14 | #define _A2DISK_H_ | |
| 15 | ||
| 16 | diablo_hd_device* m_drive[2]; //!< two diablo_hd_device drives | |
| 17 | ||
| 18 | //! disk controller context | |
| 19 | struct { | |
| 20 | UINT8 drive; //!< selected drive from KADDR[14] (written to data out with SENDADR) | |
| 21 | UINT16 kaddr; //!< A[0-15] disk hardware address (sector, cylinder, head, drive, restore) | |
| 22 | UINT16 kadr; //!< C[0-15] with read/write/check modes for header, label and data | |
| 23 | UINT16 kstat; //!< S[0-15] disk status | |
| 24 | UINT16 kcom; //!< disk command (5 bits kcom[1-5]) | |
| 25 | UINT8 krecno; //!< record number (2 bits indexing header, label, data, -/-) | |
| 26 | UINT8 egate; //!< current erase gate signal to the DIABLO hd | |
| 27 | UINT8 wrgate; //!< current write gate signal to the DIABLO hd | |
| 28 | UINT8 rdgate; //!< current read gate signal to the DIABLO hd | |
| 29 | UINT32 shiftin; //!< input shift register | |
| 30 | UINT32 shiftout; //!< output shift register | |
| 31 | UINT32 datain; //!< disk data in latch | |
| 32 | UINT32 dataout; //!< disk data out latch | |
| 33 | UINT8 krwc; //!< read/write/check for current record | |
| 34 | UINT8 kfer; //!< disk fatal error signal state | |
| 35 | UINT8 wdtskena; //!< disk word task enable (active low) | |
| 36 | UINT8 wddone; //!< previous state of WDDONE | |
| 37 | UINT8 wdinit0; //!< disk word task init at the early microcycle | |
| 38 | UINT8 wdinit; //!< disk word task init at the late microcycle | |
| 39 | UINT8 strobe; //!< strobe (still) active | |
| 40 | emu_timer* strobon_timer; //!< set strobe on timer | |
| 41 | UINT8 bitclk; //!< current bitclk state (either crystal clock, or rdclk from the drive) | |
| 42 | #if USE_BITCLK_TIMER | |
| 43 | emu_timer* bitclk_timer; //!< bit clock timer | |
| 44 | #else | |
| 45 | int bitclk_time; //!< time in clocks per bit | |
| 46 | #endif | |
| 47 | UINT8 datin; //!< current datin from the drive | |
| 48 | UINT8 bitcount; //!< bit counter | |
| 49 | UINT8 carry; //!< carry output of the bitcounter | |
| 50 | UINT8 seclate; //!< sector late (monoflop output) | |
| 51 | emu_timer* seclate_timer; //!< sector late timer | |
| 52 | UINT8 seekok; //!< seekok state (SKINC' & LAI' & ff_44a.Q') | |
| 53 | UINT8 ok_to_run; //!< ok to run signal (set to 1 some time after reset) | |
| 54 | emu_timer* ok_to_run_timer; //!< ok to run timer | |
| 55 | UINT8 ready_mf31a; //!< ready monoflop 31a | |
| 56 | emu_timer* ready_timer; //!< ready timer | |
| 57 | UINT8 seclate_mf31b; //!< seclate monoflop 31b | |
| 58 | jkff_t ff_21a; //!< JK flip-flop 21a (sector task) | |
| 59 | jkff_t ff_21a_old; //!< -"- previous state | |
| 60 | jkff_t ff_21b; //!< JK flip-flop 21b (sector task) | |
| 61 | jkff_t ff_22a; //!< JK flip-flop 22a (sector task) | |
| 62 | jkff_t ff_22b; //!< JK flip-flop 22b (sector task) | |
| 63 | jkff_t ff_43b; //!< JK flip-flop 43b (word task) | |
| 64 | jkff_t ff_53a; //!< JK flip-flop 53a (word task) | |
| 65 | jkff_t ff_43a; //!< JK flip-flop 43a (word task) | |
| 66 | jkff_t ff_53b; //!< brief JK flip-flop 53b (word task) | |
| 67 | jkff_t ff_44a; //!< JK flip-flop 44a (LAI' clocked) | |
| 68 | jkff_t ff_44b; //!< JK flip-flop 44b (CKSUM) | |
| 69 | jkff_t ff_45a; //!< JK flip-flop 45a (ready latch) | |
| 70 | jkff_t ff_45b; //!< JK flip-flop 45b (seqerr latch) | |
| 71 | } m_dsk; | |
| 72 | ||
| 73 | jkff_t m_sysclka0[4]; //!< simulate previous sysclka | |
| 74 | jkff_t m_sysclka1[4]; //!< simulate current sysclka | |
| 75 | jkff_t m_sysclkb0[4]; //!< simulate previous sysclkb | |
| 76 | jkff_t m_sysclkb1[4]; //!< simulate current sysclkb | |
| 77 | //! lookup JK flip-flop state change from s0 to s1 | |
| 78 | inline jkff_t update_jkff(UINT8 s0, UINT8 s1); | |
| 79 | ||
| 80 | void kwd_timing(int bitclk, int datin, int block); //!< disk word timing | |
| 81 | TIMER_CALLBACK_MEMBER( disk_seclate ); //!< timer callback to take away the SECLATE pulse (monoflop) | |
| 82 | TIMER_CALLBACK_MEMBER( disk_ok_to_run ); //!< timer callback to take away the OK TO RUN pulse (reset) | |
| 83 | TIMER_CALLBACK_MEMBER( disk_strobon ); //!< timer callback to pulse the STROBE' signal to the drive | |
| 84 | TIMER_CALLBACK_MEMBER( disk_ready_mf31a ); //!< timer callback to change the READY monoflop 31a | |
| 85 | #if USE_BITCLK_TIMER | |
| 86 | TIMER_CALLBACK_MEMBER( disk_bitclk ); //!< callback to update the disk controller with a new bitclk | |
| 87 | #else | |
| 88 | void disk_bitclk(void *ptr, int arg); //!< function to update the disk controller with a new bitclk | |
| 89 | #endif | |
| 90 | void disk_block(int task); //!< called if one of the disk tasks (task_kwd or task_ksec) blocks | |
| 91 | void bs_early_read_kstat(); //!< bus source: bus driven by disk status register KSTAT | |
| 92 | void bs_early_read_kdata(); //!< bus source: bus driven by disk data register KDATA input | |
| 93 | void f1_late_strobe(); //!< F1 func: initiates a disk seek | |
| 94 | void f1_late_load_kstat(); //!< F1 func: load disk status register | |
| 95 | void f1_late_load_kdata(); //!< F1 func: load data out register, or the disk address register | |
| 96 | void f1_late_increcno(); //!< F1 func: advances shift registers holding KADR | |
| 97 | void f1_late_clrstat(); //!< F1 func: reset all error latches | |
| 98 | void f1_late_load_kcom(); //!< F1 func: load the KCOM register from bus | |
| 99 | void f1_late_load_kadr(); //!< F1 func: load the KADR register from bus | |
| 100 | void f2_late_init(); //!< F2 func: branch on disk word task active and init | |
| 101 | void f2_late_rwc(); //!< F2 func: branch on read/write/check state of the current record | |
| 102 | void f2_late_recno(); //!< F2 func: branch on the current record number by a lookup table | |
| 103 | void f2_late_xfrdat(); //!< F2 func: branch on the data transfer state | |
| 104 | void f2_late_swrnrdy(); //!< F2 func: branch on the disk ready signal | |
| 105 | void f2_late_nfer(); //!< f2_nfer late: branch on the disk fatal error condition | |
| 106 | void f2_late_strobon(); //!< f2_strobon late: branch on the seek busy status | |
| 107 | void init_disk(); //!< initialize the disk context | |
| 108 | void exit_disk(); //!< deinitialize the disk context | |
| 109 | #endif // _A2DISK_H_ | |
| 110 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII memory mapped I/O keyboard | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII display word task (DWT) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2DWT_H_ | |
| 14 | #define _A2DWT_H_ | |
| 15 | ||
| 16 | //! F2 functions for display word task | |
| 17 | enum { | |
| 18 | f2_dwt_load_ddr = f2_task_10 //!< f2 10: load display data register | |
| 19 | }; | |
| 20 | ||
| 21 | void f1_early_dwt_block(); //!< F1 func: block the display word task | |
| 22 | void f2_late_dwt_load_ddr(); //!< F2 func: load the display data register | |
| 23 | void init_dwt(int task); //!< 011 initialize display word task | |
| 24 | void exit_dwt(); //!< deinitialize display word task | |
| 25 | #endif // _A2DWT_H_ | |
| 26 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII display block | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | /** | |
| 13 | * @brief start value for the horizontal line counter | |
| 14 | * | |
| 15 | * This value is loaded into the three 4 bit counters (type 9316) | |
| 16 | * with numbers 65, 67, and 75. | |
| 17 | * 65: A=0 B=1 C=1 D=0 | |
| 18 | * 67: A=1 B=0 C=0 D=1 | |
| 19 | * 75: A=0 B=0 C=0 D=0 | |
| 20 | * | |
| 21 | * The value is 150 | |
| 22 | */ | |
| 23 | #define ALTO2_DISPLAY_HLC_START (2+4+16+128) | |
| 24 | ||
| 25 | /** | |
| 26 | * @brief end value for the horizontal line counter | |
| 27 | * | |
| 28 | * This is decoded by H30, an 8 input NAND gate. | |
| 29 | * The value is 1899; horz. line count range 150…1899 = 1750. | |
| 30 | * | |
| 31 | * There are 1750 / 2 = 875 total scanlines. | |
| 32 | */ | |
| 33 | #define ALTO2_DISPLAY_HLC_END (1+2+8+32+64+256+512+1024) | |
| 34 | ||
| 35 | /** | |
| 36 | * @brief display total height, including overscan (vertical blanking and synch) | |
| 37 | * | |
| 38 | * The display is interleaved in two fields, alternatingly drawing the even and odd | |
| 39 | * scanlines to the monitor. The frame rate is 60Hz, which is actually the rate | |
| 40 | * of the half-frames. The rate for full frames is thus 30Hz. | |
| 41 | */ | |
| 42 | #define ALTO2_DISPLAY_TOTAL_HEIGHT ((ALTO2_DISPLAY_HLC_END + 1 - ALTO2_DISPLAY_HLC_START) / 2) | |
| 43 | ||
| 44 | /** | |
| 45 | * @brief display total width, including horizontal blanking | |
| 46 | * | |
| 47 | * Known facts: | |
| 48 | * | |
| 49 | * We have 606x808 visible pixels, and the pixel clock is said to be 50ns | |
| 50 | * (20MHz), while the crystal in the schematics is labeled 20.16 MHz, | |
| 51 | * so the pixel clock would actually be 49.6031ns. | |
| 52 | * | |
| 53 | * The total number of scanlines is, according to the docs, 875. | |
| 54 | * | |
| 55 | * 875 scanlines at 30 frames per second, thus the scanline rate is 26.250 kHz. | |
| 56 | * | |
| 57 | * If I divide 20.16 MHz by 26.250 kHz, I get 768 pixels for the total width | |
| 58 | * of a scanline in pixels. | |
| 59 | * | |
| 60 | * The horizontal blanking period would then be 768 - 606 = 162 pixels, and | |
| 61 | * thus 162 * 49.6031ns ~= 8036ns = 8.036us for the HBLANK time. | |
| 62 | * | |
| 63 | * In the display schematics there is a divide by 24 logic, and when | |
| 64 | * dividing the 768 pixels per scanline by 24, we have 32 phases of a scanline. | |
| 65 | * | |
| 66 | * A S8223 PROM (a63) with 32x8 bits contains the status of the HBLANK and | |
| 67 | * HSYNC signals for these phases, the SCANEND and HLCGATE signals, as well | |
| 68 | * as its own next address A0-A3! | |
| 69 | * | |
| 70 | */ | |
| 71 | #define ALTO2_DISPLAY_TOTAL_WIDTH 768 | |
| 72 | ||
| 73 | ||
| 74 | #define ALTO2_DISPLAY_FIFO 16 //!< the display fifo has 16 words | |
| 75 | #define ALTO2_DISPLAY_SCANLINE_WORDS (ALTO2_DISPLAY_TOTAL_WIDTH/16) //!< words per scanline | |
| 76 | #define ALTO2_DISPLAY_HEIGHT 808 //!< number of visible scanlines per frame; 808 really, but there are some empty lines? | |
| 77 | #define ALTO2_DISPLAY_WIDTH 606 //!< visible width of the display; 38 x 16 bit words - 2 pixels | |
| 78 | #define ALTO2_DISPLAY_VISIBLE_WORDS ((ALTO2_DISPLAY_WIDTH+15)/16) //!< visible words per scanline | |
| 79 | #define ALTO2_DISPLAY_BITCLOCK 20160000ll //!< display bit clock in in Hertz (20.16MHz) | |
| 80 | #define ALTO2_DISPLAY_BITTIME(n) (U64(1000000000000)*(n)/ALTO2_DISPLAY_BITCLOCK) //!< display bit time in in pico seconds (~= 49.6031ns) | |
| 81 | #define ALTO2_DISPLAY_SCANLINE_TIME ALTO2_DISPLAY_BITTIME(ALTO2_DISPLAY_TOTAL_WIDTH)//!< time for a scanline in pico seconds (768 * 49.6031ns ~= 38095.1808ns) | |
| 82 | #define ALTO2_DISPLAY_VISIBLE_TIME ALTO2_DISPLAY_BITTIME(ALTO2_DISPLAY_WIDTH) //!< time of the visible part of a scanline in pico seconds (606 * 49.6031ns ~= 30059.4786ns) | |
| 83 | #define ALTO2_DISPLAY_WORD_TIME ALTO2_DISPLAY_BITTIME(16) //!< time for a word in pico seconds (16 pixels * 49.6031ns ~= 793.6496ns) | |
| 84 | #define ALTO2_DISPLAY_VBLANK_TIME ((ALTO2_DISPLAY_TOTAL_HEIGHT-ALTO2_DISPLAY_HEIGHT)*HZ_TO_ATTOSECONDS(26250)) | |
| 85 | ||
| 86 | #else // ALTO2_DEFINE_CONSTANTS | |
| 87 | /** | |
| 88 | * @brief structure of the display context | |
| 89 | * | |
| 90 | * Schematics of the task clear and wakeup signal generators | |
| 91 | * <PRE> | |
| 92 | * A quote (') appended to a signal name means inverted signal. | |
| 93 | * | |
| 94 | * AND | NAND| NOR | FF | Q N174 | |
| 95 | * -----+--- -----+--- -----+--- -----+--- ----- | |
| 96 | * 0 0 | 0 0 0 | 1 0 0 | 1 S'\0| 1 delay | |
| 97 | * 0 1 | 0 0 1 | 1 0 1 | 0 R'\0| 0 | |
| 98 | * 1 0 | 0 1 0 | 1 1 0 | 0 | |
| 99 | * 1 1 | 1 1 1 | 0 1 1 | 0 | |
| 100 | * | |
| 101 | * | |
| 102 | * DVTAC' | |
| 103 | * >-------· +-----+ | |
| 104 | * | | FF | | |
| 105 | * VBLANK'+----+ DELVBLANK' +---+ DELVBLANK +----+ ·--|S' | | |
| 106 | * >------|N174|------+-----|inv|--------------|NAND| VBLANKPULSE | | WAKEDVT' | |
| 107 | * +----+ | +---+ | o--+-----------|R' Q|----------------------> | |
| 108 | * | ·-| | | | | | |
| 109 | * +----+ | DDELVBLANK' | +----+ | +-----+ | |
| 110 | * ·-|N174|-----------------------------· | +---+ | |
| 111 | * | +----+ | +------oAND| | |
| 112 | * | | DSP07.01 | | o----------· | |
| 113 | * ·-------------· >---------|------o | | | |
| 114 | * | +---+ | | |
| 115 | * | | | |
| 116 | * | +-----+ | | |
| 117 | * | | FF | | +-----+ | |
| 118 | * DHTAC' +---+ | | | | | FF | | |
| 119 | * >--------------oNOR| *07.25 +----+ ·-|S' | DHTBLK' | | | | |
| 120 | * BLOCK' | |---------------|NAND| | Q|--+----------|--|S1' | WAKEDHT' | |
| 121 | * >--------------o | DCSYSCLK | o--------|R' | | >--------|--|S2' Q|---------> | |
| 122 | * +---+ >---------| | +-----+ | DHTAC' ·--|R' | | |
| 123 | * +----+ | +-----+ | |
| 124 | * ·------------· | |
| 125 | * | | |
| 126 | * DWTAC' +---+ | +-----+ | |
| 127 | * >--------------oNOR| *07.26 +----+ | | FF | | |
| 128 | * BLOCK' | |---------|NAND| DSP07.01 | | | | |
| 129 | * >--------------o | DCSYSCLK| o----------|---|S1' | DWTCN' +---+ DWTCN | |
| 130 | * +---+ >-------| | ·---|S2' Q|--------|inv|-----------+---- | |
| 131 | * +----+ ·---|R' | +---+ | | |
| 132 | * | +-----+ | | |
| 133 | * SCANEND +----+ | | | |
| 134 | * >-------------|NAND| CLRBUF' | .----------------------· | |
| 135 | * DCLK | o----------------· | | |
| 136 | * >-------------| | | +-----+ | |
| 137 | * +----+ ·--| NAND| | |
| 138 | * STOPWAKE' | |preWake +----+ WAKEDWT' | |
| 139 | * >-----------| o--------|N174|---------> | |
| 140 | * VBLANK' | | +----+ | |
| 141 | * >-----------| | | |
| 142 | * +-----+ | |
| 143 | * a40c | |
| 144 | * VBLANKPULSE +----+ | |
| 145 | * -------------|NAND| | |
| 146 | * | o--· | |
| 147 | * ·--| | | | |
| 148 | * | +----+ | | |
| 149 | * ·----------|-· | |
| 150 | * ·----------· | | |
| 151 | * CURTAC' +---+ | +----+ | a20d | |
| 152 | * >--------------oNOR| *07.27 +----+ ·--|NAND| | +----+ | |
| 153 | * BLOCK' | |---------|NAND| DSP07.07 | o----+----o NOR| preWK +----+ WAKECURT' | |
| 154 | * >--------------o | DCSYSCLK| o-----------| | | |--------|N174|---------> | |
| 155 | * +---+ >-------| | +----+ +----o | +----+ | |
| 156 | * +----+ a40d | +----+ | |
| 157 | * a30c | | |
| 158 | * CURTAC' +----+ | | |
| 159 | * >------------|NAND| DSP07.03 | | |
| 160 | * | o--+------------· | |
| 161 | * ·--| | | | |
| 162 | * | +----+ | | |
| 163 | * ·----------|-· | |
| 164 | * ·----------· | | |
| 165 | * | +----+ | | |
| 166 | * ·--|NAND| | | |
| 167 | * CLRBUF' | o----· | |
| 168 | * >------------| | | |
| 169 | * +----+ | |
| 170 | * a30d | |
| 171 | * </PRE> | |
| 172 | */ | |
| 173 | ||
| 174 | #ifndef _A2DISP_H_ | |
| 175 | #define _A2DISP_H_ | |
| 176 | struct { | |
| 177 | UINT16 hlc; //!< horizontal line counter | |
| 178 | UINT8 a63; //!< most recent value read from the PROM a63 | |
| 179 | UINT8 a66; //!< most recent value read from the PROM a66 | |
| 180 | UINT16 setmode; //!< value written by last SETMODE<- | |
| 181 | UINT16 inverse; //!< set to 0xffff if line is inverse, 0x0000 otherwise | |
| 182 | UINT8 halfclock; //!< set 0 for normal pixel clock, 1 for half pixel clock | |
| 183 | UINT8 clr; //!< set non-zero if any of VBLANK or HBLANK is active (a39a 74S08) | |
| 184 | UINT16 fifo[ALTO2_DISPLAY_FIFO]; //!< display word fifo | |
| 185 | UINT8 fifo_wr; //!< fifo input pointer (4-bit) | |
| 186 | UINT8 fifo_rd; //!< fifo output pointer (4-bit) | |
| 187 | UINT8 dht_blocks; //!< set non-zero, if the DHT executed BLOCK | |
| 188 | UINT8 dwt_blocks; //!< set non-zero, if the DWT executed BLOCK | |
| 189 | UINT8 curt_blocks; //!< set non-zero, if the CURT executed BLOCK | |
| 190 | UINT8 curt_wakeup; //!< set non-zero, if CURT wakeups are generated | |
| 191 | UINT16 vblank; //!< most recent HLC with VBLANK still high (11-bit) | |
| 192 | UINT16 xpreg; //!< cursor cursor x position register (10-bit) | |
| 193 | UINT16 csr; //!< cursor shift register (16-bit) | |
| 194 | UINT32 curword; //!< helper: first cursor word in current scanline | |
| 195 | UINT32 curdata; //!< helper: shifted cursor data (32-bit) | |
| 196 | UINT16 *raw_bitmap; //!< array of words of the raw bitmap that is displayed | |
| 197 | UINT16 **scanline; //!< array of pointers to the scanlines | |
| 198 | } m_dsp; | |
| 199 | ||
| 200 | /** | |
| 201 | * @brief PROM a38 contains the STOPWAKE' and MBEMBPTY' signals for the FIFO | |
| 202 | * <PRE> | |
| 203 | * The inputs to a38 are the UNLOAD counter RA[0-3] and the DDR<- counter | |
| 204 | * WA[0-3], and the designer decided to reverse the address lines :-) | |
| 205 | * | |
| 206 | * a38 counter FIFO counter | |
| 207 | * -------------------------- | |
| 208 | * A0 RA[0] fifo_rd | |
| 209 | * A1 RA[1] | |
| 210 | * A2 RA[2] | |
| 211 | * A3 RA[3] | |
| 212 | * A4 WA[0] fifo_wr | |
| 213 | * A5 WA[1] | |
| 214 | * A6 WA[2] | |
| 215 | * A7 WA[3] | |
| 216 | * | |
| 217 | * Only two bits of a38 are used: | |
| 218 | * O1 (002) = STOPWAKE' | |
| 219 | * O3 (010) = MBEMPTY' | |
| 220 | * </PRE> | |
| 221 | */ | |
| 222 | UINT8* m_disp_a38; | |
| 223 | ||
| 224 | //! output bits of PROM A38 | |
| 225 | enum { | |
| 226 | A38_STOPWAKE = (1 << 1), | |
| 227 | A38_MBEMPTY = (1 << 3) | |
| 228 | }; | |
| 229 | ||
| 230 | //! PROM a38 bit O1 is STOPWAKE' (stop DWT if bit is zero) | |
| 231 | inline UINT8 FIFO_STOPWAKE_0() { return m_disp_a38[m_dsp.fifo_rd * 16 + m_dsp.fifo_wr] & A38_STOPWAKE; } | |
| 232 | ||
| 233 | //! PROM a38 bit O3 is MBEMPTY' (FIFO is empty if bit is zero) | |
| 234 | inline UINT8 FIFO_MBEMPTY_0() { return m_disp_a38[m_dsp.fifo_rd * 16 + m_dsp.fifo_wr] & A38_MBEMPTY; } | |
| 235 | ||
| 236 | /** | |
| 237 | * @brief emulation of PROM a63 in the display schematics page 8 | |
| 238 | * <PRE> | |
| 239 | * The PROM's address lines are driven by a clock CLK, which is | |
| 240 | * pixel clock / 24, and an inverted half-scanline signal H[1]'. | |
| 241 | * | |
| 242 | * It is 32x8 bits and its output bits (B) are connected to the | |
| 243 | * signals, as well as its own address lines (A) through a latch | |
| 244 | * of the type SN74774 like this: | |
| 245 | * | |
| 246 | * B 174 A others | |
| 247 | * ------------------------ | |
| 248 | * 0 5 - HBLANK | |
| 249 | * 1 0 - HSYNC | |
| 250 | * 2 4 0 | |
| 251 | * 3 1 1 | |
| 252 | * 4 3 2 | |
| 253 | * 5 2 3 | |
| 254 | * 6 - - SCANEND | |
| 255 | * 7 - - HLCGATE | |
| 256 | * ------------------------ | |
| 257 | * H[1]' - 4 | |
| 258 | * | |
| 259 | * The display_state_machine() is called by the CPU at a rate of pixelclock/24, | |
| 260 | * which happens to be very close to every 7th CPU micrcocycle. | |
| 261 | * </PRE> | |
| 262 | */ | |
| 263 | UINT8* m_disp_a63; | |
| 264 | ||
| 265 | enum { | |
| 266 | A63_HBLANK = (1 << 0), //!< PROM a63 B0 is latched as HBLANK signal | |
| 267 | A63_HSYNC = (1 << 1), //!< PROM a63 B1 is latched as HSYNC signal | |
| 268 | A63_A0 = (1 << 2), //!< PROM a63 B2 is the latched next address bit A0 | |
| 269 | A63_A1 = (1 << 3), //!< PROM a63 B3 is the latched next address bit A1 | |
| 270 | A63_A2 = (1 << 4), //!< PROM a63 B4 is the latched next address bit A2 | |
| 271 | A63_A3 = (1 << 5), //!< PROM a63 B5 is the latched next address bit A3 | |
| 272 | A63_SCANEND = (1 << 6), //!< PROM a63 B6 SCANEND signal, which resets the FIFO counters | |
| 273 | A63_HLCGATE = (1 << 7) //!< PROM a63 B7 HLCGATE signal, which enables counting the HLC | |
| 274 | }; | |
| 275 | ||
| 276 | /** | |
| 277 | * @brief vertical blank and synch PROM | |
| 278 | * | |
| 279 | * PROM a66 is a 256x4 bit (type 3601), containing the vertical blank + synch. | |
| 280 | * Address lines are driven by H[1] to H[128] of the the horz. line counters. | |
| 281 | * The PROM is enabled whenever H[256] and H[512] are both 0. | |
| 282 | * | |
| 283 | * Q1 (001) is VSYNC for the odd field (with H1024=1) | |
| 284 | * Q2 (002) is VSYNC for the even field (with H1024=0) | |
| 285 | * Q3 (004) is VBLANK for the odd field (with H1024=1) | |
| 286 | * Q4 (010) is VBLANK for the even field (with H1024=0) | |
| 287 | */ | |
| 288 | UINT8* m_disp_a66; | |
| 289 | ||
| 290 | enum { | |
| 291 | A66_VSYNC_ODD = (1 << 0), | |
| 292 | A66_VSYNC_EVEN = (1 << 1), | |
| 293 | A66_VBLANK_ODD = (1 << 2), | |
| 294 | A66_VBLANK_EVEN = (1 << 3) | |
| 295 | }; | |
| 296 | ||
| 297 | //! test the VSYNC (vertical synchronisation) signal in PROM a66 being high | |
| 298 | static inline bool A66_VSYNC_HI(UINT8 a, int hlc1024) { return a & (hlc1024 ? A66_VSYNC_ODD : A66_VSYNC_EVEN) ? false : true; } | |
| 299 | //! test the VSYNC (vertical synchronisation) signal in PROM a66 being low | |
| 300 | static inline bool A66_VSYNC_LO(UINT8 a, int hlc1024) { return a & (hlc1024 ? A66_VSYNC_ODD : A66_VSYNC_EVEN) ? true : false; } | |
| 301 | //! test the VBLANK (vertical blanking) signal in PROM a66 being high | |
| 302 | static inline bool A66_VBLANK_HI(UINT8 a, int hlc1024) { return a & (hlc1024 ? A66_VBLANK_ODD : A66_VBLANK_EVEN) ? false : true; } | |
| 303 | //! test the VBLANK (vertical blanking) signal in PROM a66 being low | |
| 304 | static inline bool A66_VBLANK_LO(UINT8 a, int hlc1024) { return a & (hlc1024 ? A66_VBLANK_ODD : A66_VBLANK_EVEN) ? true : false; } | |
| 305 | ||
| 306 | bitmap_ind16* m_bitmap; //!< screen bitmap | |
| 307 | ||
| 308 | void update_bitmap_word(int x, int y, UINT16 word); //!< update a word in the screen bitmap | |
| 309 | void unload_word(); //!< unload the next word from the display FIFO and shift it to the screen | |
| 310 | void display_state_machine(); //!< function called by the CPU to enter the next display state | |
| 311 | ||
| 312 | void f2_late_evenfield(void); //!< branch on the evenfield flip-flop | |
| 313 | ||
| 314 | void init_disp(); //!< initialize the display context | |
| 315 | void exit_disp(); //!< deinitialize the display context | |
| 316 | #endif // _A2DISP_H_ | |
| 317 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII keyboard hardware (KBD) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | //! make an Xerox AltoII key bit mask | |
| 13 | #define MAKE_KEY(a,b) (1 << (b)) | |
| 14 | ||
| 15 | #define A2_KEY_5 MAKE_KEY(0,017) //!< normal: 5 shifted: % | |
| 16 | #define A2_KEY_4 MAKE_KEY(0,016) //!< normal: 4 shifted: $ | |
| 17 | #define A2_KEY_6 MAKE_KEY(0,015) //!< normal: 6 shifted: ~ | |
| 18 | #define A2_KEY_E MAKE_KEY(0,014) //!< normal: e shifted: E | |
| 19 | #define A2_KEY_7 MAKE_KEY(0,013) //!< normal: 7 shifted: & | |
| 20 | #define A2_KEY_D MAKE_KEY(0,012) //!< normal: d shifted: D | |
| 21 | #define A2_KEY_U MAKE_KEY(0,011) //!< normal: u shifted: U | |
| 22 | #define A2_KEY_V MAKE_KEY(0,010) //!< normal: v shifted: V | |
| 23 | #define A2_KEY_0 MAKE_KEY(0,007) //!< normal: 0 shifted: ) | |
| 24 | #define A2_KEY_K MAKE_KEY(0,006) //!< normal: k shifted: K | |
| 25 | #define A2_KEY_MINUS MAKE_KEY(0,005) //!< normal: - shifted: _ | |
| 26 | #define A2_KEY_P MAKE_KEY(0,004) //!< normal: p shifted: P | |
| 27 | #define A2_KEY_SLASH MAKE_KEY(0,003) //!< normal: / shifted: ? | |
| 28 | #define A2_KEY_BACKSLASH MAKE_KEY(0,002) //!< normal: \ shifted: | | |
| 29 | #define A2_KEY_LF MAKE_KEY(0,001) //!< normal: LF | |
| 30 | #define A2_KEY_BS MAKE_KEY(0,000) //!< normal: BS | |
| 31 | ||
| 32 | #define A2_KEY_3 MAKE_KEY(1,017) //!< normal: 3 shifted: # | |
| 33 | #define A2_KEY_2 MAKE_KEY(1,016) //!< normal: 2 shifted: @ | |
| 34 | #define A2_KEY_W MAKE_KEY(1,015) //!< normal: w shifted: W | |
| 35 | #define A2_KEY_Q MAKE_KEY(1,014) //!< normal: q shifted: Q | |
| 36 | #define A2_KEY_S MAKE_KEY(1,013) //!< normal: s shifted: S | |
| 37 | #define A2_KEY_A MAKE_KEY(1,012) //!< normal: a shifted: A | |
| 38 | #define A2_KEY_9 MAKE_KEY(1,011) //!< normal: 9 shifted: ( | |
| 39 | #define A2_KEY_I MAKE_KEY(1,010) //!< normal: i shifted: I | |
| 40 | #define A2_KEY_X MAKE_KEY(1,007) //!< normal: x shifted: X | |
| 41 | #define A2_KEY_O MAKE_KEY(1,006) //!< normal: o shifted: O | |
| 42 | #define A2_KEY_L MAKE_KEY(1,005) //!< normal: l shifted: L | |
| 43 | #define A2_KEY_COMMA MAKE_KEY(1,004) //!< normal: , shifted: < | |
| 44 | #define A2_KEY_QUOTE MAKE_KEY(1,003) //!< normal: ' shifted: " | |
| 45 | #define A2_KEY_RBRACKET MAKE_KEY(1,002) //!< normal: ] shifted: } | |
| 46 | #define A2_KEY_BLANK_MID MAKE_KEY(1,001) //!< middle blank key | |
| 47 | #define A2_KEY_BLANK_TOP MAKE_KEY(1,000) //!< top blank key | |
| 48 | ||
| 49 | #define A2_KEY_1 MAKE_KEY(2,017) //!< normal: 1 shifted: ! | |
| 50 | #define A2_KEY_ESCAPE MAKE_KEY(2,016) //!< normal: ESC shifted: ? | |
| 51 | #define A2_KEY_TAB MAKE_KEY(2,015) //!< normal: TAB shifted: ? | |
| 52 | #define A2_KEY_F MAKE_KEY(2,014) //!< normal: f shifted: F | |
| 53 | #define A2_KEY_CTRL MAKE_KEY(2,013) //!< CTRL | |
| 54 | #define A2_KEY_C MAKE_KEY(2,012) //!< normal: c shifted: C | |
| 55 | #define A2_KEY_J MAKE_KEY(2,011) //!< normal: j shifted: J | |
| 56 | #define A2_KEY_B MAKE_KEY(2,010) //!< normal: b shifted: B | |
| 57 | #define A2_KEY_Z MAKE_KEY(2,007) //!< normal: z shifted: Z | |
| 58 | #define A2_KEY_LSHIFT MAKE_KEY(2,006) //!< LSHIFT | |
| 59 | #define A2_KEY_PERIOD MAKE_KEY(2,005) //!< normal: . shifted: > | |
| 60 | #define A2_KEY_SEMICOLON MAKE_KEY(2,004) //!< normal: ; shifted: : | |
| 61 | #define A2_KEY_RETURN MAKE_KEY(2,003) //!< RETURN | |
| 62 | #define A2_KEY_LEFTARROW MAKE_KEY(2,002) //!< normal: ← shifted: ↑ (caret?) | |
| 63 | #define A2_KEY_DEL MAKE_KEY(2,001) //!< normal: DEL | |
| 64 | #define A2_KEY_MSW_2_17 MAKE_KEY(2,000) //!< unused on Microswitch KDB | |
| 65 | ||
| 66 | #define A2_KEY_R MAKE_KEY(3,017) //!< normal: r shifted: R | |
| 67 | #define A2_KEY_T MAKE_KEY(3,016) //!< normal: t shifted: T | |
| 68 | #define A2_KEY_G MAKE_KEY(3,015) //!< normal: g shifted: G | |
| 69 | #define A2_KEY_Y MAKE_KEY(3,014) //!< normal: y shifted: Y | |
| 70 | #define A2_KEY_H MAKE_KEY(3,013) //!< normal: h shifted: H | |
| 71 | #define A2_KEY_8 MAKE_KEY(3,012) //!< normal: 8 shifted: * | |
| 72 | #define A2_KEY_N MAKE_KEY(3,011) //!< normal: n shifted: N | |
| 73 | #define A2_KEY_M MAKE_KEY(3,010) //!< normal: m shifted: M | |
| 74 | #define A2_KEY_LOCK MAKE_KEY(3,007) //!< LOCK | |
| 75 | #define A2_KEY_SPACE MAKE_KEY(3,006) //!< SPACE | |
| 76 | #define A2_KEY_LBRACKET MAKE_KEY(3,005) //!< normal: [ shifted: { | |
| 77 | #define A2_KEY_EQUALS MAKE_KEY(3,004) //!< normal: = shifted: + | |
| 78 | #define A2_KEY_RSHIFT MAKE_KEY(3,003) //!< RSHIFT | |
| 79 | #define A2_KEY_BLANK_BOT MAKE_KEY(3,002) //!< bottom blank key | |
| 80 | #define A2_KEY_MSW_3_16 MAKE_KEY(3,001) //!< unused on Microswitch KDB | |
| 81 | #define A2_KEY_MSW_3_17 MAKE_KEY(3,000) //!< unused on Microswitch KDB | |
| 82 | ||
| 83 | #define A2_KEY_FR2 MAKE_KEY(0,002) //!< ADL right function key 2 | |
| 84 | #define A2_KEY_FL2 MAKE_KEY(0,001) //!< ADL left function key 1 | |
| 85 | ||
| 86 | #define A2_KEY_FR4 MAKE_KEY(1,001) //!< ADL right funtion key 4 | |
| 87 | #define A2_KEY_BW MAKE_KEY(1,000) //!< ADL BW (?) | |
| 88 | ||
| 89 | #define A2_KEY_FR3 MAKE_KEY(2,002) //!< ADL right function key 3 | |
| 90 | #define A2_KEY_FL1 MAKE_KEY(2,001) //!< ADL left function key 1 | |
| 91 | #define A2_KEY_FL3 MAKE_KEY(2,000) //!< ADL left function key 3 | |
| 92 | ||
| 93 | #define A2_KEY_FR1 MAKE_KEY(3,002) //!< ADL right function key 4 | |
| 94 | #define A2_KEY_FL4 MAKE_KEY(3,001) //!< ADL left function key 4 | |
| 95 | #define A2_KEY_FR5 MAKE_KEY(3,000) //!< ADL right function key 5 | |
| 96 | ||
| 97 | #else // ALTO2_DEFINE_CONSTANTS | |
| 98 | #ifndef _A2KBD_H_ | |
| 99 | #define _A2KBD_H_ | |
| 100 | struct { | |
| 101 | UINT16 bootkey; //!< boot key - key code pressed before power on | |
| 102 | UINT16 matrix[4]; //!< a bit map of the keys pressed (ioports ROW0 ... ROW3) | |
| 103 | } m_kbd; | |
| 104 | ||
| 105 | DECLARE_READ16_MEMBER( kbd_ad_r ); //!< read the keyboard matrix | |
| 106 | ||
| 107 | void init_kbd(UINT16 bootkey = 0177777); //!< initialize the keyboard hardware, optinally set the boot key | |
| 108 | void exit_kbd(); //!< deinitialize the keyboard hardware | |
| 109 | #endif // _A2KBD_H_ | |
| 110 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII CPU core | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
| 158 | 158 | m_disp_a38(0), |
| 159 | 159 | m_disp_a63(0), |
| 160 | 160 | m_disp_a66(0), |
| 161 | m_ | |
| 161 | m_bitmap(0), | |
| 162 | 162 | m_mem(), |
| 163 | 163 | m_emu(), |
| 164 | 164 | m_ether_a41(0), |
| r26306 | r26307 | |
| 250 | 250 | } |
| 251 | 251 | |
| 252 | 252 | //------------------------------------------------- |
| 253 | // driver interface to get the internal bitmap | |
| 254 | //------------------------------------------------- | |
| 255 | ||
| 256 | bitmap_ind16*alto2_cpu_device::bitmap() | |
| 257 | { | |
| 258 | return m_bitmap; | |
| 259 | } | |
| 260 | ||
| 261 | //------------------------------------------------- | |
| 253 | 262 | // device_rom_region - device-specific (P)ROMs |
| 254 | 263 | //------------------------------------------------- |
| 255 | 264 | |
| r26306 | r26307 | |
| 2365 | 2374 | * </PRE> |
| 2366 | 2375 | */ |
| 2367 | 2376 | |
| 2368 | enum { | |
| 2369 | A10_UNUSED = (1 << 0), | |
| 2370 | A10_TSELECT = (1 << 1), | |
| 2371 | A10_ALUCI = (1 << 2), | |
| 2372 | A10_ALUM = (1 << 3), | |
| 2373 | A10_ALUS0 = (1 << 4), | |
| 2374 | A10_ALUS1 = (1 << 5), | |
| 2375 | A10_ALUS2 = (1 << 6), | |
| 2376 | A10_ALUS3 = (1 << 7), | |
| 2377 | A10_ALUIN = (A10_ALUM|A10_ALUCI|A10_ALUS0|A10_ALUS1|A10_ALUS2|A10_ALUS3) | |
| 2378 | }; | |
| 2379 | ||
| 2380 | 2377 | //! S function, M flag and C carry in |
| 2381 | 2378 | #define SMC(s3,s2,s1,s0,m,ci) (s3*A10_ALUS3 + s2*A10_ALUS2 + s1*A10_ALUS1 + s0*A10_ALUS0 + m*A10_ALUM + ci*A10_ALUCI) |
| 2382 | 2379 | |
| r26306 | r26307 | |
| 2757 | 2754 | #else |
| 2758 | 2755 | UINT32 alu; |
| 2759 | 2756 | /* compute the ALU function */ |
| 2760 | switch (aluf) { | |
| 2757 | switch (m_d_aluf) { | |
| 2761 | 2758 | /** |
| 2762 | 2759 | * 00: ALU ← BUS |
| 2763 | 2760 | * PROM data for S3-0:1111 M:1 C:0 T:0 |
| r26306 | r26307 | |
| 3119 | 3116 | init_part(task_part); |
| 3120 | 3117 | init_kwd(task_kwd); |
| 3121 | 3118 | |
| 3122 | m_dsp_time = 0; // reset the display state machine values | |
| 3123 | m_dsp_state = 020; | |
| 3119 | m_dsp_time = 0; // reset the display state timing | |
| 3120 | m_dsp_state = 020; // initial state | |
| 3124 | 3121 | |
| 3125 | m_task = 0; // start with task 0 | |
| 3126 | m_task_wakeup |= 1 << 0; // set wakeup flag | |
| 3122 | m_task = task_emu; // start with task 0 (emulator) | |
| 3123 | m_task_wakeup |= 1 << task_emu; // set wakeup flag | |
| 3127 | 3124 | } |
| 3128 | 3125 | |
| 3129 | 3126 | /** @brief software initiated reset (STARTF) */ |
| r26306 | r26307 | |
| 3136 | 3133 | if (0 == (m_reset_mode & (1 << task))) |
| 3137 | 3134 | m_task_mpc[task] |= ALTO2_UCODE_RAM_BASE; |
| 3138 | 3135 | } |
| 3139 | m_next2_task = 0; // switch to task 0 | |
| 3140 | m_reset_mode = 0xffff; // all tasks start in ROM0 again | |
| 3136 | m_next2_task = task_emu; // switch to task 0 (emulator) | |
| 3137 | m_reset_mode = 0xffff; // all tasks start in ROM0 again | |
| 3141 | 3138 | |
| 3142 | m_dsp_time = 0; // reset the display state machine values | |
| 3143 | m_dsp_state = 020; | |
| 3139 | m_dsp_time = 0; // reset the display state timing | |
| 3140 | m_dsp_state = 020; // initial state | |
| 3144 | 3141 | |
| 3145 | return m_next_task; // return next task (?) | |
| 3142 | return m_next_task; // return next task (?) | |
| 3146 | 3143 | } |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII ethernet task | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII CPU core interface | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| 9 | 9 | *****************************************************************************/ |
| 10 | #include "emu.h" | |
| 11 | #include "debugger.h" | |
| 12 | ||
| 13 | #pragma once | |
| 14 | ||
| 15 | 10 | #ifndef _CPU_ALTO2_H_ |
| 16 | 11 | #define _CPU_ALTO2_H |
| 17 | 12 | |
| 18 | #include "machine/diablo_hd.h" | |
| 19 | ||
| 20 | 13 | #define ALTO2_TAG "alto2" |
| 21 | 14 | |
| 15 | #include "emu.h" | |
| 16 | #include "debugger.h" | |
| 17 | #include "machine/diablo_hd.h" | |
| 18 | ||
| 22 | 19 | /** |
| 23 | 20 | * \brief AltoII register names |
| 24 | 21 | */ |
| r26306 | r26307 | |
| 46 | 43 | }; |
| 47 | 44 | |
| 48 | 45 | #ifndef ALTO2_DEBUG |
| 49 | #define ALTO2_DEBUG 0 | |
| 46 | #define ALTO2_DEBUG 0 //!< define to 1 to enable logerror() output | |
| 50 | 47 | #endif |
| 51 | 48 | |
| 52 | #define USE_PRIO_F9318 0 //!< define to 1 to use the F9318 priority encoder code | |
| 53 | #define USE_ALU_74181 1 //!< define to 1 to use the SN74181 ALU code | |
| 54 | #define DEBUG_DISPLAY_TIMING 0 //!< define to 1 to debug the display timing | |
| 55 | #define USE_BITCLK_TIMER 0 //!< define to 1 to use a very high rate timer for the disk bit clock | |
| 56 | #define ALTO2_HAMMING_CHECK 0 //!< define to 1 to incorporate the Hamming code and Parity check | |
| 49 | #define USE_PRIO_F9318 0 //!< define to 1 to use the F9318 priority encoder code | |
| 50 | #define USE_ALU_74181 0 //!< define to 1 to use the SN74181 ALU code | |
| 51 | #define DEBUG_DISPLAY_TIMING 0 //!< define to 1 to debug the display timing | |
| 52 | #define USE_BITCLK_TIMER 0 //!< define to 1 to use a very high rate timer for the disk bit clock | |
| 53 | #define ALTO2_HAMMING_CHECK 0 //!< define to 1 to incorporate the Hamming code and Parity check | |
| 57 | 54 | |
| 58 | #define ALTO2_TASKS 16 //!< 16 task slots | |
| 59 | #define ALTO2_REGS 32 //!< 32 16-bit words in the R register file | |
| 60 | #define ALTO2_ALUF 16 //!< 16 ALU functions (74181) | |
| 61 | #define ALTO2_BUSSRC 8 //!< 8 bus sources | |
| 62 | #define ALTO2_F1MAX 16 //!< 16 F1 functions | |
| 63 | #define ALTO2_F2MAX 16 //!< 16 F2 functions | |
| 64 | #define ALTO2_UCYCLE 169542 //!< time in pico seconds for a CPU micro cycle: 29.4912MHz/5 -> 5.898240Hz ~= 169.542ns/clock | |
| 55 | #define ALTO2_TASKS 16 //!< 16 task slots | |
| 56 | #define ALTO2_REGS 32 //!< 32 16-bit words in the R register file | |
| 57 | #define ALTO2_ALUF 16 //!< 16 ALU functions (74181) | |
| 58 | #define ALTO2_BUSSRC 8 //!< 8 bus sources | |
| 59 | #define ALTO2_F1MAX 16 //!< 16 F1 functions | |
| 60 | #define ALTO2_F2MAX 16 //!< 16 F2 functions | |
| 61 | #define ALTO2_UCYCLE 169542 //!< time in pico seconds for a CPU micro cycle: 29.4912MHz/5 -> 5.898240Hz ~= 169.542ns/clock | |
| 65 | 62 | |
| 66 | #define ALTO2_ETHER_FIFO_SIZE 16 | |
| 67 | ||
| 68 | 63 | #ifndef ALTO2_CRAM_CONFIG |
| 69 | #define ALTO2_CRAM_CONFIG 2 | |
| 64 | #define ALTO2_CRAM_CONFIG 2 //!< use default configuration 2 | |
| 70 | 65 | #endif |
| 71 | 66 | |
| 72 | 67 | #if (ALTO2_CRAM_CONFIG==1) |
| 73 | #define ALTO2_UCODE_ROM_PAGES 1 //!< number of microcode ROM pages | |
| 74 | #define ALTO2_UCODE_RAM_PAGES 1 //!< number of microcode RAM pages | |
| 68 | #define ALTO2_UCODE_ROM_PAGES 1 //!< number of microcode ROM pages | |
| 69 | #define ALTO2_UCODE_RAM_PAGES 1 //!< number of microcode RAM pages | |
| 75 | 70 | #elif (ALTO2_CRAM_CONFIG==2) |
| 76 | #define ALTO2_UCODE_ROM_PAGES 2 //!< number of microcode ROM pages | |
| 77 | #define ALTO2_UCODE_RAM_PAGES 1 //!< number of microcode RAM pages | |
| 71 | #define ALTO2_UCODE_ROM_PAGES 2 //!< number of microcode ROM pages | |
| 72 | #define ALTO2_UCODE_RAM_PAGES 1 //!< number of microcode RAM pages | |
| 78 | 73 | #elif (ALTO2_CRAM_CONFIG==3) |
| 79 | #define ALTO2_UCODE_ROM_PAGES 1 //!< number of microcode ROM pages | |
| 80 | #define ALTO2_UCODE_RAM_PAGES 3 //!< number of microcode RAM pages | |
| 74 | #define ALTO2_UCODE_ROM_PAGES 1 //!< number of microcode ROM pages | |
| 75 | #define ALTO2_UCODE_RAM_PAGES 3 //!< number of microcode RAM pages | |
| 81 | 76 | #else |
| 82 | 77 | #error "Undefined CROM/CRAM configuration" |
| 83 | 78 | #endif |
| r26306 | r26307 | |
| 99 | 94 | #define ALTO2_UCODE_SIZE ((ALTO2_UCODE_ROM_PAGES + ALTO2_UCODE_RAM_PAGES) * ALTO2_UCODE_PAGE_SIZE) //!< total number of words of microcode |
| 100 | 95 | #define ALTO2_UCODE_RAM_BASE (ALTO2_UCODE_ROM_PAGES * ALTO2_UCODE_PAGE_SIZE) //!< base offset for the RAM page(s) |
| 101 | 96 | #define ALTO2_CONST_SIZE 256 //!< number words in the constant ROM |
| 102 | #define ALTO2_RAM_SIZE 0200000 //!< size of main memory in words | |
| 103 | #define ALTO2_IO_PAGE_BASE 0177000 //!< base address of the memory mapped io range | |
| 104 | #define ALTO2_IO_PAGE_SIZE 01000 //!< size of the memory mapped io range | |
| 105 | 97 | |
| 106 | 98 | //! inverted bits in the micro instruction 32 bit word |
| 107 | 99 | #define ALTO2_UCODE_INVERTED ((1 << 10) | (1 << 15) | (1 << 19)) |
| r26306 | r26307 | |
| 133 | 125 | reg = ((reg) & ~mask) | (((val) << X_BITSHIFT(width,to)) & mask); \ |
| 134 | 126 | } while (0) |
| 135 | 127 | |
| 136 | /** | |
| 137 | * @brief start value for the horizontal line counter | |
| 138 | * | |
| 139 | * This value is loaded into the three 4 bit counters (type 9316) | |
| 140 | * with numbers 65, 67, and 75. | |
| 141 | * 65: A=0 B=1 C=1 D=0 | |
| 142 | * 67: A=1 B=0 C=0 D=1 | |
| 143 | * 75: A=0 B=0 C=0 D=0 | |
| 144 | * | |
| 145 | * The value is 150 | |
| 146 | */ | |
| 147 | #define ALTO2_DISPLAY_HLC_START (2+4+16+128) | |
| 128 | //******************************************* | |
| 129 | // define constants from the sub-devices | |
| 130 | //******************************************* | |
| 131 | #define ALTO2_DEFINE_CONSTANTS 1 | |
| 132 | #include "a2ram.h" | |
| 133 | #include "a2hw.h" | |
| 134 | #include "a2kbd.h" | |
| 135 | #include "a2mouse.h" | |
| 136 | #include "a2disk.h" | |
| 137 | #include "a2disp.h" | |
| 138 | #include "a2mem.h" | |
| 139 | #include "a2emu.h" | |
| 140 | #include "a2ksec.h" | |
| 141 | #include "a2ether.h" | |
| 142 | #include "a2mrt.h" | |
| 143 | #include "a2dwt.h" | |
| 144 | #include "a2curt.h" | |
| 145 | #include "a2dht.h" | |
| 146 | #include "a2dvt.h" | |
| 147 | #include "a2part.h" | |
| 148 | #include "a2dwt.h" | |
| 149 | #include "a2kwd.h" | |
| 150 | #undef ALTO2_DEFINE_CONSTANTS | |
| 148 | 151 | |
| 149 | /** | |
| 150 | * @brief end value for the horizontal line counter | |
| 151 | * | |
| 152 | * This is decoded by H30, an 8 input NAND gate. | |
| 153 | * The value is 1899; horz. line count range 150…1899 = 1750. | |
| 154 | * | |
| 155 | * There are 1750 / 2 = 875 total scanlines. | |
| 156 | */ | |
| 157 | #define ALTO2_DISPLAY_HLC_END (1+2+8+32+64+256+512+1024) | |
| 152 | #include "a2jkff.h" | |
| 158 | 153 | |
| 159 | /** | |
| 160 | * @brief display total height, including overscan (vertical blanking and synch) | |
| 161 | * | |
| 162 | * The display is interleaved in two fields, alternatingly drawing the even and odd | |
| 163 | * scanlines to the monitor. The frame rate is 60Hz, which is actually the rate | |
| 164 | * of the half-frames. The rate for full frames is thus 30Hz. | |
| 165 | */ | |
| 166 | #define ALTO2_DISPLAY_TOTAL_HEIGHT ((ALTO2_DISPLAY_HLC_END + 1 - ALTO2_DISPLAY_HLC_START) / 2) | |
| 167 | ||
| 168 | /** | |
| 169 | * @brief display total width, including horizontal blanking | |
| 170 | * | |
| 171 | * Known facts: | |
| 172 | * | |
| 173 | * We have 606x808 visible pixels, and the pixel clock is said to be 50ns | |
| 174 | * (20MHz), while the crystal in the schematics is labeled 20.16 MHz, | |
| 175 | * so the pixel clock would actually be 49.6031ns. | |
| 176 | * | |
| 177 | * The total number of scanlines is, according to the docs, 875. | |
| 178 | * | |
| 179 | * 875 scanlines at 30 frames per second, thus the scanline rate is 26.250 kHz. | |
| 180 | * | |
| 181 | * If I divide 20.16 MHz by 26.250 kHz, I get 768 pixels for the total width | |
| 182 | * of a scanline in pixels. | |
| 183 | * | |
| 184 | * The horizontal blanking period would then be 768 - 606 = 162 pixels, and | |
| 185 | * thus 162 * 49.6031ns ~= 8036ns = 8.036us for the HBLANK time. | |
| 186 | * | |
| 187 | * In the display schematics there is a divide by 24 logic, and when | |
| 188 | * dividing the 768 pixels per scanline by 24, we have 32 phases of a scanline. | |
| 189 | * | |
| 190 | * A S8223 PROM (a63) with 32x8 bits contains the status of the HBLANK and | |
| 191 | * HSYNC signals for these phases, the SCANEND and HLCGATE signals, as well | |
| 192 | * as its own next address A0-A3! | |
| 193 | * | |
| 194 | */ | |
| 195 | #define ALTO2_DISPLAY_TOTAL_WIDTH 768 | |
| 196 | ||
| 197 | ||
| 198 | #define ALTO2_DISPLAY_FIFO 16 //!< the display fifo has 16 words | |
| 199 | #define ALTO2_DISPLAY_SCANLINE_WORDS (ALTO2_DISPLAY_TOTAL_WIDTH/16) //!< words per scanline | |
| 200 | #define ALTO2_DISPLAY_HEIGHT 808 //!< number of visible scanlines per frame; 808 really, but there are some empty lines? | |
| 201 | #define ALTO2_DISPLAY_WIDTH 606 //!< visible width of the display; 38 x 16 bit words - 2 pixels | |
| 202 | #define ALTO2_DISPLAY_VISIBLE_WORDS ((ALTO2_DISPLAY_WIDTH+15)/16) //!< visible words per scanline | |
| 203 | #define ALTO2_DISPLAY_BITCLOCK 20160000ll //!< display bit clock in in Hertz (20.16MHz) | |
| 204 | #define ALTO2_DISPLAY_BITTIME(n) (U64(1000000000000)*(n)/ALTO2_DISPLAY_BITCLOCK) //!< display bit time in in pico seconds (~= 49.6031ns) | |
| 205 | #define ALTO2_DISPLAY_SCANLINE_TIME ALTO2_DISPLAY_BITTIME(ALTO2_DISPLAY_TOTAL_WIDTH)//!< time for a scanline in pico seconds (768 * 49.6031ns ~= 38095.1808ns) | |
| 206 | #define ALTO2_DISPLAY_VISIBLE_TIME ALTO2_DISPLAY_BITTIME(ALTO2_DISPLAY_WIDTH) //!< time of the visible part of a scanline in pico seconds (606 * 49.6031ns ~= 30059.4786ns) | |
| 207 | #define ALTO2_DISPLAY_WORD_TIME ALTO2_DISPLAY_BITTIME(16) //!< time for a word in pico seconds (16 pixels * 49.6031ns ~= 793.6496ns) | |
| 208 | #define ALTO2_DISPLAY_VBLANK_TIME ((ALTO2_DISPLAY_TOTAL_HEIGHT-ALTO2_DISPLAY_HEIGHT)*HZ_TO_ATTOSECONDS(26250)) | |
| 209 | ||
| 210 | /** | |
| 211 | * @brief enumeration of the inputs and outputs of a JK flip-flop type 74109 | |
| 212 | * <PRE> | |
| 213 | * 74109 | |
| 214 | * Dual J-/K flip-flops with set and reset. | |
| 215 | * | |
| 216 | * +----------+ +-----------------------------+ | |
| 217 | * /1RST |1 +--+ 16| VCC | J |/K |CLK|/SET|/RST| Q |/Q | | |
| 218 | * 1J |2 15| /2RST |---+---+---+----+----+---+---| | |
| 219 | * /1K |3 14| 2J | X | X | X | 0 | 0 | 1 | 1 | | |
| 220 | * 1CLK |4 74 13| /2K | X | X | X | 0 | 1 | 1 | 0 | | |
| 221 | * /1SET |5 109 12| 2CLK | X | X | X | 1 | 0 | 0 | 1 | | |
| 222 | * 1Q |6 11| /2SET | 0 | 0 | / | 1 | 1 | 0 | 1 | | |
| 223 | * /1Q |7 10| 2Q | 0 | 1 | / | 1 | 1 | - | - | | |
| 224 | * GND |8 9| /2Q | 1 | 0 | / | 1 | 1 |/Q | Q | | |
| 225 | * +----------+ | 1 | 1 | / | 1 | 1 | 1 | 0 | | |
| 226 | * | X | X |!/ | 1 | 1 | - | - | | |
| 227 | * +-----------------------------+ | |
| 228 | * | |
| 229 | * [This information is part of the GIICM] | |
| 230 | * </PRE> | |
| 231 | */ | |
| 232 | typedef enum { | |
| 233 | JKFF_0, //!< no inputs or outputs | |
| 234 | JKFF_CLK = (1 << 0), //!< clock signal | |
| 235 | JKFF_J = (1 << 1), //!< J input | |
| 236 | JKFF_K = (1 << 2), //!< K' input | |
| 237 | JKFF_S = (1 << 3), //!< S' input | |
| 238 | JKFF_C = (1 << 4), //!< C' input | |
| 239 | JKFF_Q = (1 << 5), //!< Q output | |
| 240 | JKFF_Q0 = (1 << 6) //!< Q' output | |
| 241 | } jkff_t; | |
| 242 | ||
| 243 | 154 | class alto2_cpu_device : public cpu_device |
| 244 | 155 | { |
| 245 | 156 | public: |
| r26306 | r26307 | |
| 254 | 165 | void next_sector(int unit); |
| 255 | 166 | |
| 256 | 167 | //! return the display bitmap |
| 257 | bitmap_ind16 | |
| 168 | bitmap_ind16* bitmap(); | |
| 258 | 169 | |
| 259 | 170 | DECLARE_ADDRESS_MAP( ucode_map, 32 ); |
| 260 | 171 | DECLARE_ADDRESS_MAP( const_map, 16 ); |
| r26306 | r26307 | |
| 560 | 471 | bs_read_md, //!< BUS source is memory data |
| 561 | 472 | bs_mouse, //!< BUS source is mouse data |
| 562 | 473 | bs_disp, //!< BUS source displacement |
| 563 | ||
| 564 | bs_ram_read_slocation= bs_task_3, //!< ram related: read S register | |
| 565 | bs_ram_load_slocation= bs_task_4, //!< ram related: load S register | |
| 566 | ||
| 567 | bs_emu_read_sreg = bs_task_3, //!< emulator task: read S register | |
| 568 | bs_emu_load_sreg = bs_task_4, //!< emulator task: load S register from BUS | |
| 569 | ||
| 570 | bs_ksec_read_kstat = bs_task_3, //!< disk sector task: read status register | |
| 571 | bs_ksec_read_kdata = bs_task_4, //!< disk sector task: read data register | |
| 572 | ||
| 573 | bs_ether_eidfct = bs_task_3, //!< ethernet task: Ethernet input data function | |
| 574 | ||
| 575 | bs_kwd_read_kstat = bs_task_3, //!< disk word task: read status register | |
| 576 | bs_kwd_read_kdata = bs_task_4 //!< disk word task: read data register | |
| 577 | 474 | }; |
| 578 | 475 | |
| 579 | 476 | //! Function 1 numbers |
| 580 | 477 | enum { |
| 581 | f1_nop, //!< f1 (0000) no operation | |
| 582 | f1_load_mar, //!< f1 (0001) load memory address register | |
| 583 | f1_task, //!< f1 (0010) task switch | |
| 584 | f1_block, //!< f1 (0011) block task | |
| 585 | f1_l_lsh_1, //!< f1 (0100) left shift L once | |
| 586 | f1_l_rsh_1, //!< f1 (0101) right shift L once | |
| 587 | f1_l_lcy_8, //!< f1 (0110) cycle L 8 times | |
| 588 | f1_const, //!< f1 (0111) constant from PROM | |
| 478 | f1_nop, //!< f1 00 no operation | |
| 479 | f1_load_mar, //!< f1 01 load memory address register | |
| 480 | f1_task, //!< f1 02 task switch | |
| 481 | f1_block, //!< f1 03 block task | |
| 482 | f1_l_lsh_1, //!< f1 04 left shift L once | |
| 483 | f1_l_rsh_1, //!< f1 05 right shift L once | |
| 484 | f1_l_lcy_8, //!< f1 06 cycle L 8 times | |
| 485 | f1_const, //!< f1 07 constant from PROM | |
| 589 | 486 | |
| 590 | f1_task_10, //!< f1 (1000) task specific | |
| 591 | f1_task_11, //!< f1 (1001) task specific | |
| 592 | f1_task_12, //!< f1 (1010) task specific | |
| 593 | f1_task_13, //!< f1 (1011) task specific | |
| 594 | f1_task_14, //!< f1 (1100) task specific | |
| 595 | f1_task_15, //!< f1 (1101) task specific | |
| 596 | f1_task_16, //!< f1 (1110) task specific | |
| 597 | f1_task_17, //!< f1 (1111) task specific | |
| 598 | ||
| 599 | f1_ram_swmode = f1_task_10, //!< f1 (1000) ram related: switch mode to CROM/CRAM in same page | |
| 600 | f1_ram_wrtram = f1_task_11, //!< f1 (1001) ram related: start WRTRAM cycle | |
| 601 | f1_ram_rdram = f1_task_12, //!< f1 (1010) ram related: start RDRAM cycle | |
| 602 | #if (ALTO2_UCODE_RAM_PAGES == 3) | |
| 603 | f1_ram_load_rmr = f1_task_13, //!< f1 (1011) ram related: load the reset mode register | |
| 604 | #else // ALTO2_UCODE_RAM_PAGES != 3 | |
| 605 | f1_ram_load_srb = f1_task_13, //!< f1 (1011) ram related: load the S register bank from BUS[12-14] | |
| 606 | #endif | |
| 607 | ||
| 608 | f1_emu_swmode = f1_task_10, //!< f1 (1000) emu: switch mode; branch to ROM/RAM microcode | |
| 609 | f1_emu_wrtram = f1_task_11, //!< f1 (1001) emu: write microcode RAM | |
| 610 | f1_emu_rdram = f1_task_12, //!< f1 (1010) emu: read microcode RAM | |
| 611 | f1_emu_load_rmr = f1_task_13, //!< f1 (1011) emu: load reset mode register | |
| 612 | //!< f1 (1100) emu: undefined | |
| 613 | f1_emu_load_esrb = f1_task_15, //!< f1 (1101) emu: load extended S register bank | |
| 614 | f1_emu_rsnf = f1_task_16, //!< f1 (1110) emu: read serial number (Ethernet ID) | |
| 615 | f1_emu_startf = f1_task_17, //!< f1 (1111) emu: start I/O hardware (Ethernet) | |
| 616 | ||
| 617 | f1_ksec_strobe = f1_task_11, //!< f1 (1001) ksec: strobe | |
| 618 | f1_ksec_load_kstat = f1_task_12, //!< f1 (1010) ksec: load kstat register | |
| 619 | f1_ksec_increcno = f1_task_13, //!< f1 (1011) ksec: increment record number | |
| 620 | f1_ksec_clrstat = f1_task_14, //!< f1 (1100) ksec: clear status register | |
| 621 | f1_ksec_load_kcom = f1_task_15, //!< f1 (1101) ksec: load kcom register | |
| 622 | f1_ksec_load_kadr = f1_task_16, //!< f1 (1110) ksec: load kadr register | |
| 623 | f1_ksec_load_kdata = f1_task_17, //!< f1 (1111) ksec: load kdata register | |
| 624 | ||
| 625 | f1_ether_eilfct = f1_task_13, //!< f1 (1011) ether: Ethernet input look function | |
| 626 | f1_ether_epfct = f1_task_14, //!< f1 (1100) ether: Ethernet post function | |
| 627 | f1_ether_ewfct = f1_task_15, //!< f1 (1101) ether: Ethernet countdown wakeup function | |
| 628 | ||
| 629 | f1_kwd_strobe = f1_task_11, //!< f1 (1001) kwd: strobe | |
| 630 | f1_kwd_load_kstat = f1_task_12, //!< f1 (1010) kwd: load kstat register | |
| 631 | f1_kwd_increcno = f1_task_13, //!< f1 (1011) kwd: increment record number | |
| 632 | f1_kwd_clrstat = f1_task_14, //!< f1 (1100) kwd: clear status register | |
| 633 | f1_kwd_load_kcom = f1_task_15, //!< f1 (1101) kwd: load kcom register | |
| 634 | f1_kwd_load_kadr = f1_task_16, //!< f1 (1110) kwd: load kadr register | |
| 635 | f1_kwd_load_kdata = f1_task_17, //!< f1 (1111) kwd: load kdata register | |
| 487 | f1_task_10, //!< f1 10 task specific | |
| 488 | f1_task_11, //!< f1 11 task specific | |
| 489 | f1_task_12, //!< f1 12 task specific | |
| 490 | f1_task_13, //!< f1 13 task specific | |
| 491 | f1_task_14, //!< f1 14 task specific | |
| 492 | f1_task_15, //!< f1 15 task specific | |
| 493 | f1_task_16, //!< f1 16 task specific | |
| 494 | f1_task_17, //!< f1 17 task specific | |
| 636 | 495 | }; |
| 637 | 496 | |
| 638 | 497 | //! Function 2 numbers |
| r26306 | r26307 | |
| 645 | 504 | f2_alucy, //!< f2 05 branch on (latched) ALU carry |
| 646 | 505 | f2_load_md, //!< f2 06 load memory data |
| 647 | 506 | f2_const, //!< f2 07 constant from PROM |
| 507 | ||
| 648 | 508 | f2_task_10, //!< f2 10 task specific |
| 649 | 509 | f2_task_11, //!< f2 11 task specific |
| 650 | 510 | f2_task_12, //!< f2 12 task specific |
| r26306 | r26307 | |
| 653 | 513 | f2_task_15, //!< f2 15 task specific |
| 654 | 514 | f2_task_16, //!< f2 16 task specific |
| 655 | 515 | f2_task_17, //!< f2 17 task specific |
| 656 | ||
| 657 | f2_emu_busodd = f2_task_10, //!< f2 (1000) emu: branch on bus odd | |
| 658 | f2_emu_magic = f2_task_11, //!< f2 (1001) emu: magic shifter (MRSH 1: shifter[15]=T[0], MLSH 1: shifter[015]) | |
| 659 | f2_emu_load_dns = f2_task_12, //!< f2 (1010) emu: do novel shift (RSH 1: shifter[15]=XC, LSH 1: shifer[0]=XC) | |
| 660 | f2_emu_acdest = f2_task_13, //!< f2 (1011) emu: destination accu | |
| 661 | f2_emu_load_ir = f2_task_14, //!< f2 (1100) emu: load instruction register and branch | |
| 662 | f2_emu_idisp = f2_task_15, //!< f2 (1101) emu: load instruction displacement and branch | |
| 663 | f2_emu_acsource = f2_task_16, //!< f2 (1110) emu: source accu | |
| 664 | ||
| 665 | f2_ksec_init = f2_task_10, //!< f2 (1000) ksec: branches NEXT[5-9] on WDTASKACT && WDINIT | |
| 666 | f2_ksec_rwc = f2_task_11, //!< f2 (1001) ksec: branches NEXT[8-9] on READ/WRITE/CHECK for record | |
| 667 | f2_ksec_recno = f2_task_12, //!< f2 (1010) ksec: branches NEXT[8-9] on RECNO[0-1] | |
| 668 | f2_ksec_xfrdat = f2_task_13, //!< f2 (1011) ksec: branches NEXT[9] on !SEEKONLY | |
| 669 | f2_ksec_swrnrdy = f2_task_14, //!< f2 (1100) ksec: branches NEXT[9] on !SWRDY | |
| 670 | f2_ksec_nfer = f2_task_15, //!< f2 (1101) ksec: branches NEXT[9] on !KFER | |
| 671 | f2_ksec_strobon = f2_task_16, //!< f2 (1110) ksec: branches NEXT[9] on STROBE | |
| 672 | ||
| 673 | f2_ether_eodfct = f2_task_10, //!< f2 (1000) ether: Ethernet output data function | |
| 674 | f2_ether_eosfct = f2_task_11, //!< f2 (1001) ether: Ethernet output start function | |
| 675 | f2_ether_erbfct = f2_task_12, //!< f2 (1010) ether: Ethernet reset branch function | |
| 676 | f2_ether_eefct = f2_task_13, //!< f2 (1011) ether: Ethernet end of transmission function | |
| 677 | f2_ether_ebfct = f2_task_14, //!< f2 (1100) ether: Ethernet branch function | |
| 678 | f2_ether_ecbfct = f2_task_15, //!< f2 (1101) ether: Ethernet countdown branch function | |
| 679 | f2_ether_eisfct = f2_task_16, //!< f2 (1110) ether: Ethernet input start function | |
| 680 | ||
| 681 | f2_dwt_load_ddr = f2_task_10, //!< f2 (1000) dwt: load display data register | |
| 682 | ||
| 683 | f2_curt_load_xpreg = f2_task_10, //!< f2 (1000) curt: load x position register | |
| 684 | f2_curt_load_csr = f2_task_11, //!< f2 (1001) curt: load cursor shift register | |
| 685 | ||
| 686 | f2_dht_evenfield = f2_task_10, //!< f2 (1000) dht: load even field | |
| 687 | f2_dht_setmode = f2_task_11, //!< f2 (1001) dht: set mode | |
| 688 | ||
| 689 | f2_dvt_evenfield = f2_task_10, //!< f2 (1000) dvt: load even field | |
| 690 | ||
| 691 | f2_kwd_init = f2_task_10, //!< f2 (1000) kwd: branches NEXT[5-9] on WDTASKACT && WDINIT | |
| 692 | f2_kwd_rwc = f2_task_11, //!< f2 (1001) kwd: branches NEXT[8-9] on READ/WRITE/CHECK for record | |
| 693 | f2_kwd_recno = f2_task_12, //!< f2 (1010) kwd: branches NEXT[8-9] on RECNO[0-1] | |
| 694 | f2_kwd_xfrdat = f2_task_13, //!< f2 (1011) kwd: branches NEXT[9] on !SEEKONLY | |
| 695 | f2_kwd_swrnrdy = f2_task_14, //!< f2 (1100) kwd: branches NEXT[9] on !SWRDY | |
| 696 | f2_kwd_nfer = f2_task_15, //!< f2 (1101) kwd: branches NEXT[9] on !KFER | |
| 697 | f2_kwd_strobon = f2_task_16, //!< f2 (1110) kwd: branches NEXT[9] on STROBE | |
| 698 | 516 | }; |
| 699 | 517 | |
| 700 | 518 | //! enumeration of the micro code word bits |
| r26306 | r26307 | |
| 991 | 809 | |
| 992 | 810 | /** |
| 993 | 811 | * @brief unused PROM a90 |
| 812 | * Data sheet 05a_AIM.pdf page 14 | |
| 813 | * inputs A0-A7 from R0-R7 (?) | |
| 814 | * output signal | |
| 815 | * ------------------- | |
| 816 | * Q0 KP3 | |
| 817 | * Q1 KP4 | |
| 818 | * Q2 KP5 | |
| 819 | * Q3 unused | |
| 820 | * | |
| 821 | * I haven't found yet where KP3-KP5 are used | |
| 994 | 822 | */ |
| 995 | 823 | UINT8* m_madr_a90; |
| 996 | 824 | |
| 997 | 825 | /** |
| 998 | 826 | * @brief unused PROM a91 |
| 827 | * Data sheet 05a_AIM.pdf page 14 | |
| 828 | * inputs A0-A7 from R0-R7 (?) | |
| 829 | * | |
| 830 | * Output Signal | |
| 831 | * ------------------- | |
| 832 | * Q0 KP0 | |
| 833 | * Q1 KP1 | |
| 834 | * Q2 KP2 | |
| 835 | * Q3 unused | |
| 836 | * KP0-KP3 are decoded using 7442 a78 to select | |
| 837 | * the keyboard row enable | |
| 838 | * | |
| 839 | * Enable Keys | |
| 840 | * ------------------------------------------------------------------------ | |
| 841 | * KE(0) KB(R) KB(1) KB(3) KB(5) KB(T) KB(ESC) KB(2) KB(4) | |
| 842 | * KE(1) KB(G) KB(TAB) KB(W) KB(6) KB(Y) KB(F) KB(0) KB(E) | |
| 843 | * KE(2) KB(H) KB(CTL) KB(S) KB(7) KB(8) KB(C) KB(A) KB(D) | |
| 844 | * KE(3) KB(N) KB(J) KB(9) KB(U) KB(M) KB(B) KB(I) KB(V) | |
| 845 | * KE(4) KB(LCK) KB(Z) KB(X) KB(Q) KB(SPC) KB(↑R) KB(O) KB(K) | |
| 846 | * KE(5) KB([) KB(.) KB(L) KB(-) KB(+) KB(;) KB(,) KB(P) | |
| 847 | * KE(6) KB(↑L) KB(RTN) KB(") KB(/) KB(S3) KB(←) KB(]) KB(\) | |
| 848 | * KE(7) KB(S1) KB(DEL) KB(S2) KB(LF) KB(S4) KB(S5) KB(BW) KB(BS) | |
| 999 | 849 | */ |
| 1000 | 850 | UINT8* m_madr_a91; |
| 1001 | 851 | |
| 852 | /** | |
| 853 | * @brief ALU function to 74181 operation lookup PROM | |
| 854 | */ | |
| 855 | UINT8* m_alu_a10; | |
| 856 | ||
| 857 | //! output lines of the ALU a10 PROM | |
| 858 | enum { | |
| 859 | A10_UNUSED = (1 << 0), | |
| 860 | A10_TSELECT = (1 << 1), | |
| 861 | A10_ALUCI = (1 << 2), | |
| 862 | A10_ALUM = (1 << 3), | |
| 863 | A10_ALUS0 = (1 << 4), | |
| 864 | A10_ALUS1 = (1 << 5), | |
| 865 | A10_ALUS2 = (1 << 6), | |
| 866 | A10_ALUS3 = (1 << 7), | |
| 867 | A10_ALUIN = (A10_ALUM|A10_ALUCI|A10_ALUS0|A10_ALUS1|A10_ALUS2|A10_ALUS3) | |
| 868 | }; | |
| 869 | ||
| 1002 | 870 | //! no operating function to put in the m_bs, m_f1 and m_f2 slots |
| 1003 | 871 | void noop() {} |
| 1004 | 872 | |
| r26306 | r26307 | |
| 1067 | 935 | void f2_late_alucy(); //!< F2 func: branch on latched ALU carry |
| 1068 | 936 | void f2_late_load_md(); //!< F2 func: load memory data |
| 1069 | 937 | |
| 1070 | UINT8* m_alu_a10; //!< ALU function to 74181 operation lookup PROM | |
| 1071 | 938 | #if USE_ALU_74181 |
| 1072 | 939 | UINT32 alu_74181(UINT32 a, UINT32 b, UINT8 smc); |
| 1073 | 940 | #endif |
| 1074 | 941 | void rdram(); //!< read the microcode ROM/RAM halfword |
| 1075 | 942 | void wrtram(); //!< write the microcode RAM from M register and ALU |
| 1076 | 943 | |
| 1077 | // ************************************************ | |
| 1078 | // ram related stuff | |
| 1079 | // ************************************************ | |
| 1080 | void bs_early_read_sreg(); //!< bus source: drive bus by S register or M (MYL), if rsel is = 0 | |
| 1081 | void bs_early_load_sreg(); //!< bus source: load S register puts garbage on the bus | |
| 1082 | void bs_late_load_sreg(); //!< bus source: load S register from M | |
| 1083 | void branch_ROM(const char *from, int page); //!< branch to ROM page | |
| 1084 | void branch_RAM(const char *from, int page); //!< branch to RAM page | |
| 1085 | void f1_late_swmode(); //!< F1 func: switch to micro program counter BUS[6-15] in other bank | |
| 1086 | void f1_late_wrtram(); //!< F1 func: start WRTRAM cycle | |
| 1087 | void f1_late_rdram(); //!< F1 func: start RDRAM cycle | |
| 1088 | #if (ALTO2_UCODE_RAM_PAGES == 3) | |
| 1089 | void f1_late_load_rmr(); //!< F1 func: load the reset mode register | |
| 1090 | #else // ALTO2_UCODE_RAM_PAGES != 3 | |
| 1091 | void f1_late_load_srb(); //!< F1 func: load the S register bank from BUS[12-14] | |
| 1092 | #endif | |
| 1093 | void init_ram(int task); //!< called by RAM related tasks | |
| 1094 | void exit_ram(); | |
| 1095 | ||
| 1096 | # include "a2hw.h" | |
| 1097 | // ************************************************ | |
| 1098 | // keyboard stuff | |
| 1099 | // ************************************************ | |
| 1100 | struct { | |
| 1101 | UINT16 bootkey; //!< boot key - key code pressed before power on | |
| 1102 | UINT16 matrix[4]; //!< a bit map of the keys pressed (ioports ROW0 ... ROW3) | |
| 1103 | } m_kbd; | |
| 1104 | DECLARE_READ16_MEMBER( kbd_ad_r ); //!< read the keyboard matrix | |
| 1105 | void init_kbd(UINT16 bootkey = 0177777); //!< initialize the keyboard hardware, optinally set the boot key | |
| 1106 | void exit_kbd(); //!< deinitialize the keyboard hardware | |
| 1107 | ||
| 1108 | // ************************************************ | |
| 1109 | // mouse stuff | |
| 1110 | // ************************************************ | |
| 1111 | /** | |
| 1112 | * @brief PROM madr.a32 contains a lookup table to translate mouse motions | |
| 1113 | * | |
| 1114 | * <PRE> | |
| 1115 | * The 4 mouse motion signals MX1, MX2, MY1, and MY2 are connected | |
| 1116 | * to a 256x4 PROM's (3601, SN74387) address lines A0, A2, A4, and A6. | |
| 1117 | * The previous (latched) state of the 4 signals is connected to the | |
| 1118 | * address lines A1, A3, A5, and A7. | |
| 1119 | * | |
| 1120 | * SN74387 | |
| 1121 | * +---+--+---+ | |
| 1122 | * | +--+ | | |
| 1123 | * MY2 A6 -|1 16|- Vcc | |
| 1124 | * | | | |
| 1125 | * LMY1 A5 -|2 15|- A7 LMY2 | |
| 1126 | * | | | |
| 1127 | * MY1 A4 -|3 14|- FE1' 0 | |
| 1128 | * | | | |
| 1129 | * LMX2 A3 -|4 13|- FE2' 0 | |
| 1130 | * | | | |
| 1131 | * MX1 A0 -|5 12|- D0 BUS[12] | |
| 1132 | * | | | |
| 1133 | * LMX1 A1 -|6 11|- D1 BUS[13] | |
| 1134 | * | | | |
| 1135 | * MX2 A2 -|7 10|- D2 BUS[14] | |
| 1136 | * | | | |
| 1137 | * GND -|8 9|- D3 BUS[15] | |
| 1138 | * | | | |
| 1139 | * +----------+ | |
| 1140 | * | |
| 1141 | * A motion to the west will first toggle MX2, then MX1. | |
| 1142 | * sequence: 04 -> 0d -> 0b -> 02 | |
| 1143 | * A motion to the east will first toggle MX1, then MX2. | |
| 1144 | * sequence: 01 -> 07 -> 0e -> 08 | |
| 1145 | * | |
| 1146 | * A motion to the north will first toggle MY2, then MY1. | |
| 1147 | * sequence: 40 -> d0 -> b0 -> 20 | |
| 1148 | * A motion to the south will first toggle MY1, then MY2. | |
| 1149 | * sequence: 10 -> 70 -> e0 -> 80 | |
| 1150 | * </PRE> | |
| 1151 | */ | |
| 1152 | UINT8* m_madr_a32; | |
| 1153 | ||
| 1154 | //! mouse context | |
| 1155 | struct { | |
| 1156 | int x; //!< current X coordinate | |
| 1157 | int y; //!< current Y coordinate | |
| 1158 | int dx; //!< destination X coordinate (real mouse X) | |
| 1159 | int dy; //!< destination Y coordinate (real mouse Y) | |
| 1160 | UINT8 latch; //!< current latch value | |
| 1161 | UINT8 phase; //!< current read latch phase | |
| 1162 | } m_mouse; | |
| 1163 | ||
| 1164 | UINT16 mouse_read(); //!< return the mouse motion flags | |
| 1165 | void init_mouse(); //!< initialize the mouse context to useful values | |
| 1166 | void exit_mouse(); //!< deinitialize the mouse | |
| 1167 | ||
| 1168 | // ************************************************ | |
| 1169 | // disk controller stuff | |
| 1170 | // ************************************************ | |
| 1171 | diablo_hd_device* m_drive[2]; //!< two diablo_hd_device drives | |
| 1172 | ||
| 1173 | //! disk controller context | |
| 1174 | struct { | |
| 1175 | UINT8 drive; //!< selected drive from KADDR[14] (written to data out with SENDADR) | |
| 1176 | UINT16 kaddr; //!< A[0-15] disk hardware address (sector, cylinder, head, drive, restore) | |
| 1177 | UINT16 kadr; //!< C[0-15] with read/write/check modes for header, label and data | |
| 1178 | UINT16 kstat; //!< S[0-15] disk status | |
| 1179 | UINT16 kcom; //!< disk command (5 bits kcom[1-5]) | |
| 1180 | UINT8 krecno; //!< record number (2 bits indexing header, label, data, -/-) | |
| 1181 | UINT8 egate; //!< current erase gate signal to the DIABLO hd | |
| 1182 | UINT8 wrgate; //!< current write gate signal to the DIABLO hd | |
| 1183 | UINT8 rdgate; //!< current read gate signal to the DIABLO hd | |
| 1184 | UINT32 shiftin; //!< input shift register | |
| 1185 | UINT32 shiftout; //!< output shift register | |
| 1186 | UINT32 datain; //!< disk data in latch | |
| 1187 | UINT32 dataout; //!< disk data out latch | |
| 1188 | UINT8 krwc; //!< read/write/check for current record | |
| 1189 | UINT8 kfer; //!< disk fatal error signal state | |
| 1190 | UINT8 wdtskena; //!< disk word task enable (active low) | |
| 1191 | UINT8 wddone; //!< previous state of WDDONE | |
| 1192 | UINT8 wdinit0; //!< disk word task init at the early microcycle | |
| 1193 | UINT8 wdinit; //!< disk word task init at the late microcycle | |
| 1194 | UINT8 strobe; //!< strobe (still) active | |
| 1195 | emu_timer* strobon_timer; //!< set strobe on timer | |
| 1196 | UINT8 bitclk; //!< current bitclk state (either crystal clock, or rdclk from the drive) | |
| 1197 | #if USE_BITCLK_TIMER | |
| 1198 | emu_timer* bitclk_timer; //!< bit clock timer | |
| 1199 | #else | |
| 1200 | int bitclk_time; //!< time in clocks per bit | |
| 1201 | #endif | |
| 1202 | UINT8 datin; //!< current datin from the drive | |
| 1203 | UINT8 bitcount; //!< bit counter | |
| 1204 | UINT8 carry; //!< carry output of the bitcounter | |
| 1205 | UINT8 seclate; //!< sector late (monoflop output) | |
| 1206 | emu_timer* seclate_timer; //!< sector late timer | |
| 1207 | UINT8 seekok; //!< seekok state (SKINC' & LAI' & ff_44a.Q') | |
| 1208 | UINT8 ok_to_run; //!< ok to run signal (set to 1 some time after reset) | |
| 1209 | emu_timer* ok_to_run_timer; //!< ok to run timer | |
| 1210 | UINT8 ready_mf31a; //!< ready monoflop 31a | |
| 1211 | emu_timer* ready_timer; //!< ready timer | |
| 1212 | UINT8 seclate_mf31b; //!< seclate monoflop 31b | |
| 1213 | jkff_t ff_21a; //!< JK flip-flop 21a (sector task) | |
| 1214 | jkff_t ff_21a_old; //!< -"- previous state | |
| 1215 | jkff_t ff_21b; //!< JK flip-flop 21b (sector task) | |
| 1216 | jkff_t ff_22a; //!< JK flip-flop 22a (sector task) | |
| 1217 | jkff_t ff_22b; //!< JK flip-flop 22b (sector task) | |
| 1218 | jkff_t ff_43b; //!< JK flip-flop 43b (word task) | |
| 1219 | jkff_t ff_53a; //!< JK flip-flop 53a (word task) | |
| 1220 | jkff_t ff_43a; //!< JK flip-flop 43a (word task) | |
| 1221 | jkff_t ff_53b; //!< brief JK flip-flop 53b (word task) | |
| 1222 | jkff_t ff_44a; //!< JK flip-flop 44a (LAI' clocked) | |
| 1223 | jkff_t ff_44b; //!< JK flip-flop 44b (CKSUM) | |
| 1224 | jkff_t ff_45a; //!< JK flip-flop 45a (ready latch) | |
| 1225 | jkff_t ff_45b; //!< JK flip-flop 45b (seqerr latch) | |
| 1226 | } m_dsk; | |
| 1227 | ||
| 1228 | jkff_t m_sysclka0[4]; //!< simulate previous sysclka | |
| 1229 | jkff_t m_sysclka1[4]; //!< simulate current sysclka | |
| 1230 | jkff_t m_sysclkb0[4]; //!< simulate previous sysclkb | |
| 1231 | jkff_t m_sysclkb1[4]; //!< simulate current sysclkb | |
| 1232 | //! lookup JK flip-flop state change from s0 to s1 | |
| 1233 | inline jkff_t update_jkff(UINT8 s0, UINT8 s1); | |
| 1234 | ||
| 1235 | void kwd_timing(int bitclk, int datin, int block); //!< disk word timing | |
| 1236 | TIMER_CALLBACK_MEMBER( disk_seclate ); //!< timer callback to take away the SECLATE pulse (monoflop) | |
| 1237 | TIMER_CALLBACK_MEMBER( disk_ok_to_run ); //!< timer callback to take away the OK TO RUN pulse (reset) | |
| 1238 | TIMER_CALLBACK_MEMBER( disk_strobon ); //!< timer callback to pulse the STROBE' signal to the drive | |
| 1239 | TIMER_CALLBACK_MEMBER( disk_ready_mf31a ); //!< timer callback to change the READY monoflop 31a | |
| 1240 | #if USE_BITCLK_TIMER | |
| 1241 | TIMER_CALLBACK_MEMBER( disk_bitclk ); //!< callback to update the disk controller with a new bitclk | |
| 1242 | #else | |
| 1243 | void disk_bitclk(void *ptr, int arg); //!< function to update the disk controller with a new bitclk | |
| 1244 | #endif | |
| 1245 | void disk_block(int task); //!< called if one of the disk tasks (task_kwd or task_ksec) blocks | |
| 1246 | void bs_early_read_kstat(); //!< bus source: bus driven by disk status register KSTAT | |
| 1247 | void bs_early_read_kdata(); //!< bus source: bus driven by disk data register KDATA input | |
| 1248 | void f1_late_strobe(); //!< F1 func: initiates a disk seek | |
| 1249 | void f1_late_load_kstat(); //!< F1 func: load disk status register | |
| 1250 | void f1_late_load_kdata(); //!< F1 func: load data out register, or the disk address register | |
| 1251 | void f1_late_increcno(); //!< F1 func: advances shift registers holding KADR | |
| 1252 | void f1_late_clrstat(); //!< F1 func: reset all error latches | |
| 1253 | void f1_late_load_kcom(); //!< F1 func: load the KCOM register from bus | |
| 1254 | void f1_late_load_kadr(); //!< F1 func: load the KADR register from bus | |
| 1255 | void f2_late_init(); //!< F2 func: branch on disk word task active and init | |
| 1256 | void f2_late_rwc(); //!< F2 func: branch on read/write/check state of the current record | |
| 1257 | void f2_late_recno(); //!< F2 func: branch on the current record number by a lookup table | |
| 1258 | void f2_late_xfrdat(); //!< F2 func: branch on the data transfer state | |
| 1259 | void f2_late_swrnrdy(); //!< F2 func: branch on the disk ready signal | |
| 1260 | void f2_late_nfer(); //!< f2_nfer late: branch on the disk fatal error condition | |
| 1261 | void f2_late_strobon(); //!< f2_strobon late: branch on the seek busy status | |
| 1262 | void init_disk(); //!< initialize the disk context | |
| 1263 | void exit_disk(); //!< deinitialize the disk context | |
| 1264 | ||
| 1265 | // ************************************************ | |
| 1266 | // display stuff | |
| 1267 | // ************************************************ | |
| 1268 | /** | |
| 1269 | * @brief structure of the display context | |
| 1270 | * | |
| 1271 | * Schematics of the task clear and wakeup signal generators | |
| 1272 | * <PRE> | |
| 1273 | * A quote (') appended to a signal name means inverted signal. | |
| 1274 | * | |
| 1275 | * AND | NAND| NOR | FF | Q N174 | |
| 1276 | * -----+--- -----+--- -----+--- -----+--- ----- | |
| 1277 | * 0 0 | 0 0 0 | 1 0 0 | 1 S'\0| 1 delay | |
| 1278 | * 0 1 | 0 0 1 | 1 0 1 | 0 R'\0| 0 | |
| 1279 | * 1 0 | 0 1 0 | 1 1 0 | 0 | |
| 1280 | * 1 1 | 1 1 1 | 0 1 1 | 0 | |
| 1281 | * | |
| 1282 | * | |
| 1283 | * DVTAC' | |
| 1284 | * >-------· +-----+ | |
| 1285 | * | | FF | | |
| 1286 | * VBLANK'+----+ DELVBLANK' +---+ DELVBLANK +----+ ·--|S' | | |
| 1287 | * >------|N174|------+-----|inv|--------------|NAND| VBLANKPULSE | | WAKEDVT' | |
| 1288 | * +----+ | +---+ | o--+-----------|R' Q|----------------------> | |
| 1289 | * | ·-| | | | | | |
| 1290 | * +----+ | DDELVBLANK' | +----+ | +-----+ | |
| 1291 | * ·-|N174|-----------------------------· | +---+ | |
| 1292 | * | +----+ | +------oAND| | |
| 1293 | * | | DSP07.01 | | o----------· | |
| 1294 | * ·-------------· >---------|------o | | | |
| 1295 | * | +---+ | | |
| 1296 | * | | | |
| 1297 | * | +-----+ | | |
| 1298 | * | | FF | | +-----+ | |
| 1299 | * DHTAC' +---+ | | | | | FF | | |
| 1300 | * >--------------oNOR| *07.25 +----+ ·-|S' | DHTBLK' | | | | |
| 1301 | * BLOCK' | |---------------|NAND| | Q|--+----------|--|S1' | WAKEDHT' | |
| 1302 | * >--------------o | DCSYSCLK | o--------|R' | | >--------|--|S2' Q|---------> | |
| 1303 | * +---+ >---------| | +-----+ | DHTAC' ·--|R' | | |
| 1304 | * +----+ | +-----+ | |
| 1305 | * ·------------· | |
| 1306 | * | | |
| 1307 | * DWTAC' +---+ | +-----+ | |
| 1308 | * >--------------oNOR| *07.26 +----+ | | FF | | |
| 1309 | * BLOCK' | |---------|NAND| DSP07.01 | | | | |
| 1310 | * >--------------o | DCSYSCLK| o----------|---|S1' | DWTCN' +---+ DWTCN | |
| 1311 | * +---+ >-------| | ·---|S2' Q|--------|inv|-----------+---- | |
| 1312 | * +----+ ·---|R' | +---+ | | |
| 1313 | * | +-----+ | | |
| 1314 | * SCANEND +----+ | | | |
| 1315 | * >-------------|NAND| CLRBUF' | .----------------------· | |
| 1316 | * DCLK | o----------------· | | |
| 1317 | * >-------------| | | +-----+ | |
| 1318 | * +----+ ·--| NAND| | |
| 1319 | * STOPWAKE' | |preWake +----+ WAKEDWT' | |
| 1320 | * >-----------| o--------|N174|---------> | |
| 1321 | * VBLANK' | | +----+ | |
| 1322 | * >-----------| | | |
| 1323 | * +-----+ | |
| 1324 | * a40c | |
| 1325 | * VBLANKPULSE +----+ | |
| 1326 | * -------------|NAND| | |
| 1327 | * | o--· | |
| 1328 | * ·--| | | | |
| 1329 | * | +----+ | | |
| 1330 | * ·----------|-· | |
| 1331 | * ·----------· | | |
| 1332 | * CURTAC' +---+ | +----+ | a20d | |
| 1333 | * >--------------oNOR| *07.27 +----+ ·--|NAND| | +----+ | |
| 1334 | * BLOCK' | |---------|NAND| DSP07.07 | o----+----o NOR| preWK +----+ WAKECURT' | |
| 1335 | * >--------------o | DCSYSCLK| o-----------| | | |--------|N174|---------> | |
| 1336 | * +---+ >-------| | +----+ +----o | +----+ | |
| 1337 | * +----+ a40d | +----+ | |
| 1338 | * a30c | | |
| 1339 | * CURTAC' +----+ | | |
| 1340 | * >------------|NAND| DSP07.03 | | |
| 1341 | * | o--+------------· | |
| 1342 | * ·--| | | | |
| 1343 | * | +----+ | | |
| 1344 | * ·----------|-· | |
| 1345 | * ·----------· | | |
| 1346 | * | +----+ | | |
| 1347 | * ·--|NAND| | | |
| 1348 | * CLRBUF' | o----· | |
| 1349 | * >------------| | | |
| 1350 | * +----+ | |
| 1351 | * a30d | |
| 1352 | * </PRE> | |
| 1353 | */ | |
| 1354 | struct { | |
| 1355 | UINT16 hlc; //!< horizontal line counter | |
| 1356 | UINT8 a63; //!< most recent value read from the PROM a63 | |
| 1357 | UINT8 a66; //!< most recent value read from the PROM a66 | |
| 1358 | UINT16 setmode; //!< value written by last SETMODE<- | |
| 1359 | UINT16 inverse; //!< set to 0xffff if line is inverse, 0x0000 otherwise | |
| 1360 | UINT8 halfclock; //!< set 0 for normal pixel clock, 1 for half pixel clock | |
| 1361 | UINT8 clr; //!< set non-zero if any of VBLANK or HBLANK is active (a39a 74S08) | |
| 1362 | UINT16 fifo[ALTO2_DISPLAY_FIFO]; //!< display word fifo | |
| 1363 | UINT8 fifo_wr; //!< fifo input pointer (4-bit) | |
| 1364 | UINT8 fifo_rd; //!< fifo output pointer (4-bit) | |
| 1365 | UINT8 dht_blocks; //!< set non-zero, if the DHT executed BLOCK | |
| 1366 | UINT8 dwt_blocks; //!< set non-zero, if the DWT executed BLOCK | |
| 1367 | UINT8 curt_blocks; //!< set non-zero, if the CURT executed BLOCK | |
| 1368 | UINT8 curt_wakeup; //!< set non-zero, if CURT wakeups are generated | |
| 1369 | UINT16 vblank; //!< most recent HLC with VBLANK still high (11-bit) | |
| 1370 | UINT16 xpreg; //!< cursor cursor x position register (10-bit) | |
| 1371 | UINT16 csr; //!< cursor shift register (16-bit) | |
| 1372 | UINT32 curword; //!< helper: first cursor word in current scanline | |
| 1373 | UINT32 curdata; //!< helper: shifted cursor data (32-bit) | |
| 1374 | UINT16 *raw_bitmap; //!< array of words of the raw bitmap that is displayed | |
| 1375 | UINT16 **scanline; //!< array of pointers to the scanlines | |
| 1376 | } m_dsp; | |
| 1377 | ||
| 1378 | /** | |
| 1379 | * @brief PROM a38 contains the STOPWAKE' and MBEMBPTY' signals for the FIFO | |
| 1380 | * <PRE> | |
| 1381 | * The inputs to a38 are the UNLOAD counter RA[0-3] and the DDR<- counter | |
| 1382 | * WA[0-3], and the designer decided to reverse the address lines :-) | |
| 1383 | * | |
| 1384 | * a38 counter FIFO counter | |
| 1385 | * -------------------------- | |
| 1386 | * A0 RA[0] fifo_rd | |
| 1387 | * A1 RA[1] | |
| 1388 | * A2 RA[2] | |
| 1389 | * A3 RA[3] | |
| 1390 | * A4 WA[0] fifo_wr | |
| 1391 | * A5 WA[1] | |
| 1392 | * A6 WA[2] | |
| 1393 | * A7 WA[3] | |
| 1394 | * | |
| 1395 | * Only two bits of a38 are used: | |
| 1396 | * O1 (002) = STOPWAKE' | |
| 1397 | * O3 (010) = MBEMPTY' | |
| 1398 | * </PRE> | |
| 1399 | */ | |
| 1400 | UINT8* m_disp_a38; | |
| 1401 | ||
| 1402 | //! output bits of PROM A38 | |
| 1403 | enum { | |
| 1404 | A38_STOPWAKE = (1 << 1), | |
| 1405 | A38_MBEMPTY = (1 << 3) | |
| 1406 | }; | |
| 1407 | ||
| 1408 | //! PROM a38 bit O1 is STOPWAKE' (stop DWT if bit is zero) | |
| 1409 | inline UINT8 FIFO_STOPWAKE_0() { return m_disp_a38[m_dsp.fifo_rd * 16 + m_dsp.fifo_wr] & A38_STOPWAKE; } | |
| 1410 | ||
| 1411 | //! PROM a38 bit O3 is MBEMPTY' (FIFO is empty if bit is zero) | |
| 1412 | inline UINT8 FIFO_MBEMPTY_0() { return m_disp_a38[m_dsp.fifo_rd * 16 + m_dsp.fifo_wr] & A38_MBEMPTY; } | |
| 1413 | ||
| 1414 | /** | |
| 1415 | * @brief emulation of PROM a63 in the display schematics page 8 | |
| 1416 | * <PRE> | |
| 1417 | * The PROM's address lines are driven by a clock CLK, which is | |
| 1418 | * pixel clock / 24, and an inverted half-scanline signal H[1]'. | |
| 1419 | * | |
| 1420 | * It is 32x8 bits and its output bits (B) are connected to the | |
| 1421 | * signals, as well as its own address lines (A) through a latch | |
| 1422 | * of the type SN74774 like this: | |
| 1423 | * | |
| 1424 | * B 174 A others | |
| 1425 | * ------------------------ | |
| 1426 | * 0 5 - HBLANK | |
| 1427 | * 1 0 - HSYNC | |
| 1428 | * 2 4 0 | |
| 1429 | * 3 1 1 | |
| 1430 | * 4 3 2 | |
| 1431 | * 5 2 3 | |
| 1432 | * 6 - - SCANEND | |
| 1433 | * 7 - - HLCGATE | |
| 1434 | * ------------------------ | |
| 1435 | * H[1]' - 4 | |
| 1436 | * | |
| 1437 | * The display_state_machine() is called by the CPU at a rate of pixelclock/24, | |
| 1438 | * which happens to be very close to every 7th CPU micrcocycle. | |
| 1439 | * </PRE> | |
| 1440 | */ | |
| 1441 | UINT8* m_disp_a63; | |
| 1442 | ||
| 1443 | enum { | |
| 1444 | A63_HBLANK = (1 << 0), //!< PROM a63 B0 is latched as HBLANK signal | |
| 1445 | A63_HSYNC = (1 << 1), //!< PROM a63 B1 is latched as HSYNC signal | |
| 1446 | A63_A0 = (1 << 2), //!< PROM a63 B2 is the latched next address bit A0 | |
| 1447 | A63_A1 = (1 << 3), //!< PROM a63 B3 is the latched next address bit A1 | |
| 1448 | A63_A2 = (1 << 4), //!< PROM a63 B4 is the latched next address bit A2 | |
| 1449 | A63_A3 = (1 << 5), //!< PROM a63 B5 is the latched next address bit A3 | |
| 1450 | A63_SCANEND = (1 << 6), //!< PROM a63 B6 SCANEND signal, which resets the FIFO counters | |
| 1451 | A63_HLCGATE = (1 << 7) //!< PROM a63 B7 HLCGATE signal, which enables counting the HLC | |
| 1452 | }; | |
| 1453 | ||
| 1454 | /** | |
| 1455 | * @brief vertical blank and synch PROM | |
| 1456 | * | |
| 1457 | * PROM a66 is a 256x4 bit (type 3601), containing the vertical blank + synch. | |
| 1458 | * Address lines are driven by H[1] to H[128] of the the horz. line counters. | |
| 1459 | * The PROM is enabled whenever H[256] and H[512] are both 0. | |
| 1460 | * | |
| 1461 | * Q1 (001) is VSYNC for the odd field (with H1024=1) | |
| 1462 | * Q2 (002) is VSYNC for the even field (with H1024=0) | |
| 1463 | * Q3 (004) is VBLANK for the odd field (with H1024=1) | |
| 1464 | * Q4 (010) is VBLANK for the even field (with H1024=0) | |
| 1465 | */ | |
| 1466 | UINT8* m_disp_a66; | |
| 1467 | ||
| 1468 | enum { | |
| 1469 | A66_VSYNC_ODD = (1 << 0), | |
| 1470 | A66_VSYNC_EVEN = (1 << 1), | |
| 1471 | A66_VBLANK_ODD = (1 << 2), | |
| 1472 | A66_VBLANK_EVEN = (1 << 3) | |
| 1473 | }; | |
| 1474 | ||
| 1475 | //! test the VSYNC (vertical synchronisation) signal in PROM a66 being high | |
| 1476 | static inline bool A66_VSYNC_HI(UINT8 a, int hlc1024) { return a & (hlc1024 ? A66_VSYNC_ODD : A66_VSYNC_EVEN) ? false : true; } | |
| 1477 | //! test the VSYNC (vertical synchronisation) signal in PROM a66 being low | |
| 1478 | static inline bool A66_VSYNC_LO(UINT8 a, int hlc1024) { return a & (hlc1024 ? A66_VSYNC_ODD : A66_VSYNC_EVEN) ? true : false; } | |
| 1479 | //! test the VBLANK (vertical blanking) signal in PROM a66 being high | |
| 1480 | static inline bool A66_VBLANK_HI(UINT8 a, int hlc1024) { return a & (hlc1024 ? A66_VBLANK_ODD : A66_VBLANK_EVEN) ? false : true; } | |
| 1481 | //! test the VBLANK (vertical blanking) signal in PROM a66 being low | |
| 1482 | static inline bool A66_VBLANK_LO(UINT8 a, int hlc1024) { return a & (hlc1024 ? A66_VBLANK_ODD : A66_VBLANK_EVEN) ? true : false; } | |
| 1483 | ||
| 1484 | //! screen bitmap | |
| 1485 | bitmap_ind16* m_displ_bitmap; | |
| 1486 | ||
| 1487 | //! update a word in the screen bitmap | |
| 1488 | void update_bitmap_word(int x, int y, UINT16 word); | |
| 1489 | ||
| 1490 | //! unload the next word from the display FIFO and shift it to the screen | |
| 1491 | void unload_word(); | |
| 1492 | ||
| 1493 | /** | |
| 1494 | * @brief function called by the CPU to enter the next display state | |
| 1495 | * | |
| 1496 | * There are 32 states per scanline and 875 scanlines per frame. | |
| 1497 | * | |
| 1498 | * @param arg the current m_disp_a63 PROM address | |
| 1499 | * @return next state of the display state machine | |
| 1500 | */ | |
| 1501 | void display_state_machine(); | |
| 1502 | ||
| 1503 | //! branch on the evenfield flip-flop | |
| 1504 | void f2_late_evenfield(void); | |
| 1505 | ||
| 1506 | //! initialize the display context | |
| 1507 | void init_disp(); | |
| 1508 | //! deinitialize the display context | |
| 1509 | void exit_disp(); | |
| 1510 | ||
| 1511 | // ************************************************ | |
| 1512 | // memory stuff | |
| 1513 | // ************************************************ | |
| 1514 | ||
| 1515 | enum { | |
| 1516 | ALTO2_MEM_NONE, | |
| 1517 | ALTO2_MEM_ODD = (1 << 0), | |
| 1518 | ALTO2_MEM_RAM = (1 << 1), | |
| 1519 | ALTO2_MEM_NIRVANA = (1 << 2) | |
| 1520 | }; | |
| 1521 | ||
| 1522 | struct { | |
| 1523 | UINT32* ram; //!< main memory organized as double-words | |
| 1524 | UINT8* hpb; //!< Hamming Code bits (6) and Parity bits (1) per double word | |
| 1525 | UINT32 mar; //!< memory address register | |
| 1526 | UINT32 rmdd; //!< read memory data double-word | |
| 1527 | UINT32 wmdd; //!< write memory data double-word | |
| 1528 | UINT16 md; //!< memory data register | |
| 1529 | UINT64 cycle; //!< cycle when the memory address register was loaded | |
| 1530 | ||
| 1531 | /** | |
| 1532 | * @brief memory access under the way if non-zero | |
| 1533 | * 0: no memory access (MEM_NONE) | |
| 1534 | * 1: invalid | |
| 1535 | * 2: memory access even word (MEM_RAM) | |
| 1536 | * 3: memory access odd word (MEM_RAM | MEM_ODD) | |
| 1537 | * 4: refresh even word (MEM_REFRESH) | |
| 1538 | * 5: refresh odd word (MEM_REFRESH | MEM_ODD) | |
| 1539 | */ | |
| 1540 | int access; | |
| 1541 | int error; //!< non-zero after a memory error was detected | |
| 1542 | int mear; //!< memory error address register | |
| 1543 | UINT16 mesr; //!< memory error status register | |
| 1544 | UINT16 mecr; //!< memory error control register | |
| 1545 | } m_mem; | |
| 1546 | ||
| 1547 | /** | |
| 1548 | * @brief check if memory address register load is yet possible | |
| 1549 | * suspend if accessing RAM and previous MAR<- was less than 5 cycles ago | |
| 1550 | * | |
| 1551 | * 1. MAR<- ANY | |
| 1552 | * 2. REQUIRED | |
| 1553 | * 3. MD<- whatever | |
| 1554 | * 4. SUSPEND | |
| 1555 | * 5. SUSPEND | |
| 1556 | * 6. MAR<- ANY | |
| 1557 | * | |
| 1558 | * @result returns 0, if memory address can be loaded | |
| 1559 | */ | |
| 1560 | inline bool check_mem_load_mar_stall(UINT8 rsel) { | |
| 1561 | return (ALTO2_MEM_NONE == m_mem.access ? false : cycle() < m_mem.cycle+5); | |
| 1562 | } | |
| 1563 | ||
| 1564 | /** | |
| 1565 | * @brief check if memory read is yet possible | |
| 1566 | * MAR<- = cycle #1, earliest read at cycle #5, i.e. + 4 | |
| 1567 | * | |
| 1568 | * 1. MAR<- ANY | |
| 1569 | * 2. REQUIRED | |
| 1570 | * 3. SUSPEND | |
| 1571 | * 4. SUSPEND | |
| 1572 | * 5. whereever <-MD | |
| 1573 | * | |
| 1574 | * @result returns 0, if memory can be read without wait cycle | |
| 1575 | */ | |
| 1576 | inline bool check_mem_read_stall() { | |
| 1577 | return (ALTO2_MEM_NONE == m_mem.access ? false : cycle() < m_mem.cycle+4); | |
| 1578 | } | |
| 1579 | ||
| 1580 | /** | |
| 1581 | * @brief check if memory write is yet possible | |
| 1582 | * MAR<- = cycle #1, earliest write at cycle #3, i.e. + 2 | |
| 1583 | * | |
| 1584 | * 1. MAR<- ANY | |
| 1585 | * 2. REQUIRED | |
| 1586 | * 3. OPTIONAL | |
| 1587 | * 4. MD<- whatever | |
| 1588 | * | |
| 1589 | * @result returns 0, if memory can be written without wait cycle | |
| 1590 | */ | |
| 1591 | inline bool check_mem_write_stall() { | |
| 1592 | return (ALTO2_MEM_NONE == m_mem.access ? false : cycle() < m_mem.cycle+2); | |
| 1593 | } | |
| 1594 | ||
| 1595 | //! memory error address register read | |
| 1596 | DECLARE_READ16_MEMBER( mear_r ); | |
| 1597 | ||
| 1598 | //! memory error status register read | |
| 1599 | DECLARE_READ16_MEMBER( mesr_r ); | |
| 1600 | ||
| 1601 | //! memory error status register write (clear) | |
| 1602 | DECLARE_WRITE16_MEMBER( mesr_w ); | |
| 1603 | ||
| 1604 | //! memory error control register read | |
| 1605 | DECLARE_READ16_MEMBER( mecr_r ); | |
| 1606 | ||
| 1607 | //! memory error control register write | |
| 1608 | DECLARE_WRITE16_MEMBER( mecr_w ); | |
| 1609 | ||
| 1610 | //! read or write a memory double-word and caluclate its Hamming code | |
| 1611 | UINT32 hamming_code(int write, UINT32 dw_addr, UINT32 dw_data); | |
| 1612 | ||
| 1613 | //! load the memory address register with some value | |
| 1614 | void load_mar(UINT8 rsel, UINT32 addr); | |
| 1615 | ||
| 1616 | //! read memory or memory mapped I/O from the address in mar to md | |
| 1617 | UINT16 read_mem(); | |
| 1618 | ||
| 1619 | //! write memory or memory mapped I/O from md to the address in mar | |
| 1620 | void write_mem(UINT16 data); | |
| 1621 | ||
| 1622 | //! debugger interface to read memory | |
| 1623 | UINT16 debug_read_mem(UINT32 addr); | |
| 1624 | ||
| 1625 | //! debugger interface to write memory | |
| 1626 | void debug_write_mem(UINT32 addr, UINT16 data); | |
| 1627 | ||
| 1628 | #if ALTO2_DEBUG | |
| 1629 | void watch_write(UINT32 addr, UINT32 data); | |
| 1630 | void watch_read(UINT32 addr, UINT32 data); | |
| 1631 | #endif | |
| 1632 | void init_memory(); //!< initialize the memory system | |
| 1633 | void exit_memory(); //!< deinitialize the memory system | |
| 1634 | ||
| 1635 | // ************************************************ | |
| 1636 | // emulator task | |
| 1637 | // ************************************************ | |
| 1638 | struct { | |
| 1639 | UINT16 ir; //!< emulator instruction register | |
| 1640 | UINT8 skip; //!< emulator skip | |
| 1641 | UINT8 cy; //!< emulator carry | |
| 1642 | } m_emu; | |
| 1643 | void bs_early_emu_disp(); //!< bus source: drive bus by IR[8-15], possibly sign extended | |
| 1644 | void f1_early_emu_block(); //!< F1 func: block task | |
| 1645 | void f1_late_emu_load_rmr(); //!< F1 func: load the reset mode register | |
| 1646 | void f1_late_emu_load_esrb(); //!< F1 func: load the extended S register bank from BUS[12-14] | |
| 1647 | void f1_early_rsnf(); //!< F1 func: drive the bus from the Ethernet node ID | |
| 1648 | void f1_early_startf(); //!< F1 func: defines commands for for I/O hardware, including Ethernet | |
| 1649 | void f2_late_busodd(); //!< F2 func: branch on odd bus | |
| 1650 | void f2_late_magic(); //!< F2 func: shift and use T | |
| 1651 | void f2_early_load_dns(); //!< F2 func: modify RESELECT with DstAC = (3 - IR[3-4]) | |
| 1652 | void f2_late_load_dns(); //!< F2 func: do novel shifts | |
| 1653 | void f2_early_acdest(); //!< F2 func: modify RSELECT with DstAC = (3 - IR[3-4]) | |
| 1654 | void bitblt_info(); //!< debug bitblt opcode | |
| 1655 | void f2_late_load_ir(); //!< F2 func: load instruction register IR and branch on IR[0,5-7] | |
| 1656 | void f2_late_idisp(); //!< F2 func: branch on: arithmetic IR_SH, others PROM ctl2k_u3[IR[1-7]] | |
| 1657 | void f2_early_acsource(); //!< F2 func: modify RSELECT with SrcAC = (3 - IR[1-2]) | |
| 1658 | void f2_late_acsource(); //!< F2 func: branch on arithmetic IR_SH, others PROM ctl2k_u3[IR[1-7]] | |
| 1659 | void init_emu(int task); //!< 000 initialize emulator task | |
| 1660 | void exit_emu(); //!< deinitialize emulator task | |
| 1661 | ||
| 1662 | // ************************************************ | |
| 1663 | // ksec task | |
| 1664 | // ************************************************ | |
| 1665 | void f1_early_ksec_block(void); | |
| 1666 | void init_ksec(int task); //!< 004 initialize disk sector task | |
| 1667 | void exit_ksec(); | |
| 1668 | ||
| 1669 | // ************************************************ | |
| 1670 | // ethernet task | |
| 1671 | // ************************************************ | |
| 1672 | /** | |
| 1673 | * @brief BPROMs P3601-1; 256x4; enet.a41 "PE1" and enet.a42 "PE2" | |
| 1674 | * | |
| 1675 | * Phase encoder | |
| 1676 | * | |
| 1677 | * a41: P3601-1; 256x4; "PE1" | |
| 1678 | * a42: P3601-1; 256x4; "PE2" | |
| 1679 | * | |
| 1680 | * PE1/PE2 inputs | |
| 1681 | * ---------------- | |
| 1682 | * A0 (5) OUTGO | |
| 1683 | * A1 (6) XDATA | |
| 1684 | * A2 (7) OSDATAG | |
| 1685 | * A3 (4) XCLOCK | |
| 1686 | * A4 (3) OCNTR0 | |
| 1687 | * A5 (2) OCNTR1 | |
| 1688 | * A6 (1) OCNTR2 | |
| 1689 | * A7 (15) OCNTR3 | |
| 1690 | * | |
| 1691 | * PE1 outputs | |
| 1692 | * ---------------- | |
| 1693 | * D0 (12) OCNTR0 | |
| 1694 | * D1 (11) OCNTR1 | |
| 1695 | * D2 (10) OCNTR2 | |
| 1696 | * D3 (9) OCNTR3 | |
| 1697 | * | |
| 1698 | * PE2 outputs | |
| 1699 | * ---------------- | |
| 1700 | * D0 (12) n.c. | |
| 1701 | * D1 (11) to OSLOAD flip flop J and K' | |
| 1702 | * D2 (10) XDATA | |
| 1703 | * D3 (9) XCLOCK | |
| 1704 | */ | |
| 1705 | UINT8* m_ether_a41; | |
| 1706 | UINT8* m_ether_a42; | |
| 1707 | ||
| 1708 | /** | |
| 1709 | * @brief BPROM; P3601-1; 265x4 enet.a49 "AFIFO" | |
| 1710 | * | |
| 1711 | * Perhaps try with the contents of the display FIFO, as it is | |
| 1712 | * the same type and the display FIFO has the same size. | |
| 1713 | * | |
| 1714 | * FIFO control | |
| 1715 | * | |
| 1716 | * a49: P3601-1; 256x4; "AFIFO" | |
| 1717 | * | |
| 1718 | * inputs | |
| 1719 | * ---------------- | |
| 1720 | * A0 (5) fifo_wr[0] | |
| 1721 | * A1 (6) fifo_wr[1] | |
| 1722 | * A2 (7) fifo_wr[2] | |
| 1723 | * A3 (4) fifo_wr[3] | |
| 1724 | * A4 (3) fifo_rd[0] | |
| 1725 | * A5 (2) fifo_rd[1] | |
| 1726 | * A6 (1) fifo_rd[2] | |
| 1727 | * A7 (15) fifo_rd[3] | |
| 1728 | * | |
| 1729 | * outputs active low | |
| 1730 | * ---------------------------- | |
| 1731 | * D0 (12) BE' (buffer empty) | |
| 1732 | * D1 (11) BNE' (buffer next empty ?) | |
| 1733 | * D2 (10) BNNE' (buffer next next empty ?) | |
| 1734 | * D3 (9) BF' (buffer full) | |
| 1735 | */ | |
| 1736 | UINT8* m_ether_a49; | |
| 1737 | ||
| 1738 | static const int m_duckbreath_sec = 15; //!< send duckbreath every 15 seconds | |
| 1739 | ||
| 1740 | struct { | |
| 1741 | UINT16 fifo[ALTO2_ETHER_FIFO_SIZE]; //!< FIFO buffer | |
| 1742 | UINT16 fifo_rd; //!< FIFO input pointer | |
| 1743 | UINT16 fifo_wr; //!< FIFO output pointer | |
| 1744 | UINT16 status; //!< status word | |
| 1745 | UINT32 rx_crc; //!< receiver CRC | |
| 1746 | UINT32 tx_crc; //!< transmitter CRC | |
| 1747 | UINT32 rx_count; //!< received words count | |
| 1748 | UINT32 tx_count; //!< transmitted words count | |
| 1749 | emu_timer* tx_timer; //!< transmitter timer | |
| 1750 | int duckbreath; //!< if non-zero, interval in seconds at which to broadcast the duckbreath | |
| 1751 | } m_eth; | |
| 1752 | ||
| 1753 | TIMER_CALLBACK_MEMBER( rx_duckbreath ); //!< HACK: pull the next word from the duckbreath in the fifo | |
| 1754 | TIMER_CALLBACK_MEMBER( tx_packet ); //!< transmit data from the FIFO to <nirvana for now> | |
| 1755 | void eth_wakeup(); //!< check for the various reasons to wakeup the Ethernet task | |
| 1756 | void eth_startf(); //!< start input or output depending on m_bus | |
| 1757 | void bs_early_eidfct(); //!< bus source: Ethernet input data function | |
| 1758 | void f1_early_eth_block(); //!< F1 func: block the Ether task | |
| 1759 | void f1_early_eilfct(); //!< F1 func: Ethernet input look function | |
| 1760 | void f1_early_epfct(); //!< F1 func: Ethernet post function | |
| 1761 | void f1_late_ewfct(); //!< F1 func: Ethernet countdown wakeup function | |
| 1762 | void f2_late_eodfct(); //!< F2 func: Ethernet output data function | |
| 1763 | void f2_late_eosfct(); //!< F2 func: Ethernet output start function | |
| 1764 | void f2_late_erbfct(); //!< F2 func: Ethernet reset branch function | |
| 1765 | void f2_late_eefct(); //!< F2 func: Ethernet end of transmission function | |
| 1766 | void f2_late_ebfct(); //!< F2 func: Ethernet branch function | |
| 1767 | void f2_late_ecbfct(); //!< F2 func: Ethernet countdown branch function | |
| 1768 | void f2_late_eisfct(); //!< F2 func: Ethernet input start function | |
| 1769 | void activate_eth(); //!< called by the CPU when the Ethernet task becomes active | |
| 1770 | void init_ether(int task); //!< 007 initialize ethernet task | |
| 1771 | void exit_ether(); //!< deinitialize ethernet task | |
| 1772 | ||
| 1773 | // ************************************************ | |
| 1774 | // memory refresh task | |
| 1775 | // ************************************************ | |
| 1776 | void f1_early_mrt_block(); //!< F1 func: block the display word task | |
| 1777 | void activate_mrt(); //!< called by the CPU when MRT becomes active | |
| 1778 | void init_mrt(int task); //!< 010 initialize memory refresh task | |
| 1779 | void exit_mrt(); //!< deinitialize memory refresh task | |
| 1780 | ||
| 1781 | // ************************************************ | |
| 1782 | // display word task | |
| 1783 | // ************************************************ | |
| 1784 | void f1_early_dwt_block(); //!< F1 func: block the display word task | |
| 1785 | void f2_dwt_load_ddr_1(); //!< F2 func: load the display data register | |
| 1786 | void init_dwt(int task); //!< 011 initialize display word task | |
| 1787 | void exit_dwt(); //!< deinitialize display word task | |
| 1788 | ||
| 1789 | // ************************************************ | |
| 1790 | // cursor task | |
| 1791 | // ************************************************ | |
| 1792 | void f1_early_curt_block(); //!< f1_curt_block early: disable the cursor task and set the curt_blocks flag | |
| 1793 | void f2_late_load_xpreg(); //!< f2_load_xpreg late: load the x position register from BUS[6-15] | |
| 1794 | void f2_late_load_csr(); //!< f2_load_csr late: load the cursor shift register from BUS[0-15] | |
| 1795 | void activate_curt(); //!< curt_activate: called by the CPU when the cursor task becomes active | |
| 1796 | void init_curt(int task); //!< 012 initialize cursor task | |
| 1797 | void exit_curt(); //!< deinitialize cursor task | |
| 1798 | ||
| 1799 | // ************************************************ | |
| 1800 | // display horizontal task | |
| 1801 | // ************************************************ | |
| 1802 | void f1_early_dht_block(); //!< F1 func: disable the display word task | |
| 1803 | void f2_late_dht_setmode(); //!< F2 func: set the next scanline's mode inverse and half clock and branch | |
| 1804 | void activate_dht(); //!< called by the CPU when the display horizontal task becomes active | |
| 1805 | void init_dht(int task); //!< 013 initialize display horizontal task | |
| 1806 | void exit_dht(); //!< deinitialize display horizontal task | |
| 1807 | ||
| 1808 | // ************************************************ | |
| 1809 | // display vertical task | |
| 1810 | // ************************************************ | |
| 1811 | void f1_early_dvt_block(); //!< F1 func: disable the display word task | |
| 1812 | void activate_dvt(); //!< called by the CPU when the display vertical task becomes active | |
| 1813 | void init_dvt(int task); //!< 014 initialize display vertical task | |
| 1814 | void exit_dvt(); //!< deinitialize display vertical task | |
| 1815 | ||
| 1816 | // ************************************************ | |
| 1817 | // parity task | |
| 1818 | // ************************************************ | |
| 1819 | void activate_part(); | |
| 1820 | void init_part(int task); //!< 015 initialize parity task | |
| 1821 | void exit_part(); //!< deinitialize parity task | |
| 1822 | ||
| 1823 | // ************************************************ | |
| 1824 | // disk word task | |
| 1825 | // ************************************************ | |
| 1826 | void f1_early_kwd_block(); //!< F1 func: disable the disk word task | |
| 1827 | void init_kwd(int task); //!< 016 initialize disk word task | |
| 1828 | void exit_kwd(); //!< deinitialize disk word task | |
| 944 | #include "a2ram.h" | |
| 945 | #include "a2hw.h" | |
| 946 | #include "a2kbd.h" | |
| 947 | #include "a2mouse.h" | |
| 948 | #include "a2disk.h" | |
| 949 | #include "a2disp.h" | |
| 950 | #include "a2mem.h" | |
| 951 | #include "a2emu.h" | |
| 952 | #include "a2ksec.h" | |
| 953 | #include "a2ether.h" | |
| 954 | #include "a2mrt.h" | |
| 955 | #include "a2dwt.h" | |
| 956 | #include "a2curt.h" | |
| 957 | #include "a2dht.h" | |
| 958 | #include "a2dvt.h" | |
| 959 | #include "a2part.h" | |
| 960 | #include "a2dwt.h" | |
| 961 | #include "a2kwd.h" | |
| 1829 | 962 | }; |
| 1830 | 963 | |
| 1831 | 964 | extern const device_type ALTO2; |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII ethernet task (ETHER) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #define ALTO2_ETHER_FIFO_SIZE 16 //!< number of words in the ethernet FIFO | |
| 13 | ||
| 14 | #else // ALTO2_DEFINE_CONSTANTS | |
| 15 | #ifndef _A2ETHER_H_ | |
| 16 | #define _A2ETHER_H_ | |
| 17 | //! BUS source for ethernet task | |
| 18 | enum { | |
| 19 | bs_ether_eidfct = bs_task_3 //!< ethernet task: Ethernet input data function | |
| 20 | }; | |
| 21 | ||
| 22 | //! F1 functions for ethernet task | |
| 23 | enum { | |
| 24 | f1_ether_eilfct = f1_task_13, //!< f1 (1011): ethernet input look function | |
| 25 | f1_ether_epfct = f1_task_14, //!< f1 (1100): ethernet post function | |
| 26 | f1_ether_ewfct = f1_task_15 //!< f1 (1101): ethernet countdown wakeup function | |
| 27 | }; | |
| 28 | ||
| 29 | //! F2 functions for ethernet task | |
| 30 | enum { | |
| 31 | f2_ether_eodfct = f2_task_10, //!< f2 (1000): ethernet output data function | |
| 32 | f2_ether_eosfct = f2_task_11, //!< f2 (1001): ethernet output start function | |
| 33 | f2_ether_erbfct = f2_task_12, //!< f2 (1010): ethernet reset branch function | |
| 34 | f2_ether_eefct = f2_task_13, //!< f2 (1011): ethernet end of transmission function | |
| 35 | f2_ether_ebfct = f2_task_14, //!< f2 (1100): ethernet branch function | |
| 36 | f2_ether_ecbfct = f2_task_15, //!< f2 (1101): ethernet countdown branch function | |
| 37 | f2_ether_eisfct = f2_task_16 //!< f2 (1110): ethernet input start function | |
| 38 | //!< f2 (1111): undefined | |
| 39 | }; | |
| 40 | ||
| 41 | /** | |
| 42 | * @brief BPROMs P3601-1; 256x4; enet.a41 "PE1" and enet.a42 "PE2" | |
| 43 | * | |
| 44 | * Phase encoder | |
| 45 | * | |
| 46 | * a41: P3601-1; 256x4; "PE1" | |
| 47 | * a42: P3601-1; 256x4; "PE2" | |
| 48 | * | |
| 49 | * PE1/PE2 inputs | |
| 50 | * ---------------- | |
| 51 | * A0 (5) OUTGO | |
| 52 | * A1 (6) XDATA | |
| 53 | * A2 (7) OSDATAG | |
| 54 | * A3 (4) XCLOCK | |
| 55 | * A4 (3) OCNTR0 | |
| 56 | * A5 (2) OCNTR1 | |
| 57 | * A6 (1) OCNTR2 | |
| 58 | * A7 (15) OCNTR3 | |
| 59 | * | |
| 60 | * PE1 outputs | |
| 61 | * ---------------- | |
| 62 | * D0 (12) OCNTR0 | |
| 63 | * D1 (11) OCNTR1 | |
| 64 | * D2 (10) OCNTR2 | |
| 65 | * D3 (9) OCNTR3 | |
| 66 | * | |
| 67 | * PE2 outputs | |
| 68 | * ---------------- | |
| 69 | * D0 (12) n.c. | |
| 70 | * D1 (11) to OSLOAD flip flop J and K' | |
| 71 | * D2 (10) XDATA | |
| 72 | * D3 (9) XCLOCK | |
| 73 | */ | |
| 74 | UINT8* m_ether_a41; | |
| 75 | UINT8* m_ether_a42; | |
| 76 | ||
| 77 | /** | |
| 78 | * @brief BPROM; P3601-1; 265x4 enet.a49 "AFIFO" | |
| 79 | * | |
| 80 | * Perhaps try with the contents of the display FIFO, as it is | |
| 81 | * the same type and the display FIFO has the same size. | |
| 82 | * | |
| 83 | * FIFO control | |
| 84 | * | |
| 85 | * a49: P3601-1; 256x4; "AFIFO" | |
| 86 | * | |
| 87 | * inputs | |
| 88 | * ---------------- | |
| 89 | * A0 (5) fifo_wr[0] | |
| 90 | * A1 (6) fifo_wr[1] | |
| 91 | * A2 (7) fifo_wr[2] | |
| 92 | * A3 (4) fifo_wr[3] | |
| 93 | * A4 (3) fifo_rd[0] | |
| 94 | * A5 (2) fifo_rd[1] | |
| 95 | * A6 (1) fifo_rd[2] | |
| 96 | * A7 (15) fifo_rd[3] | |
| 97 | * | |
| 98 | * outputs active low | |
| 99 | * ---------------------------- | |
| 100 | * D0 (12) BE' (buffer empty) | |
| 101 | * D1 (11) BNE' (buffer next empty ?) | |
| 102 | * D2 (10) BNNE' (buffer next next empty ?) | |
| 103 | * D3 (9) BF' (buffer full) | |
| 104 | */ | |
| 105 | UINT8* m_ether_a49; | |
| 106 | ||
| 107 | static const int m_duckbreath_sec = 15; //!< send duckbreath every 15 seconds | |
| 108 | ||
| 109 | struct { | |
| 110 | UINT16 fifo[ALTO2_ETHER_FIFO_SIZE]; //!< FIFO buffer | |
| 111 | UINT16 fifo_rd; //!< FIFO input pointer | |
| 112 | UINT16 fifo_wr; //!< FIFO output pointer | |
| 113 | UINT16 status; //!< status word | |
| 114 | UINT32 rx_crc; //!< receiver CRC | |
| 115 | UINT32 tx_crc; //!< transmitter CRC | |
| 116 | UINT32 rx_count; //!< received words count | |
| 117 | UINT32 tx_count; //!< transmitted words count | |
| 118 | emu_timer* tx_timer; //!< transmitter timer | |
| 119 | int duckbreath; //!< if non-zero, interval in seconds at which to broadcast the duckbreath | |
| 120 | } m_eth; | |
| 121 | ||
| 122 | TIMER_CALLBACK_MEMBER( rx_duckbreath ); //!< HACK: pull the next word from the duckbreath in the fifo | |
| 123 | TIMER_CALLBACK_MEMBER( tx_packet ); //!< transmit data from the FIFO to <nirvana for now> | |
| 124 | void eth_wakeup(); //!< check for the various reasons to wakeup the Ethernet task | |
| 125 | void eth_startf(); //!< start input or output depending on m_bus | |
| 126 | void bs_early_eidfct(); //!< bus source: Ethernet input data function | |
| 127 | void f1_early_eth_block(); //!< F1 func: block the Ether task | |
| 128 | void f1_early_eilfct(); //!< F1 func: Ethernet input look function | |
| 129 | void f1_early_epfct(); //!< F1 func: Ethernet post function | |
| 130 | void f1_late_ewfct(); //!< F1 func: Ethernet countdown wakeup function | |
| 131 | void f2_late_eodfct(); //!< F2 func: Ethernet output data function | |
| 132 | void f2_late_eosfct(); //!< F2 func: Ethernet output start function | |
| 133 | void f2_late_erbfct(); //!< F2 func: Ethernet reset branch function | |
| 134 | void f2_late_eefct(); //!< F2 func: Ethernet end of transmission function | |
| 135 | void f2_late_ebfct(); //!< F2 func: Ethernet branch function | |
| 136 | void f2_late_ecbfct(); //!< F2 func: Ethernet countdown branch function | |
| 137 | void f2_late_eisfct(); //!< F2 func: Ethernet input start function | |
| 138 | void activate_eth(); //!< called by the CPU when the Ethernet task becomes active | |
| 139 | void init_ether(int task); //!< 007 initialize ethernet task | |
| 140 | void exit_ether(); //!< deinitialize ethernet task | |
| 141 | #endif // _A2ETHER_H_ | |
| 142 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII cursor task | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII memory mapped I/O hardware | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII display horizontal task | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /***************************************************************************** |
| 2 | 2 | * |
| 3 | * | |
| 3 | * Xerox AltoII PROM loading and decoding | |
| 4 | 4 | * |
| 5 | * Copyright | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | 6 | * |
| 7 | 7 | * Licenses: MAME, GPLv2 |
| 8 | 8 | * |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII cursor task (CURT) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2CURT_H_ | |
| 14 | #define _A2CURT_H_ | |
| 15 | ||
| 16 | //! F2 functions for cursor task | |
| 17 | enum { | |
| 18 | f2_curt_load_xpreg = f2_task_10, //!< f2 10: load x position register | |
| 19 | f2_curt_load_csr = f2_task_11, //!< f2 11: load cursor shift register | |
| 20 | }; | |
| 21 | ||
| 22 | void f1_early_curt_block(); //!< f1_curt_block early: disable the cursor task and set the curt_blocks flag | |
| 23 | void f2_late_load_xpreg(); //!< f2_load_xpreg late: load the x position register from BUS[6-15] | |
| 24 | void f2_late_load_csr(); //!< f2_load_csr late: load the cursor shift register from BUS[0-15] | |
| 25 | void activate_curt(); //!< curt_activate: called by the CPU when the cursor task becomes active | |
| 26 | void init_curt(int task = task_curt); //!< initialize cursor task | |
| 27 | void exit_curt(); //!< deinitialize cursor task | |
| 28 | #endif // _A2CURT_H_ | |
| 29 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r26306 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII memory mapped i/o stuff (HW) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 1 | 13 | #ifndef _A2HW_H_ |
| 2 | 14 | #define _A2HW_H_ |
| 15 | //! miscellaneous hardware registers in the memory mapped I/O range | |
| 16 | struct { | |
| 17 | UINT16 eia; //!< the EIA port at 0177001 | |
| 18 | UINT16 utilout; //!< the UTILOUT port at 0177016 (active-low outputs) | |
| 19 | UINT16 xbus[4]; //!< the XBUS port at 0177020 to 0177023 | |
| 20 | UINT16 utilin; //!< the UTILIN port at 0177030 to 0177033 (same value on all addresses) | |
| 21 | } m_hw; | |
| 3 | 22 | |
| 4 | // ************************************************ | |
| 5 | // hardware (memory mapped i/o stuff) | |
| 6 | // ************************************************ | |
| 7 | 23 | DECLARE_READ16_MEMBER ( pprdy_r ); //!< read UTILIN[0] printer paper ready bit |
| 8 | 24 | DECLARE_READ16_MEMBER ( pcheck_r ); //!< read UTILIN[1] printer check bit |
| 9 | 25 | DECLARE_READ16_MEMBER ( unused2_r ); //!< read UTILIN[2] unused bit |
| r26306 | r26307 | |
| 39 | 55 | DECLARE_WRITE16_MEMBER( mouse_yellow_w ); //!< write UTILIN[15] mouse yellow button bit |
| 40 | 56 | DECLARE_WRITE16_MEMBER( mouse_buttons_w ); //!< write UTILIN[13-15] mouse buttons bits |
| 41 | 57 | |
| 42 | /** @brief miscellaneous hardware registers in the memory mapped I/O range */ | |
| 43 | struct { | |
| 44 | UINT16 eia; //!< the EIA port at 0177001 | |
| 45 | UINT16 utilout; //!< the UTILOUT port at 0177016 (active-low outputs) */ | |
| 46 | UINT16 xbus[4]; //!< the XBUS port at 0177020 to 0177023 | |
| 47 | UINT16 utilin; //!< the UTILIN port at 0177030 to 0177033 (same value on all addresses) | |
| 48 | } m_hw; | |
| 49 | ||
| 50 | DECLARE_READ16_MEMBER( utilin_r ); //!< read an UTILIN address | |
| 51 | DECLARE_READ16_MEMBER( utilout_r ); //!< read the UTILOUT address | |
| 58 | DECLARE_READ16_MEMBER ( utilin_r ); //!< read an UTILIN address | |
| 59 | DECLARE_READ16_MEMBER ( utilout_r ); //!< read the UTILOUT address | |
| 52 | 60 | DECLARE_WRITE16_MEMBER( utilout_w ); //!< write the UTILOUT address |
| 53 | DECLARE_READ16_MEMBER( xbus_r ); //!< read an XBUS address | |
| 61 | DECLARE_READ16_MEMBER ( xbus_r ); //!< read an XBUS address | |
| 54 | 62 | DECLARE_WRITE16_MEMBER( xbus_w ); //!< write an XBUS address (?) |
| 63 | ||
| 55 | 64 | void init_hw(); //!< initialize miscellaneous hardware |
| 56 | 65 | void exit_hw(); //!< deinitialize miscellaneous hardware |
| 57 | ||
| 58 | #endif // _A2HW_H_ | |
| 66 | #endif // _A2HW_H_ | |
| 67 | #endif // ALTO2_DEFINE_CONSTANTS |
| r0 | r26307 | |
|---|---|---|
| 1 | /***************************************************************************** | |
| 2 | * | |
| 3 | * Xerox AltoII display horizontal task (DHT) | |
| 4 | * | |
| 5 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 6 | * | |
| 7 | * Licenses: MAME, GPLv2 | |
| 8 | * | |
| 9 | *****************************************************************************/ | |
| 10 | #ifdef ALTO2_DEFINE_CONSTANTS | |
| 11 | ||
| 12 | #else // ALTO2_DEFINE_CONSTANTS | |
| 13 | #ifndef _A2DHT_H_ | |
| 14 | #define _A2DHT_H_ | |
| 15 | ||
| 16 | //! F2 functions for display horizontal task | |
| 17 | enum { | |
| 18 | f2_dht_evenfield = f2_task_10, //!< f2 10: load even field | |
| 19 | f2_dht_setmode = f2_task_11, //!< f2 11: set mode | |
| 20 | }; | |
| 21 | ||
| 22 | void f1_early_dht_block(); //!< F1 func: disable the display word task | |
| 23 | void f2_late_dht_setmode(); //!< F2 func: set the next scanline's mode inverse and half clock and branch | |
| 24 | void activate_dht(); //!< called by the CPU when the display horizontal task becomes active | |
| 25 | void init_dht(int task = task_dht); //!< initialize display horizontal task | |
| 26 | void exit_dht(); //!< deinitialize display horizontal task | |
| 27 | #endif // _A2DHT_H_ | |
| 28 | #endif // ALTO2_DEFINE_CONSTANTS |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r26306 | r26307 | |
|---|---|---|
| 2303 | 2303 | $(CPUSRC)/alto2/alto2cpu.h |
| 2304 | 2304 | |
| 2305 | 2305 | $(CPUOBJ)/alto2/a2disk.o: $(CPUSRC)/alto2/a2disk.c \ |
| 2306 | $(CPUSRC)/alto2/a2disk.h \ | |
| 2306 | 2307 | $(CPUSRC)/alto2/alto2cpu.h |
| 2307 | 2308 | |
| 2308 | 2309 | $(CPUOBJ)/alto2/a2disp.o: $(CPUSRC)/alto2/a2disp.c \ |
| 2310 | $(CPUSRC)/alto2/a2disp.h \ | |
| 2309 | 2311 | $(CPUSRC)/alto2/alto2cpu.h |
| 2310 | 2312 | |
| 2311 | 2313 | $(CPUOBJ)/alto2/a2curt.o: $(CPUSRC)/alto2/a2curt.c \ |
| 2314 | $(CPUSRC)/alto2/a2curt.h \ | |
| 2312 | 2315 | $(CPUSRC)/alto2/alto2cpu.h |
| 2313 | 2316 | |
| 2314 | 2317 | $(CPUOBJ)/alto2/a2dht.o: $(CPUSRC)/alto2/a2dht.c \ |
| 2318 | $(CPUSRC)/alto2/a2dht.h \ | |
| 2315 | 2319 | $(CPUSRC)/alto2/alto2cpu.h |
| 2316 | 2320 | |
| 2317 | 2321 | $(CPUOBJ)/alto2/a2dvt.o: $(CPUSRC)/alto2/a2dvt.c \ |
| 2322 | $(CPUSRC)/alto2/a2dvt.h \ | |
| 2318 | 2323 | $(CPUSRC)/alto2/alto2cpu.h |
| 2319 | 2324 | |
| 2320 | 2325 | $(CPUOBJ)/alto2/a2dwt.o: $(CPUSRC)/alto2/a2dwt.c \ |
| 2326 | $(CPUSRC)/alto2/a2dwt.h \ | |
| 2321 | 2327 | $(CPUSRC)/alto2/alto2cpu.h |
| 2322 | 2328 | |
| 2323 | 2329 | $(CPUOBJ)/alto2/a2emu.o: $(CPUSRC)/alto2/a2emu.c \ |
| 2330 | $(CPUSRC)/alto2/a2emu.h \ | |
| 2324 | 2331 | $(CPUSRC)/alto2/alto2cpu.h |
| 2325 | 2332 | |
| 2326 | 2333 | $(CPUOBJ)/alto2/a2ether.o: $(CPUSRC)/alto2/a2ether.c \ |
| 2334 | $(CPUSRC)/alto2/a2ether.h \ | |
| 2327 | 2335 | $(CPUSRC)/alto2/alto2cpu.h |
| 2328 | 2336 | |
| 2329 | 2337 | $(CPUOBJ)/alto2/a2hw.o: $(CPUSRC)/alto2/a2hw.c \ |
| 2338 | $(CPUSRC)/alto2/a2hw.h \ | |
| 2330 | 2339 | $(CPUSRC)/alto2/alto2cpu.h |
| 2331 | 2340 | |
| 2332 | 2341 | $(CPUOBJ)/alto2/a2kbd.o: $(CPUSRC)/alto2/a2kbd.c \ |
| 2342 | $(CPUSRC)/alto2/a2kbd.h \ | |
| 2333 | 2343 | $(CPUSRC)/alto2/alto2cpu.h |
| 2334 | 2344 | |
| 2335 | 2345 | $(CPUOBJ)/alto2/a2ksec.o: $(CPUSRC)/alto2/a2ksec.c \ |
| 2346 | $(CPUSRC)/alto2/a2ksec.h \ | |
| 2336 | 2347 | $(CPUSRC)/alto2/alto2cpu.h |
| 2337 | 2348 | |
| 2338 | 2349 | $(CPUOBJ)/alto2/a2kwd.o: $(CPUSRC)/alto2/a2kwd.c \ |
| 2350 | $(CPUSRC)/alto2/a2kwd.h \ | |
| 2339 | 2351 | $(CPUSRC)/alto2/alto2cpu.h |
| 2340 | 2352 | |
| 2341 | 2353 | $(CPUOBJ)/alto2/a2mem.o: $(CPUSRC)/alto2/a2mem.c \ |
| 2354 | $(CPUSRC)/alto2/a2mem.h \ | |
| 2342 | 2355 | $(CPUSRC)/alto2/alto2cpu.h |
| 2343 | 2356 | |
| 2344 | 2357 | $(CPUOBJ)/alto2/a2mouse.o: $(CPUSRC)/alto2/a2mouse.c \ |
| 2358 | $(CPUSRC)/alto2/a2mouse.h \ | |
| 2345 | 2359 | $(CPUSRC)/alto2/alto2cpu.h |
| 2346 | 2360 | |
| 2347 | 2361 | $(CPUOBJ)/alto2/a2mrt.o: $(CPUSRC)/alto2/a2mrt.c \ |
| 2362 | $(CPUSRC)/alto2/a2mrt.h \ | |
| 2348 | 2363 | $(CPUSRC)/alto2/alto2cpu.h |
| 2349 | 2364 | |
| 2350 | 2365 | $(CPUOBJ)/alto2/a2part.o: $(CPUSRC)/alto2/a2part.c \ |
| 2366 | $(CPUSRC)/alto2/a2part.h \ | |
| 2351 | 2367 | $(CPUSRC)/alto2/alto2cpu.h |
| 2352 | 2368 | |
| 2353 | 2369 | $(CPUOBJ)/alto2/a2ram.o: $(CPUSRC)/alto2/a2ram.c \ |
| 2370 | $(CPUSRC)/alto2/a2ram.h \ | |
| 2354 | 2371 | $(CPUSRC)/alto2/alto2cpu.h |
| 2355 | 2372 | |
| 2356 | 2373 | $(CPUOBJ)/alto2/a2roms.o: $(CPUSRC)/alto2/a2roms.c \ |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /********************************************************** |
| 2 | 2 | * DIABLO31 and DIABLO44 hard drive support |
| 3 | 3 | * |
| 4 | * Copyright | |
| 4 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 5 | 5 | * |
| 6 | 6 | * Licenses: MAME, GPLv2 |
| 7 | 7 | **********************************************************/ |
| r26306 | r26307 | |
| 309 | 309 | } |
| 310 | 310 | |
| 311 | 311 | if (m_disk) { |
| 312 | / | |
| 312 | // allocate a buffer for this page | |
| 313 | 313 | m_cache[m_page] = auto_alloc_array(machine(), UINT8, sizeof(diablo_sector_t)); |
| 314 | / | |
| 314 | // and read the page from the hard_disk image | |
| 315 | 315 | if (hard_disk_read(m_disk, m_page, m_cache[m_page])) { |
| 316 | 316 | LOG_DRIVE((2,"[DHD%u] CHS:%03d/%d/%02d => page:%d loaded\n", m_unit, m_cylinder, m_head, m_sector, m_page)); |
| 317 | 317 | } else { |
| r26306 | r26307 | |
| 443 | 443 | diablo_sector_t *s = reinterpret_cast<diablo_sector_t *>(m_cache[m_page]); |
| 444 | 444 | |
| 445 | 445 | /* allocate a bits image */ |
| 446 | UINT32 *bits = | |
| 446 | UINT32 *bits = auto_alloc_array_clear(machine(), UINT32, 400); | |
| 447 | 447 | |
| 448 | 448 | if (m_diablo31) { |
| 449 | 449 | /* write sync bit after (MFROBL-MRPAL) words - 1 bit */ |
| r26306 | r26307 | |
| 979 | 979 | m_addx_acknowledge_0 = 0; // assert address acknowledge (?) |
| 980 | 980 | m_log_addx_interlock_0 = 1; // deassert log address interlock (?) |
| 981 | 981 | LOG_DRIVE((1,"[DHD%u] select unit:%d ready\n", m_unit, unit)); |
| 982 | read_sector(); | |
| 982 | 983 | } else { |
| 983 | 984 | m_ready_0 = 1; // it is not ready (?) |
| 984 | 985 | m_s_r_w_0 = 1; // can't take seek/read/write commands (?) |
| r26306 | r26307 | |
| 986 | 987 | m_log_addx_interlock_0 = 1; // deassert log address interlock (?) |
| 987 | 988 | LOG_DRIVE((1,"[DHD%u] select unit:%d not ready (no image)\n", m_unit, unit)); |
| 988 | 989 | } |
| 989 | read_sector(); | |
| 990 | 990 | } |
| 991 | 991 | |
| 992 | 992 | /** |
| r26306 | r26307 | |
| 1256 | 1256 | m_packs = 1; // FIXME: get from configuration? |
| 1257 | 1257 | m_unit = strstr(m_image->tag(), "diablo0") ? 0 : 1; |
| 1258 | 1258 | |
| 1259 | m_cache = auto_alloc_array(machine(), UINT8*, m_pages); | |
| 1260 | memset(m_cache, 0, sizeof(UINT8*) * m_pages); | |
| 1261 | m_bits = auto_alloc_array(machine(), UINT32*, m_pages); | |
| 1262 | memset(m_bits, 0, sizeof(UINT32*) * m_pages); | |
| 1263 | ||
| 1264 | 1259 | m_timer = timer_alloc(1, 0); |
| 1265 | 1260 | } |
| 1266 | 1261 | |
| 1267 | 1262 | void diablo_hd_device::device_reset() |
| 1268 | 1263 | { |
| 1264 | // free previous page cache | |
| 1265 | if (m_cache) { | |
| 1266 | for (int page = 0; page < m_pages; page++) | |
| 1267 | if (m_cache[page]) | |
| 1268 | auto_free(machine(), m_cache[page]); | |
| 1269 | auto_free(machine(), m_cache); | |
| 1270 | m_cache = 0; | |
| 1271 | } | |
| 1272 | // free previous bits cache | |
| 1273 | if (m_bits) { | |
| 1274 | for (int page = 0; page < m_pages; page++) | |
| 1275 | if (m_bits[page]) | |
| 1276 | auto_free(machine(), m_bits[page]); | |
| 1277 | auto_free(machine(), m_bits); | |
| 1278 | m_bits = 0; | |
| 1279 | } | |
| 1269 | 1280 | m_handle = m_image->get_chd_file(); |
| 1270 | 1281 | m_diablo31 = true; // FIXME: get from m_handle meta data? |
| 1271 | 1282 | m_disk = m_image->get_hard_disk_file(); |
| r26306 | r26307 | |
| 1276 | 1287 | m_sector_mark_0_time = DIABLO31_SECTOR_MARK_PULSE_PRE; |
| 1277 | 1288 | m_sector_mark_1_time = DIABLO31_SECTOR_MARK_PULSE_PRE; |
| 1278 | 1289 | m_bit_time = DIABLO31_BIT_TIME(1); |
| 1290 | m_pages = DIABLO_PAGES; | |
| 1279 | 1291 | } else { |
| 1280 | 1292 | snprintf(m_description, sizeof(m_description), "DIABLO44"); |
| 1281 | 1293 | m_rotation_time = DIABLO44_ROTATION_TIME; |
| r26306 | r26307 | |
| 1283 | 1295 | m_sector_mark_0_time = DIABLO44_SECTOR_MARK_PULSE_PRE; |
| 1284 | 1296 | m_sector_mark_1_time = DIABLO44_SECTOR_MARK_PULSE_PRE; |
| 1285 | 1297 | m_bit_time = DIABLO44_BIT_TIME(1); |
| 1298 | m_pages = 2 * DIABLO_PAGES; | |
| 1286 | 1299 | } |
| 1287 | 1300 | LOG_DRIVE((0,"[DHD%u] rotation time : %.0fns\n", m_unit, m_rotation_time.as_double() * ATTOSECONDS_PER_NANOSECOND)); |
| 1288 | 1301 | LOG_DRIVE((0,"[DHD%u] sector time : %.0fns\n", m_unit, m_sector_time.as_double() * ATTOSECONDS_PER_NANOSECOND)); |
| r26306 | r26307 | |
| 1317 | 1330 | // for units with a CHD assigned to them start the timer |
| 1318 | 1331 | if (m_handle) { |
| 1319 | 1332 | timer_set(m_sector_time - m_sector_mark_0_time, 1, 0); |
| 1333 | m_cache = auto_alloc_array_clear(machine(), UINT8*, m_pages); | |
| 1334 | m_bits = auto_alloc_array_clear(machine(), UINT32*, m_pages); | |
| 1320 | 1335 | read_sector(); |
| 1321 | 1336 | } |
| 1322 | 1337 | } |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /********************************************************** |
| 2 | 2 | * DIABLO31 and DIABLO44 hard drive support |
| 3 | 3 | * |
| 4 | * Copyright | |
| 4 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 5 | 5 | * |
| 6 | 6 | * Licenses: MAME, GPLv2 |
| 7 | 7 | **********************************************************/ |
| r26306 | r26307 | |
| 13 | 13 | #include "imagedev/diablo.h" |
| 14 | 14 | |
| 15 | 15 | #ifndef DIABLO_DEBUG |
| 16 | #define DIABLO_DEBUG | |
| 16 | #define DIABLO_DEBUG 0 //!< set to 1 to enable debug log output | |
| 17 | 17 | #endif |
| 18 | 18 | |
| 19 | 19 | #define DIABLO_HD_0 "diablo0" |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /********************************************************** |
| 2 | 2 | * DIABLO drive image to hard disk interface |
| 3 | 3 | * |
| 4 | * Copyright | |
| 4 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 5 | 5 | * |
| 6 | 6 | * Licenses: MAME, GPLv2 |
| 7 | 7 | **********************************************************/ |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /********************************************************** |
| 2 | 2 | * DIABLO drive image to hard disk interface |
| 3 | 3 | * |
| 4 | * Copyright | |
| 4 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 5 | 5 | * |
| 6 | 6 | * Licenses: MAME, GPLv2 |
| 7 | 7 | **********************************************************/ |
| r26306 | r26307 | |
|---|---|---|
| 1 | 1 | /*************************************************************************** |
| 2 | * | |
| 2 | * Xerox AltoII driver for MESS | |
| 3 | 3 | * |
| 4 | * Copyright | |
| 4 | * Copyright © Jürgen Buchmüller <pullmoll@t-online.de> | |
| 5 | 5 | * |
| 6 | 6 | * Licenses: MAME, GPLv2 |
| 7 | 7 | ***************************************************************************/ |
| r26306 | r26307 | |
| 13 | 13 | UINT32 alto2_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 14 | 14 | { |
| 15 | 15 | alto2_cpu_device* cpu = downcast<alto2_cpu_device *>(m_maincpu.target()); |
| 16 | bitmap_ind16& src = cpu->display(); | |
| 17 | if (src.valid()) | |
| 18 | copybitmap(bitmap, src, 0, 0, 0, 0, cliprect); | |
| 16 | bitmap_ind16* source = cpu->bitmap(); | |
| 17 | if (source && source->valid()) | |
| 18 | copybitmap(bitmap, *source, 0, 0, 0, 0, cliprect); | |
| 19 | 19 | return 0; |
| 20 | 20 | } |
| 21 | 21 | |
| 22 | 22 | /* Input Ports */ |
| 23 | 23 | |
| 24 | /** @brief make an Alto key int from 1 << bit */ | |
| 25 | #define MAKE_KEY(a,b) (1 << (b)) | |
| 26 | ||
| 27 | /** @brief no key assigned is -1 */ | |
| 28 | #define A2_KEY_NONE (-1) | |
| 29 | ||
| 30 | #define A2_KEY_5 MAKE_KEY(0,017) //!< normal: 5 shifted: % | |
| 31 | #define A2_KEY_4 MAKE_KEY(0,016) //!< normal: 4 shifted: $ | |
| 32 | #define A2_KEY_6 MAKE_KEY(0,015) //!< normal: 6 shifted: ~ | |
| 33 | #define A2_KEY_E MAKE_KEY(0,014) //!< normal: e shifted: E | |
| 34 | #define A2_KEY_7 MAKE_KEY(0,013) //!< normal: 7 shifted: & | |
| 35 | #define A2_KEY_D MAKE_KEY(0,012) //!< normal: d shifted: D | |
| 36 | #define A2_KEY_U MAKE_KEY(0,011) //!< normal: u shifted: U | |
| 37 | #define A2_KEY_V MAKE_KEY(0,010) //!< normal: v shifted: V | |
| 38 | #define A2_KEY_0 MAKE_KEY(0,007) //!< normal: 0 shifted: ) | |
| 39 | #define A2_KEY_K MAKE_KEY(0,006) //!< normal: k shifted: K | |
| 40 | #define A2_KEY_MINUS MAKE_KEY(0,005) //!< normal: - shifted: _ | |
| 41 | #define A2_KEY_P MAKE_KEY(0,004) //!< normal: p shifted: P | |
| 42 | #define A2_KEY_SLASH MAKE_KEY(0,003) //!< normal: / shifted: ? | |
| 43 | #define A2_KEY_BACKSLASH MAKE_KEY(0,002) //!< normal: \ shifted: | | |
| 44 | #define A2_KEY_LF MAKE_KEY(0,001) //!< normal: LF shifted: ? | |
| 45 | #define A2_KEY_BS MAKE_KEY(0,000) //!< normal: BS shifted: ? | |
| 46 | ||
| 47 | #define A2_KEY_FR2 MAKE_KEY(0,002) //!< ADL right function key 2 | |
| 48 | #define A2_KEY_FL2 MAKE_KEY(0,001) //!< ADL left function key 1 | |
| 49 | ||
| 50 | #define A2_KEY_3 MAKE_KEY(1,017) //!< normal: 3 shifted: # | |
| 51 | #define A2_KEY_2 MAKE_KEY(1,016) //!< normal: 2 shifted: @ | |
| 52 | #define A2_KEY_W MAKE_KEY(1,015) //!< normal: w shifted: W | |
| 53 | #define A2_KEY_Q MAKE_KEY(1,014) //!< normal: q shifted: Q | |
| 54 | #define A2_KEY_S MAKE_KEY(1,013) //!< normal: s shifted: S | |
| 55 | #define A2_KEY_A MAKE_KEY(1,012) //!< normal: a shifted: A | |
| 56 | #define A2_KEY_9 MAKE_KEY(1,011) //!< normal: 9 shifted: ( | |
| 57 | #define A2_KEY_I MAKE_KEY(1,010) //!< normal: i shifted: I | |
| 58 | #define A2_KEY_X MAKE_KEY(1,007) //!< normal: x shifted: X | |
| 59 | #define A2_KEY_O MAKE_KEY(1,006) //!< normal: o shifted: O | |
| 60 | #define A2_KEY_L MAKE_KEY(1,005) //!< normal: l shifted: L | |
| 61 | #define A2_KEY_COMMA MAKE_KEY(1,004) //!< normal: , shifted: < | |
| 62 | #define A2_KEY_QUOTE MAKE_KEY(1,003) //!< normal: ' shifted: " | |
| 63 | #define A2_KEY_RBRACKET MAKE_KEY(1,002) //!< normal: ] shifted: } | |
| 64 | #define A2_KEY_BLANK_MID MAKE_KEY(1,001) //!< middle blank key | |
| 65 | #define A2_KEY_BLANK_TOP MAKE_KEY(1,000) //!< top blank key | |
| 66 | ||
| 67 | #define A2_KEY_FR4 MAKE_KEY(1,001) //!< ADL right funtion key 4 | |
| 68 | #define A2_KEY_BW MAKE_KEY(1,000) //!< ADL BW (?) | |
| 69 | ||
| 70 | #define A2_KEY_1 MAKE_KEY(2,017) //!< normal: 1 shifted: ! | |
| 71 | #define A2_KEY_ESCAPE MAKE_KEY(2,016) //!< normal: ESC shifted: ? | |
| 72 | #define A2_KEY_TAB MAKE_KEY(2,015) //!< normal: TAB shifted: ? | |
| 73 | #define A2_KEY_F MAKE_KEY(2,014) //!< normal: f shifted: F | |
| 74 | #define A2_KEY_CTRL MAKE_KEY(2,013) //!< CTRL | |
| 75 | #define A2_KEY_C MAKE_KEY(2,012) //!< normal: c shifted: C | |
| 76 | #define A2_KEY_J MAKE_KEY(2,011) //!< normal: j shifted: J | |
| 77 | #define A2_KEY_B MAKE_KEY(2,010) //!< normal: b shifted: B | |
| 78 | #define A2_KEY_Z MAKE_KEY(2,007) //!< normal: z shifted: Z | |
| 79 | #define A2_KEY_LSHIFT MAKE_KEY(2,006) //!< LSHIFT | |
| 80 | #define A2_KEY_PERIOD MAKE_KEY(2,005) //!< normal: . shifted: > | |
| 81 | #define A2_KEY_SEMICOLON MAKE_KEY(2,004) //!< normal: ; shifted: : | |
| 82 | #define A2_KEY_RETURN MAKE_KEY(2,003) //!< RETURN | |
| 83 | #define A2_KEY_LEFTARROW MAKE_KEY(2,002) //!< normal: left arrow shifted: up arrow (caret) | |
| 84 | #define A2_KEY_DEL MAKE_KEY(2,001) //!< normal: DEL shifted: ? | |
| 85 | #define A2_KEY_MSW_2_17 MAKE_KEY(2,000) //!< unused on Microswitch KDB | |
| 86 | ||
| 87 | #define A2_KEY_FR3 MAKE_KEY(2,002) //!< ADL right function key 3 | |
| 88 | #define A2_KEY_FL1 MAKE_KEY(2,001) //!< ADL left function key 1 | |
| 89 | #define A2_KEY_FL3 MAKE_KEY(2,000) //!< ADL left function key 3 | |
| 90 | ||
| 91 | #define A2_KEY_R MAKE_KEY(3,017) //!< normal: r shifted: R | |
| 92 | #define A2_KEY_T MAKE_KEY(3,016) //!< normal: t shifted: T | |
| 93 | #define A2_KEY_G MAKE_KEY(3,015) //!< normal: g shifted: G | |
| 94 | #define A2_KEY_Y MAKE_KEY(3,014) //!< normal: y shifted: Y | |
| 95 | #define A2_KEY_H MAKE_KEY(3,013) //!< normal: h shifted: H | |
| 96 | #define A2_KEY_8 MAKE_KEY(3,012) //!< normal: 8 shifted: * | |
| 97 | #define A2_KEY_N MAKE_KEY(3,011) //!< normal: n shifted: N | |
| 98 | #define A2_KEY_M MAKE_KEY(3,010) //!< normal: m shifted: M | |
| 99 | #define A2_KEY_LOCK MAKE_KEY(3,007) //!< LOCK | |
| 100 | #define A2_KEY_SPACE MAKE_KEY(3,006) //!< SPACE | |
| 101 | #define A2_KEY_LBRACKET MAKE_KEY(3,005) //!< normal: [ shifted: { | |
| 102 | #define A2_KEY_EQUALS MAKE_KEY(3,004) //!< normal: = shifted: + | |
| 103 | #define A2_KEY_RSHIFT MAKE_KEY(3,003) //!< RSHIFT | |
| 104 | #define A2_KEY_BLANK_BOT MAKE_KEY(3,002) //!< bottom blank key | |
| 105 | #define A2_KEY_MSW_3_16 MAKE_KEY(3,001) //!< unused on Microswitch KDB | |
| 106 | #define A2_KEY_MSW_3_17 MAKE_KEY(3,000) //!< unused on Microswitch KDB | |
| 107 | ||
| 108 | #define A2_KEY_FR1 MAKE_KEY(3,002) //!< ADL right function key 4 | |
| 109 | #define A2_KEY_FL4 MAKE_KEY(3,001) //!< ADL left function key 4 | |
| 110 | #define A2_KEY_FR5 MAKE_KEY(3,000) //!< ADL right function key 5 | |
| 111 | ||
| 112 | 24 | static INPUT_PORTS_START( alto2 ) |
| 113 | 25 | PORT_START("ROW0") |
| 114 | 26 | PORT_BIT(A2_KEY_5, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("5 %") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') //!< normal: 5 shifted: % |
| r26306 | r26307 | |
| 211 | 123 | PORT_START("mousey") // Mouse - Y AXIS |
| 212 | 124 | PORT_BIT( 0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(50) PORT_KEYDELTA(1) PORT_PLAYER(1) PORT_CHANGED_MEMBER( ":maincpu", alto2_cpu_device, mouse_motion_y, 0 ) |
| 213 | 125 | |
| 214 | PORT_START("CONFIG") /* config diode on main board */ | |
| 215 | PORT_CONFNAME( 0x40, 0x40, "TV system") | |
| 216 | PORT_CONFSETTING( 0x00, "NTSC") | |
| 217 | PORT_CONFSETTING( 0x40, "PAL") | |
| 126 | PORT_START("CONFIG") /* Memory switch on AIM board */ | |
| 127 | PORT_CONFNAME( 1<<9, 1<<9, "Memory switch") | |
| 128 | PORT_CONFSETTING( 0, "on") | |
| 129 | PORT_CONFSETTING( 1<<9, "off") | |
| 218 | 130 | INPUT_PORTS_END |
| 219 | 131 | |
| 220 | 132 | /* ROM */ |
| r26306 | r26307 | |
| 283 | 195 | /* Game Drivers */ |
| 284 | 196 | |
| 285 | 197 | // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS |
| 286 | COMP( 197 | |
| 198 | COMP( 1977, alto2, 0, 0, alto2, alto2, alto2_state, alto2, "Xerox", "Alto-II", GAME_NO_SOUND ) |
| Previous | 199869 Revisions | Next |