|
1 | 1 | #include <stdio.h> |
| 2 | +#include <stdlib.h> |
| 3 | +#include <string.h> |
2 | 4 |
|
3 | 5 | #include "utest.h" |
4 | 6 | #include "../cap.h" |
| 7 | +#include "../binimage.h" |
| 8 | +#include "../transcode.h" |
| 9 | + |
| 10 | +static uint16_t test_colbin_encode_byte(uint8_t b) |
| 11 | +{ |
| 12 | + uint16_t col = 0; |
| 13 | + |
| 14 | + if (b & 0x80) col |= (uint16_t)(1u << 0); |
| 15 | + if (b & 0x40) col |= (uint16_t)(1u << 1); |
| 16 | + if (b & 0x20) col |= (uint16_t)(1u << 2); |
| 17 | + if (b & 0x10) col |= (uint16_t)(1u << 3); |
| 18 | + if (b & 0x08) col |= (uint16_t)(1u << 6); |
| 19 | + if (b & 0x04) col |= (uint16_t)(1u << 7); |
| 20 | + if (b & 0x02) col |= (uint16_t)(1u << 8); |
| 21 | + if (b & 0x01) col |= (uint16_t)(1u << 9); |
| 22 | + |
| 23 | + return col; |
| 24 | +} |
| 25 | + |
| 26 | +static int write_single_card_cap(const char *path, const uint16_t cols[80]) |
| 27 | +{ |
| 28 | + FILE *f = fopen(path, "w"); |
| 29 | + if (!f) |
| 30 | + return -1; |
| 31 | + fprintf(f, "Synthetic cap for capcat test\n"); |
| 32 | + fprintf(f, "Card n. 1\n"); |
| 33 | + for (int i = 0; i < 80; i++) |
| 34 | + fprintf(f, "%04X%c", cols[i] & 0x1FFFu, (i == 79) ? '\n' : ' '); |
| 35 | + fclose(f); |
| 36 | + return 0; |
| 37 | +} |
5 | 38 |
|
6 | 39 | UTEST(cap, parse_funktional) |
7 | 40 | { |
@@ -29,3 +62,54 @@ UTEST(cap, missing_file) |
29 | 62 | struct cap_deck *d = cap_load("DUMP1/does-not-exist.cap"); |
30 | 63 | ASSERT_TRUE(d == NULL); |
31 | 64 | } |
| 65 | + |
| 66 | +UTEST(cap, capcat_appends_overlay_cards) |
| 67 | +{ |
| 68 | + static const char base_path[] = "/tmp/gemu_capcat_base.cap"; |
| 69 | + static const char overlay_path[] = "/tmp/gemu_capcat_overlay.bin"; |
| 70 | + static const char out_path[] = "/tmp/gemu_capcat_out.cap"; |
| 71 | + static const char tool_path[] = "tools/capcat"; |
| 72 | + static const uint8_t prefix[8] = { 0x00, 0x04, 0x40, 0x00, 0x20, 0x40, 0x40, 0x42 }; |
| 73 | + uint16_t cols[80] = {0}; |
| 74 | + uint8_t image[65536]; |
| 75 | + unsigned lo = 0, hi = 0; |
| 76 | + char cmd[512]; |
| 77 | + FILE *probe; |
| 78 | + |
| 79 | + probe = fopen(tool_path, "r"); |
| 80 | + if (!probe) { |
| 81 | + printf(" [SKIP] %s not built\n", tool_path); |
| 82 | + return; |
| 83 | + } |
| 84 | + fclose(probe); |
| 85 | + |
| 86 | + for (int i = 0; i < 8; i++) |
| 87 | + cols[i] = test_colbin_encode_byte(prefix[i]); |
| 88 | + cols[8] = test_colbin_encode_byte(0x01); /* 2 payload bytes */ |
| 89 | + cols[9] = test_colbin_encode_byte(0x01); |
| 90 | + cols[10] = test_colbin_encode_byte(0x00); |
| 91 | + cols[11] = test_colbin_encode_byte(0xAA); |
| 92 | + cols[12] = test_colbin_encode_byte(0x55); |
| 93 | + ASSERT_EQ(write_single_card_cap(base_path, cols), 0); |
| 94 | + |
| 95 | + { |
| 96 | + uint8_t ov[3] = { 0x11, 0x22, 0x33 }; |
| 97 | + FILE *f = fopen(overlay_path, "wb"); |
| 98 | + ASSERT_TRUE(f != NULL); |
| 99 | + ASSERT_EQ(binimage_write(f, 0x0200, 0x0200, ov, (uint16_t)sizeof(ov)), BINIMAGE_OK); |
| 100 | + fclose(f); |
| 101 | + } |
| 102 | + |
| 103 | + snprintf(cmd, sizeof(cmd), "%s -o %s %s %s >/tmp/gemu_capcat_cmd.log 2>&1", |
| 104 | + tool_path, out_path, base_path, overlay_path); |
| 105 | + ASSERT_EQ(system(cmd), 0); |
| 106 | + |
| 107 | + memset(image, 0, sizeof(image)); |
| 108 | + ASSERT_GT(cap_load_scattered(out_path, TC_COLBIN, image, &lo, &hi), 0); |
| 109 | + ASSERT_EQ(lo, 0x0100u); |
| 110 | + ASSERT_EQ(image[0x0100], 0xAA); |
| 111 | + ASSERT_EQ(image[0x0101], 0x55); |
| 112 | + ASSERT_EQ(image[0x0200], 0x11); |
| 113 | + ASSERT_EQ(image[0x0201], 0x22); |
| 114 | + ASSERT_EQ(image[0x0202], 0x33); |
| 115 | +} |
0 commit comments