diff --git a/sim_fio.c b/sim_fio.c index 50321402..806fde5b 100644 --- a/sim_fio.c +++ b/sim_fio.c @@ -52,6 +52,7 @@ sim_buf_copy_swapped - copy data swapping elements along the way sim_buf_swap_data - swap data elements inplace in buffer if needed sim_byte_swap_data - swap data elements inplace in buffer + sim_buf_pack_unpack - pack or unpack data between buffers sim_shmem_open create or attach to a shared memory region sim_shmem_close close a shared memory region sim_chdir change working directory @@ -91,6 +92,28 @@ t_bool sim_toffset_64; /* Large File (>2GB) file I/O Support availa #define MIN(a,b) (((a) <= (b)) ? (a) : (b)) #endif +#define FIO_DBG_PACK 1 /* Pack/Unpack Test Detail */ + +static DEBTAB fio_debug[] = { + {"PACK", FIO_DBG_PACK, "Pack/Unpack Test Detail"}, + {0} +}; + +static const char *sim_fio_test_description (DEVICE *dptr) +{ +return "SCP FIO Testing"; +} + +static UNIT sim_fio_unit = { 0 }; + +static DEVICE sim_fio_test_dev = { + "SCP-FIO", &sim_fio_unit, NULL, NULL, + 1, 0, 0, 0, 0, 0, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, DEV_NOSAVE|DEV_DEBUG, 0, + fio_debug, NULL, NULL, NULL, NULL, NULL, + sim_fio_test_description}; + /* OS-independent, endian independent binary I/O package For consistency, all binary data read and written by the simulator @@ -177,6 +200,60 @@ for (j = 0; j < count; j++) { /* loop on items */ } } +static uint32 _bit_index (uint32 bit, uint32 bits, t_bool LSB) +{ +uint32 base, offset; + +if (LSB) + return bit; +//return (bits * (bit / bits)) + bits - ((bit % bits) + 1); /* Reverse bit ordering - likely not useful */ +base = (bits * (bit / bits)) - (((bits % 8) == 0) ? 8 : 0); +offset = ((base / bits) * (bits % 8)); +bit = (bit % bits) + offset; +return base + (bits - (((bit + (bits % 8)) / 8) * 8) - (bits % 8)) + offset + ((bit + (bits % 8)) % 8); +} + +t_bool sim_buf_pack_unpack (const void *sptr, /* source buffer pointer */ + void *dptr, /* destination buffer pointer */ + uint32 sbits, /* source buffer element size in bits */ + t_bool sLSB_o_numbering, /* source numbered using LSB ordering */ + uint32 scount, /* count of source elements */ + uint32 dbits, /* interesting bits of each destination element */ + t_bool dLSB_o_numbering) /* destination numbered using LSB ordering */ +{ +const uint8 *s = (const uint8 *)sptr; +uint8 *d = (uint8 *)dptr; +uint32 bits_to_process; /* bits in current source element remaining to be processed */ +uint32 sbit_offset, dbit_offset;/* source and destination bit offsets */ +uint32 sx; /* source byte index */ +uint32 dx; /* destination byte index */ +uint32 bit; /* Current Bit number */ +uint32 element; /* Current element number */ + +sim_debug (FIO_DBG_PACK, &sim_fio_test_dev, "sim_buf_pack_unpack(sbits=%d, dLSB_o=%s, scount=%d, dbits=%d, dLSB_o=%s)\n", sbits, sLSB_o_numbering ? "True" : "False", scount, dbits, dLSB_o_numbering ? "True" : "False"); +if (((dbits * scount) & 7) != 0) + return TRUE; /* Error - Can't process all source elements */ +memset (d, 0, (dbits * scount) >> 3); + +if (((sbits % 8) == 0) && + (sbits == dbits) && + (sLSB_o_numbering == dLSB_o_numbering)) { + sim_buf_copy_swapped (dptr, sptr, sbits >> 3, scount); + return FALSE; + } +bits_to_process = MIN (sbits, dbits); +for (element = 0; element < scount; element++) { + sbit_offset = element * sbits; + dbit_offset = element * dbits; + for (bit = 0; bit < bits_to_process; bit++, sbit_offset++, dbit_offset++) { + sx = _bit_index (sbit_offset, sbits, sLSB_o_numbering); + dx = _bit_index (dbit_offset, dbits, dLSB_o_numbering); + d[dx >> 3] |= (((s[sx >> 3] >> (sx & 7)) & 1) << (dx & 7)); + } + } +return FALSE; +} + size_t sim_fwrite (const void *bptr, size_t size, size_t count, FILE *fptr) { size_t c, nelem, nbuf, lcnt, total; @@ -308,6 +385,178 @@ free (without_quotes); return dest; } +/* + * DBD9 packing/encoding is: + * 9 character per pair of 36 bit words. + * + * 36b Bit numbers using bit + * word standard bit numbering byte offset + * 0 - 35 34 33 32 31 30 29 28 0 0 + * 0 - 27 26 25 24 23 22 21 20 1 8 + * 0 - 19 18 17 16 15 14 13 12 2 16 + * 0 - 11 10 9 8 7 6 5 4 3 24 + * 0 - 3 2 1 0 35 34 33 32 4 32 + * 1 - 31 30 29 28 27 26 25 24 5 40 + * 1 - 23 22 21 20 19 18 17 16 6 48 + * 1 - 15 14 13 12 11 10 9 8 7 56 + * 1 - 7 6 5 4 3 2 1 0 8 64 + * + * word Bit numbers using PDP10 bit numbering + * 0 - B0 1 2 3 4 5 6 7 + * 0 - 8 9 10 11 12 13 14 15 + * 0 - 16 17 18 19 20 21 22 23 + * 0 - 24 25 26 27 28 29 30 31 + * 0 - 32 33 34 35 B0 1 2 3 + * 1 - 4 5 6 7 8 9 10 11 + * 1 - 12 13 14 15 16 17 18 19 + * 1 - 20 21 22 23 24 25 26 27 + * 1 - 28 29 30 31 32 33 34 35 + * + * DLD9 packing/encoding is: + * 9 character per pair of 36 bit words. + * + * 36b Bit numbers using bit + * word standard bit numbering byte offset + * 0 - 7 6 5 4 3 2 1 0 0 0 + * 0 - 15 14 13 12 11 10 9 8 1 8 + * 0 - 23 22 21 20 19 18 17 16 2 16 + * 0 - 31 30 29 28 27 26 25 24 3 24 + * 0 - 3 2 1 0 35 34 33 32 4 32 + * 1 - 11 10 9 8 7 6 5 4 5 40 + * 1 - 19 18 17 16 15 14 13 12 6 48 + * 1 - 27 26 25 24 23 22 21 20 7 56 + * 1 - 35 34 33 32 31 30 29 28 8 64 + * + * word Bit numbers using PDP10 bit numbering + * 0 - 28 29 30 31 32 33 34 35 + * 0 - 20 21 22 23 24 25 26 27 + * 0 - 12 13 14 15 16 17 18 19 + * 0 - 4 5 6 7 8 9 10 11 + * 0 - 32 33 34 35 B0 1 2 3 + * 1 - 24 25 26 27 28 29 30 31 + * 1 - 16 17 18 19 20 21 22 23 + * 1 - 8 9 10 11 12 13 14 15 + * 1 - B0 1 2 3 4 5 6 7 + */ + +uint32 int32_data[] = { 0x00000000, 0x00000001, 0x00000002, 0x00000003, + 0x00000004, 0x00000005, 0x00000006, 0x00000007, + 0x00000008, 0x00000009, 0x0000000A, 0x0000000B, + 0x0000000C, 0x0000000D, 0x0000000E, 0x0000000F}; +uint32 res_32bitM[] = { 0x00000000, 0x01000000, 0x02000000, 0x03000000, + 0x04000000, 0x05000000, 0x06000000, 0x07000000, + 0x08000000, 0x09000000, 0x0A000000, 0x0B000000, + 0x0C000000, 0x0D000000, 0x0E000000, 0x0F000000}; +uint32 res_32_1[] = { 0, 1, 0, 1, + 0, 1, 0, 1, + 0, 1, 0, 1, + 0, 1, 0, 1}; +uint16 int16_data[] = { 0x1234, 0x5678, + 0x9ABC, 0xDEF0}; +uint16 res_16bit[] = { 0x3412, 0x7856, + 0xBC9A, 0xF0DE}; +uint8 res_8bit[] = { 0, 1, 2, 3, + 4, 5, 6, 7, + 8, 9, 10, 11, + 12, 13, 14, 15}; +uint8 res_4bit[] = { 0x10, 0x32, 0x54, 0x76, + 0x98, 0xba, 0xdc, 0xfe}; +uint8 res_2bit[] = { 0xE4, 0xE4, 0xE4, 0xE4}; +uint8 res_1bit[] = { 0xAA, 0xAA}; +#if defined (USE_INT64) +t_uint64 int64_data[] = { 0x876543210, 0x012345678, 0x987654321, 0x123456789}; +uint8 res_36bit[] = {0x10, 0x32, 0x54, 0x76, 0x88, 0x67, 0x45, 0x23, 0x01, + 0x21, 0x43, 0x65, 0x87, 0x99, 0x78, 0x56, 0x34, 0x12}; +uint8 res_36bitM[]= {0x87, 0x65, 0x43, 0x21, 0x00, 0x12, 0x34, 0x56, 0x78, + 0x98, 0x76, 0x54, 0x32, 0x11, 0x23, 0x45, 0x67, 0x89}; +uint8 int64_data_dbd9[18]; +uint8 int64_data_dld9[18]; +#endif + +static struct pack_test { + const void *src; + const void *exp_dst; + uint32 sbits; + t_bool slsb; + uint32 dbits; + t_bool dlsb; + uint32 scount; + t_bool exp_stat; + } p_test[] = + { +#if defined (USE_INT64) + {&int64_data, &res_36bitM, 64, TRUE, 36, FALSE, 4, FALSE}, + {&res_36bitM, &int64_data, 36, FALSE, 64, TRUE, 4, FALSE}, + {&int64_data, &res_36bit, 64, TRUE, 36, TRUE, 4, FALSE}, + {&res_36bit, &int64_data, 36, TRUE, 64, TRUE, 4, FALSE}, +#endif + {&int16_data, &res_16bit, 16, TRUE, 16, FALSE, 4, FALSE}, + {&int16_data, &res_16bit, 16, FALSE, 16, TRUE, 4, FALSE}, + {&int16_data, &int16_data, 16, TRUE, 16, TRUE, 4, FALSE}, + {&int16_data, &int16_data, 16, FALSE, 16, FALSE, 4, FALSE}, + {&int32_data, &int32_data, 32, FALSE, 32, FALSE,16, FALSE}, + {&int32_data, &int32_data, 32, TRUE, 32, TRUE, 16, FALSE}, + {&int32_data, &res_32bitM, 32, TRUE, 32, FALSE,16, FALSE}, + {&res_32bitM, &int32_data, 32, FALSE, 32, TRUE, 16, FALSE}, + {&res_8bit, &res_8bit, 8, TRUE, 8, FALSE,16, FALSE}, + {&res_8bit, &res_8bit, 8, FALSE, 8, TRUE, 16, FALSE}, + {&res_8bit, &res_8bit, 8, FALSE, 8, FALSE,16, FALSE}, + {&res_8bit, &res_8bit, 8, TRUE, 8, TRUE, 16, FALSE}, + {&res_8bit, &res_8bit, 16, TRUE, 16, TRUE, 8, FALSE}, + {&res_8bit, &res_8bit, 16, FALSE, 16, FALSE, 8, FALSE}, + {&res_1bit, &res_32_1, 1, TRUE, 32, TRUE, 16, FALSE}, + {&res_8bit, &int32_data, 8, TRUE, 32, TRUE, 2, FALSE}, + {&res_4bit, &int32_data, 4, TRUE, 32, TRUE, 16, FALSE}, + {&int32_data, &res_8bit, 32, TRUE, 8, TRUE, 16, FALSE}, + {&int32_data, &int32_data, 32, TRUE, 32, TRUE, 16, FALSE}, + {&int32_data, &int32_data, 16, TRUE, 16, TRUE, 32, FALSE}, + {&int32_data, &int32_data, 8, TRUE, 8, TRUE, 64, FALSE}, + {&int32_data, &res_8bit, 32, TRUE, 8, TRUE, 16, FALSE}, + {&int32_data, &res_4bit, 32, TRUE, 4, TRUE, 16, FALSE}, + {&int32_data, &res_2bit, 32, TRUE, 2, TRUE, 16, FALSE}, + {&int32_data, &res_1bit, 32, TRUE, 1, TRUE, 16, FALSE}, + {NULL}, + }; + +t_stat sim_fio_test (const char *cptr) +{ +struct pack_test *pt; +t_stat r = SCPE_OK; +char test_desc[128]; +uint8 result[128]; + +sim_register_internal_device (&sim_fio_test_dev); +sim_fio_test_dev.dctrl = (sim_switches & SWMASK ('D')) ? FIO_DBG_PACK : 0; +sim_set_deb_switches (SWMASK ('F')); +sim_messagef (SCPE_OK, "sim_buf_pack_unpack - tests\n"); +for (pt = p_test; pt->src; ++pt) { + t_bool res; + + snprintf (test_desc, sizeof (test_desc), "%dbit%s->%dbit%s %d words", pt->sbits, pt->slsb ? "LSB" : "MSB", pt->dbits, pt->dlsb ? "LSB" : "MSB", pt->scount); + memset (result, 0x80, sizeof (result)); + res = sim_buf_pack_unpack (pt->src, result, pt->sbits, pt->slsb, pt->scount, pt->dbits, pt->dlsb); + if (res == pt->exp_stat) { + if (!res) { + if (0 == memcmp (pt->exp_dst, result, (pt->scount * pt->dbits) / 8)) + sim_messagef (SCPE_OK, "%s - GOOD\n", test_desc); + else { + uint32 i; + + r = sim_messagef (SCPE_IERR, "%s - BAD Data:\n", test_desc); + sim_messagef (SCPE_IERR, "Off: Exp: Got:\n"); + for (i = 0; i < ((pt->scount * pt->dbits) / 8); i++) + sim_messagef (SCPE_IERR, "%3d 0x%02X%s0x%02X\n", i, ((uint8 *)pt->exp_dst)[i], (((uint8 *)pt->exp_dst)[i] == result[i]) ? " " : " != ", result[i]); + } + } + } + else + r = sim_messagef (SCPE_IERR, "%s - BAD Status - Expected: %s got %s\n", test_desc, pt->exp_stat ? "True" : "False", res ? "True" : "False"); + } +return r; +} + + + #if defined(_WIN32) #include #include diff --git a/sim_fio.h b/sim_fio.h index 7d1a3d2a..43373b4f 100644 --- a/sim_fio.h +++ b/sim_fio.h @@ -94,6 +94,14 @@ void sim_print_filelist (char **filelist); void sim_buf_swap_data (void *bptr, size_t size, size_t count); void sim_byte_swap_data (void *bptr, size_t size, size_t count); void sim_buf_copy_swapped (void *dptr, const void *bptr, size_t size, size_t count); +t_bool sim_buf_pack_unpack (const void *sptr, /* source buffer pointer */ + void *dptr, /* destination buffer pointer */ + uint32 sbits, /* source buffer element size in bits */ + t_bool sLSB_o_numbering, /* source numbered using LSB ordering */ + uint32 scount, /* count of source elements */ + uint32 dbits, /* interesting bits of each destination element */ + t_bool dLSB_o_numbering); /* destination numbered using LSB ordering */ +t_stat sim_fio_test (const char *cptr); const char *sim_get_os_error_text (int error); typedef struct SHMEM SHMEM; t_stat sim_shmem_open (const char *name, size_t size, SHMEM **shmem, void **addr);