11import { BufferAccess } from '../../common/BufferAccess.js' ;
2+ import { InvalidArgumentError } from '../../common/Exceptions.js' ;
23import { calculateChecksum8WithCarry } from '../../common/Utils.js' ;
3- import { type OptionContainer } from '../../encoding/Options.js' ;
4+ import { type OptionContainer , type ArgumentOptionDefinition } from '../../encoding/Options.js' ;
45import { type ConverterDefinition } from './ConverterDefinition.js' ;
56
7+ const irgLengthOption : ArgumentOptionDefinition < number | undefined > = {
8+ name : 'irglength' ,
9+ label : 'Intra record gap length' ,
10+ description : 'Gap between blocks in ms (default: 250)' ,
11+ common : false ,
12+ required : false ,
13+ type : 'text' ,
14+ parse ( value : string ) {
15+ if ( value === '' ) {
16+ return undefined ;
17+ }
18+ const casted = Number ( value ) ;
19+ if ( isNaN ( casted ) ) {
20+ throw new InvalidArgumentError ( this . name , `Option ${ this . name } is expected to be a number in decimal or hexadecimal notation.` ) ;
21+ }
22+
23+ return casted ;
24+ } ,
25+ } ;
26+
627const definition : ConverterDefinition = {
728 name : 'Atari .CAS-File' ,
829 identifier : 'ataricas' ,
@@ -20,7 +41,9 @@ const dataBytesPerBlock = 128;
2041const pilotIrgLength = 20000 ;
2142const defaultIrgLength = 250 ; // TODO: longer for 'ENTER'-loading
2243
23- function convert ( data : BufferAccess , _options : OptionContainer ) : BufferAccess {
44+ function convert ( data : BufferAccess , options : OptionContainer ) : BufferAccess {
45+ const irgLength = options . getArgument ( irgLengthOption ) ?? defaultIrgLength ;
46+
2447 const chunks = data . chunks ( dataBytesPerBlock ) ;
2548
2649 // FUJI-Header, baud-block, data blocks, end of file block
@@ -36,36 +59,43 @@ function convert(data: BufferAccess, _options: OptionContainer): BufferAccess {
3659
3760 for ( let i = 0 ; i < chunks . length ; i ++ ) {
3861 const chunk = chunks [ i ] ;
39-
4062 outBa . writeAsciiString ( 'data' ) ;
4163 outBa . writeUint16Le ( 132 ) ;
42- outBa . writeUint16Le ( i === 0 ? pilotIrgLength : defaultIrgLength ) ;
43-
44- const blockBa = BufferAccess . create ( 132 ) ;
45- blockBa . writeUint8 ( markerByte ) ;
46- blockBa . writeUint8 ( markerByte ) ;
47- const partialBlock = chunk . length ( ) !== dataBytesPerBlock ;
48- const blockType = partialBlock ? blockTypePartial : blockTypeFull ;
49- blockBa . writeUint8 ( blockType ) ;
50- blockBa . writeBa ( partialBlock ? chunk . chunksPadded ( dataBytesPerBlock , 0x00 ) [ 0 ] : chunk ) ;
51- if ( partialBlock ) {
52- blockBa . setUint8 ( 130 , chunk . length ( ) ) ;
53- }
54- blockBa . setUint8 ( 131 , calculateChecksum8WithCarry ( blockBa ) ) ;
55-
56- outBa . writeBa ( blockBa ) ;
64+ outBa . writeUint16Le ( i === 0 ? pilotIrgLength : irgLength ) ;
65+ outBa . writeBa ( createDataBlock ( chunk ) ) ;
5766 }
5867
5968 // end of file block
6069 outBa . writeAsciiString ( 'data' ) ;
6170 outBa . writeUint16Le ( 132 ) ;
62- outBa . writeUint16Le ( defaultIrgLength ) ;
71+ outBa . writeUint16Le ( irgLength ) ;
72+ outBa . writeBa ( createEndBlock ( ) ) ;
73+
74+ return outBa ;
75+ }
76+
77+ function createDataBlock ( data : BufferAccess ) : BufferAccess {
78+ const dataBlock = BufferAccess . create ( 132 ) ;
79+ dataBlock . writeUint8 ( markerByte ) ;
80+ dataBlock . writeUint8 ( markerByte ) ;
81+ const partialBlock = data . length ( ) !== dataBytesPerBlock ;
82+ const blockType = partialBlock ? blockTypePartial : blockTypeFull ;
83+ dataBlock . writeUint8 ( blockType ) ;
84+ dataBlock . writeBa ( partialBlock ? data . chunksPadded ( dataBytesPerBlock , 0x00 ) [ 0 ] : data ) ;
85+ if ( partialBlock ) {
86+ dataBlock . setUint8 ( 130 , data . length ( ) ) ;
87+ }
88+ dataBlock . setUint8 ( 131 , calculateChecksum8WithCarry ( dataBlock ) ) ;
89+
90+ return dataBlock ;
91+ }
92+
93+ function createEndBlock ( ) : BufferAccess {
6394 const endBlock = BufferAccess . create ( 132 ) ;
6495 endBlock . writeUint8 ( markerByte ) ;
6596 endBlock . writeUint8 ( markerByte ) ;
6697 endBlock . writeUint8 ( blockTypeEndOfFile ) ;
6798 endBlock . setUint8 ( 131 , calculateChecksum8WithCarry ( endBlock ) ) ;
68- outBa . writeBa ( endBlock ) ;
6999
70- return outBa ;
100+ return endBlock ;
71101}
0 commit comments