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
#include <86box/86box.h>
#include <86box/timer.h>
#include <86box/crc.h>
#include <86box/dma.h>
#include <86box/nvr.h>
#include <86box/random.h>
@@ -223,6 +224,7 @@ typedef struct d86f_t {
uint8_t *filebuf;
uint8_t *outbuf;
sector_t *last_side_sector[2];
uint16_t crc_table[256];
} d86f_t;
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 uint16_t CRCTable[256];
static fdc_t *d86f_fdc;
uint64_t poly = 0x42F0E1EBA9EA3693LL; /* ECMA normal */
@@ -276,28 +277,6 @@ d86f_log(const char *fmt, ...)
# define d86f_log(fmt, ...)
#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
d86f_destroy_linked_lists(int drive, int side)
{
@@ -1237,16 +1216,10 @@ decodefm(UNUSED(int drive), uint16_t dat)
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
d86f_calccrc(d86f_t *dev, uint8_t byte)
{
fdd_calccrc(byte, &(dev->calc_crc));
crc16_calc(dev->crc_table, byte, &(dev->calc_crc));
}
int
@@ -1274,7 +1247,9 @@ d86f_word_is_aligned(int drive, int side, uint32_t base_pos)
/* State 1: Find sector ID */
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];
@@ -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) {
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_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)) {
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_pos = 0xFFFFFFFF;
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 (d86f_word_is_aligned(drive, side, find->sync_pos)) {
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_pos = 0xFFFFFFFF;
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 (d86f_word_is_aligned(drive, side, find->sync_pos)) {
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_pos = 0xFFFFFFFF;
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) {
dev->last_sector.byte_array[dev->id_find.bytes_obtained] =
decodefm(drive, dev->last_word[side]);
fdd_calccrc(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)) {
crc16_calc(dev->crc_table,
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] =
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)
dev->track_crc.bytes[(dev->data_find.bytes_obtained - sector_len) ^ 1] =
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) {
/* This is a data byte, so CRC it. */
if (!dev->data_find.bytes_obtained) {
fdd_calccrc(decodefm(drive, am), &(dev->calc_crc));
} else {
fdd_calccrc(dev->current_byte[side], &(dev->calc_crc));
}
if (!dev->data_find.bytes_obtained)
crc16_calc(dev->crc_table, decodefm(drive, am),
&(dev->calc_crc));
else
crc16_calc(dev->crc_table, dev->current_byte[side],
&(dev->calc_crc));
}
}
} else {
@@ -3861,8 +3844,6 @@ d86f_load(int drive, char *fn)
void
d86f_init(void)
{
setup_crc(0x1021);
for (uint8_t i = 0; i < FDD_NUM; i++)
d86f[i] = NULL;
}
@@ -3926,6 +3907,8 @@ d86f_setup(int drive)
dev->last_side_sector[0] = NULL;
dev->last_side_sector[1] = NULL;
crc16_setup(dev->crc_table, 0x1021);
/* Set the drive as active. */
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.
*
*
*
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
*
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2025 Sarah Walker.
* Copyright 2016-2025 Miran Grca.
* Copyright 2018-2025 Fred N. van Kempen.
*/
#ifndef EMU_FDD_H
#define EMU_FDD_H
@@ -129,13 +127,6 @@ extern int drive_empty[FDD_NUM];
#define SECTOR_FIRST -2
#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 {
uint16_t (*disk_flags)(int drive);
uint16_t (*side_flags)(int drive);

View File

@@ -17,6 +17,7 @@
add_library(utils OBJECT
cJSON.c
crc.c
fifo.c
fifo8.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];
}