TOS checksums ?

News,announcements,programming,fixes,game patches & discussions.

Moderator: troed

Post Reply
User avatar
exxos
Site Admin
Site Admin
Posts: 23499
Joined: Wed Aug 16, 2017 11:19 pm
Location: UK
Contact:

TOS checksums ?

Post by exxos »

Example TOS206.HI has a checksum of 07 C8... But does anyone know how this is created ? I tried various checksums in winhex but can't seem to match it. Really I want a way of doing this in basic :)


EDIT:

OK this looks a bit more complicated that I thought... Can someone "translate" ? :lol:


Code: Select all

		text
/*
 * uint16_t check_rom_crc(void *start, long count, short offset)
 * For 512k ROMs in 4x128k chips (TOS 3.x), call with
 *      check_rom_crc(0xe00000, 0x1fffe, 4)
 *      check_rom_crc(0xe00001, 0x1fffe, 4)
 *      check_rom_crc(0xe00002, 0x1fffe, 4)
 *      check_rom_crc(0xe00003, 0x1fffe, 4)
 * For 512k ROMs in a single chip (TOS 4.x), call with
 *      check_rom_crc(0xe00000, 0x7fffe, 1)
 * For 256k ROMs in 2x128k chips (TOS 2.x), call with
 *      check_rom_crc(0xe00000, 0x3fffe, 2)
 *      check_rom_crc(0xe00001, 0x3fffe, 2)
 * Older TOS (192k images) do not have a checksum.
 */
/* 306de: 00e01724 */
/* 206de: 00e015b4 */
check_rom_crc:
        movea.l   4(a7),a0
        move.l    8(a7),d2
        movea.w   12(a7),a1
        clr.w     d0
        clr.w     d1
        clr.w     d3
        lea.l     rom_crc_table,a2
ckcrc1:
        move.w    d0,d1
        lsl.w     #8,d0
        lsr.w     #8,d1
        move.b    (a0),d3
        adda.l    a1,a0
        eor.b     d3,d1
        add.w     d1,d1
        move.w    0(a2,d1.w),d4
        eor.w     d4,d0
        subq.l    #1,d2
        bne.s     ckcrc1
        rts

	data

rom_crc_table:
	dc.w $0000,$1021,$2042,$3063,$4084,$50a5,$60c6,$70e7
        dc.w $8108,$9129,$a14a,$b16b,$c18c,$d1ad,$e1ce,$f1ef
        dc.w $1231,$0210,$3273,$2252,$52b5,$4294,$72f7,$62d6
        dc.w $9339,$8318,$b37b,$a35a,$d3bd,$c39c,$f3ff,$e3de
        dc.w $2462,$3443,$0420,$1401,$64e6,$74c7,$44a4,$5485
        dc.w $a56a,$b54b,$8528,$9509,$e5ee,$f5cf,$c5ac,$d58d
        dc.w $3653,$2672,$1611,$0630,$76d7,$66f6,$5695,$46b4
        dc.w $b75b,$a77a,$9719,$8738,$f7df,$e7fe,$d79d,$c7bc
        dc.w $48c4,$58e5,$6886,$78a7,$0840,$1861,$2802,$3823
        dc.w $c9cc,$d9ed,$e98e,$f9af,$8948,$9969,$a90a,$b92b
        dc.w $5af5,$4ad4,$7ab7,$6a96,$1a71,$0a50,$3a33,$2a12
        dc.w $dbfd,$cbdc,$fbbf,$eb9e,$9b79,$8b58,$bb3b,$ab1a
        dc.w $6ca6,$7c87,$4ce4,$5cc5,$2c22,$3c03,$0c60,$1c41
        dc.w $edae,$fd8f,$cdec,$ddcd,$ad2a,$bd0b,$8d68,$9d49
        dc.w $7e97,$6eb6,$5ed5,$4ef4,$3e13,$2e32,$1e51,$0e70
        dc.w $ff9f,$efbe,$dfdd,$cffc,$bf1b,$af3a,$9f59,$8f78
        dc.w $9188,$81a9,$b1ca,$a1eb,$d10c,$c12d,$f14e,$e16f
        dc.w $1080,$00a1,$30c2,$20e3,$5004,$4025,$7046,$6067
        dc.w $83b9,$9398,$a3fb,$b3da,$c33d,$d31c,$e37f,$f35e
        dc.w $02b1,$1290,$22f3,$32d2,$4235,$5214,$6277,$7256
        dc.w $b5ea,$a5cb,$95a8,$8589,$f56e,$e54f,$d52c,$c50d
        dc.w $34e2,$24c3,$14a0,$0481,$7466,$6447,$5424,$4405
        dc.w $a7db,$b7fa,$8799,$97b8,$e75f,$f77e,$c71d,$d73c
        dc.w $26d3,$36f2,$0691,$16b0,$6657,$7676,$4615,$5634
        dc.w $d94c,$c96d,$f90e,$e92f,$99c8,$89e9,$b98a,$a9ab
        dc.w $5844,$4865,$7806,$6827,$18c0,$08e1,$3882,$28a3
        dc.w $cb7d,$db5c,$eb3f,$fb1e,$8bf9,$9bd8,$abbb,$bb9a
        dc.w $4a75,$5a54,$6a37,$7a16,$0af1,$1ad0,$2ab3,$3a92
        dc.w $fd2e,$ed0f,$dd6c,$cd4d,$bdaa,$ad8b,$9de8,$8dc9
        dc.w $7c26,$6c07,$5c64,$4c45,$3ca2,$2c83,$1ce0,$0cc1
        dc.w $ef1f,$ff3e,$cf5d,$df7c,$af9b,$bfba,$8fd9,$9ff8
        dc.w $6e17,$7e36,$4e55,$5e74,$2e93,$3eb2,$0ed1,$1ef0

	text

https://www.exxosforum.co.uk/atari/ All my hardware guides - mods - games - STOS
https://www.exxosforum.co.uk/atari/store2/ - All my hardware mods for sale - Please help support by making a purchase.
viewtopic.php?f=17&t=1585 Have you done the Mandatory Fixes ?
Just because a lot of people agree on something, doesn't make it a fact. ~exxos ~
People should find solutions to problems, not find problems with solutions.
User avatar
exxos
Site Admin
Site Admin
Posts: 23499
Joined: Wed Aug 16, 2017 11:19 pm
Location: UK
Contact:

Re: TOS checksums ?

Post by exxos »

It looks like its taking a bank size of $1fffe and adding every 4th byte up.. I will have to start a routine and see if things add up anywhere..

Code: Select all

/*
 * check the ROM crc
 */
#if STBOOK | (TOSVERSION >= 0x400)
banksize equ $3fffe
numbanks equ 1
#else
#if TOSVERSION < 0x300
banksize equ $1fffe
numbanks equ 2
#else
banksize equ $1fffe
numbanks equ 4
#endif
#endif

        move.l    #banksize,d7
        move.w    #numbanks-1,d6
        movea.l   #_os_entry,a5
crccheck:
        move.w    #numbanks,-(a7)    /* checksum over every nth byte */
        move.l    d7,-(a7)           /* number of bytes */
        move.l    a5,-(a7)           /* buffer address */
        bsr       check_rom_crc
        adda.w    #10,a7
        movea.l   a5,a0
#if STBOOK | (TOSVERSION >= 0x400)
        adda.l    d7,a0
#else
        adda.l    #banksize*numbanks,a0
#endif
        move.b    (a0),d1            /* high byte of CRC */
        lsl.w     #8,d1
        move.b    numbanks(a0),d1    /* low byte of CRC */
        cmp.w     d1,d0
        bne.s     crcfail
        addq.l    #1,a5
        dbf       d6,crccheck
#if TP_50 /* PAK */
        bra       crcok
#else
        bra.s     crcok
#endif
crcmsg: dc.b 'WARNING: BAD ROM CRC IN CHIP ',0
crcmsg2 dc.b '.',13,10,0
crcfail:
        move.l    a5,d5
        pea.l     crcmsg
        move.w    #9,-(a7)
        trap      #1
        move.b    #$45,d0            /* 'E' - even */
        btst      #0,d5
        beq.s     chipE
        move.b    #$4F,d0            /* 'O' - odd */
chipE:
        move.w    d0,2(a7)
        move.w    #2,(a7)
        trap      #1
#if TOSVERSION >= 0x300
        move.b    #$45,d0            /* 'E' - even */
        btst      #1,d5
        beq.s     chipE2
        move.b    #$4F,d0            /* 'O' - odd */
chipE2:
        move.w    d0,2(a7)
        move.w    #2,(a7)
        trap      #1
#endif
        move.l    #crcmsg2,2(a7)
        move.w    #9,(a7)
        trap      #1
        addq.w    #6,a7
        addq.l    #1,a5


EDIT:

Code: Select all

 * For 256k ROMs in 2x128k chips (TOS 2.x), call with
 *      check_rom_crc(0xe00000, 0x3fffe, 2)
 *      check_rom_crc(0xe00001, 0x3fffe, 2)
Going by the data sizes (8x32) it would work out each 4 numbers would be a checksum of 1023 bytes...
https://www.exxosforum.co.uk/atari/ All my hardware guides - mods - games - STOS
https://www.exxosforum.co.uk/atari/store2/ - All my hardware mods for sale - Please help support by making a purchase.
viewtopic.php?f=17&t=1585 Have you done the Mandatory Fixes ?
Just because a lot of people agree on something, doesn't make it a fact. ~exxos ~
People should find solutions to problems, not find problems with solutions.
User avatar
PhilC
Moderator
Moderator
Posts: 6016
Joined: Fri Mar 23, 2018 8:22 pm

Re: TOS checksums ?

Post by PhilC »

Do you even need the rom crc any more? Surely it's easier to nop the jump to the routine? Or something similar?

First crack I did on the Amiga was just a simple nop, I did start easy though, with battle chess.
If it ain't broke, test it to Destruction.
User avatar
exxos
Site Admin
Site Admin
Posts: 23499
Joined: Wed Aug 16, 2017 11:19 pm
Location: UK
Contact:

Re: TOS checksums ?

Post by exxos »

I guess it could be skipped.. Though I think I rather have it there... It helps with debugging booters etc.
https://www.exxosforum.co.uk/atari/ All my hardware guides - mods - games - STOS
https://www.exxosforum.co.uk/atari/store2/ - All my hardware mods for sale - Please help support by making a purchase.
viewtopic.php?f=17&t=1585 Have you done the Mandatory Fixes ?
Just because a lot of people agree on something, doesn't make it a fact. ~exxos ~
People should find solutions to problems, not find problems with solutions.
User avatar
thorsten.otto
Posts: 148
Joined: Mon Nov 04, 2019 2:20 am

Re: TOS checksums ?

Post by thorsten.otto »

These are C-routines to check & update the CRCs. They are copied from another project, so are somewhat incomplete: the file loading routines are missing, and you have to set some variable like the length of the tos file, and the version which can be extracted from the header.

Code: Select all

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

static unsigned char *tosmem;
static size_t tossize;
static size_t tosstart;
static unsigned short tos_version;
static int is_emutos;

#define ONE_KB (1024u)

static unsigned short const crc_tab[256] = {
	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
	0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
	0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
	0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
	0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
	0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
	0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
	0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
	0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
	0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
	0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
	0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
	0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
	0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
	0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
	0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};


static uint16_t calc_crc(uint32_t pos, uint32_t size, uint32_t inc)
{
	uint16_t sum;
	uint16_t run;
	uint8_t *p;
	
	p = tosmem + pos;
	sum = run = 0;
	do {
		run = sum;
		sum <<= 8;
		run >>= 8;
		run ^= *p;
		sum ^= crc_tab[run];
		p += inc;
	} while (--size != 0);
	return sum;
}


int check_rom_crcs(void)
{
	uint32_t size;
	uint32_t banksize;
	uint32_t crcpos;
	uint16_t crc, sum;
	int i, banks;

	size = tossize;
	/*
	 * check the current crc.
	 * not all tos versions perform a CRC check,
	 * and the file that we loaded might have been patched already,
	 * so we don't update the crc if it wasn't right before
	 */
	if ((tos_version >= 0x400 && tos_version < 0x500) && size > 256 * ONE_KB)
	{
		/*
		 * Falcon TOS 4.x: a single 512KB ROM
		 */
		banks = 1;
		banksize = ((size + 1) & ~1) - 2;
	} else if ((tos_version == 0x206 || tos_version == 0x207 || tos_version == 0x208) &&
		size > 256 * ONE_KB &&
		!is_emutos)
	{
		/*
		 * ST-Book TOS 2.x: a single 256KB ROM
		 * The second half of the image contains a cartridge ROM
		 */
		banks = 1;
		banksize = (((size >> 1) + 1) & ~1) - 2;
	} else if (size > 256 * ONE_KB)
	{
		/*
		 * TT TOS 3.x: 4 128KB ROMs
		 */
		banks = 4;
		banksize = (((size + 3) / 4) & ~1) - 2;
	} else if (size > 192 * ONE_KB)
	{
		/*
		 * STE TOS 2.x: 2 128KB ROMs
		 */
		banks = 2;
		/*
		 * size should be only -4 (for the 4 checksum bytes at the end),
		 * but i've seen patched TOSes that are 1 byte too short,
		 * hence the +1
		 */
		banksize = (((size + 1) / 2) & ~1) - 2;
	} else
	{
		/*
		 * TOS 1.x: 6 32KB ROMs, without CRC
		 */
		banks = -1;
		banksize = 0;
	}
	if (banks > 0)
	{
		for (i = 0; i < banks; i++)
		{
			crc = calc_crc(tosstart + i, banksize, banks);
			crcpos = tosstart + banksize * banks + i;
			sum = (tosmem[crcpos] << 8) | tosmem[crcpos + banks];
			if (crc != sum)
			{
				banks = 0;
				fprintf(stderr, "TOS: WARNING: BAD ROM CRC IN CHIP %d\n", i);
			}
		}
	}
	if (banks > 0)
		fprintf(stderr, "TOS: CRC for %uKB ok\n", size >> 10);
	return banks > 0;
}


void update_rom_crcs(void)
{
	uint32_t size;
	uint32_t banksize;
	uint32_t crcpos;
	uint16_t crc, sum;
	int i, banks;

	size = tossize;
	/*
	 * check the current crc.
	 * not all tos versions perform a CRC check,
	 * and the file that we loaded might have been patched already,
	 * so we don't update the crc if it wasn't right before
	 */
	if ((tos_version >= 0x400 && tos_version < 0x500) && size > 256 * ONE_KB)
	{
		/*
		 * Falcon TOS 4.x: a single 512KB ROM
		 */
		banks = 1;
		banksize = ((size + 1) & ~1) - 2;
	} else if ((tos_version == 0x206 || tos_version == 0x207 || tos_version == 0x208) &&
		size > 256 * ONE_KB &&
		!is_emutos)
	{
		/*
		 * ST-Book TOS 2.x: a single 256KB ROM
		 * The second half of the image contains a cartridge ROM
		 */
		banks = 1;
		banksize = (((size >> 1) + 1) & ~1) - 2;
	} else if (size > 256 * ONE_KB)
	{
		/*
		 * TT TOS 3.x: 4 128KB ROMs
		 */
		banks = 4;
		banksize = (((size + 3) / 4) & ~1) - 2;
	} else if (size > 192 * ONE_KB)
	{
		/*
		 * STE TOS 2.x: 2 128KB ROMs
		 */
		banks = 2;
		/*
		 * size should be only -4 (for the 4 checksum bytes at the end),
		 * but i've seen patched TOSes that are 1 byte too short,
		 * hence the +1
		 */
		banksize = (((size + 1) / 2) & ~1) - 2;
	} else
	{
		/*
		 * TOS 1.x: 6 32KB ROMs, without CRC
		 */
		banks = -1;
		banksize = 0;
	}
	if (banks > 0)
	{
		for (i = 0; i < banks; i++)
		{
			crc = calc_crc(tosstart + i, banksize, banks);
			crcpos = tosstart + banksize * banks + i;
			sum = (tosmem[crcpos] << 8) | tosmem[crcpos + banks];
			tosmem[crcpos] = crc >> 8;
			tosmem[crcpos + banks] = crc;
			if (sum != crc)
				fprintf(stderr, "ROM checksum %d updated from %04x to %04x\n", i, sum, crc);
		}
	}
}



User avatar
stephen_usher
Posts: 5580
Joined: Mon Nov 13, 2017 7:19 pm
Location: Oxford, UK.
Contact:

Re: TOS checksums ?

Post by stephen_usher »

Based upon that code, here's a CRC fixing program.

Usage: fixcrc tos.img

If the CRC is not correct it writes a modified file out with the same name but with the suffix ".new" added.

I've not tried compiling it under Linux or anything else other than macOS using gcc but it's all just using standard C library stuff.
Attachments
fixcrc.zip
(3.4 KiB) Downloaded 37 times
Intro retro computers since before they were retro...
ZX81->Spectrum->Memotech MTX->Sinclair QL->520STM->BBC Micro->TT030->PCs & Sun Workstations.
Added code to the MiNT kernel (still there the last time I checked) + put together MiNTOS.
Collection now with added Macs, Amigas, Suns and Acorns.
User avatar
sporniket
Posts: 956
Joined: Sat Sep 26, 2020 9:12 pm
Location: France
Contact:

Re: TOS checksums ?

Post by sporniket »

exxos wrote: Thu Jan 02, 2020 10:19 pm It looks like its taking a bank size of $1fffe and adding every 4th byte up.. I will have to start a routine and see if things add up anywhere..
The offset is because bytes are split among eprom chips, so the crc is done chip by chip ?
Post Reply

Return to “SOFTWARE PROGRAMMING & DISCUSSION”