@@ -65,13 +65,13 @@ class fp1100_state : public driver_device
6565public:
6666 fp1100_state (const machine_config &mconfig, device_type type, const char *tag)
6767 : driver_device(mconfig, type, tag)
68- , m_palette(*this , " palette" )
6968 , m_maincpu(*this , " maincpu" )
7069 , m_subcpu(*this , " sub" )
7170 , m_crtc(*this , " crtc" )
7271 , m_ipl(*this , " ipl" )
7372 , m_wram(*this , " wram" )
74- , m_videoram(*this , " videoram" )
73+ , m_videoram(*this , " videoram.%u" , 0 )
74+ , m_palette(*this , " palette" )
7575 , m_keyboard(*this , " KEY.%u" , 0 )
7676 , m_beep(*this , " beeper" )
7777 , m_centronics(*this , " centronics" )
@@ -84,12 +84,30 @@ class fp1100_state : public driver_device
8484 virtual void machine_reset () override ;
8585
8686private:
87+ required_device<cpu_device> m_maincpu;
88+ required_device<upd7801_device> m_subcpu;
89+ required_device<mc6845_device> m_crtc;
90+ required_region_ptr<u8 > m_ipl;
91+ required_shared_ptr<u8 > m_wram;
92+ required_shared_ptr_array<u8 , 3 > m_videoram;
93+ required_device<palette_device> m_palette;
94+ required_ioport_array<16 > m_keyboard;
95+ required_device<beep_device> m_beep;
96+ required_device<centronics_device> m_centronics;
97+ required_device<cassette_image_device> m_cass;
98+
99+ void main_map (address_map &map);
100+ void io_map (address_map &map);
101+ void sub_map (address_map &map);
102+
87103 void main_bank_w (u8 data);
88104 void irq_mask_w (u8 data);
89105 void slot_bank_w (u8 data);
90106 u8 slot_id_r ();
91107 u8 memory_r (offs_t offset);
92108 void colour_control_w (u8 data);
109+ template <unsigned N> u8 vram_r (offs_t offset);
110+ template <unsigned N> void vram_w (offs_t offset, u8 data);
93111 void kbd_row_w (u8 data);
94112 void porta_w (u8 data);
95113 u8 portb_r ();
@@ -100,11 +118,6 @@ class fp1100_state : public driver_device
100118 MC6845_UPDATE_ROW (crtc_update_row);
101119 TIMER_DEVICE_CALLBACK_MEMBER (kansas_w);
102120
103- required_device<palette_device> m_palette;
104-
105- void io_map (address_map &map);
106- void main_map (address_map &map);
107- void sub_map (address_map &map);
108121 void handle_int_to_main ();
109122
110123 u8 m_irq_mask = 0 ;
@@ -130,29 +143,21 @@ class fp1100_state : public driver_device
130143 u8 portb = 0 ;
131144 u8 portc = 0 ;
132145 }m_upd7801;
133- required_device<cpu_device> m_maincpu;
134- required_device<upd7801_device> m_subcpu;
135- required_device<mc6845_device> m_crtc;
136- required_region_ptr<u8 > m_ipl;
137- required_shared_ptr<u8 > m_wram;
138- required_shared_ptr<u8 > m_videoram;
139- required_ioport_array<16 > m_keyboard;
140- required_device<beep_device> m_beep;
141- required_device<centronics_device> m_centronics;
142- required_device<cassette_image_device> m_cass;
143146};
144147
145148MC6845_UPDATE_ROW ( fp1100_state::crtc_update_row )
146149{
147150 rgb_t const *const palette = m_palette->palette ()->entry_list_raw ();
148151 u32 *p = &bitmap.pix (y);
152+ const u8 porta = m_upd7801.porta ;
149153
150- if (BIT (m_upd7801. porta , 4 ))
154+ if (BIT (porta, 4 ))
151155 { // green screen
152156 for (u16 x = 0 ; x < x_count; x++)
153157 {
154158 u16 const mem = (((ma + x) << 3 ) + ra) & 0x3fff ;
155- u8 const g = m_videoram[mem];
159+ // TODO: ORs contents from the other two layers (for FP-1100 only)
160+ u8 const g = m_videoram[0 ][mem];
156161 for (u8 i = 0 ; i < 8 ; i++)
157162 {
158163 u8 col = BIT (g, i);
@@ -167,9 +172,9 @@ MC6845_UPDATE_ROW( fp1100_state::crtc_update_row )
167172 for (u16 x = 0 ; x < x_count; x++)
168173 {
169174 u16 const mem = (((ma + x) << 3 ) + ra) & 0x3fff ;
170- u8 const b = m_videoram[mem];
171- u8 const r = m_videoram[mem + 0x4000 ] ;
172- u8 const g = m_videoram[mem + 0x8000 ] ;
175+ u8 const b = BIT (porta, 2 ) ? m_videoram[0 ][ mem] : 0 ;
176+ u8 const r = BIT (porta, 1 ) ? m_videoram[1 ][ mem] : 0 ;
177+ u8 const g = BIT (porta, 0 ) ? m_videoram[2 ][ mem] : 0 ;
173178 for (u8 i = 0 ; i < 8 ; i++)
174179 {
175180 u8 col = BIT (r, i) | (BIT (g, i) << 1 ) | (BIT (b, i) << 2 );
@@ -225,6 +230,7 @@ u8 fp1100_state::slot_id_r()
225230 return m_slot[m_slot_num & 7 ].id ;
226231}
227232
233+ // TODO: convert to `memory_view`
228234u8 fp1100_state::memory_r (offs_t offset)
229235{
230236 if (offset < 0x9000 && !m_bank_sel)
@@ -259,14 +265,28 @@ d7 - 1=display area; 0=cursor
259265*/
260266void fp1100_state::colour_control_w (u8 data)
261267{
262- data = bitswap< 8 >(data, 7 , 4 , 6 , 5 , 3 , 0 , 2 , 1 ); // change BRG to RGB
263-
268+ // HACK: change BRG to RGB
269+ data = bitswap< 8 >(data, 7 , 4 , 6 , 5 , 3 , 0 , 2 , 1 );
264270 m_col_border = data & 7 ;
265271
266272 if (BIT (data, 7 ))
267273 m_col_display = (data >> 4 ) & 7 ;
268274 else
275+ {
276+ m_col_display = 0 ;
269277 m_col_cursor = data >> 4 ;
278+ }
279+ }
280+
281+ template <unsigned N> u8 fp1100_state::vram_r (offs_t offset)
282+ {
283+ return m_videoram[N][offset];
284+ }
285+
286+ template <unsigned N> void fp1100_state::vram_w (offs_t offset, u8 data)
287+ {
288+ // NOTE: POST makes sure to punt in FP-1000 mode if this don't XOR the value
289+ m_videoram[N][offset] = ~data;
270290}
271291
272292/*
@@ -287,7 +307,9 @@ void fp1100_state::kbd_row_w(u8 data)
287307void fp1100_state::sub_map (address_map &map)
288308{
289309 map (0x0000 , 0x1fff ).rom ().region (" sub_ipl" , 0x0000 );
290- map (0x2000 , 0xdfff ).ram ().share (m_videoram); // vram B/R/G
310+ map (0x2000 , 0x5fff ).rw (FUNC (fp1100_state::vram_r<0 >), FUNC (fp1100_state::vram_w<0 >)).share (m_videoram[0 ]);
311+ map (0x6000 , 0x9fff ).rw (FUNC (fp1100_state::vram_r<1 >), FUNC (fp1100_state::vram_w<1 >)).share (m_videoram[1 ]);
312+ map (0xa000 , 0xdfff ).rw (FUNC (fp1100_state::vram_r<2 >), FUNC (fp1100_state::vram_w<2 >)).share (m_videoram[2 ]);
291313 map (0xe000 , 0xe000 ).mirror (0x3fe ).rw (m_crtc, FUNC (mc6845_device::status_r), FUNC (mc6845_device::address_w));
292314 map (0xe001 , 0xe001 ).mirror (0x3fe ).rw (m_crtc, FUNC (mc6845_device::register_r), FUNC (mc6845_device::register_w));
293315 map (0xe400 , 0xe400 ).mirror (0x3ff ).portr (" DSW" ).w (FUNC (fp1100_state::kbd_row_w));
@@ -309,10 +331,19 @@ The SO pin is Serial Output to CMT (1=2400Hz; 0=1200Hz)
309331*/
310332void fp1100_state::porta_w (u8 data)
311333{
312- m_upd7801.porta = data;
334+ if (BIT (m_upd7801.porta , 5 ) && !BIT (data, 5 ))
335+ {
336+ for (int i = 0 ; i < 3 ; i++)
337+ {
338+ const u8 fill_value = BIT (m_col_display, i) ? 0xff : 0 ;
339+ std::fill (m_videoram[i].begin (), m_videoram[i].end (), fill_value);
340+ }
341+ }
313342
314- if (BIT (data, 5 ))
315- memset (m_videoram, 0 , 0xc000 );
343+ const u8 crtc_divider = BIT (data, 3 ) ? 16 : 8 ;
344+ m_crtc->set_unscaled_clock (MAIN_CLOCK / crtc_divider);
345+
346+ m_upd7801.porta = data;
316347}
317348
318349u8 fp1100_state::portb_r ()
@@ -383,7 +414,7 @@ void fp1100_state::handle_int_to_main()
383414 }
384415}
385416
386- // Input ports
417+
387418static INPUT_PORTS_START ( fp1100 )
388419 PORT_START(" KEY.0" )
389420 PORT_BIT(0xff , IP_ACTIVE_LOW, IPT_UNUSED)
@@ -654,7 +685,6 @@ void fp1100_state::machine_reset()
654685
655686void fp1100_state::fp1100 (machine_config &config)
656687{
657- // basic machine hardware
658688 Z80 (config, m_maincpu, MAIN_CLOCK/4 );
659689 m_maincpu->set_addrmap (AS_PROGRAM, &fp1100_state::main_map);
660690 m_maincpu->set_addrmap (AS_IO, &fp1100_state::io_map);
@@ -672,7 +702,17 @@ void fp1100_state::fp1100(machine_config &config)
672702 GENERIC_LATCH_8 (config, " main2sub" );
673703 GENERIC_LATCH_8 (config, " sub2main" );
674704
675- // video hardware
705+ CENTRONICS (config, m_centronics, centronics_devices, " printer" );
706+ m_centronics->busy_handler ().set (FUNC (fp1100_state::centronics_busy_w));
707+
708+ output_latch_device &latch (OUTPUT_LATCH (config, " cent_data_out" ));
709+ m_centronics->set_output_latch (latch);
710+
711+ CASSETTE (config, m_cass);
712+ m_cass->set_default_state (CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
713+ m_cass->add_route (ALL_OUTPUTS, " mono" , 0.05 );
714+ TIMER (config, " kansas_w" ).configure_periodic (FUNC (fp1100_state::kansas_w), attotime::from_hz (4800 ));
715+
676716 screen_device &screen (SCREEN (config, " screen" , SCREEN_TYPE_RASTER));
677717 screen.set_refresh_hz (60 );
678718 screen.set_vblank_time (ATTOSECONDS_IN_USEC (2500 )); // not accurate
@@ -682,30 +722,15 @@ void fp1100_state::fp1100(machine_config &config)
682722 PALETTE (config, m_palette).set_entries (8 );
683723 GFXDECODE (config, " gfxdecode" , m_palette, gfx_fp1100);
684724
685- // sound hardware
686- SPEAKER (config, " mono" ).front_center ();
687- BEEP (config, " beeper" , 950 ) // guess
688- .add_route (ALL_OUTPUTS, " mono" , 0.50 ); // inside the keyboard
689-
690- // CRTC
691725 HD6845S (config, m_crtc, MAIN_CLOCK/8 ); // hand tuned to get ~60 fps
692726 m_crtc->set_screen (" screen" );
693727 m_crtc->set_show_border_area (false );
694728 m_crtc->set_char_width (8 );
695729 m_crtc->set_update_row_callback (FUNC (fp1100_state::crtc_update_row));
696730
697- // Printer
698- CENTRONICS (config, m_centronics, centronics_devices, " printer" );
699- m_centronics->busy_handler ().set (FUNC (fp1100_state::centronics_busy_w));
700-
701- output_latch_device &latch (OUTPUT_LATCH (config, " cent_data_out" ));
702- m_centronics->set_output_latch (latch);
703-
704- // Cassette
705- CASSETTE (config, m_cass);
706- m_cass->set_default_state (CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED);
707- m_cass->add_route (ALL_OUTPUTS, " mono" , 0.05 );
708- TIMER (config, " kansas_w" ).configure_periodic (FUNC (fp1100_state::kansas_w), attotime::from_hz (4800 )); // cass write
731+ SPEAKER (config, " mono" ).front_center ();
732+ BEEP (config, " beeper" , 950 ) // guess
733+ .add_route (ALL_OUTPUTS, " mono" , 0.50 ); // inside the keyboard
709734}
710735
711736// ROM definitions
0 commit comments