bcs3 marked as WORKING

(nw) added notes.
This commit is contained in:
Robbbert 2019-05-19 19:08:32 +10:00
parent e2eff85901
commit ee60a5f0fb

View File

@ -2,29 +2,61 @@
// copyright-holders:Robbbert
/***************************************************************************
BCS 3
BCS 3
2009-05-12 Skeleton driver.
2015-09-25 Improvements
2009-05-12 Skeleton driver.
2015-09-25 Improvements
http://hc-ddr.hucki.net/wiki/doku.php/homecomputer:bcs3
http://hc-ddr.hucki.net/wiki/doku.php/homecomputer:bcs3
East German home built computer. No sound facilities.
All documents are in German.
East German home built computer. No sound facilities.
All documents are in German.
Main CPU is a U880 (Z80 equivalent). Other ICs also have unusual names.
Main CPU is a U880 (Z80 equivalent). Other ICs also have unusual names.
The CTC sends an interrupt every so often. This uses a lookup table to
jump to an address in the range 38xx-39xx. This seems to work much the
same as reading video memory in the ZX80. This, I think, is to stop snow
appearing on the screen. It also slows everything down noticeably.
The CTC sends an interrupt every so often. This uses a lookup table to
jump to an address in the range 38xx-39xx. This seems to work much the
same as reading video memory in the ZX80. This, I think, is to stop snow
appearing on the screen. It also slows everything down noticeably.
It appears that a read of 1400 activates the Z80's /WAIT pin. This will
be released by a VS pulse. (Not emulated)
It appears that a read of 1400 activates the Z80's /WAIT pin. This will
be released by a VS pulse. (Not emulated)
Cassette is hooked up according to the documentation, but it doesn't work.
System Clock
- is not a crystal, but instead an LC oscillator at 5 MHz
- frequency divided by 2 to form the CPU clock.
- bcs3b increased oscillator frequency to 7 MHz to handle 40 characters per line
Known Memory Map:
CTC channels
- 0, 15625Hz, TV line sync
- 1, 244Hz, scanline counter for character generator (976Hz on bcs3)
- 2, 49Hz, TV frame sync
- 3, 1Hz, not used
During cassette save, ch 1 is disabled, which causes ch 2 and 3 to stop.
Ch 0 will output pulses at a rate of 1220Hz while each bit is different from
the last, or 2441Hz if bits are the same (1708 and 3417Hz for bcs3b).
These pulses are fed to a flipflop to create a train of wide and narrow
cycles, to be recorded onto the tape.
Cassette
- is hooked up according to the documentation, but doesn't work.
- on the real machine it overrides the video output, so the video will
be lost during cassette operations.
- does not exist on "bcs3". The commands SAVE and LOAD will attempt to
use a non-existing rom at 0800, and crash the system.
- When you start any cassette-based system it asks for the number of lines
you'd like on the screen, or hit enter for the default. Depending on the
number, the BASIC program starts in a different place. So, to LOAD a tape,
you must have the same number of lines that the program was SAVED at.
- Recordings are not compatible between the versions of BASIC.
Bugs:
- Tell it to PRINT ! (or any character it doesn't understand) and the screen
fills up with zeroes. String are enclosed in single quotes. Double quotes
will cause this bug.
- Undefined strings print as 0 instead of nothing.
Known Memory Map:
0000 - 0FFF: Main ROM
1000 - 13FF: Keyboard
1400 - 17FF: /WAIT circuit
@ -33,7 +65,7 @@
2000 - 3FFF: Mirror of 0000 - 1FFF.
4000 - up : Extra RAM (required for hack versions)
Hack versions:
Hack versions:
- They are fitted with Basic 3.x, require more RAM, and use hardware scrolling.
- No schematic has been found, so the code is educated guesswork.
- The ZX process is still to be worked out. For now, we return 0xF7 to finish.
@ -41,7 +73,7 @@
-- Y = USR(0F000H)
-- Commands are S (substitute), M (move), T (test), G (go), Q (quit)
To Do:
To Do:
- Need software
- Fix cassette
- Hack versions: fix the ZX process
@ -53,6 +85,7 @@
#include "machine/z80daisy.h"
#include "machine/z80ctc.h"
#include "imagedev/cassette.h"
#include "sound/wave.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
@ -64,6 +97,7 @@ public:
bcs3_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_screen(*this, "screen")
, m_ctc(*this, "ctc")
, m_p_chargen(*this, "chargen")
, m_p_videoram(*this, "videoram")
@ -71,36 +105,38 @@ public:
, m_io_keyboard(*this, "KEY.%u", 0)
{ }
void bcs3(machine_config &config);
void bcs3a(machine_config &config);
void bcs3b(machine_config &config);
void init_bcs3a();
void init_bcs3b();
void init_bcs3c();
void init_bcs3d();
private:
DECLARE_READ8_MEMBER(keyboard_r);
DECLARE_READ8_MEMBER(video_r);
DECLARE_READ8_MEMBER(zx_r);
DECLARE_WRITE_LINE_MEMBER(ctc_z0_w);
DECLARE_WRITE_LINE_MEMBER(ctc_z1_w);
void init_bcs3a();
void init_bcs3b();
void init_bcs3c();
void init_bcs3d();
u32 screen_update_bcs3(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
u32 screen_update_bcs3a(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void bcs3a(machine_config &config);
void bcs3(machine_config &config);
void bcs3b(machine_config &config);
void bcs3_io(address_map &map);
void bcs3_mem(address_map &map);
void bcs3a_mem(address_map &map);
private:
bool m_cass_bit;
bool m_cassbit;
u8 s_curs;
u8 s_init;
u8 s_rows;
u8 s_cols;
required_device<z80_device> m_maincpu;
required_device<screen_device> m_screen;
required_device<z80ctc_device> m_ctc;
required_region_ptr<u8> m_p_chargen;
required_shared_ptr<u8> m_p_videoram;
required_device<cassette_image_device> m_cass;
optional_device<cassette_image_device> m_cass;
required_ioport_array<10> m_io_keyboard;
};
@ -108,7 +144,7 @@ READ8_MEMBER( bcs3_state::keyboard_r )
{
u8 i, data = 0;
if (offset == 0)
if (offset == 0 && m_cass)
data = (m_cass->input() > +0.01) ? 0x80 : 0;
offset ^= 0x3ff;
@ -334,13 +370,15 @@ GFXDECODE_END
WRITE_LINE_MEMBER( bcs3_state::ctc_z0_w )
{
m_ctc->trg1(state);
if (state)
if (state && m_cass)
{
m_cass_bit ^= 1;
m_cass->output(m_cass_bit ? -1.0 : +1.0);
m_cassbit ^= 1;
m_cass->output(m_cassbit ? -1.0 : +1.0);
}
}
// The manual says the cassette pulses come from here, but
// it's total silence during cassette saving.
WRITE_LINE_MEMBER( bcs3_state::ctc_z1_w )
{
m_ctc->trg2(state);
@ -393,13 +431,13 @@ void bcs3_state::bcs3(machine_config &config)
m_maincpu->set_daisy_config(daisy_chain_intf);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(50);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
screen.set_size(28*8, 12*10);
screen.set_visarea_full();
screen.set_screen_update(FUNC(bcs3_state::screen_update_bcs3));
screen.set_palette("palette");
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(50);
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
m_screen->set_size(28*8, 12*10);
m_screen->set_visarea_full();
m_screen->set_screen_update(FUNC(bcs3_state::screen_update_bcs3));
m_screen->set_palette("palette");
GFXDECODE(config, "gfxdecode", "palette", gfx_bcs3);
PALETTE(config, "palette", palette_device::MONOCHROME);
@ -407,11 +445,24 @@ void bcs3_state::bcs3(machine_config &config)
m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_ctc->zc_callback<0>().set(FUNC(bcs3_state::ctc_z0_w));
m_ctc->zc_callback<1>().set(FUNC(bcs3_state::ctc_z1_w));
CASSETTE(config, m_cass);
}
void bcs3_state::bcs3a(machine_config &config)
{
bcs3(config);
m_maincpu->set_addrmap(AS_PROGRAM, &bcs3_state::bcs3a_mem);
m_screen->set_size(29*8, 12*10);
m_screen->set_visarea(0, 29*8-1, 0, 12*10-1);
m_screen->set_screen_update(FUNC(bcs3_state::screen_update_bcs3a));
CASSETTE(config, m_cass);
/* sound hardware */
SPEAKER(config, "mono").front_center();
WAVE(config, "wave", "cassette").add_route(ALL_OUTPUTS, "mono", 0.05);
}
void bcs3_state::bcs3b(machine_config &config)
{
/* basic machine hardware */
Z80(config, m_maincpu, XTAL(7'000'000) /2);
@ -420,13 +471,13 @@ void bcs3_state::bcs3a(machine_config &config)
m_maincpu->set_daisy_config(daisy_chain_intf);
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_refresh_hz(50);
screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
screen.set_size(29*8, 12*10);
screen.set_visarea_full();
screen.set_screen_update(FUNC(bcs3_state::screen_update_bcs3a));
screen.set_palette("palette");
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(50);
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
m_screen->set_size(40*8, 24*10);
m_screen->set_visarea_full();
m_screen->set_screen_update(FUNC(bcs3_state::screen_update_bcs3a));
m_screen->set_palette("palette");
GFXDECODE(config, "gfxdecode", "palette", gfx_bcs3);
PALETTE(config, "palette", palette_device::MONOCHROME);
@ -436,13 +487,10 @@ void bcs3_state::bcs3a(machine_config &config)
m_ctc->zc_callback<1>().set(FUNC(bcs3_state::ctc_z1_w));
CASSETTE(config, m_cass);
}
void bcs3_state::bcs3b(machine_config &config)
{
bcs3a(config);
subdevice<screen_device>("screen")->set_size(40*8, 24*10);
subdevice<screen_device>("screen")->set_visarea(0, 40*8-1, 0, 24*10-1);
/* sound hardware */
SPEAKER(config, "mono").front_center();
WAVE(config, "wave", "cassette").add_route(ALL_OUTPUTS, "mono", 0.05);
}
@ -452,6 +500,7 @@ ROM_START( bcs3 )
//ROM_LOAD( "se24.bin", 0x0000, 0x0800, CRC(268de5ee) SHA1(78784945956c1b0282a4e82ad55e7c3a77389e50))
ROM_LOAD( "se24_000.d6", 0x0000, 0x0400, CRC(157a0d28) SHA1(0a6666c289b95d98128fd282478dff6319031b6e) )
ROM_LOAD( "se24_400.d7", 0x0400, 0x0400, CRC(2159de0f) SHA1(09b567e750931019de914f25d5ab1e4910465de6) )
// Cassette rom goes here starting at 0x0800 ... but did this rom ever exist??
ROM_REGION( 0x0400, "chargen", 0 )
ROM_LOAD( "bcs_zg_24.d21", 0x0000, 0x0400, CRC(eaed9d84) SHA1(7023a6187cd6bd0c6489d76ff662453f14e5b636))
@ -498,7 +547,7 @@ ROM_END
/* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1984, bcs3, 0, 0, bcs3, bcs3, bcs3_state, empty_init, "Eckhard Schiller", "BCS 3 rev 2.4", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW )
COMP( 1984, bcs3, 0, 0, bcs3, bcs3, bcs3_state, empty_init, "Eckhard Schiller", "BCS 3 rev 2.4", MACHINE_NO_SOUND_HW )
COMP( 1986, bcs3a, bcs3, 0, bcs3a, bcs3, bcs3_state, init_bcs3a, "Eckhard Schiller", "BCS 3 rev 3.1 29-column", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW )
COMP( 1986, bcs3b, bcs3, 0, bcs3b, bcs3, bcs3_state, init_bcs3b, "Eckhard Schiller", "BCS 3 rev 3.1 40-column", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW )
COMP( 1986, bcs3c, bcs3, 0, bcs3a, bcs3, bcs3_state, init_bcs3c, "Eckhard Schiller", "BCS 3 rev 3.2", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW )