Discussion:
creating a new Apple IIgs ROM 03 checksum
(too old to reply)
retrogear
2013-04-24 11:16:09 UTC
Permalink
With the hopes of someday producing a ROM 03 source which could be modified, I decided to embark on the issue of how to create a new ROM checksum. What is required from Apple is the checksum must equal a magic value of $1234. A fudge value called 'tweak' is placed at address FF/FFF6 to make the sum = $1234. I figured if I could do a checksum and skip the tweak then use a little algebra I could come up with a new tweak value. I derived the following subroutine from the checksum diagnostics source. It does a checksum calculation without the tweak value then calculates: tweak = $1234 - checksum. I reassembled the gsport emulator to not do any ROM patches, then ran my subroutine which returned the value $6250 which is the tweak value in the ROM !!! Verify with FF/FFF6.FFF7
returns FF/FFF6: 50 62. Here is the routine in Orca/m :

keep checksum
mcopy prodos.mac

* this subroutine does a ROM 03 checksum calculation to determine
* a 'tweak' value to place in ROM location $FF/FFF6.FFF7 which
* will certify this ROM to pass onboard ROM diagnostics.
* to be certified, the checksum of this ROM should = $1234

checksum start

tweak equ $FFF6 ;tweak value address

clc
xce ;full native mode
long i,m
longa on
longi on
lda #0
sta chksum ;reset checksum
pea $FCFC ;start with bank $FC
plb
plb
ldy #$FFFF
jsr chksum1 ;do checksum of bank $FC
pea $FDFD ;bank $FD
plb
plb
dey
jsr chksum2 ;do checksum of bank $FD
pea $FEFE ;bank $FE
plb
plb
dey
jsr chksum2 ;do checksum of bank $FE
pea $FFFF ;bank $FF
plb
plb
dey
jsr chksum3 ;do checksum of bank $FF
pea $0000
plb
plb
sta chksum ;ROM checksum minus 'tweak'
lda #$1234 ;certified checksum from Apple
sbc chksum ;carry is pre-conditioned
sta chksum ;new tweak = $1234 minus checksum
rtl ;return to caller
chksum1 lda #$0000
clc
chksum2 dey
nxtchk adc ($FD),y
dey
beq chkend
dey
bne nxtchk
chkend adc ($FD),y
rts
chksum3 dey
ffnxtchk php ;need to preserve carry flag
cpy #tweak ;check for tweak address
bne noskip
plp ;restore carry
bra skip ;skip adding tweak into checksum
noskip plp ;restore carry
adc ($FD),y
skip dey
beq ffchkend
dey
bne ffnxtchk
ffchkend adc ($FD),y
rts ;returns w/conditioned carry

chksum ds 2 ;will contain the new tweak value

end
Antoine Vignau
2013-04-24 13:33:41 UTC
Permalink
I am skeptical. There are inits missing...
Av
retrogear
2013-04-24 15:23:38 UTC
Permalink
I am skeptical. There are inits missing... Av
Orca assembles it by default to $2000 maybe because of the 'keep' statement?. I just execute it from the monitor with 2000g and it returns with the value. I am going to test it some more by playing with the ROM hex file. It's fun to experiment...

Larry
Antoine Vignau
2013-04-24 16:53:18 UTC
Permalink
You assume $fd..$fe are set to 0 because they are unused ZP locations?

av
retrogear
2013-04-24 17:02:45 UTC
Permalink
You assume $fd..$fe are set to 0 because they are unused ZP locations? av
Good catch. Need to init to 0 at beginning - thanks.

Larry
barrym95838
2013-04-24 17:15:29 UTC
Permalink
Post by Antoine Vignau
You assume $fd..$fe are set to 0 because they are unused ZP locations?
Hi Antoine.

Please correct me if I'm being foolish, because I've never done anything in 65c816 assembly, but wouldn't bank "wrap-around" make the base vector in $fd(e) irrelevant, as long as he's check-summing all 64k?

Mike
Antoine Vignau
2013-04-24 18:23:21 UTC
Permalink
I do not know if i understand wrap around correctly but what i can say is:
- if you set the data bank with pea plb plbthen you can use the ($) zp addressing instead of the long one. Useful for saving cycles.

I am not an orca expert, are long a.m.x etc. sufficient? No need for a REP #$30?

Reading code on a smartphone is a nightmare!!!
Av
retrogear
2013-04-24 19:06:08 UTC
Permalink
I do not know if i understand wrap around correctly but what i can say is: - if you set the data bank with pea plb plbthen you can use the ($) zp addressing instead of the long one. Useful for saving cycles. I am not an orca expert, are long a.m.x etc. sufficient? No need for a REP #$30? Reading code on a smartphone is a nightmare!!! Av
long i,m generates the REP #$30

Larry
Antoine Vignau
2013-04-24 19:13:29 UTC
Permalink
Thanks, Larry
Av
barrym95838
2013-04-25 00:35:53 UTC
Permalink
Post by Antoine Vignau
- if you set the data bank with pea plb plbthen you can use the ($) zp addressing instead of the long one. Useful for saving cycles.
I am not an orca expert, are long a.m.x etc. sufficient? No need for a REP #$30?
It seems to me that if the uninitialized value @ $fd is an odd number, then the 16-bit check-sum is guaranteed to be incorrect. If it's an even number, then it might be okay due to wrap-around. I have almost no 65c816 experience, but it seems to me (with all due respect) that Larry's subroutine is a candidate for some revisions and optimizations. If I'm stepping out of line, I apologize, especially since I would have to do some studying before being able to do any better.

Mike
retrogear
2013-04-25 01:33:58 UTC
Permalink
No way are you stepping out of line. All discussion is welcome. This is not actually 'my' subroutine. This is the ROM diagnostic routine from the System 601 sources which I modified into a subroutine to calculate the checksum needed to pass the diagnostic. I agree that FD and FE sould be inited to 0. It just happens they are 0. This led to a new discovery. I'm going to start a new thread about getting further with the Twain ROM !!! Larry
Antoine Vignau
2013-04-25 05:01:18 UTC
Permalink
We are in ROM. Diagnostics resets the machine, thus plenty of ZP values are 0, that seems normal if the code is executed prior to anything else.
Here, this is a program that is executed in RAM after booting, with an OS installed. You just do not have the guarantee that ZP values are 0.

Antoine
barrym95838
2013-04-25 06:05:57 UTC
Permalink
Post by Antoine Vignau
[...]
Here, this is a program that is executed in RAM after booting, with an OS installed. You just do not have the guarantee that ZP values are 0.
Hi, Antoine

I'm sure that Larry understands. I haven't compared my cycle counts with your $0000,x example, but what do you think about something like this? I always seem to favor shorter over faster when I compose, but I think my way shouldn't be much slower ...

[...]
lda #0
tax
clc
ckloop adc $fd0000,x
adc $fe0000,x
adc $ff0000,x
inx
inx
bne ckloop
[...]

Mike
barrym95838
2013-04-25 06:09:43 UTC
Permalink
oops! I meant ...

[...]
lda #0
tax
clc
ckloop adc $fc0000,x
adc $fd0000,x
adc $fe0000,x
adc $ff0000,x
inx
inx
bne ckloop
[...]

Mike
barrym95838
2013-04-25 06:34:39 UTC
Permalink
Post by barrym95838
[...]
I always seem to favor shorter over faster when I compose,
but I think my way shouldn't be much slower ...
Well, at first glance, it looks like:

Larry's: ~1.8 M clocks
Antoine's: ~1.4 M clocks
Mine: ~1.0 M clocks

If I didn't make a horrible rookie coding- or cycle-counting error, it looks like my way is the shortest AND the fastest.

Mike
Antoine Vignau
2013-04-25 09:31:56 UTC
Permalink
Sure! Nice speed improvement but you have to skip the magic word of bank $FF
Av
Jerry
2013-04-26 05:26:24 UTC
Permalink
Post by Antoine Vignau
Sure! Nice speed improvement but you have to skip the magic word of bank $FF
Av
Couldn't this magic word be subtracted after all the other summing was
complete? SEC, SBC abs-long, and you're done?

--
Jerry awanderin at yahoo dot ca
retrogear
2013-04-26 05:58:15 UTC
Permalink
Couldn't this magic word be subtracted after all the other summing was complete? SEC, SBC abs-long, and you're done? -- Jerry awanderin at yahoo dot ca

sum + 'magic word' = 1234
(solving for magic word)
'magic word' = 1234 - sum

The magic word is the unknown. I'm not a math teacher so maybe there could be an easier solution but this works - Larry
barrym95838
2013-04-28 03:41:21 UTC
Permalink
Post by Jerry
Couldn't this magic word be subtracted after all the other summing was
complete? SEC, SBC abs-long, and you're done?
Hi, Jerry

I strongly agree that adding it with everything else in the inner loop and subtracting it when done is the more desirable choice, since that strategy is just as compact, and much faster than 32768 php/cpy/bne/plp combos! I know, we're only talking about a few hundred milliseconds in this particular case, but the benefit of being aware of this is that it can help in other projects, ones that may have much longer loops and/or tight performance constraints.

Of course, if we were coding for a "more modern" processor, some of us might just let it go as is, and let brute power take over. I don't usually include myself in that group, since I will likely have an 8-bit mentality for life! ;-)

Mike
Michael J. Mahon
2013-04-28 04:11:37 UTC
Permalink
Post by barrym95838
Post by Jerry
Couldn't this magic word be subtracted after all the other summing was
complete? SEC, SBC abs-long, and you're done?
Hi, Jerry
I strongly agree that adding it with everything else in the inner loop
and subtracting it when done is the more desirable choice, since that
strategy is just as compact, and much faster than 32768 php/cpy/bne/plp
combos! I know, we're only talking about a few hundred milliseconds in
this particular case, but the benefit of being aware of this is that it
can help in other projects, ones that may have much longer loops and/or
tight performance constraints.
Of course, if we were coding for a "more modern" processor, some of us
might just let it go as is, and let brute power take over. I don't
usually include myself in that group, since I will likely have an 8-bit
mentality for life! ;-)
Mike
It also acknowledges that the "twiddle" value can be anywhere, not just
where it happens to be located currently.

In fact, a program seeking to identify an unmatched ROM might not only
require the checksum to be as expected, but might also require the original
twiddle value to be unchanged. In this case, one would have to leave the
original twiddle value and add another elsewhere to correct the checksum.

The main point is that it is completely unnecessary to know where the
"original" twiddle value is, or even if there is one. Just add a word that
causes the checksum to be unchanged.

-michael - NadaNet 3.1 and AppleCrate II: http://home.comcast.net/~mjmahon
Michael J. Mahon
2013-04-28 14:11:00 UTC
Permalink
Post by Michael J. Mahon
Post by barrym95838
Post by Jerry
Couldn't this magic word be subtracted after all the other summing was
complete? SEC, SBC abs-long, and you're done?
Hi, Jerry
I strongly agree that adding it with everything else in the inner loop
and subtracting it when done is the more desirable choice, since that
strategy is just as compact, and much faster than 32768 php/cpy/bne/plp
combos! I know, we're only talking about a few hundred milliseconds in
this particular case, but the benefit of being aware of this is that it
can help in other projects, ones that may have much longer loops and/or
tight performance constraints.
Of course, if we were coding for a "more modern" processor, some of us
might just let it go as is, and let brute power take over. I don't
usually include myself in that group, since I will likely have an 8-bit
mentality for life! ;-)
Mike
It also acknowledges that the "twiddle" value can be anywhere, not just
where it happens to be located currently.
In fact, a program seeking to identify an unmatched ROM might not only
Should be "unpatched"--(autocorrect). ;-(
Post by Michael J. Mahon
require the checksum to be as expected, but might also require the original
twiddle value to be unchanged. In this case, one would have to leave the
original twiddle value and add another elsewhere to correct the checksum.
The main point is that it is completely unnecessary to know where the
"original" twiddle value is, or even if there is one. Just add a word that
causes the checksum to be unchanged.
-michael - NadaNet 3.1 and AppleCrate II: http://home.comcast.net/~mjmahon
D Finnigan
2013-04-28 04:30:48 UTC
Permalink
Post by barrym95838
Of course, if we were coding for a "more modern" processor, some of us
might just let it go as is, and let brute power take over. I don't
usually
include myself in that group, since I will likely have an 8-bit mentality
for life! ;-)
Same here. Programming on the Apple II has affected how I think and program
in high-level language on today's computers. Permanently, I'm afraid. ;-)
barrym95838
2013-04-28 08:30:33 UTC
Permalink
Post by D Finnigan
Same here. Programming on the Apple II has affected how I think and program
in high-level language on today's computers. Permanently, I'm afraid. ;-)
Imagine how small and fast Windoze would be, if everyone at Micro$oft had our mentality! I'm sure that it would still crash once in a while, but I'm also sure that it would haul a$$ between crashes, with all of that horse-power on tap!

Mike
Antoine Vignau
2013-04-24 18:33:16 UTC
Permalink
2000x would be better too ;-)
The code ends with RTL, reset MX and emulation code too.

Just wondering if (hope my S2 will support this... fu.. virtual kbd)

Lda #0
Tax
Pea bnkbnk
Plb
Plb
Jsr checksum1....

Checksum call / keep clc where needed
Here:
Adc $0000,x
Inx
Inx
Bne here:
Antoine Vignau
2013-04-24 18:38:42 UTC
Permalink
From my understanding of the original code, this is a checksum from 16-bit values every 2 bytes, then the DEY BEQ END is useless.

Am i right?
Av
retrogear
2013-04-24 19:32:44 UTC
Permalink
From my understanding of the original code, this is a checksum from 16-bit values every 2 bytes, then the DEY BEQ END is useless. Am i right? Av
it could be, or just added insurance it doesn't double decrement below zero

Larry
Michael J. Mahon
2013-04-24 16:51:24 UTC
Permalink
Post by retrogear
With the hopes of someday producing a ROM 03 source which could be
modified, I decided to embark on the issue of how to create a new ROM
checksum. What is required from Apple is the checksum must equal a magic
value of $1234. A fudge value called 'tweak' is placed at address FF/FFF6
to make the sum = $1234. I figured if I could do a checksum and skip the
tweak then use a little algebra I could come up with a new tweak value. I
derived the following subroutine from the checksum diagnostics source. It
tweak = $1234 - checksum. I reassembled the gsport emulator to not do any
ROM patches, then ran my subroutine which returned the value $6250 which
is the tweak value in the ROM !!! Verify with FF/FFF6.FFF7
keep checksum
mcopy prodos.mac
* this subroutine does a ROM 03 checksum calculation to determine
* a 'tweak' value to place in ROM location $FF/FFF6.FFF7 which
* will certify this ROM to pass onboard ROM diagnostics.
* to be certified, the checksum of this ROM should = $1234
checksum start
tweak equ $FFF6 ;tweak value address
clc
xce ;full native mode
long i,m
longa on
longi on
lda #0
sta chksum ;reset checksum
pea $FCFC ;start with bank $FC
plb
plb
ldy #$FFFF
jsr chksum1 ;do checksum of bank $FC
pea $FDFD ;bank $FD
plb
plb
dey
jsr chksum2 ;do checksum of bank $FD
pea $FEFE ;bank $FE
plb
plb
dey
jsr chksum2 ;do checksum of bank $FE
pea $FFFF ;bank $FF
plb
plb
dey
jsr chksum3 ;do checksum of bank $FF
pea $0000
plb
plb
sta chksum ;ROM checksum minus 'tweak'
lda #$1234 ;certified checksum from Apple
sbc chksum ;carry is pre-conditioned
sta chksum ;new tweak = $1234 minus checksum
rtl ;return to caller
chksum1 lda #$0000
clc
chksum2 dey
nxtchk adc ($FD),y
dey
beq chkend
dey
bne nxtchk
chkend adc ($FD),y
rts
chksum3 dey
ffnxtchk php ;need to preserve carry flag
cpy #tweak ;check for tweak address
bne noskip
plp ;restore carry
bra skip ;skip adding tweak into checksum
noskip plp ;restore carry
adc ($FD),y
skip dey
beq ffchkend
dey
bne ffnxtchk
ffchkend adc ($FD),y
rts ;returns w/conditioned carry
chksum ds 2 ;will contain the new tweak value
end
This is essentially the same approach I took in creating the NadaBoot
ROM(s) for AppleCrate machines.

Just once, load the original ROM file and compute its checksum, then for
each modification:

1. Load the new ROM file, with zero "twiddle"
2. Compute the checksum
3. Subtract new checksum from original ROM checksum
4. Poke difference into "twiddle"
5. Re-checksum to verify same as original

Of course, the "twiddle" value can be any unused location within the ROM.

-michael - NadaNet 3.1 and AppleCrate II: http://home.comcast.net/~mjmahon
Loading...