mirror of
https://github.com/wader/fq.git
synced 2024-11-22 15:45:45 +03:00
Merge pull request #990 from mrcook/tzx-updates
TZX updates - mostly for easier JSON parsing
This commit is contained in:
commit
1fac9516bf
@ -6,6 +6,7 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"embed"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/text/encoding/charmap"
|
||||
|
||||
@ -54,9 +55,11 @@ func decodeTapBlock(d *decode.D) {
|
||||
// read header, fragment, or data block
|
||||
switch length {
|
||||
case 0:
|
||||
// fragment with no data
|
||||
d.Fatalf("TAP fragments with 0 bytes are not supported")
|
||||
case 1:
|
||||
d.FieldRawLen("data", 8)
|
||||
d.FieldStruct("data", func(d *decode.D) {
|
||||
d.FieldRawLen("bytes", 8)
|
||||
})
|
||||
case 19:
|
||||
d.FieldStruct("header", func(d *decode.D) {
|
||||
decodeHeader(d)
|
||||
@ -72,15 +75,34 @@ func decodeTapBlock(d *decode.D) {
|
||||
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"})
|
||||
// flag indicating the type of header block, usually 0 (standard speed data)
|
||||
d.FieldU8("flag", scalar.UintFn(func(s scalar.Uint) (scalar.Uint, error) {
|
||||
if s.Actual == 0x00 {
|
||||
s.Sym = "standard_speed_data"
|
||||
} else {
|
||||
s.Sym = "custom_data_block"
|
||||
}
|
||||
return s, nil
|
||||
}))
|
||||
|
||||
// Header type
|
||||
dataType := d.FieldU8("data_type", scalar.UintMapSymStr{
|
||||
0x00: "program",
|
||||
0x01: "numeric",
|
||||
0x02: "alphanumeric",
|
||||
0x03: "data",
|
||||
})
|
||||
dataType := d.FieldU8("data_type", scalar.UintFn(func(s scalar.Uint) (scalar.Uint, error) {
|
||||
switch s.Actual {
|
||||
case 0x00:
|
||||
s.Sym = "program"
|
||||
case 0x01:
|
||||
s.Sym = "numeric"
|
||||
case 0x02:
|
||||
s.Sym = "alphanumeric"
|
||||
case 0x03:
|
||||
s.Sym = "data"
|
||||
default:
|
||||
// unofficial header types
|
||||
s.Sym = fmt.Sprintf("unknown%02X", s.Actual)
|
||||
}
|
||||
return s, nil
|
||||
}))
|
||||
|
||||
// Loading name of the program. Filled with spaces (0x20) to 10 characters.
|
||||
d.FieldStr("program_name", 10, charmap.ISO8859_1)
|
||||
|
||||
@ -120,7 +142,10 @@ func decodeHeader(d *decode.D) {
|
||||
// UnusedWord: 32768.
|
||||
d.FieldU16("unused")
|
||||
default:
|
||||
d.Fatalf("invalid TAP header type, got: %d", dataType)
|
||||
// Unofficial header types
|
||||
d.FieldU16("data_length")
|
||||
d.FieldU16("unknown1", scalar.UintHex)
|
||||
d.FieldU16("unknown2", scalar.UintHex)
|
||||
}
|
||||
|
||||
// Simply all bytes XORed (including flag byte).
|
||||
@ -140,7 +165,8 @@ func decodeDataBlock(d *decode.D, length uint64) {
|
||||
return s, nil
|
||||
}))
|
||||
// The essential data: length minus the flag/checksum bytes (may be empty)
|
||||
d.FieldRawLen("data", int64(length-2)*8)
|
||||
d.FieldRawLen("bytes", int64(length-2)*8)
|
||||
|
||||
// Simply all bytes (including flag byte) XORed
|
||||
d.FieldU8("checksum", d.UintValidate(calculateChecksum(d, blockStartPosition, d.Pos()-blockStartPosition)), scalar.UintHex)
|
||||
}
|
||||
|
2
format/tap/testdata/basic_prog1.fqtest
vendored
2
format/tap/testdata/basic_prog1.fqtest
vendored
@ -15,7 +15,7 @@ $ fq -d tap dv basic_prog1.tap
|
||||
0x10| 28 00 | (. | length: 40 0x15-0x17 (2)
|
||||
| | | data{}: 0x17-0x3f (40)
|
||||
0x10| ff | . | flag: "standard_speed_data" (255) 0x17-0x18 (1)
|
||||
0x10| 00 0a 14 00 20 f5 22 66| .... ."f| data: raw bits 0x18-0x3e (38)
|
||||
0x10| 00 0a 14 00 20 f5 22 66| .... ."f| bytes: 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 (valid) 0x3e-0x3f (1)
|
||||
|
131
format/tzx/testdata/basic_prog1.fqtest
vendored
131
format/tzx/testdata/basic_prog1.fqtest
vendored
@ -5,77 +5,80 @@ $ 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 | 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)
|
||||
| | | [0]{}: entry 0xe-0x1a (12)
|
||||
0x00| 00 | . | id: "title" (0) 0xe-0xf (1)
|
||||
0x00| 0a| .| length: 10 0xf-0x10 (1)
|
||||
0x10|66 71 74 65 73 74 70 72 6f 67 |fqtestprog | value: "fqtestprog" 0x10-0x1a (10)
|
||||
| | | [1]{}: entry 0x1a-0x21 (7)
|
||||
0x10| 01 | . | id: "publisher" (1) 0x1a-0x1b (1)
|
||||
0x10| 05 | . | length: 5 0x1b-0x1c (1)
|
||||
0x10| 77 61 64 65| wade| value: "wader" 0x1c-0x21 (5)
|
||||
| | | archive_info{}: 0xa-0x88 (126)
|
||||
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)
|
||||
| | | entries[0:9]: 0xe-0x88 (122)
|
||||
| | | [0]{}: entry 0xe-0x1a (12)
|
||||
0x00| 00 | . | id: "title" (0) 0xe-0xf (1)
|
||||
0x00| 0a| .| length: 10 0xf-0x10 (1)
|
||||
0x10|66 71 74 65 73 74 70 72 6f 67 |fqtestprog | value: "fqtestprog" 0x10-0x1a (10)
|
||||
| | | [1]{}: entry 0x1a-0x21 (7)
|
||||
0x10| 01 | . | id: "publisher" (1) 0x1a-0x1b (1)
|
||||
0x10| 05 | . | length: 5 0x1b-0x1c (1)
|
||||
0x10| 77 61 64 65| wade| value: "wader" 0x1c-0x21 (5)
|
||||
0x20|72 |r |
|
||||
| | | [2]{}: entry 0x21-0x32 (17)
|
||||
0x20| 02 | . | id: "author" (2) 0x21-0x22 (1)
|
||||
0x20| 0f | . | length: 15 0x22-0x23 (1)
|
||||
0x20| 4d 69 63 68 61 65 6c 20 52 2e 20 43 6f| Michael R. Co| value: "Michael R. Cook" 0x23-0x32 (15)
|
||||
| | | [2]{}: entry 0x21-0x32 (17)
|
||||
0x20| 02 | . | id: "author" (2) 0x21-0x22 (1)
|
||||
0x20| 0f | . | length: 15 0x22-0x23 (1)
|
||||
0x20| 4d 69 63 68 61 65 6c 20 52 2e 20 43 6f| Michael R. Co| value: "Michael R. Cook" 0x23-0x32 (15)
|
||||
0x30|6f 6b |ok |
|
||||
| | | [3]{}: entry 0x32-0x38 (6)
|
||||
0x30| 03 | . | id: "year" (3) 0x32-0x33 (1)
|
||||
0x30| 04 | . | length: 4 0x33-0x34 (1)
|
||||
0x30| 32 30 32 34 | 2024 | value: "2024" 0x34-0x38 (4)
|
||||
| | | [4]{}: entry 0x38-0x41 (9)
|
||||
0x30| 04 | . | id: "language" (4) 0x38-0x39 (1)
|
||||
0x30| 07 | . | length: 7 0x39-0x3a (1)
|
||||
0x30| 45 6e 67 6c 69 73| Englis| value: "English" 0x3a-0x41 (7)
|
||||
| | | [3]{}: entry 0x32-0x38 (6)
|
||||
0x30| 03 | . | id: "year" (3) 0x32-0x33 (1)
|
||||
0x30| 04 | . | length: 4 0x33-0x34 (1)
|
||||
0x30| 32 30 32 34 | 2024 | value: "2024" 0x34-0x38 (4)
|
||||
| | | [4]{}: entry 0x38-0x41 (9)
|
||||
0x30| 04 | . | id: "language" (4) 0x38-0x39 (1)
|
||||
0x30| 07 | . | length: 7 0x39-0x3a (1)
|
||||
0x30| 45 6e 67 6c 69 73| Englis| value: "English" 0x3a-0x41 (7)
|
||||
0x40|68 |h |
|
||||
| | | [5]{}: entry 0x41-0x4f (14)
|
||||
0x40| 05 | . | id: "category" (5) 0x41-0x42 (1)
|
||||
0x40| 0c | . | length: 12 0x42-0x43 (1)
|
||||
0x40| 54 65 73 74 20 50 72 6f 67 72 61 6d | Test Program | value: "Test Program" 0x43-0x4f (12)
|
||||
| | | [6]{}: entry 0x4f-0x5c (13)
|
||||
0x40| 07| .| id: "loader" (7) 0x4f-0x50 (1)
|
||||
0x50|0b |. | length: 11 0x50-0x51 (1)
|
||||
0x50| 52 4f 4d 20 74 69 6d 69 6e 67 73 | ROM timings | value: "ROM timings" 0x51-0x5c (11)
|
||||
| | | [7]{}: entry 0x5c-0x6e (18)
|
||||
0x50| 08 | . | id: "origin" (8) 0x5c-0x5d (1)
|
||||
0x50| 10 | . | length: 16 0x5d-0x5e (1)
|
||||
0x50| 4f 72| Or| value: "Original release" 0x5e-0x6e (16)
|
||||
| | | [5]{}: entry 0x41-0x4f (14)
|
||||
0x40| 05 | . | id: "category" (5) 0x41-0x42 (1)
|
||||
0x40| 0c | . | length: 12 0x42-0x43 (1)
|
||||
0x40| 54 65 73 74 20 50 72 6f 67 72 61 6d | Test Program | value: "Test Program" 0x43-0x4f (12)
|
||||
| | | [6]{}: entry 0x4f-0x5c (13)
|
||||
0x40| 07| .| id: "loader" (7) 0x4f-0x50 (1)
|
||||
0x50|0b |. | length: 11 0x50-0x51 (1)
|
||||
0x50| 52 4f 4d 20 74 69 6d 69 6e 67 73 | ROM timings | value: "ROM timings" 0x51-0x5c (11)
|
||||
| | | [7]{}: entry 0x5c-0x6e (18)
|
||||
0x50| 08 | . | id: "origin" (8) 0x5c-0x5d (1)
|
||||
0x50| 10 | . | length: 16 0x5d-0x5e (1)
|
||||
0x50| 4f 72| Or| value: "Original release" 0x5e-0x6e (16)
|
||||
0x60|69 67 69 6e 61 6c 20 72 65 6c 65 61 73 65 |iginal release |
|
||||
| | | [8]{}: entry 0x6e-0x88 (26)
|
||||
0x60| ff | . | id: "comment" (255) 0x6e-0x6f (1)
|
||||
0x60| 18| .| length: 24 0x6f-0x70 (1)
|
||||
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)
|
||||
| | | [8]{}: entry 0x6e-0x88 (26)
|
||||
0x60| ff | . | id: "comment" (255) 0x6e-0x6f (1)
|
||||
0x60| 18| .| length: 24 0x6f-0x70 (1)
|
||||
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 | . | 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)
|
||||
| | | [0]{}: block 0x8b-0xa0 (21)
|
||||
0x80| 13 00 | .. | length: 19 0x8b-0x8d (2)
|
||||
| | | header{}: 0x8d-0xa0 (19)
|
||||
0x80| 00 | . | flag: "standard_speed_data" (0) 0x8d-0x8e (1)
|
||||
0x80| 00 | . | data_type: "program" (0) 0x8e-0x8f (1)
|
||||
0x80| 66| f| program_name: "fqTestProg" 0x8f-0x99 (10)
|
||||
| | | standard_speed_data{}: 0x88-0xa0 (24)
|
||||
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)
|
||||
| | | [0]{}: block 0x8b-0xa0 (21)
|
||||
0x80| 13 00 | .. | length: 19 0x8b-0x8d (2)
|
||||
| | | header{}: 0x8d-0xa0 (19)
|
||||
0x80| 00 | . | flag: "standard_speed_data" (0) 0x8d-0x8e (1)
|
||||
0x80| 00 | . | data_type: "program" (0) 0x8e-0x8f (1)
|
||||
0x80| 66| f| program_name: "fqTestProg" 0x8f-0x99 (10)
|
||||
0x90|71 54 65 73 74 50 72 6f 67 |qTestProg |
|
||||
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 (valid) 0x9f-0xa0 (1)
|
||||
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 (valid) 0x9f-0xa0 (1)
|
||||
| | | [2]{}: block 0xa0-0xcd (45)
|
||||
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)
|
||||
| | | [0]{}: block 0xa3-0xcd (42)
|
||||
0xa0| 28 00 | (. | length: 40 0xa3-0xa5 (2)
|
||||
| | | data{}: 0xa5-0xcd (40)
|
||||
0xa0| ff | . | flag: "standard_speed_data" (255) 0xa5-0xa6 (1)
|
||||
0xa0| 00 0a 14 00 20 f5 22 66 71 20| .... ."fq | data: raw bits 0xa6-0xcc (38)
|
||||
| | | standard_speed_data{}: 0xa0-0xcd (45)
|
||||
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)
|
||||
| | | [0]{}: block 0xa3-0xcd (42)
|
||||
0xa0| 28 00 | (. | length: 40 0xa3-0xa5 (2)
|
||||
| | | data{}: 0xa5-0xcd (40)
|
||||
0xa0| ff | . | flag: "standard_speed_data" (255) 0xa5-0xa6 (1)
|
||||
0xa0| 00 0a 14 00 20 f5 22 66 71 20| .... ."fq | bytes: 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 (valid) 0xcc-0xcd (1)
|
||||
0xc0| b6| | .| | checksum: 0xb6 (valid) 0xcc-0xcd (1)
|
||||
|
@ -97,7 +97,7 @@ func decodeBlock(d *decode.D) {
|
||||
length := d.FieldU24("length") // Length of data that follows
|
||||
|
||||
// Data as in .TAP files
|
||||
d.FieldRawLen("data", int64(length*8))
|
||||
d.FieldRawLen("data", int64(length)*8)
|
||||
},
|
||||
|
||||
// ID: 12h (18d) | Pure Tone
|
||||
@ -131,7 +131,7 @@ func decodeBlock(d *decode.D) {
|
||||
length := d.FieldU24("length") // Length of data that follows
|
||||
|
||||
// Data as in .TAP files
|
||||
d.FieldRawLen("data", int64(length*8))
|
||||
d.FieldRawLen("data", int64(length)*8)
|
||||
},
|
||||
|
||||
// ID: 15h (21d) | Direct Recording
|
||||
@ -147,7 +147,7 @@ func decodeBlock(d *decode.D) {
|
||||
d.FieldU16("pause") // Pause after this block in milliseconds (ms.)
|
||||
d.FieldU8("used_bits") // Used bits (samples) in last byte of data (1-8)
|
||||
length := d.FieldU24("length") // Length of data that follows
|
||||
d.FieldRawLen("data", int64(length*8)) // Samples data. Each bit represents a state on the EAR port
|
||||
d.FieldRawLen("data", int64(length)*8) // Samples data. Each bit represents a state on the EAR port
|
||||
},
|
||||
|
||||
// ID: 18h (24d) | CSW Recording
|
||||
@ -165,12 +165,12 @@ func decodeBlock(d *decode.D) {
|
||||
// Sampling rate
|
||||
d.FieldU24("sample_rate")
|
||||
// Compression type
|
||||
d.FieldU8("compression_type", scalar.UintMapSymStr{0x01: "rle", 0x02: "zrle"})
|
||||
d.FieldU8("compression_type", scalar.UintMapSymStr{0x00: "unknown", 0x01: "rle", 0x02: "zrle"})
|
||||
// Number of stored pulses (after decompression)
|
||||
d.FieldU32("stored_pulse_count")
|
||||
|
||||
// CSW data, encoded according to the CSW specification
|
||||
d.FieldRawLen("data", int64(length*8))
|
||||
d.FieldRawLen("data", int64(length)*8)
|
||||
},
|
||||
|
||||
// ID: 19h (25d) | Generalized Data
|
||||
@ -194,7 +194,7 @@ func decodeBlock(d *decode.D) {
|
||||
// PilotStreams []PilotRLE // 0x12+ (2*NPP+1)*ASP - PRLE[TOTP] Pilot and sync data stream
|
||||
// DataSymbols []Symbol // 0x12+ (TOTP>0)*((2*NPP+1)*ASP)+TOTP*3 - SYMDEF[ASD] Data symbols definition table
|
||||
// DataStreams []uint8 // 0x12+ (TOTP>0)*((2*NPP+1)*ASP)+ TOTP*3+(2*NPD+1)*ASD - BYTE[DS] Data stream
|
||||
d.FieldRawLen("data", int64(length*8))
|
||||
d.FieldRawLen("data", int64(length)*8)
|
||||
},
|
||||
|
||||
// ID: 20h (32d) | Pause Tape Command
|
||||
@ -340,7 +340,7 @@ func decodeBlock(d *decode.D) {
|
||||
count := d.FieldU8("count") // Number of entries in the archive info
|
||||
|
||||
// the archive strings
|
||||
d.FieldArray("archive_info", func(d *decode.D) {
|
||||
d.FieldArray("entries", func(d *decode.D) {
|
||||
for i := uint64(0); i < count; i++ {
|
||||
d.FieldStruct("entry", func(d *decode.D) {
|
||||
d.FieldU8("id", scalar.UintMapSymStr{
|
||||
@ -372,11 +372,11 @@ func decodeBlock(d *decode.D) {
|
||||
for i := uint64(0); i < count; i++ {
|
||||
d.FieldStruct("info", func(d *decode.D) {
|
||||
// Hardware Type ID (computers, printers, mice, etc.)
|
||||
typeId := d.FieldU8("type", hwInfoTypeMapper)
|
||||
// Hardware ID (ZX81, Kempston Joystick, etc.)
|
||||
d.FieldU8("id", hwInfoTypeIdMapper[typeId])
|
||||
typeId := d.FieldU8("type_id", hwInfoTypes)
|
||||
// Hardware Device ID (ZX81, Kempston Joystick, etc.)
|
||||
d.FieldU8("device_id", hwInfoDevices[typeId])
|
||||
// Hardware compatibility information
|
||||
d.FieldU8("info_id", hwInfoIdMapper)
|
||||
d.FieldU8("info_id", hwInfoCompatibilityInfo)
|
||||
})
|
||||
}
|
||||
})
|
||||
@ -387,9 +387,9 @@ func decodeBlock(d *decode.D) {
|
||||
// some information written by a utility, extra settings required by a
|
||||
// particular emulator, etc.
|
||||
0x35: func(d *decode.D) {
|
||||
d.FieldStr("identification", 10, charmap.ISO8859_1)
|
||||
d.FieldStr("identification", 16, charmap.ISO8859_1)
|
||||
length := d.FieldU32("length")
|
||||
d.FieldRawLen("info", int64(length*8))
|
||||
d.FieldRawLen("info", int64(length)*8)
|
||||
},
|
||||
|
||||
// ID: 5Ah (90d) | Glue Block
|
||||
@ -404,22 +404,26 @@ func decodeBlock(d *decode.D) {
|
||||
0x5A: func(d *decode.D) {
|
||||
// Value: { "XTape!",0x1A,MajR,MinR }
|
||||
// Just skip these 9 bytes and you will end up on the next ID.
|
||||
d.FieldRawLen("value", int64(9*8))
|
||||
d.FieldRawLen("value", 9*8)
|
||||
},
|
||||
}
|
||||
|
||||
blockType := d.FieldU8("type", blockTypeMapper)
|
||||
|
||||
blockType := d.PeekUintBits(8)
|
||||
// Deprecated block types: C64RomType, C64TurboData, EmulationInfo, Snapshot
|
||||
if blockType == 0x16 || blockType == 0x17 || blockType == 0x34 || blockType == 0x40 {
|
||||
d.Fatalf("deprecated block type encountered: %02x", blockType)
|
||||
}
|
||||
|
||||
if fn, ok := blocks[blockType]; ok {
|
||||
fn(d)
|
||||
} else {
|
||||
d.Fatalf("block type not valid, got: %02x", blockType)
|
||||
}
|
||||
blockLabel := blockTypeMapper[blockType]
|
||||
d.FieldStruct(blockLabel, func(d *decode.D) {
|
||||
d.FieldU8("type", blockTypeMapper)
|
||||
|
||||
if fn, ok := blocks[blockType]; ok {
|
||||
fn(d)
|
||||
} else {
|
||||
d.Fatalf("block type not valid, got: %02x", blockType)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var blockTypeMapper = scalar.UintMapSymStr{
|
||||
@ -454,7 +458,7 @@ var blockTypeMapper = scalar.UintMapSymStr{
|
||||
0x5A: "glue_block",
|
||||
}
|
||||
|
||||
var hwInfoTypeMapper = scalar.UintMapDescription{
|
||||
var hwInfoTypes = scalar.UintMapDescription{
|
||||
0x00: "Computers",
|
||||
0x01: "External storage",
|
||||
0x02: "ROM/RAM type add-ons",
|
||||
@ -474,7 +478,7 @@ var hwInfoTypeMapper = scalar.UintMapDescription{
|
||||
0x10: "Graphics",
|
||||
}
|
||||
|
||||
var hwInfoTypeIdMapper = map[uint64]scalar.UintMapDescription{
|
||||
var hwInfoDevices = map[uint64]scalar.UintMapDescription{
|
||||
0x00: { // Computers
|
||||
0x00: "ZX Spectrum 16k",
|
||||
0x01: "ZX Spectrum 48k, Plus",
|
||||
@ -647,7 +651,7 @@ var hwInfoTypeIdMapper = map[uint64]scalar.UintMapDescription{
|
||||
},
|
||||
}
|
||||
|
||||
var hwInfoIdMapper = scalar.UintMapDescription{
|
||||
var hwInfoCompatibilityInfo = scalar.UintMapDescription{
|
||||
00: "RUNS on this machine or with this hardware, but may or may not use the hardware or special features of the machine.",
|
||||
01: "USES the hardware or special features of the machine, such as extra memory or a sound chip.",
|
||||
02: "RUNS but it DOESN'T use the hardware or special features of the machine.",
|
||||
|
Loading…
Reference in New Issue
Block a user