Split off the CRC code to its own module.
This commit is contained in:
@@ -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
34
src/include/86box/crc.h
Normal 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*/
|
||||
@@ -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);
|
||||
|
||||
@@ -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
77
src/utils/crc.c
Normal 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];
|
||||
}
|
||||
Reference in New Issue
Block a user