Home Page
Posted By: Ensjo CCE MC-1000 - 07/25/09 03:23 AM
I am Emerson José Silveira da Costa <emerson.costa@gmail.com>, a Brazilian owner of a CCE MC-1000. I also have a wiki on this machine, and would love to see it fully implemented in MESS.

I would like to help. I know some details of the hardware. I also know some C and could even code, if I had a tutorial on the files and functions that MESS uses.
Posted By: Ensjo Re: CCE MC-1000 - 08/10/09 03:22 PM
Current MC-1000 driver code:
http://git.redump.net/cgit.cgi/mess/tree/src/mess/drivers/mc1000.c

Info on MC-1000 to help the emulating process:
http://ensjo.wikispaces.com/MC-1000+on+JEMU

~~~~~

I'll try to interpret the code and then comment on it.
Posted By: Just Desserts Re: CCE MC-1000 - 08/10/09 05:20 PM
Originally Posted By Ensjo
I am Emerson José Silveira da Costa <emerson.costa@gmail.com>, a Brazilian owner of a CCE MC-1000. I also have a wiki on this machine, and would love to see it fully implemented in MESS.

I would like to help. I know some details of the hardware. I also know some C and could even code, if I had a tutorial on the files and functions that MESS uses.


Some file-related advice: For the most part, the only files you'll need to deal with are in src/mess/, and possibly src/mame/machine/ and src/mame/includes/ for some peripheral chips. CPU-specific files are located in src/emu/cpu/, but that would be the only reason to venture into src/emu/ for any reason.

If you have specific questions that you'd like to know more about, that would probably allow us to help you better. smile
Posted By: Ensjo Re: CCE MC-1000 - 08/10/09 06:47 PM
Well... for one, I see three memory-related code sections at mc1000.c... Memory Banking, Memory Maps and setup memory banking... I (still) don't get exactly the difference.

Someone REALLY should set up a M.E.S.S. programming tutorial somewhere. smile
Posted By: Just Desserts Re: CCE MC-1000 - 08/10/09 09:23 PM
Originally Posted By Ensjo
Well... for one, I see three memory-related code sections at mc1000.c... Memory Banking, Memory Maps and setup memory banking... I (still) don't get exactly the difference.

Someone REALLY should set up a M.E.S.S. programming tutorial somewhere. smile


First, Memory Maps are used to describe a range of addresses belonging to a CPU. In the case of the Z80, they can be Program addresses, or I/O addresses. Program addresses are typically used by things like ROM, RAM, video RAM, and some devices. I/O addresses are typically used for things like direct access to peripherals like audio / video chips, cassette interfaces, disk drives, keyboards, joysticks, and so on. Each entry in the memory map contains a starting address, an ending address, and a Read, Write, or Read + Write handler. The purpose of the handler is to handle reads and writes from those addresses.

Memory banking is a technique that was used by some computers, game consoles, and arcade machines to expand the amount of memory that the CPU can use beyond the normal amount. This is accomplished by swapping different sections of RAM and ROM, or "banks", into the same address range at different times. If you need further explanation, don't hesitate to ask.

Setting up memory banking is necessary in the MACHINE_RESET or MACHINE_START functions, because the emulated machine needs to know to what area of ROM or RAM a bank is pointing when it starts up. Again, if you need a more in-depth explanation, feel free to ask. smile
Posted By: Stiletto Re: CCE MC-1000 - 08/11/09 03:03 AM
Originally Posted By Ensjo
Someone REALLY should set up a M.E.S.S. programming tutorial somewhere. smile


Good stuff (hopefully not too outdated) on MAMEDEV Wiki:
http://mamedev.org/devwiki/index.php/How_MAME_Works

See also Programming Docs:
http://mess.redump.net/#documentation

There's another, much older, how-to made by... Brian McPhail? ... for some programming website, but I forgot when and where. I think it was around MAME 0.110-series. (Anyone remember?)
[EDIT] Wow, I have a good memory - and I figured out the magical Google query: http://www.codeproject.com/KB/cpp/vcmame.aspx
From 2003, so that would be MAME 0.72. Pretty outdated.

There's also some REALLY old how-to's written by Dan Boris on how to do things like convert schematics into an arcade driver, but they date from 1998-1999 or so.
http://www.atarihq.com/danb/emulation.shtml
Posted By: Ensjo Re: CCE MC-1000 - 08/12/09 01:47 PM
Originally Posted By Just Desserts
Memory Maps are used to describe a range of addresses belonging to a CPU. [...]

Memory banking is a technique [...] to expand the amount of memory that the CPU can use beyond the normal amount. This is accomplished by swapping different sections of RAM and ROM, or "banks", into the same address range at different times.


I understand the concepts. I just don't get exactly what each section of code is doing. Tell me if I get it right:

This section of code just defines the possible ranges of memory. (It neither allocates memory for the banks, nor sets which bank is active.)

(Why does the range 0x2800~0x3fff is defined differently? It just says "AM_RAM", not "AM_RAMBANK(n)"? Is this how one defines a non-switchable range?)

Then... this section of code under MACHINE_START defines the banks that can be active in each range of memory.

(Is this where the memory is actually allocated for each bank? By the way, I don't see any memory allocation for the non-switchable range 0x2800~0x3fff above.)

The banks that will be active are selected by means of the memory_set_bank() function call.

Then comes the bankswitch function... I would expect it to use make a lot of memory_set_bank() function calls based on the state of the machine... but it calls a memory_install_readwrite8_handler() instead. What is the difference between both functions?
Posted By: Just Desserts Re: CCE MC-1000 - 08/12/09 05:51 PM
Originally Posted By Ensjo
I understand the concepts. I just don't get exactly what each section of code is doing. Tell me if I get it right:

This section of code just defines the possible ranges of memory. (It neither allocates memory for the banks, nor sets which bank is active.)

(Why does the range 0x2800~0x3fff is defined differently? It just says "AM_RAM", not "AM_RAMBANK(n)"? Is this how one defines a non-switchable range?)


Correct!

Then... [url=http://git.redump.net/cgit....section of code under MACHINE_START defines the banks that can be active in each range of memory.

(Is this where the memory is actually allocated for each bank? By the way, I don't see any memory allocation for the non-switchable range 0x2800~0x3fff above.)[/quote]

Memory allocation for memory maps is handled entirely by the core. If you want to be able to access the storage area directly, supply an AM_BASE() parameter for that entry in the address map, like so:

At the top of the file:

static UINT8* ramarea;

...

AM_RANGE(start, end) AM_RAM AM_BASE(&ramarea)

When the driver is initialized, ramarea will be automatically updated to point to the internal memory region.


Originally Posted By Ensjo
The banks that will be active are selected by means of the memory_set_bank() function call.

Then comes the bankswitch function... I would expect it to use make a lot of memory_set_bank() function calls based on the state of the machine... but it calls a memory_install_readwrite8_handler() instead. What is the difference between both functions?


mc1000_bankswitch is called by the mc6847_attr_w and mc6845_ctrl_w write handlers. In mc1000_bankswitch, the majority of what it's doing is conditionally mapping or unmapping regions of memory depending on how much expansion memory is currently installed as well as what bank is being assigned to the MC6847 and MC6845 peripheral chips.

The installed read/write functions for SMH_BANK(1) and SMH_BANK(2) never appear to change, though, so it might be a good idea to move line 42 and line 45 to a DRIVER_INIT function. There are plenty of examples of how to use DRIVER_INIT in various drivers.
Posted By: Curt Coder Re: CCE MC-1000 - 08/12/09 08:58 PM
Originally Posted By Just Desserts
The installed read/write functions for SMH_BANK(1) and SMH_BANK(2) never appear to change, though, so it might be a good idea to move line 42 and line 45 to a DRIVER_INIT function. There are plenty of examples of how to use DRIVER_INIT in various drivers.


They can be placed in MACHINE_START just as well. I haven't gotten around to optimizing the driver yet, I just wanted to see it boot smile
Posted By: Ensjo Re: CCE MC-1000 - 08/13/09 11:35 AM
Originally Posted By Curt Coder
[...] I just wanted to see it boot smile


Hey, Curt... I downloaded MESS and run MC-1000... All I got was a black screen. Did you really see it boot? confused
Posted By: Anna Wu Re: CCE MC-1000 - 08/13/09 11:43 AM
SVN r5421 or official 0.133

Seems to be ok. Unfortunately, I can not test the tape function because of missing software.


Posted By: Anna Wu Re: CCE MC-1000 - 08/13/09 05:03 PM
The tape is playing but ignore the end of tape time.

Ensjo, I made following :

1.) Convert the .bas file to .bin (BAS2BIN)
2.) Convert the .bin file to .wav (BIN2WAV)
Posted By: Anna Wu Re: CCE MC-1000 - 08/13/09 05:45 PM
Originally Posted By Ensjo
Originally Posted By Curt Coder
[...] I just wanted to see it boot smile


Hey, Curt... I downloaded MESS and run MC-1000... All I got was a black screen. Did you really see it boot? confused


Use the version 0.133, not 0.132 !
The romset " mc1000.zip " content following :

mc1000.ic12
SHA1: fd766f5ea4481ef7fd4df92cf7d8397cc2b5a6c4
CRC32: 750c95f0

mc1000.ic17
SHA1: 9480270e67a5db2e7de8bc5c8b9e0bb210d4142b
CRC32: 8e78d80d

It seems, the ic12/ic17 files (8192 bytes) are from the splitted mc1000.rom (16384 bytes)

Posted By: Ensjo Re: CCE MC-1000 - 08/13/09 05:51 PM
Originally Posted By Anna Wu
Use the version 0.133, not 0.132 !


Ugh, mess.org is blocked at work, I can't download it here now. I only have access to mess.redump.net, where I've downloaded 0.132 from.

Originally Posted By Anna Wu
The romset " mc1000.zip " content following :

mc1000.ic12
SHA1: fd766f5ea4481ef7fd4df92cf7d8397cc2b5a6c4
CRC32: 750c95f0

mc1000.ic17
SHA1: 9480270e67a5db2e7de8bc5c8b9e0bb210d4142b
CRC32: 8e78d80d


Aha, my mc1000.zip contains only one file mc1000.rom. I'll try to split it and see if it works. Thanks.
Posted By: Anna Wu Re: CCE MC-1000 - 08/13/09 05:56 PM
MESS 0.133
You need the windows binary ?
Posted By: Ensjo Re: CCE MC-1000 - 08/13/09 06:07 PM
Originally Posted By Anna Wu
MESS 0.133
You need the windows binary ?


Yes. Could you send it to me via e-mail? emerson.costa@gmail.com
Posted By: Anna Wu Re: CCE MC-1000 - 08/13/09 06:09 PM
You can also try Bobz Automatic MESS SVN Build
Posted By: Ensjo Re: CCE MC-1000 - 08/13/09 06:27 PM
IT'S ALIVE!!! \o/ Thank you Anna! laugh
Posted By: Anna Wu Re: CCE MC-1000 - 08/13/09 06:30 PM
Now you can test the tape function. Maybe you have more luck. smile
Posted By: Ensjo Re: CCE MC-1000 - 08/13/09 06:32 PM
I'm still new to M.E.S.S., so I still need to discover how to do it. smile Are the .WAV files all that we need?
Posted By: Anna Wu Re: CCE MC-1000 - 08/13/09 06:35 PM
Originally Posted By Ensjo
I'm still new to M.E.S.S., so I still need to discover how to do it. smile Are the .WAV files all that we need?


Yes.
If you use the MESS GUI you will see the supported devices and the supported image types.
Posted By: Ensjo Re: CCE MC-1000 - 08/13/09 08:07 PM
Originally Posted By Anna Wu
The tape is playing but ignore the end of tape time.


Indeed, I just see that the line of code that would bring the cassette data into the machine is commented (I don't know why, that seems correct to me):

http://git.redump.net/cgit.cgi/mess/tree/src/mess/drivers/mc1000.c#n326

// data &= (((cassette_input(state->cassette) < +0.0) << 7) | 0x7f);

(The sound of the cassette becomes 0 or 1, and becomes the most signifying bit of the byte that is served by the selected port.)
Posted By: judge Re: CCE MC-1000 - 08/13/09 08:19 PM
It could be me, but I'd kinda expect to see something like:
Code:
data &= (((cassette_input(state->cassette) < +0.0 ? 0 : 1) << 7) | 0x7f);


or

Code:
data &= (((cassette_input(state->cassette) < +0.0 ? 1 : 0) << 7) | 0x7f);
Posted By: Justin Re: CCE MC-1000 - 08/14/09 04:36 AM
Originally Posted By Ensjo
I only have access to mess.redump.net, where I've downloaded 0.132 from.


Thanks for reminding me to go upload 0.133 to mess.redump.net smile
Posted By: Spirantho Re: CCE MC-1000 - 08/14/09 07:43 AM
As it happens, I have a CCE MC-1000 at home (doesn't everybody in Wales?). I can try and save out a BASIC "Hello World" program to a WAV file if you want...?
Posted By: judge Re: CCE MC-1000 - 08/14/09 09:26 AM
I suppose that would be useful for debugging.
Posted By: Curt Coder Re: CCE MC-1000 - 08/14/09 09:31 AM
Originally Posted By Spirantho
As it happens, I have a CCE MC-1000 at home (doesn't everybody in Wales?). I can try and save out a BASIC "Hello World" program to a WAV file if you want...?


Please do, I don't have any CCE WAV files to test with.
Posted By: Ensjo Re: CCE MC-1000 - 08/19/09 04:04 PM
Originally Posted By Curt Coder
I don't have any CCE WAV files to test with.


Have you tried to use these (MS-DOS) applications for converting .BAS files into .WAV files?

http://mc-1000.wikispaces.com/Cassete#toc0

Download the .zip file linked by the word "aqui", then you can use the four applications:

BAS2BIN.EXE filename.BAS

From a plain text file containing a BASIC program, generates a filename.BIN containing all the bytes that are to be saved to tape (header, then the tokenized version of the program).

You can get a handful of BASIC programs here.

BIN2WAV.EXE filename.BIN

Generates a filename.WAV file from the .BIN file. The .WAV file generated has an unusual sample rate of 2757 samples/second (instead of 44100 or something like that), tuned to produce .WAV files as small as possible, with one sample per peak or valley. But the sound seems to get distorted in some players. For instance, it plays well in Windows Sound Recorder, but differently in Windows Media Player. (Higher frequency becomes mute.) Would M.E.S.S. read them well?

WAV2BIN.EXE filename.WAV

Analyzes a .WAV file to generate a .BIN file. Accepts files with any sample rate.

LISTBIN.EXE filename.BIN

Lists the BASIC program contained in a .BIN file. It doesn't generate a .BAS file, but you can redirect (>) the output to a file.

NOTE: These applications were made with an old QuickBasic, so file names must have no more than 8 characters.
Posted By: Anna Wu Re: CCE MC-1000 - 08/19/09 05:55 PM
Originally Posted By Ensjo
Originally Posted By Curt Coder
I don't have any CCE WAV files to test with.


Have you tried to use these (MS-DOS) applications for converting .BAS files into .WAV files?

http://mc-1000.wikispaces.com/Cassete#toc0

Download the .zip file linked by the word "aqui", then you can use the four applications:

BAS2BIN.EXE filename.BAS

From a plain text file containing a BASIC program, generates a filename.BIN containing all the bytes that are to be saved to tape (header, then the tokenized version of the program).

You can get a handful of BASIC programs here.

BIN2WAV.EXE filename.BIN

Generates a filename.WAV file from the .BIN file. The .WAV file generated has an unusual sample rate of 2757 samples/second (instead of 44100 or something like that), tuned to produce .WAV files as small as possible, with one sample per peak or valley. But the sound seems to get distorted in some players. For instance, it plays well in Windows Sound Recorder, but differently in Windows Media Player. (Higher frequency becomes mute.) Would M.E.S.S. read them well?

WAV2BIN.EXE filename.WAV

Analyzes a .WAV file to generate a .BIN file. Accepts files with any sample rate.

LISTBIN.EXE filename.BIN

Lists the BASIC program contained in a .BIN file. It doesn't generate a .BAS file, but you can redirect (>) the output to a file.

NOTE: These applications were made with an old QuickBasic, so file names must have no more than 8 characters.


I tried without success. See my older posting.

Originally Posted By Anna Wu
The tape is playing but ignore the end of tape time.

Ensjo, I made following :

1.) Convert the .bas file to .bin (BAS2BIN)
2.) Convert the .bin file to .wav (BIN2WAV)
Posted By: Ensjo Re: CCE MC-1000 - 08/19/09 08:14 PM
Originally Posted By Anna Wu
I tried without success. See my older posting.

Originally Posted By Anna Wu
The tape is playing but ignore the end of tape time.

Ensjo, I made following :

1.) Convert the .bas file to .bin (BAS2BIN)
2.) Convert the .bin file to .wav (BIN2WAV)


Anna, but you did manage to produce a .wav file with the programs, right? That's one thing. That the emulator still can't read the .wav files is another issue. But .wav files will be needed to make the tests, that's why I explained about these applications.

Curt: Why is this line commented in the code?
Code:
// data &= (((cassette_input(state->cassette) < +0.0) << 7) | 0x7f);

This prevents the emulator from "hearing" the .wav files. Is the line commented because it generates some error? Does this suggestions from Judge solve the problem?

Originally Posted By judge
It could be me, but I'd kinda expect to see something like:
Code:
data &= (((cassette_input(state->cassette) < +0.0 ? 0 : 1) << 7) | 0x7f);

or
Code:
data &= (((cassette_input(state->cassette) < +0.0 ? 1 : 0) << 7) | 0x7f);
Posted By: Anna Wu Re: CCE MC-1000 - 08/19/09 10:02 PM
Yes.
Posted By: Curt Coder Re: CCE MC-1000 - 08/20/09 07:36 AM
Originally Posted By Ensjo
Curt: Why is this line commented in the code?
Code:
// data &= (((cassette_input(state->cassette) < +0.0) << 7) | 0x7f);

This prevents the emulator from "hearing" the .wav files. Is the line commented because it generates some error?


It was commented out because it messed with the keyboard. It is implemented in current svn, but tapes still don't load. The screen changes colors a couple of times during loading, but after the tape ends, there is no program.
Posted By: Ensjo Re: CCE MC-1000 - 08/20/09 01:15 PM
Originally Posted By Curt Coder
Originally Posted By Ensjo
Curt: Why is this line commented in the code?
Code:
// data &= (((cassette_input(state->cassette) < +0.0) << 7) | 0x7f);

This prevents the emulator from "hearing" the .wav files. Is the line commented because it generates some error?


It was commented out because it messed with the keyboard.


Yes, it happens in the actual machine as well, since the tape signal is "in the same wire" as the CTRL key. Just imagine trying to type something while the CTRL key is flickering madly. smile

Originally Posted By Curt Coder
It is implemented in current svn, but tapes still don't load. The screen changes colors a couple of times during loading, but after the tape ends, there is no program.


Aha, I downloaded the current version and confirm what you say. It's funny that I have converted some real (machine code) game tapes .WAV into .BIN and back into .WAV and they are loading fine in M.E.S.S. But the .BAS->.BIN->.WAV files don't finish loading... it's as if, say, a last byte is missing or something like that. But theses files DID load fine in my real MC-1000 when I tested them! Something to review...

I have an ALTERNATE SOLUTION, though: The recording function is working fine, so you can type and SAVE a program in M.E.S.S., and LOAD it later. I tested it, and it worked.

BUG NOTE (in the actual machine, not in your implementation smile ): When you load a program saved without the optional filename, it runs automatically after loading. But for some reason the PRINT commands don't get displayed on screen! Only after the program ends (or is stopped with CTRL+C) and you run it again it works properly. MC-1000 is such a weird machine... :p )

You can save a program with a filename up to 5 characters long, but then you'll have to remember the filename to load it back.
Posted By: judge Re: CCE MC-1000 - 08/20/09 01:25 PM
This sounds a lot like an issue i encountered before with a different system (exidy sorcerer). Is there some feedbackish frequency detecting hardware in the original system?
Posted By: Ensjo Re: CCE MC-1000 - 08/20/09 01:30 PM
None that I'm aware of. smirk
Posted By: judge Re: CCE MC-1000 - 08/20/09 01:53 PM
Are there any schematics available of the system somewhere?
Posted By: Ensjo Re: CCE MC-1000 - 08/20/09 01:57 PM
Unfortunately the only schematics I ever found is awfully blurred. frown
Posted By: Stiletto Re: CCE MC-1000 - 08/20/09 02:02 PM
Crap. With that level of quality, you'll really need high-definition PCB scans and/or photos and someone willing to make a new schematic based on this poor scan.

Or you'll need to find a better source (if possible).
Posted By: judge Re: CCE MC-1000 - 08/20/09 03:42 PM
At what frequencies are the signals stored on tape? 1200hz and 2400hz?
Posted By: Ensjo Re: CCE MC-1000 - 08/20/09 04:03 PM
Curt, the graphic modes aren't working fine. I found there's a problem in this section of code:
Code:
  277 static const UINT8 *mc1000_get_video_ram(running_machine *machine, int scanline)
  278 {
  279     mc1000_state *state = machine->driver_data;
  280 
  281     return state->mc6847_video_ram + (scanline / 12) * 0x20;
  282 }

If I understand this correctly, this causes MC6847 to get the same 32 bytes (one screen row) from the VRAM during 12 scanlines. While this is correct for the text and semigraphic modes (where each character/box is composed of 12 lines), it's not true for the graphic modes.

If the MC6847 works the way I guess it works, these return values should do:
Code:
   12     AG  AS  INTEXT  INV  GM2  GM1  GM0
   13     --  --  ------  ---  ---  ---  ---
   14      0   0       0    0    X    X    X  Internal Alphanumerics
   15      0   0       0    1    X    X    X  Internal Alphanumerics Inverted
   16      0   0       1    0    X    X    X  External Alphanumerics
   17      0   0       1    1    X    X    X  External Alphanumerics Inverted
   18      0   1       0    X    X    X    X  Semigraphics 4
   19      0   1       1    X    X    X    X  Semigraphics 6

For these: return state->mc6847_video_ram + (scanline / 12) * 0x20;

   20      1   X       X    X    0    0    0  Graphics CG1 (64x64x4)    (16 bpr)
   21      1   X       X    X    0    0    1  Graphics RG1 (128x64x2)   (16 bpr)

For these: return state->mc6847_video_ram + (scanline / 3) * 0x10;

   22      1   X       X    X    0    1    0  Graphics CG2 (128x64x4)   (32 bpr)

For this: return state->mc6847_video_ram + (scanline / 3) * 0x20;

   23      1   X       X    X    0    1    1  Graphics RG2 (128x96x2)   (16 bpr)

For this: return state->mc6847_video_ram + (scanline / 2) * 0x10;

   24      1   X       X    X    1    0    0  Graphics CG3 (128x96x4)   (32 bpr)

For this: return state->mc6847_video_ram + (scanline / 2) * 0x20;

   25      1   X       X    X    1    0    1  Graphics RG3 (128x192x2)  (16 bpr)

For this: return state->mc6847_video_ram + (scanline / 2) * 0x10;

   26      1   X       X    X    1    1    0  Graphics CG6 (128x192x4)  (32 bpr)
   27      1   X       X    X    1    1    1  Graphics RG6 (256x192x2)  (32 bpr)

For these: return state->mc6847_video_ram + scanline * 0x20;
Posted By: Ensjo Re: CCE MC-1000 - 08/20/09 06:19 PM
Originally Posted By judge
At what frequencies are the signals stored on tape? 1200hz and 2400hz?

According to my analysis of .wav recorded directly from the MC-1000 MIC port, each short (bit 1) wave (1 peak + 1 valley) takes about 16 samples at 22050 samples per second. That gives 5512.5 waves per second. The long (bit 0) wave is twice as long, so half the frequency. Then, if my calculations are right:

short (bit 1) wave: 5512.5 Hz
long (bit 0) wave: 2756.25 Hz
Posted By: Ensjo Re: CCE MC-1000 - 08/20/09 06:55 PM
By the way... Curt, I see that the .WAV file generated by M.E.S.S. MC-1000 is the inverse of what is generated by a real MC-1000: instead of peaks and valleys of the same length, we have valleys and peaks.

Example: a bit sequence "10" should generate:
Code:
  1     0
+-+ +---+
| | |   |   |
  +-+   +---+

But instead it's generating:
Code:
  1     0
  +-+   +---+
| | |   |   |
+-+ +---+

It seems the +1.0 and -1.0 below should be switched:
Code:
  301 static WRITE8_DEVICE_HANDLER( keylatch_w )
  302 {
  303     mc1000_state *state = device->machine->driver_data;
  304 
  305     state->keylatch = data;
  306 
  307     cassette_output(state->cassette, BIT(data, 7) ? +1.0 : -1.0);
  308 }
Posted By: Curt Coder Re: CCE MC-1000 - 08/21/09 11:38 AM
Cassette output polarity swapped, and hopefully fixed graphics modes in svn now.
Posted By: Ensjo Re: CCE MC-1000 - 08/21/09 12:26 PM
Originally Posted By Curt Coder
The screen changes colors a couple of times during loading, but after the tape ends, there is no program.

I wonder it that's caused by the same problem that I identified before, regarding the polarity of the cassette output. Maybe the polarity of the cassette INPUT is also inverted?

Try to change the "<" sign below into ">" or ">=" and see if you can successfully LOAD the .wav files generated by BIN2WAV.EXE.
Code:
  345     if (cassette_input(state->cassette) < +0.0) data &= 0x7f;


Edit: On a second thought, maybe you should try "<=" too.
Posted By: Ensjo Re: CCE MC-1000 - 08/21/09 12:47 PM
Hey, Curt. More on the video modes...

MC-1000 doesn't provide the external ROM that MC6847 may use to get the characters bytes when it is in "External Alphanumerics" mode (AG=0, AS=0, INTEXT=1). Currently the emulation doesn't provide a cfg.get_char_rom at VIDEO_START, and thus it works as if a byte 0x00 is read. In the actual machine, though, MC6847 puts the character code byte into the wires trying to reach the external character ROM, and then reads the wires again for the pattern... but it gets the very same byte that it put there, i.e., the ASCII code of the character.

I think you could add something like...

Code:
UINT8 mc1000_get_char_rom(running_machine *machine, UINT8 ch,int line)
{
   return ch;
}

Then @ VIDEO_START:
Code:
cfg.get_char_rom = mc1000_get_char_rom;

The result is not usefull at all, as you can see by accessing this MC-1000 Java emulator and typing
Code:
POKE 245,33

but that's how it works, so here you have it.
Posted By: Ensjo Re: CCE MC-1000 - 08/21/09 01:50 PM
Hey, Curt, there's a bug in the MC6847 implementation!

Compare this code in current M.E.S.S. MC-1000 and in BrMC-1000:
Code:
10 GR : OUT 128,96
20 FOR A = 0 TO 255
30 POKE 32768 + A, A
40 NEXT
50 CALL 49158 : REM PRESS ANY KEY TO EXIT
60 TEXT

(Real MC-1000 works just like BrMC-1000 here.)

The difference is due to an error in http://git.redump.net/cgit.cgi/mess/tree/src/mess/video/m6847.c:
Code:
 1732             /* semigraphics 6 */
 1733             ch = (byte & 0x3F) + 0x60;
 1734             *fg = ((byte >> 5) & 0x03) + ((attr & M6847_CSS) ? BUFF : GREEN);

">> 5" should be ">> 6".
Posted By: Anna Wu Re: CCE MC-1000 - 08/21/09 04:11 PM
I will check following possibilities :

if (cassette_input(state->cassette) <= +0.0) data &= 0x7f;
or
if (cassette_input(state->cassette) > +0.0) data &= 0x7f;
or
if (cassette_input(state->cassette) >= +0.0) data &= 0x7f;


Posted By: Anna Wu Re: CCE MC-1000 - 08/21/09 04:36 PM
Originally Posted By Anna Wu
I will check following possibilities :

if (cassette_input(state->cassette) <= +0.0) data &= 0x7f;
or
if (cassette_input(state->cassette) > +0.0) data &= 0x7f;
or
if (cassette_input(state->cassette) >= +0.0) data &= 0x7f;




Test data : aventura.wav (168522 bytes)
I tried, the tape is playing but still ignore the end of tape time (No OK).

PS:For each possibility, the mc1000.o file was deleted before.
Posted By: judge Re: CCE MC-1000 - 08/21/09 04:42 PM
Anna Wu: Could you send me that .wav file?
Posted By: Anna Wu Re: CCE MC-1000 - 08/21/09 04:50 PM
Originally Posted By judge
Anna Wu: Could you send me that .wav file?


No

but I can show you the posted Link > "aqui" smile

Posted By: judge Re: CCE MC-1000 - 08/21/09 04:55 PM
Ah, thanks. I thought those were only ms-dos executables wink
Posted By: Curt Coder Re: CCE MC-1000 - 08/21/09 05:22 PM
Added the MC6847 fixes (shift and charROM) to svn. Does it look right now?
Posted By: Ensjo Re: CCE MC-1000 - 08/21/09 05:33 PM
Originally Posted By Curt Coder
Added the MC6847 fixes (shift and charROM) to svn. Does it look right now?


Due to my access restrictions (firewall at work & internet still not available after moving to a new house), I can only download BobZ Automated MESS SVN Build... The next will be available only tomorrow... So probably only Monday I'll be able to check everything. ¦´-(
Posted By: Anna Wu Re: CCE MC-1000 - 08/21/09 06:04 PM
Originally Posted By Ensjo
Originally Posted By Curt Coder
Added the MC6847 fixes (shift and charROM) to svn. Does it look right now?


Due to my access restrictions (firewall at work & internet still not available after moving to a new house), I can only download BobZ Automated MESS SVN Build... The next will be available only tomorrow... So probably only Monday I'll be able to check everything. ¦´-(


You have a PM.
Posted By: Ensjo Re: CCE MC-1000 - 08/21/09 06:22 PM
Originally Posted By Anna Wu
I tried, the tape is playing but still ignore the end of tape time (No OK).


I just compared a BASIC program saved by M.E.S.S. turned into .BIN via WAV2BIN to a .BIN of the same program produced by BAS2BIN. It's official now: .BIN files generated by BAS2BIN lack an extra byte at the end. frown

If you somehow manage to add an extra 0x00 byte at the end of the .BIN file, you'll be able to turn it into a working .WAV file.
Posted By: Anna Wu Re: CCE MC-1000 - 08/21/09 06:36 PM
Originally Posted By Ensjo
Originally Posted By Anna Wu
I tried, the tape is playing but still ignore the end of tape time (No OK).


I just compared a BASIC program saved by M.E.S.S. turned into .BIN via WAV2BIN to a .BIN of the same program produced by BAS2BIN. It's official now: .BIN files generated by BAS2BIN lack an extra byte at the end. frown

If you somehow manage to add an extra 0x00 byte at the end of the .BIN file, you'll be able to turn it into a working .WAV file.


You are right. Just load aventura.wav (168558 bytes) and circulos.wav (40350 bytes)and it works. smile
Unfortunately, I not speak spanish or is this portuguese ? frown

Posted By: Ensjo Re: CCE MC-1000 - 08/21/09 07:52 PM
Originally Posted By Anna Wu
Originally Posted By Ensjo
If you somehow manage to add an extra 0x00 byte at the end of the .BIN file, you'll be able to turn it into a working .WAV file.


You are right.


I changed the applications and uploaded them. Now the extra byte is there.

Originally Posted By Anna Wu
Just load aventura.wav (168558 bytes) and circulos.wav (40350 bytes)and it works. smile
Unfortunately, I not speak spanish or is this portuguese ? frown


That's Portuguese. smile

Well... My time's over. See you again on Monday!
Posted By: Anna Wu Re: CCE MC-1000 - 08/21/09 10:43 PM
I convert a bigger file (MP3 to WAV), it is working too.
Game: RESTA UM
TLOAD




Posted By: Duke Re: CCE MC-1000 - 08/22/09 09:28 AM
Originally Posted By Ensjo
Originally Posted By Curt Coder
Added the MC6847 fixes (shift and charROM) to svn. Does it look right now?


Due to my access restrictions (firewall at work & internet still not available after moving to a new house), I can only download BobZ Automated MESS SVN Build... The next will be available only tomorrow... So probably only Monday I'll be able to check everything. ¦´-(


You can use cgit to get the most current source. Just click on the most recent commit and select "Download" (either as zip or tar.bz2).
Posted By: Ensjo Re: CCE MC-1000 - 08/24/09 12:30 PM
Goooooooood morning, Vietnam! It's Monday, another day is shining upon us... Let's see what we've got. smile

Originally Posted By Duke
You can use cgit to get the most current source. Just click on the most recent commit and select "Download" (either as zip or tar.bz2).

I don't have a C compiler/SDK either... frown Any suggestions?

Originally Posted By Anna Wu
Just load aventura.wav [...] and it works. smile Unfortunately, I not speak [...] portuguese[.]

Ah, I forgot to say... It's just the sample adventure given in the old Input Magazine.
Posted By: Duke Re: CCE MC-1000 - 08/24/09 12:39 PM
Originally Posted By Ensjo
I don't have a C compiler/SDK either... frown Any suggestions?

http://mess.redump.net/compiling_mess
Posted By: Ensjo Re: CCE MC-1000 - 08/24/09 01:55 PM
Originally Posted By Curt Coder
Added the MC6847 fixes (shift and charROM) to svn. Does it look right now?

Yes, Curt, the ROM chars do look right.

The change of the shift from ">> 5" to ">> 6" was right, but it comes out that more of MC6847's code still needs to be changed to behave properly. frown The most significative bit of the VRAM byte is lost somewhere, so only two colors are displayed twice, instead of four colors. Gotta check better to find what to change (without breaking what's working, glup).
Posted By: JoJo Re: CCE MC-1000 - 08/24/09 09:17 PM
Originally Posted By Ensjo

Ah, I forgot to say... It's just the sample adventure given in the old Input Magazine.


OMG! The Input Magazine!!! I still have the Italian edition at my parents' home... and this one too!
Posted By: Ensjo Re: CCE MC-1000 - 08/25/09 06:18 PM
Originally Posted By Ensjo
The change of the shift from ">> 5" to ">> 6" was right, but it comes out that more of MC6847's code still needs to be changed to behave properly. frown The most significative bit of the VRAM byte is lost somewhere, so only two colors are displayed twice, instead of four colors. Gotta check better to find what to change (without breaking what's working, glup).


The Semigraphics 6 mode uses all of the bits of the byte read from the VRAM. Bits 7~6 code the foreground color; bits 5~0 code the block pattern. After trying to understand how m6847.c works, I guess that these changes would make Semigraphis 6 work correctly:
Code:
  150     /* 2^7 modes, 256/16 character groups, background/foreground */
  151     UINT8 colordata[128][256/16][2];
  152 
  153     /* 2^7 modes, 256 characters, 12 scanlines */
  154     UINT8 fontdata[128][256][12];

Code:
 1200         bg_color = color(m6847->colordata[attr_index][byte / 16][0]);
 1201         fg_color = color(m6847->colordata[attr_index][byte / 16][1]);

Code:
 1210             char_data = m6847->fontdata[attr_index][byte][scanline % 12];

Code:
 1798         for (byte = 0; byte < 256; byte++)

Try these, then type and run this BASIC program to see if there are four colors:
Code:
10 GR : OUT 128, 96
20 FOR A = 0 TO 255
30 POKE 32768 + A, A
40 NEXT
50 CALL 49158 : REM PRESS ANY KEY TO EXIT
60 TEXT
Posted By: Curt Coder Re: CCE MC-1000 - 08/26/09 08:41 AM
Yes, there is now in svn r5501:

green
yellow
blue
red

stripes on the screen with your changes.

I hope this doesn't break other drivers.
Posted By: Ensjo Re: CCE MC-1000 - 08/26/09 08:08 PM
Originally Posted By Curt Coder
Yes, there is now in svn r5501: green, yellow, blue, red stripes on the screen with your changes.

I hope this doesn't break other drivers.
Me too. smile

Only one thing, though: You forgot to change 128 into 256 in one comment line:
Code:
  153     /* 2^7 modes, 128 characters, 12 scanlines */
  154     UINT8 fontdata[128][256][12];
When the changes appear on the next BobZ Automatic Daily Build I'll check them out.
_________________________________________________

Given that, let's check what's left at the TODO for MC-1000:
Code:
   16     - cassette
   17     - interrupt from NE555
   18     - xtal frequency?
   19     - Z80 wait at 0x0000-0x1fff when !hsync & !vsync
   20     - MC6847 color artifacting is broken
   21     - 80-column card (MC6845)
   22     - Charlemagne / GEM-1000 / Junior Computer
  • Cassette seems to be working right already.
  • MC6847 does implement (NTSC) artifacts. Why you say it is broken? Because it doesn't implement PAL-M artifacts?
  • Implementing Charlemagne/GEM-1000 smile depends on someone finding info on that obscure machine other than what's found in Old-Computers.com.
  • As for MC6845 (80-column card)... In this case we would have the machine generating two screens simultaneously. How is this to be handled in M.E.S.S.?
  • I'd need a longer description of the other TODOs.
Posted By: JoJo Re: CCE MC-1000 - 08/26/09 08:56 PM
Originally Posted By Ensjo
  • MC6847 does implement (NTSC) artifacts. Why you say it is broken? Because it doesn't implement PAL-M artifacts?


One of the (very) long-term goals of MAME/MESS is to implement artifacting at core level rather than at device level.

I wonder if, given the specs of the three major standards (NTSC, PAL and SECAM) and the ITU id table, is possible to model (in a mathematical sense) all the possible artifact schemes.

Of course, there will still be a little number of parameters that have to be tweaked by the user (gamma, tint, etc.) but it'd be funny to "connect" e.g. an Oric Atmos to a SECAM-M monitor and see what happens wink

Originally Posted By Ensjo
  • As for MC6845 (80-column card)... In this case we would have the machine generating two screens simultaneously. How is this to be handled in M.E.S.S.?


That's definitely easier to achieve: see the SVI-318 driver. Basically you plot the 32-columns display on screen #1, and the 80-columns display on screen #2: with the proper layout file you can display one of the two screens, or both, at your pleasure!
Posted By: Curt Coder Re: CCE MC-1000 - 08/27/09 12:25 PM
Originally Posted By Ensjo

[*]Cassette seems to be working right already.
[*]MC6847 does implement (NTSC) artifacts. Why you say it is broken? Because it doesn't implement PAL-M artifacts?
[*]Implementing Charlemagne/GEM-1000 smile depends on someone finding info on that obscure machine other than what's found in Old-Computers.com.
[*]As for MC6845 (80-column card)... In this case we would have the machine generating two screens simultaneously. How is this to be handled in M.E.S.S.?
[*]I'd need a longer description of the other TODOs.
[/list]


Cassette/MC6847 comments were obsolete, I removed them.

Implementing the 80-column screen is trivial once we get a dump of the MC6845 character generator ROM. Or does it use video RAM instead?
Posted By: Ensjo Re: CCE MC-1000 - 08/31/09 07:18 PM
Originally Posted By Curt Coder
Implementing the 80-column screen is trivial once we get a dump of the MC6845 character generator ROM. Or does it use video RAM instead?

Uh, I have no info on how MC-1000's 80-column capability was implemented. frown
In order to check if the M.E.S.S. implementation of MC6847 was correct, I wrote a program in my MC-1000 (.wav file) that draws the characters in Resolution Graphics 6 (two-color 256x192) mode (with data from one of the "fontdata" arrays found in file m6847.c) and other bytes so that, alternating between text mode and RG6 mode, the real characters and the characters drawn alternate in the same screen positions, so I could compare and easily perceive any misplaced or lacking pixels.

Code:
10  HGR 
20  OUT 128,158
30  FOR A = 0 TO 511
40  POKE 32768 + A,32
50  NEXT 
60  FOR A = 64 TO 127
70  POKE 32768 + A,A
80  FOR B = 3 TO 9
90  READ C
100  IF C THEN  POKE 32768 + (A AND 224) * 12 + B * 32 + (A AND 31),C
110  NEXT B,A
120  OUT 128,1: FOR A = 1 TO 200: NEXT 
130  OUT 128,159: FOR A = 1 TO 200: NEXT 
140  GOTO 120
10000  REM DADOS DOS CARACTERES
10010  DATA 28,34,2,26,42,42,28
10020  DATA 8,20,34,34,62,34,34
10030  DATA 60,18,18,28,18,18,60
10040  DATA 28,34,32,32,32,34,28
10050  DATA 60,18,18,18,18,18,60
10060  DATA 62,32,32,60,32,32,62
10070  DATA 62,32,32,60,32,32,32
10080  DATA 30,32,32,38,34,34,30
10090  DATA 34,34,34,62,34,34,34
10100  DATA 28,8,8,8,8,8,28
10110  DATA 2,2,2,2,34,34,28
10120  DATA 34,36,40,48,40,36,34
10130  DATA 32,32,32,32,32,32,62
10140  DATA 34,54,42,42,34,34,34
10150  DATA 34,50,42,38,34,34,34
10160  DATA 62,34,34,34,34,34,62
10170  DATA 60,34,34,60,32,32,32
10180  DATA 28,34,34,34,42,36,26
10190  DATA 60,34,34,60,40,36,34
10200  DATA 28,34,16,8,4,34,28
10210  DATA 62,8,8,8,8,8,8
10220  DATA 34,34,34,34,34,34,28
10230  DATA 34,34,34,20,20,8,8
10240  DATA 34,34,34,42,42,54,34
10250  DATA 34,34,20,8,20,34,34
10260  DATA 34,34,20,8,8,8,8
10270  DATA 62,2,4,8,16,32,62
10280  DATA 56,32,32,32,32,32,56
10290  DATA 32,32,16,8,4,2,2
10300  DATA 14,2,2,2,2,2,14
10310  DATA 8,28,42,8,8,8,8
10320  DATA 0,8,16,62,16,8,0
10330  DATA 0,0,0,0,0,0,0
10340  DATA 8,8,8,8,8,0,8
10350  DATA 20,20,20,0,0,0,0
10360  DATA 20,20,54,0,54,20,20
10370  DATA 8,30,32,28,2,60,8
10380  DATA 50,50,4,8,16,38,38
10390  DATA 16,40,40,16,42,36,26
10400  DATA 24,24,24,0,0,0,0
10410  DATA 8,16,32,32,32,16,8
10420  DATA 8,4,2,2,2,4,8
10430  DATA 0,8,28,62,28,8,0
10440  DATA 0,8,8,62,8,8,0
10450  DATA 0,0,0,48,48,16,32
10460  DATA 0,0,0,62,0,0,0
10470  DATA 0,0,0,0,0,48,48
10480  DATA 2,2,4,8,16,32,32
10490  DATA 24,36,36,36,36,36,24
10500  DATA 8,24,8,8,8,8,28
10510  DATA 28,34,2,28,32,32,62
10520  DATA 28,34,2,12,2,34,28
10530  DATA 4,12,20,62,4,4,4
10540  DATA 62,32,60,2,2,34,28
10550  DATA 28,32,32,60,34,34,28
10560  DATA 62,2,4,8,16,32,32
10570  DATA 28,34,34,28,34,34,28
10580  DATA 28,34,34,30,2,2,28
10590  DATA 0,24,24,0,24,24,0
10600  DATA 24,24,0,24,24,8,16
10610  DATA 4,8,16,32,16,8,4
10620  DATA 0,0,62,0,62,0,0
10630  DATA 16,8,4,2,4,8,16
10640  DATA 24,36,4,8,8,0,8

Here I used black-and-white RG6. To avoid the resulting artifacting, I changed to black-and-green RG6:

Code:
130  OUT 128,157: FOR A = 1 TO 200: NEXT 

Then I realized that NO CHANGE IN BACKGROUND COLOR is perceived. shocked

Here's a video with the result:
http://www.ensjo.net/mc-1000/MVI_1262.AVI

I have realized long before that black-and-green RG6's "black" background was somewhat greenish, but it never occurred to me that it was SO SIMILAR to text mode's dark green background. (Seemingly RG6's bright border gives us the impression that they are different.)

Note that when we alternate between black-and-white and black-and-green RG6, we do perceive a change in background color:
http://www.ensjo.net/mc-1000/MVI_1261.AVI

This having been said... QUESTIONS: Is this phenomenon observed in other machines based on MC6847? (A real TRS-80 Color Computer, for instance. Can anyone check it?) Is DARK GREEN the real background color of MC6847's black-and-green RG6 mode?
You can disable the artifacting from MESS user interface. It's under Options-Configuration menu.
Originally Posted By Curt Coder
You can disable the artifacting from MESS user interface. It's under Options-Configuration menu.


No, no, no... The dark green background is not a M.E.S.S. artifacting... It's what happens in the REAL machine, even though MC6847's specification says it should be fully black. I wonder if it is a particular MC-1000 "glitch", or if it is the standard functioning of MC6847, in which case the emulation should be changed accordingly.

That's why I asked for people who have a real MC6847 based machine to test it, if possible.

(I wonder if I should turn these posts into a separate thread, so that more people will see it.)

(Edit: I'll do it.)
Here's the separate discussion on MC6847's dark green background:

http://www.bannister.org/forums/ubbthreads.php?ubb=showflat&Number=53498&#Post53498
Curt,

I see that M.E.S.S. MC-1000's SOUND command doesn't work. The emulation halts. The following sample program should produce a continuous siren-like sound:
Code:
10 TEMPO 150,2,1
20 SOUND 87,15,1
30 SOUND 96,15,1
40 GOTO 20

The SOUND command depends on Z80's interrupt. In the list of TODOs there is:
Code:
   16     - interrupt from NE555

What do you mean by that? To copy the interrupt solution from another computer? (I can't find any "ne555" under /machine or /driver.
NE555 is a timer chip.
http://en.wikipedia.org/wiki/555_timer_IC

Hopefully you can now guess what the comment means. smile

Edit: Dang it RB, 11 seconds.
Originally Posted By Ensjo
I see that M.E.S.S. MC-1000's SOUND command doesn't work.


Fixed in svn 5651.
Originally Posted By R. Belmont
NE555 is a timer chip.
Originally Posted By Just Desserts
Thank you guys. Indeed, there's a NE555P among MC-1000's chips (#28).

Originally Posted By Curt Coder
Fixed in svn 5651.
I'll check it out tomorrow. smile
Hey, Curt.

Well, yes, the SOUND program works at first, but once you stop it with CTRL+C and RUN it again, no sound is produced.

Also, I TLOAD-ed the Music Composer program. It plays a music right after loading, but in M.E.S.S. the music is unrecognizable (notes have very short duration?), and not synchronized with the appearing of the notes on screen. After a little while (when there's no more notes to play?) the program halts.

There's still something that needs to be adjusted, but I don't know what.
Hey, Curt!

Recently I discovered MESS' debug functionality. As I traced a machine language program in MC-1000 step by step, I realized something weird: Once the automatic interruption RST #38 was called, it didn't run only once, but MANY TIMES IN SEQUENCE before returning to the normal running code. It seems that once the interruption is activated, it is called again at every line that MC6847 sends to the screen. (!?!?!)

I did a little machine code program to confirm the multiple interruption calls. You can use the debugger to put it in memory:
Code:
3f00 f3 21 00 00 22 4b 3f 2a 39 00 22 49 3f 21 3c 3f
3f10 22 39 00 fb 11 00 01 d5 2a 4b 3f 7c b5 28 09 cd
3f20 8b ee 21 00 00 22 4b 3f 0e 2e cd 97 c8 d1 1b 7a
3f30 b3 20 e4 f3 2a 49 3f 22 39 00 fb c9 f3 e5 2a 4b
3f40 3f 23 22 4b 3f e1 fb ed 4d 00 00 00 00

Essentially, this program implements the following pseudo-code:
Code:
main() {
 counter = 0;
 set rst#38 to myint;
 for (i = 256; i != 0; i--) {
  if (counter != 0) {
   print(counter);
   counter = 0;
  }
  print(".");
 }
 set rst#38 to default;
}

myint() {
 counter++;
}

The program was expected to print 256 dots, with some "1"s here and there accusing that the interruption has been called and increased the counter to 1.

BUT... what we actually see in MESS is that, instead of "1", the number "574" is displayed every now and then. The RST#38 interruption is being called 574 times in sequence before returning control to the running program!!!
Code:
CALL 16128
................................
..................574...........
.............................574
................................
.......574......................
..................574...........
............................574.
................................
......574.........
OK

Maybe this explains what is happenning to the Music Composer program, as described in my previous message. The routine originally called by the RST#38 interruption is responsible for the timing of music. If RST#38 is being overcalled 574 times in a row, the notes are rapidly consumed, and this unexpected condition somehow crashes the program.

How could this be fixed?

(Tonight I'll run this machine code program on my real MC-1000 and see what it displays. It could give us some clues for calibrating MESS — how many times the RST#38 is called during execution and if it produces only "1"s as expected.)
Either there's a missing ack for that interrupt (a hardware register the interrupt handler writes to lower the interrupt) or it's supposed to be edge-triggered rather than level-triggered.
And here we have it: The result of the interrupt test program on my real MC-1000:
Code:
CALL 16128
......1......1...............1..
1..1......1...............1.....
.....1................1......1..
2......1......1...............1.
1......1......1......1......1...
.......1......1...............1.
2......1...............1.......1
..........1.....1......1......1.
.1.....1......1.......1.....1...
2...
OK
CALL 16128
...............1.....1.....1....
1........1.....1.....1.....1....
1.......1..............1....1...
2.1.....1.....1.....1......1....
1...............1...............
2......1.....1.............1....
2.........1.....1.....1.....1...
1........1.....1.....1.....1....
1.......1......1.....1.....1....
1.......
OK

It's a little more erratic than I expected*, but there are the predicted 1's.

(* Why do 2's appear sometimes, and also consecutive interrupts too close to each other?)
Because my NE555 timer hack keeps the interrupt active for too long.
Originally Posted By Ensjo
(* Why do 2's appear sometimes, and also consecutive interrupts too close to each other?)

Just for the record, I think I undestood the pattern:
  • The normal behaviour is that the interrupt occurs after every 6 or 5 dots are printed.
  • The long sequences of dots are probably caused by interrupts being disabled somewhere down the ROM printing routine I call; interrupts that occur right in that moment are lost.
  • The 2's and the short sequences of dots appear at the end and at the beginning of the lines. That apparent "agglutination" of interrupts occur because extra processing is needed to SCROLL the screen (copying the contents of the VRAM 32 bytes up, filling the last line with spaces).
Posted By: Ensjo MC-1000 & NE555 - 10/19/10 12:52 PM
Originally Posted By Curt Coder
Because my NE555 timer hack keeps the interrupt active for too long.

Hm... Looking at the code we see:
Code:
static MACHINE_CONFIG_START( mc1000, mc1000_state )
[...]
    MDRV_TIMER_ADD_PERIODIC("ne555", ne555_tick, HZ(60))

and:
Code:
static TIMER_DEVICE_CALLBACK( ne555_tick )
{
    mc1000_state *state = timer.machine->driver_data<mc1000_state>();

    if (state->ne555_int == ASSERT_LINE)
    {
        state->ne555_int = CLEAR_LINE;
    }
    else
    {
        state->ne555_int = ASSERT_LINE;
    }

    cputag_set_input_line(timer.machine, Z80_TAG, INPUT_LINE_IRQ0, state->ne555_int);
}

If I understand this, "ne555_int" remain alternately "asserted" and "clear" (1 and 0, up and down, whatever) for 1/60 second:
Code:
*      *      *      *      *      *
+------+      +------+      +------+
|      |      |      |      |      |
+      +------+      +------+      +-...

How should this work instead? At every 1/60 second it should have a quick "asserted" time, and then remain "clear" for the rest of the cycle?
Code:
*      *      *      *      *      *
+-+    +-+    +-+    +-+    +-+    +-...
| |    | |    | |    | |    | |    |
+ +----+ +----+ +----+ +----+ +----+
Posted By: Curt Coder Re: MC-1000 & NE555 - 10/19/10 01:19 PM
It's connected as an astable oscillator in the MC-1000. It should work as you described above (short 0, long 1)

http://www.kpsec.freeuk.com/555timer.htm#astable
Posted By: Ensjo Re: MC-1000 & NE555 - 10/19/10 01:47 PM
Hm... Maybe this could be done by increasing the frequency and adding a counter somewhere? Let's suppose it should remain "clear" (is "clear" = 0?) during 1/10 of the cycle. We could have something like...
Code:
static MACHINE_CONFIG_START( mc1000, mc1000_state )
[...]
    MDRV_TIMER_ADD_PERIODIC("ne555", ne555_tick, HZ(60*10))

and...
Code:
static TIMER_DEVICE_CALLBACK( ne555_tick )
{
    mc1000_state *state = timer.machine->driver_data<mc1000_state>();

    if (++counter == 10)
    {
        counter = 0;
        state->ne555_int = CLEAR_LINE;
    }
    else
    {
        state->ne555_int = ASSERT_LINE;
    }

    cputag_set_input_line(timer.machine, Z80_TAG, INPUT_LINE_IRQ0, state->ne555_int);
}

Whaddya think?
Posted By: Curt Coder Re: MC-1000 & NE555 - 10/19/10 01:58 PM
Non-hacky solution would be to either emulate an NE555 chip properly, or have 2 scanline timers (one for ASSERT, another for CLEAR_LINE).
Posted By: Ensjo Re: MC-1000 & NE555 - 10/19/10 02:13 PM
Aha. Well, proper emulation of NE555 may take a while... Is the 2-timers solution quickly implementable? How to displace the second timer wave from the first, so that they are not coincident?
Posted By: R. Belmont Re: MC-1000 & NE555 - 10/19/10 03:08 PM
For the two-timers solution you'd start the second timer in the service routine for the first one. It's a fairly common pattern in MAME/MESS.
Posted By: Just Desserts Re: MC-1000 & NE555 - 10/19/10 03:12 PM
Originally Posted By R. Belmont
For the two-timers solution you'd start the second timer in the service routine for the first one. It's a fairly common pattern in MAME/MESS.


To me, this seems like a good use case for some sort of 555 device. It would manage two timers and one output line, generating a fixed PWM pulse train. Simple to implement, but given how commonplace the 555 was, it might prove useful.
Posted By: Ensjo Re: MC-1000 & NE555 - 10/19/10 03:15 PM
Hey, Belmont. Could you give an example of a MESS machine that implements this?
Posted By: judge Re: MC-1000 & NE555 - 10/19/10 06:11 PM
There is NE555 stuff in the discrete sound emulation. I don't know how reusable that is.

See src/emu/sound/discrete.h and src/emu/sound/disc_dev.c.
Posted By: Curt Coder Re: MC-1000 & NE555 - 10/20/10 09:24 AM
I don't think the discrete system supports output via WRITE_LINE_DEVICE_HANDLER ?
Posted By: R. Belmont Re: MC-1000 & NE555 - 10/20/10 12:21 PM
Also, it's difficult to sync audio devices with the emulation. I just had to add a timer to the ASC that does nothing but stream_update() to get the latency on the "buffer half empty" IRQ to a reasonable level.
Posted By: Ensjo Re: CCE MC-1000 - 10/25/10 02:20 PM
FINALLY! I got a MacBook Pro, installed XCode, svn'd down MESS source code and managed to make a functional change.
Originally Posted By Ensjo
MC-1000 doesn't provide the external ROM that MC6847 may use to get the characters bytes when it is in "External Alphanumerics" mode (AG=0, AS=0, INTEXT=1). Currently the emulation doesn't provide a cfg.get_char_rom at VIDEO_START, and thus it works as if a byte 0x00 is read. In the actual machine, though, MC6847 puts the character code byte into the wires trying to reach the external character ROM, and then reads the wires again for the pattern... but it gets the very same byte that it put there, i.e., the ASCII code of the character.

I think you could add something like...

Code:
UINT8 mc1000_get_char_rom(running_machine *machine, UINT8 ch,int line)
{
   return ch;
}

Then @ VIDEO_START:
Code:
cfg.get_char_rom = mc1000_get_char_rom;

The result is not usefull at all, as you can see by accessing this MC-1000 Java emulator and typing
Code:
POKE 245,33

but that's how it works, so here you have it.

In fact, there was no need for VIDEO_START. I found another machine that used external character ROM and found a solution. Under MACHINE_CONFIG_START I added:
Code:
	MDRV_MC6847_CHAR_ROM(mc1000_get_char_rom)

And voilà. smile
I'll see if "svn diff" can really send my changes for approval now...
Posted By: Ensjo Re: CCE MC-1000 - 10/25/10 04:28 PM
Well, according to Duke @ the Shout Box,
Quote:
you need to capture the output [of "svn diff"] and send it to nathan, who will then apply it (or not)

see mess.org contacts

And so I did. Since this is my first change submission, I think it's better to document it in case I'm doing something wrong. Here is the diff:
Code:
Index: src/mess/drivers/mc1000.c
===================================================================
--- src/mess/drivers/mc1000.c	(revision 9441)
+++ src/mess/drivers/mc1000.c	(working copy)
@@ -272,6 +272,11 @@
 	return mc6847_update(state->mc6847, bitmap, cliprect);
 }
 
+UINT8 mc1000_get_char_rom(running_machine *machine, UINT8 ch,int line)
+{
+	return ch;
+}
+
 /* AY-3-8910 Interface */
 
 static WRITE8_DEVICE_HANDLER( keylatch_w )
@@ -438,6 +443,7 @@
 
     MDRV_MC6847_ADD(MC6847_TAG, mc1000_mc6847_intf)
     MDRV_MC6847_TYPE(M6847_VERSION_ORIGINAL_NTSC)
+	MDRV_MC6847_CHAR_ROM(mc1000_get_char_rom)
 
 	/* sound hardware */
 	MDRV_SPEAKER_STANDARD_MONO("mono")
Posted By: Ensjo MC-1000 right & left SHIFT & CONTROL - 10/25/10 07:05 PM
MC-1000's keyboard has a single SHIFT key to the left, and a single CTRL key to the right:



The emulation replicates this, recognizing only LEFT SHIFT and RIGHT CONTROL keys from a PC keyboard.

This annoyed me a little: From time to time I press the "wrong" CONTROL or SHIFT key.

Even worse: I bought a MacBook Pro 33", and it has ONLY ONE CONTROL KEY, to the LEFT. I tried to stop MESS running a BASIC program with CTRL-C and couldn't do it.

Since the emulation has nothing mapped to PC's RIGHT SHIFT and LEFT CONTROL keys, it would be more comfortable to have both left and right keys map to MC-1000's single keys.

The emulation currently has:
Code:
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))

How can we have both SHIFT/CTRL keys recognized by the emulation? Is it enough to add the PORT_CODE(KEYCODE_RSHIFT) and PORT_CODE(KEYCODE_LCONTROL) in both lines? Is it necessary to change something in the PORT_CHAR() part?
Posted By: R. Belmont Re: MC-1000 right & left SHIFT & CONTROL - 10/25/10 07:15 PM
That diff looks fine. I'll apply it myself later if nobody else does.
Posted By: tlindner Re: MC-1000 right & left SHIFT & CONTROL - 10/25/10 07:18 PM
Originally Posted By Ensjo
Even worse: I bought a MacBook Pro 33"


Sound pretty nice to me! smile
Posted By: Justin Re: MC-1000 right & left SHIFT & CONTROL - 10/26/10 12:56 AM
Originally Posted By Ensjo
keys recognized by the emulation? Is it enough to add the PORT_CODE(KEYCODE_RSHIFT) and PORT_CODE(KEYCODE_LCONTROL) in both lines? Is it necessary to change something in the PORT_CHAR() part?


Adding the PORT_CODEs to both lines should work for "emulated keyboard" mode, yes. The PORT_CHAR stuff is for the "natural keyboard" mode - I'm not sure if any change would be needed there. The right shift at least seems to already work in natural keyboard mode, I don't know what the control key is supposed to do in MC-1000 so I can't check.
Posted By: R. Belmont Re: MC-1000 right & left SHIFT & CONTROL - 10/26/10 02:24 AM
The M6847 external rom change is submitted as #9449.
Posted By: Ensjo Re: MC-1000 right & left SHIFT & CONTROL - 10/26/10 06:06 AM
Originally Posted By Justin
Originally Posted By Ensjo
keys recognized by the emulation? Is it enough to add the PORT_CODE(KEYCODE_RSHIFT) and PORT_CODE(KEYCODE_LCONTROL) in both lines? Is it necessary to change something in the PORT_CHAR() part?

Adding the PORT_CODEs to both lines should work for "emulated keyboard" mode, yes. The PORT_CHAR stuff is for the "natural keyboard" mode - I'm not sure if any change would be needed there.

Hm... Do you know why SHIFT has PORT_CHAR(UCHAR_SHIFT_1) while CTRL has PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))?

Why doesn't SHIFT have PORT_CHAR(UCHAR_MAMEKEY(LSHIFT))? And, more importantly... What's the difference? confused

Originally Posted By Justin
The right shift at least seems to already work in natural keyboard mode, I don't know what the control key is supposed to do in MC-1000 so I can't check.

Well... CTRL+M should be the same as pressing the RETURN key, CTRL+C should break a running BASIC program or LIST output, and abort a line you were typing, CTRL+S should pause (and then resume) a running BASIC program or LIST output... not much more than that.
Posted By: Ensjo Re: MC-1000 right & left SHIFT & CONTROL - 10/26/10 06:10 AM
Originally Posted By R. Belmont
The M6847 external rom change is submitted as #9449.

Seen it. Thank you, Belmont!
Posted By: Justin Re: MC-1000 right & left SHIFT & CONTROL - 10/26/10 02:12 PM
Originally Posted By Ensjo
Why doesn't SHIFT have PORT_CHAR(UCHAR_MAMEKEY(LSHIFT))? And, more importantly... What's the difference? confused


For natural keyboard mode you can list two characters for the same key, e.g. PORT_CHAR('4') PORT_CHAR('$')

The PORT_CHAR(UCHAR_SHIFT_1) then tells MESS that this is the modifier key that needs to be held down to get the second character listed. This allows things like copy-paste into MESS to work. (It's also possible to use PORT_CHAR(UCHAR_SHIFT_2) and have 3 characters for the same key.)

Originally Posted By Ensjo
Well... CTRL+M should be the same as pressing the RETURN key, CTRL+C should break a running BASIC program or LIST output, and abort a line you were typing, CTRL+S should pause (and then resume) a running BASIC program or LIST output... not much more than that.


OK. Looks like both Ctrl keys are already working in natural keyboard mode as well so the PORT_CODE changes should be enough.
Posted By: Ensjo Re: MC-1000 right & left SHIFT & CONTROL - 10/27/10 02:51 AM
Originally Posted By Justin
the PORT_CODE changes should be enough.

Done. SVN diff:
Code:

Index: src/mess/drivers/mc1000.c
===================================================================
--- src/mess/drivers/mc1000.c	(revision 9454)
+++ src/mess/drivers/mc1000.c	(working copy)
@@ -237,8 +237,8 @@
 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
 
 	PORT_START("MODIFIERS")
-	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
-	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
+	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
+	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
 
 	PORT_INCLUDE( m6847_artifacting )
 INPUT_PORTS_END
Posted By: Justin Re: MC-1000 right & left SHIFT & CONTROL - 10/27/10 09:29 PM
I don't think adding the second PORT_CHAR for the Ctrl key is necessary since it already works in emulated keyboard mode, and multiple PORT_CHARs have a different semantic than PORT_CODE (the second one is to be used when a modifier key is held down).
Posted By: Anna Wu Re: CCE MC-1000 - 10/28/10 05:07 PM
Ensjo, did you get running "Aventura.wav" on the current MESS build ?

It is a Adventure in Basic so the "LOAD" command needed.
Posted By: Ensjo Re: CCE MC-1000 - 10/28/10 07:47 PM
Yes, Anna. I just pasted the source code into a .BAS file, then used BAS2BIN.EXE and BIN2WAV.EXE to make the .BIN and then the .WAV files, and then loaded it successfully with LOAD.

(Note that, when the program automatically runs after loading, some PRINT comands don't work... [Yet another MC-1000 BUG! smile ] Stop the program with CTRL+C and then RUN it again.)

Why, are you having any trouble?
Posted By: Anna Wu Re: CCE MC-1000 - 10/28/10 08:58 PM
I used the tools already to convert it to wav format.
Thanks again for the tools. smile

All other converted basic (LOAD) + assembler (TLOAD) programs are working, except "Aventura.wav". The tape file is loading but not running.
Anyway, I will convert this file again for testing.
Posted By: Anna Wu Re: CCE MC-1000 - 10/28/10 10:44 PM
OK, "Aventura.wav". is working. smile
Some bytes was missing before, 168522 bytes instead of 168558 bytes.
Posted By: Ensjo Re: MC-1000 & NE555 - 10/29/10 12:13 PM
Originally Posted By Curt Coder
Non-hacky solution [for emulating NE555's non-simetric wave] would be to either emulate an NE555 chip properly, or have 2 scanline timers (one for ASSERT, another for CLEAR_LINE).

Originally Posted By R. Belmont
For the two-timers solution you'd start the second timer in the service routine for the first one. It's a fairly common pattern in MAME/MESS.

Guys, searching MESS sources for "MDRV_TIMER_ADD_PERIODIC" I found this (src/mame/drivers/mw8080bw.c):
Code:
#define SPCENCTR_STROBE_FREQ        (9.00)  /* Hz - calculated from the 555 timer */
#define SPCENCTR_STROBE_DUTY_CYCLE  (95)    /* % */


static TIMER_DEVICE_CALLBACK( spcenctr_strobe_timer_callback )
{
    mw8080bw_state *state = timer.machine->driver_data<mw8080bw_state>();
    output_set_value("STROBE", param && state->spcenctr_strobe_state);
}

[...]

static MACHINE_CONFIG_DERIVED( spcenctr, mw8080bw_root )

    [...]

    /* timers */
    MDRV_TIMER_ADD_PERIODIC("strobeon", spcenctr_strobe_timer_callback, HZ(SPCENCTR_STROBE_FREQ))
    MDRV_TIMER_PARAM(TRUE)  /* indicates strobe ON */

    MDRV_TIMER_ADD_PERIODIC("strobeoff", spcenctr_strobe_timer_callback, HZ(SPCENCTR_STROBE_FREQ))
    MDRV_TIMER_START_DELAY(HZ(SPCENCTR_STROBE_FREQ * 100 / SPCENCTR_STROBE_DUTY_CYCLE))
    MDRV_TIMER_PARAM(FALSE) /* indicates strobe OFF */

    [...]

MACHINE_CONFIG_END

It seems that this MDRV_TIMER_START_DELAY can do the magic, is it so?
Posted By: R. Belmont Re: MC-1000 & NE555 - 10/29/10 12:15 PM
Correct.
Posted By: Ensjo Re: MC-1000 & NE555 - 10/29/10 04:26 PM
Well... I did this:
Code:
#define MC1000_NE555_FREQ       (60) /* Hz - calculated from the 555 timer */
#define MC1000_NE555_DUTY_CYCLE	(.16666) /* % */

static TIMER_DEVICE_CALLBACK( ne555_tick )
{
    mc1000_state *state = timer.machine->driver_data<mc1000_state>();

    // (state->ne555_int not needed anymore and can be done with?)
    state->ne555_int = param;

    cputag_set_input_line(timer.machine, Z80_TAG, INPUT_LINE_IRQ0, param);
}

...and...
Code:
static MACHINE_CONFIG_START( mc1000, mc1000_state )

    [...]

    /* timers */
    MDRV_TIMER_ADD_PERIODIC("ne555assert", ne555_tick, HZ(MC1000_NE555_FREQ))
    MDRV_TIMER_PARAM(ASSERT_LINE)

    MDRV_TIMER_ADD_PERIODIC("ne555clear", ne555_tick, HZ(MC1000_NE555_FREQ))
    MDRV_TIMER_START_DELAY(HZ(MC1000_NE555_FREQ * 100 / MC1000_NE555_DUTY_CYCLE))
    MDRV_TIMER_PARAM(CLEAR_LINE)

    [...]

MACHINE_CONFIG_END

Now, when I run that machine code program I made before I get:
Code:
CALL 16128
..................1.............
.................1..............
................1...............
...............1................
..............1.................
.............1..................
............1...................
...........1....................
........
OK

Compare this to the real MC-1000 output:
Code:
CALL 16128
...............1.....1.....1....
1........1.....1.....1.....1....
1.......1..............1....1...
2.1.....1.....1.....1......1....
1...............1...............
2......1.....1.............1....
2.........1.....1.....1.....1...
1........1.....1.....1.....1....
1.......1......1.....1.....1....
1.......
OK

Now... what stands for the difference? Is the emulated Z80 clock faster than the original machine (so that the program can print more dots before being interrupted by NE555)? Doesn't NE555 really produce interrupts at 60MHz? Or what? (And how could I test the hypotheses?)
Posted By: Ensjo Re: MC-1000 right & left SHIFT & CONTROL - 10/29/10 05:00 PM
Originally Posted By Justin
For natural keyboard mode you can list two characters for the same key, e.g. PORT_CHAR('4') PORT_CHAR('$')

The PORT_CHAR(UCHAR_SHIFT_1) then tells MESS that this is the modifier key that needs to be held down to get the second character listed. This allows things like copy-paste into MESS to work.

You having said that, I tried to paste something to emulated MC-1000, and noticed that some of the characters disappeared, more specifically, the keys that in MC-1000 are associated to the joystick (up-down-right-left-button for player 1 are I-Q-Y-1-9, and for player 2 are H-P-X-O-@).

I realized that in the ports definition, those keys are not associated to IPT_KEYBOARD like the others, only to IPT_JOYSTICK_UP etc.:
Code:
    PORT_START("ROW0")
    PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('@')
    PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
    PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
    PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
    PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
    PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
    PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )

    PORT_START("ROW1")
    PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
    PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
    PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
    PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
    PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
    PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
    PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )

Then I thought of creating other two ports for the joysticks, and mixing them later. I did this:
Code:
	PORT_START("JOY0")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)        /* @ */
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)    /* H */
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)  /* P */
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)  /* X */
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) /* 0 */
	PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )

	PORT_START("JOY1")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )    /* I */
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )  /* Q */
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )  /* Y */
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) /* 1 */
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )        /* 9 */
	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )

	PORT_START("ROW0")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('@')
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )

	PORT_START("ROW1")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )

And then:
Code:
static READ8_DEVICE_HANDLER( keydata_r )
{
	mc1000_state *state = device->machine->driver_data<mc1000_state>();

	UINT8 data = 0xff;

	if (!BIT(state->keylatch, 0)) data &= input_port_read(device->machine, "ROW0") &
                                              input_port_read(device->machine, "JOY0");
	if (!BIT(state->keylatch, 1)) data &= input_port_read(device->machine, "ROW1") &
	                                      input_port_read(device->machine, "JOY1");
	if (!BIT(state->keylatch, 2)) data &= input_port_read(device->machine, "ROW2");
	if (!BIT(state->keylatch, 3)) data &= input_port_read(device->machine, "ROW3");
	if (!BIT(state->keylatch, 4)) data &= input_port_read(device->machine, "ROW4");
	if (!BIT(state->keylatch, 5)) data &= input_port_read(device->machine, "ROW5");
	if (!BIT(state->keylatch, 6)) data &= input_port_read(device->machine, "ROW6");
	if (!BIT(state->keylatch, 7)) data &= input_port_read(device->machine, "ROW7");

	data = (input_port_read(device->machine, "MODIFIERS") & 0xc0) | (data & 0x3f);

	if (cassette_input(state->cassette) < +0.0)	data &= 0x7f;

	return data;
}

Then I could paste successfully. smile

But... how can I disable joystick mapping to keyboard in MESS? In my MacBook Pro I edited mc1000.ini and changed "joystick" option to 0, and it still mapping. frown
Posted By: Ensjo Re: MC-1000 & NE555 - 10/30/10 07:48 PM
Hello, people. I opened my real MC-1000 to know what are the resistors that are linked to the NE555 astable circuit.

Then I used this online toot to interpret the color codes:
  • R16 = brown, black, red, gold = 1000 ohms
  • R17 = orange, white, yellow, gold = 390 Kohms

Then I could reconstitute the NE555 part of MC-1000's awfully blurred schematics:
Code:
 +---------*---*---o V+
 |         |   |
+-+        |   |
| |309K    |   |
| |R17     |8  |4
+-+      +-------+
 |      7|       |3
 *-------|       |-------> /INT (Z80)
 |       |       |
 |       |       |
+-+R16  2| IC 28 |
| |1K +--|       |
| |   |  |  555  |
+-+   |  |       |
 |    | 6|       |5
 *----*—-|       |---+
 |       |       |   |
---C30   +-------+  ---C29
---103       |1     ---103
_|_         _|_     _|_
///         ///     ///

Then I used this other online tool to calculate the square wave produced by NE555.

I filled the fields with:
  • 0.00000001 farads (C = C30; "103" = 10 x 10³ pF = 0.01 µF)
  • 390000 ohms (resistor 1 = R17)
  • 1000 ohms (resistor 2 = R16)

...and got:
  • 99.74489795918367 Duty Cycle Percentage
  • 368.1126130105722 Frequency in Hertz
  • 0.00000693 Seconds Low
  • 0.0027096299999999998 Seconds High

368Hz?! What do you say? I know nothing of electronics. Did I use the right values? Are this results correct?
Posted By: R. Belmont Re: MC-1000 & NE555 - 10/30/10 08:13 PM
368 Hz sounds ballpark given your real hardware has roughly 1/5th as many 1s between dots as the 60 Hz MESS version, and 5*60 = 300.
Posted By: Ensjo Re: MC-1000 & NE555 - 10/30/10 11:21 PM
Well, I used 368 Hz and a 99.745 duty cycle percentage, and got this:
Code:
CALL 16128
..1..1..1...1..1..1..1...1..1..1
.1..1...1..1..1...1..1..1..1...1
.1..1..1..1...1..1..1...1..1..1.
2..1...1..1..1..1...1..1..1..1..
2..1..1..1...1..1..1..1...1..1..
2.1..1...1..1..1..1...1..1..1...
2..........1..1..1..1...1..1..1.
2..1...1..1..1...1..1..1..1...1.
2..1..1..1...1..1..1...1..1..1..
2.1...1..1..1..1...1..1..1..1...
.1..1...1..1..1..1.
OK

The frequency is a little too high compared to the machine, but I'll leave it like this for the time being. At least it's much more close to the real machine than before. smile

So... HERE IS OUR NEW DIFF: smile Someone apply it, please.
Code:
Index: src/mess/drivers/mc1000.c
===================================================================
--- src/mess/drivers/mc1000.c	(revision 9475)
+++ src/mess/drivers/mc1000.c	(working copy)
@@ -164,22 +164,39 @@
 /* Input Ports */
 
 static INPUT_PORTS_START( mc1000 )
+	PORT_START("JOY0")
+	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)        /* = '@' */
+	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)    /* = 'H' */
+	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)  /* = 'P' */
+	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)  /* = 'X' */
+	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) /* = '0' */
+	PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
+
+	PORT_START("JOY1")
+	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )    /* = 'I' */
+	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )  /* = 'Q' */
+	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )  /* = 'Y' */
+	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) /* = '1' */
+	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )        /* = '9' */
+	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
+
 	PORT_START("ROW0")
-	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('@')
-	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
-	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
-	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
-	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
+	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('@')
+	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
+	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
+	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
+	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
 
 	PORT_START("ROW1")
 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
-	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
-	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
-	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
-	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
-	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
+	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
+	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
+	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
+	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
+	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
 
 	PORT_START("ROW2")
@@ -238,7 +255,7 @@
 
 	PORT_START("MODIFIERS")
 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
-	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
+	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
 
 	PORT_INCLUDE( m6847_artifacting )
 INPUT_PORTS_END
@@ -294,8 +311,10 @@
 
 	UINT8 data = 0xff;
 
-	if (!BIT(state->keylatch, 0)) data &= input_port_read(device->machine, "ROW0");
-	if (!BIT(state->keylatch, 1)) data &= input_port_read(device->machine, "ROW1");
+	if (!BIT(state->keylatch, 0)) data &= input_port_read(device->machine, "ROW0") &
+	                                      input_port_read(device->machine, "JOY0");
+	if (!BIT(state->keylatch, 1)) data &= input_port_read(device->machine, "ROW1") &
+	                                      input_port_read(device->machine, "JOY1");
 	if (!BIT(state->keylatch, 2)) data &= input_port_read(device->machine, "ROW2");
 	if (!BIT(state->keylatch, 3)) data &= input_port_read(device->machine, "ROW3");
 	if (!BIT(state->keylatch, 4)) data &= input_port_read(device->machine, "ROW4");
@@ -378,20 +397,53 @@
 
 /* Machine Driver */
 
+/*
+ 
+ Interrupt generator:
+ NE555 chip in astable circuit.
+ 
+  +---------*---*---o V+
+  |         |   |
+ +-+        |   |
+ | |309K    |   |
+ | |R17     |8  |4
+ +-+      +-------+
+  |      7|       |3
+  *-------|       |-------> /INT (Z80)
+  |       |       |
+  |       |       |
+ +-+R16  2| IC 28 |
+ | |1K +--|       |
+ | |   |  |  555  |
+ +-+   |  |       |
+  |    | 6|       |5
+  *----*—-|       |---+
+  |       |       |   |
+ ---C30   +-------+  ---C29
+ ---103       |1     ---103
+ _|_         _|_     _|_
+ ///         ///     ///
+ 
+ Calculated properties:
+ 
+ * 99.74489795918367 Duty Cycle Percentage
+ * 368.1126130105722 Frequency in Hertz
+ * 0.00000693 Seconds Low
+ * 0.0027096299999999998 Seconds High
+ 
+ */
+
+#define MC1000_NE555_FREQ       (368) /* Hz */
+#define MC1000_NE555_DUTY_CYCLE (99.745) /* % */
+
 static TIMER_DEVICE_CALLBACK( ne555_tick )
 {
 	mc1000_state *state = timer.machine->driver_data<mc1000_state>();
 
-	if (state->ne555_int == ASSERT_LINE)
-	{
-		state->ne555_int = CLEAR_LINE;
-	}
-	else
-	{
-		state->ne555_int = ASSERT_LINE;
-	}
+	// (state->ne555_int not needed anymore and can be done with?)
+	state->ne555_int = param;
 
-	cputag_set_input_line(timer.machine, Z80_TAG, INPUT_LINE_IRQ0, state->ne555_int);
+	cputag_set_input_line(timer.machine, Z80_TAG, INPUT_LINE_IRQ0, param);
 }
 
 static const cassette_config mc1000_cassette_config =
@@ -421,28 +473,34 @@
 static MACHINE_CONFIG_START( mc1000, mc1000_state )
 
 	/* basic machine hardware */
-    MDRV_CPU_ADD(Z80_TAG, Z80, 3579545)
-    MDRV_CPU_PROGRAM_MAP(mc1000_mem)
-    MDRV_CPU_IO_MAP(mc1000_io)
+	MDRV_CPU_ADD(Z80_TAG, Z80, 3579545)
+	MDRV_CPU_PROGRAM_MAP(mc1000_mem)
+	MDRV_CPU_IO_MAP(mc1000_io)
 
-    MDRV_MACHINE_START(mc1000)
-    MDRV_MACHINE_RESET(mc1000)
+	MDRV_MACHINE_START(mc1000)
+	MDRV_MACHINE_RESET(mc1000)
 
-	MDRV_TIMER_ADD_PERIODIC("ne555", ne555_tick, HZ(60))
+	/* timers */
+	MDRV_TIMER_ADD_PERIODIC("ne555clear", ne555_tick, HZ(MC1000_NE555_FREQ))
+	MDRV_TIMER_PARAM(CLEAR_LINE)
 
-    /* video hardware */
-    MDRV_SCREEN_ADD(SCREEN_TAG, RASTER)
-    MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND)
-    MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
-    MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
+	MDRV_TIMER_ADD_PERIODIC("ne555assert", ne555_tick, HZ(MC1000_NE555_FREQ))
+	MDRV_TIMER_START_DELAY(HZ(MC1000_NE555_FREQ * 100 / MC1000_NE555_DUTY_CYCLE))
+	MDRV_TIMER_PARAM(ASSERT_LINE)
+
+	/* video hardware */
+	MDRV_SCREEN_ADD(SCREEN_TAG, RASTER)
+	MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND)
+	MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
+	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
 	MDRV_SCREEN_SIZE(320, 25+192+26)
 	MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)
-    MDRV_PALETTE_LENGTH(16)
+	MDRV_PALETTE_LENGTH(16)
 
-    MDRV_VIDEO_UPDATE(mc1000)
+	MDRV_VIDEO_UPDATE(mc1000)
 
-    MDRV_MC6847_ADD(MC6847_TAG, mc1000_mc6847_intf)
-    MDRV_MC6847_TYPE(M6847_VERSION_ORIGINAL_NTSC)
+	MDRV_MC6847_ADD(MC6847_TAG, mc1000_mc6847_intf)
+	MDRV_MC6847_TYPE(M6847_VERSION_ORIGINAL_NTSC)
 	MDRV_MC6847_CHAR_ROM(mc1000_get_char_rom)
 
 	/* sound hardware */
Posted By: Robbbert Re: MC-1000 & NE555 - 10/30/10 11:37 PM
I tested this and the keyboard is having significant problems. For example typing R gives H, A gives @, etc. The current svn works properly.
Posted By: Ensjo Re: MC-1000 & NE555 - 10/31/10 02:41 AM
Originally Posted By robbbert
I tested this and the keyboard is having significant problems. For example typing R gives H, A gives @, etc. The current svn works properly.

Yes, it's a weird side-effect of the change I explain at this post.

In MC-1000, the joystick positions & buttons are equivalent to the pressing of certain keys:
  • Player one: up=I, down=Q, right=Y, left=1, button=9;
  • Player two: up=H, down=P, right=X, left=0, button=@

In the current svn, these keys are defined only as IPT_JOYSTICK_... ports. When you PASTE a text to the emulation, the corresponding characters are not inserted because MESS doesn't find a corresponding IPT_KEYBOARD port for them.

(Paste 10 PRINT "HELLO WORLD" and you'll see only RNT "ELLO WORLD"

It works when a PERSON types something, though, because, in the code, the joystick lines are "wired" to the keyboard lines.

What did I do? Defined separate, proper ports for the keyboard and joystick, and then "wired" them.

It did work (now pasting a text to the emulation does work... But now MESS' own keyboard mapping of joystick is causing that weird side-effect.

MESS keyboard-to-joystick mapping is:
  • Player one: up=UP, down=DOWN, right=RIGHT, left=LEFT, button=LEFT CTRL;
  • Player two: up=R, down=F, right=G, left=D, button=A

What is happening is that MESS is mapping these keys to the keys above, and we have:
  • UP->I, DOWN->Q, RIGHT->Y, LEFT->1, LEFT CTRL->9 (in fact, we get the equivalent to CTRL+9);
  • R->H, F->P, G->X, D->0, A->@

But it is enabled by default, so the keyboard is confused.

Probably, disabling MESS' keyboard-to-joystick mapping should solve the problem, but how can we do it?

In mc1000.ini I found an option "joystick" with value "1"; I changed it to "0", but the mapping is STILL enabled.

HOW CAN WE DISABLE MESS' JOYSTICK MAPPING when the machine starts, in a way that the user can enable it only when needed (i.e., to play a game using the arrow keys)? frown
Posted By: R. Belmont Re: MC-1000 & NE555 - 10/31/10 02:49 AM
"joystick 0" turns off MESS reading any USB or gameport joypads/sticks you have connected to your PC/Mac. It does nothing to the internal mappings.

As for the rest of your problem, you appear to be doing something horribly wrong, but I do not understand keyboard mapping well enough to tell you what. Perhaps next time Justin signs in he would know.
Posted By: Ensjo Re: MC-1000 & NE555 - 10/31/10 05:51 AM
Hm... I see that MC6847's color artifacting is enabled via a UI config option, which is available to the code as a port:
Code:
INPUT_PORTS_START( m6847_artifacting )
    PORT_START("artifacting")
    PORT_CONFNAME( 0x03, 0x01, "Artifacting" ) PORT_CHANGED(artifacting_changed, NULL)
    PORT_CONFSETTING(    0x00, DEF_STR( Off ) )
    PORT_CONFSETTING(    0x01, DEF_STR( Standard ) )
    PORT_CONFSETTING(    0x02, DEF_STR( Reverse ) )
INPUT_PORTS_END

Then...
Code:
    /* are we artifacting? */
    artifacting = input_port_read_safe(machine, "artifacting", 0x00) & 0x03;
    if (artifacting == 0x00)
        return;

...else (artifacting != 0x00), proceed to produce the artifacting effect.

I could do something similar, add a UI config option so that joystick is only mixed to the keyboard if the user chooses that.

(Unless, of course, there is already something like that already implemented in MESS' core.)

Whaddya think?
Posted By: Anna Wu Re: MC-1000 & NE555 - 10/31/10 08:20 AM
Quote:
Whaddya think?


Is this a American slang expression ? smile
Posted By: R. Belmont Re: MC-1000 & NE555 - 10/31/10 03:01 PM
It's essentially a typed out version of "what do you think?" in a specific kind of New York accent smile
Posted By: Anna Wu Re: MC-1000 & NE555 - 10/31/10 08:10 PM
Originally Posted By R. Belmont
It's essentially a typed out version of "what do you think?" in a specific kind of New York accent smile


Thank you for the explanation. smile
Posted By: Ensjo Re: MC-1000 & NE555 - 11/01/10 12:23 AM
I wouldn't be able to tell where "whaddya" comes from; it's just something I have read here and there and eventually incorporated into my own idiolect. smile
Posted By: Ensjo Re: MC-1000 & NE555 - 11/01/10 02:02 AM
Originally Posted By Ensjo
I could do something similar, add a UI config option so that joystick is only mixed to the keyboard if the user chooses that.

IMPLEMENTED. New driver configuration options allow user to enable/disable keyboard mapping for both joysticks independently. Both are disabled by default, so no more keyboard side effects. Yay! smile HERE IS THE NEW DIFF:
Code:
Index: src/mess/drivers/mc1000.c
===================================================================
--- src/mess/drivers/mc1000.c	(revision 9472)
+++ src/mess/drivers/mc1000.c	(working copy)
@@ -164,22 +164,39 @@
 /* Input Ports */
 
 static INPUT_PORTS_START( mc1000 )
+	PORT_START("JOYA") /* Player 1 */
+	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
+	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )    /* = 'I' */
+	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )  /* = 'Q' */
+	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )  /* = 'Y' */
+	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) /* = '1' */
+	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )        /* = '9' */
+	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
+
+	PORT_START("JOYB") /* Player 2 */
+	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)        /* = '@' */
+	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)    /* = 'H' */
+	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)  /* = 'P' */
+	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)  /* = 'X' */
+	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) /* = '0' */
+	PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNUSED )
+
 	PORT_START("ROW0")
-	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('@')
-	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
-	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
-	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
-	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
+	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('@')
+	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H')
+	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P')
+	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X')
+	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
 
 	PORT_START("ROW1")
 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
-	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
-	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
-	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
-	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
-	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
+	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I')
+	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
+	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
+	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
+	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
 	PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED )
 
 	PORT_START("ROW2")
@@ -238,8 +255,18 @@
 
 	PORT_START("MODIFIERS")
 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
-	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
+	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
 
+	PORT_START("JOYAKEYMAP")
+	PORT_CONFNAME( 0x01, 0x00, "JOYSTICK A (P1) keyboard mapping" )
+	PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
+	PORT_CONFSETTING( 0x01, DEF_STR( On ) )
+
+	PORT_START("JOYBKEYMAP")
+	PORT_CONFNAME( 0x01, 0x00, "JOYSTICK B (P2) keyboard mapping" )
+	PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
+	PORT_CONFSETTING( 0x01, DEF_STR( On ) )
+
 	PORT_INCLUDE( m6847_artifacting )
 INPUT_PORTS_END
 
@@ -294,15 +321,25 @@
 
 	UINT8 data = 0xff;
 
-	if (!BIT(state->keylatch, 0)) data &= input_port_read(device->machine, "ROW0");
-	if (!BIT(state->keylatch, 1)) data &= input_port_read(device->machine, "ROW1");
+	if (!BIT(state->keylatch, 0))
+	{
+	                              data &= input_port_read(device->machine, "ROW0");
+		if (input_port_read(device->machine, "JOYBKEYMAP"))
+	                              data &= input_port_read(device->machine, "JOYB");
+	}
+	if (!BIT(state->keylatch, 1))
+	{
+	                              data &= input_port_read(device->machine, "ROW1");
+		if (input_port_read(device->machine, "JOYAKEYMAP"))
+	                              data &= input_port_read(device->machine, "JOYA");
+	}
 	if (!BIT(state->keylatch, 2)) data &= input_port_read(device->machine, "ROW2");
 	if (!BIT(state->keylatch, 3)) data &= input_port_read(device->machine, "ROW3");
 	if (!BIT(state->keylatch, 4)) data &= input_port_read(device->machine, "ROW4");
 	if (!BIT(state->keylatch, 5)) data &= input_port_read(device->machine, "ROW5");
 	if (!BIT(state->keylatch, 6)) data &= input_port_read(device->machine, "ROW6");
 	if (!BIT(state->keylatch, 7)) data &= input_port_read(device->machine, "ROW7");
-
+	
 	data = (input_port_read(device->machine, "MODIFIERS") & 0xc0) | (data & 0x3f);
 
 	if (cassette_input(state->cassette) < +0.0)	data &= 0x7f;
@@ -378,20 +415,53 @@
 
 /* Machine Driver */
 
+/*
+ 
+ Interrupt generator:
+ NE555 chip in astable circuit.
+ 
+  +---------*---*---o V+
+  |         |   |
+ +-+        |   |
+ | |309K    |   |
+ | |R17     |8  |4
+ +-+      +-------+
+  |      7|       |3
+  *-------|       |-------> /INT (Z80)
+  |       |       |
+  |       |       |
+ +-+R16  2| IC 28 |
+ | |1K +--|       |
+ | |   |  |  555  |
+ +-+   |  |       |
+  |    | 6|       |5
+  *----*—-|       |---+
+  |       |       |   |
+ ---C30   +-------+  ---C29
+ ---103       |1     ---103
+ _|_         _|_     _|_
+ ///         ///     ///
+ 
+ Calculated properties:
+ 
+ * 99.74489795918367 Duty Cycle Percentage
+ * 368.1126130105722 Frequency in Hertz
+ * 0.00000693 Seconds Low
+ * 0.0027096299999999998 Seconds High
+ 
+ */
+
+#define MC1000_NE555_FREQ       (368) /* Hz */
+#define MC1000_NE555_DUTY_CYCLE (99.745) /* % */
+
 static TIMER_DEVICE_CALLBACK( ne555_tick )
 {
 	mc1000_state *state = timer.machine->driver_data<mc1000_state>();
 
-	if (state->ne555_int == ASSERT_LINE)
-	{
-		state->ne555_int = CLEAR_LINE;
-	}
-	else
-	{
-		state->ne555_int = ASSERT_LINE;
-	}
+	// (state->ne555_int not needed anymore and can be done with?)
+	state->ne555_int = param;
 
-	cputag_set_input_line(timer.machine, Z80_TAG, INPUT_LINE_IRQ0, state->ne555_int);
+	cputag_set_input_line(timer.machine, Z80_TAG, INPUT_LINE_IRQ0, param);
 }
 
 static const cassette_config mc1000_cassette_config =
@@ -421,28 +491,34 @@
 static MACHINE_CONFIG_START( mc1000, mc1000_state )
 
 	/* basic machine hardware */
-    MDRV_CPU_ADD(Z80_TAG, Z80, 3579545)
-    MDRV_CPU_PROGRAM_MAP(mc1000_mem)
-    MDRV_CPU_IO_MAP(mc1000_io)
+	MDRV_CPU_ADD(Z80_TAG, Z80, 3579545)
+	MDRV_CPU_PROGRAM_MAP(mc1000_mem)
+	MDRV_CPU_IO_MAP(mc1000_io)
 
-    MDRV_MACHINE_START(mc1000)
-    MDRV_MACHINE_RESET(mc1000)
+	MDRV_MACHINE_START(mc1000)
+	MDRV_MACHINE_RESET(mc1000)
 
-	MDRV_TIMER_ADD_PERIODIC("ne555", ne555_tick, HZ(60))
+	/* timers */
+	MDRV_TIMER_ADD_PERIODIC("ne555clear", ne555_tick, HZ(MC1000_NE555_FREQ))
+	MDRV_TIMER_PARAM(CLEAR_LINE)
 
-    /* video hardware */
-    MDRV_SCREEN_ADD(SCREEN_TAG, RASTER)
-    MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND)
-    MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
-    MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
+	MDRV_TIMER_ADD_PERIODIC("ne555assert", ne555_tick, HZ(MC1000_NE555_FREQ))
+	MDRV_TIMER_START_DELAY(HZ(MC1000_NE555_FREQ * 100 / MC1000_NE555_DUTY_CYCLE))
+	MDRV_TIMER_PARAM(ASSERT_LINE)
+
+	/* video hardware */
+	MDRV_SCREEN_ADD(SCREEN_TAG, RASTER)
+	MDRV_SCREEN_REFRESH_RATE(M6847_NTSC_FRAMES_PER_SECOND)
+	MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
+	MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
 	MDRV_SCREEN_SIZE(320, 25+192+26)
 	MDRV_SCREEN_VISIBLE_AREA(0, 319, 1, 239)
-    MDRV_PALETTE_LENGTH(16)
+	MDRV_PALETTE_LENGTH(16)
 
-    MDRV_VIDEO_UPDATE(mc1000)
+	MDRV_VIDEO_UPDATE(mc1000)
 
-    MDRV_MC6847_ADD(MC6847_TAG, mc1000_mc6847_intf)
-    MDRV_MC6847_TYPE(M6847_VERSION_ORIGINAL_NTSC)
+	MDRV_MC6847_ADD(MC6847_TAG, mc1000_mc6847_intf)
+	MDRV_MC6847_TYPE(M6847_VERSION_ORIGINAL_NTSC)
 	MDRV_MC6847_CHAR_ROM(mc1000_get_char_rom)
 
 	/* sound hardware */
Posted By: Robbbert Re: MC-1000 & NE555 - 11/01/10 03:49 AM
Ok it's in, r9492.

Just wondering, if you make a syntax error, why does it say ?SN ERRO

Where did the trailing R go? It appears the driver has always does this, what about a real machine?
Posted By: Ensjo Re: MC-1000 & NE555 - 11/01/10 03:59 AM
"ERRO" is "ERROR" in Portuguese, robbbert.

MC-1000's system messages (error codes included) are in Portuguese.

Stop a program 10 GOTO 10 with CTRL+C and you'll get PAUSA EM 10 ("pause at (line) 10").
Posted By: ASH Re: MC-1000 & NE555 - 11/01/10 09:58 AM
Nice work on the MC-1000

noticed this.

10 PRINT "2";
20 GOTO 10
RUN

after about 8 lines it doesn't print a character?

I.E.

2222222222
2222222222
2222222222
2222222222
222222222
2222222222
2222222222

is that a bug?
Posted By: Ensjo Re: MC-1000 & NE555 - 11/01/10 01:27 PM
No, not a bug, just another of MC-1000's peculiarities. smile Every character printed increases the 1-byte counter for the POS() function. Because the higher number it can hold is 255, MC-1000 forces a line break at that point, and you see that gap where the 256th character should have been printed. :P
© Forums