1
1
mirror of https://github.com/wader/fq.git synced 2024-09-11 20:07:11 +03:00

tap: verify checksum values

This commit is contained in:
Michael R. Cook 2024-08-06 22:57:06 +02:00
parent e345528d74
commit c93dc8bbf9
3 changed files with 28 additions and 9 deletions

View File

@ -3,11 +3,14 @@ package tzx
// https://worldofspectrum.net/zx-modules/fileformats/tapformat.html
import (
"bufio"
"bytes"
"embed"
"golang.org/x/text/encoding/charmap"
"github.com/wader/fq/format"
"github.com/wader/fq/pkg/bitio"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/interp"
"github.com/wader/fq/pkg/scalar"
@ -67,6 +70,8 @@ func decodeTapBlock(d *decode.D) {
// decodes the different types of 19-byte header blocks.
func decodeHeader(d *decode.D) {
blockStartPosition := d.Pos()
// Always 0: byte indicating a standard ROM loading header
d.FieldU8("flag", scalar.UintMapSymStr{0: "standard_speed_data"})
// Header type
@ -119,10 +124,12 @@ func decodeHeader(d *decode.D) {
}
// Simply all bytes XORed (including flag byte).
d.FieldU8("checksum", scalar.UintHex)
d.FieldU8("checksum", d.UintValidate(calculateChecksum(d, blockStartPosition, d.Pos()-blockStartPosition)), scalar.UintHex)
}
func decodeDataBlock(d *decode.D, length uint64) {
blockStartPosition := d.Pos()
// flag indicating the type of data block, usually 255 (standard speed data)
d.FieldU8("flag", scalar.UintFn(func(s scalar.Uint) (scalar.Uint, error) {
if s.Actual == 0xFF {
@ -135,5 +142,17 @@ func decodeDataBlock(d *decode.D, length uint64) {
// The essential data: length minus the flag/checksum bytes (may be empty)
d.FieldRawLen("data", int64(length-2)*8)
// Simply all bytes (including flag byte) XORed
d.FieldU8("checksum", scalar.UintHex)
d.FieldU8("checksum", d.UintValidate(calculateChecksum(d, blockStartPosition, d.Pos()-blockStartPosition)), scalar.UintHex)
}
func calculateChecksum(d *decode.D, blockStartPos, blockEndPos int64) uint64 {
var blockSlice bytes.Buffer
writer := bufio.NewWriter(&blockSlice)
d.Copy(writer, bitio.NewIOReader(d.BitBufRange(blockStartPos, blockEndPos)))
var checksum uint8
for _, v := range blockSlice.Bytes() {
checksum ^= v
}
return uint64(checksum)
}

View File

@ -10,7 +10,7 @@ $ fq -d tap dv basic_prog1.tap
0x00| 26 00| &.| data_length: 38 0xe-0x10 (2)
0x10|0a 00 |.. | auto_start_line: 10 0x10-0x12 (2)
0x10| 26 00 | &. | program_length: 38 0x12-0x14 (2)
0x10| 01 | . | checksum: 0x1 0x14-0x15 (1)
0x10| 01 | . | checksum: 0x1 (valid) 0x14-0x15 (1)
| | | [1]{}: block 0x15-0x3f (42)
0x10| 28 00 | (. | length: 40 0x15-0x17 (2)
| | | data{}: 0x17-0x3f (40)
@ -18,4 +18,4 @@ $ fq -d tap dv basic_prog1.tap
0x10| 00 0a 14 00 20 f5 22 66| .... ."f| data: raw bits 0x18-0x3e (38)
0x20|71 20 69 73 20 74 68 65 20 62 65 73 74 21 22 0d|q is the best!".|
0x30|00 14 0a 00 ec 31 30 0e 00 00 0a 00 00 0d |.....10....... |
0x30| b6| | .|| checksum: 0xb6 0x3e-0x3f (1)
0x30| b6| | .|| checksum: 0xb6 (valid) 0x3e-0x3f (1)

View File

@ -5,7 +5,7 @@ $ fq -d tzx dv basic_prog1.tzx
0x00| 14 | . | minor_version: 20 0x9-0xa (1)
| | | blocks[0:3]: 0xa-0xcd (195)
| | | [0]{}: block 0xa-0x88 (126)
0x00| 32 | 2 | block_type: "archive_info" (50) 0xa-0xb (1)
0x00| 32 | 2 | type: "archive_info" (50) 0xa-0xb (1)
0x00| 7b 00 | {. | length: 123 0xb-0xd (2)
0x00| 09 | . | count: 9 0xd-0xe (1)
| | | archive_info[0:9]: 0xe-0x88 (122)
@ -51,7 +51,7 @@ $ fq -d tzx dv basic_prog1.tzx
0x70|54 5a 58 65 64 20 62 79 20 4d 69 63 68 61 65 6c|TZXed by Michael| value: "TZXed by Michael R. Cook" 0x70-0x88 (24)
0x80|20 52 2e 20 43 6f 6f 6b | R. Cook |
| | | [1]{}: block 0x88-0xa0 (24)
0x80| 10 | . | block_type: "standard_speed_data" (16) 0x88-0x89 (1)
0x80| 10 | . | type: "standard_speed_data" (16) 0x88-0x89 (1)
0x80| e8 03 | .. | pause: 1000 0x89-0x8b (2)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| tap{}: (tap) 0x8b-0xa0 (21)
| | | blocks[0:1]: 0x8b-0xa0 (21)
@ -65,9 +65,9 @@ $ fq -d tzx dv basic_prog1.tzx
0x90| 26 00 | &. | data_length: 38 0x99-0x9b (2)
0x90| 0a 00 | .. | auto_start_line: 10 0x9b-0x9d (2)
0x90| 26 00 | &. | program_length: 38 0x9d-0x9f (2)
0x90| 01| .| checksum: 0x1 0x9f-0xa0 (1)
0x90| 01| .| checksum: 0x1 (valid) 0x9f-0xa0 (1)
| | | [2]{}: block 0xa0-0xcd (45)
0xa0|10 |. | block_type: "standard_speed_data" (16) 0xa0-0xa1 (1)
0xa0|10 |. | type: "standard_speed_data" (16) 0xa0-0xa1 (1)
0xa0| e8 03 | .. | pause: 1000 0xa1-0xa3 (2)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| tap{}: (tap) 0xa3-0xcd (42)
| | | blocks[0:1]: 0xa3-0xcd (42)
@ -78,4 +78,4 @@ $ fq -d tzx dv basic_prog1.tzx
0xa0| 00 0a 14 00 20 f5 22 66 71 20| .... ."fq | data: raw bits 0xa6-0xcc (38)
0xb0|69 73 20 74 68 65 20 62 65 73 74 21 22 0d 00 14|is the best!"...|
0xc0|0a 00 ec 31 30 0e 00 00 0a 00 00 0d |...10....... |
0xc0| b6| | .| | checksum: 0xb6 0xcc-0xcd (1)
0xc0| b6| | .| | checksum: 0xb6 (valid) 0xcc-0xcd (1)