Previous Thread
Next Thread
Print Thread
Page 1 of 14 1 2 3 13 14
#108050 - 11/29/16 08:27 PM 8bit Apples - Apple I, II, /// and the 16 bit GS  
Joined: Jan 2012
Posts: 878
rfka01 Offline
Senior Member
rfka01  Offline
Senior Member

Joined: Jan 2012
Posts: 878
Bavaria
I think we don't have a dedicated 8 bit Apple thread yet - I came across an Apple /// blog that also has disk images, rom listings and a lot of information.

http://drop-iii-inches.com/

The earlier posts warp back to the time the Apple III driver in MESS became funcional smile

Last edited by rfka01; 11/29/16 08:41 PM.

NCR DMV- DEC Rainbow- Siemens PCD- ITT 3030-Oly People- Acorn A5000- Olivetti M20
#108051 - 11/29/16 08:35 PM Re: 8bit Apples - Apple I, II, /// and GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Yeah, I've been following their podcast since it started. I might even actually be on it sometime.

Also, the IIgs isn't an 8-bit Apple smile

#108052 - 11/29/16 08:42 PM Re: 8bit Apples - Apple I, II, /// and GS [Re: rfka01]  
Joined: Jan 2012
Posts: 878
rfka01 Offline
Senior Member
rfka01  Offline
Senior Member

Joined: Jan 2012
Posts: 878
Bavaria
noted and reflected in the edited title smile


NCR DMV- DEC Rainbow- Siemens PCD- ITT 3030-Oly People- Acorn A5000- Olivetti M20
#108053 - 11/29/16 09:04 PM Re: 8bit Apples - Apple I, II, /// and GS [Re: rfka01]  
Joined: Mar 2008
Posts: 165
robcfg Offline
Senior Member
robcfg  Offline
Senior Member

Joined: Mar 2008
Posts: 165
Madrid, Spain
I'm after a friend of mine to dump a german IIe.

Will be telling you when I achieve it.

#108054 - 11/29/16 09:16 PM Re: 8bit Apples - Apple I, II, /// and GS [Re: rfka01]  
Joined: Jan 2012
Posts: 878
rfka01 Offline
Senior Member
rfka01  Offline
Senior Member

Joined: Jan 2012
Posts: 878
Bavaria
@robcfg
A quick search shows the ROMs for a German IIe are available.


NCR DMV- DEC Rainbow- Siemens PCD- ITT 3030-Oly People- Acorn A5000- Olivetti M20
#108056 - 11/29/16 10:53 PM Re: 8bit Apples - Apple I, II, /// and GS [Re: rfka01]  
Joined: Mar 2008
Posts: 165
robcfg Offline
Senior Member
robcfg  Offline
Senior Member

Joined: Mar 2008
Posts: 165
Madrid, Spain
Well, nobody knows for sure what you'll find inside an old computer laugh

It could have a less known rom set or an unusual expansion card... You get what I mean.

I'll also be scanning the PCB and taking pictures.

#108057 - 11/29/16 11:02 PM Re: 8bit Apples - Apple I, II, /// and GS [Re: rfka01]  
Joined: Jan 2012
Posts: 878
rfka01 Offline
Senior Member
rfka01  Offline
Senior Member

Joined: Jan 2012
Posts: 878
Bavaria
True dat smile


NCR DMV- DEC Rainbow- Siemens PCD- ITT 3030-Oly People- Acorn A5000- Olivetti M20
#109048 - 03/02/17 06:30 PM Re: 8bit Apples - Apple I, II, /// and GS [Re: rfka01]  
Joined: Jan 2012
Posts: 878
rfka01 Offline
Senior Member
rfka01  Offline
Senior Member

Joined: Jan 2012
Posts: 878
Bavaria
This thread

https://groups.google.com/forum/#!topic/comp.sys.apple2/19Q2hVgAS18

has links to Ramfast SCSI ROMs.


NCR DMV- DEC Rainbow- Siemens PCD- ITT 3030-Oly People- Acorn A5000- Olivetti M20
#109049 - 03/02/17 07:18 PM Re: 8bit Apples - Apple I, II, /// and GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Thanks! I actually have my own Ramfast rev. D board I can dump, and the Apple II Documentation Project has both the Apple II and Z180 ROMs for rev. C and D, but more versions are always better smile

#109503 - 05/01/17 06:19 PM Konan David Jr II [Re: rfka01]  
Joined: Jan 2012
Posts: 878
rfka01 Offline
Senior Member
rfka01  Offline
Senior Member

Joined: Jan 2012
Posts: 878
Bavaria


NCR DMV- DEC Rainbow- Siemens PCD- ITT 3030-Oly People- Acorn A5000- Olivetti M20
#109567 - 05/11/17 01:25 PM Re: 8bit Apples - Apple I, II, /// and GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
The site What Is The Apple IIgs? put together a hard disk image of all of MECC's educational software for the Apple II that boots into a menu. Yes, Oregon Trail is included smile

I've converted it to CHD for the CFFA2 card here: https://mega.nz/#!8iRhHbwK!lcOVKK_BTo1wVvQFfRjZmPRgyulEFQisOnmrtUnXKSI

You can run it like so:

mess64 apple2ee -sl7 cffa2 -hard1 MECC.chd

Or if you want to risk some games being a bit fast:

mess64 apple2gs -sl7 cffa2 -hard1 MECC.chd

As a bonus, load times are far, far faster on the CFFA2 than even a mechanical HDD, and it blows floppies out of the water.

Last edited by R. Belmont; 05/11/17 01:28 PM.
#109577 - 05/14/17 10:32 AM Re: 8bit Apples - Apple I, II, /// and GS [Re: R. Belmont]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I thought I'd try the MECC.chd and it's pretty cool.

A couple of problems though, on the apple2gs for some reason the auto repeat doesn't work for the arrow keys. The arrow key repeat works fine on the apple2ee. This makes the menu really hard to navigate as you can't get to the bottom of the list without pressing down arrow over and over. I did find that the open-apple or closed-apple plus arrow keys moves by a page in the menu.

And I can't seem to get the apple2gs into the text control panel with ctrl+open apple+escape. I tried everything I could think of, but it just won't go. (I was able to get into the text control panel by holding down closed apple on booting and choosing 1 for control panel)

On the apple2ee the Word Munchers game has all kinds of horizontal glitching on the screen when you're on the word grid. I don't see the horizontal glitching when run on the apple2gs driver.

I'm finding out that I'm not very good at matching the vowel sounds in word munchers. Guess I need some remedial practice.

I'm a bit of a noob with mame and the apple drivers so sorry if these are dumb questions.


Pics of the horizontal glitch on apple2ee on ubuntu 16.04 and mame185 compiled from source:
[Linked Image]
[Linked Image]

Last edited by Golden Child; 05/14/17 03:03 PM. Reason: added pics
#109580 - 05/14/17 04:10 PM Re: 8bit Apples - Apple I, II, /// and GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
The 8-bit drivers are more modern and complete than the apple2gs driver, which dates to 2005 and has pretty much just been hacked to death since then. The 8-bit drivers support raster splits in order to (not always successfully) support the French Touch demos; the IIgs driver doesn't attempt to support 8-bit raster effects because they were basically unknown in 2005. My guess is the issue with Word Munchers is that it's inadvertently causing that support to engage when it shouldn't, I'll take a look.

I'm writing a new IIgs driver when I have time, which isn't often. It emulates the IIgs at a lower level than any existing emulator, and so progress is slower than I want it to be, but it's IMO necessary to do it that way.

Last edited by R. Belmont; 05/14/17 04:10 PM.
#110635 - 08/21/17 05:50 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jan 2012
Posts: 878
rfka01 Offline
Senior Member
rfka01  Offline
Senior Member

Joined: Jan 2012
Posts: 878
Bavaria
This thread

http://forum.classic-computing.de/index.php?page=Thread&postID=123001#post123001

contains a link to a book with hardware descriptions and circuit diagrams of the German Apple II clone maker, IBS.


NCR DMV- DEC Rainbow- Siemens PCD- ITT 3030-Oly People- Acorn A5000- Olivetti M20
#110636 - 08/21/17 06:25 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
I couldn't immediately find that link, but all of the IBS hardware seems to be exact clones, not enhanced or modified so it's all good.

#110651 - 08/23/17 11:50 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jun 2014
Posts: 64
peter ferrie Offline
Member
peter ferrie  Offline
Member

Joined: Jun 2014
Posts: 64
The glitching might be caused by the game touching the graphics soft-switches while already in graphics mode, as a II+ compatible refresh-polling.
Canyon Climber did exactly that. I have fixed the driver for that case.

#110655 - 08/24/17 06:38 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: peter ferrie]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I just cloned current git and compiled it and I saw some glitching when doing hgr while in 80 column mode on the apple2e driver.

Just start up, interrupt the boot with CTRL+F12, PR#3, HGR, and then hitting enter repeatedly causes the text screen to scroll and while it's scrolling, there's a bunch of glitching. Once the scroll stops, the glitching disappears.


[Linked Image]

#110658 - 08/24/17 10:51 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jun 2014
Posts: 64
peter ferrie Offline
Member
peter ferrie  Offline
Member

Joined: Jun 2014
Posts: 64
It's likely to be same issue, but caused by another switch access which I overlooked.

#110659 - 08/25/17 01:38 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: peter ferrie]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Cool. Thanks for looking into the glitching issue.

On another note, I was having some trouble getting a printout from applesoft basic using the ssc and pr#1.

I can get it to output to a file, but the high bit on each byte seems to be set. A quick "tr '\200-\377' '\000-\177' " will strip the high bit from the output file but I was wondering if that's normal.

./mame64 apple2e -sl1 ssc -sl1:ssc:ssc_rs232 printer -printout outputfile.bin

and making sure that the printer and the ssc are using the same bps of 9600 in the Dip Switches and Machine Configuration menus

and then PR#1 and PRINT "HELLO" and PR#0


cat outputfile.bin | hexdump -C
00000000 8d 8a dd d0 d2 c9 ce d4 a0 a2 c8 c5 cc cc cf a2 |................|
00000010 8d 8a c8 c5 cc cc cf 8d 8a 8d 8a dd d0 d2 a3 b0 |................|
00000020

cat outputfile.bin | tr '\200-\377' '\000-\177' | hexdump -C
00000000 0d 0a 5d 50 52 49 4e 54 20 22 48 45 4c 4c 4f 22 |..]PRINT "HELLO"|
00000010 0d 0a 48 45 4c 4c 4f 0d 0a 0d 0a 5d 50 52 23 30 |..HELLO....]PR#0|
00000020

cat outputfile.bin | tr '\200-\377' '\000-\177'

]PRINT "HELLO"
HELLO

]PR#0

#110664 - 08/25/17 01:38 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
It's normal AFAIK for PR#1 to output Apple high-ASCII since the text screen requires the high bit to be set. Changing the SSC DIP switches to a 7-bit data format might help, assuming the serial printer device can also be changed to that format.

#110665 - 08/25/17 03:27 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: R. Belmont]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
That makes sense with regards to the high-bit.

I tried setting the ssc to 7 bit and the printer to 7 bit but it didn't seem to work properly, inserting spurious 7f characters.

PR#1, PRINT "TESTING 7 BIT" and it comes out mangled. Looks like 8 bit is the way to go.

Code
hexdump -C test7bit5.bin  
00000000  0d 29 5d 7f 50 52 7f 49  7f 4e 54 7f 20 7f 22 54  |.)].PR.I.NT. ."T|
00000010  7f 45 7f 53 54 7f 49 7f  4e 47 20 7f 37 7f 20 7f  |.E.ST.I.NG .7. .|
00000020  42 49 7f 54 7f 22 0d 29  54 15 4d 54 25 39 47 20  |BI.T.".)T.MT%9G |
00000030  5d 05 25 49 51 7f 0d 29  0d 29 5d 7f 50 52 7f 23  |].%IQ..).)].PR.#|
00000040  7f 30                                             |.0|
00000042

#110666 - 08/25/17 06:55 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jun 2014
Posts: 64
peter ferrie Offline
Member
peter ferrie  Offline
Member

Joined: Jun 2014
Posts: 64
Yes, it's normal behavior, as RB said. Apple "normal" mode text has at least the seventh bit set (i.e. #$80-FF); flash mode has only the sixth bit set (#$40-7F), inverse has neither bit set (i.e. #$00-3F), and you might notice that there's no lowercase in flash or inverse because of the restricted range.
No, you can't switch to 7-bit, because when it was 8-bit originally, you'll get the marker to say that a conversion happened, as you can see.
You'll have to send in 8-bit form, and then perform the conversion after the data arrive.

#110670 - 08/26/17 12:35 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Just for fun, I was fiddling with the arcbd and was able to get the MLDEMO to do something by adding this to a2arcadebd.cpp.

I don't know how correct this is, but they seem to run.

void a2bus_arcboard_device::write_c0nx(address_space &space, uint8_t offset, uint8_t data)
{
switch (offset)
{
case 0:
m_tms->vram_write(space, 0, data);
break;
case 1:
m_tms->register_write(space, 0, data);
break;


./mame64 apple2e -sl4 arcbd -flop1 Amparcade_1983_Third_Millenium_Engineering_Corporation.do -debug


[Linked Image]
[Linked Image]
[Linked Image]

It's interesting that in this article from Creative Computing that the mountain scene gets horizontally flipped left/right.

[Linked Image]


and the VDPTEST program runs now

before:
[Linked Image]
with the change:
[Linked Image]

#110674 - 08/27/17 11:55 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I got inspired and thought I'd take a stab at making a driver for the supersprite board basically copying the arcbd source and it works!

I hooked up the tms5220 and it has speech too. Amazing.

./mame64 apple2e -sl7 ssprite -flop1 StarSprite\ Demonstration.DSK -debug

[Linked Image]
[Linked Image]
[Linked Image]
[Linked Image]
[Linked Image]


[Linked Image]

Last edited by Golden Child; 08/27/17 12:34 PM.
#110693 - 09/01/17 02:01 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: peter ferrie]  
Joined: Jun 2014
Posts: 64
peter ferrie Offline
Member
peter ferrie  Offline
Member

Joined: Jun 2014
Posts: 64
The glitching is caused by the same issue, but I can't see how to fix it without rewriting the driver to use a timer to control screen updating.
The 80-column firmware does a lot of switching between pages, faster than the hardware can refresh the display, but each switch triggers a screen update in MAME.

#110694 - 09/01/17 12:14 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Oh, that sucks. The French Touch demos flip page 1 / page 2 mid-scanline and expect it to change the display immediately. (BTW, they posted the source for all their stuff if you missed it).

#110696 - 09/01/17 05:52 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jan 2012
Posts: 878
rfka01 Offline
Senior Member
rfka01  Offline
Senior Member

Joined: Jan 2012
Posts: 878
Bavaria
Alive as ... a Do-Do

http://forum.classic-computing.de/index.php?page=Thread&threadID=11845

This thread contains the ROMs for an Apple II clone which has "Do-Do" as its signon message smile


NCR DMV- DEC Rainbow- Siemens PCD- ITT 3030-Oly People- Acorn A5000- Olivetti M20
#110745 - 09/06/17 08:12 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I've been noticing that the sound output from the apple2e driver has a lot of "pops and crackles." It must be coming from the Mockingboard because it disappears if I bring up the ` volume sliders and set the volume for each AY channel to zero. It has a very regular pattern, almost like someone typing.

Is there a way to disable the Mockingboard from the command line as it seems to be hard wired in the driver? Like -sl4 empty_slot? I suppose I could always just comment it out and recompile.

MCFG_A2BUS_SLOT_ADD("a2bus", "sl4", apple2_cards, "mockingboard")

You can hear it in this video in the background:


#110746 - 09/06/17 08:23 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2004
Posts: 1,939
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member

Joined: Feb 2004
Posts: 1,939
Sydney, Australia
You can empty a slot from the command line, e.g. -sl4 "" (two double quotes with nothing between them), or you can put something like a mouse card in the slot instead.

#110747 - 09/06/17 12:09 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
I've never gotten that noise. I suspect your system isn't able to keep up with full frame rate with the Mockingboard installed. Enable the MAME keys and press F11 to monitor that - if it drops below 100% when you hear the crackles that's what's happening.

#110748 - 09/06/17 03:49 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I brought up the F11 display and sure enough, it was tracking below 100% at times. Most of the time it would hover from 90% to 100%. The pops would definitely get worse when momentarily it would drop to around 60%.

I'm running Ubuntu on a core i5 2.67G x 4, should that be able to keep up?

Unfortunately, the on board sound doesn't work under ubuntu, so I've got a USB audio adapter and I wonder if that contributes to any slowdowns.

Thanks for the -sl4 "" tip, that empties out the Mockingboard.

#110749 - 09/06/17 04:23 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
2.67 i5 should be fine. Do you have some background process that's using a lot of CPU?

#110750 - 09/06/17 04:37 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jul 2015
Posts: 36
anikom15 Offline
Member
anikom15  Offline
Member

Joined: Jul 2015
Posts: 36
I know if I don't plug in my laptop, CPU governing kills performance on Windows.

#110751 - 09/06/17 05:07 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I can close pretty much everything (including firefox) and I still get the pops. It all works so well graphics and soundwise aside from the pops. If it didn't pop I wouldn't even notice that it wasn't running 100%.


I have ubuntu's system monitor running and it doesn't show excessive cpu.

edit:

using F8 and F9 to adjust the frameskip, along with F10 to toggle the throttle makes a big difference.

Setting frameskip to 4/10 and keeping throttle on results in virtually no popping/crackling at all.

I fiddled with some pulseaudio tips at https://wiki.archlinux.org/index.php/PulseAudio/Troubleshooting#Glitches.2C_skips_or_crackling but that didn't seem to make any difference for me.


Last edited by Golden Child; 09/06/17 06:37 PM.
#110752 - 09/07/17 09:31 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2004
Posts: 1,939
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member

Joined: Feb 2004
Posts: 1,939
Sydney, Australia
If increasing frameskip improves performance, and MAME isn't pegged at 100% on a CPU core when you're experiencing the issues, it suggests an issue with video card drivers/configuration.

#110753 - 09/07/17 12:58 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
-sdlvideofps will give an idea how performant your video output is. Running an HP9000/320 on my MacBook, it says this:

Code
  0.01s,    1 F, avrg game: 68.78 FPS 14.54 ms/f, avrg video: 414.14 FPS 2.41 ms/f, last video:   inf FPS 1.26 ms/f
  1.03s,   72 F, avrg game: 70.02 FPS 14.28 ms/f, avrg video: 708.18 FPS 1.41 ms/f, last video:   inf FPS 1.18 ms/f
  2.03s,  142 F, avrg game: 69.98 FPS 14.29 ms/f, avrg video: 700.22 FPS 1.43 ms/f, last video:   inf FPS 2.07 ms/f
  3.04s,  213 F, avrg game: 70.01 FPS 14.28 ms/f, avrg video: 719.18 FPS 1.39 ms/f, last video:   inf FPS 1.15 ms/f
  4.06s,  284 F, avrg game: 70.00 FPS 14.29 ms/f, avrg video: 735.14 FPS 1.36 ms/f, last video:   inf FPS 1.47 ms/f
  5.07s,  355 F, avrg game: 70.00 FPS 14.28 ms/f, avrg video: 738.10 FPS 1.35 ms/f, last video:   inf FPS 1.19 ms/f


The "avrg game" is the core emulation's frame rate (this system is a computer putting out a 1024x768@70 Hz screen, so the 70.00 once it settles in is correct), and "avrg video" shows how fast MAME would run if all it did was upload frames in the current configuration. With decent GL drivers that should be above 300%; if it's much below that you might have problems.

#110754 - 09/07/17 04:25 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I tried -sdlvideofps with both -video opengl and -video soft and

Code
./mame64 apple2e -sdlvideofps -video opengl
  0.02s,    1 F, avrg game: 60.09 FPS 16.64 ms/f, avrg video: 115.03 FPS 8.69 ms/f, last video:   inf FPS 4.33 ms/f
  1.02s,   57 F, avrg game: 55.82 FPS 17.91 ms/f, avrg video: 169.71 FPS 5.89 ms/f, last video:   inf FPS 1.17 ms/f
  2.04s,  115 F, avrg game: 56.45 FPS 17.71 ms/f, avrg video: 164.82 FPS 6.07 ms/f, last video:   inf FPS 2.71 ms/f
  3.04s,  171 F, avrg game: 56.27 FPS 17.77 ms/f, avrg video: 165.24 FPS 6.05 ms/f, last video:   inf FPS 1.96 ms/f
  4.05s,  230 F, avrg game: 56.74 FPS 17.62 ms/f, avrg video: 170.18 FPS 5.88 ms/f, last video:   inf FPS 16.02 ms/f
  5.07s,  289 F, avrg game: 57.04 FPS 17.53 ms/f, avrg video: 184.40 FPS 5.42 ms/f, last video:   inf FPS 7.71 ms/f
  6.08s,  349 F, avrg game: 57.40 FPS 17.42 ms/f, avrg video: 196.23 FPS 5.10 ms/f, last video:   inf FPS 1.16 ms/f
  7.09s,  408 F, avrg game: 57.53 FPS 17.38 ms/f, avrg video: 193.83 FPS 5.16 ms/f, last video:   inf FPS 15.00 ms/f

./mame64 apple2e -video soft
  0.01s,    1 F, avrg game: 78.69 FPS 12.71 ms/f, avrg video: 75.66 FPS 13.22 ms/f, last video:   inf FPS 6.12 ms/f
  1.02s,   59 F, avrg game: 57.62 FPS 17.36 ms/f, avrg video: 135.10 FPS 7.40 ms/f, last video:   inf FPS 5.98 ms/f
  2.04s,  117 F, avrg game: 57.42 FPS 17.41 ms/f, avrg video: 121.47 FPS 8.23 ms/f, last video:   inf FPS 6.30 ms/f
  3.06s,  175 F, avrg game: 57.12 FPS 17.51 ms/f, avrg video: 120.19 FPS 8.32 ms/f, last video:   inf FPS 19.81 ms/f
  4.07s,  231 F, avrg game: 56.75 FPS 17.62 ms/f, avrg video: 114.54 FPS 8.73 ms/f, last video:   inf FPS 29.81 ms/f
  5.08s,  289 F, avrg game: 56.92 FPS 17.57 ms/f, avrg video: 114.66 FPS 8.72 ms/f, last video:   inf FPS 6.87 ms/f
  6.10s,  348 F, avrg game: 57.02 FPS 17.54 ms/f, avrg video: 112.14 FPS 8.92 ms/f, last video:   inf FPS 19.09 ms/f
  7.12s,  408 F, avrg game: 57.33 FPS 17.44 ms/f, avrg video: 115.75 FPS 8.64 ms/f, last video:   inf FPS 6.46 ms/f



-nowaitvsync doesn't seem to make any difference.

lspci tells me that I'm running a:
01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] RV710 [Radeon HD 4550]

glxinfo | grep AMD
Device: AMD RV710 (DRM 2.49.0 / 4.10.0-33-generic, LLVM 4.0.0) (0x9540)
OpenGL renderer string: Gallium 0.4 on AMD RV710 (DRM 2.49.0 / 4.10.0-33-generic, LLVM 4.0.0)

#110773 - 09/11/17 10:01 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I was fiddling with the apple2e driver's Machine Configuration/Composite Monitor Type options and I noticed that the B+W/green/amber don't properly show the shift from the high bit.

So if I do this:

HGR
HCOLOR=1
HPLOT 0,0 TO 8,0
HPLOT 0,1 TO 8,1
POKE 8192,PEEK(8192)+128

and if you are in the black and white modes,
the pixels in the top row should have a horizontal shift to them.

[Linked Image]

and here's another small program to illustrate:

100 HGR:DATA 1,5,2,6:FOR I = 1 TO 4:READ C:HCOLOR=C:HPLOT 0,I TO 279,I:NEXT

[Linked Image]
[Linked Image]

and this is the result running the applepc emulator under dosbox

[Linked Image]
[Linked Image]

Last edited by Golden Child; 09/11/17 12:04 PM.
#110774 - 09/11/17 12:13 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Yes, that's known. It'll get fixed whenever we end up doing correct NTSC decoding in-line.

#110781 - 09/12/17 01:57 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Is there a way to keep mame from exiting when you hit ESC when in Partial Keyboard Mode?

When using the apple2e driver, I find myself hitting ESC to do stuff like apple ESC-IJKM text screen editing and mame drops out immediately. It'd be awesome if there was a delay or something that you had to hold ESC for 3 seconds or some kind of exit confirmation. "Are you sure you want to exit?"

I must've done this 100 times now.

#110782 - 09/12/17 02:02 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Apr 2012
Posts: 199
Pernod Online content
Senior Member
Pernod  Online Content
Senior Member

Joined: Apr 2012
Posts: 199
UK
Originally Posted by Golden Child
Is there a way to keep mame from exiting when you hit ESC when in Partial Keyboard Mode?

Yep, add this to your mame.ini:
Code
confirm_quit              1

It'll be in the CORE MISC OPTIONS section.


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
#110783 - 09/12/17 04:03 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Pernod]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
ahhhh, thank you.

I see there's a command line option -confirm_quit also.

I kept looking for the mame.ini file and I see that I have to create it with ./mame64 -createconfig

#110787 - 09/12/17 02:15 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
It'd be cool if mame had a quit delay where you could just hit ESC, it would pop up a notification of an impending quit and if you were quiet for say 5 seconds without hitting any keystrokes it would exit, otherwise it would cancel the quit.

You'd have the convenience of -noconfirm_quit with the ability to recover if you accidentally hit ESC.

That would save you a keystroke of hitting the enter key.

Last edited by Golden Child; 09/12/17 02:15 PM.
#110789 - 09/12/17 11:47 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: R. Belmont]  
Joined: Jun 2014
Posts: 64
peter ferrie Offline
Member
peter ferrie  Offline
Member

Joined: Jun 2014
Posts: 64
Originally Posted by R. Belmont
Oh, that sucks. The French Touch demos flip page 1 / page 2 mid-scanline and expect it to change the display immediately. (BTW, they posted the source for all their stuff if you missed it).


I've added a check for 80-column mode, which seems to solve the problem.
The 40-col screen updates immediately, the 80-col one doesn't.
And yes, I saw the French Touch stuff. He was one person. His name is Arnaud. We got to know each other a little bit before he retired.

#110790 - 09/12/17 11:54 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Great, thanks Peter!

#110792 - 09/14/17 07:50 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I got an Intel Core i3-2120 based system running the integrated graphics and sound and that seems to have totally fixed the audio stuttering that I was seeing before:

According to Ubuntu's System Information:
Processor: Intel® Core™ i3-2120 CPU @ 3.30GHz × 4 (2 cores with hyperthreading)
Graphics: Intel® Sandybridge Desktop

I took the hard drive of my original Ubuntu 17.04 system, made an image with dd and copied that to the new system so it's the exact same system running on different hardware.

I hear no popping at all unless I fiddle with the bgfx video filter sliders and get to the slow ones.

On this computer, the onboard Intel audio works fine and I don't get pops even with the -video soft.

Code

./mame64 apple2e  -sdlvideofps -video bgfx  -prescale 2
  0.02s,    1 F, avrg game: 59.75 FPS 16.74 ms/f, avrg video: 1561.91 FPS 0.64 ms/f, last video:   inf FPS 0.36 ms/f
  1.03s,   62 F, avrg game: 60.00 FPS 16.67 ms/f, avrg video: 3662.88 FPS 0.27 ms/f, last video:   inf FPS 0.28 ms/f
  2.05s,  123 F, avrg game: 60.00 FPS 16.67 ms/f, avrg video: 3540.34 FPS 0.28 ms/f, last video:   inf FPS 0.33 ms/f


./mame64 apple2e -sdlvideofps -video opengl -prescale 2
  0.02s,    1 F, avrg game: 60.02 FPS 16.66 ms/f, avrg video: 487.59 FPS 2.05 ms/f, last video:   inf FPS 1.01 ms/f
  1.03s,   62 F, avrg game: 60.00 FPS 16.67 ms/f, avrg video: 821.80 FPS 1.22 ms/f, last video:   inf FPS 1.01 ms/f
  2.05s,  123 F, avrg game: 60.00 FPS 16.67 ms/f, avrg video: 814.30 FPS 1.23 ms/f, last video:   inf FPS 1.08 ms/f
 

./mame64 apple2e -sdlvideofps -video soft -prescale 2
  0.02s,    1 F, avrg game: 61.71 FPS 16.21 ms/f, avrg video: 77.32 FPS 12.93 ms/f, last video:   inf FPS 6.24 ms/f
  1.03s,   62 F, avrg game: 60.05 FPS 16.65 ms/f, avrg video: 152.53 FPS 6.56 ms/f, last video:   inf FPS 5.82 ms/f
  2.03s,  122 F, avrg game: 60.00 FPS 16.67 ms/f, avrg video: 151.10 FPS 6.62 ms/f, last video:   inf FPS 6.66 ms/f


Are those bgfx numbers for real? 3662 FPS?

So I did learn a couple of things:

Onboard video can be faster than a discrete card. (really!)

You can change the audio driver with:

export SDL_AUDIODRIVER=pulseaudio
export SDL_AUDIODRIVER=alsa

and -frameskip 6 will do exactly 30 FPS if you're into 30 fps video:

I pulled the usb audio device and put it on the new system and the pops are back. So I'm going to blame it on the usb sound dongle.

I feel like widlarizing that thing.

#110793 - 09/14/17 08:47 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
That's much better performance, glad you found the issue!

BGFX uses modern OpenGL on Linux, which is likely a faster path on the Intel drivers than the ancient GL 1.2/2.0 stuff -video opengl uses, although that much speedup is still kind of unexpected.

#110794 - 09/14/17 10:54 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: R. Belmont]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Thanks for your help, RB. I am sure enjoying playing with the apple2e driver, especially now with no pops 8-)

#110827 - 09/23/17 08:33 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I've been fiddling with trying to write to the TMS9918 on the ssprite from Applesoft Basic. But for some reason it doesn't work correctly.

The ssprite board sits in slot 7, so it has the io addresses $C0Fx.

I set an address $C0F1 in the variable AD, then poke AD twice, which should set one of the TMS registers, but it doesn't, because it's reading from $C0F1 before it writes, which creates the side effect of resetting the TMS9918 address that it's going to write to. So it keeps thinking that it's getting the low byte of the address forever.

AD = 12*16*256+15*16+1:POKE AD,4:POKE AD, 128+7

(that should write 4 to the TMS9918 register 7, but it has no effect)


[Linked Image]


But doing the same thing from machine language doesn't introduce a read before the write.

CALL -151
4000: AD F1 C0 A9 F2 8D F1 C0 A9 87 8D F1 C0 60
which is just
LDA $C0F1
LDA #$F2
STA $C0F1
LDA #$87
STA $C0F1
RTS

4000G to execute it, and it works.


[Linked Image]

This is totally baffling me.

Is there something about the way applesoft does a poke, using

STA ($50),y

that activates a read before the write?

#110829 - 09/23/17 10:30 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: May 2010
Posts: 1,019
seanriddle Offline
Very Senior Member
seanriddle  Offline
Very Senior Member

Joined: May 2010
Posts: 1,019
Although my 6502 books don't seem to mention it, it looks like indirect indexed mode does a read from the effective address.

From the MAME source:
https://git.redump.net/mame/tree/src/devices/cpu/m6502/om6502.lst
Code
sta_idy
	TMP2 = read_pc();
	TMP = read(TMP2);
	TMP = set_h(TMP, read((TMP2+1) & 0xff));
	read(set_l(TMP, TMP+Y));
	write(TMP+Y, A);
	prefetch();


Another reference:
https://github.com/eteran/pretendo/blob/master/doc/cpu/6502.txt
Code
Indirect indexed addressing
Write instructions (STA, SHA)

        #    address   R/W description
       --- ----------- --- ------------------------------------------
        1      PC       R  fetch opcode, increment PC
        2      PC       R  fetch pointer address, increment PC
        3    pointer    R  fetch effective address low
        4   pointer+1   R  fetch effective address high,
                           add Y to low byte of effective address
        5   address+Y*  R  read from effective address,
                           fix high byte of effective address
        6   address+Y   W  write to effective address

       Notes: The effective address is always fetched from zero page,
              i.e. the zero page boundary crossing is not handled.

              * The high byte of the effective address may be invalid
                at this time, i.e. it may be smaller by $100.

#110830 - 09/24/17 01:22 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: seanriddle]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Hi Sean,

Thanks for looking that up. I was totally bewildered why machine language would work, but Applesoft pokes would not. That may explain why the Third Millennium Arcade Board has its write register port at $C0C1 and $C0C3 and the read register port at $C0C1 so it could work from both machine language and also Applesoft BASIC POKEing. If you POKE to $C0C3, on the Arcade Board, the STA ($50),Y read is harmless.

I was trying to do a little demo with both the Third Millennium Arcade Board in slot 4 and the Super Sprite in slot 7 and both have them display something, Now I know why my POKEs were ineffective. Man, that was driving me bats.


Last edited by Golden Child; 09/24/17 01:40 AM.
#110835 - 09/24/17 01:03 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I was using PR#1 along with specifying the ssc and a printer, but for some reason the DIP switches would reset themselves to "Communications Mode" along with "19200 baud". I'd set them to "Printer Mode / 9600" and that would disappear sometimes.

./mame64 apple2e -sl1 ssc -sl1:ssc:ssc_rs232 printer -printout myprintout.bin

What I discovered is that you have to keep specifying the "-sl1 ssc -sl1:ssc:ssc_rs232 printer -printout myprintout.bin" part on the command line.

If you don't, the DIP switches disappear from the UI menus and the next time you specify the ssc, those values will reset themselves to communications mode/19200 and your printout file will be scrambled eggs instead of sunny side up.


Is there a way to specify those settings from the command line?

Last edited by Golden Child; 09/24/17 01:04 PM.
#110836 - 09/24/17 02:08 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Right, the switches are only saved if the card is present, because otherwise you could put a different card with different switches in slot 1 and really confuse things. Your best bet is probably to make a batch file that runs MAME with the -sl1 ssc and so on.

#110837 - 09/24/17 02:31 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2004
Posts: 1,939
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member

Joined: Feb 2004
Posts: 1,939
Sydney, Australia
There's no way to set DIP switches on the command line right now, and the options system is rather buggy and limited. It's being rewritten, it's just time-consuming. This will open up more possibilities.

#110838 - 09/24/17 03:53 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
One last question for today: I was trying to edit my basic program in a text editor and paste it into the apple2e driver with UI Paste (Left Shift+Scroll Lock).

Some characters on the PC keyboard don't get typed properly:

" turns into @
* turns into nothing
() turns into *(
& turns into ^
@ turns into nothing

which makes it hard to paste programs.

pasting the following text into the apple2e driver:

Code
    exclaim!atsign@hash#dollarsign$percent%caret^amper&asterisk*leftparen(rightparen)
    dash-underscore_plus+equals=bracket[]curly{}backslash\verticalbar|
    tick`tilde~
    comma,period.lessthan<greaterthan>slash/question?semicolon;colon:singlequote'doublequote"
    abcdefghijklmnopqrstuvwxyz
    ABCDEFGHJIJKLMNOPQRSTUVWXYZ

[Linked Image]



so for instance:
Code
50 PRINT "ADDR WRITE SLOT=";S;" VALUE LO=";W0;" HI=";W1
51 SB = 49280:S0 = SB + 16 * S:S1 = S0 + 1:IP = 16384+20:I0=IP
52 POKE IP,160 + 13: POKE IP + 1, FN LO(S1): POKE IP + 2, FN HI(S1): IP = IP + 3 REM  AD LDA $C0C1

turns into:

Code
50 PRINT @ADDR WRITE SLOT=@;S;@ VALUE LO=@;W0;@ HI=@;W1
51 SB = 49280:S0 = SB + 16  S:S1 = S0 + 1:IP = 16384+20:I0=IP
52 POKE IP,160 + 13: POKE IP + 1, FN LO*S1(: POKE IP + 2, FN HI*S1(: IP = IP + 3 REM  AD LDA $C0C1




and a couple of things about UI Paste:

ALT+TAB to switch to my text editor, copy with CTRL+C, ALT+TAB to go back to the apple2e driver, ends up putting a CTRL+I into the text buffer so you have to hit enter to clear the input line.

if you type ? ASC(" then hit alt+tab then go back to mame with alt+tab then type ") you get a 9 (a CTRL+I).



You have to be really quick to hit Left Shift+Scroll Lock and let go of the Left Shift or 1234 PRINT turns into !@#$ PRINT.

It'd be cool if there was a delay before it actually started typing, and maybe even have a notification that comes on screen saying : UI Paste in progress. Perhaps even an abort mechanism that can stop a UI Paste in progress.


When a CR is encountered, the basic interpreter can't keep up with the keystrokes sometimes while it's processing the line and will sometimes drop the first character of the next line which can easily stomp other basic lines since the line number isn't right.

Note how the pasted text has missing characters at the beginning of the line.

Maybe there could be a CR delay that's longer than the normal character send time.


Upper and lowercase is a bit of a problem since caps lock is a must for Applesoft Basic programming, but if you were to paste UI lowercase text it wouldn't come out properly.

#110839 - 09/24/17 06:08 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Silly fun with having both the Arcade Board and the Super Sprite active.

./mame64 apple2e -sl4 arcbd -sl7 ssprite

[Linked Image]

edit:

and even more silly fun:

./mame64 apple2e -sl4 arcbd -sl5 arcbd -sl7 ssprite

[Linked Image]

trying to do more gets me a segfault:

./mame64 apple2e -sl7 ssprite -sl4 arcbd -sl5 arcbd -sl2 arcbd
Segmentation fault (core dumped)

Last edited by Golden Child; 09/24/17 11:45 PM.
#110845 - 09/25/17 12:00 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
MAME has a hardcoded max of 4 screens. I'm not sure where it comes from, it limits my ability to put 6 NuBus video cards in a Mac II and have real fun frown

#110846 - 09/25/17 01:54 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2004
Posts: 1,939
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member

Joined: Feb 2004
Posts: 1,939
Sydney, Australia
The maximum screen count comes from the built-in layouts. MAME can't dynamically generate layouts for an arbitrary number of screens. Make a github issue and assign it to me - I'll get around to it at some point.

#110863 - 09/26/17 12:33 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Some baby steps with lua: I thought I'd see if I could "dump" the Apple 2 text screen memory to the lua console.


./mame64 apple2e -plugin console


Code
cpu = manager:machine().devices[":maincpu"];mem = cpu.spaces["program"]

for i=0,23 do appletextaddress=0x400+(math.floor(i/8)*40+128*(i%8)); print(i.."  "..appletextaddress.."") end

for i=0,23 do appletextaddress=0x400+(math.floor(i/8)*40+128*(i%8)); a="";for k=0,39 do newchar = mem:read_i8(appletextaddress+k); newchar = newchar & 127 ; if newchar < 32 then newchar = newchar + 64; end; a=a..string.char(newchar); end; print (i.."  "..appletextaddress.." "..a); end



There's a minimal amount of character fixing, just take the char, strip the high bit and turn characters less than 32 into something recognizable by adding 64.


Running the little program:

100 HOME : FOR I = 1 TO 24: HTAB 1 : VTAB I: PRINT "Apple Text Line: ";I;: NEXT : VTAB 1

[Linked Image]


Code
0  1024 Apple Text Line: 1                      
1  1152 ]pple Text Line: 2                      
2  1280 Apple Text Line: 3                      
3  1408 Apple Text Line: 4                      
4  1536 Apple Text Line: 5                      
5  1664 Apple Text Line: 6                      
6  1792 Apple Text Line: 7                      
7  1920 Apple Text Line: 8                      
8  1064 Apple Text Line: 9                      
9  1192 Apple Text Line: 10                     
10  1320 Apple Text Line: 11                     
11  1448 Apple Text Line: 12                     
12  1576 Apple Text Line: 13                     
13  1704 Apple Text Line: 14                     
14  1832 Apple Text Line: 15                     
15  1960 Apple Text Line: 16                     
16  1104 Apple Text Line: 17                     
17  1232 Apple Text Line: 18                     
18  1360 Apple Text Line: 19                     
19  1488 Apple Text Line: 20                     
20  1616 Apple Text Line: 21                     
21  1744 Apple Text Line: 22                     
22  1872 Apple Text Line: 23                     
23  2000 Apple Text Line: 24                     


and my UI paste test becomes:

Code
0  1024                                         
1  1152 ]    EXCLAIM!ATSIGNHASH#DOLLARSIGN$PERCE
2  1280 NT%CARETAMPER^ASTERISKLEFTPAREN*RIGHTPAR
3  1408 EN(                                     
4  1536                                         
5  1664 ?SYNTAX ERROR                           
6  1792 ]ASH-UNDERSCORE_PLUS+EQUALS=BRACKET[]CUR
7  1920 LY{}BACKSLASH\VERTICALBAR|              
8  1064                                         
9  1192 ?SYNTAX ERROR                           
10  1320 ]TICK`TILDE~                            
11  1448                                         
12  1576 ?SYNTAX ERROR                           
13  1704 ]    COMMA,PERIOD.LESSTHAN<GREATERTHAN>S
14  1832 LASH/QUESTION?SEMICOLON;COLON:SINGLEQUOT
15  1960 E&DOUBLEQUOTE@                          
16  1104                                         
17  1232 ?SYNTAX ERROR                           
18  1360 ]BCDEFGHIJKLMNOPQRSTUVWXYZ              
19  1488                                         
20  1616 ?SYNTAX ERROR                           
21  1744 ]   ABCDEFGHJIJKLMNOPQRSTUVWXYZ         
22  1872                                         
23  2000                                         

#110868 - 09/26/17 10:33 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
This lua stuff is really cool.

I wanted to see if it could write to the TMS9918 on the arcade board and I was able to write to the VRAM, but I couldn't find a way to access the TMS9918 registers programmatically.

I think that the TMS9918 have to be initialized with a real program, because there are side effects from the code that sets the registers. Once it's initialized, then I can just write stuff to the VRAM space and it displays.

Wow, this is so much faster to run than my Applesoft programs. The effects are seen virtually instantaneously.

Now if I just had a way to do an emu.frameadvance() (which doesn't work) or some kind of way to do a delay like wait for vblank.


[Linked Image]



A very short program to initialize the TMS 9918 registers.

Code
1  DEF  FN LO(X) = ((X / 256) -  INT (X / 256)) * 256: DEF  FN HI(X) =  INT (X / 256)

4  GOTO 100
5  PRINT "REG WRITE: SLOT=";S;" VALUE=";W0;" REG=";W1
6 SB = 49280:S0 = SB + 16 * S:S1 = S0 + 1
7 IP = 16384
8  POKE IP,160 + 13: POKE IP + 1, FN LO(S1): POKE IP + 2, FN HI(S1): REM LDA $C0C1
9 IP = IP + 3: POKE IP,160 + 9: POKE IP + 1,W0:IP = IP + 2: REM LDA #$W0
10  POKE IP,128 + 13: POKE IP + 1, FN LO(S1): POKE IP + 2, FN HI(S1):IP = IP + 3: REM STA $C0C1
11 IP = IP + 0: POKE IP,160 + 9: POKE IP + 1,W1:IP = IP + 2: REM LDA #$W1
13 IP = IP + 0: POKE IP,128 + 13: POKE IP + 1, FN LO(S1): POKE IP + 2, FN HI(S1):IP = IP + 3: REM STA $C0C1
14  POKE IP,6 * 16:IP = IP + 1: REM  RTS
15  CALL 16384
16  RETURN 

100 S = 4:W0 = 2:W1 = 128 + 0: GOSUB 5
101 S = 4:W0 = 193:W1 = 128 + 1: GOSUB 5
102 S = 4:W0 = 14:W1 = 128 + 2: GOSUB 5
103 S = 4:W0 = 255:W1 = 128 + 3: GOSUB 5
104 S = 4:W0 = 3:W1 = 128 + 4: GOSUB 5
105 S = 4:W0 = 118:W1 = 128 + 5: GOSUB 5
106 S = 4:W0 = 3:W1 = 128 + 6: GOSUB 5
107 S = 4:W0 = 15:W1 = 128 + 7: GOSUB 5
108  END 


Then I can run this lua program with dofile("fontarray_tms.lua")


Code
tms= manager:machine().devices[":sl4:arcbd:arcbd_tms"]
mem = tms.spaces["vram"]

fontarray = {32, 0,0,0,0,0,0,0,0,
33, 24,60,60,24,24,0,24,0,
34, 108,108,0,0,0,0,0,0,
35, 108,108,254,108,254,108,108,0,
36, 24,62,96,60,6,124,24,0,
37, 0,198,204,24,48,102,198,0,
38, 56,108,104,118,220,204,118,0,
39, 24,24,48,0,0,0,0,0,
40, 12,24,48,48,48,24,12,0,
41, 48,24,12,12,12,24,48,0,
42, 0,102,60,255,60,102,0,0,
43, 0,24,24,126,24,24,0,0,
44, 0,0,0,0,0,24,24,48,
45, 0,0,0,126,0,0,0,0,
46, 0,0,0,0,0,24,24,0,
47, 3,6,12,24,48,96,192,0,
48, 60,102,110,126,118,102,60,0,
49, 24,56,24,24,24,24,126,0,
50, 60,102,6,28,48,102,126,0,
51, 60,102,6,28,6,102,60,0,
52, 28,60,108,204,254,12,30,0,
53, 126,96,124,6,6,102,60,0,
54, 28,48,96,124,102,102,60,0,
55, 126,102,6,12,24,24,24,0,
56, 60,102,102,60,102,102,60,0,
57, 60,102,102,62,6,12,56,0,
58, 0,24,24,0,0,24,24,0,
59, 0,24,24,0,0,24,24,48,
60, 12,24,48,96,48,24,12,0,
61, 0,0,126,0,0,126,0,0,
62, 48,24,12,6,12,24,48,0,
63, 60,102,6,12,24,0,24,0,
64, 124,198,222,222,222,192,120,0,
65, 24,60,60,102,126,195,195,0,
66, 252,102,102,124,102,102,252,0,
67, 60,102,192,192,192,102,60,0,
68, 248,108,102,102,102,108,248,0,
69, 254,102,96,120,96,102,254,0,
70, 254,102,96,120,96,96,240,0,
71, 60,102,192,206,198,102,62,0,
72, 102,102,102,126,102,102,102,0,
73, 126,24,24,24,24,24,126,0,
74, 14,6,6,6,102,102,60,0,
75, 230,102,108,120,108,102,230,0,
76, 240,96,96,96,98,102,254,0,
77, 130,198,238,254,214,198,198,0,
78, 198,230,246,222,206,198,198,0,
79, 56,108,198,198,198,108,56,0,
80, 252,102,102,124,96,96,240,0,
81, 56,108,198,198,198,108,60,6,
82, 252,102,102,124,108,102,227,0,
83, 60,102,112,56,14,102,60,0,
84, 126,90,24,24,24,24,60,0,
85, 102,102,102,102,102,102,62,0,
86, 195,195,102,102,60,60,24,0,
87, 198,198,198,214,254,238,198,0,
88, 195,102,60,24,60,102,195,0,
89, 195,195,102,60,24,24,60,0,
90, 254,198,140,24,50,102,254,0,
91, 60,48,48,48,48,48,60,0,
92, 192,96,48,24,12,6,3,0,
93, 60,12,12,12,12,12,60,0,
94, 16,56,108,198,0,0,0,0,
95, 0,0,0,0,0,0,0,254,
96, 24,24,12,0,0,0,0,0,
97, 0,0,60,6,30,102,59,0,
98, 224,96,108,118,102,102,60,0,
99, 0,0,60,102,96,102,60,0,
100, 14,6,54,110,102,102,59,0,
101, 0,0,60,102,126,96,60,0,
102, 28,54,48,120,48,48,120,0,
103, 0,0,59,102,102,60,198,124,
104, 224,96,108,118,102,102,230,0,
105, 24,0,56,24,24,24,60,0,
106, 6,0,6,6,6,6,102,60,
107, 224,96,102,108,120,108,230,0,
108, 56,24,24,24,24,24,60,0,
109, 0,0,102,119,107,99,99,0,
110, 0,0,124,102,102,102,102,0,
111, 0,0,60,102,102,102,60,0,
112, 0,0,220,102,102,124,96,240,
113, 0,0,61,102,102,62,6,7,
114, 0,0,236,118,102,96,240,0,
115, 0,0,62,96,60,6,124,0,
116, 16,48,124,48,48,52,24,0,
117, 0,0,204,204,204,204,118,0,
118, 0,0,204,204,204,120,48,0,
119, 0,0,198,214,214,108,108,0,
120, 0,0,99,54,28,54,99,0,
121, 0,0,102,102,102,60,24,112,
122, 0,0,126,76,24,50,126,0,
123, 14,24,24,112,24,24,14,0,
124, 24,24,24,24,24,24,24,0,
125, 112,24,24,14,24,24,112,0,
126, 114,156,0,0,0,0,0,0,
127, 0,0,0,0,0,0,0,0
}

-- pattern table at 0x0000

i=1
bytepos=0x0000+32*8
while(true) do
 if i>table.maxn(fontarray) then break; end;
  charnum = fontarray[i];
  i = i + 1;
  for j=1,8 do  mem:write_i8(bytepos,fontarray[i]); i = i + 1; bytepos = bytepos+1; end
end

-- name table at 0x3800

bytepos = 0x3800

for j=0,2 do
for i=0,255 do mem:write_i8(bytepos,i); bytepos = bytepos+1; end
end

-- color table at 0x2000

bytepos = 0x2000

for i=0,6143 do mem:write_i8(bytepos,15*16+4); bytepos = bytepos+1; end

-- use our font array for a sprite pattern table also

i=1
bytepos=0x1800+32*8
while(true) do
 if i>table.maxn(fontarray) then break; end;
  charnum = fontarray[i];
  i = i + 1;
  for j=1,8 do  mem:write_i8(bytepos,fontarray[i]); i = i + 1; bytepos = bytepos+1; end
end

function setsprite(sprite,x,y,pattern,color)
bytepos=0x3b00+sprite*4
if y>=0 then mem:write_i8(bytepos,y) end -- vertical first
if x>=0 then mem:write_i8(bytepos+1,x)  end
if pattern>=0 then mem:write_i8(bytepos+2,pattern) end
if color >=0 then mem:write_i8(bytepos+3,color) end
end


a = "MameTMS 99184 spriteper line max"

for i=0,string.len(a)-1 do
 setsprite(i,50+(i%4)*20,30+math.floor(i/4)*20,string.byte(a,i+1),(i*2+1)%16);
end

-- dofile("fontarray_tms.lua")



#110869 - 09/26/17 11:55 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
You could write the TMS registers from Lua by going through the Apple II's address space, I think. Obviously it wouldn't be slot-independent then, but smile

#110870 - 09/27/17 12:13 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Jan 2012
Posts: 763
crazyc Offline
Senior Member
crazyc  Offline
Senior Member

Joined: Jan 2012
Posts: 763
Originally Posted by Golden Child
Now if I just had a way to do an emu.frameadvance() (which doesn't work) or some kind of way to do a delay like wait for vblank.

emu.register_frame(cbfunction) will call cbfunction at vblank. If you want to draw to the screen though lua (directly, not by writing to the emulated vram) you need to use emu.register_frame_done(cbfunction) which calls cbfunction after the frame is drawn to the host screen.

#110877 - 09/27/17 03:29 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: R. Belmont]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Thanks RB, you're right, I can just mem:write_i8(0xc0c1,data).

I don't know why I couldn't get it to work before, probably because I had an OBOE where I write the registers.

I had a for loop whose index started at 1 but the register write was mem:write_i8(0xc0c1,128+i) instead of write_i8(0xc0c1,128+(i-1)) so the wrong register was getting the value.


Code
cpu = manager:machine().devices[":maincpu"];mem = cpu.spaces["program"]

reginitarray = {2,196,14,255,3,118,3,15}

for i=1,table.maxn(reginitarray) do 
dummy=mem:read_i8(0xc0c1);
mem:write_i8(0xc0c1,reginitarray[i]); mem:write_i8(0xc0c1,128+(i-1)); end



Code
-- dofile("tms9918_apple_memspace.lua")

fontarray = {32, 0,0,0,0,0,0,0,0,
33, 24,60,60,24,24,0,24,0,
34, 108,108,0,0,0,0,0,0,
35, 108,108,254,108,254,108,108,0,
36, 24,62,96,60,6,124,24,0,
37, 0,198,204,24,48,102,198,0,
38, 56,108,104,118,220,204,118,0,
39, 24,24,48,0,0,0,0,0,
40, 12,24,48,48,48,24,12,0,
41, 48,24,12,12,12,24,48,0,
42, 0,102,60,255,60,102,0,0,
43, 0,24,24,126,24,24,0,0,
44, 0,0,0,0,0,24,24,48,
45, 0,0,0,126,0,0,0,0,
46, 0,0,0,0,0,24,24,0,
47, 3,6,12,24,48,96,192,0,
48, 60,102,110,126,118,102,60,0,
49, 24,56,24,24,24,24,126,0,
50, 60,102,6,28,48,102,126,0,
51, 60,102,6,28,6,102,60,0,
52, 28,60,108,204,254,12,30,0,
53, 126,96,124,6,6,102,60,0,
54, 28,48,96,124,102,102,60,0,
55, 126,102,6,12,24,24,24,0,
56, 60,102,102,60,102,102,60,0,
57, 60,102,102,62,6,12,56,0,
58, 0,24,24,0,0,24,24,0,
59, 0,24,24,0,0,24,24,48,
60, 12,24,48,96,48,24,12,0,
61, 0,0,126,0,0,126,0,0,
62, 48,24,12,6,12,24,48,0,
63, 60,102,6,12,24,0,24,0,
64, 124,198,222,222,222,192,120,0,
65, 24,60,60,102,126,195,195,0,
66, 252,102,102,124,102,102,252,0,
67, 60,102,192,192,192,102,60,0,
68, 248,108,102,102,102,108,248,0,
69, 254,102,96,120,96,102,254,0,
70, 254,102,96,120,96,96,240,0,
71, 60,102,192,206,198,102,62,0,
72, 102,102,102,126,102,102,102,0,
73, 126,24,24,24,24,24,126,0,
74, 14,6,6,6,102,102,60,0,
75, 230,102,108,120,108,102,230,0,
76, 240,96,96,96,98,102,254,0,
77, 130,198,238,254,214,198,198,0,
78, 198,230,246,222,206,198,198,0,
79, 56,108,198,198,198,108,56,0,
80, 252,102,102,124,96,96,240,0,
81, 56,108,198,198,198,108,60,6,
82, 252,102,102,124,108,102,227,0,
83, 60,102,112,56,14,102,60,0,
84, 126,90,24,24,24,24,60,0,
85, 102,102,102,102,102,102,62,0,
86, 195,195,102,102,60,60,24,0,
87, 198,198,198,214,254,238,198,0,
88, 195,102,60,24,60,102,195,0,
89, 195,195,102,60,24,24,60,0,
90, 254,198,140,24,50,102,254,0,
91, 60,48,48,48,48,48,60,0,
92, 192,96,48,24,12,6,3,0,
93, 60,12,12,12,12,12,60,0,
94, 16,56,108,198,0,0,0,0,
95, 0,0,0,0,0,0,0,254,
96, 24,24,12,0,0,0,0,0,
97, 0,0,60,6,30,102,59,0,
98, 224,96,108,118,102,102,60,0,
99, 0,0,60,102,96,102,60,0,
100, 14,6,54,110,102,102,59,0,
101, 0,0,60,102,126,96,60,0,
102, 28,54,48,120,48,48,120,0,
103, 0,0,59,102,102,60,198,124,
104, 224,96,108,118,102,102,230,0,
105, 24,0,56,24,24,24,60,0,
106, 6,0,6,6,6,6,102,60,
107, 224,96,102,108,120,108,230,0,
108, 56,24,24,24,24,24,60,0,
109, 0,0,102,119,107,99,99,0,
110, 0,0,124,102,102,102,102,0,
111, 0,0,60,102,102,102,60,0,
112, 0,0,220,102,102,124,96,240,
113, 0,0,61,102,102,62,6,7,
114, 0,0,236,118,102,96,240,0,
115, 0,0,62,96,60,6,124,0,
116, 16,48,124,48,48,52,24,0,
117, 0,0,204,204,204,204,118,0,
118, 0,0,204,204,204,120,48,0,
119, 0,0,198,214,214,108,108,0,
120, 0,0,99,54,28,54,99,0,
121, 0,0,102,102,102,60,24,112,
122, 0,0,126,76,24,50,126,0,
123, 14,24,24,112,24,24,14,0,
124, 24,24,24,24,24,24,24,0,
125, 112,24,24,14,24,24,112,0,
126, 114,156,0,0,0,0,0,0,
127, 0,0,0,0,0,0,0,0
}

cpu = manager:machine().devices[":maincpu"];mem = cpu.spaces["program"]

reginitarray = {2,196,14,255,3,118,3,15}

for i=1,table.maxn(reginitarray) do 
dummy=mem:read_i8(0xc0c1);
mem:write_i8(0xc0c1,reginitarray[i]); mem:write_i8(0xc0c1,128+(i-1)); end

-- name table at 0x3800

mem:write_i8(0xc0c1,0x0);
mem:write_i8(0xc0c1,0x38+64);

for j=0,2 do
for i=0,255 do mem:write_i8(0xc0c0,i) end
end

-- color table at 0x2000

mem:write_i8(0xc0c1,0x0);
mem:write_i8(0xc0c1,0x20+64);

for i=0,6143 do mem:write_i8(0xc0c0,15*16+4) end


-- pattern table at 0, but we'll start at 0x100 because our character data starts at 32

mem:write_i8(0xc0c1,0x0);
mem:write_i8(0xc0c1,0x0+1+64);  -- going to write data, so we add 64

i=1
while(true) do
 if i>table.maxn(fontarray) then break; end;
  charnum = fontarray[i];
  i = i + 1;
  for j=1,8 do  mem:write_i8(0xc0c0,fontarray[i]); i = i + 1; end
end

a = "Writing to the TMS9918 using addresses C0C0 and C0C1 with Lua"

xpos = 0  -- horizontal character pos (in characters)
ypos = 16*8  -- y character pos (in pixels)

copychar = {}  -- init array copychar

for aindex = 1,string.len(a) do

screenaddr = math.floor(ypos/8)*256+xpos*8 + (ypos % 8)

char = string.byte(a,aindex)
charaddr = char*8

-- get char into copychar array
mem:write_i8(0xc0c1,charaddr % 256);
mem:write_i8(0xc0c1,math.floor(charaddr/256));  -- going to read data, don't need to add anything

for i = 0,7 do copychar[i]=mem:read_i8(0xc0c0) end
mem:write_i8(0xc0c1,screenaddr % 256);
mem:write_i8(0xc0c1,math.floor(screenaddr/256)+64);  -- going to write data, add 64

for i= 0,7 do mem:write_i8(0xc0c0,copychar[i]); end
xpos = xpos + 1
end

#110878 - 09/27/17 03:37 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: crazyc]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Thanks for the emu.register_frame(cbfunction) suggestion. I'll give it a try. For some reason I had always had problems wrapping my head around that style of programming where you have functions that are called.

I've always thought linearly where the program follows a strict sequence. I like the concept of having a regular function that can pause itself and pick right up where it left off.

#110879 - 09/27/17 05:01 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Ok, just tried writing a little routine for emu.register_frame()

This will make the TMS9918 sprites swing back and forth.

I did run into a little trouble with write_i8 because it wants integer values, not floating point. If you send it a floating point value, it will write a zero.

-- mem:write_i8(0,255)
-- mem:write_i8(0,5.5) writes a ZERO for a floating point value, so we'd better use math.floor to integerize it.

So I can register_frame(), how do I unregister a function?

Every time I execute this lua script, it calls emu.register_frame again and swings back and forth faster and faster. Whee!


Code
-- dofile("tms_frame_call.lua")

framecount = 0

function tms_frame_call()

framecount = framecount + 4
sinoffset = math.floor(math.sin((framecount % 360)/360*(2*math.pi))*20);
for i=0,string.len(a)-1 do
 setsprite(i,math.floor(50+(i%4)*20+sinoffset),30+math.floor(i/4)*20,string.byte(a,i+1),(i*2+1)%16);
end
end

emu.register_frame(tms_frame_call)





This script sets everything up beforehand:

Code

-- dofile("fontarray_tms.lua")

tms= manager:machine().devices[":sl4:arcbd:arcbd_tms"]

-- tms= manager:machine().devices[":sl4:ezcgi:ezcgi_tms"]

mem = tms.spaces["vram"]


fontarray = {32, 0,0,0,0,0,0,0,0,
33, 24,60,60,24,24,0,24,0,
34, 108,108,0,0,0,0,0,0,
35, 108,108,254,108,254,108,108,0,
36, 24,62,96,60,6,124,24,0,
37, 0,198,204,24,48,102,198,0,
38, 56,108,104,118,220,204,118,0,
39, 24,24,48,0,0,0,0,0,
40, 12,24,48,48,48,24,12,0,
41, 48,24,12,12,12,24,48,0,
42, 0,102,60,255,60,102,0,0,
43, 0,24,24,126,24,24,0,0,
44, 0,0,0,0,0,24,24,48,
45, 0,0,0,126,0,0,0,0,
46, 0,0,0,0,0,24,24,0,
47, 3,6,12,24,48,96,192,0,
48, 60,102,110,126,118,102,60,0,
49, 24,56,24,24,24,24,126,0,
50, 60,102,6,28,48,102,126,0,
51, 60,102,6,28,6,102,60,0,
52, 28,60,108,204,254,12,30,0,
53, 126,96,124,6,6,102,60,0,
54, 28,48,96,124,102,102,60,0,
55, 126,102,6,12,24,24,24,0,
56, 60,102,102,60,102,102,60,0,
57, 60,102,102,62,6,12,56,0,
58, 0,24,24,0,0,24,24,0,
59, 0,24,24,0,0,24,24,48,
60, 12,24,48,96,48,24,12,0,
61, 0,0,126,0,0,126,0,0,
62, 48,24,12,6,12,24,48,0,
63, 60,102,6,12,24,0,24,0,
64, 124,198,222,222,222,192,120,0,
65, 24,60,60,102,126,195,195,0,
66, 252,102,102,124,102,102,252,0,
67, 60,102,192,192,192,102,60,0,
68, 248,108,102,102,102,108,248,0,
69, 254,102,96,120,96,102,254,0,
70, 254,102,96,120,96,96,240,0,
71, 60,102,192,206,198,102,62,0,
72, 102,102,102,126,102,102,102,0,
73, 126,24,24,24,24,24,126,0,
74, 14,6,6,6,102,102,60,0,
75, 230,102,108,120,108,102,230,0,
76, 240,96,96,96,98,102,254,0,
77, 130,198,238,254,214,198,198,0,
78, 198,230,246,222,206,198,198,0,
79, 56,108,198,198,198,108,56,0,
80, 252,102,102,124,96,96,240,0,
81, 56,108,198,198,198,108,60,6,
82, 252,102,102,124,108,102,227,0,
83, 60,102,112,56,14,102,60,0,
84, 126,90,24,24,24,24,60,0,
85, 102,102,102,102,102,102,62,0,
86, 195,195,102,102,60,60,24,0,
87, 198,198,198,214,254,238,198,0,
88, 195,102,60,24,60,102,195,0,
89, 195,195,102,60,24,24,60,0,
90, 254,198,140,24,50,102,254,0,
91, 60,48,48,48,48,48,60,0,
92, 192,96,48,24,12,6,3,0,
93, 60,12,12,12,12,12,60,0,
94, 16,56,108,198,0,0,0,0,
95, 0,0,0,0,0,0,0,254,
96, 24,24,12,0,0,0,0,0,
97, 0,0,60,6,30,102,59,0,
98, 224,96,108,118,102,102,60,0,
99, 0,0,60,102,96,102,60,0,
100, 14,6,54,110,102,102,59,0,
101, 0,0,60,102,126,96,60,0,
102, 28,54,48,120,48,48,120,0,
103, 0,0,59,102,102,60,198,124,
104, 224,96,108,118,102,102,230,0,
105, 24,0,56,24,24,24,60,0,
106, 6,0,6,6,6,6,102,60,
107, 224,96,102,108,120,108,230,0,
108, 56,24,24,24,24,24,60,0,
109, 0,0,102,119,107,99,99,0,
110, 0,0,124,102,102,102,102,0,
111, 0,0,60,102,102,102,60,0,
112, 0,0,220,102,102,124,96,240,
113, 0,0,61,102,102,62,6,7,
114, 0,0,236,118,102,96,240,0,
115, 0,0,62,96,60,6,124,0,
116, 16,48,124,48,48,52,24,0,
117, 0,0,204,204,204,204,118,0,
118, 0,0,204,204,204,120,48,0,
119, 0,0,198,214,214,108,108,0,
120, 0,0,99,54,28,54,99,0,
121, 0,0,102,102,102,60,24,112,
122, 0,0,126,76,24,50,126,0,
123, 14,24,24,112,24,24,14,0,
124, 24,24,24,24,24,24,24,0,
125, 112,24,24,14,24,24,112,0,
126, 114,156,0,0,0,0,0,0,
127, 0,0,0,0,0,0,0,0
}

cpu = manager:machine().devices[":maincpu"];apmem = cpu.spaces["program"]


reginitarray = {2,197,14,255,3,118,3,15}

for i=1,table.maxn(reginitarray) do 
dummy=apmem:read_i8(0xc0c1);
apmem:write_i8(0xc0c1,reginitarray[i]); apmem:write_i8(0xc0c1,128+(i-1)); end

-- pattern table at 0x0000

i=1
bytepos=0x0000+32*8
while(true) do
 if i>table.maxn(fontarray) then break; end;
  charnum = fontarray[i];
  i = i + 1;
  for j=1,8 do  mem:write_i8(bytepos,fontarray[i]); i = i + 1; bytepos = bytepos+1; end
end



-- name table at 0x3800

bytepos = 0x3800

for j=0,2 do
for i=0,255 do mem:write_i8(bytepos,i); bytepos = bytepos+1; end
end


-- color table at 0x2000

bytepos = 0x2000

for i=0,6143 do mem:write_i8(bytepos,15*16+4); bytepos = bytepos+1; end


-- use our font array for a sprite pattern table also

i=1
bytepos=0x1800+32*8
while(true) do
 if i>table.maxn(fontarray) then break; end;
  charnum = fontarray[i];
  i = i + 1;
  for j=1,8 do  mem:write_i8(bytepos,fontarray[i]); i = i + 1; bytepos = bytepos+1; end
end




function setsprite(sprite,x,y,pattern,color)

--print ("sprite: " .. sprite .. " x: " .. x)
bytepos=0x3b00+sprite*4
if y>=0 then mem:write_i8(bytepos,y) end -- vertical first
if x>=0 then mem:write_i8(bytepos+1,x)  end
if pattern>=0 then mem:write_i8(bytepos+2,pattern) end
if color >=0 then mem:write_i8(bytepos+3,color) end
end


a = "MameTMS 99184 spriteper line max"

for i=0,string.len(a)-1 do
 setsprite(i,50+(i%4)*20,30+math.floor(i/4)*20,string.byte(a,i+1),(i*2+1)%16);
end


#110882 - 09/27/17 07:47 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
A couple of modifications to my little routine so you can control it from the console:

deactivate = true to stop it
speed = 8 to change the speed
speed = 184 looks kind of ghostly with each frame alternating out of phase


Code
deactivate = false
speed = 4
framecount = 0

function tms_frame_call()

if not deactivate then
framecount = framecount + speed
sinoffset = math.floor(math.sin((framecount % 360)/360*(2*math.pi))*20);
for i=0,string.len(a)-1 do
 setsprite(i,math.floor(50+(i%4)*20+sinoffset),30+math.floor(i/4)*20,string.byte(a,i+1),(i*2+1)%16);
end
end
end

emu.register_frame(tms_frame_call)

#110893 - 09/28/17 05:19 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I saw the Coleco Adam SmartLogo demo where it shows all 32 sprites flying around the screen and wanted to see if I could reproduce it.

I run the adam driver and wrote a little lua script to save out the vram to a file.


[Linked Image]


So we launch the adam driver with "./mame64 adam smartlog -plugin console" and get to the examples screen so we can dump the vram. We run the following script with dofile("adam_dump_vram.lua")

Code
-- Coleco Adam calls its tms device ":tms9928a"

tms= manager:machine().devices[":tms9928a"]

mem = tms.spaces["vram"]

-- read vram and save to a file

outfile = assert(io.open("vram_dump_file", "wb"))

for i=0,16384-1 do
  outfile:write(string.char(mem:read_u8(i)))
end

assert(outfile:close())



I take the vram dump and load it into the apple2 arcade board's memory.

"./mame64 apple2e -sl4 arcbd -plugin console" and run this script to load the vram dump: dofile("arcbd_load_vram.lua")

Code
tms= manager:machine().devices[":sl4:arcbd:arcbd_tms"]

mem = tms.spaces["vram"]

-- read vram from a file and close it

infile = assert(io.open("vram_dump_file", "rb"))

datablock = infile:read("*all")    

assert(infile:close())

for i=0,16384-1 do
  mem:write_i8(i,string.byte(datablock,(i+1)))  -- datablock index starts at 1
end



and init the TMS9918 registers to match (since it puts its sprite attribute tables in a different spot than I was using at 1F80).


dofile("smartlogo_demo.lua")

Code
cpu = manager:machine().devices[":maincpu"];apmem = cpu.spaces["program"]

reginitarray = {2,194,14,255,3,63,3,1}

for i=1,table.maxn(reginitarray) do 
dummy=apmem:read_i8(0xc0c1);
apmem:write_i8(0xc0c1,reginitarray[i]); apmem:write_i8(0xc0c1,128+(i-1)); end


myspriteattributes = {}

for i=0,31 do
  myspriteattributes[i]={ }
end

for i = 0,31 do
  myspriteattributes[i][0] = 128
  myspriteattributes[i][1] = 96
  myspriteattributes[i][2] = (i+1)*4  -- pattern  (since we are doing 16x16 sprites must be multiples of 4
  myspriteattributes[i][3] = (i % 14) + 2   --color
  myspriteattributes[i][4] = .5   --speed
  myspriteattributes[i][5] = i * (360/32) -- heading
end


function setspritetable(tablepos,sprite,x,y,pattern,color)
  bytepos=tablepos+sprite*4
  if y>=0 then mem:write_i8(bytepos,y) end
  if x>=0 then mem:write_i8(bytepos+1,x)  end
  if pattern>=0 then mem:write_i8(bytepos+2,pattern) end
  if color >=0 then mem:write_i8(bytepos+3,color) end
end


deactivate = false


function do_each_frame()

  if not deactivate then 
  for i=0,31 do
    xoffset = spritespeed*math.cos(myspriteattributes[i][5]/360*2*math.pi)
    yoffset = spritespeed*math.sin(myspriteattributes[i][5]/360*2*math.pi) 

    myspriteattributes[i][0] =   myspriteattributes[i][0] + xoffset
    myspriteattributes[i][1] =   myspriteattributes[i][1] - yoffset 

    if myspriteattributes[i][0] < 0 then  myspriteattributes[i][0] = 256  end
    if myspriteattributes[i][0] > 256 then myspriteattributes[i][0] = 0 end

    if myspriteattributes[i][1] < 0 then myspriteattributes[i][1] = 192 end
    if myspriteattributes[i][1] > 192 then myspriteattributes[i][1] = 0 end

    setspritetable(0x1f80,i,math.floor(myspriteattributes[i][0]),
                            math.floor(myspriteattributes[i][1]),
                            myspriteattributes[i][2],
                            myspriteattributes[i][3])
  end -- for
  end -- if
end -- function

print("do you want to add the function do each frame to emu.register_frame?")
if io.read() == "y" then emu.register_frame(do_each_frame) end

spritespeed = 4



What's cool is to modify the myspriteattributes array in real time from the console and see the result.

For example:
for i = 0,31 do myspriteattributes[i][2]=36*4 end
spritespeed = 0.5

#110894 - 09/28/17 06:21 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
That's really awesome. I'm glad to see someone combining MAME capabilities in unexpected-to-us ways smile

#110910 - 09/29/17 09:59 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: R. Belmont]  
Joined: Feb 2004
Posts: 1,939
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member

Joined: Feb 2004
Posts: 1,939
Sydney, Australia
Originally Posted by Golden Child
trying to do more gets me a segfault:

./mame64 apple2e -sl7 ssprite -sl4 arcbd -sl5 arcbd -sl2 arcbd
Segmentation fault (core dumped)


Originally Posted by R. Belmont
MAME has a hardcoded max of 4 screens. I'm not sure where it comes from, it limits my ability to put 6 NuBus video cards in a Mac II and have real fun frown


Happy new year

#110913 - 09/29/17 04:03 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: R. Belmont]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Thanks RB,

Mame is super addictive and fun. I figure something new out every day. It's like a learning lab for old systems. I was struggling so hard trying to get the tms9918 to do something interesting with applesoft and now I've discovered lua is 300x faster and easier. I wish I'd had this back in the days of the apple 2.

I remember reading about the SuperSprite / Arcade Board in Creative Computing back in 1984 and being fascinated with the concept. Now I finally get a chance to actually give it a try.

BTW, thanks for putting in the ssprite stuff in for 0.190.


My discovery for today: how to roll your own dispatch function in lua. I'd make a mistake in a lua function that I called emu.register_frame() on and it would run away happily typing garbage in the console forever until you killed it (and your whole mame session) with CTRL+C.


Once you get a runaway, you can't see what you're typing at all with all of the output clogging the terminal.
So if you get in trouble, just type "cld()" and hit enter and that clears the dispatch_list.
Or if you like to type, type "dispatch_list = {}"



Code

dispatch_list = { }


function frame_dispatcher()
for index,my_func in pairs(dispatch_list) do  my_func() end
end


function print_hello() print("hello") end
function print_there() print("there") end
function print_howareyou() print("how are you") end

function dispatch_list_remove(a_func)
for my_index,my_func in pairs(dispatch_list) do if my_func == a_func then table.remove(dispatch_list,my_index) end end
end

function print_dispatch_list() for my_index,my_func in pairs(dispatch_list) do print(my_func) end end


table.insert(dispatch_list,print_hello) 
table.insert(dispatch_list,print_there) 
table.insert(dispatch_list,print_howareyou)


frame_dispatcher()
print_dispatch_list()

dispatch_list_remove(print_there)

frame_dispatcher()

print_dispatch_list()


function cld()
dispatch_list = {}
end


-- emu.register_frame(frame_dispatcher);
print("type cld(); to stop a runaway dispatch");
print("copy the next line and paste to execute to add our frame dispatcher:");
print("emu.register_frame(frame_dispatcher);");


#110917 - 09/29/17 07:13 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
So why not make it so you can control the little turtle guy with the keyboard?

The ultimate goal would be to program a game in mame with lua.

[Linked Image]

This lua script assumes that you've already got the vram loaded with the dump from the smartlogo program, and you've initialized the TMS9918 registers:

Code
function heading_to_spritenumber(heading)
  local heading24
  -- reverse the heading direction and rotate by 90 degrees and scale to 0..23
  heading24 = ((-1*(heading - 90)) % 360) *(24/360)
  return  math.floor(36+heading24)*4  -- turtles run from 36 to 59 (24 different sprites patterns)
end

myspriteattributes = {}

for i=0,31 do
  myspriteattributes[i]={ }
end

for i = 0,31 do
  myspriteattributes[i][0] = 128
  myspriteattributes[i][1] = 96
  myspriteattributes[i][2] = (i+1)*4  -- pattern  (since we are doing 16x16 sprites must be multiples of 4
  myspriteattributes[i][3] = (i % 14) + 2   --color
  myspriteattributes[i][4] = .5   --speed
  myspriteattributes[i][5] = i * (360/32) -- heading
  spritespeed = 1
  myspriteattributes[i]["xvel"] = math.cos(myspriteattributes[i][5]*(2*math.pi/360))
  myspriteattributes[i]["yvel"] = math.sin(myspriteattributes[i][5]*(2*math.pi/360))
end


function setspritetable(tablepos,sprite,x,y,pattern,color)
bytepos=tablepos+sprite*4
if y>=0 then mem:write_i8(bytepos,y) end -- vertical first
if x>=0 then mem:write_i8(bytepos+1,x)  end
if pattern>=0 then mem:write_i8(bytepos+2,pattern) end
if color >=0 then mem:write_i8(bytepos+3,color) end
end


function read_keys()
inp = manager:machine():input()
thrust_value = 0.05

if inp:code_pressed(inp:code_from_token("KEYCODE_UP")) then 
myspriteattributes[0]["xvel"] = myspriteattributes[0]["xvel"] + math.cos(myspriteattributes[0][5]*(2*math.pi/360)) * thrust_value
myspriteattributes[0]["yvel"] = myspriteattributes[0]["yvel"] - math.sin(myspriteattributes[0][5]*(2*math.pi/360)) * thrust_value
end

if inp:code_pressed(inp:code_from_token("KEYCODE_DOWN")) then 
myspriteattributes[0]["xvel"] = myspriteattributes[0]["xvel"] * 0.9
myspriteattributes[0]["yvel"] = myspriteattributes[0]["yvel"] * 0.9
end


if inp:code_pressed(inp:code_from_token("KEYCODE_LEFT")) then myspriteattributes[0][5] = myspriteattributes[0][5] + 2 end
if inp:code_pressed(inp:code_from_token("KEYCODE_RIGHT")) then myspriteattributes[0][5] = myspriteattributes[0][5] - 2 end

myspriteattributes[0][2] = heading_to_spritenumber(myspriteattributes[0][5])

if inp:code_pressed(inp:code_from_token("KEYCODE_C")) then setotherspritepattern(128) end
if inp:code_pressed(inp:code_from_token("KEYCODE_D")) then setotherspritepattern(0) end

end




function update_sprites()

for i=0,31 do
  myspriteattributes[i][0] =   myspriteattributes[i][0] + myspriteattributes[i]["xvel"]
  myspriteattributes[i][1] =   myspriteattributes[i][1] + myspriteattributes[i]["yvel"]

if myspriteattributes[i][0] < 0 then  myspriteattributes[i][0] = 256  end
 if myspriteattributes[i][0] > 256 then myspriteattributes[i][0] = 0 end

if myspriteattributes[i][1] < 0 then myspriteattributes[i][1] = 192 end
 if myspriteattributes[i][1] > 192 then myspriteattributes[i][1] = 0 end

  setspritetable(0x1f80,i,math.floor(myspriteattributes[i][0]),
              math.floor(myspriteattributes[i][1]),myspriteattributes[i][2],myspriteattributes[i][3])
end

end




dispatch_list = { }

function frame_dispatcher()
for index,my_func in pairs(dispatch_list) do  my_func() end
end

function dispatch_list_remove(a_func)
for my_index,my_func in pairs(dispatch_list) do if my_func == a_func then table.remove(dispatch_list,my_index) end end
end

function print_dispatch_list() for my_index,my_func in pairs(dispatch_list) do print(my_func) end end

function cld()
dispatch_list = {}
end

print ("cld() installed type cld() and hit enter to stop dispatch")
print()

table.insert(dispatch_list,update_sprites)
table.insert(dispatch_list,read_keys)

print("table.insert(dispatch_list,update_sprites)")
print("table.insert(dispatch_list,read_keys)")
print()
print(" you will need to manually register frame since I don't want to have it done every time I run the lua file")
print()
print(" so copy and paste the following line on the console")
print()
print("emu.register_frame(frame_dispatcher)")
--print("   equivalent to: emu.register_frame(read_keys)")
print()
print("C key to clear the other sprites")
print("D key to bring the other sprites back")
print("UP key for thrust   DOWN key to slow down")
print("LEFT RIGHT to turn")

function setotherspritepattern(spritepattern)
  for i=1,31 do myspriteattributes[i][2]=spritepattern end
end



#110932 - 09/30/17 10:13 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Vas Crabb]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Thanks Vas,

I had to try the new screens capability with the apple 2.

Here's a 6 TMS9918 board demo in addition to the apple screen to make 7 total:

./mame64 apple2e -sl1 ezcgi -sl2 arcbd -sl3 arcbd -sl4 arcbd -sl5 arcbd -sl7 ssprite

I can choose a 4x2 layout that looks good:

[Linked Image]

mame's screen shot still gives me 7 across:

[Linked Image]

Very cool!

Code
-- dofile("apple_6_board_demo.lua")
-- uses the vram_dump_file from coleco adam smartlog

function read_tms_vram_from_file(tms,filename)
mem = tms.spaces["vram"]
infile = assert(io.open("vram_dump_file", "rb"))
datablock = infile:read("*all")    
assert(infile:close())
for i=0,16384-1 do
  mem:write_u8(i,string.byte(datablock,(i+1)))
end
end

function init_tms_registers(slotnum)
cpu = manager:machine().devices[":maincpu"];apmem = cpu.spaces["program"]
reginitarray = {2,194,14,255,3,63,3,1}
regaddress = 0xc080+slotnum*16+1
for i=1,table.maxn(reginitarray) do 
dummy=apmem:read_u8(regaddress);
apmem:write_u8(regaddress,reginitarray[i]); 
apmem:write_u8(regaddress,128+(i-1)); 
end
end

-- ./mame64 apple2e -sl1 ezcgi -sl2 arcbd -sl3 arcbd -sl4 arcbd -sl5 arcbd -sl7 ssprite 

tms=manager:machine().devices[":sl1:ezcgi:ezcgi_tms"]
read_tms_vram_from_file(tms,"vram_dump_file")
init_tms_registers(1)

tms=manager:machine().devices[":sl2:arcbd:arcbd_tms"]
read_tms_vram_from_file(tms,"vram_dump_file")
init_tms_registers(2)

tms=manager:machine().devices[":sl3:arcbd:arcbd_tms"]
read_tms_vram_from_file(tms,"vram_dump_file")
init_tms_registers(3)

tms=manager:machine().devices[":sl4:arcbd:arcbd_tms"]
read_tms_vram_from_file(tms,"vram_dump_file")
init_tms_registers(4)

tms=manager:machine().devices[":sl5:arcbd:arcbd_tms"]
read_tms_vram_from_file(tms,"vram_dump_file")
init_tms_registers(5)

tms=manager:machine().devices[":sl7:ssprite:ssprite_tms"]
read_tms_vram_from_file(tms,"vram_dump_file")
init_tms_registers(7)

#110945 - 10/02/17 07:51 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Just came across this while searching around on the internet and thought it was cool: A demo of Captain Pixel which ran on a "flippy card" that had a TMS 34010 and had interfaces to the Apple II and IBM PC.


According to the description:

Quote
arhenderson2006
Published on Jul 17, 2007
This was an interactive graphics demonstration that ran on the 34010 S.D.B. (software development board) and the TMS34010 "Flippy".

The "Flippy" was a 34010 graphics card with an Apple // compatible edge connector on one side and a PC compat. connector on the other. There was a machine specific "loader" module for each platform but a single executable. "Flippy" code was cross platform compatible because the actual application executed on the 34010.

Captain Pixel went on to have two offspring: Captain Comic for the PC by Michael Denio and a version of Captain Comic for the NES that Mike and I collaborated on.

This video does not have audio...


https://www.youtube.com/watch?v=Rn9KTTqN0pw


#110947 - 10/02/17 12:34 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Wow, that would've been a very powerful card. Games like the arcade versions of Smash TV and Mortal Kombat ran entirely on a 34010. If the Apple II software exists (or the PC software, but A2 would be more fun) we could definitely emulate it.

TI tried to push 34010 ISA cards on the PC as a "TIGA" standard but they were too pricey to catch on.

#110948 - 10/02/17 12:59 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: R. Belmont]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I came across this page that was interesting regarding some tms 34010 development:

http://about.endlessskye.com/

Quote
The TMS34010

Texas Instruments came to Media Cybernetics as a then market leader with their latest bleeding edge graphics chip, the TMS34010. The 34010 was a true 32-bit processor with thirty-two 32-bit registers, bit addressability (and variable field width!), and a few graphics instructions. It sat in its own address space on an ISA card, where it communicated with the outside world through memory mapped registers. It was basically an embedded device that ran in true parallel with the host processor. Our development board had no BIOS, no OS, only the 34010 and its own address space. Only the open steppe. So management in its infinite wisdom agreed to port the HALO 2D graphics library in time for the upcoming trade show in San Jose, a ridiculously short 6 weeks away. I didn't step back fast enough when they asked for volunteers, so I "volunteered" for the work. Between myself and another guy on my HALO team we managed to port the entire HALO graphics kernel from 8086 assembler to 34010 assembler.(As a principal engineer and manager I rated a screaming 10 Mhz 286 with a full 640 KB, he had only a 6 Mhz 286 with 512 KB of memory.) I designed a way to download and bootstrap the HALO 34010 kernel onto the 34010 device, using only a simulator and a serial port built into the 34010 device. We had no hardware assistance for debugging. A truly Herculean achievement. You could do a warm reboot and the 34010 device would still be running, merrily drawing graphics from a vector list on its own display. Way cool. And this was way back in prehistory, in 1988. Truly revolutionary. Try doing that with a dual-core x64, dual-graphics card computer.


http://34010.endlessskye.com/

Quote
The TMS34010:Two Generations Too Soon?

Recently I received an out of the blue inquiry from a hobbyist requesting some information on the TMS34010. Interestingly a few days prior I had run across my design notes for the TMS34010 where I had detailed the port of the Media Cybernetics Halo graphics kernel onto the 34010 for an upcoming trade show. Talk about deja vu all over again.

The TMS34010 was a fully independent processor that ran in it's own address space, a relatively small memory window being mapped into the host adress space for data transfer and control. You could program the word size from 1 to 32 bits. You could also read or write the arbitrary word size from or to an arbitrary bit address. Totally awesome! Quite an advantage in the mid-80s when pixels were smaller than bytes, and had to be read and written using shifts and bitwise logical operations. Processor speed on a high end PC AT was 10 mHz, so this provided a significant speed advantage.

Even though the herculean effort to design and port the Halo graphics kernel was a success, the TMS34010 never seemed to find widespread success in the graphics card market. I heard rumors of it being used in the unglamorous niche markets of fax machines and printers, where it's bit twiddling prowess would have provided a significant benefit. So to me the TMS34010 drifted out of thought, to be relegated to that twilight of yet another technology that was just too far ahead of its time.

So imagine my surprise when I heard the hobbyist was tinkering with an arcade game complete with 34010 processor on board. (Below are a closeup of the 34010 on the board and the entire arcade game board.) I've been meaning for years to transfer the 34010 compiler and other tools from the aging 5-1/4" floppies (with the gargantuan capacity of 360 KB!) Hopefully they still are readable. (I was told that VHS tapes would lose the image in a few years but I still have movies taped from HBO in 1984 that are still alive and well, so I'm optimistic.) I hope to make this page a resource for others trying to breathe life into an old 34010 system or trying to port 34010 code onto a more modern platform. I still have the 34010 programmer's manual (a fascinating architecture, a 32-bit word with Motorola like instructions and a scan line by scan line programmable palette) but whereas I may try to set up an old machine to read the floppies I can't see myself scanning the manual. Any links to a digital version of the programmer's manual would be awesome.

#110949 - 10/02/17 02:55 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Same guy posted this video: https://www.youtube.com/watch?v=730tmDmzeDE

There's a shadebobs-like effect in the video that well predates any demoscene version AFAIK, so that's interesting.

#110960 - 10/03/17 02:02 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: R. Belmont]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Here's a rare unicorn that would be awesome to see in mame one day.



This was the Apple2 DTV before there was even a C64 DTV or a C64 mini.

#110961 - 10/03/17 02:35 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Oh, I'd *love* to see a dump of that thing.

#110962 - 10/03/17 03:21 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Jan 2011
Posts: 167
Al Kossow Offline
Senior Member
Al Kossow  Offline
Senior Member

Joined: Jan 2011
Posts: 167
"I can't see myself scanning the manual."

wtf is the point, I did that 10+ years ago
he apparently has never heard of the 34020 either.

#110963 - 10/03/17 04:38 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
There's a cool gallery of the Tiger Learning computer and carts at:

https://juiced.gs/2012/01/tiger-learning-computer-gallery/

along with a shot of the motherboard.

#110971 - 10/04/17 11:56 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I was trying to wrap my head around the code of how mame does its UI Paste function (and also the lua does its emu.keypost()) because the text pasting in the apple2e driver seems to scramble the input.

Grep is pretty useful to scan the whole source tree because I couldn't figure out where things are:

-r is recursive
-i is ignore case

Code
grep -r -i "keypost" src/
src/frontend/mame/luaengine.cpp: * emu.keypost(keys) - post keys to natural keyboard
src/frontend/mame/luaengine.cpp:	emu["keypost"] = [this](const char *keys){ machine().ioport().natkeyboard().post_utf8(keys); };
src/frontend/mame/mame.cpp:		std::string val = std::string("emu.keypost('").append(cmd).append("')");


grep -r -i "post_utf8" src/
src/emu/natkeyboard.cpp://  post_utf8 - post a UTF-8 encoded string
src/emu/natkeyboard.cpp:void natural_keyboard::post_utf8(const char *text, size_t length, const attotime &rate)
src/emu/natkeyboard.h:	void post_utf8(const char *text, size_t length = 0, const attotime &rate = attotime::zero);
src/frontend/mame/ui/ui.cpp:		machine().ioport().natkeyboard().post_utf8(text);
src/frontend/mame/luaengine.cpp:	emu["keypost"] = [this](const char *keys){ machine().ioport().natkeyboard().post_utf8(keys); };


grep -r -i "paste" src/
...
src/frontend/mame/ui/ui.h:	bool can_paste();
src/frontend/mame/ui/ui.h:	void paste();
src/frontend/mame/ui/ui.cpp://  can_paste
src/frontend/mame/ui/ui.cpp:bool mame_ui_manager::can_paste()
src/frontend/mame/ui/ui.cpp://  paste - does a paste from the keyboard
src/frontend/mame/ui/ui.cpp:void mame_ui_manager::paste()
src/frontend/mame/ui/ui.cpp:		// paste command
src/frontend/mame/ui/ui.cpp:		if (machine().ui_input().pressed(IPT_UI_PASTE))
src/frontend/mame/ui/ui.cpp:			paste();


and the actual paste code in ui.cpp:

//-------------------------------------------------
//  paste - does a paste from the keyboard
//-------------------------------------------------

void mame_ui_manager::paste()
{
	// retrieve the clipboard text
	char *text = osd_get_clipboard_text();

	// was a result returned?
	if (text != nullptr)
	{
		// post the text
		machine().ioport().natkeyboard().post_utf8(text);

		// free the string
		free(text);
	}
}





So it uses the natural keyboard mapping, and what's interesting is if I launch mame with the -natural option, I lose a lot of keyboard functionality.

./mame64 apple2e -natural

Ctrl+C, Ctrl+F doesn't work, left and right arrow don't work, ESC key doesn't work, and the @ disappear and various symbols are shifted.

Also it seems that the keyboard has gotten a lot slower in the "natural mode", there's a bunch of latency and it can't keep up with fast typing.

#110974 - 10/04/17 01:38 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2004
Posts: 1,939
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member

Joined: Feb 2004
Posts: 1,939
Sydney, Australia
Natural keyboard mode will never work particularly well, since it's a pretty much impossible set of requirements. It's supposed to translate host character input to emulated keystrokes. Not all keystrokes produce characters, some characters require multiple keystrokes to produce, and IME edit opens another whole can of worms. It kinda works for simple cases, but it's always going to be something that's nice if it works at best.

#110976 - 10/04/17 01:42 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Vas Crabb]  
Joined: May 2009
Posts: 1,669
Just Desserts Offline
Very Senior Member
Just Desserts  Offline
Very Senior Member

Joined: May 2009
Posts: 1,669
Sounds like something that should be implemented or enabled on a per-driver basis, then. Otherwise it seems like exactly the sort of half-baked, user-hostile, anti-feature that MAME is infamous for. It violates the hell out of the rule of least surprise.

#110978 - 10/04/17 02:11 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2004
Posts: 1,939
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member

Joined: Feb 2004
Posts: 1,939
Sydney, Australia
Natural keyboard mode isn't enabled by default, you have to use -natural on command line or go into the menu and switch it on. It works a lot better than it used to provided the PORT_CHAR declarations for the driver are done properly. It also performs a bit better in 0.190 than it did before, as I eliminated an O(n) lookup, but the speed at which it generates keystrokes is still pretty conservative, as it has to work with some slow systems.

I had a quick look at the apple2e driver and it seems to have the wrong PORT_CHAR for a few keys, as though it was quickly copy/pasted from the Apple II+ and not fully updated (Apple II+ uses a "bitshift" style layout, while Apple IIe uses a "typewriter shift" style layout). I'm not going to mess with trying to make control keys work in natural mode, as that's problematic, but I've tried to at least fix the shifted digits and arrow keys in natural keyboard mode with 64ac8e4. I've only tried fixing the US Apple IIe and variants, not the UK, French and Spanish versions.

Note that the Apple II drivers are set up to translate uppercase letters to unshifted letter keys for natural keyboard/UI paste/keypost. If you type/paste/post lowercase letters, it will press the emulated shift key when typing each one.

#110983 - 10/04/17 05:31 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Vas Crabb]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Thanks Vas,

I just gave it a try and the missing characters type properly now in a paste. Yay!

#111004 - 10/09/17 11:58 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Vas Crabb]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I really wanted to have a proper "delay after a CR" during a paste so that after a CR, you'd have a delay while the computer would process the line of input.

If you have a key pressed too long on the Apple2e, it starts to auto repeat. So you want your delay AFTER the CR has been pressed and released.

Calling m_timer->adjust(choose_delay(m_buffer[m_bufbegin])); doesn't really give you a proper delay amount, especially since this function gets executed at least twice for each keypress/release.

I wrestled mightily with the function natural_keyboard::timer to get a delay that was "long" without triggering the autorepeat.

This function actually first "presses" all of the fields for a given keycode, then it releases them one by one each time it gets called after that. It seems really counter-intuitive. One of the things that really threw me for a loop is that it does things "reversed" like field->set_value(!m_status_keydown). m_status_keydown comes in as false, it sets all the fields, then it flips the m_status_keydown.

I haven't tested this very much, but it seems to work for the couple of pastes I've thrown at it.


Code
void natural_keyboard::timer(void *ptr, int param)
{

attotime next_delay = attotime::from_msec(20);  
	if (!m_queue_chars.isnull())
	{
		// the driver has a queue_chars handler
		while (!empty() && m_queue_chars(&m_buffer[m_bufbegin], 1))
		{
			m_bufbegin = (m_bufbegin + 1) % m_buffer.size();
			if (m_current_rate != attotime::zero)
				break;
		}
	}
	else
	{
		// the driver does not have a queue_chars handler

		// loop through this character's component codes
		const keycode_map_entry *const code = find_code(m_buffer[m_bufbegin]);
		bool advance;
		if (code)
		{
			do
			{
				assert(m_fieldnum < ARRAY_LENGTH(code->field));
				ioport_field *const field = code->field[m_fieldnum];
				if (field)
				{
					// special handling for toggle fields
					if (!field->live().toggle)
						field->set_value(!m_status_keydown);
					else if (!m_status_keydown)
						field->set_value(!field->digital_value());
				}
			}
			while (code->field[m_fieldnum] && (++m_fieldnum < ARRAY_LENGTH(code->field)) && m_status_keydown);
			advance = (m_fieldnum >= ARRAY_LENGTH(code->field)) || !code->field[m_fieldnum];

// if we're at a CR then let's set the next delay for 5 seconds
 if (m_status_keydown && (m_buffer[m_bufbegin] == '\r') && (advance)) next_delay = attotime::from_msec(5000);
		}
		else
		{
			advance = true;
		}

		if (advance)
		{
			m_fieldnum = 0;
			m_status_keydown = !m_status_keydown;

			// proceed to next character when keydown expires
			if (!m_status_keydown)
				m_bufbegin = (m_bufbegin + 1) % m_buffer.size();

		}
	}

       // m_status_keydown has already been flipped for the next invocation
	// need to make sure timerproc is called again if buffer not empty
	if (!empty())
m_timer->adjust(next_delay);

}


#111005 - 10/09/17 01:16 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Just Desserts]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Originally Posted by Just Desserts
Sounds like something that should be implemented or enabled on a per-driver basis, then. Otherwise it seems like exactly the sort of half-baked, user-hostile, anti-feature that MAME is infamous for. It violates the hell out of the rule of least surprise.


On the contrary, it's exactly the sort of user-friendliness you advocate: it changes the keyboard emulation from matching the layout of the original at the expense of what's actually marked on your PC keyboard to (attempting to) make it so e.g. shift-2 on a US keyboard is always @, even on machines where shift-2 is " or a UK pound sign or whatever. I would argue that having keys on your PC keyboard *not* generate the same thing on the emulated system is actually the major violation of least-surprise here. In particular, pretty much all other computer emulators *only* have an equivalent of natural keyboard mode.

#111006 - 10/09/17 01:31 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: May 2004
Posts: 1,494
Haze Offline
Very Senior Member
Haze  Offline
Very Senior Member

Joined: May 2004
Posts: 1,494
it's user unfriendly when it doesn't work for games etc. because it never really seems to register keys as held down, only 'pressed once' especially if they're shifted keys or whatever else..

while the idea is good in concept, the implementation of it is definitely horrible and acts in completely unexpected ways and how you toggle it on / off at runtime doesn't seem to be common knowledge either.



Last edited by Haze; 10/09/17 01:32 PM.
#111007 - 10/09/17 01:43 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Yes, we all agree the implementation sucks; it should hold down the keys on the emulated keyboard for the same amount of time that the user holds down the original key(s) etc. But the concept is pretty much industry-standard.

#111013 - 10/10/17 02:09 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2004
Posts: 1,939
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member

Joined: Feb 2004
Posts: 1,939
Sydney, Australia
What are all the PC emulators doing "natural keyboard' translation? It definitely isn't VirtualBox or VMware - both of those map keys directly. DOSbox kind of does for DOS itself by virtue of the fact that it's HLE'ing the character input function, but when a program accesses the keyboard directly it reads the keys that are down directly.

It's impossible to hold the same amount of time, because there isn't a 1:1 correspondence between keys and characters. It's also impossible to "translate" modifiers since it's all over the shop with whether something uses a modifier or not. Let's use some real-world examples of why you can't do perfect translation.

Emulated system has a JIS "bitshift" keyboard, host system has a US "typewriter" layout keyboard:
  • User presses Right Shift
  • User presses 2 (on host this types an '@' character)
  • User releases 2
  • User releases RIght Shift


On the emulated system, typing '@' does not involve the shift key at all - it's the key to the right of P unshifted (this key has '[' on the host keyboard). So if you're trying to translate modifiers, what do you do? Press the emulated shift key, then release it for some amount of time before pressing the @ key, then press it again after releasing the emulated @ key?

Same emulated and host configurations:
  • User presses ' (on host this types a "single straight quote")
  • User releases '


The emulated system requires you to type Shift-7 to type a ' character. You're going to need to press the emulated shift key, wait long enough to ensure matrix scanning can detect it, press the emulated 7 key, and then release both keys.

It gets even messier with dead keys. Emulated system had a German DIN keyboard, host has Windows US International layout:
  • User presses Left Shift
  • User presses ' (on host system this initiates a dead key sequence)
  • User releases '
  • User releases Left Shift
  • User presses U (on host system this types ü because of the current dead key state)
  • User releases U


On the emulated system, this is a single keystroke - the key to the right of P, with no modifiers at all. You can't translate all the keystrokes leading up to the character being typed, because they don't actually produce characters.

What about a failed dead key sequence? Same emulated and host configurations:
  • User presses Left Shift
  • User presses ' (on host system this initiates a dead key sequence)
  • User releases '
  • User releases Left Shift
  • User presses X (on host system this types "x because there's no mapping for X in the current dead key state)
  • User releases X


You can't press the emulated keys for the " (shift-2) when the user starts the dead key sequence, because you can't anticipate the next character they'll type. You need to do the whole sequence when they press X.

You have no way of knowing whether the emulated system is running a game or other program that processes raw keystrokes and works best with everything passed through based on position, or it's running something accepting character input and you should translate characters to keystrokes. And what if it's both? You could be typing into a text editor while some other program is snooping the keyboard directly.

Also, if you want to be able to hold the key for a corresponding amount of time, you need to be doing key translation yourself. You don't get information on when a key is pressed/released from character input events. To be able to pass that through to the emulated system (assuming you had correspondence between keystrokes on both sides to begin with), you'd need to load the host system's keyboard layout, do translation from keystrokes to characters yourself, including dead key mapping, etc. and then pass it through. This would be a big mess of OS-dependent code, and it would have no chance of working at all for languages with IME edit.

If I'm completely missing something that makes this simple, please point it out to me. But I'm really sick of people saying natural keyboard is best and should work properly, when decades of dealing with multiple language support across operating systems tells me it's impossible to do in a satisfactory way, and what we've got now is about the best compromise we're going to get.

#111014 - 10/10/17 02:20 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2004
Posts: 1,939
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member

Joined: Feb 2004
Posts: 1,939
Sydney, Australia
Originally Posted by Golden Child
This function actually first "presses" all of the fields for a given keycode, then it releases them one by one each time it gets called after that. It seems really counter-intuitive. One of the things that really threw me for a loop is that it does things "reversed" like field->set_value(!m_status_keydown). m_status_keydown comes in as false, it sets all the fields, then it flips the m_status_keydown.


You've missed some of the subtlety - it presses the keys one-at-a-time with a delay between each to ensure there's time for matrix scanning to detect the modifiers before the character key is pressed. Without this, uppercase letters, shifted numbers etc. don't work on Amiga, Sun, RM Nimbus, and a host of other systems (I implemented this myself after over a year of complaints about it not working but none of the natural keyboard advocates addressing it). However it releases all the emulated keys at the same time - it doesn't wait for the timer to fire between releasing keys.

Yes, it's "dumb" in cases where a sequence of shifted keys are typed in a row - it presses and releases shift for each one - but making it "smarter" about this would complicated the code quite a bit.

The trouble with adding a delay on CR is it's going to be a real pain for actually typing into a text editor, and even at a command prompt, different commands all take different amounts of time.

#111018 - 10/10/17 12:48 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Vas Crabb]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Hi Vas,

Yes I think I've missed a lot of the subtlety of how it works and how it needs to work across a spectrum of different machines.

Perhaps some of the problem is trying to get the natural keyboard to do a paste function with the same routine that handles normal user input.

A paste doesn't have to be fast, it could be on its own timer (and buffer) and just feed its keystrokes into the natural keyboard's posting systems on its own timetable. Then you could do it as slowly as you wish and not affect the normal typing.

#111022 - 10/10/17 04:24 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Dec 1999
Posts: 1,170
Justin Offline
Very Senior Member
Justin  Offline
Very Senior Member

Joined: Dec 1999
Posts: 1,170
Vancouver Island, BC, Canada
I could have sworn this was all working in the (distant) past with natural keyboard mappings for apple2 (which I set up iirc) and a coded delay after carriage returns when pasting, I guess various refactorings over the years KO'd it.

#111023 - 10/10/17 05:59 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
It can't work with a fixed delay, because Applesoft takes more or less an unbounded amount of time to process a line. (Up to the limits of what you can fit on one line, of course). You'd probably want to use something like CiderPress which can convert tokenized .BAS files to and from .TXT listing files.

#111040 - 10/12/17 12:25 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: R. Belmont]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I thought I'd see if I could do something with lua and coroutines to feed keystrokes with delays.

So I create a lua coroutine to pump keystrokes from a buffer. It's called every frame and calls coroutine.yield() when it's done.

After a normal keystroke, it delays 3 frames. After a cr, it will delay 5*60 frames.

What's kind of cool about lua coroutines is that you can call them with parameters if you like. So to add text I call the coroutine with a parameter.

Just an experiment...


Code

-- you must initialize these globals or the routine won't work, any error in the coroutine kills it so coroutine.status is dead

keyfeed_buffer = ""
keydelay = -1
keyfeed_buffer_pos = 1

normalkeydelay = 3
crkeydelay = 5 * 60

function keyboard_feeder()
 while 1 do
   --print("going to yield")
   newparam = coroutine.yield()
   --print ("keyboard_feeder_coroutine")
   if newparam == nil then

      --print("keydelay" .. keydelay)
      if keydelay < 0 then  -- get the next character

      nextkeytofeed = string.sub(keyfeed_buffer,keyfeed_buffer_pos,keyfeed_buffer_pos)
      keyfeed_buffer_pos = keyfeed_buffer_pos+1
      emu.keypost(nextkeytofeed)
      
      if nextkeytofeed == "" then keydelay = -1; keyfeed_buffer  = ""; keyfeed_buffer_pos = 1
      elseif nextkeytofeed == "\n" then keydelay = crkeydelay
      else keydelay = normalkeydelay
      end

      else
         keydelay = keydelay -1
      end
   else 
      -- print("adding " .. newparam .. " to buffer");
      keyfeed_buffer=keyfeed_buffer .. newparam; 
      -- print(keyfeed_buffer);
   end -- if
 end -- while
end -- function


function call_keyboard_feeder()
   --print ("call keyboard feeder")
   coroutine.resume(keyboard_feeder_coroutine)
   --print ("done call keyboard feeder")
end

function add_text(newtext)
   coroutine.resume(keyboard_feeder_coroutine,newtext)
end

function register_keyboard_feeder()
   keyboard_feeder_coroutine=coroutine.create(keyboard_feeder)
   table.insert(dispatch_list,call_keyboard_feeder)   
end


dispatch_list = { }

function frame_dispatcher()
for index,my_func in pairs(dispatch_list) do  my_func() end
end

if already_registered_frame_dispatcher == nil then
   emu.register_frame(frame_dispatcher);
   already_registered_frame_dispatcher = 1
end

function cld()
dispatch_list = {}
end

print("type cld(); to stop a runaway dispatch");

cld()
register_keyboard_feeder()

add_text("this is a test of the emergency broadcast system.\n")
add_text("this is only a test.\n")
add_text("FEEDING 255 CHARACTERS.\n")
for i=1,255 do add_text(string.char(string.byte("0")+i%10)) end
add_text("\n")
add_text("That's 255 characters\n")

#111042 - 10/12/17 02:28 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
If you're feeding from Lua, you should be able to check the Apple II zero page variables to determine when Applesoft is ready to accept input.

#111043 - 10/12/17 05:01 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: R. Belmont]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Perhaps I could watch the PC of the apple and see when it hits the loop to accept user input. I don't know where it actually stores the buffer position in the zero page. I was thinking that it just kept it in the X register as far as I could tell.

I could register a function that would watch the PC.


for key,value in pairs(manager:machine().devices[":maincpu"].state) do print(key,value) end
PC sol.device_state_entry*: 0x55a370aea448
CURFLAGS sol.device_state_entry*: 0x55a370aea598
IR sol.device_state_entry*: 0x55a370ae9848
CURSP sol.device_state_entry*: 0x55a370aea848
P sol.device_state_entry*: 0x55a370ae9c48
SP sol.device_state_entry*: 0x55a370ae9998
CURPC sol.device_state_entry*: 0x55a370aeac48
A sol.device_state_entry*: 0x55a370aea198
GENPC sol.device_state_entry*: 0x55a370aead98
Y sol.device_state_entry*: 0x55a370ae9d98
X sol.device_state_entry*: 0x55a370aea048


print(manager:machine().devices[":maincpu"].state["PC"].value)
64903


Maybe I could even stuff the keys into the $200-2FF input buffer rather than going through posting keystrokes.

#111044 - 10/12/17 06:12 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
That's an idea as well - put a whole line into the buffer, adjust the buffer position accordingly, and send an Enter keypress.

#111047 - 10/12/17 11:02 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jan 2012
Posts: 763
crazyc Offline
Senior Member
crazyc  Offline
Senior Member

Joined: Jan 2012
Posts: 763
It's an Applesoft TAS!

Last edited by crazyc; 10/12/17 11:02 PM.
#111060 - 10/15/17 08:12 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jan 2012
Posts: 878
rfka01 Offline
Senior Member
rfka01  Offline
Senior Member

Joined: Jan 2012
Posts: 878
Bavaria
Originally Posted by rfka01
Alive as ... a Do-Do

http://forum.classic-computing.de/index.php?page=Thread&threadID=11845

This thread contains the ROMs for an Apple II clone which has "Do-Do" as its signon message smile


Do-Do ROMs on the FTP and here ... now including the Chargen, thanks to Toshi on the German VzEkC forum

https://forum.classic-computing.org/index.php?page=Thread&postID=127185#post127185

GTAC/Do-Do ROMs

http://john.ccac.rwth-aachen.de:8000/patrick/MEWA48.htm

No pull request, as I couldn't get it beyond garbled text.

Last edited by rfka01; 10/15/17 08:12 PM.

NCR DMV- DEC Rainbow- Siemens PCD- ITT 3030-Oly People- Acorn A5000- Olivetti M20
#111101 - 10/17/17 06:06 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I figured out why using the debugger memory view to change the TMS9918 registers doesn't work.

so I try to set the TMS registers by hand with the debugger memory view, but it doesn't have any effect.

Because when you do it with the debugger memory view, it doesn't update the corresponding member variables. So not only do you have to set the m_Regs[x] variable, you also have to change the member variables.

In the file src/devices/video/tms9928.cpp when you write the registers with tms9928a_device::change_register, it updates other variables inside the driver, so for register 0, it will update m_color and m_pattern. Likewise for other registers.


Code
void tms9928a_device::change_register(uint8_t reg, uint8_t val)
{

...
		switch (reg)
	{
	case 0:
		/* re-calculate masks and pattern generator & colour */
		if (val & 2)
		{
			m_colour = ((m_Regs[3] & 0x80) * 64) & (m_vram_size - 1);
			m_pattern = ((m_Regs[4] & 4) * 2048) & (m_vram_size - 1);
			update_table_masks();
		}
		else
		{
			m_colour = (m_Regs[3] * 64) & (m_vram_size - 1);
			m_pattern = (m_Regs[4] * 2048) & (m_vram_size - 1);
		}
		m_mode = ( (m_reva ? (m_Regs[0] & 2) : 0) | ((m_Regs[1] & 0x10)>>4) | ((m_Regs[1] & 8)>>1));
		if ((val ^ prev) & 1)
			update_backdrop();
		if (TRACE_MODE) logerror("TMS9928A('%s'): %s\n", tag(), modes[m_mode]);
		break;



So I load my vram dump into the TMS.

The values to load into the registers are as follows:

Code
reginitarray = {2,194,14,255,3,63,3,1}; for index,val in pairs(reginitarray) do print(index-1,string.format("%x",val)) end
0	2
1	c2
2	e
3	ff
4	3
5	3f
6	3
7	1



so I set by hand with the debugger:

TMS9918A VDP/:sl4:arcbd:arcbd_tms/0/m_Regs[0] to 2
TMS9918A VDP/:sl4:arcbd:arcbd_tms/0/m_Regs[1] to c2
TMS9918A VDP/:sl4:arcbd:arcbd_tms/0/m_pattern to 0 (address of the pattern table)
TMS9918A VDP/:sl4:arcbd:arcbd_tms/0/m_colour to 2000 (address of the color table)
TMS9918A VDP/:sl4:arcbd:arcbd_tms/0/m_nametbl to 3800 (address of the name table)
TMS9918A VDP/:sl4:arcbd:arcbd_tms/0/m_mode to 2 (graphics mode 2)

then I can see the bitmap display.

and if I further set:

TMS9918A VDP/:sl4:arcbd:arcbd_tms/0/m_spritepattern to 1800
TMS9918A VDP/:sl4:arcbd:arcbd_tms/0/m_spriteattribute to 1f80

then I can see the sprites.

And if you want some weird effects, just set m_pattern to 1 to 7 (something you could never have on real hardware) or to 1800 (where the sprite patterns are).



I can see a table with the items in lua but it's just a list of items with the corresponding number.

Code
for i,j in pairs(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items) do print(i,j) end
1/0/m_start.seconds	610
0/0/m_start.seconds	605
0/m_clock_scale	439
0/m_Regs[6]	437
0/m_pattern	448
0/m_colour	441
0/m_colourmask	442
0/m_palette	446
0/m_patternmask	449
0/m_Regs[7]	440
0/m_spriteattribute	450
0/m_spritepattern	451
0/m_FifthSprite	428
0/m_nametbl	445
0/m_Regs[1]	432
0/m_Regs[0]	431
0/0/m_enabled	594
1/0/m_enabled	602
1/0/m_start.attoseconds	609
0/0/m_start.attoseconds	601
1/0/m_param	606
0/0/m_param	598
0/m_ReadAhead	429
0/m_Regs[2]	433
0/m_unscaled_clock	452
1/00000000-0000ffff	673
1/0/m_period.seconds	608
0/0/m_period.seconds	600
0/m_Regs[4]	435
0/m_StatusReg	444
0/m_INT	427
1/0/m_expire.attoseconds	603
0/m_latch	447
0/0/m_expire.seconds	596
1/0/m_expire.seconds	604
0/0/m_period.attoseconds	599
0/m_clock	438
0/0/m_expire.attoseconds	595
1/0/m_period.attoseconds	607
0/m_mode	443
0/m_Regs[5]	436
0/m_Addr	425
0/m_Regs[3]	434



I wish that I could read/write these items with lua in the same way that I can read/write them with the debugger memory view window.

#111102 - 10/17/17 06:17 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Jan 2012
Posts: 763
crazyc Offline
Senior Member
crazyc  Offline
Senior Member

Joined: Jan 2012
Posts: 763
try emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["1/0/m_start.seconds"]):read(offset) or :write(offset, newval) or :read_block(byte_offset, len).

Last edited by crazyc; 10/17/17 06:17 PM.
#111106 - 10/18/17 03:41 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: crazyc]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Thank you, crazyc! That's exactly what I was looking for. Beauty!

#111107 - 10/18/17 02:42 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
So with emu.item I can do this:

Code
dofile("../../arcbd_load_vram.lua")

emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[0]"]):write(0,2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[1]"]):write(0,0xc2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_pattern"]):write(0,0)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_colour"]):write(0,0x2000)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_nametbl"]):write(0,0x3800)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_mode"]):write(0,2)

emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_spritepattern"]):write(0,0x1800)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_spriteattribute"]):write(0,0x1f80)




There's a couple of other properties of emu.item that are interesting too, like .size and .count that are interesting to examine.

Item "0/m_pattern" has a size of 2 and count 1 while item "0/m_Regs[0]" has size of 1 and count 1.

Item "1/00000000-0000ffff" has a size of 1 and count 65536, and I can read/write into the vram with it.

Very cool. This lua engine is awesome!


Code
for i,j in pairs(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items) do print(i,j) end
print(emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_pattern"]).size)
print(emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_pattern"]).count)
print(emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[0]"]).size)
print(emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[0]"]).count)
print(emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["1/00000000-0000ffff"]).size)
print(emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["1/00000000-0000ffff"]).count)

emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["1/00000000-0000ffff"]):write(0,255)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["1/00000000-0000ffff"]):write(1,0xaa)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["1/00000000-0000ffff"]):write(2,0x55)

print(emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["1/00000000-0000ffff"]):read(0))
print(emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["1/00000000-0000ffff"]):read(1))
print(emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["1/00000000-0000ffff"]):read(2))


#111108 - 10/18/17 03:02 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jan 2012
Posts: 763
crazyc Offline
Senior Member
crazyc  Offline
Senior Member

Joined: Jan 2012
Posts: 763
Right, size is the native byte width of an entry (like sizeof()) while count is number of size width words. If there are any other mame internals that you think would be useful to access from lua let me know. Also, if you haven't looked at the Scripty Things thead above, there's some neat stuff in there (and maybe post some of your stuff in it too).

Last edited by crazyc; 10/18/17 03:05 PM.
#111110 - 10/18/17 07:53 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: crazyc]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Thanks again, CrazyC!

I am having such a blast fiddling with lua and mame. I haven't had this much fun programming for a long time.

I am still learning lua but it's so forgiving. And the console has auto-completion. Awesome! TAB for the win! This is pure genius.


I haven't quite figured out what the difference is between : and .

According to something I read, "The colon is for implementing methods that pass self as the first parameter. So x:bar(3,4) should be the same as x.bar(x,3,4)."


To start up the machine if you have the debugger active:
Code
manager:machine().devices[":maincpu"]:debug():go() 


And in trying to figure out the syntax I invariably interchange : with .

Code
print(manager:machine().devices[":maincpu"]:debug())
sol.device_debug*: 0x559857771518


but if I call the same thing, without the colon syntax, it blows with a segfault.

Code
print(manager:machine().devices[":maincpu"].debug())
Segmentation fault (core dumped)




The console plug in history is only 10 entries, but we can fix that easily by changing the line in plugins/console.init.lua
ln.historysetmaxlen(10) to something like 30.

#111117 - 10/19/17 08:17 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
And one of the interesting things about older systems is that you often have to write your own routines to do graphics, like linedraws on the TMS9918. Drawing lines is actually pretty easy, just plot a pixel in the pattern memory by setting a bit, and set the color byte in the color memory.


[Linked Image]


Code
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[0]"]):write(0,2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[1]"]):write(0,0xc2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_pattern"]):write(0,0)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_colour"]):write(0,0x2000)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_nametbl"]):write(0,0x3800)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_mode"]):write(0,2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_spritepattern"]):write(0,0x1800)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_spriteattribute"]):write(0,0x1f80)
--set background to 4
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[7]"]):write(0,0xf4)

mem=manager:machine().devices[":sl4:arcbd:arcbd_tms"].spaces["vram"]

function plotpixel(screenaddr,x,y)
local byteaddr = screenaddr + math.floor(y/8) * 256 + (y % 8) + math.floor(x/8) * 8
if x>=0 and x <=255 and y>=0 and y <=191 then
mem:write_u8(byteaddr,mem:read_u8(byteaddr)| (1 << (7-(x%8))))
end
end


function plotcolor(screenaddr,x,y,colorfg)
local byteaddr = screenaddr + math.floor(y/8) * 256 + (y % 8) + math.floor(x/8) * 8
if x>=0 and x<=255 and y>=0 and y<=191 then
--foreground single color
mem:write_u8(byteaddr,(mem:read_u8(byteaddr)& 0x0) | (math.floor(colorfg) << (4)) )
end
end


function deltasign(x)
if x<0 then return -1
elseif x==0 then return 0
elseif x>0 then return 1
else return 0
end
end


function linedraw(x1,y1,x2,y2,colorfg)
-- using basic code converted to lua from:
-- https://rosettacode.org/wiki/Bitmap/Bresenham's_line_algorithm
--[[
 1500 REM === DRAW a LINE. Ported from C version
 1510 REM Inputs are X1, Y1, X2, Y2: Destroys value of X1, Y1
 1520 DX = ABS(X2 - X1):SX = -1:IF X1 < X2 THEN SX = 1
 1530 DY = ABS(Y2 - Y1):SY = -1:IF Y1 < Y2 THEN SY = 1
 1540 ER = -DY:IF DX > DY THEN ER = DX
 1550 ER = INT(ER / 2)
 1560 PLOT X1,Y1:REM This command may differ depending ON BASIC dialect
 1570 IF X1 = X2 AND Y1 = Y2 THEN RETURN
 1580 E2 = ER
 1590 IF E2 > -DX THEN ER = ER - DY:X1 = X1 + SX
 1600 IF E2 < DY THEN ER = ER + DX:Y1 = Y1 + SY
 1610 GOTO 1560
--]]

x1 = math.floor(x1)
x2 = math.floor(x2)
y1 = math.floor(y1)
y2 = math.floor(y2)
 dx = x2-x1
 dy = y2-y1
 sx = deltasign(dx)
 sy = deltasign(dy)
 local x = x1
 local y = y1
 local adx = math.abs(dx)
 local ady = math.abs(dy)
 local er,e2

if adx > ady then er =  adx 
else er = - ady
end 

er = math.floor(er / 2)

while 1 do
  plotpixel(0,x,y)
  plotcolor(8192,x,y,colorfg)
  if x == x2 and y == y2 then return end
  e2 = er
  if e2 > -adx then er = er - ady; x = x + sx  end
  if e2 <  ady then er = er + adx; y = y + sy  end
  if x<0 or x > 255 or y < 0 or y > 191 then return end
end  -- while
end -- function


function clearscreentms()
tms= manager:machine().devices[":sl4:arcbd:arcbd_tms"]
mem = tms.spaces["vram"]
local addr
for addr = 0,6143 do mem:write_u8(addr,0) end
end

function circlerandomcolor(step,size)
local i
for i=0,360,step do linedraw(128,96,128+math.cos(i/360*2*math.pi)*size,96+math.sin(i/360*2*math.pi)*size,math.floor(math.random()*15)) end
end

function initpatterntms()
local pat
for pat = 0,768-1 do
   mem:write_u8(pat+0x3800,pat % 256)
end
end


clearscreentms()
initpatterntms()
for i = 0,255,16 do linedraw(i,0,0,192,math.floor(i/16)) end
circlerandomcolor(1,50)
for i = 0,255,16 do linedraw(i,0,255,191,math.floor(i/16)) end

#111152 - 10/25/17 02:40 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I wanted to see if I could rip atari 2600 graphics from the game Stampede, so I wrote a little lua script to dump the ram from the 2600.

I didn't know how much to grab, so I went for 4k. I now know that Stampede is a 2k cartridge.

Code
mem=manager:machine().devices[":maincpu"].spaces["program"]

-- read ram and save to a file

outfile = assert(io.open("2600_dump_file", "wb"))

for i=0x1000,0x2000-1 do
  outfile:write(string.char(mem:read_u8(i)))
end

assert(outfile:close())


and once you have the 2600_dump_file saved, you can run this script on the apple2e driver with -sl4 arcbd which will make the following display:

The horse animates and you can move it left right/up and down.


I always wondered why the legs of the horse had an interlaced effect. That's because of the HMOVEs so the legs can split and display wider than the 8 pixels in a byte.

[Linked Image]

Code
-- ==============================================================
-- read datablock from a file and close it

infile = assert(io.open("2600_dump_file", "rb"))

datablock = infile:read("*all")    

assert(infile:close())

-- ====================================================================

emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[0]"]):write(0,2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[1]"]):write(0,0xc2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[1]"]):write(0,0xc3) -- dbl size
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_pattern"]):write(0,0)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_colour"]):write(0,0x2000)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_nametbl"]):write(0,0x3800)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_mode"]):write(0,2)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_spritepattern"]):write(0,0x1800)
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_spriteattribute"]):write(0,0x1f80)
--set background to 4
emu.item(manager:machine().devices[":sl4:arcbd:arcbd_tms"].items["0/m_Regs[7]"]):write(0,0xf4)

mem=manager:machine().devices[":sl4:arcbd:arcbd_tms"].spaces["vram"]

function plotpixel(screenaddr,x,y)
local byteaddr = screenaddr + math.floor(y/8) * 256 + math.floor(y % 8) + math.floor(x/8) * 8
if x>=0 and x <=255 and y>=0 and y <=191 then
mem:write_u8(byteaddr,mem:read_u8(byteaddr)| (1 << (7-(x%8))))
end
end


function plotcolor(screenaddr,x,y,colorfg)
local byteaddr = screenaddr + math.floor(y/8) * 256 + math.floor(y % 8) + math.floor(x/8) * 8
if x>=0 and x<=255 and y>=0 and y<=191 then
--foreground single color
mem:write_u8(byteaddr,(mem:read_u8(byteaddr)& 0x0) | (math.floor(colorfg) << (4)) )
end
end

function deltasign(x)
if x<0 then return -1
elseif x==0 then return 0
elseif x>0 then return 1
else return 0
end
end

function linedraw(x1,y1,x2,y2,colorfg)
-- using basic code converted to lua from:
-- https://rosettacode.org/wiki/Bitmap/Bresenham's_line_algorithm

 x1 = math.floor(x1);x2 = math.floor(x2);y1 = math.floor(y1);y2 = math.floor(y2)
 dx = x2-x1; dy = y2-y1
 sx = deltasign(dx); sy = deltasign(dy)
 local x = x1; local y = y1
 local adx = math.abs(dx)
 local ady = math.abs(dy)
 local er,e2

if adx > ady then er =  adx 
else er = - ady
end 

er = math.floor((er / 2)+0.5)  -- INT rounding because math.floor rounding doesn't work for 1 pixel lines

while 1 do
  plotpixel(0,x,y)
  plotcolor(8192,x,y,colorfg)
  if x == x2 and y == y2 then return end
  e2 = er
  if e2 > -adx then er = er - ady; x = x + sx  end
  if e2 <  ady then er = er + adx; y = y + sy  end
  if x<0 or x > 255 or y < 0 or y > 191 then print("hit edge",x1,y1,x2,y2) return end
end  -- while
end -- function

function drawbox(x1,y1,x2,y2,col)
 linedraw(x1,y1,x2,y1,col)
 linedraw(x2,y1,x2,y2,col)
 linedraw(x2,y2,x1,y2,col)
 linedraw(x1,y2,x1,y1,col)
end


function clearscreentms()
tms= manager:machine().devices[":sl4:arcbd:arcbd_tms"]
mem = tms.spaces["vram"]
local addr
for addr = 0,6143 do mem:write_u8(addr,0) end
end

function initpatterntms()
local pat
for pat = 0,768-1 do
   mem:write_u8(pat+0x3800,pat % 256)
end
end

function initcolortms(fg,bg)
for addr = 0,6143 do mem:write_u8(addr+8192,bg|(fg<<4)) end end


function clstms()
clearscreentms()
initpatterntms()
initcolortms(15,4)
end

clstms()

function reversebits(x)
local outbyte = 0
for bit=0,7 do
  if(x & (1<<bit))~=0 then outbyte = outbyte | (1<<(7-bit)) end
end
return outbyte
end

function draw2600intoscreendirect()
for i=0,4096-1 do
  mem:write_u8(i,reversebits(string.byte(datablock,(i+1))))  -- datablock index starts at 1
end
end

clstms()

function draw2600intoscreen()
xpos = 0; ypos = 0
for i = 4096-1,4096-2048-1,-1 do
  for bit=0,7 do
    if (reversebits(string.byte(datablock,(i+1))) & (1<<bit))~=0 then linedraw(xpos+bit,ypos,xpos+bit,ypos,7) end
  end
  ypos = ypos + 1
  if ypos >= 128+16 then ypos = 0; xpos = xpos + 16; end
end
end

clstms()
draw2600intoscreen()

function stampededogie(p8d,p8f)
--linedraw(xpos,ypos,xpos,ypos,1)
for offset = 0xf,1,-1 do
grp1 =p8f+offset
hmove=p8d+offset-1
  for bit=0,7 do
    if (reversebits(string.byte(datablock,(grp1+1))) & (1<<bit))~=0 then linedraw(xpos+bit,ypos,xpos+bit,ypos,7) end
  end
  hmoveval = (string.byte(datablock,(hmove+1))>>4)
  if hmoveval >= 8 then hmoveval = hmoveval - 16 end
  xpos = xpos - hmoveval
  ypos = ypos + 1
  if ypos >= 128+64 then ypos = 128+32; xpos = xpos + 16; end
end
end

xpos = 32;       ypos = 128+48; stampededogie(0x6c9,0x67d);
xpos = 32+1*16;  ypos = 128+48; stampededogie(0x6c9,0x66e);
xpos = 32+2*16+6;ypos = 128+48; stampededogie(0x6ac,0x68b)

function stampede_horse(p8b,p8d,p8f) 
--p8b is ptr to hmp0, p8d is ptr to nusiz0, p8f is ptr to grp0
xpos = xpos + 32
ypos = 128+24
for offset=0x19,1,-1 do
grp0 =p8f+offset
hmove=p8b+offset-1  -- hmove happens to "next line"
nusiz=p8d+offset
-- follows the atari 2600 stampede code which ORs these 2 together
nusiz=string.byte(datablock,(nusiz+1)) | (string.byte(datablock,(hmove+1+1))&5)
nusiz=nusiz & 0xd
  if (nusiz & 7) == 5 then dbl=2 else dbl=1 end
  for bit=0,7 do
    if (reversebits(string.byte(datablock,(grp0+1))) & (1<<bit))~=0 then 
          linedraw(xpos+bit*dbl,ypos,xpos+(bit+1)*dbl-1,ypos,7+dbl)
    end
  end
  hmovedelta = (string.byte(datablock,(hmove+1))>>4)
  if hmovedelta >= 8 then hmovedelta = hmovedelta - 16 end
  xpos = xpos - hmovedelta
  ypos = ypos + 1
  if ypos >= 128+64 then ypos = 128+24; xpos = xpos + 32; end
end
end

xpos=64;      stampede_horse(0x74d,0x6c7,0x71a); 
xpos=64+1*32; stampede_horse(0x766,0x6c7,0x700); 
xpos=64+2*32; stampede_horse(0x74d,0x6c7,0x700); 
xpos=64+3*32; stampede_horse(0x77f,0x6c3,0x734);

function drawblock(addr,offset1,offset2)
ypos0 = ypos
for i=addr+offset1,addr+offset2,-1 do
  for bit=0,7 do
    if (reversebits(string.byte(datablock,(i+1))) & (1<<bit))~=0 then 
       linedraw(xpos+bit,ypos,xpos+bit,ypos,10)
    end
  end    
  ypos = ypos + 1
end
xpos = xpos + 8
ypos = ypos0
end

function stampede_activision()
drawblock(0x668,6,0) -- act
drawblock(0x660,6,0) -- iv
drawblock(0x658,6,0) -- isi
drawblock(0x650,6,0) -- on
end

xpos = 128; ypos= 128+56
stampede_activision()

function stampede_skull()
drawblock(0x69b,9,1)
end

xpos = 64;ypos = 128+20
stampede_skull()

function stampede_0123456789()
for num = 0,9 do
drawblock(0x600+num*8,6,0)
end
end

xpos = 0;  ypos = 128+30; stampede_0123456789()

function xytoaddress(x,y)
--print(x,y,math.floor(y/8)*256+(y%8)+math.floor(x/8)*8)
x = math.floor(x)
y = math.floor(y)
return math.floor(y/8)*256+(y%8)+math.floor(x/8)*8
end

for box=0,3 do drawbox(80+32*box,150,80+32*(box+1)-1,150+31,9) end

-- 4 different 16x16 blocks

bytepos=0x1800; 
for box = 0,3 do
for cellx = 0,1 do for celly = 0,1 do for j = 0,1 do for i=0,15 do mem:write_u8(bytepos,mem:read_u8(xytoaddress(80+8*j+16*cellx+box*32,150+i+16*celly))); bytepos = bytepos + 1; end end end end end


spriteatt = 0x1f80

horsex = 25
horsey = 25

scale = 2

function setsprite(sprnum,sprimgnum)
for celly = 0,1 do
for cellx = 0,1 do
mem:write_u8(spriteatt + cellx*2*4 + celly*4 + 0, horsey+16*celly*scale)
mem:write_u8(spriteatt + cellx*2*4 + celly*4 + 1, horsex+16*cellx*scale)
mem:write_u8(spriteatt + cellx*2*4 + celly*4 + 2,(cellx * 2 + celly)*4+16*sprimgnum)
mem:write_u8(spriteatt + cellx*2*4 + celly*4 + 3, 11)
end
end
end


setsprite(0,0)


dispatch_list={}


function frame_dispatcher()
for index,my_func in pairs(dispatch_list) do  my_func() end
end


function dispatch_list_remove(a_func)
for my_index,my_func in pairs(dispatch_list) do if my_func == a_func then table.remove(dispatch_list,my_index) end end
end

function print_dispatch_list() for my_index,my_func in pairs(dispatch_list) do print(my_func) end end



if already_registered_frame_dispatcher == nil then
   emu.register_frame(frame_dispatcher);
   already_registered_frame_dispatcher = 1
end

function cld()
dispatch_list = {}
end


delaycounter1 = 0
spriteimageseq = {0,1,2,1}
spriteimageseqnum = 1


function every_frame()
--  everydelay(1,delaycounter1)
  
  delaycounter1 = (delaycounter1+1)%5
  if delaycounter1 == 0 then 
           spriteimageseqnum = (((spriteimageseqnum + 1)-1) % #spriteimageseq)+1
  end

  inp = manager:machine():input()
  if inp:code_pressed(inp:code_from_token("KEYCODE_UP")) then 
     horsey = horsey - 2
   end

  if inp:code_pressed(inp:code_from_token("KEYCODE_DOWN")) then 
     horsey = horsey + 2
  end
      
  if inp:code_pressed(inp:code_from_token("KEYCODE_RIGHT")) then 
    horsex = horsex + 2
  end
  if inp:code_pressed(inp:code_from_token("KEYCODE_LEFT")) then 
    horsex = horsex - 2
  end


  setsprite(0,spriteimageseq[spriteimageseqnum])
  

end

table.insert(dispatch_list,every_frame)

#111210 - 11/01/17 12:02 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Coming soon....

[Linked Image]

It actually works except for detecting slot 6 and dropping the speed right now, so obviously the Disk II is unhappy with that smile

#111230 - 11/05/17 04:58 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I finally figured out how to read the apple joystick from lua.

Code
-- this is a little function to print a table

function printt(a) local i,j; for i,j in pairs(a) do print(i,j) end end


 printt(manager:machine():ioport().ports)

:X5	sol.ioport_port*: 0x55d3d11cd778
:joystick_1_y	sol.ioport_port*: 0x55d3d11cd7f8
:X3	sol.ioport_port*: 0x55d3d11d2fa8
:keyb_special	sol.ioport_port*: 0x55d3d11cd958
:joystick_buttons	sol.ioport_port*: 0x55d3d11cd9c8
:joystick_2_y	sol.ioport_port*: 0x55d3d11cda38
:X7	sol.ioport_port*: 0x55d3d11cd698
:joystick_2_x	sol.ioport_port*: 0x55d3d11cdaa8
:a2_config	sol.ioport_port*: 0x55d3d11cd5b8
:X4	sol.ioport_port*: 0x55d3d11cd7b8
:joystick_1_x	sol.ioport_port*: 0x55d3d11cd548
:X2	sol.ioport_port*: 0x55d3d52ee878
:X1	sol.ioport_port*: 0x55d3d52ee8f8
:X8	sol.ioport_port*: 0x55d3d11cd628
:X0	sol.ioport_port*: 0x55d3d11d2cd8
:X6	sol.ioport_port*: 0x55d3d11cd708


and if you look at the apple2e.cpp code, you can see that it maps right up to this:

Code
	PORT_START("joystick_buttons")
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1)  PORT_PLAYER(1)            PORT_CODE(KEYCODE_0_PAD)    PORT_CODE(JOYCODE_BUTTON1)
	PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2)  PORT_PLAYER(1)            PORT_CODE(KEYCODE_ENTER_PAD)PORT_CODE(JOYCODE_BUTTON2)
	PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1)  PORT_PLAYER(2)            PORT_CODE(JOYCODE_BUTTON1)


so to read the buttons you can do:

Code
print(manager:machine():ioport().ports[":joystick_buttons"]:read())
0

and to test it in an if statement:

Code
if (manager:machine():ioport().ports[":joystick_buttons"]:read() & 0x10) ~= 0 then
  -- button 1 pressed
end
if (manager:machine():ioport().ports[":joystick_buttons"]:read() & 0x20) ~= 0 then
  -- button 2 pressed
end



The joystick axes come in under the names "joystick_1_x" and "joystick_1_y"

Looking at apple2e.cpp we have:
Code
static INPUT_PORTS_START( apple2_joystick )
	PORT_START("joystick_1_x")      /* Joystick 1 X Axis */
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X) PORT_NAME("P1 Joystick X")
	PORT_SENSITIVITY(JOYSTICK_SENSITIVITY)
	PORT_KEYDELTA(JOYSTICK_DELTA)
	PORT_CENTERDELTA(JOYSTICK_AUTOCENTER)
	PORT_MINMAX(0,0xff) PORT_PLAYER(1)
	PORT_CODE_DEC(KEYCODE_4_PAD)    PORT_CODE_INC(KEYCODE_6_PAD)
	PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH)    PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH)

	PORT_START("joystick_1_y")      /* Joystick 1 Y Axis */
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y) PORT_NAME("P1 Joystick Y")
	PORT_SENSITIVITY(JOYSTICK_SENSITIVITY)
	PORT_KEYDELTA(JOYSTICK_DELTA)
	PORT_CENTERDELTA(JOYSTICK_AUTOCENTER)
	PORT_MINMAX(0,0xff) PORT_PLAYER(1)
	PORT_CODE_DEC(KEYCODE_8_PAD)    PORT_CODE_INC(KEYCODE_2_PAD)
	PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH)      PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH)


and in lua we can read it with:

Code
print(manager:machine():ioport().ports[":joystick_1_x"]:read())
128
print(manager:machine():ioport().ports[":joystick_1_y"]:read())
128


Note that to get the input events for the joystick movement and buttons, the apple2e window must be selected.

So if you do a print(manager:machine():ioport().ports[":joystick_buttons"]:read()) from the lua console you will get zero unless you select the apple2e window, hold the joystick button(s), click on the lua console window and then do your print statement.

What's kind of interesting is that with the focus taken away from the window, the joystick and buttons will center or release but won't move away from center.

#111231 - 11/05/17 06:11 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jan 2012
Posts: 763
crazyc Offline
Senior Member
crazyc  Offline
Senior Member

Joined: Jan 2012
Posts: 763
Note if you want to set the input port value you have to use field:set_value() not port:write().

#111232 - 11/06/17 01:16 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: crazyc]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Cool, field:set_value seems to work for buttons.

Code
[MAME]> function printt(a) local i,j; for i,j in pairs(a) do print(i,j) end end
[MAME]> printt(manager:machine():ioport().ports[":joystick_buttons"].fields)
P1 Button 2	sol.ioport_field*: 0x55c6ff3a0d28
P2 Button 1	sol.ioport_field*: 0x55c6ff3a0d68
P1 Button 1	sol.ioport_field*: 0x55c6ff3a0ce8
[MAME]>  print(manager:machine():ioport().ports[":joystick_buttons"]:read())
0
[MAME]> manager:machine():ioport().ports[":joystick_buttons"].fields["P1 Button 2"]:set_value(1)
[MAME]> print(manager:machine():ioport().ports[":joystick_buttons"]:read())
32
[MAME]> manager:machine():ioport().ports[":joystick_buttons"].fields["P1 Button 2"]:set_value(0)
[MAME]>  print(manager:machine():ioport().ports[":joystick_buttons"]:read())
0


I thought I'd try it for a joystick axis value but it doesn't seem to have any effect. I removed the bindings to the second joystick too.

Code
manager:machine():ioport().ports[":joystick_2_y"].fields["P2 Joystick Y"]:set_value(0)
print(manager:machine():ioport().ports[":joystick_2_y"]:read())
128

Last edited by Golden Child; 11/06/17 01:42 AM.
#111235 - 11/06/17 11:12 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jan 2012
Posts: 763
crazyc Offline
Senior Member
crazyc  Offline
Senior Member

Joined: Jan 2012
Posts: 763
Unfortunately analog fields are only read directly from the source, there isn't currently any way to override it.

#111236 - 11/07/17 08:55 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I thought I'd see if I can have the arcade board's AY-3-8912 make some beeps.

But I need to have some delays or it doesn't work. Without delays everything happens all at once... so let's fiddle some more with coroutines.

The advantage of this is that we can call a delay() function.

So for example if you want

Code
for i = 1,60 do
  sound(7,24)
  settonevol(0,175,15)
  delay(2)  -- delays for 2 frames
  settonevol(0,175,0)
  delay(2)
end


then you call:

Code
add_func_string([[local i; for i=1,30 do sound(7,24); settonevol(0,175,8); delay(2); settonevol(0,175,0); delay(2); end ]])


and what's cool is that you can enter little tests from the command line quite easily with add_func_string.

Code

-- ===========================================================================
-- FRAME DISPATCHER

dispatch_list={}

function frame_dispatcher()
for index,my_func in pairs(dispatch_list) do  my_func() end
end


function dispatch_list_remove(a_func)
for my_index,my_func in pairs(dispatch_list) do if my_func == a_func then table.remove(dispatch_list,my_index) end end
end

function print_dispatch_list() for my_index,my_func in pairs(dispatch_list) do print(my_func) end end

print("type cld() and hit enter to stop a runaway dispatch")

if already_registered_frame_dispatcher == nil then
   emu.register_frame(frame_dispatcher);
   already_registered_frame_dispatcher = 1
end

function cld()
dispatch_list = {}
end


-- ===========================================================================
-- COROUTINE DISPATCHER

coroutine_frame_list = { }

function coroutine_frame_dispatch()
local i,thread
  for i,thread in pairs(coroutine_frame_list) do coroutine.resume(thread) end
  for i = #coroutine_frame_list,1,-1 do if coroutine.status(coroutine_frame_list[i]) == "dead" then table.remove(coroutine_frame_list,i) end end
end

function delay(frames)
  local f
  for f = 1,frames do coroutine.yield() end
end

function add_func_exec(myfunc)
local newthread
  newthread = coroutine.create(myfunc)
  table.insert(coroutine_frame_list,newthread)
end

function add_func_string(func_string)
local newfunc
  newfunc = assert(loadstring(func_string))
  if newfunc ~= nil then add_func_exec(newfunc) end
end 




function addco()
-- once you clear your dispatch list, you must add the coroutine_frame_dispatch
-- to get the coroutine_dispatch to work
table.insert(dispatch_list,coroutine_frame_dispatch)
end


cld()
addco()


function lobyte(x)
 return x & 255
end
function hibyte(x)
  return (x & (255<<8))>>8
end

function checkrange(x,lo,hi)
if not(x >= lo and x <= hi) then print("checkrange failed ",x,lo,hi); return false 
else return true; end
end


aystr = ":sl7:ssprite:ssprite_ay"
aystr = ":sl4:arcbd:arcbd_ay"

function sound(regnum,value)
emu.item(manager:machine().devices[aystr].items["0/m_regs"]):write(regnum,value)
end



function settone(chan,tone)
  if checkrange(chan,0,2) then
    regnum = chan*2  
    sound(regnum,lobyte(tone))
    sound(regnum+1,hibyte(tone))
  end
end

function setvol(chan,vol)
  if checkrange(chan,0,2) then
    regnum = chan+8  
    sound(regnum,vol)
  end
end

function settonevol(chan,tone,vol)
  settone(chan,tone)
  setvol(chan,vol)
end

-- two different ways to add a function, pass a function to add_func_exec
-- or pass add_func_string a string and if you use double brackets you don't have to escape the quotes

add_func_exec(function () local i; for i = 1,10 do print("yoyo",i);delay(5);end end)

add_func_string("local i; for i=1,15 do print(\"hello\",i);delay(5); end")


-- sound(7,24) turns on sound ABC and turns off the noise channels

add_func_string([[local d; local i; for d = 1,4 do print("delay="..d) for i=1,30 do sound(7,24); settonevol(0,175,8); delay(d); settonevol(0,175,0); delay(d); end end ]])




Last edited by Golden Child; 11/07/17 09:06 AM.
#111260 - 11/11/17 01:04 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I wanted to see if I could reproduce the apple 2 beep sound with the AY-3-8912. It's supposed to be around 1000hz, but that doesn't sound quite right if I'm using the apple2e driver as a reference.

Reading some Synetix SuperSprite documentation (Synetix SuperSprite Owners Manual.pdf page 40 of 266) it says that I just have to divide 63920.438 by the desired pitch.

Tone Period =1,022,727 / 16 X desired pitch
= 63,920.438 / desired pitch

so let's make a little function to calculate the tone:

Code
function calctone(freq)
return math.floor (63920.438 / freq)
end



then I can make something that sounds pretty close to the CTRL+G bell.

I came up with around 930 hz just by listening to the tone and hunting for a number that was close.

Code
add_func_string([[for i=0,0 do sound(7,24);settonevol(0,calctone (930),15); delay(6); settonevol(0,0,0); delay(1); end print("done")]])



but how close is that actually?

I fired up mame with the debugger and set a watchpoint on $c030 with

Code
wpset c030,1,r 


and then typed g in the debug window.

Once the boot beep hit c030 I went to the lua console and typed:

Code
a = emu.time()

then hit g again in the debugger, and then got the time at that point:

Code
b = emu.time()


so how long did that take?

Code
print(b-a)

0.00053435114503789


so let's convert that to hertz:

Code
print(1/(b-a))
1871.4285714295


oh but wait, it should be half that since we've only counted half a tone cycle

Code
print(1/(b-a)/2)
935.71428571477


which I got pretty darn close to, 930 vs 936. Not bad for someone who's tone deaf.

Now I've got a beep that is pretty much identical.



Code
add_func_string([[for i=0,0 do sound(7,24);settonevol(0,calctone (936),15); delay(6); settonevol(0,0,0); delay(1); end print("done")]])

Last edited by Golden Child; 11/11/17 01:12 PM.
#111317 - 11/22/17 02:24 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
One of the things I'm terrible at is counting cpu cycles.

So let's figure out how many cycles it takes to do the system beep, and while we're at it figure out what the cpu clock is.

How can we get the totalcycles?
./mame64 apple2e -plugin console -debug

Just ask the debugger to print the totalcycles.

Immediately after boot, if we ask the debugger for totalcycles we get:

Code
>print totalcycles
3


so how to get that value into a variable in lua?

Code
function getcycles() 
  dbg = manager:machine():debugger()
  dbg:command("print totalcycles") 
  lastline = dbg.consolelog[#dbg.consolelog] 
  cycles = tonumber(lastline,16) 
  return cycles
end


and a single line version to paste at the lua console:

Code
function getcycles() dbg = manager:machine():debugger() dbg:command("print totalcycles")   lastline = dbg.consolelog[#dbg.consolelog]   cycles = tonumber(lastline,16)   return cycles end

so let's set a watchpoint and then go:

Code
dbg = manager:machine():debugger()
dbg:command("wpset c030,1,rw")
dbg:command("g")


so we've hit the first click of the speaker so get the time and the cycles:

Code
a = emu.time(); cyclesa = getcycles()


so let's get the next click:

Code
dbg:command("g")
b = emu.time(); cyclesb = getcycles()

print(cyclesb-cyclesa)

546


and remember that it's a half cycle (since the c030 inverts the speaker) so we multiply by 2


and if we do a little math we can get the system clock:


Code
[MAME]> print(1/((b-a)/(cyclesb-cyclesa)))
1021800.0000005
[MAME]> print((cyclesb-cyclesa)*2)
1092
[MAME]> print(1021800/1092)
935.71428571429
[MAME]> 


and sure enough the cpu clock corresponds exactly to the source code that defines the cpu frequency

Code
static MACHINE_CONFIG_DERIVED( apple2ee, apple2e )
	MCFG_CPU_REPLACE("maincpu", M65C02, 1021800)        /* close to actual CPU frequency of 1.020484 MHz */
	MCFG_CPU_PROGRAM_MAP(apple2e_map)
MACHINE_CONFIG_END



One of the things that baffled me for a bit was why the system clock for the Atari 2600 would come up as not matching the source code exactly:


Code
MAME debugger version 0.191 (mame0191-183-g346a935839-dirty)
Currently targeting a2600 (Atari 2600 (NTSC))
[MAME]> function getcycles() dbg = manager:machine():debugger() dbg:command("print totalcycles")   lastline = dbg.consolelog[#dbg.consolelog]   cycles = tonumber(lastline,16)   return cycles end


[MAME]> a = emu.time(); acycles=getcycles()
[MAME]> 
3
[MAME]> dbg:command("step")
[MAME]> b = emu.time(); bcycles=getcycles()
[MAME]> 
5

print((bcycles-acycles)/(b-a))
1193181.0000007

print((bcycles-acycles)/(b-a)*3)
3579543.0000022

print(3579545/3)
1193181.6666667



so why doesn't 3579543 match up with 3579545? Finally I realized that there's some rounding taking place that converts (3579543/3) = 1193181.6666667 into 1193181.0 because the machines take an integer value for the frequency and that accounts for the discrepancy (bye bye fractional part).

Code

#define MASTER_CLOCK_NTSC   3579545

static MACHINE_CONFIG_START( a2600 )
	/* basic machine hardware */
	MCFG_CPU_ADD("maincpu", M6507, MASTER_CLOCK_NTSC / 3)

Last edited by Golden Child; 11/22/17 02:47 PM.
#111318 - 11/22/17 02:28 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jan 2012
Posts: 763
crazyc Offline
Senior Member
crazyc  Offline
Senior Member

Joined: Jan 2012
Posts: 763
dbg.consolelog:__len() == #dbg.consolelog

#111320 - 11/22/17 02:48 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: crazyc]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Originally Posted by crazyc
dbg.consolelog:__len() == #dbg.consolelog


I didn't think anyone would see that. Post edited 8-)

#111321 - 11/22/17 02:59 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Are there any "bad" side-effects to enabling SOL_CHECK_ARGUMENTS in luaengine.h aside from performance reasons?

Code
#define SOL_CHECK_ARGUMENTS
#include "sol2/sol.hpp"


I inevitably type . instead of : and get a segfault.

For example:

Code
print((manager:machine():debugger().consolelog:__len()))
2


but if I change the : to a ., then kaboom.

Code
print((manager:machine():debugger().consolelog.__len()))
Segmentation fault (core dumped)

and if I uncomment #define SOL_CHECK_ARGUMENTS
it will gracefully give me an error.

Code
print((manager:machine():debugger().consolelog.__len()))
error: 	[string "print((manager:machine():debugger().consolelo..."]:1: stack index 1, expected userdata, received no value



according to:

https://github.com/ThePhD/sol2/issues/408

Quote

ThePhD commented on May 19

Please turn on the safety features. This will crash your code with a specific error message. You can turn on the most important safety feature by definining SOL_CHECK_ARGUMENTS either VIA command line or by putting it before every single <sol.hpp> include.

The segfault is intentional at this level. If you do not turn on safety features we assume that you are doing so for performance reasons and do not want the (small, but sometimes important to people) overhead, or because you expect certain kinds of type punning to happen (e.g., like the many type-puns the MAME engine does in order to fiddle with bits and mess with other low-level things).

Last edited by Golden Child; 11/22/17 03:02 PM.
#111322 - 11/22/17 03:06 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jan 2012
Posts: 763
crazyc Offline
Senior Member
crazyc  Offline
Senior Member

Joined: Jan 2012
Posts: 763
There shouldn't be any issues enabling that.

#111323 - 11/22/17 03:22 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: crazyc]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Originally Posted by crazyc
There shouldn't be any issues enabling that.


Cool. That was one of the things that would crash when I'd experiment.

Now I just have to remember not to try to copy with CTRL+C in the mame console. kaboom! Old habits die hard.


Interestingly, if I type CTRL+V (for paste) I see a ^V in the console, but it takes two deletes to remove it.

If I only delete once after hitting CTRL+V I get this "unexpected symbol" and I could not figure out why my command didn't work.

type print("hello") then CTRL+V and then delete once, the command line looks ok, but there's a bizarro character at the end.

This is with Ubuntu terminal console.

Code
print("hello")
error: 	[string "print("hello")"]:1: unexpected symbol near '<\127>'




I can edit the plugins/console/init.lua and add this line:

Code
local ln = require("linenoise")
ln_global = ln


so I can access the linenoise as the global variable ln_global and then I can save the history as:

Code
ln_global.savehistory("mysavehistoryln.txt")


and loading that into a text editor I can see that there's a strange 007F character at the end.


Is there an easy way of accessing the actual linenoise history entries, like a "history" command in bash, for example?

If I type ln_global. and then hit TAB to complete I get:

Code
ln_global.                                  

addcompletion
clearscreen
sethistorymaxlen
linenoise
lines
historysave
line
preload
loadhistory
savehistory
setcompletion
addhistory
refresh
historyadd
historysetmaxlen
historyload



But none of those seem to give me access to the actual history.


edit:
Hmmm, why not savehistory to /dev/stdout, that seems to work.

Code
ln_global.savehistory("/dev/stdout")


Last edited by Golden Child; 11/22/17 03:55 PM.
#111324 - 11/22/17 03:56 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Jan 2012
Posts: 763
crazyc Offline
Senior Member
crazyc  Offline
Senior Member

Joined: Jan 2012
Posts: 763
The linenoise function char **linenoiseHistory(int *len) provides access to the history but it's not passed to lua in to lua-linenoise. If you can add it that'd be great, it shouldn't be hard to do.

#111325 - 11/22/17 04:12 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: crazyc]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Originally Posted by crazyc
The linenoise function char **linenoiseHistory(int *len) provides access to the history but it's not passed to lua in to lua-linenoise. If you can add it that'd be great, it shouldn't be hard to do.


sounds like an interesting idea, I'll give it a shot.

#111329 - 11/22/17 10:41 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134

I took a stab at adding it to linenoise.c, this seems to work. Cool!

Code
static int l_gethistorytable(lua_State *L)
{
    int i,j;
    char ** phist;
    int lenhist = linenoiseHistoryGetMaxLen();

    phist = linenoiseHistory(&lenhist); 

    lua_newtable(L);
    i = 1;

    for (j=0; j<lenhist; j++){

        /* create result table */
        lua_pushnumber(L, i++);  /* push key */
        lua_pushstring(L, (char *)*(phist+j));  /* push value */
        lua_settable(L, -3);  /* adds key and value to table on top of stack */
      }
      return 1;  /* table is already on top */
}

luaL_Reg linenoise_funcs[] = {
    { "linenoise", l_linenoise },
    { "historyadd", l_historyadd },
    { "historysetmaxlen", l_historysetmaxlen },
    { "historysave", l_historysave },
    { "historyload", l_historyload },
    { "clearscreen", l_clearscreen },
    { "setcompletion", l_setcompletion},
    { "addcompletion", l_addcompletion },
    { "preload", l_preloadbuffer },
    { "refresh", l_refresh },

    /* Aliases for more consistent function names */
    { "addhistory", l_historyadd },
    { "sethistorymaxlen", l_historysetmaxlen },
    { "savehistory", l_historysave },
    { "loadhistory", l_historyload },

    { "line", l_linenoise },
    { "lines", l_lines },

    { "gethistory", l_gethistorytable},  // added function to gethistory
    { NULL, NULL }
};



I think you don't see the current command in the history list because it gets added after it gets executed.

Code
MAME debugger version 0.191 (mame0191-183-g346a935839-dirty)
Currently targeting a2600 (Atari 2600 (NTSC))
[MAME]> print(#ln_global.gethistory())
0
[MAME]> print(#ln_global.gethistory())
1
[MAME]> function printt(a) local i,j; for i,j in pairs(a) do print(i,j) end end

[MAME]> printt(ln_global.gethistory())
1	print(#ln_global.gethistory())
2	function printt(a) local i,j; for i,j in pairs(a) do print(i,j) end end

[MAME]> printt(ln_global.gethistory())
1	print(#ln_global.gethistory())
2	function printt(a) local i,j; for i,j in pairs(a) do print(i,j) end end
3	printt(ln_global.gethistory())
[MAME]> 

#111330 - 11/23/17 05:23 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2004
Posts: 1,939
Vas Crabb Offline
Very Senior Member
Vas Crabb  Offline
Very Senior Member

Joined: Feb 2004
Posts: 1,939
Sydney, Australia
Originally Posted by Golden Child
Interestingly, if I type CTRL+V (for paste) I see a ^V in the console, but it takes two deletes to remove it.

If I only delete once after hitting CTRL+V I get this "unexpected symbol" and I could not figure out why my command didn't work.

type print("hello") then CTRL+V and then delete once, the command line looks ok, but there's a bizarro character at the end.

This is with Ubuntu terminal console.

Code
print("hello")
error: 	[string "print("hello")"]:1: unexpected symbol near '<\127>'



Ctrl-V means "interpret the next character literally", so Ctrl-V Ctrl-C will type a literal ETX character rather than sending SIGINT, Ctrl-V Delete will type a literal DEL rather than deleting the previous character, etc.

#111333 - 11/23/17 08:21 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Vas Crabb]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Originally Posted by Vas Crabb

Ctrl-V means "interpret the next character literally", so Ctrl-V Ctrl-C will type a literal ETX character rather than sending SIGINT, Ctrl-V Delete will type a literal DEL rather than deleting the previous character, etc.


Ohhhh, now that makes perfect sense. That explains why if I'd type Ctrl+v Return that I'd get a ^M or Ctrl+v left arrow I'd get ESC [ D. So that's why I'd get an 007F character from Ctrl+V DEL.

I guess that's a keystroke from VIM.

And sure enough, the code in 3rdparty/linenoise/linenoise.c is pretty straightforward.

Code
    case ctrl('V'):    /* ctrl-v */
            if (has_room(current, 3)) {
                /* Insert the ^V first */
                if (insert_char(current, current->pos, c)) {
                    refreshLine(current->prompt, current);
                    /* Now wait for the next char. Can insert anything except \0 */
                    c = fd_read(current);

                    /* Remove the ^V first */
                    remove_char(current, current->pos - 1);
                    if (c != -1) {
                        /* Insert the actual char */
                        insert_char(current, current->pos, c);
                    }
                    refreshLine(current->prompt, current);
                }
            }

Last edited by Golden Child; 11/23/17 08:33 AM.
#111335 - 11/23/17 09:29 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
So while we're at it, why not do a historygetmaxlen too:

Code
static int l_gethistorytable(lua_State *L)
{
    int i,j;
    char ** phist;
    int lenhist = linenoiseHistoryGetMaxLen();

    phist = linenoiseHistory(&lenhist); 

    lua_newtable(L); /* put a table on the stack */
    i = 1;

    for (j=0; j<lenhist; j++){
        /* create result table */
        lua_pushnumber(L, i++);  /* push key */
        lua_pushstring(L, phist[j]);  /* push value */
        lua_settable(L, -3);  /* adds key and value to table at position 3 from top of stack */
      }
      return 1;  /* table is already on top */
}


static int l_historygetmaxlen(lua_State *L)
{
      lua_pushinteger(L, linenoiseHistoryGetMaxLen());  /* push max len on stack */
      return 1;  /* number of items on stack */
}

luaL_Reg linenoise_funcs[] = {
    { "linenoise", l_linenoise },
    { "historyadd", l_historyadd },
    { "historysetmaxlen", l_historysetmaxlen },
    { "historysave", l_historysave },
    { "historyload", l_historyload },
    { "clearscreen", l_clearscreen },
    { "setcompletion", l_setcompletion},
    { "addcompletion", l_addcompletion },
    { "preload", l_preloadbuffer },
    { "refresh", l_refresh },

    /* Aliases for more consistent function names */
    { "addhistory", l_historyadd },
    { "sethistorymaxlen", l_historysetmaxlen },
    { "savehistory", l_historysave },
    { "loadhistory", l_historyload },

    { "line", l_linenoise },
    { "lines", l_lines },

    { "gethistory", l_gethistorytable},
    { "historygetmaxlen", l_historygetmaxlen},
    { NULL, NULL }
};




Code
MAME debugger version 0.191 (mame0191-183-g346a935839-dirty)
Currently targeting a2600 (Atari 2600 (NTSC))
[MAME]> print(ln_global.historygetmaxlen())
100
[MAME]> print(ln_global.historysetmaxlen(250))
true
[MAME]> print(ln_global.historygetmaxlen())
250
[MAME]> function printt(a) local i,j; for i,j in pairs(a) do print(i,j) end end
[MAME]> printt(ln_global.gethistory())
1	print(ln_global.historygetmaxlen())
2	print(ln_global.historysetmaxlen(250))
3	print(ln_global.historygetmaxlen())
4	function printt(a) local i,j; for i,j in pairs(a) do print(i,j) end end
[MAME]> 

#111361 - 11/24/17 09:29 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Ok, I thought I should clean the code up a little bit, and maybe add a couple of functions to return the history length ln.historylen() and to print the history ln.print() or ln.history().


3rdparty/lua-linenoise/linenoise.c
Code

static int l_gethistorytable(lua_State *L)
{
    int history_len;
    char ** history = linenoiseHistory(&history_len);

    lua_newtable(L); /* put a table on the stack */

    for (int i=0; i<history_len; i++){
        /* create result table */
        lua_pushnumber(L, i+1);  /* push key */
        lua_pushstring(L, history[i]);  /* push value */
        lua_settable(L, -3);  /* adds key and value to table at position 3 from top of stack */
      }
      return 1;  /* table is on top of stack */
}

static int l_historylen(lua_State *L)
{
     int history_len;
     char ** history = linenoiseHistory(&history_len);
     history = history;  // compiler warning about unused variable
     lua_pushinteger(L, history_len);
     return 1;
}

static int l_historygetmaxlen(lua_State *L)
{
      lua_pushinteger(L, linenoiseHistoryGetMaxLen());
      return 1;
}

static int l_historyprint(lua_State *L)
{
    int history_len;
    char ** history = linenoiseHistory(&history_len);

    printf("print history: %d entries\n",history_len);
    for (int i=0; i<history_len; i++){
       printf("%d %s\n",i+1,history[i]);
      }
    return handle_ln_ok(L);
}


luaL_Reg linenoise_funcs[] = {
    { "linenoise", l_linenoise },
    { "historyadd", l_historyadd },
    { "historysetmaxlen", l_historysetmaxlen },
    { "historysave", l_historysave },
    { "historyload", l_historyload },
    { "clearscreen", l_clearscreen },
    { "setcompletion", l_setcompletion},
    { "addcompletion", l_addcompletion },
    { "preload", l_preloadbuffer },
    { "refresh", l_refresh },

    /* Aliases for more consistent function names */
    { "addhistory", l_historyadd },
    { "sethistorymaxlen", l_historysetmaxlen },
    { "savehistory", l_historysave },
    { "loadhistory", l_historyload },

    { "line", l_linenoise },
    { "lines", l_lines },

    { "gethistorytable", l_gethistorytable},
    { "historygetmaxlen", l_historygetmaxlen},
    { "historylen", l_historylen},
    { "print", l_historyprint},
    { "history", l_historyprint},
    { NULL, NULL }
};


What's kind of interesting is that if you set the history to n, the maximum length is actually n-1.

So for ln.historysetmaxlen(5), the length of the history is actually a maximum of 4 entries.


And if you remove this line from plugins/console/init.lua it will default to a maximum length of 100.

Code
ln.historysetmaxlen(10)

since 3rdparty/linenoise/linenoise.c has this:
Code
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100


And if you like to make ln a global variable ln for access you can do this in plugins/console/init.lua

Code
  
local ln = require("linenoise")
_G.ln = ln  -- make a global ln for console access

#111369 - 11/25/17 06:00 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
I was curious how the CTRL+C worked in linenoise and whether it could be "caught".


One interesting side effect of enabling SOL_CHECK_ARGUMENTS in luaengine.h is in whether sol will throw an exception when it executes this in luaengine.cpp:

Code
auto ret = func();

if (ret.valid()) {
	const char *tmp = ret.get<const char *>();
        if (tmp != nullptr)
			ctx.result = tmp;
		else
			exit(0);
	}



So when you type a CTRL+C on the console, it will return a nil from linenoise, tmp will be null so it calls exit(0);

When you've got SOL_CHECK_ARGUMENTS enabled, it will throw a sol::error exception immediately when it executes the following line

Code
const char *tmp = ret.get<const char *>();


It drops out and never sees the following if (tmp != nullptr) statement.

I had to put a bunch of printfs around to figure out exactly where it was blowing up.

And you get this kind of exit.

Code
[MAME]> 
terminate called after throwing an instance of 'sol::error'
  what():  lua: error: stack index 2, expected string, received nil
Aborted (core dumped)


So if we insert a little try catch block, we can catch that sol::error on the get.
Code
if (ret.valid()) {

    printf("calling ret.get const char *\n");

    try{
       const char *tmp = ret.get<const char *>();

	if (tmp != nullptr)
		ctx.result = tmp;
	else
		exit(0);
	
 catch (const std::exception& e) {  
     printf("Caught Exception:\n"); std::cout << e.what() << std::endl;
          }
}
	
		


With the catch it will catch the sol::error and keep you in the console. Of course, it's so convenient to just hit CTRL+C to drop out of mame, but there are other ways, like manager:machine():exit()


Code
[MAME]> 
calling ret.get const char *
Caught exception:
lua: error: stack index 2, expected string, received nil
[MAME]> 

#111370 - 11/25/17 06:54 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Now that I've thought about for a bit, it's just getting a nil result from linenoise when you hit CTRL+C. The nil will cause the exception so why not look for that in plugins/console/init.lua:

The linenoise reading code:

Code
local scr = [[
local ln = require('linenoise')
ln.setcompletion(function(c, str, pos)
	status = str .. "\x01" .. tostring(pos)
	yield()
	ln.addcompletion(c, status:match("([^\x01]*)\x01(.*)"))
end)
return ln.linenoise('\x1b[1;36m[MAME]\x1b[0m> ')
]]



so instead of just returning the value from ln.linenoise, we'll check it for NIL and if so, convert it to the empty string.

Code
local scr = [[
local ln = require('linenoise')
ln.setcompletion(function(c, str, pos)
	status = str .. "\x01" .. tostring(pos)
	yield()
	ln.addcompletion(c, status:match("([^\x01]*)\x01(.*)"))
end)
local lnresult = ln.linenoise('\x1b[1;36m[MAME]\x1b[0m> ')
if lnresult == nil then print ("NIL result") lnresult = "" end
return lnresult
]]


#111382 - 11/26/17 10:18 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
Or how about ask the user if they'd like to exit.

If so, then pass a nil result through.

Code
local lnresult = ln.linenoise('\x1b[1;36m[MAME]\x1b[0m> ')
if (lnresult == nil) then 
  lnresult = "" 
  io.write("CTRL+C detected: are you sure you want to exit?") 
  if io.read() == "y" then lnresult = nil end 
end
return lnresult
]]

#111501 - 12/04/17 12:29 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child]  
Joined: Feb 2014
Posts: 134
Golden Child Offline
Senior Member
Golden Child  Offline
Senior Member

Joined: Feb 2014
Posts: 134
So a couple of things I was trying to figure out,
1. how to print to another text console, and
2. how often register_periodic will call a routine.


So how to send lua print output to another text console.

I would get lots of output information that would mess up my command line, so why not send it to another window?

On ubuntu 17.10, you can launch an xterm with a command line like:
Code
xterm -e "tty;cat" &

So it executes the program tty which prints something like "/dev/pts/3" on the top line which is the pseudoterminal assigned to the terminal and then executes cat. The & is to run it in the background so you get your console back.

I tried it with "gnome-terminal -- tty;cat" but it didn't seem to work, giving me some kind of error.

I launch mame with this command line:

Code
./mame64 a2600 stampede -plugin console -debug -window  2>/dev/pts/3


so the 2> redirects stderr to my freshly created xterm at /dev/pts/3.

and any error messages from lua goes to stderr and I can also print stuff directly with

Code
io.stderr:write("This goes to stderr\n")




I was trying to figure out how often a routine registered to emu().register_periodic would get called:

Code
function testperiodic() if not stopprint then if cycles == nil then cycles = 1 end io.stderr:write(" cycles="..(cycles).."  "..os.date().."\n") if cycles then cycles=cycles+1 end end end

-- same function on multiple lines:

function testperiodic() 
  if not stopprint then 
    if cycles == nil then cycles = 1 end 
    io.stderr:write(" cycles="..(cycles).."  "..os.date().."\n") 
    if cycles then cycles=cycles+1 end 
  end 
end

emu.register_periodic(testperiodic)


-- and when you want to stop the printing, set stopprint to true
-- stopprint=true


and you get output like:
Code
 cycles=1  Mon 04 Dec 2017 04:05:44 PM EST
 cycles=2  Mon 04 Dec 2017 04:05:44 PM EST
 cycles=3  Mon 04 Dec 2017 04:05:44 PM EST
 cycles=4  Mon 04 Dec 2017 04:05:44 PM EST
 cycles=5  Mon 04 Dec 2017 04:05:44 PM EST
 cycles=6  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=7  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=8  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=9  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=10  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=11  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=12  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=13  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=14  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=15  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=16  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=17  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=18  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=19  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=20  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=21  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=22  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=23  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=24  Mon 04 Dec 2017 04:05:45 PM EST
 cycles=25  Mon 04 Dec 2017 04:05:46 PM EST


And it looks like you get around 20 cycles per second.

And if you want other terminal output windows, you can use io.open like so:
Code
[MAME]> out2 = io.open("/dev/pts/4","w")
[MAME]> print(out2)
file (0x56300b8219b0)
[MAME]> out2:write("hello wont be seen until newline")
[MAME]> out2:write("hello\n")
[MAME]> out2:write("wont see me until flush")
[MAME]> out2:flush()


#112860 - 03/13/18 02:26 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: May 2012
Posts: 445
shattered Offline
Senior Member
shattered  Offline
Senior Member

Joined: May 2012
Posts: 445
Working on Apple disk support in SAMdisk -- this is a (probably cracked) Datasoft Conan disk. And it boots when converted into .DO image:

[Linked Image]

Code
[a140-023.scp]
35 Cyls Head 0:
cyl 32 head 0 sec 6: invalid gcr at 016 - A5 -> FF
cyl 32 head 0 sec 6: invalid gcr at 017 - 7B -> FF
cyl 32 head 0 sec 6: invalid gcr at 01E - 7F -> FF
cyl 32 head 0 sec 6: invalid gcr at 01F - D5 -> FF
cyl 32 head 0 sec 6: invalid gcr at 020 - 93 -> FF
cyl 32 head 0 sec 6: invalid gcr at 021 - A9 -> FF
250Kbps Apple, 16 sectors,  256 bytes/sector:
  0.0  5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4
  1.0  10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9
  2.0  14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13
  3.0  2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1
  4.0  7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6
  5.0  11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10
  6.0  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  7.0  4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3
  8.0  9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8
  9.0  13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12
 10.0  2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1
 11.0  6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5
 12.0  11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10
 13.0  15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
 14.0  4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3
 15.0  8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7
 16.0  13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12
 17.0  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0
 18.0  14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13
 19.0  2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1
 20.0  7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6
 21.0  11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10
 22.0  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
 23.0  4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3
 24.0  9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8
 25.0  13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12
 26.0  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0
 27.0  6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5
 28.0  11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10
 29.0  15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
 30.0  3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2
 31.0  8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7
 32.0  12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11
 33.0  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0
 34.0  5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4

#112861 - 03/13/18 02:44 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Mar 2001
Posts: 15,896
R. Belmont Online content
R. Belmont  Online Content

Very Senior Member

Joined: Mar 2001
Posts: 15,896
USA
Very nice!

#113096 - 04/11/18 11:04 AM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01]  
Joined: Oct 2015
Posts: 9
robj Offline
Member
robj  Offline
Member

Joined: Oct 2015
Posts: 9
Not to sure where to post this, but this seems like a good place.

One of the members of the Apple /// Facebook group, Madeleine, has noticed an issue in the Apple /// emulation when writing to floppy images. This was noticed when trying to use MAME to help speed up some A3 driver development. After a few operations writing to the disk, then some corruption happens and the disk image will not work anymore.

It is easily reproducable and looks like its been there for quite some time, the current 0.196 has it, and looks like back to 0.158, but 0.153 is ok.

You can test and reproduce with the following disk image:
http://www.apple3.org/Software/programming/basic/Apple3BusBasic.dsk

1. Boot the dsk image mounted as flop1
2. type 'load volumes' (read a basic program to save in)
3. repeat saving the same file many times 'save volumes1', 'save volumes2' ..etc
4. Error can occur after 1 or 2 times, or may take quite a bit more. Looks like you can get two things that happen when the write errors occur
- ?VOLUME NOT FOUND - then the disk directory blocks seem trashed, you can see this if you open up the dks image in ciderpress using the block viewer
- ?I/O ERROR - cannot save after this, but can do a CATALOG but this shows errors. Again, I think the directory sector is trashed some how.

I'm wondering if someone can have a look at why this might be happening?

/Robj

#113098 - 04/11/18 02:18 PM Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: robj]  
Joined: Apr 2012
Posts: 199
Pernod Online content
Senior Member
Pernod  Online Content
Senior Member

Joined: Apr 2012
Posts: 199
UK
Originally Posted by robj
It is easily reproducable and looks like its been there for quite some time, the current 0.196 has it, and looks like back to 0.158, but 0.153 is ok.

I don't think this is specific to the Apple or any particular format as I've also had BBC users reporting to me something similar. I have been able to replicate the issue myself with bbcb and a ssd format floppy and it seems to insert an extra byte after the first sector rendering the image corrupt. Haven't yet investigated further as it seems core floppy image related.


BBC Model B, ATPL Sidewise, Acorn Speech, 2xWatford Floppy Drives, AMX Mouse, Viglen case, etc.
Page 1 of 14 1 2 3 13 14

Who's Online Now
6 registered members (Stick, R. Belmont, Praxis, Pernod, gerbilsrcute, 1 invisible), 22 guests, and 3 spiders.
Key: Admin, Global Mod, Mod
Shout Box
Forum Statistics
Forums9
Topics8,525
Posts111,251
Members4,792
Most Online225
May 26th, 2014
Powered by UBB.threads™ PHP Forum Software 7.6.0
Page Time: 0.163s Queries: 14 (0.019s) Memory: 6.3753 MB (Peak: 7.7079 MB) Zlib enabled. Server Time: 2018-04-20 18:23:21 UTC