Subject: Disabling interrupts = No LCD?

From: "Jeff" <fyberoptic1979@...>
Date: Sat, 04 Aug 2007 00:28:30 -0000

After finally realizing the simplest of bugs which was keeping my app 
to transfer code from the pc to mailstation ram from working (didn't 
realize 16-bit dec didn't set the zero flag, doh), I've finally 
gotten to mucking around much more.  Particularly since it doesn't 
require typing in hex code anymore!

But I found something strange.  Basically, with interrupts disabled, 
whenever I have the LCD set to accept the current column with the cas 
bit in port 2, and then write my column, the lcd goes blank.  When I 
write to it without cas, it just kind of flickers I think.  But 
commenting out that simple 'di' instruction makes everything work 
like a charm again.

More tinkering seems to reveal that I can still update the screen and 
everything behind the scenes, then when I reenable interrupts again 
afterwards, the screen shows up again properly, with all the data I 
set while it was "off".

Anyone know why the lcd goes away without'em enabled?

---

From: "Jeff" <fyberoptic1979@...>
Date: Sat, 04 Aug 2007 08:04:49 -0000

I thought this was LCD-related enough to reply to my own topic.  The
circled emoticon is coincidentally pretty much the expression I had once
I was finished writing the code both to convert the original CGA 8x8
font into an assembly include file (thanks to Perl).  That, as well
as all the other hours of code on the PC and Mailstation side today in
order to easily transfer code back and forth, to allow me to start
writing LCD routines for a text mode (to use less ram for a video buffer
than in "graphics" mode).

Anyhoo, I got a chuckle out of it, nonetheless!

---

From: "Cyrano Jones" <cyranojones_lalp@...>
Date: Sun, 05 Aug 2007 06:17:09 -0000

--- In [email-masked], "Jeff" <fyberoptic1979@...> wrote:
> realize 16-bit dec didn't set the zero flag, doh), 

Computers can be awfully nit-picky, can't they?  :-)

> I've finally 

I'm working on an app that will load other apps, if I get 
enough time this weekend....
 
> commenting out that simple 'di' instruction makes everything work 

Are you using the port 2 shadow var????  And, it just occured
to me as I typed that, I don't know if we know it's address in
3.03a.  Port 2.7 needs to be "1" to keep the LCD on.
 
> afterwards, the screen shows up again properly, with all the data I 

While ints are disabled, the mailstation gears pretty much stop 
turning.  After you reenable them, it won't be long till ms writes
something to port #02, and it will use the shadow that has 
bit 7 set???  Just a guess.

> Anyone know why the lcd goes away without'em enabled?

I don't particulary recall this behavior, and I do think I
have had display on while ints were disabled.

--CJ

---

From: "Cyrano Jones" <cyranojones_lalp@...>
Date: Sun, 05 Aug 2007 06:52:31 -0000

> circled emoticon is coincidentally pretty much the expression I had once

He looks as if he has been staring at tiny pixels for too long, kinda
bleary eyed???

> than in "graphics" mode).

I uploaded a rendering of the ms fonts and icons.
http://tech.groups.yahoo.com/group/mailstation/files/Mailbug/253yr/

The fonts are probably mostly the same, if not exactly, for 
all versions????   There's both an eMessage icon, and Mailstation 
icon in this 2.53yr rom.

I also recently uploaded some assembler code to 
http://tech.groups.yahoo.com/group/mailstation/files/Mailbug/include/

There is code for the "tribble link" interface, and another 
file with a bunch of equ's for the ms firmware routines
that I have been using, and some scrolling text output code, too.

Hey, how did you embed the graphic???  I didn't think we could
post html to the list?

--CJ

---

From: "Jeff" <fyberoptic1979@...>
Date: Sun, 05 Aug 2007 16:19:32 -0000

--- In [email-masked], "Cyrano 

> bit 7 set???  Just a guess.

I'm not using the shadow bit (which is at 0xDBA5 on 3.03a), but I 
made sure to set all the bits correctly when writing to port 2.  The 
LCD bit is kept on at all times.  As I said before, the screen 
doesn't actually go off until I attempt to write the current column 
to the LCD during cas.  Until I do that, the LCD is still on, even 
after I setup port 2 and cas, and even with interrupts disabled.  
It's just when writing the column that makes it turn off when the 
interrupts are disabled.  When I remove only the "di" instruction 
from my code, it all works just fine again.  This is why it doesn't 
make sense to me.

I thought about trying to use my trick to steal the interrupt routine 
and just immediately ei/reti without handling anything, just to see 
if it's something in there causing it.  Maybe I'll also try using the 
shadow bit, just in case.  Anything's worth a shot.

Also, speaking of the LCD, it seems the list I had been using of 
Mailstation devices (from I-Appliance) isn't quite accurate.  It says 
device 2 is the right half of the LCD, and the left half is device 
4.  It appears to be the opposite, from my experience.  I also 
checked the disassembled code of the three firmware versions I know 
of, and it seems to be the same across the board.  Device 2 is the 
left half, updated from the buffer at 0xC010, and device 4 is the 
right half, updated from 0xCA10.

---

From: "Jeff" <fyberoptic1979@...>
Date: Sun, 05 Aug 2007 16:40:21 -0000

> all versions????   There's both an eMessage icon, and Mailstation 

Ah that's a nice list.  It makes me ponder trying to replace the big 
CIDCO logo with one of my own.  Though it seems I don't start up my 
Mailstation normally enough to see that logo most times.  I almost 
always end up doing a "hard" restart, either by pulling the 
batteries, or jumping to 0x0000.  In the test code I've been working 
with, for example, after it does its main task, it goes into a loop 
where it just constantly checks for new keyboard scancodes.  If it 
detects #1 (the Back button), the loop ends, and it jumps to 0x0000.  
I'm not really sure yet how to "properly" restart the Mailstation via 
software, to get the logo and all.  I always end up at the screen 
asking me if I want to erase the flash memory.  I assume during 
shutdown, the Mailstation is setting some value to designate that it 
was turned off properly via the power button, and when you turn it on 
next, it's checking if that was set.

> that I have been using, and some scrolling text output code, too.

More code to look through is always useful!

> Hey, how did you embed the graphic???  I didn't think we could

Well when I'm typing a message here on the Yahoo Groups page, there's 
something along the top just above the "To:" field that says "New! 
Compose your message with Rich-Text Editor (Beta)".  I realized I 
couldn't embed images here, so I clicked that.  It takes you to a 
different text entry form, with a checkbox at the bottom below the 
message body area.  When clicked, it puts your messages into raw html 
mode.  I went in there just long enough to add my img tag.

---

From: "Jeff" <fyberoptic1979@...>
Date: Sun, 05 Aug 2007 17:25:06 -0000

Welp, I tried using the shadow byte, and crazily enough, it worked 
fine with interrupts disabled.

The values I was originally writing straight to port 2 were 0x93 to 
start CAS (turning bit 3 off), then writing my column address, 
followed up by writing 0x9B to port 2 to toggle CAS back.

Assuming this is still all accurate:
7-lcd_on, 6-callid_data, 5-not_modem_power, 4-yougotmail_LED, 3-
LCD_cas, 2-callid_data_rdy, 1-keyrow_9, 0-keyrow_8

The 0x93 I wrote is 10010011.  lcd_on is obviously enabled.  I was 
also turning on the LED to know when I got to this point.  Bits 0 and 
1 are high because that's where the interrupt routine keeps them, and 
only pulls them low when reading from that row of the keyboard 
matrix.  0x9B is 10011011, with the only difference being the CAS bit.

Oh ho!  I just found something!  Instead of the values I had been 
writing, I decided to write 0xF7 (11110111) to start CAS, wrote my 
address, then wrote 0xFF (11111111).  It worked fine!  I then traced 
it down to exactly which bit needed to be on:  bit 5.  If bit 5 is 
not on when you write your column address during cas, the LCD goes 
off.  Why do you suppose that is??

---

From: "Cyrano Jones" <cyranojones_lalp@...>
Date: Tue, 07 Aug 2007 00:30:28 -0000

--- In [email-masked], "Jeff" <fyberoptic1979@...> wrote:

> 4.  It appears to be the opposite, from my experience.  

I made a "datasheet" for the cpu, and updated it with your info,
and also formated it a bit nicer.

http://tech.groups.yahoo.com/group/mailstation/files/part%20files/RSDRD_3SI176_0A.txt

I added some info on the RTC ports, and fixed another mistake
while I was at it (+6 volt good and +5 volt good were reversed 
on the pinout).

There are two bits that relate to battery state, I think one is
"battery getting low", and other "battery is almost dead".  
They might be reversed, I'm not sure which is which.

-CJ

---

From: "Cyrano Jones" <cyranojones_lalp@...>
Date: Tue, 07 Aug 2007 01:41:12 -0000

--- In [email-masked], "Jeff" <fyberoptic1979@...> wrote:

> I almost 

Why noy just return?  If you are running your app from the 
menu, then I guess your whole prog runs when it receives
the "init" event.  So, to prevent it from running again
for every event the ms sends (I think there will be at least
3 or 4???) you would want to check the sig param, and 
just return immediately on any other sig.

> detects #1 (the Back button), the loop ends, and it jumps to 0x0000.  

Why not check for a "back key" event, and handle it, too?

> was turned off properly via the power button, and when you turn it
> on next, it's checking if that was set.

If jp #0000 gives that menu even with batteries in, then you
probably do need to set a state var, and it is prob that first
var that is saved in the routine called "Init" on your disassembly.
I'd tell you the location, but it might be different on your 3.03a.

Try setting that var to #5A before reboot.  The "moreinit"
routine checks for that value, and sets a different "app mode"
depending if that var was #5A.  I don't know what the difference
is, though.  Maybe it is whether or not you get that menu (seems
like a good guess).

If that doesn't work, I just don't know what else is involved.

When I run code from mailbug, I end with a ret.  If all goes
well, mbug gets control again, and I can issue more commands.
Otherwise, I hit the reset button (I leave a jeweler's screwdriver
sticking out of the reset hole, 'coz I need to hit it often!)

I rarely have batteries installed, and I thought that was why
I was seeing that message all the time.

Another thought I just had was that the mailstation does not boot
up from scratch when you turn it on with power button.  That's
because it doesn't really shut off when you push power button.
It just goes to sleep.  So, when you push button to "turn it on"
you are really just waking it up.  Maybe it always asks that 
question when it boots up from #0000?

> message body area.  When clicked, it puts your messages into raw
> html mode.  

Cool!  I've used the rich-text mode, just never noticed that
checkbox!

--CJ

---

From: "Cyrano Jones" <cyranojones_lalp@...>
Date: Tue, 07 Aug 2007 01:50:16 -0000

> matrix.  0x9B is 10011011, with the only difference being the CAS bit.

Both those values are turning the modem on, too.  Bit 5 is
active-low.

> off.  Why do you suppose that is??

Maybe there is a bus conflict if the modem is on when you are
trying to talk to LCD???  Just why it goes away if int's are 
enabled is a bit of a mystery.

--CJ

---

From: "Jeff" <fyberoptic1979@...>
Date: Tue, 07 Aug 2007 05:06:48 -0000

> They might be reversed, I'm not sure which is which.

Hey awesome, I was wondering if anyone had discovered what any more 
of the ports were for yet.  Those RTC ones should be of use for 
something or another.

---

From: "Jeff" <fyberoptic1979@...>
Date: Tue, 07 Aug 2007 05:39:38 -0000

> Why not check for a "back key" event, and handle it, too?

I pretty much have tried to avoid depending on all Mailstation 
functions as much as possible, particularly its whole message loop 
system.  The only thing I'm currently depending on with code I'm 
working on is getkeycodefrombuffer, until I write a routine to handle 
scanning the keyboard matrix myself.  Seems easy enough, I just 
haven't gotten around to it, from trying to deal with text output 
first.

I've gotten routines in place for a decent text-mode interface, with 
a 640-byte buffer to hold 40x16 characters.  I can either write to 
the memory buffer and then run a routine to update it all at once, or 
I can update it one character at a time (which also writes to the 
buffer, but is better for printing strings instead of updating the 
whole display).  It also tracks the cursor x/y position to know where 
to put the next character.

I just need a routine to map scancodes to keys, track whether shift/
caps lock is on, etc, and I'll have my own basic i/o routines to work 
with.

Actually I just remembered, I just recently started using a second 
Mailstation function:  powerdownmode.  I tried emulating what it's 
doing, but sometimes the thing just resets instead of fully staying 
off.  Haven't figured that out yet.  It certainly appears like bit 1 
of port 28 seems to play an important part in shutting down, though.  
But now, Back resets me to #0000, while the power button turns it 
off.  Pushing any other button prints its scan code (and status of up/
down/shift/capslock below), and prints the ascii representation of 
the scancode on the screen (and incrementing the cursor position 
along the way).  This will be neater when it's actually displaying 
the corresponding letter to the key I'm pressing!

As mentioned before I think, I was trying to stray from using 
Mailstation code when possible so that I never have to rely on any of 
it in the event that I replace it.  Relying on Mailstation code also 
means relying on where it locates things in ram, and trying to avoid 
writing over any of it.

> is, though.  Maybe it is whether or not you get that menu (seems

Yeah this was something I found out when reading over that nice 
disassembled/commented page 0.  I can't try it until I find out the 
v3.03a location though, as you mentioned.  But if I'm possibly 
messing up "important" Mailstation ram at some point, I wonder if 
it's really safe to let it think the system is still okay by slipping 
the #5a in myself, or if I should just intentionally let it reboot 
completely.

I actually think it's faster anyway, since the Cidco logo takes a 
second go to away, where as I just need to tap enter to get past the 
other one.

> sticking out of the reset hole, 'coz I need to hit it often!)

I saw that button when I was messing with it the other day, but 
wasn't sure just what exactly it might do if I press it.  I didn't 
want to go and erase the dataflash or anything.

> question when it boots up from #0000?

I've used the same set of batteries in it since I first started 
mucking around, and I only once saw a low battery warning at startup, 
and that was when I forgot and left it running for a few minutes in 
an app I was testing (since no auto-shutoff).  It's surprisingly good 
on batteries, especially considering it never truly goes off.  I 
still haven't replaced them, either.

This also means the ram retains its contents, which could be a useful 
method of code storage.  A ram drive, of sorts.  Would let you avoid 
writing to the flash unless necessary.

---

From: "Cyrano Jones" <cyranojones_lalp@...>
Date: Thu, 09 Aug 2007 00:10:47 -0000

> to put the next character.

That's sounds pretty cool.  :-)

I have wondered myself if the lcd buffer provids any real benefit,
or if it was just there to let the progrmmers defer thinking about 
how to get image on the screen (possibly defer to another team?).  
I don't see any particular timing issue.

For that matter, the ms code doesn't even copy directly from 
the font data to lcd buffer.  Each character is copied to a 
"char buffer", and then copied to the lcd buffer.  Seems like 
it would be much more efficient to just copy from font directly 
to lcd, and skip both buffers!

> I just need a routine to map scancodes to keys, track whether 
> shift/caps lock is on, etc, and I'll have my own basic i/o 
> routines to work with.

Keyboard events have both scancode and ascii fields.  
Why reinvent the wheel?   :-)   :-)   :-)

> of port 28 seems to play an important part in shutting down, though.  

If you look at the code for "powerdownmode", it is bit 0 
that shuts it off.  Oh wow!  I was just looking at the 
disassembly.  I thought you were saying "powerdown" which 
is at 1AC0 in 2.53yr.

"powerdownmode" is just a wrapper that sets bootstate to 5A, 
and then calls "powerdown"!!!  I didn't even remember that 
was there, but I must have seen it, 'coz I named it!  There 
is just too much to remember about this thing.  :-)

And, unlike "powerdown" , which might float around in 
different versions, "powerdownmode" has one of those handles 
in that real long jump table. 

So, I bet you can call powerdownmode at #0A6B in all versions.  
I seem to recall that jumptable is at same address in the 
versions I looked at.

But what I started to say was, if you look at the code for 
"powerdown" @1AC0 in the 2.53 disassembly, you'll see that 
it is toggling P28.0

P28.0 is connected to the power control flip-flop (74c74 chip)
via a 600 ohm resistor.  I don't completely understand circuit, 
there are several caps and resistors, and 2 stages of D type
flip-flop, but the gist of it seems to be that a pulse on 
P28.0 sets the flip-flop to the "poweroff" state, after a 
short delay.  I think the delay is there to give cpu time to 
execute up to the "halt" inst before removing power from the 
codeflash chip.  (I'm talking about RC time-constant delay 
of pulse, NOT the delay loop in the code.  That delay loop 
is just timing the pusle width.)  I don't know if the cpu 
loses power here or not.

I made a mistake when I identified callid dataclock as 
P28.2, it is really P28.1.  The  "xor 02" instruction 
is flipping bit 1, but my brain seems to have trouble 
grasping that, and wants to call it bit 2.  That led to 
all the P28 bits being jogged over 1 bit.  I changed the 
datasheet in groups file section, eventually I need to 
update linux-hacker, too.

> the corresponding letter to the key I'm pressing!

So, what is ascii code for F1 key???  We had a rather 
short thread on that subject 2 years ago (holy crap, 
2 years???).  I came to conclusion nobody here really 
cared about pursuing "getchar()".
http://tech.groups.yahoo.com/group/mailstation/message/392

> the #5a in myself, or if I should just intentionally let it reboot 

I was just now looking to see where "powerdownmode" is 
called.  It is from keyscan, which I guess makes some 
sense, if you think of powerbutton as a special "key".  
I'm not really sure offhand what happens at poweron, 
though.  Does it continue from the "halt", or start 
over at #0000?  I need to look at databook, and it's 
not handy right now.

How much ram do you need?  The lcd buffer is 5k, and you 
reduced yours to 640 bytes, so you got 4.4k right there.  
The modem buffer is where I have been sticking the mbug 
code.  That should be safe, as long as modem is not used.

Did you see the RAM "disassembly"?  It's not really  
disassembly, but I put some notes in the comment file 
for rampage #00.  (ms always has rampage #00 mapped 
into slotC000.)   

I also tagged the data types by hand for the vars that 
are known. 
http://tech.groups.yahoo.com/group/mailstation/files/Mailbug/253yr/ms253yr_80.html

Then there is the stack.  You can allocate space for 
*any* routine that needs local vars, by just calling 
the same routine that the compiled c code uses.  I 
named it "localize" in the disassembly, because it 
was creating a local context for each function.
In addition to allocating stack for local vars, 
it also saves all the regs for you.  

You just load DE with number of bytes you need for 
locals, and call localize.  Then you can access your 
locals relative to the stack pointer.  

The first local byte is at sp+8.  Any params are at 
sp+8+n+4  (iow, last local addr + 5).

The cleanup is automatic, your code just needs to "return".

> want to go and erase the dataflash or anything.

It just asserts the CPU's reset pin, so pretty much 
the same as power cycle, or "jp 0000" .  I think reset 
also sets i/o ports to initial state (0 for most???), 
but they all get init before use anyway, no matter 
which of the 3 methods you use.
 
--CJ

---

From: "Jeff" <fyberoptic1979@...>
Date: Tue, 14 Aug 2007 19:25:18 -0000

> I don't see any particular timing issue.

Well from my experience, it would probably be slower to write 
directly to the lcd all the time, because of the math involved to 
translate pixel coordinates.  You have to figure out which lcd device 
to swap into the slot, which column you need to activate, then which 
row inside of there to write the bit to, and then which bit inside 
the byte is the particular pixel you're wanting to change.  You then 
have to pretty much do these calculations for all the pixels you're 
writing, because you don't know when one will cross into another 
column, or even into the other lcd device.

The math to just draw this stuff on a buffer with standard x/y 
coordinates would be simpler, and then doing one big incremental pass 
across the lcd columns/devices after you've drawn all you need to the 
buffer would likely take less time in the long run.

This is partially why I chose an 8x8 font size to work with in what 
I've been messing with, because it's always aligned to a particular 
lcd column.  I just have figure out which column the character needs 
to be written to, and then the starting row inside of there, and dump 
8 bytes of font data in.

> to lcd, and skip both buffers!

I didn't quite get this at first either, but then I realized that it 
probably makes sense for when they're wanting to modify the text in 
some way.  Particularly to invert the color.  You wouldn't really 
want to try and invert the font once it hit the actual lcd buffer, 
cause you might invert bits to other graphical data around/underneath 
the character you just wrote.

> Why reinvent the wheel?   :-)   :-)   :-)

Well, I did finish my routines to scan the matrix, detect changes, 
and put the scancodes of those changes into a buffer.  But then I 
found that certain letters on my keyboard are twitchy and sometimes 
trigger too many presses/depresses.  I then realized that all the 
extra stuff the MS code was doing was likely debouncing the keys.  
Since I'm almost tired of just writing keyboard routines for now (and 
have gotten distracted away from it lately as well), I'm thinking I 
might just pull all their routines I need out for now and put them in 
my own code to possibly be rewritten later, so that I can move onto 
more interesting stuff.

The problem with just leaving them in the Mailstation code is the 
page swapping required to get to them.  One of those "wormhole" 
functions in page 0 might help keep it from being a problem in some 
respects, but if I ever tried to hijack the interrupt for example, it 
could be a problem yet again.  So I'd prefer to just keep my own 
pages activated when possible, by just copying out their code.

> http://tech.groups.yahoo.com/group/mailstation/message/392

Back in my DOS days I seem to remember that pressing any of those 
sorts of keys (such as the arrows) would produce two bytes out of a 
getchar type of function.  The first byte was a particular value to 
indicate an extended key, and the following byte would indicate which 
button.

I wrote a brief C program just now using getch() (not getchar, since 
it waits for enter to be pressed) to see the values, and pushing F1 
gets me 0,59 for example.  Pushing up gets 224,72.  F1-F10 always 
return a 0 first, and F11-F12 and the other buttons (arrows, home/end/
etc) always return a 224 first, it seems.

> code.  That should be safe, as long as modem is not used.

Well my intention was to preferably have the entire upper 32K as ram 
for my own use (OS, running applications, etc).  That'd basically 
make a 32k machine, while using slot4000 for paging the lcd/dataflash/
ram (for a ramdrive perhaps) for I/O.  It also works out well to 
start the OS code at the 32k point, because then if I ever tried to 
convert any CP/M apps, for example, I'd mostly only need to toggle 
the upper address bit in any spots where they accessed memory.

I only wish I knew more about when an NMI interrupt hit, because if 
it rarely or never happens aside from like modem use (which I'll 
never use), then I could use all the page 0 ram without worry, by 
just turning off maskable interrupts, or hijacking the routine.

---

From: "Cyrano Jones" <cyranojones_lalp@...>
Date: Thu, 16 Aug 2007 00:20:51 -0000

> >  ...

> directly to the lcd all the time, because of the math involved to 

Yeah, I realized that about half a second after I sent that.

I just meant I don't think there is any need to synchronize
writes with any video-like timing (retrace), or any wait states
generated.

When painting whole screen, it can be faster to use buffer,
particularly if you are doing graphic stuff, like line drawing.

But if you are displaying text, I don't think the overhead of 
accessing the LCD directly is that big a deal, compared to
copying the whole screen, particularly if you are just updating 
a small area, such as a "writeln".  You would just have the 
X coord overhead once per char, (with your 8x8 font).

If you were using proportional font, you could buffer two 8x8 
or 8x11 pixel areas, and copy each to LCD after curor moves past. 
That would save the 5KB used for current LCD buffer.  

Also, scrolling the LCD would be faster directly on LCD.  And 
clearing screen, too.  (But the question may be moot, see below.)

> the character you just wrote.

I think I figured out an even better reason for what at first
seemed like a lot of needless copying, not only in LCD routines, but
a lot of other places:  The bank switching!!!

Since they chose a banking scheme where the codeflash, dataflash,
and LCD (and modem, too) all use slot4000, you can't copy
directly between two of them!  Same problem as my original
helloapp had with the foldertabtext.  :-)

> extra stuff the MS code was doing was likely debouncing the keys. 

Yes.  Debouncing.  And probably key repeat.  All free!!!  ;^)

...
> pages activated when possible, by just copying out their code.

I'd have to check to be sure, but I think the keyboard code might
all be in page 00?

And, even if you do want to use a function from one of the higher 
pages, you don't need to do the bankswitching, you just call them
through the handles in page 00, and the bankswitching is done for
you, including puting your page back before they return.

But, as we have seen recently, it does pay to be aware of the
fact that slot4000 is not fixed!!!  :-)

> > So, what is ascii code for F1 key??? 
 
> indicate an extended key, and the following byte would indicate which 

I think pascal (well, turbo & freepascal, at least) rets a 0 for
the first byte of extended codes.  I just could not find any docs 
for c that said what it returned.  Maybe it is not part of c, but 
rather part of your particular OS spec???

> etc) always return a 224 first, it seems.

I didn't even know the right name.  I have been away from c for
quite a while.  (hey, "away from c", does that make me a landlubber???)

I used it in school a bit, and again when I started using Linux,
but I was not impressed with it's compile speed (gcc).  Perl was
a lot more fun!!!

I have recently been re-learning c, though (winavr).  I think my 
computer is faster now, and maybe my programs are smaller, too.

> the upper address bit in any spots where they accessed memory.

I see.  You are gonna need to change the isr, then, either with your
nifty method, or reflashing codeflash page 00 (unless your os can work
around the ram that existing isr uses).  

> just turning off maskable interrupts, or hijacking the routine.

My hunch is there is no NMI, but I could be wrong.  

I had thought about reflashing page 00 to put a hook into isr so I 
could borrow it.  Find a free RAM location (maybe move stack down
4 or 8 bytes) and init it to "jp oldisr" (with a patch to init in 
page 00).  Then patch the existing jp oldisr in page 00 to jump to 
that new jp in ram.

But what I really need more than the ISR is to borrow one of the 
"restarts", for the breakpoint mechanism.  Not exactly rocket science.
just haven't got "a round tuit".  

Probably 'coz I spend too much timewatching stuff like this: 
http://menino.com/question-is-moot.mov

-- CJ

---

From: "Jeff" <fyberoptic1979@...>
Date: Fri, 17 Aug 2007 02:13:50 -0000

> you, including puting your page back before they return.

Yeah the keyboard stuff is in page 0, but the problem is that it 
still uses pieces of ram way up in the C000-FFFF range.  So I pulled 
all the keyboard routines out of the disassembled listing, fixed them 
up and re-labeled them so that they'd assemble again, and created the 
variables in memory where I wanted.  But I'm having problems with 
it.  

The topmost function the interrupt calls seems to be the one at 
0x2FE3 (keyscan).  So I'm calling that, then calling my pulled 
version of getkeycodefrombuffer, and looping these if it doesn't find 
a key (which is how I did it with the built-in routines before, just 
minus the call to the 0x2FE3 one, since that's done in interrupt).  I 
can get the power and back buttons, since it handles them separately, 
but it either doesn't read anything else, or reads a bunch of 
gibberish for a moment and then stops reading anything (aside from 
back and power).

I'm calling my pulled init_keyboard and clearing a couple of the 
variables the functions use before I get there, but I dunno, maybe 
I'm missing something.  There might be some initialization called at 
startup in page 6 of codeflash that I don't know about.  I don't have 
any commented versions of that page, so it's tough to go through.  
I'm almost tempted to just forget it and write my own debouncing code 
for what I already have.  Seems like it might be easier at this point 
than trying to debug that entire mess, unless you have any ideas.

> but I was not impressed with it's compile speed (gcc).  Perl was

I use Perl a lot myself since it's so easy to use, and generally 
works fine cross-platform for testing and debugging and such 
(depending on the modules).  For C, I got that Dev-C++ thing before 
for Windows, but ended up not really caring for the GUI, so I just 
setup the environment variables to it so that it's pretty much just 
back to basic gcc/g++ and 'make' from the command line.  I keep it 
all installed since it has a package system in the GUI that lets me 
update it and other libraries fairly easily.

> My hunch is there is no NMI, but I could be wrong.  

The keyboard routines seem to get called from an NMI (since NMI and 
maskable interrupts apparently go to the same place), but I found 
that I never get keyboard input (using the mailstation's built-in 
functions) with interrupts disabled.  So you could be right, there 
may just never be one, or never one unless using the modem or some 
such thing that I'll never do.

> page 00).  Then patch the existing jp oldisr in page 00 to jump to 

I'm kind of afraid of trying anything like that, but it seems like 
the best way to deal with doing anything with the thing in the long 
run.  I fear that I'll write code, but not take into account some 
sort of initialization aspect that the MS does, and then when my code 
goes on there, it'll just be a brick.

I'm also not exactly sure what process I'd go about using to flash 
any of it.

---

From: "Cyrano Jones" <cyranojones_lalp@...>
Date: Sat, 18 Aug 2007 06:00:06 -0000

> gibberish for a moment and then stops reading anything (aside from 

That looks like right address in 2.53yr.  I was wondering if 
calling in a loop might not give enough settling time for row
select?  I can't look at it right now (won't be home till tues),
but does ms scan whole matrix each time 2fe3 is called? 
Or just one row???  I seem to remember wondering why 
row address was set when it was, and extra settling time 
was my only guess as to why.  If that is prob, maybe doing
a 1ms delay in your loop would help.
 
> startup in page 6 of codeflash that I don't know about.  

As far as I could see (I looked at keyboard code last night,
before I left) the keyscan vars are not init to anything beyond
the zeroing of ram in init.  The page 6 init relating to keyboard
is mostly for the reading of buffer, andconverting to key events.
They also enable keyboard int, which you wouldn't need, and
make a call to keyboard init, which you probably do need.  I
am not sure what param is for, but they push #0000 on stack
before calling keyboard init.  I think keyboard init is neccesary 
for initing keybuffer.

> I don't have 

That is next one I will post.  There are some mistakes I was correcting,
and alway seems there is new details to add.  The most interesting
stuff in page 6 is the event loop, and related queue, and event
generating.

Also, the app table is init there, along with the widget stuff.

I did some experiments the other night, setting bootstate = 5a
before jp 0, and it worked (didn't get the "memory testing", or
"reset system data" menu.  AFAICT, the ram gets completely
zeroed either way, only difference is what app/screen you get to
on bootup (splash, or mem test).  Seems the "ram valid" is
only used to determine if it will look at "bootstate" or not.

I wonder if the memory test is for the flash???  Seems like it must
be, if they are gonna init the ram either way???

> goes on there, it'll just be a brick.

But think of the rush you get when it works!!! :-)

A bricked mailstation is a pretty low price to pay, and you might
get it right the first try.  If only *all* the mistakes we make
could be limited to the cost of a new mailstation!!!

> I'm also not exactly sure what process I'd go about using to flash 

I started writing patch, but did not finish yet.  Basic approach
would be:

1) create patch.  
1.5) save rom image to file, if you don't already have one.
2) load rom image into RAM target of mailbug.  
3) apply the patch.  
4) save image to file (you need pages 0, 1, 2, & 3, 'coz you have to
erase that much).
5) using MBUG target, erase pgs 0, 1, 2, 3.
5.5) don't reboot mailstation!!!!!!
6) still using mbug target, write patched image to codeflash.
7) successfully reboot your patched mailstation.
8) stand up, raise two fists in air, and sing chourus of "I've Got the
Power".
9) remember to *not* spike your mailstation in endzone!

(OK, I usually do step 8 while still seated.)

--CJ

---

From: "Jeff" <fyberoptic1979@...>
Date: Tue, 21 Aug 2007 00:50:26 -0000

> before calling keyboard init.  I think keyboard init is neccesary 

I ended up disassembling it a second time since I thought I might 
have messed up during my labeling process, but it turned out to just 
be some minor issues elsewhere.  I was declaring my 'keybuffer' 
variable as just 32 bytes instead of 64, and had to set 'keycolstate' 
and 'keycolstate2' to #FF during init.  

So basically my entire keyboard initialization is:
- Activate all keyboard rows (MS appears to do it)
- Set 'flagz', 'keyscanstate', and 'anotherkeyvar' to 0 (I don't see 
MS doing this, but I figure it's best to do it)
- Set 'keycolstate' and 'keycolstate2' to #FF (if set to 0, they 
trigger a power button press)
- call init_keyboard

This lets all of the keyboard routines I pulled out of the firmware 
work properly, using my own variables as well, so that none of the 
actual firmware code or variables are needed anymore.

For anyone that might be interested, here's some variable locations 
in the v3.03a firmware that I jotted down along the way:

flagz			equ	#D631
kbd_last_up_keycode	equ	#DA46
keybuffer		equ	#E5AF
keybuffin		equ	#E5EF
keybuffout		equ	#E5F0
keycolstate		equ	#E5F1
keycolstate2		equ	#E5F2
anotherkeyvar		equ	#E5F3
keyscanstate		equ	#E5F4
keytable3		equ	#E5F5
keytable2		equ	#E5FF
keytable1		equ	#E609

p2shadow		equ	#DBA5
p3shadow		equ	#DBA6

> 8) stand up, raise two fists in air, and sing chourus of "I've Got 
> the Power".

I have to admit that I haven't used mailbug yet since it apparently 
needs DOS.  But I can pull my laptop out and try it on there if I 
decide to patch, since it boots to a few different OS's.  

Out of curiosity, what process are you using to initiate a code 
flash?  Is it like a trigger over the parallel port, or are you 
loading some software onto the MS and doing it with internal 
functions?

I noticed my MS did something weird the other day when the power was 
fluctuating some during a code transfer (my power jack and AC adapter 
are a bit wiggly).  It prompted me to do a firmware update, but then 
failed almost immediately.  I'm fairly sure there's no way I could 
accidently screw it up in such a manner though, since it does I CRC 
check and stuff I think from what I've seen in the code.  

And yes, alas, I finally went to an AC adapter.  Those batteries I 
had been using finally spewed their last scancode to the screen, 
until it started to gripe at me nonstop about them being low and 
force itself off again when I'd try to start it up.

---

From: "Cyrano Jones" <cyranojones_lalp@...>
Date: Wed, 22 Aug 2007 10:57:18 -0000

> trigger a power button press)

The vars are all set to 0 in "init".  

In 2.53yr disassembly, look at 0000:3890, a call to "memfill" 
that zeroes #C000 thru #FBFF.

"flagz" is also explicitly set to 0 at 0000:1B75.

I'm gonna make a guess that the reason you need to set
"keycolstate" & "keycolstate2" to #FF is because the
real vars are set that way (at least the bits that matter)
when you press the power button to turn ms on.  iow,
your keyscan is init after the power has already been
turned on.  The real keyscan would have seen that
button press and flipped some bits in the real state vars.
Or, maybe all it is seeing is the button release, since that
will happen after the init code runs.  It can't really see
button down transition, can it?  ;^)

> actual firmware code or variables are needed anymore.

:-)

...

> decide to patch, since it boots to a few different OS's.  

I use win 98.  Mailbug 0.0.4 won't work with NT, 2000, or XP, due
to the restriction on port access.  Mailbug 0.0.5 uses the same DLL
you used, and I imagine it will work with XP and friends, when it
is done.  But it won't even compile now, and I don't know what 
I broke.  It is nowhere near done anyways, there is a LOT that needs 
changing to make it a real windows app.  I have not had any time to
tinker with it lately.

I compiled 0.0.4 (and earlier) as dos app, because freepascal
did not allow port access in windows, even if you were running
on win 98.  I don't know if anyone is actually running it under 
dos.  (I really don't think anyone is running it, period.)  It
may not run under dos without changing the default paths & filenames
to 8.3 form.  But I would go with win 98.

> loading some software onto the MS and doing it with internal 

This does not use the native reflash mode at all.

Mailbug just accesses the addresses in the pattern that unlocks the
flash, writes a byte, and watches for the write to complete.  Same 
as if the flash was RAM.  Earlier versions loaded the flash
algorithm into ms RAM, and sent it the data to flash.

I removed the actual flash code from the ms side due to the
fact that it was too easy to change flash by sending nonsense
bytes.  This happens more often than you might think, when
the ms and mailbug are not in sync.

It is a bit slower now, but not a big deal IMO.  I realize
there are ways that would make it safer without incurring
as big a speed penalty, but this way struck me as a particularly
easy way to make it safer.
 
> check and stuff I think from what I've seen in the code.  

Actually, it is pretty easy to screw it up this way!  :-)

It sounds like your ms app that was interfacing with your PC
was canceled by a power-on reset, and the PC kept sending bytes
which then were received by the native reflash monitor.  

That checksum calc happens *after* it erases and rewrites the 
codeflash.  And for that matter, it just displays the checksum
for the operator to read, it has no idea of right or wrong 
checksum.

> force itself off again when I'd try to start it up.

Hmmmm...  I tried running on batteries for a while, myself, in 
last week or so.  One problem was I had to dig up my reset-button 
poker, coz I couldn't just pull plug to reset.  No big deal.
But there was another issue which escapes me right now (It's way
past bedtime!), but something was not acting right, and I 
determined it was because the battery was low.  I think that I 
was leaving it running for long periods with code that did not
know how to go to sleep, and drained batteries extra fast.

--CJ