@@ -65,13 +65,13 @@ class fp1100_state : public driver_device
65
65
public:
66
66
fp1100_state (const machine_config &mconfig, device_type type, const char *tag)
67
67
: driver_device(mconfig, type, tag)
68
- , m_palette(*this , " palette" )
69
68
, m_maincpu(*this , " maincpu" )
70
69
, m_subcpu(*this , " sub" )
71
70
, m_crtc(*this , " crtc" )
72
71
, m_ipl(*this , " ipl" )
73
72
, m_wram(*this , " wram" )
74
- , m_videoram(*this , " videoram" )
73
+ , m_videoram(*this , " videoram.%u" , 0 )
74
+ , m_palette(*this , " palette" )
75
75
, m_keyboard(*this , " KEY.%u" , 0 )
76
76
, m_beep(*this , " beeper" )
77
77
, m_centronics(*this , " centronics" )
@@ -84,12 +84,30 @@ class fp1100_state : public driver_device
84
84
virtual void machine_reset () override ;
85
85
86
86
private:
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
+
87
103
void main_bank_w (u8 data);
88
104
void irq_mask_w (u8 data);
89
105
void slot_bank_w (u8 data);
90
106
u8 slot_id_r ();
91
107
u8 memory_r (offs_t offset);
92
108
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);
93
111
void kbd_row_w (u8 data);
94
112
void porta_w (u8 data);
95
113
u8 portb_r ();
@@ -100,11 +118,6 @@ class fp1100_state : public driver_device
100
118
MC6845_UPDATE_ROW (crtc_update_row);
101
119
TIMER_DEVICE_CALLBACK_MEMBER (kansas_w);
102
120
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);
108
121
void handle_int_to_main ();
109
122
110
123
u8 m_irq_mask = 0 ;
@@ -130,29 +143,21 @@ class fp1100_state : public driver_device
130
143
u8 portb = 0 ;
131
144
u8 portc = 0 ;
132
145
}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;
143
146
};
144
147
145
148
MC6845_UPDATE_ROW ( fp1100_state::crtc_update_row )
146
149
{
147
150
rgb_t const *const palette = m_palette->palette ()->entry_list_raw ();
148
151
u32 *p = &bitmap.pix (y);
152
+ const u8 porta = m_upd7801.porta ;
149
153
150
- if (BIT (m_upd7801. porta , 4 ))
154
+ if (BIT (porta, 4 ))
151
155
{ // green screen
152
156
for (u16 x = 0 ; x < x_count; x++)
153
157
{
154
158
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];
156
161
for (u8 i = 0 ; i < 8 ; i++)
157
162
{
158
163
u8 col = BIT (g, i);
@@ -167,9 +172,9 @@ MC6845_UPDATE_ROW( fp1100_state::crtc_update_row )
167
172
for (u16 x = 0 ; x < x_count; x++)
168
173
{
169
174
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 ;
173
178
for (u8 i = 0 ; i < 8 ; i++)
174
179
{
175
180
u8 col = BIT (r, i) | (BIT (g, i) << 1 ) | (BIT (b, i) << 2 );
@@ -225,6 +230,7 @@ u8 fp1100_state::slot_id_r()
225
230
return m_slot[m_slot_num & 7 ].id ;
226
231
}
227
232
233
+ // TODO: convert to `memory_view`
228
234
u8 fp1100_state::memory_r (offs_t offset)
229
235
{
230
236
if (offset < 0x9000 && !m_bank_sel)
@@ -259,14 +265,28 @@ d7 - 1=display area; 0=cursor
259
265
*/
260
266
void fp1100_state::colour_control_w (u8 data)
261
267
{
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 );
264
270
m_col_border = data & 7 ;
265
271
266
272
if (BIT (data, 7 ))
267
273
m_col_display = (data >> 4 ) & 7 ;
268
274
else
275
+ {
276
+ m_col_display = 0 ;
269
277
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;
270
290
}
271
291
272
292
/*
@@ -287,7 +307,9 @@ void fp1100_state::kbd_row_w(u8 data)
287
307
void fp1100_state::sub_map (address_map &map)
288
308
{
289
309
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 ]);
291
313
map (0xe000 , 0xe000 ).mirror (0x3fe ).rw (m_crtc, FUNC (mc6845_device::status_r), FUNC (mc6845_device::address_w));
292
314
map (0xe001 , 0xe001 ).mirror (0x3fe ).rw (m_crtc, FUNC (mc6845_device::register_r), FUNC (mc6845_device::register_w));
293
315
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)
309
331
*/
310
332
void fp1100_state::porta_w (u8 data)
311
333
{
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
+ }
313
342
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;
316
347
}
317
348
318
349
u8 fp1100_state::portb_r ()
@@ -383,7 +414,7 @@ void fp1100_state::handle_int_to_main()
383
414
}
384
415
}
385
416
386
- // Input ports
417
+
387
418
static INPUT_PORTS_START ( fp1100 )
388
419
PORT_START(" KEY.0" )
389
420
PORT_BIT(0xff , IP_ACTIVE_LOW, IPT_UNUSED)
@@ -654,7 +685,6 @@ void fp1100_state::machine_reset()
654
685
655
686
void fp1100_state::fp1100 (machine_config &config)
656
687
{
657
- // basic machine hardware
658
688
Z80 (config, m_maincpu, MAIN_CLOCK/4 );
659
689
m_maincpu->set_addrmap (AS_PROGRAM, &fp1100_state::main_map);
660
690
m_maincpu->set_addrmap (AS_IO, &fp1100_state::io_map);
@@ -672,7 +702,17 @@ void fp1100_state::fp1100(machine_config &config)
672
702
GENERIC_LATCH_8 (config, " main2sub" );
673
703
GENERIC_LATCH_8 (config, " sub2main" );
674
704
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
+
676
716
screen_device &screen (SCREEN (config, " screen" , SCREEN_TYPE_RASTER));
677
717
screen.set_refresh_hz (60 );
678
718
screen.set_vblank_time (ATTOSECONDS_IN_USEC (2500 )); // not accurate
@@ -682,30 +722,15 @@ void fp1100_state::fp1100(machine_config &config)
682
722
PALETTE (config, m_palette).set_entries (8 );
683
723
GFXDECODE (config, " gfxdecode" , m_palette, gfx_fp1100);
684
724
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
691
725
HD6845S (config, m_crtc, MAIN_CLOCK/8 ); // hand tuned to get ~60 fps
692
726
m_crtc->set_screen (" screen" );
693
727
m_crtc->set_show_border_area (false );
694
728
m_crtc->set_char_width (8 );
695
729
m_crtc->set_update_row_callback (FUNC (fp1100_state::crtc_update_row));
696
730
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
709
734
}
710
735
711
736
// ROM definitions
0 commit comments