Skip to content

Commit 77ae23a

Browse files
committed
casio/fp1100.cpp: fix video writes and fill
1 parent f0bf4f6 commit 77ae23a

File tree

1 file changed

+74
-49
lines changed

1 file changed

+74
-49
lines changed

src/mame/casio/fp1100.cpp

Lines changed: 74 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ class fp1100_state : public driver_device
6565
public:
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

8686
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+
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

145148
MC6845_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`
228234
u8 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
*/
260266
void 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)
287307
void 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
*/
310332
void 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

318349
u8 fp1100_state::portb_r()
@@ -383,7 +414,7 @@ void fp1100_state::handle_int_to_main()
383414
}
384415
}
385416

386-
// Input ports
417+
387418
static 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

655686
void 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

Comments
 (0)