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:
parent
e345528d74
commit
c93dc8bbf9
@ -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)
|
||||
}
|
||||
|
4
format/tap/testdata/basic_prog1.fqtest
vendored
4
format/tap/testdata/basic_prog1.fqtest
vendored
@ -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)
|
||||
|
10
format/tzx/testdata/basic_prog1.fqtest
vendored
10
format/tzx/testdata/basic_prog1.fqtest
vendored
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user