Split off the CRC code to its own module.

This commit is contained in:
OBattler
2025-02-15 07:09:14 +01:00
parent 4a93a939fb
commit c6dfd688f4
5 changed files with 143 additions and 57 deletions

View File

@@ -28,6 +28,7 @@
#define HAVE_STDARG_H #define HAVE_STDARG_H
#include <86box/86box.h> #include <86box/86box.h>
#include <86box/timer.h> #include <86box/timer.h>
#include <86box/crc.h>
#include <86box/dma.h> #include <86box/dma.h>
#include <86box/nvr.h> #include <86box/nvr.h>
#include <86box/random.h> #include <86box/random.h>
@@ -223,6 +224,7 @@ typedef struct d86f_t {
uint8_t *filebuf; uint8_t *filebuf;
uint8_t *outbuf; uint8_t *outbuf;
sector_t *last_side_sector[2]; sector_t *last_side_sector[2];
uint16_t crc_table[256];
} d86f_t; } d86f_t;
static const uint8_t encoded_fm[64] = { static const uint8_t encoded_fm[64] = {
@@ -247,7 +249,6 @@ static const uint8_t encoded_mfm[64] = {
}; };
static d86f_t *d86f[FDD_NUM]; static d86f_t *d86f[FDD_NUM];
static uint16_t CRCTable[256];
static fdc_t *d86f_fdc; static fdc_t *d86f_fdc;
uint64_t poly = 0x42F0E1EBA9EA3693LL; /* ECMA normal */ uint64_t poly = 0x42F0E1EBA9EA3693LL; /* ECMA normal */
@@ -276,28 +277,6 @@ d86f_log(const char *fmt, ...)
# define d86f_log(fmt, ...) # define d86f_log(fmt, ...)
#endif #endif
static void
setup_crc(uint16_t poly)
{
int c = 256;
int bc;
uint16_t temp;
while (c--) {
temp = c << 8;
bc = 8;
while (bc--) {
if (temp & 0x8000)
temp = (temp << 1) ^ poly;
else
temp <<= 1;
CRCTable[c] = temp;
}
}
}
void void
d86f_destroy_linked_lists(int drive, int side) d86f_destroy_linked_lists(int drive, int side)
{ {
@@ -1237,16 +1216,10 @@ decodefm(UNUSED(int drive), uint16_t dat)
return temp; return temp;
} }
void
fdd_calccrc(uint8_t byte, crc_t *crc_var)
{
crc_var->word = (crc_var->word << 8) ^ CRCTable[(crc_var->word >> 8) ^ byte];
}
static void static void
d86f_calccrc(d86f_t *dev, uint8_t byte) d86f_calccrc(d86f_t *dev, uint8_t byte)
{ {
fdd_calccrc(byte, &(dev->calc_crc)); crc16_calc(dev->crc_table, byte, &(dev->calc_crc));
} }
int int
@@ -1274,7 +1247,9 @@ d86f_word_is_aligned(int drive, int side, uint32_t base_pos)
/* State 1: Find sector ID */ /* State 1: Find sector ID */
void void
d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, uint16_t other_am, uint16_t wrong_am, uint16_t ignore_other_am) d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am,
uint16_t other_am, uint16_t wrong_am,
uint16_t ignore_other_am)
{ {
d86f_t *dev = d86f[drive]; d86f_t *dev = d86f[drive];
@@ -1282,7 +1257,8 @@ d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, ui
if (dev->last_word[side] == req_am) { if (dev->last_word[side] == req_am) {
dev->calc_crc.word = 0xFFFF; dev->calc_crc.word = 0xFFFF;
fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); crc16_calc(dev->crc_table, decodefm(drive, dev->last_word[side]),
&(dev->calc_crc));
find->sync_marks = find->bits_obtained = find->sync_marks = find->bits_obtained =
find->bytes_obtained = 0; find->bytes_obtained = 0;
find->sync_pos = 0xFFFFFFFF; find->sync_pos = 0xFFFFFFFF;
@@ -1302,7 +1278,8 @@ d86f_find_address_mark_fm(int drive, int side, find_t *find, uint16_t req_am, ui
if ((ignore_other_am & 2) && (dev->last_word[side] == other_am)) { if ((ignore_other_am & 2) && (dev->last_word[side] == other_am)) {
dev->calc_crc.word = 0xFFFF; dev->calc_crc.word = 0xFFFF;
fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); crc16_calc(dev->crc_table, decodefm(drive, dev->last_word[side]),
&(dev->calc_crc));
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
find->sync_pos = 0xFFFFFFFF; find->sync_pos = 0xFFFFFFFF;
if (ignore_other_am & 1) { if (ignore_other_am & 1) {
@@ -1378,7 +1355,8 @@ d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_am, u
if ((dev->last_word[side] == req_am) && (find->sync_marks >= 3)) { if ((dev->last_word[side] == req_am) && (find->sync_marks >= 3)) {
if (d86f_word_is_aligned(drive, side, find->sync_pos)) { if (d86f_word_is_aligned(drive, side, find->sync_pos)) {
dev->calc_crc.word = 0xCDB4; dev->calc_crc.word = 0xCDB4;
fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); crc16_calc(dev->crc_table, decodefm(drive, dev->last_word[side]),
&(dev->calc_crc));
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
find->sync_pos = 0xFFFFFFFF; find->sync_pos = 0xFFFFFFFF;
dev->preceding_bit[side] = dev->last_word[side] & 1; dev->preceding_bit[side] = dev->last_word[side] & 1;
@@ -1390,7 +1368,8 @@ d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_am, u
if ((ignore_other_am & 2) && (dev->last_word[side] == other_am) && (find->sync_marks >= 3)) { if ((ignore_other_am & 2) && (dev->last_word[side] == other_am) && (find->sync_marks >= 3)) {
if (d86f_word_is_aligned(drive, side, find->sync_pos)) { if (d86f_word_is_aligned(drive, side, find->sync_pos)) {
dev->calc_crc.word = 0xCDB4; dev->calc_crc.word = 0xCDB4;
fdd_calccrc(decodefm(drive, dev->last_word[side]), &(dev->calc_crc)); crc16_calc(dev->crc_table, decodefm(drive, dev->last_word[side]),
&(dev->calc_crc));
find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; find->sync_marks = find->bits_obtained = find->bytes_obtained = 0;
find->sync_pos = 0xFFFFFFFF; find->sync_pos = 0xFFFFFFFF;
if (ignore_other_am & 1) { if (ignore_other_am & 1) {
@@ -1464,8 +1443,11 @@ d86f_read_sector_id(int drive, int side, int match)
if (dev->id_find.bytes_obtained < 4) { if (dev->id_find.bytes_obtained < 4) {
dev->last_sector.byte_array[dev->id_find.bytes_obtained] = dev->last_sector.byte_array[dev->id_find.bytes_obtained] =
decodefm(drive, dev->last_word[side]); decodefm(drive, dev->last_word[side]);
fdd_calccrc(dev->last_sector.byte_array[dev->id_find.bytes_obtained], &(dev->calc_crc)); crc16_calc(dev->crc_table,
} else if ((dev->id_find.bytes_obtained >= 4) && (dev->id_find.bytes_obtained < 6)) { dev->last_sector.byte_array[dev->id_find.bytes_obtained],
&(dev->calc_crc));
} else if ((dev->id_find.bytes_obtained >= 4) &&
(dev->id_find.bytes_obtained < 6)) {
dev->track_crc.bytes[(dev->id_find.bytes_obtained & 1) ^ 1] = dev->track_crc.bytes[(dev->id_find.bytes_obtained & 1) ^ 1] =
decodefm(drive, dev->last_word[side]); decodefm(drive, dev->last_word[side]);
} }
@@ -1643,7 +1625,7 @@ d86f_read_sector_data(int drive, int side)
} }
} }
} }
fdd_calccrc(data, &(dev->calc_crc)); crc16_calc(dev->crc_table, data, &(dev->calc_crc));
} else if (dev->data_find.bytes_obtained < crc_pos) } else if (dev->data_find.bytes_obtained < crc_pos)
dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] = dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] =
decodefm(drive, dev->last_word[side]); decodefm(drive, dev->last_word[side]);
@@ -1730,11 +1712,12 @@ d86f_write_sector_data(int drive, int side, int mfm, uint16_t am)
if (dev->data_find.bytes_obtained < sector_len) { if (dev->data_find.bytes_obtained < sector_len) {
/* This is a data byte, so CRC it. */ /* This is a data byte, so CRC it. */
if (!dev->data_find.bytes_obtained) { if (!dev->data_find.bytes_obtained)
fdd_calccrc(decodefm(drive, am), &(dev->calc_crc)); crc16_calc(dev->crc_table, decodefm(drive, am),
} else { &(dev->calc_crc));
fdd_calccrc(dev->current_byte[side], &(dev->calc_crc)); else
} crc16_calc(dev->crc_table, dev->current_byte[side],
&(dev->calc_crc));
} }
} }
} else { } else {
@@ -3861,8 +3844,6 @@ d86f_load(int drive, char *fn)
void void
d86f_init(void) d86f_init(void)
{ {
setup_crc(0x1021);
for (uint8_t i = 0; i < FDD_NUM; i++) for (uint8_t i = 0; i < FDD_NUM; i++)
d86f[i] = NULL; d86f[i] = NULL;
} }
@@ -3926,6 +3907,8 @@ d86f_setup(int drive)
dev->last_side_sector[0] = NULL; dev->last_side_sector[0] = NULL;
dev->last_side_sector[1] = NULL; dev->last_side_sector[1] = NULL;
crc16_setup(dev->crc_table, 0x1021);
/* Set the drive as active. */ /* Set the drive as active. */
d86f[drive] = dev; d86f[drive] = dev;
} }

34
src/include/86box/crc.h Normal file
View File

@@ -0,0 +1,34 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the CRC code.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2025 Miran Grca.
*/
#ifndef EMU_CRC_H
#define EMU_CRC_H
#ifdef __cplusplus
extern "C" {
#endif
typedef union {
uint16_t word;
uint8_t bytes[2];
} crc_t;
extern void crc16_setup(uint16_t *crc_table, uint16_t poly);
extern void crc16_calc(uint16_t *crc_table, uint8_t byte, crc_t *crc_var);
#ifdef __cplusplus
}
#endif
#endif /*EMU_CRC_H*/

View File

@@ -8,15 +8,13 @@
* *
* Definitions for the floppy drive emulation. * Definitions for the floppy drive emulation.
* *
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/> * Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com> * Fred N. van Kempen, <decwiz@yahoo.com>
* *
* Copyright 2008-2018 Sarah Walker. * Copyright 2008-2025 Sarah Walker.
* Copyright 2016-2018 Miran Grca. * Copyright 2016-2025 Miran Grca.
* Copyright 2018 Fred N. van Kempen. * Copyright 2018-2025 Fred N. van Kempen.
*/ */
#ifndef EMU_FDD_H #ifndef EMU_FDD_H
#define EMU_FDD_H #define EMU_FDD_H
@@ -129,13 +127,6 @@ extern int drive_empty[FDD_NUM];
#define SECTOR_FIRST -2 #define SECTOR_FIRST -2
#define SECTOR_NEXT -1 #define SECTOR_NEXT -1
typedef union {
uint16_t word;
uint8_t bytes[2];
} crc_t;
void fdd_calccrc(uint8_t byte, crc_t *crc_var);
typedef struct d86f_handler_t { typedef struct d86f_handler_t {
uint16_t (*disk_flags)(int drive); uint16_t (*disk_flags)(int drive);
uint16_t (*side_flags)(int drive); uint16_t (*side_flags)(int drive);

View File

@@ -17,6 +17,7 @@
add_library(utils OBJECT add_library(utils OBJECT
cJSON.c cJSON.c
crc.c
fifo.c fifo.c
fifo8.c fifo8.c
ini.c ini.c

77
src/utils/crc.c Normal file
View File

@@ -0,0 +1,77 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* CRC implementation.
*
* Authors: Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2016-2025 Miran Grca.
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/timer.h>
#include <86box/dma.h>
#include <86box/nvr.h>
#include <86box/random.h>
#include <86box/plat.h>
#include <86box/ui.h>
#include <86box/crc.h>
#ifdef ENABLE_CRC_LOG
int d86f_do_log = ENABLE_CRC_LOG;
static void
crc_log(const char *fmt, ...)
{
va_list ap;
if (crc_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
# define crc_log(fmt, ...)
#endif
void
crc16_setup(uint16_t *crc_table, uint16_t poly)
{
int c = 256;
int bc;
uint16_t temp;
while (c--) {
temp = c << 8;
bc = 8;
while (bc--) {
if (temp & 0x8000)
temp = (temp << 1) ^ poly;
else
temp <<= 1;
crc_table[c] = temp;
}
}
}
void
crc16_calc(uint16_t *crc_table, uint8_t byte, crc_t *crc_var)
{
crc_var->word = (crc_var->word << 8) ^
crc_table[(crc_var->word >> 8) ^ byte];
}