[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: IIGS battery ram format, reading, writing?
Here is some notes I came across for all who want to copy and paste this into your documents.
//gs Battery RAM and Clock/Calendar
There are 256 bytes of RAM inside the clock chip in the Apple //gs. These bytes are backed up by the same battery that keeps the clock ticking when you turn off your Apple. You can read and write the battery RAM locations, but not the same as regular RAM. You can either do it the hard way, by direct hardware, or you can do it through the built-in firmware.
First, the easy way. When you turn on your //gs, the power-up routines install a lot of stuff in RAM in banks $E0 and $E1. At the beginning of $E1 there are a lot of JMP opcodes, with long (24-bit) addresses. The one at $E10000 is a jump to the Tool Locater. The Tool Locater is simply a way to access a lot of firmware subroutines without knowing their actual addresses. Instead of calling a firmware subroutine directly, you load up a subroutine number in a register and call the single known address, $E10000.
To keep things organized, the //gs firmware designers require you to call $E10000 with the 65816 in Native mode, with a JSL $E10000. Any parameters the subroutines need must be pushed onto the stack before the JSL, and any results will be on the stack when the subroutine is finished. The carry status will indicate whether the subroutine returned an error code or not, just as in ProDOS MLI. If carry is clear, there was no error; if carry is set, there was an error and the error code is in the A-register. Regardless of the setting of the m- and x-status bits when you call $E10000, it will return with both of them zero (full 16-bit mode).
You tell the Tool Locater which "tool" to call by a code number in the X-register. This is a 16-bit value, so you must have 16-bit mode on for the X-register when you call $E10000 (x-status bit=0). It doesn't matter whether m-status is 0 or 1. The tool code is made up of a tool set number (00-FF, in the low byte) and a tool number (00-FF, in the high byte). The tool code to read all 256 bytes of battery RAM is $0A03; to write 256 bytes out to battery RAM, the tool code is $0903. The following program will read battery RAM:
1000 *SAVE S.BATTERY.RAM
1010 *--------------------------------
1020 .OP 65816
1030 *--------------------------------
1040 R CLC
1050 XCE
1060 REP #$30
1070 *--------------------------------
1080 PEA BUF/256/256
1090 PEA BUF
1100 LDX ##$0A03 READ BATTERY RAM
1110 JSR $E10000
1120 *--------------------------------
1130 SEC
1140 XCE
1150 RTS
1160 *--------------------------------
1170 W CLC
1180 XCE
1190 REP #$30
1200 *--------------------------------
1210 PEA BUF/256/256
1220 PEA BUF
1230 LDX ##$0903 WRITE BATTERY RAM
1240 JSR $E10000
1250 *--------------------------------
1260 SEC
1270 XCE
1280 RTS
1290 *--------------------------------
1300 BUF .EQ $900
1310 *--------------------------------
When I did this on my //gs prototype, this is what I got:
0900-00 00 00 01 00 00 0d 06 02 01 01 00 01 00 00 00-................
0910-00 00 07 06 02 01 01 00 00 00 00 0F 07 00 08 0B-................
0920-01 01 00 00 00 00 01 01 05 00 00 00 03 02 02 02-................
0930-00 00 00 00 00 00 00 0C 08 00 01 02 03 04 05 06-................
0940-07 0A 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D-................
0950-0E 0F FF FF FF FF FF FF FF FF FF FF FF FF FF FF-................
0960-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF-................
0970-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF-................
0980-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF-................
0990-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF-................
09A0-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF-................
09B0-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF-................
09C0-C2 CF C2 A0 D3 C1 CE C4 C5 D2 AD C3 C5 C4 C5 D2-BOB SANDER-CEDER
09D0-CC CF C6 A0 FF FF FF FF FF FF FF FF FF FF FF FF-LOF ............
09E0-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF-................
09F0-FF FF FF FF FF FF FF FF FF FF FF FF 27 CE 8D 64-............'N.d
Those last four bytes are some kind of a check sum, handled automatically by the tool. I suppose that if the checksum is incorrect on power up, you will be popped into the configurator instead of going into a boot. You can read these bytes, but you cannot write them with the tool: the tool will calculate a checksum and write it when you write the other 252 bytes. Bytes $52 through $FB are either used by the operating system or reserved for the future. Just for fun, I have now written my own name in ASCII code into the bytes starting at $C0.
The rest of the bytes are used as shown in the following table. Where two choices are shown, separated by a slash, the left one has a code of $00 and the right choice has a code of $01.
Port 1 Port 2
$00 $0C Printer/Modem
$01 $0D Line Length (Any/40/72/80/132)
$02 $0E Delete LF after CR (No/Yes)
$03 $0F Add LF after CR (No/Yes)
$04 $10 Echo (No/Yes)
$05 $11 Buffer (No/Yes)
$06 $12 Baud Rate
$07 $13 Data & Stop Bits
$08 $14 Parity
$09 $15 DCD Handshake (No/Yes)
$0A $16 DSR Handshake (No/Yes)
$0B $17 XON-XOFF Handshake (No/Yes)
Display Parameters
$18 Color/Monochrome
$19 40/80 Column
$1A Text Color (00-0F)
$1B Background Color (00-0F)
$1C Border Color (00-0F)
$1D 60/50 Hertz Operation
$29 Text Language (0=English)
$2F Flash Rate
Keyboard Parameters
$2A Language (0=English)
$2B Buffering (No/Yes)
$2C Repeat Speed
$2D Repeat Delay
$30 Shift Caps-LowerCase (No/Yes)
$31 Fast Space-Delete Keys (No/Yes)
$32 Dual Speed (Normal/Fast)
Slot Configuration
$21-27 Slot 1-7 Internal/External
$28 Boot Slot
Miscellaneous
$1E User Volume
$1F Bell Volume
$20 System Speed (Normal/Fast)
$2E Double-Click Time
$33 High Mouse Resolution
$34 Date Format
$35 Time Format
$36 Min RAM for Ramdisk
$37 Max RAM for Ramdisk
$38-40 Count & Languages
$41-51 Count & Layouts
$80 AppleTalk Node Number
$81-A1 Operating System Variables
It is possible, as I said before, to talk directly to the battery RAM via I/O addresses. If you learn how to do this, and you use the skill to write values into battery RAM, you will probably do so without properly changing the checksum. In that case you have violated your system, and your next power-up will revert to default values for all parameters. It will stay that way until you reconfigure everything and/or install a proper checksum. The best policy is to use the standard firmware tools for all reading and writing, so that the checksum stays current.
You do not have to read or write the whole battery RAM at once. There are two tools for reading and writing a single byte. Tool Code $0B03 will write one byte, and tool code $0C03 will read one byte. The following code segments illustrate how to do it. The code as shown must be in Native Mode, with both x- and m-bits zero (full 16-bit mode).
WR PEA $00xx xx is new value for byte
PEA $00yy yy is address in battery RAM
LDX ##$0B03 write xx at yy
JSL $E10000
-----
RD PEA $0000 make room for result
PEA $00yy yy is address in battery RAM
LDX ##$0C03 read value at yy
JSL $E10000
PLA get result from stack (00xx)
The Clock/Calendar Chip not only contains the battery RAM; it also contains the date and time information, naturally. There are three tools for reading and writing the time and date. You can read time/date in either hexadecimal format or as an ASCII string, and you can write a new time/date in a hex format. The following code segments illustrate how to use the tools.
Read.Time.Into.ASCII.String
PEA BUFFER/256/256 Hi 16-bits of buffer address
PEA BUFFER Lo 16-bits of buffer address
LDX ##$0F03 Tool Code
JSL $E10000
The date and time will be converted to ASCII (with msb = 1) and stored in BUFFER, according to the formats selected in the configuration menu (stored in battery RAM locations $34 and $35). The most likely choice among North Americans will be the format "mm/dd/yy HH:MM:SS xM", but you have five other possibilities.
Read.Time.Hex
PEA 0 Make room for 8 bytes
PEA 0 to be returned
PEA 0
PEA 0
LDX ##$0D03
JSL $E10000
PLA Get $MMSS (minutes, seconds)
STA MMSS
PLA Get $yyHH (year, hours)
STA YYHH
PLA Get $mmdd (month, day)
STA MMDD
PLA Get day of week (in low byte)
STA DOW
The value for day of week runs from 0 to 6, with 0=Sunday. The value for "day" is 0-30, meaning that you have to add 1 to get the true day number. (Why? This is a little ridiculous!) Likewise, the value for month is 0-11, with 0 standing for January. (I can understand why the hardware might work with 0-based values for day and month, but why couldn't the firmware do the correction to "real" day and month numbers?) The year is specified as the actual year number minus 1900. I hope that means my //gs will still give correct dates after 1999. If the value of the "yy" byte can go all the way to 255, then we could use //gs until the end of the year 2155. Frankly, I think I'll get tired of computers before then.
To write a new date and time out to the Clock chip, you have to push the values onto the stack and call the tool:
Write.New.Time
PEA $mmdd month, day
PEA $yyHH year, hour
PEA $MMSS minute, second
LDX ##$0E03
JSR $E10000
Again, the month and day values are zero-based. Note that you cannot update the day-of-week directly; apparently it is only a CALCULATED value provided when you READ the date/time in hex format.
You might wonder whether anyone would really NEED all the above information. After all, Apple has provided the configuration system to see/modify all those parameters. The problem is you cannot really use that system unless you can SEE. A lot of Apple owners are not able to see, so they use the ECHO or other some other brand of speech synthesizer to speak everything that goes out to the screen. The configuration program cannot be made to speak, as it is now written.