Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dusted off an old emu project and spiced it up

11 views
Skip to first unread message

Steve Nickolas

unread,
Feb 6, 2010, 6:29:20 PM2/6/10
to
I dug up a simple little emulator I wrote 6 years ago called "fruit2" and
started hacking on it again. Before long I changed it from a very simple,
no-ui 48K Apple ][+ emu to a 64K ][+ emu with a command line interface,
activated by F10, and a macro feature like ApplePC's (which I use a LOT, to
import files from the outside world).

I got a lot of work to do still to make this really of any use, but I'm
considering what I could add to it:

1. The option to use SDL mode for video and/or sound, or simply to use
NCurses (as already). Possibly use Dapple 1.42 code for the video, and
emu2/sddapple code for the sound.
2. A better command mode. Possibly also file dialogs (I *could* pipe zenity
but that sounds ugly).
3. Apple //e emulation using the Dapple source as a guide.
4. Built-in file import/export (I have support for export from DOS 3.3 in a
standalone tool).
5. Virtual filesystem?

Dunno what I'm going to do with it yet. http://usotsuki.info/fruit-0.11.zip

(Keep in mind there could be some linuxisms here. It uses ncurses and
readline, I don't THINK it does anything linuxy but it might not work well
outside of Linux. Also, it uses underscore for flash - which, for the
cursor, is remarkably effective!)

johnsonlam

unread,
Feb 8, 2010, 2:11:36 AM2/8/10
to

Remember your DAPPLE and EMU][?

Steve Nickolas

unread,
Feb 8, 2010, 10:49:25 AM2/8/10
to

If you look at it you'll notice the CPU core and the disk code are the same.
Fruit was, at core, just a way stripped-down version of Dapple made to run
under NCurses.

I'm planning to import the Dapple 1.42 video code, port it to SDL, and use
that along with the EMU][ SDL sound code (which is also in SDDapple). I'll
prolly need to study Dapple and the prototype for EMU][ as well, to recall
how the hell I got Apple //e emulation working (it's been the better part of
a decade!)

The interface for Fruit is a command line because that's what was easiest
for me to code. It's a little clumsier than Dapple's interface but more
powerful (though it lacks the biggest feature of EMU][, the macro assembler,
because I can't write a very good one - I do have a 65C02 assembler of my
own, but it's awful!). It fixes some of the issues I've had with the cpu
core, and addresses the things I felt were lacking in the other emulators.
So basically - once I import Dapple's video core, SDDapple's audio core, and
//e support, this will be potentially better than any of my other emus, and
I might also add in unfinished parts of the EMU][ project, and redesign the
UI again so that (like NDapple, EMU][ and SDDapple) it doesn't have to keep
turning off the screen.

I have been focusing on the CLI. The most important pieces of Fruit in the
not-yet-released 0.13, some of which are in the 0.11 and 0.12 versions
(follow the filename and adapt it) are bload/brun pg2 (which all my
emulators have), bsave pg2 (it works kind-of like debug.com), load/run/save
fp (which never worked right in older emus but does work here, and quite
well), gosub emu (return on keypoll), and keyboard macro files (like
ApplePC). A lot of this is tied to my own personal needs - these tricks are
the quickest ways for me to import code into the emulation.

-uso.

BluPhoenyx

unread,
Feb 9, 2010, 3:34:49 AM2/9/10
to lyricalnanoha
To: lyricalnanoha

lyricalnanoha wrote:
>
> If you look at it you'll notice the CPU core and the disk code are the same.
> Fruit was, at core, just a way stripped-down version of Dapple made to run
> under NCurses.
>

It would have interesting if none of the emulators had a built in
interface and could be loaded on demand from a single application.

Looking forward to your next release.


Cheers,
Mike T

Steve Nickolas

unread,
Feb 9, 2010, 11:22:45 AM2/9/10
to

Still working on it, though I'm feeling like a doof because my current goal
is eluding me even though I have gotten there already.

I'm working on 0.14, which I am intending to have Apple //e support. (It's
there but it barely works.) At the point AppleWorks is able to run I will
call it 0.20. (ProDOS doesn't boot on the //e yet, only the ][+.) I am
using information from Dapple, some of which I have written and some of
which I have not written. Dapple does work. It appears to be issues with
my banking code:

http://usotsuki.hoshinet.org/fruit_iiefail1.png

First goal is that I get FrEdWriter working, then Appleworks booting. After
that, I'll work on an SDL graphics mode (using as my base the Dapple 1.42
code).

There really isn't that far to go before it can do anything Dapple could.
It's just a lot more complex now, and I've started to get frustrated at
myself because I've been starting to lose my edge.

-uso.

BLuRry

unread,
Feb 9, 2010, 3:27:53 PM2/9/10
to
On Feb 9, 10:22 am, lyricalnan...@dosius.ath.cx (Steve Nickolas)
wrote:

Oh, I've been in this boat a bit. The memory softswitches are a total
pain in the neck to get 100% right. Nick had to pull me out of a
ditch over the same thing! Sather captures everything correctly, but
some of the terminology used is a bit dense and in a few cases leads
to some double-negatives that can trip you up if you are following it
closely. Check out the source tree for Jace in sourceforge -- I got
the 128k emulation and all softswitches laid out in there, as well as
abstracted out how the memory model bankswitching reacts to it. I
tried to emulate the logic of the MMU directly so it could be a
reference to anyone needing it.

jace.apple2e.SoftSwitches is an enumeration that identifies all
softswitches, their set/clear addresses and their read addresses (if
any). E.g.:
_80STORE(new MemorySoftSwitch("80Store", /*off*/ 0x0c000, /* on */
0x0c001, /* poll */ 0x0c018, RAMEvent.TYPE.WRITE, false)),
AUXRD(new MemorySoftSwitch("AuxRead", 0x0c002, 0x0c003, 0x0c013,
RAMEvent.TYPE.WRITE, false)),
AUXWR(new MemorySoftSwitch("AuxWrite", 0x0c004, 0x0c005, 0x0c014,
RAMEvent.TYPE.WRITE, false)),
CXROM(new MemorySoftSwitch("IntCXROM", 0x0c006, 0x0c007, 0x0c015,
RAMEvent.TYPE.WRITE, false)),
AUXZP(new MemorySoftSwitch("AuxZeroPage", 0x0c008, 0x0c009,
0x0c016, RAMEvent.TYPE.WRITE, false)),
SLOTC3ROM(new MemorySoftSwitch("C3ROM", 0x0c00a, 0x0c00b, 0x0c017,
RAMEvent.TYPE.WRITE, false)),
... and so on.

The odd ball is INTC8rom which is disabled by any access to Cfff and
set by any access to c3xx if SLOTC3Rom is off.

jace.apple2e.RAM128k represents the memory model and has a method
named "configureActiveMemory" which illustrates how active pages for
read and write are determined by softswitches. fillBanks maps blocks
of memory as needed to their preferred locations, set maps a single
page of ram/rom and setBanks maps chunks of memory as indicated
(convenience method to keep code tidy). I should explain the memory
model is dynamically re-mapped, so that during normal reads/writes
there is no conditional logic required to address the correct byte
requested.

public void configureActiveMemory() {
// First off, set up read/write for main memory (might get
changed later on)
activeRead.fillBanks(SoftSwitches.AUXRD.getState() ?
auxMemory : mainMemory);
activeWrite.fillBanks(SoftSwitches.AUXWR.getState() ?
auxMemory : mainMemory);

// Handle language card softswitches
activeRead.fillBanks(rom);
//activeRead.fillBanks(cPageRom);
for (int i = 0x0c0; i < 0x0d0; i++) {
activeWrite.set(i, null);
}
if (SoftSwitches.LCRAM.getState()) {
if (SoftSwitches.AUXZP.getState()) {
activeRead.fillBanks(languageCard);
if (!SoftSwitches.LCBANK1.getState()) {
activeRead.fillBanks(languageCard2);
}
} else {
activeRead.fillBanks(auxLanguageCard);
if (!SoftSwitches.LCBANK1.getState()) {
activeRead.fillBanks(auxLanguageCard2);
}
}
}

if (SoftSwitches.LCWRITE.getState()) {
if (SoftSwitches.AUXZP.getState()) {
activeWrite.fillBanks(languageCard);
if (!SoftSwitches.LCBANK1.getState()) {
activeWrite.fillBanks(languageCard2);
}
} else {
activeWrite.fillBanks(auxLanguageCard);
if (!SoftSwitches.LCBANK1.getState()) {
activeWrite.fillBanks(auxLanguageCard2);
}
}
} else {
// Make 0xd000 - 0xffff non-writable!
for (int i = 0x0d0; i < 0x0100; i++) {
activeWrite.set(i, null);
}
}

// Handle 80STORE logic for bankswitching video ram
if (SoftSwitches._80STORE.isOn()) {
activeRead.setBanks(0x04, 0x04, 0x04,
SoftSwitches.PAGE2.isOn() ? auxMemory :
mainMemory);
activeWrite.setBanks(0x04, 0x04, 0x04,
SoftSwitches.PAGE2.isOn() ? auxMemory :
mainMemory);
if (SoftSwitches.HIRES.isOn() ) {
activeRead.setBanks(0x020, 0x020, 0x020,
SoftSwitches.PAGE2.isOn() ? auxMemory :
mainMemory);
activeWrite.setBanks(0x020, 0x020, 0x020,
SoftSwitches.PAGE2.isOn() ? auxMemory :
mainMemory);
}
}

// Handle zero-page bankswitching
if (SoftSwitches.AUXZP.getState()) {
// Aux pages 0 and 1
activeRead.setBanks(0, 2, 0, auxMemory);
activeWrite.setBanks(0, 2, 0, auxMemory);
} else {
// Main pages 0 and 1
activeRead.setBanks(0, 2, 0, mainMemory);
activeWrite.setBanks(0, 2, 0, mainMemory);
}

/*
INTCXROM SLOTC3ROM C1,C2,C4-CF C3
0 0 slot rom
0 1 slot slot
1 - rom rom
*/
if (SoftSwitches.CXROM.getState()) {
// Enable C1-CF to point to rom
activeRead.setBanks(0, 0x0F, 0x0C1, cPageRom);
} else {
// Enable C1-CF to point to slots
for (int slot = 1; slot <= 7; slot++) {
Card c = getCard(slot);
if (c != null) {
// Enable card slot ROM
activeRead.setBanks(0, 1, 0x0C0 + slot,
c.getCxRom());
if (getActiveSlot() == slot) {
activeRead.setBanks(0, 8, 0x0C8,
c.getC8Rom());
}
}
else {
// Disable card slot ROM (TODO: floating bus)
activeRead.set(0x0C0 + slot, blank.get(0));
}
}
if (getActiveSlot() == 0) {
for (int i = 0x0C8; i < 0x0D0; i++) {
activeRead.set(i, blank.get(0));
}
}
if (SoftSwitches.SLOTC3ROM.isOff()) {
// Enable C3 to point to internal ROM
activeRead.setBanks(2, 1, 0x0C3, cPageRom);
}
if (SoftSwitches.INTC8ROM.getState()) {
// Enable C8-CF to point to internal ROM
activeRead.setBanks(7, 8, 0x0C8, cPageRom);
}
}
// All ROM reads not intecepted will return 0xFF! (TODO:
floating bus)
activeRead.set(0x0c0, blank.get(0));
}


-B

Steve Nickolas

unread,
Feb 9, 2010, 8:58:15 PM2/9/10
to
I think what would be useful to me is an "exerciser", which is able to point
out any specific issues with the banking, and with function calls not doing
what they should. Something more specific and more verbose than the
Opt-Ctrl-Reset tests.

http://usotsuki.info/fruit.htm - put up a page to reduce some of my needless
posts here.

-uso.

BLuRry

unread,
Feb 10, 2010, 10:10:50 AM2/10/10
to
On Feb 9, 7:58 pm, lyricalnan...@dosius.ath.cx (Steve Nickolas) wrote:
> I think what would be useful to me is an "exerciser", which is able to point
> out any specific issues with the banking, and with function calls not doing
> what they should.  Something more specific and more verbose than the
> Opt-Ctrl-Reset tests.

Understood -- it's looking for a needle in a haystack for sure. You
can do some tests from the monitor if you know what you're looking
for. I validated my emulator self-tests work (from monitor: c007:00
then c600g), so the logic I pasted shouldn't lead you too astray at
the worst case (i hope? :-) ) Prodos and 80-col firmware don't work
until everything is 100% right -- and in some cases it's a matter of
ensuring that the switches are set correctly at power-up.

> http://usotsuki.info/fruit.htm- put up a page to reduce some of my needless
> posts here.

Good luck!

-Brendan

Steve Nickolas

unread,
Feb 11, 2010, 6:59:47 PM2/11/10
to
Replying to myself.

I was looking at this: http://support.apple.com/kb/TA38047?viewlocale=en_US

MMU FLAG E4:
0 The Read Lang Card Bank0 switch didn't initialize properly during reset.
6 The 80STORE switch didn't initialize properly during reset.

Only thing is they do exactly what Dapple does, so it should work like
Dapple...

void memcpureset (void)
{
lc_rbank=lc_wbank=LC_ROM;
if (iie)
{
slotc3=iou=ann3=128;
mostxt=intcxrom=lcaux=auxread=auxwrite=store80=0;
}
}

Still digging around.

-uso.

Steve Nickolas

unread,
Feb 11, 2010, 9:07:57 PM2/11/10
to
Replying to myself again.

Steve Nickolas wrote:
> MMU FLAG E4:
> 0 The Read Lang Card Bank0 switch didn't initialize properly during reset.

After studying this further, I figured that my emulation was slightly off
here (it interpreted "bank2?" to mean "is bank2 currently readable?", which
wasn't quite correct), and fixed it.

> 6 The 80STORE switch didn't initialize properly during reset.

This error remains.

ProDOS version 1.0.2 and earlier are capable of running on version 0.15 in
//e mode; 1.1 is untested, 1.1.1 hangs. Some software on ProDOS is borking
too. PUD reports it as a 64K //e, as does MECC Computer Inspector.

-uso.

BluPhoenyx

unread,
Feb 11, 2010, 10:23:45 PM2/11/10
to lyricalnanoha
To: lyricalnanoha

As long as your posts are on topic and so far they have been, there is
no reason for you to not post them here. In fact there are a number of
reasons that you should do so. A few that come to (my) mind,

They are related to Apple II and/or emulation of these machines.

Your questions generate some interesting discussions regarding II
emulation.

It generates more traffic in this group.

Your emulator has some very interesting possibilities.

Keep up the good work!

Cheers,
Mike T

Steve Nickolas

unread,
Feb 11, 2010, 11:24:11 PM2/11/10
to

I just always feel like I'm crapflooding by tooting my own horn so much
around here.

I've started to surpass my last emulator already. SDDapple could never do
Apple //c. SDDapple's //e emulation didn't get as far along as fruit2. I
have a goal in mind of portability, and if I can finally ditch that crusty
old ApplePC emulator (from 1996!) that I've clung to for over a decade,
that's one less thing requiring me to have DOSEMU installed on this beast.
I didn't get far enough with Dapple, I couldn't do anything with EMU][
(didn't have enough of the source), and every attempt I'd made since then
had me beating my head against a wall, but I dug this out of cold storage,
and I think I might finally have a winner.

-uso.

BLuRry

unread,
Feb 12, 2010, 12:19:09 AM2/12/10
to
> >>http://usotsuki.info/fruit.htm- put up a page to reduce some of my

> >> needless
> >> posts here.
>
> > As long as your posts are on topic and so far they have been, there is
> > no reason for you to not post them here. In fact there are a number of
> > reasons that you should do so. A few that come to (my) mind,
>
> >    They are related to Apple II and/or emulation of these machines.

Indeed, and really what you're running in to is a good dialog of what
pitfalls one can expect along the way when working on this stuff. I
felt the same way when I was working on Jace a couple of years back,
and again when I was working on Apple Game Server. But really, I
found out that the conversations sparked other more interesting
conversations. (e.g. ADTPro and Applewin adopted some rather
interesting features as a result of community conversations on these
topics.)

> >    Your emulator has some very interesting possibilities.

Indeed. A virtual machine that acts like a regular commandline
program. Would be trivial to convert ncurses to VT100.

> I just always feel like I'm crapflooding by tooting my own horn so much
> around here.

Yeah, me too. But nobody's flamed me for it yet. (ducks under table)

> I've started to surpass my last emulator already.  SDDapple could never do
> Apple //c.  SDDapple's //e emulation didn't get as far along as fruit2.  I
> have a goal in mind of portability, and if I can finally ditch that crusty
> old ApplePC emulator (from 1996!) that I've clung to for over a decade,
> that's one less thing requiring me to have DOSEMU installed on this beast.

Kegs is pretty easy to tinker with -- which I had to do when building
out the TCP/IP support for Apple Game Server. But I understand what
you mean about wanting to add hardware support and portability. I
spent probably a month off and on just building out the core concepts
of my emulator before I even started on the Apple // hardware
emulation aspects of it. 65c02 emulation kicked my ass for quite a
bit (especially getting the decimal mode just right, dealing with the
overflow flag, and IRQ support). The MMU flags were especially
tricky, and it takes everything to get them working just so the 80-
column firmware can be emulated properly.

A lot of that machine detection deals out softswitch flipping AND
going back and reading the state of those switches, as well as looking
for key bytes in ram. For example, one such detection might swap out
Language Card ROM with some RAM and try writing to and reading from to
see if anything happens. I can fiddle with my emulator and produce
debug output to let you know what softswitches get set/cleared/read
and what location in RAM is making the request if it provides useful
data for you to work from.

-Brendan

Keep up the great work!

-Brendan

Steve Nickolas

unread,
Feb 12, 2010, 8:23:14 AM2/12/10
to
BLuRry wrote:
>> >>http://usotsuki.info/fruit.htm- put up a page to reduce some of my
>> >> needless
>> >> posts here.
>>
>> > As long as your posts are on topic and so far they have been, there is
>> > no reason for you to not post them here. In fact there are a number of
>> > reasons that you should do so. A few that come to (my) mind,
>>
>> > � �They are related to Apple II and/or emulation of these machines.
>
> Indeed, and really what you're running in to is a good dialog of what
> pitfalls one can expect along the way when working on this stuff. I
> felt the same way when I was working on Jace a couple of years back,
> and again when I was working on Apple Game Server. But really, I
> found out that the conversations sparked other more interesting
> conversations. (e.g. ADTPro and Applewin adopted some rather
> interesting features as a result of community conversations on these
> topics.)

And it's possible that AppleWin picked up Z80 emulation as a result of me
talking about adding it to emu2.

>
>> > � �Your emulator has some very interesting possibilities.


>
> Indeed. A virtual machine that acts like a regular commandline
> program. Would be trivial to convert ncurses to VT100.

While I will be working on a GUI mode for the emulator, I will most likely
leave the ncurses implementation intact - and allow either one to be used.
MPlayer has many video and audio back ends, which has inspired me to attempt
the same here. (e.g., depending on how compiled, the current version has
"none", "timebeep", "sdl" and "direct" sound drivers. "direct" only works
on DOS.)

>> I just always feel like I'm crapflooding by tooting my own horn so much
>> around here.
>
> Yeah, me too. But nobody's flamed me for it yet. (ducks under table)

I guess it's me being afraid of being compared to comp.os.cpm regular
Emmanuel Roche (aka French Luser).

> Kegs is pretty easy to tinker with -- which I had to do when building
> out the TCP/IP support for Apple Game Server.

I'm led to understand the sdl code can be traced to KEGS. (Fortunately
there's no license issue - fruit was always gpl2, KEGS is gpl2)

> But I understand what
> you mean about wanting to add hardware support and portability.

Linux is a second-class citizen in emulation land. If done right, though,
my project should work on DOS, Win32, Linux and OSX, and prolly a host of
other systems too (Dapple 1.25 and earlier and most versions of EMU2 were
DOS only; the last EMU2 release was DOS/Windows; Dapple 1.4x could run on
DOS, Linux and NetBSD and prolly Windows too.)

> I spent probably a month off and on just building out the core concepts
> of my emulator before I even started on the Apple // hardware
> emulation aspects of it. 65c02 emulation kicked my ass for quite a
> bit (especially getting the decimal mode just right, dealing with the
> overflow flag, and IRQ support).

I've been using, basically, two cpu cores for everything. Initially I used
a hacked version of Marat Fayzullin's M6502 with 65C02 support added from
Andrew Gregory's emulator. Holger Picker contributed a new cpu core to
Dapple and most of my Apple ][ emulators use that. (Most of my non-Apple
emulators still use the modified M6502.)

> The MMU flags were especially
> tricky, and it takes everything to get them working just so the 80-
> column firmware can be emulated properly.

It's still kicking my A. I figured out the "E4:0" error, but I got "E4:6"
(supposedly an 80STORE issue) now, an issue which plagues Dapple as well
(but not emu2).

> A lot of that machine detection deals out softswitch flipping AND
> going back and reading the state of those switches, as well as looking
> for key bytes in ram. For example, one such detection might swap out
> Language Card ROM with some RAM and try writing to and reading from to
> see if anything happens. I can fiddle with my emulator and produce
> debug output to let you know what softswitches get set/cleared/read
> and what location in RAM is making the request if it provides useful
> data for you to work from.

Perhaps. I was doing some testing with 80STORE on ApplePC and Fruit and
that turned up nothing, since I couldn't see any difference in observed
behavior between the two emulators.

5 HOME : PRINT
10 POKE 49153,23: POKE -16299,23: POKE 1024,0: POKE -16300,23: POKE
49152,23: POKE 1024,1
15 PRINT "PRESS ANY KEY TO CONTINUE ";: GET A$
20 POKE 49153,23: POKE -16299,23:X=PEEK (1024): POKE -16300,23:Y=PEEK
(1024): POKE 49152,23:Z=PEEK (1024): POKE 49153,23:A=PEEK (1024): POKE
49152,23: PRINT X,Y,Z,A

(the visual output could not be tested, but should be @A in the top left,
inverted, followed by "0 1 1 1")

> Keep up the great work!
>
> -Brendan

*^^*

-uso.

BLuRry

unread,
Feb 12, 2010, 12:16:21 PM2/12/10
to
> (the visual output could not be tested, but should be @A in the top left,
> inverted, followed by "0 1 1 1")

Ah, took me a while to realize this requires 80 cols to be active.
Yes, this is the result I see in Jace. It leaves flags in an odd
state and causes prodos to crash -- but it does result in the output
you mentioned.

-Brendan

Steve Nickolas

unread,
Feb 12, 2010, 2:07:42 PM2/12/10
to

And ApplePC, which Does The Right Thing, also makes that output. So I'm
stumped.

The primary goal for me at this point is to at least get the emulator to
pass the firmware diagnostics for the original //e. (The EDM doesn't have
any, and the E/P firmware passes.) Prolly by then ProDOS should work all
right.

I still wonder how hard it would be to emulate an emulator, specifically,
SimSystem IIe. If successful, it would completely save us the issue of
warezing ROMs (granted, I *have* a Platinum //e).

-uso.

Steve Nickolas

unread,
Feb 12, 2010, 11:51:15 PM2/12/10
to
I've been thinking again...I might consider whether it might be feasible to
build up a translator of some sort to emulate a C. Itoh 8510/Apple
ImageWriter printer?

-uso.

johnsonlam

unread,
Feb 23, 2010, 12:36:44 AM2/23/10
to
On Feb 13, 12:51 pm, lyricalnan...@dosius.ath.cx (Steve Nickolas)
wrote:

> I've been thinking again...I might consider whether it might be feasible to
> build up a translator of some sort to emulate a C. Itoh 8510/Apple
> ImageWriter printer?

A little suggestion, if the core is stable enough, adding printer
support is a good idea.

There's lot of code you can reuse, Applewin got a lot of existing code
can be a reference.

Hope you EMU will be ready for trial soon.

Steve Nickolas

unread,
Feb 23, 2010, 3:08:49 AM2/23/10
to

Printer support itself is trivial. But translating input using C. Itoh
escape sequences to graphics is not.

I'm still thinking of how I could get the best results of Apple //e
emulation again, as well as the graphics. I wish I were better at
understanding *other people's code*...

-uso.

0 new messages