Subject: Checksum Conundrum

From: "FyberOptic" <fyberoptic@...>
Date: Fri, 15 Jan 2010 19:10:00 -0000

As recently discovered, the Mailstation emulator seems to be returning a different checksum value for the firmware than what you get on the real hardware.  I've been digging through the disassembled code, trying to figure out why.

From what I can tell, the firmware does a checksum of each 16K page of the codeflash (just adding all the bytes together), then adds it to an overall total as it goes through each page.  I made a simple C util to mimic this, printing out the current and total checksums for each iteration of the loop.  I then also set a trace (via the emulator) on the address in the v2.53 firmware where the addition takes place, so that I could see both the current checksum and total checksum in its CPU registers.  Each loop iteration's values match in both the firmware and my util.  Final checksum values also match.

So, unless I've missed something, which is seeming less likely the more I dig into the overall checksum function, then it's looking like it might not be an emulator issue.  If this is the case, then what could possibly be the cause of two different people dumping two different firmware versions with incorrect checksums?

If anyone has a way to debug this in the actual hardware, that'd be even more helpful.  In v2.53, the checksum function starts in page 2 (if you start at 0), at 0x5e2c.  This all calls on 0x2731 in page 0 to do the checksum of each page.  The addition of each page checksum into the total happens at 0x5e79 (I was tracing at 0x5e7a after the addition took place).  

Dunno if there's anyone still here who can do hardware debugging, but it's worth a shot!

---

From: "cyranojones_lalp" <cyranojones_lalp@...>
Date: Fri, 15 Jan 2010 23:59:17 -0000

--- In [email-masked], "FyberOptic" <fyberoptic@...> wrote:
> From what I can tell, the firmware does a checksum of each 16K page of the codeflash (just adding all the bytes together), then adds it to an overall total as it goes through each page.  

That sounds like what I remember, but what I don't get is,
64 pages x 255 max value an 8 bit byte can hold = 0x3fc0 max
value the checksum could be.  Seems like both the hardware
and emulator are getting higher values!!!  I guess I
need to take a look at that calc.  

From the values both you and I got last week, the
diff between hardware and emulated was 0x0011 & 0x0055,
IIRC.  I find it curious that the differences are
so low, and one is exactly 5x the other.

> I made a simple C util to mimic this, printing out the current and total checksums for each iteration of the loop.  I then also set a trace (via the emulator) on the address in the v2.53 firmware where the addition takes place, so that I could see both the current checksum and total checksum in its CPU registers.  Each loop iteration's values match in both the firmware and my util.  Final checksum values also match.

I assume you mean you ran  the test on PC (without emulator).
Can you run it on the mailstation hardware?
 
> So, unless I've missed something, which is seeming less likely the more I dig into the overall checksum function, then it's looking like it might not be an emulator issue.  If this is the case, the…

If the code in hardware mailstation matches the code emulator
is running, and gives different results, it seems it has to be
a problem in emulator, or maybe the z80 emulation.

For what it is worth, last few days I have been messing with
trying to run an app on emulator, without much success.

One problem I found is the mailstation apparently only
uses the low 4 bits of the "device" byte, and when
accessing "apps" from dataflash, it uses one of the high
4 bits of device as a flag.  I added a printf to emulator,
and the device is sometimes "0x13" when accessing apps.
I added "& 0x0f" to the address calc in emulator, but I
still was not able to run an app.  Without the "& 0x0f"
it the emulation locked up, and with it, it reboots.

I decided I wanted to step thru the code, and since the
"docs" for z80em (and I use the term "doc" very loosely 
here) mentioned a built in debugger, I set out to try
to enable it.  Unless I am missing something here,
there is not really a debugger, rather just a "trace",
and you can set the address you want to start tracing
at.  The trace is not very helpful, unless you can
actually see it, and it flys by faster than the retrace
on my monitor can keep up with.

Have you tried to use it???  Maybe I missed something?
I did not see any way to single-step.

I imagine I could redirect trace to a file, but I did not
do that yet.  I have been wondering if it would be
worth the trouble to add some real debug capability,
or if it would be easier to use a different emulator
that already had one.  (MAME/MESS comes to mind, but I
have zero experience with it.)

> Dunno if there's anyone still here who can do hardware debugging, but it's worth a shot!

It's been quite a few years now since I had that stuff set up.
I still have the modded mailstation, but I am sure a wire or
two has come loose.  I would like to be able to set it
up, but I have a severe lack of empty horizontalness here.
And, prolly the main holdup, I don't use the computer it
ran with anymore.  I had started to do a new version of
the "mailbug" stuff, that ran on XP, but I never finished
it.  I would like to resurrect it, and get it running on
Linux now, just have not had time.

CJ

---

From: "FyberOptic" <fyberoptic@...>
Date: Sat, 16 Jan 2010 07:50:49 -0000

> need to take a look at that calc.  

Well see, for each page it's just adding each individual byte together to a 16-bit value.  For example, if every byte was 0xFF, you'd end up with a page total of 4,177,920 (16384 bytes in page * 255).  But since it's 16-bit it wraps around several times (you'd get a value of like 49,152 instead).  That resulting page value is then added to the overall checksum value each time through the loop, so the total checksum also wraps many times.  So the checksum could be any 16-bit value.

> Can you run it on the mailstation hardware?

Yeah the test app was a standalone program on the PC, which did a checksum of whatever firmware file I specified on the command line.  On the Mailstation side, I was letting it do its normal checksum routine from the test menu, but had a trace set on a particular address in that function so I could witness each addition operation during the checksum calculation.

> a problem in emulator, or maybe the z80 emulation.

My assumption was that the code quite possibly didn't match between the emulator and hardware.  I especially started thinking this when my standalone utility was giving me the same checksum as the emulator.

> it the emulation locked up, and with it, it reboots.

I'd be curious to try that app out myself to see if I can figure out what the problem is.

> I did not see any way to single-step.

What I did was recompile z80em with debug enabled.  I then added a command-line switch to specify a breakpoint address, which I set into the Z80_Trace variable.  When the emulator hits the address, my debug function prints the page/device, prints the registers and some stack, dumps the ram to a file, and gives me a basic prompt on the console window.  I can hit enter to progress line by line, or hit C to continue with emulation (until it hits the breakpoint again).  Unfortunately it doesn't display the assembly code instruction when stopped, which I don't think is even possible using this emulation core (though libz80 could!).  But it was fine for my purposes.  I knew what lines were what based on the disassembled source in my text editor.  I just needed to see register values and ram.

Still can't peek/poke memory or I/O or anything like that, but it shouldn't be hard to add at this point.  This will all be in the next version I release I guess, whenever it gets cleaned up.  I've been poking a bunch of junk in for my own purposes as of late.

I may modify the z80em core to be capable of multiple breakpoints too, which would be useful.  And I can probably do memory and I/O breakpoints in the normal handler functions for those.

> have zero experience with it.)

Z80em should be fine with maybe some minor updates.  I can write in a function to decypher the next opcode to text myself if I want a more advanced debugger, it'll just take a little work.

So, now to what I've done since my last post.  After digging for ages trying to find my laplink/interlink cable again just to send code to the Mailstation (I put things where I'll remember them later, then forget where I put them), I wrote a Mailstation test program to work very similar to the one I wrote on my PC.  It does the checksum of a codeflash page, displays the value of that, along with the current total checksum value, looping through all 64 pages (with a pause between each one).  I'm still using a checksum function from the firmware to do this, which is 0x2731 in v2.53, and 0x2724 in v3.03a.  No need to rewrite something so small when it's easy to see exactly what it does in the disassembly.  It's called from the larger function which calculates the total firmware checksum.  

Anyhow, with this, I was able to match up page checksums displayed on the Mailstation screen to the ones from my PC equivalent of the program (not in the emulator, mind you).  From a glance, it seemed like the page checksums all matched, until it got to the end.  I then saw the same alternate total checksum value that I get in the maintenance tests on the hardware.

So I increased the delay between outputs so that I could confirm each individual page checksum.  It started out good, until it got to page 17.  Instead of 0x7c6e which I get on the PC, I got 0x7c5D.  But then, oddly, all the rest of the pages matched up perfectly.  So only page 17 had the problem.  That's the 0x11 byte difference in the overall checksum I was getting between hardware and emulator.  

This shows that it's apparently not the emulator after all, and is something different between the firmware and my dump of it.

Next step is to redump just page 17 to my computer and see if transfers wrong again, but that'll take more assembly code, and I'm off to bed for now.  Yet I have a feeling I'm going to get the same alternate version of the page, in which case I'm going to have to break that page down into pieces to see what's going on.  We'll see.

---

From: "randy129" <randy129@...>
Date: Wed, 20 Jan 2010 00:14:15 -0000

--- FyberOptic wrote:
>
> --- cyranojones_lalp wrote:
> > 

> Well see, for each page it's just adding each individual byte together 

Yeah.  I jumped to conclusion that "checksum8" was returning 8 bit checksums.
 
> I'd be curious to try that app out myself to see if I can figure out what the 

I got it working.  :-)

I'll post some stuff soon, but helloapp.rom is in file area.
Just paste it into your dataflash image with a hex editor,
and tweak the "app directory" in page 8.

The app I was having trouble with is a sort of frankenstein
app, with a bunch of tests of various widgets from
the mailstation firmware.

Turns out it was a problem with sdcc linking the wrong putchar.
I don't remember doing it, but it probably happened a few months ago
when I was switching between various snapshots of sdcc.  I had
commented out the custom putchar in my makefile!!!  

I have not actually used sdcc for anything since feb 2008, but
I joined their mail list back in '07.  Since then, there have
been a few problems others were having 
(with the z80 port of sdcc), that I remembered having myself.  

One in particular was that -o just did not work
with the z80 linker.  I had learned to work around it myself,
and I even looked into fixing it, but never got to the bottom of it.

So, though I was not presently using sdcc, when yet another
was learning of this bug the hard way (~ Sept 2009), I took another
look at it.  This time I saw what the problem was,
and patched it.

In the process of testing, I was recompiling a mailstation app,
and I guess I got tired of deleting the "putchar" from sdcc's
z80 lib in various sdcc snapshot versions.  I knew at the time 
that the standard putchar would not work on the mailstation,
but since I was not actually gonna try to run the code (or so I 
thought!) it did not matter.  When I got done with the 
patch, I forgot to put the putchar back in my lib.

I don't really have a lot of experience with c libs, but I
seem to recall that the sdcc manual states that it will use
the version of a lib from the first place it finds it on the
lib search list.  IIRC, I had to remove the standard putchar,
but not getchar, to get my code to link.  Likewise with crt0.

Anyone care to comment on what the standard behaviour is in this
regard?  And by standard, I guess I mean "what does gcc do?".
 
> What I did was recompile z80em with debug enabled.  I then added a 
> command-line switch to specify a breakpoint address, which I set into 
> the Z80_Trace variable.  

That is essentialy what I did, too.

> When the emulator hits the address, my debug 
> function prints the page/device, prints the registers and some stack, 
> dumps the ram to a file, and gives me a basic prompt on the console window.  
> I can hit enter to progress line by line, or hit C to continue with 
> emulation (until it hits the breakpoint again). 

Sounds like you replaced the built in "Z80_Debug(Z80_Regs *R)" with
your own, 'coz the built-in one does *not* stop.

> Unfortunately it doesn't 
> display the assembly code instruction when stopped, 

Sounds like you replaced the built in "Z80_Debug(Z80_Regs *R)" with
your own, 'coz the built-in one *does* display the disassemled inst.

> which I don't think is 
> even possible using this emulation core (though libz80 could!).  

See one comment above.  ;-)

> But it 
> was fine for my purposes.  I knew what lines were what based on the 
> disassembled source in my text editor.  I just needed to see register 
> values and ram.
> 
> Still can't peek/poke memory or I/O or anything like that, but it shouldn't 
> be hard to add at this point.  

Nothing is "hard" about it, except maybe finding the time to do it.

> This will all be in the next version I release 
> I guess, whenever it gets cleaned up.  I've been poking a bunch of junk in 
> for my own purposes as of late.
> 
> I may modify the z80em core to be capable of multiple breakpoints too, 
> which would be useful.  And I can probably do memory and I/O breakpoints 
> in the normal handler functions for those.

Yeah, I made some changes to it myself, but I wonder if it might be
better to keep it "as is", and extend it on the msemu side.
One idea I had was to change how you call it, so it only executes
a single inst on every call (and of course mod the interrupt emulation
to compensate).

As far as the number of breakpoints, in my experience, the only
time I ever really needed more than one was when single stepping
over conditional branches, where you drop a breakpoint for both
possible "next" cases.  And that is only when debugging on hardware,
where you need to modify the code at the "breakpoints".  With an
emulated cpu, you don't need to do this, you can just execute a 
single instruction, and it will stop whichever way it branched.

<snip> 

> Next step is to redump just page 17 to my computer and see if transfers 
> wrong again, but that'll take more assembly code, and I'm off to bed for now.  
> Yet I have a feeling I'm going to get the same alternate version of the page, 
> in which case I'm going to have to break that page down into pieces to see 
> what's going on.  

Can't you just dump the whole rom again (with existing code)?

When you say 17, do you mean decimal 17, or 0x17?

CJ

---

From: "FyberOptic" <fyberoptic@...>
Date: Thu, 21 Jan 2010 19:58:02 -0000

> regard?  And by standard, I guess I mean "what does gcc do?".

I recently updated my SDCC as well and ran into this problem again.  All I do though is delete their version of putchar.o from the LIB then include my own version on the command line when I link a program (along with my custom crt0).  I could add it to their system library and all, but I like to keep my code separate from theirs.  If one regularly updates their SDCC from the snapshot, then it should be easy enough to make a script to take care of deleting putchar.o from their LIB automatically.

They don't use the SDCCLIB utility anymore for the system libraries, which threw me off a bit at first till I read the updated manual.  They use the standard binutils "ar" command now.  Though to create the index the normal "ranlib" doesn't work, so you have to use "asranlib" that comes with SDCC.

> your own, 'coz the built-in one does *not* stop.

Yeah Z80_Debug in the z80em header is just a placeholder, you have to create your own function to handle it.  

> a single inst on every call (and of course mod the interrupt emulation

Well, if you only want to execute one instruction at a time without modifying the z80em source, you could enable Z80_Trace, and then it calls your debug function regularly.  That just slows you down in the end, though, unless you're only using it during debugging.

> When you say 17, do you mean decimal 17, or 0x17?

I meant decimal 17.

I finally got around to redumping my codeflash.  As it turns out, I must have just had a bad dump all along.  On this one, my checksum utility now returns the same value as the emulator which also returns the same value as the hardware.  As for what's in page 17 where I was getting the checksum difference, I haven't looked.  I never had any problems out of my previous dump aside from that checksum, so maybe it was either code I was never executing or some graphical data or something.

I just never assumed it was a dump issue, because usually whenever those happened it threw the whole dump off (and then usually stopped just short of 100% of the total data).  I guess if I ever implement anything involving parallel port transfer (which I started writing into FyOS before), I'll definitely be including some kind of checksum on the data packets.

---

From: "cyranojones_lalp" <cyranojones_lalp@...>
Date: Fri, 22 Jan 2010 20:55:53 -0000

> I recently updated my SDCC as well and ran into this problem again.  
> All I do though is delete their version of putchar.o from the LIB 

In the older versions of SDCC, the libs were not archives, they just
had all the .o's in the lib directory.  I really did not want to get
sidetracked learning how to remove the putchar from the z80.lib
archive file.  So, I just commented mine out in the makefile for 
my library!

> then include my own version on the command line when I link a program 

I did take the time to learn how to make a library, and I can't find
where the instructions are now, but (~fall 2007, whatever version of
sdcc might have been current then) the info I found then suggested
just leaving the .o's in your lib's dir, and creating a .lib file 
in same dir, 
where this .lib was just a list of the .o filenames that make up your
library.

So, I created a library for mailstation apps, with putchar & getchar
(which I only use for debugging), and also a custom crt0 for 
mailstation apps.  Also the header and .s wrappers for the firmware
calls.  And a few other functions, like "triblink", etc.

The main thing different about crt0 for apps is I left the call
to gsinit out, because the app is not a standalone program, it
is just a single "eventhandler" function.  I let that eventhandler
call the gsinit for the app when it receives the "init" event
from the mailstation.  That way my globals don't get re-init
for every event, just once when app is "inited".

This is similar to a standard program calling gsinit as the
very first thing.  Just I don't want to call it every time code runs.

> (along with my custom crt0).  I could add it to their system library and all, 
> but I like to keep my code separate from theirs.  

Right, I like to keep mine separate, too.  

I really think they should remove the putchar, getchar, 
and crt0 from the z80 lib, because they are not 
appropriate for all z80 systems.  In fact they are only 
appropriate for whatever system the default code works on.  
(And just what system is it, anyways?????????)

Those 3 functions belong in a lib specific to a particular
system.  They should separate them out into z80.lib and
generic system_demo.lib.  Then it would be a lot clearer
what parts you needed to customise for your particular hardware.

I imagine *everyone* who uses sdcc needs to remove those 
from the system library.

I suppose most people are more familiar with programming
on a PC, where the people who create the lib can make
assumption that you are compiling for same type of system 
the compiler is running on, and those functions can be
part of the lib that comes with compiler.

I know I am used to taking that kind of stuff for granted.
I don't think I realized there was even any "startup"
code linked when on PC, but I guess it is standard (with
c at least???)  I suppose I always thought that whatever
it needed to set up, it did at the start of "main", before
my code.

After playing with sdcc, I took a look at avr-gcc, and 
it has startup code, too!  A different startup for each 
type of AVR chip.

> If one regularly 
> updates their SDCC from the snapshot, then it should be easy enough 
> to make a script to take care of deleting putchar.o from their LIB automatically.

I think that when I get farther up the sdcc learning curve
I will figure out how others are doing this.  I suspect that 
you are supposed to "install" even the snapshots, but I still 
don't know exactly how to tell it where.  And more important,
where it puts the library.  I don't want it to install in
the default location, because I want to have more than one
version available at same time, so I can just change 
SDCCPATH in my projects makefile, to pick which to use.

I thought I knew how to do this.  I was running the snap
from exactly where "make" put the bin's.  And I thought it
was using the right library, too.  But the snaps after
2.9.0 seem to not find the lib.  Actually, it seems it
is using the lib installed in usr/local/whatever, iow
the lib that installed with 2.9.0.

I'm *sure* the older versions were finding lib relative to
the executable.  I wish they would quit changing this stuff!  :-)

> They don't use the SDCCLIB utility anymore for the system libraries, which threw me off a bit at first till I read the updated manual.  They use the standard binutils "ar" command now.  Though to c…

It seems the old way still works, too, coz my lib is still working.
 
CJ

(I think Yahoo has a bug, where it grows blank lines at top
of your post every time you "preview".  I just deleted 3 or 4
lines, so this should be rammed right to top.  We'll see...)

---

From: "cyranojones_lalp" <cyranojones_lalp@...>
Date: Fri, 22 Jan 2010 21:33:09 -0000

> create your own function to handle it.

No, I didn't create one, I used the one in Z80Debug.c.

Did you find documentation that said you need your own?

From the comments in Z80Debug.c:

/*** This file contains a simple single step debugger which is called     ***/
/*** when DEBUG is #defined and Z80_Trace is true                         ***/

And it implements the function 

void Z80_Debug(Z80_Regs *R);

that is prototyped in Z80.h.

But I agree 110 percent that you need to create your own, coz this
one does not do what the comment says it does!!!

But It DOES disassemble the instructions.  It just does not stop,
it keeps going, pouring out the disassembly from the point that you set 
with the trap var.  I tried redirecting to a file, and you don't know
what fun IS until you have tried to open a 1.5 gigabyte text file!

And that was only running a second or so past the trap point.  I
knew it would be a large file, but this is ridiculous!

But I did find where my code went haywire and started executing
from the low address of 0000:0008.  There was a "rst 8" right
before that, and I checked the address of the function with
the rst 8 in in it, with the .map file, and it was putchar.  

That rst 8 looked mighty familiar at that point, just like 
the "standard" putchar!!!!  It all came back to me soon 
after that...

> Well, if you only want to execute one instruction at a time without modifying the z80em source, you could enable Z80_Trace, and then it calls your debug function regularly.  That just slows you dow…

Yeah, you could do it that way too, but then you need to leave out
Z80Debug.c that comes with z80em.

But if you just set the "Z80_IPeriod" to 0, then I think it will
single step, and you can handle it in msemu.  I don't know if
it is better, just how I think I would do it.  of course you
would need to mod the interrupt emulation, too. (iow, you
need to time them yourself, if z80em is now checking for
int after every instruction.) 

The way it is now, you *can't* get an interrupt except 
once every millisec.

That is probably good enough, though.  Particularly for the 
1 ms interrupt.  But when is the 1 sec int happening????  
Is it stealing one of the 1 ms ints on those cases????

What about other interrupts, like the ones you found for kbd &
power button????  I imagine 1 ms period is ok there too, but
it is not really an interrupt if it can only happen at a particular 
time.  Not that it really matters.  

Perhaps it will do all the pending interrupts on each 1 ms beat???
I'm not sure just how it is working now.

> I finally got around to redumping my codeflash.  As it turns out, I must have just had a bad dump all along.  On this one, my checksum utility now returns the same value as the emulator which also…

If you start at 0, and mean page 0x11, then it looks like it
is all related to address book functions, either the address
book app itself, or the address book functions in "inbox", "outbox", 
"create new", or "sent" apps.

> I just never assumed it was a dump issue, because usually whenever those happened it threw the whole dump off (and then usually stopped just short of 100% of the total data).  

So, you are saying it happens often?  ;^)

I still need to get to the bottom of my checksum "anomally".
I an using the data from the 253yr dump in file area, not my
actual 2.53yr mailstation.  I probably should get around to
making room to set up old pc, and dump actual code.  Or maybe
I need to figure out how to run it on Linux???  I can run
it under a dos emulator (for what it's worth, that pegs cpu 
at 100% too).  But I don't know how hard it is to get access 
to par port???  Maybe if I run as root?  heh heh heh!  

Everywhere I look, more learning curves.  And only one lifetime.  sniff.

> I guess if I ever implement anything involving parallel port transfer (which I started writing into FyOS before), I'll definitely be including some kind of checksum on the data packets.

I know it makes some cringe, but I did not put any checksum 
in the tribblelink code, and I never noticed a hiccup.  
Doesn't mean it didn't, but I never noticed any, and I 
was using it A LOT.  I was loading the ms firmware into RAM,
and verifying whenever I thought I should, and NEVER
was there a problem.  And all the commands to mbug
went over it.  Heck, even mbug got loaded over it!!!
[ouch, I think I dislocated my shoulder...]

CJ

---

From: "FyberOptic" <fyberoptic@...>
Date: Sat, 23 Jan 2010 02:50:38 -0000

--- In [email-masked], "cyranojones_lalp" <cyranojones_lalp@...> wrote:
> with the trap var.  

Aha, you found out something I didn't even realize.  I didn't know it was capable of displaying the instruction in ascii.  I'll have to add this into my own debug function.

The reason I never noticed this is because I never included z80debug.o when building msemu.  Going by the makefile, it's not built into z80.o automatically.  I'm sure if I included this object file in mine and commented out my debug function, I'd get the same result as you.

So the solution is to just dump including z80debug.o and write your own version of the function.  Or wait forever until I get around to releasing another version, I suppose!

> I tried redirecting to a file, and you don't know

When I was using libz80 and capturing all its disassembly output (along with my custom debug stuff too) to a file, I had me some fun times as well.  Eventually I changed it to start outputting to a separate file after hitting a certain keypress (this was before I had breakpoints or anything), which helped somewhat.  But UltraEdit can handle big files relatively well without keeling over, fortunately.  

I lost my ability to print out disassembled code when switching to z80em, but now that you brought that capability to my attention, I'll have to see about adding that in.  I don't really need disassembled output at the moment, particularly after getting a CPU library that's not full of bugs, but it could be handy to have later.

> Is it stealing one of the 1 ms ints on those cases????

The Z80_Interrupt function is being called 64 times a second (when z80em runs out of t-states to execute each time).  This function triggers the "keyboard" interrupt to the Mailstation every time, as long as it's enabled in the interrupt mask (P3).  Also inside the Z80_Interrupt function is a counter up to 64, at which point it triggers the 1-second "time16" interrupt (again, if enabled in the interrupt mask).

The "interrupts_active" variable acts as the value that the Mailstation gets when it reads P3.  So at the end of the Z80_Interrupt function, it checks if any of these device interrupts are currently active, and if so, it causes the emulator to execute an actual cpu interrupt (which runs the Mailstation's handler).  

I assume in the actual hardware that P3 is somehow also connected (OR'd) to the Mailstation's interrupt pin, so that's what this simulates.  If any bits of P3 aren't toggled during the interrupt, then they will just cause an interrupt to happen again next time.  Though it won't happen immediately, as would happen on the hardware, I just realized.  But they'll happen at the next execution of Z80_Interrupt.  

I know that they definitely happen in quick succession on the hardware, because I had it happen in my interrupt hook before when I didn't toggle the bits in P3.  The interrupt just kept happening over and over.

> I'm not sure just how it is working now.

Only two of the hardware interrupts are being emulated right now, as mentioned above.  I didn't bother implementing the physical power button and keypress interrupts I found before, since the Mailstation software doesn't use them.  I will at some point though, in order to stay hardware-accurate.  I was mostly concerned about getting the firmware running properly first and foremost.

In my current version though I've been emulating the modem interrupt, because I actually have emulated enough of the modem chip that the Mailstation starts sending ascii characters to it.  I've managed to get the initialization string to come through so far.  I now need to emulate the chip sending data back, to do an "OK" and "CONNECT" and all when appropriate.

I'd just like to get the modem emulated so that eventually my own Mailstation software can communicate with the PC over that connection, freeing up the much more useful parallel port for other capabilities.  Like an SD card reader or something.

> So, you are saying it happens often?  ;^)

Not often I suppose, but my cable does run past various wires, including electrical, so the potential for problems always exists in my case.

> to par port???  Maybe if I run as root?  heh heh heh!  

I've never done it personally under Linux, but it does seem somewhat straightforward (permissions aside).  I'm tempted to try it sometime just for curiosity's sake.

Here's you a potentially helpful resource which I've looked over before:

http://www.faqs.org/docs/Linux-mini/IO-Port-Programming.html

I'd say if Linux is your OS of choice these days then it's worth learning.  Lots of things you can do with it outside of just Mailstation-related, after all.  

I don't know if your original code is in C or not though, so that might make porting it over a little more complicated.  But the maildump utility I wrote is in C, if you ever want it.