; Burst Nibbler - floppy routines ; ; Fragen: $05f7: Formatieren eines Tracks, wird hier SYNC geloescht ? $c2: current track $0300: 78 SEI $0301: a9 ee LDA #$ee $0303: 8d 0c 1c STA $1c0c $0306: a9 0b LDA #$0b $0308: 8d 0c 18 STA $180c $030b: ad 00 1c LDA $1c00 ; $030e: 29 f3 AND #$f3 ; motor off, LED off $0310: 8d 00 1c STA $1c00 ; $0313: a9 24 LDA #$24 ; $0315: 85 c2 STA $c2 ; current halftrack = 36 ; MAIN LOOP $0317: a2 45 LDX #$45 ; $0319: 9a TXS ; reset stack $031a: 98 TYA ; return value from last call $031b: 20 3f 05 JSR $053f ; parallel-send data byte to C64 $031e: a9 03 LDA #$03 ; $0320: 48 PHA ; set RTS to main loop $0317 $0321: a9 16 LDA #$16 ; $0323: 48 PHA ; $0324: 20 6e 05 JSR $056e ; read 1 byte with 4 byte command header $0327: 0a ASL ; * 2 for 16 bit index $0328: aa TAX ; $0329: bd 7c 06 LDA $067c,X ; get lb for RTS address $032c: 48 PHA ; $032d: bd 7b 06 LDA $067b,X ; get hb for RTS address $0330: 48 PHA ; $0331: 60 RTS ; -> function ---------------------------------------- ; read out track w/out waiting for Sync $0332: 20 3f 05 JSR $053f ; parallel-send data byte to C64 $0335: a9 ff LDA #$ff ; $0337: 8d 00 18 STA $1800 ; send handshake $033a: a2 20 LDX #$20 ; read $2000 GCR bytes $033c: 86 c0 STX $c0 ; $033e: b8 CLV ; $033f: d0 17 BNE $0358 ; read without waiting for Sync ; read out track after Sync $0341: 20 3f 05 JSR $053f ; parallel-send data byte to C64 $0344: a9 ff LDA #$ff ; $0346: 8d 00 18 STA $1800 ; send handshake $0349: a2 20 LDX #$20 ; read $2000 GCR bytes $034b: 86 c0 STX $c0 ; $034d: 2c 00 1c BIT $1c00 ; $0350: 30 fb BMI $034d ; wait for end of Sync $0352: ae 01 1c LDX $1c01 ; read GCR byte $0355: b8 CLV ; $0356: 50 fe BVC $0356 ; $0358: 70 25 BVS $037f ; $035a: 70 23 BVS $037f ; wait for next GCR byte $035c: 70 21 BVS $037f ; $035e: 70 1f BVS $037f ; $0360: 70 1d BVS $037f ; $0362: 70 1b BVS $037f ; $0364: 70 19 BVS $037f ; $0366: a2 ff LDX #$ff $0368: 70 15 BVS $037f $036a: 49 ff EOR #$ff ; toggle handshake value $036c: 70 28 BVS $0396 ; read and transfer GCR byte $036e: 8e 01 18 STX $1801 ; PA, port A (8 bit parallel data) $0371: 70 23 BVS $0396 ; read and transfer GCR byte $0373: 8d 00 18 STA $1800 ; send handshake (repeat last byte) $0376: c8 INY ; $0377: d0 df BNE $0358 ; $0379: c6 c0 DEC $c0 ; total byte counter hb $037b: f0 15 BEQ $0392 ; $037d: 50 d9 BVC $0358 $037f: ae 01 1c LDX $1c01 ; read GCR byte $0382: b8 CLV ; $0383: 49 ff EOR #$ff ; toggle handshake flag $0385: 8e 01 18 STX $1801 ; PA, port A (8 bit parallel data) $0388: 8d 00 18 STA $1800 ; send handshake $038b: c8 INY ; $038c: d0 ca BNE $0358 ; read 0x100 GCR bytes $038e: c6 c0 DEC $c0 ; $0390: d0 c6 BNE $0358 ; read 0x2000 GCR bytes total $0392: 8c 00 18 STY $1800 ; send handshake: $00 $0395: 60 RTS ; done reading ---------------------------------------- $0396: ae 01 1c LDX $1c01 ; read GCR byte $0399: b8 CLV ; $039a: 8e 01 18 STX $1801 ; PA, port A (8 bit parallel data) $039d: 8d 00 18 STA $1800 ; send handshake $03a0: c8 INY ; $03a1: d0 b5 BNE $0358 ; $03a3: c6 c0 DEC $c0 ; total byte counter hb $03a5: d0 b1 BNE $0358 ; $03a7: 8c 00 18 STY $1800 ; send handshake: $00 $03aa: 60 RTS ; done reading ---------------------------------------- ; step motor to destination halftrack $03ab: 20 7b 05 JSR $057b ; read byte from parallel data port $03ae: a2 01 LDX #$01 ; step value: step up $03b0: c5 c2 CMP $c2 ; compare with current track (CARRY!!!) $03b2: f0 33 BEQ $03e7 ; destination track == current -> RTS $03b4: 48 PHA ; push destination track $03b5: e5 c2 SBC $c2 ; calculate track difference $03b7: 10 04 BPL $03bd ; destination track > current -> $03b9: 49 ff EOR #$ff ; else negate track difference $03bb: a2 ff LDX #$ff ; step value: step down $03bd: a8 TAY ; # of tracks to step $03be: 8a TXA ; step value $03bf: 18 CLC ; $03c0: 6d 00 1c ADC $1c00 ; $03c3: 29 03 AND #$03 ; $03c5: 85 c0 STA $c0 ; temp store $03c7: ad 00 1c LDA $1c00 ; $03ca: 29 fc AND #$fc ; mask off stepper bits $03cc: 05 c0 ORA $c0 ; $03ce: 8d 00 1c STA $1c00 ; perform half step $03d1: a9 04 LDA #$04 ; $03d3: 85 c1 STA $c1 ; $03d5: a9 00 LDA #$00 ; busy wait $0400 times $03d7: 85 c0 STA $c0 ; $03d9: c6 c0 DEC $c0 ; $03db: d0 fc BNE $03d9 ; $03dd: c6 c1 DEC $c1 ; $03df: d0 f8 BNE $03d9 ; $03e1: 88 DEY ; $03e2: d0 da BNE $03be ; repeat for # of halftracks $03e4: 68 PLA ; pull destination track $03e5: 85 c2 STA $c2 ; current track = destination $03e7: 60 RTS ---------------------------------------- ; adjust routines to density value $03e8: 20 7b 05 JSR $057b ; read byte from parallel data port $03eb: 8d a6 03 STA $03a6 ; $03ee: 18 CLC ; $03ef: 69 04 ADC #$04 ; $03f1: 8d a2 03 STA $03a2 ; adjust read routines to the $03f4: 69 11 ADC #$11 ; density (timing) value read $03f6: 8d 91 03 STA $0391 ; from computer $03f9: 69 04 ADC #$04 ; $03fb: 8d 8d 03 STA $038d ; $03fe: 69 13 ADC #$13 ; $0400: 8d 7e 03 STA $037e ; $0403: 69 06 ADC #$06 ; $0405: 8d 78 03 STA $0378 ; ; set $1c00 bits (head/motor) $0408: 20 7b 05 JSR $057b ; read byte from parallel data port $040b: 85 c0 STA $c0 ; $1c00 mask $040d: 20 7b 05 JSR $057b ; read byte from parallel data port $0410: 85 c1 STA $c1 ; new bit value for $1c00 $0412: ad 00 1c LDA $1c00 ; $0415: 25 c0 AND $c0 ; mask off $1c00 bits $0417: 05 c1 ORA $c1 ; set new $1c00 bits $0419: 8d 00 1c STA $1c00 ; $041c: 60 RTS ; ---------------------------------------- ; detect 'killer tracks' $041d: a2 80 LDX #$80 ; $041f: 84 c0 STY $c0 ; $0421: ad 00 1c LDA $1c00 ; wait for end of Sync $0424: 10 09 BPL $042f ; $0426: 88 DEY ; $0427: d0 f8 BNE $0421 ; wait max. $8000 times $0429: ca DEX ; $042a: d0 f5 BNE $0421 ; $042c: a0 40 LDY #$40 ; track consists of neverending Sync $042e: 60 RTS ; -> $40 = $ff killer track ---------------------------------------- $042f: a2 00 LDX #$00 ; $0431: ad 01 1c LDA $1c01 ; read GCR byte $0434: b8 CLV ; $0435: 88 DEY ; $0436: d0 03 BNE $043b ; wait max $10000 times $0438: ca DEX ; $0439: f0 0a BEQ $0445 ; $043b: 50 f8 BVC $0435 ; $043d: b8 CLV ; $043e: c6 c0 DEC $c0 ; $0440: d0 f9 BNE $043b ; $0442: a0 00 LDY #$00 ; track contains at least 256 bytes $0444: 60 RTS ; -> $00 = track OK ---------------------------------------- $0445: a0 80 LDY #$80 ; track doesn't contain enough bytes $0447: 60 RTS ; -> $80 = track not formatted ---------------------------------------- ---------------------------------------- --- Density Scan for current track --- ---------------------------------------- $0448: a2 05 LDX #$05 ; $044a: 94 c3 STY $c3,X ; reset bit-rate statistic $044c: ca DEX ; $044d: 10 fb BPL $044a ; $044f: b8 CLV ; $0450: 50 fe BVC $0450 ; wait for GCR byte $0452: b8 CLV ; $0453: ad 01 1c LDA $1c01 ; read GCR byte $0456: 48 PHA ; $0457: 68 PLA ; (busy wait timing) $0458: 48 PHA ; $0459: 68 PLA ; $045a: ea NOP ; $045b: 70 0c BVS $0469 ; $045d: 70 0e BVS $046d ; $045f: 70 10 BVS $0471 ; measure bit-rate between bytes $0461: 70 12 BVS $0475 ; $0463: 70 14 BVS $0479 ; $0465: 70 16 BVS $047d ; $0467: d0 e6 BNE $044f ; -> time too long, retry with next pair $0469: a2 00 LDX #$00 ; bit-rate = 0 $046b: f0 14 BEQ $0481 ; $046d: a2 01 LDX #$01 ; bit-rate = 1 $046f: d0 10 BNE $0481 ; $0471: a2 02 LDX #$02 ; bit-rate = 2 $0473: d0 0c BNE $0481 ; $0475: a2 03 LDX #$03 ; bit-rate = 3 $0477: d0 08 BNE $0481 ; $0479: a2 04 LDX #$04 ; bit-rate = 4 $047b: d0 04 BNE $0481 ; $047d: a2 05 LDX #$05 ; bit-rate = 5 $047f: d0 00 BNE $0481 ; $0481: b8 CLV ; $0482: fe c3 00 INC $00c3,X ; adjust statistic for bit-rate X $0485: c8 INY ; $0486: 10 d2 BPL $045a ; $0488: a0 00 LDY #$00 ; $048a: b9 c4 00 LDA $00c4,Y ; transfer density statistic 1-5 to C64 $048d: 20 3f 05 JSR $053f ; parallel-send data byte to C64 $0490: c8 INY ; $0491: c0 04 CPY #$04 ; $0493: d0 f5 BNE $048a ; $0495: a0 00 LDY #$00 ; $0497: 60 RTS ; ---------------------------------------- ; write track after variable Sync length $0498: 20 7b 05 JSR $057b ; read byte from parallel data port $049b: 8d c3 04 STA $04c3 ; killer Sync length $049e: 20 7b 05 JSR $057b ; read byte from parallel data port $04a1: 8d e6 04 STA $04e6 ; branch value after last written byte $04a4: 20 7b 05 JSR $057b ; read byte from parallel data port $04a7: 8d ae 04 STA $04ae ; branch value if in Sync $04aa: 2c 00 1c BIT $1c00 ; $04ad: 30 fb BMI $04aa ; -> branch to parameter #3 $04af: a9 ce LDA #$ce $04b1: 8d 0c 1c STA $1c0c $04b4: 98 TYA ; $04b5: 8d 00 18 STA $1800 ; send handshake $04b8: a2 ff LDX #$ff ; $04ba: 8e 03 1c STX $1c03 ; CA data direction head (0->$ff: write) $04bd: a2 ff LDX #$ff ; $04bf: 8e 01 1c STX $1c01 ; write 0xff byte $04c2: a2 1e LDX #$1e ; Killer Sync length = parameter #1 $04c4: b8 CLV ; $04c5: 50 fe BVC $04c5 ; $04c7: b8 CLV ; $04c8: c8 INY ; Sync length = parameter #1 * 0x100 $04c9: d0 fa BNE $04c5 ; $04cb: ca DEX ; $04cc: 10 f7 BPL $04c5 ; $04ce: a0 ee LDY #$ee $04d0: 8e 01 1c STX $1c01 ; write data byte to track $04d3: b8 CLV ; $04d4: 49 ff EOR #$ff ; toggle handshake value $04d6: ae 01 18 LDX $1801 ; PA, port A (8 bit parallel data) $04d9: 8d 00 18 STA $1800 ; handshake $04dc: 50 fe BVC $04dc ; $04de: d0 f0 BNE $04d0 ; write until 0x00 byte is read $04e0: a9 55 LDA #$55 ; write a final 0x55 byte $04e2: 8d 01 1c STA $1c01 ; write 0x55 byte $04e5: d0 03 BNE $04ea ; (branch value = parameter #2) $04e7: ea NOP $04e8: ea NOP $04e9: ea NOP $04ea: ea NOP $04eb: ea NOP $04ec: 8c 0c 1c STY $1c0c $04ef: 8e 03 1c STX $1c03 ; CA data direction head ($ff->0: read) $04f2: 8e 00 18 STX $1800 ; handshake $04f5: a0 00 LDY #$00 ; done writing $04f7: 60 RTS ---------------------------------------- ; write a track on destination $04f8: 20 7b 05 JSR $057b ; read byte from parallel data port $04fb: 8d 02 05 STA $0502 ; can change Sync Branch value $04fe: 2c 00 1c BIT $1c00 ; wait for end of Sync, if writing $0501: 30 fb BMI $04fe ; halftracks, and 'adjust target' $0503: a9 ce LDA #$ce ; selected, else BMI $0503 $0505: 8d 0c 1c STA $1c0c $0508: 98 TYA $0509: ce 03 1c DEC $1c03 ; CA data direction head (0->$ff: write) $050c: 8d 00 18 STA $1800 ; send handshake $050f: a2 55 LDX #$55 ; write 256x $55 bytes after Sync $0511: 8e 01 1c STX $1c01 ; $0514: b8 CLV ; $0515: 50 fe BVC $0515 ; $0517: c8 INY ; $0518: d0 fa BNE $0514 ; $051a: 8e 01 1c STX $1c01 ; write GCR byte to disk $051d: b8 CLV ; $051e: 49 ff EOR #$ff ; toggle handshake value $0520: ae 01 18 LDX $1801 ; PA, port A (8 bit parallel data) $0523: 8d 00 18 STA $1800 ; send handshake $0526: 50 fe BVC $0526 ; $0528: d0 f0 BNE $051a ; write GCR bytes until $00 byte $052a: b8 CLV ; $052b: 50 fe BVC $052b ; $052d: a9 ee LDA #$ee $052f: 8d 0c 1c STA $1c0c $0532: 8e 03 1c STX $1c03 ; CA data direction head ($ff->0: read) $0535: 8e 00 18 STX $1800 ; send handshake $0538: a0 00 LDY #$00 $053a: 60 RTS ---------------------------------------- ; read $1c00 motor/head status $053b: ac 00 1c LDY $1c00 ; $053e: 60 RTS ; ---------------------------------------- $053f: 4c 52 05 JMP $0552 ; parallel-send data byte to C64 ---------------------------------------- $0542: a2 00 LDX #$00 $0544: 8e 0c b8 STX $b80c $0547: ca DEX $0548: 8e 08 b8 STX $b808 $054b: a2 04 LDX #$04 $054d: 8e 0c b8 STX $b80c $0550: d0 05 BNE $0557 $0552: a2 ff LDX #$ff ; $0554: 8e 03 18 STX $1803 ; data direction port A = output $0557: a2 10 LDX #$10 ; $0559: 2c 00 18 BIT $1800 ; wait for ATN IN = 1 $055c: 10 fb BPL $0559 ; $055e: 8d 01 18 STA $1801 ; PA, port A (8 bit parallel data) $0561: 8e 00 18 STX $1800 ; handshake: DATA OUT = 0, ATN ack = 1 $0564: ca DEX ; $0565: 2c 00 18 BIT $1800 ; $0568: 30 fb BMI $0565 ; wait for ATN IN = 0 $056a: 8e 00 18 STX $1800 ; ATN OUT = 0 $056d: 60 RTS ; ---------------------------------------- ; read 1 byte with 4 byte command header $056e: a0 04 LDY #$04 ; read 4 byte command header $0570: 20 7b 05 JSR $057b ; read byte from parallel data port $0573: d9 9a 06 CMP $069a,Y ; check with command header: $0576: d0 f6 BNE $056e ; $00,$55,$aa,$ff $0578: 88 DEY ; $0579: d0 f5 BNE $0570 ; $057b: 4c 8d 05 JMP $058d ; read byte from parallel data port ---------------------------------------- $057e: a2 00 LDX #$00 $0580: 8e 0c b8 STX $b80c $0583: 8e 08 b8 STX $b808 $0586: a2 04 LDX #$04 $0588: 8e 0c b8 STX $b80c $058b: d0 05 BNE $0592 $058d: a2 00 LDX #$00 ; $058f: 8e 03 18 STX $1803 ; data direction port A = input $0592: a2 10 LDX #$10 ; $0594: 2c 00 18 BIT $1800 ; wait for ATN IN = 1 $0597: 10 fb BPL $0594 ; $0599: 8e 00 18 STX $1800 ; handshake: DATA OUT = 0, ATN ack = 0 $059c: ca DEX ; $059d: 2c 00 18 BIT $1800 ; $05a0: 30 fb BMI $059d ; wait for ATN IN = 0 $05a2: ad 01 18 LDA $1801 ; PA, port A (8 bit parallel data) $05a5: 8e 00 18 STX $1800 ; DATA OUT = 1 $05a8: 60 RTS ; ---------------------------------------- ; send 0,1,2,...,$ff bytes to C64 $05a9: 98 TYA ; $05aa: 20 3f 05 JSR $053f ; parallel-send data byte to C64 $05ad: c8 INY ; (send 0,1,2,...,$ff) $05ae: d0 f9 BNE $05a9 ; $05b0: 60 RTS ; ---------------------------------------- $05b1: a9 11 LDA #$11 ; $05b3: 85 22 STA $22 ; current track = 17 $05b5: 4c 22 eb JMP $eb22 ; UI command (?) ---------------------------------------- ; measure destination track length $05b8: a2 20 LDX #$20 $05ba: a9 ce LDA #$ce $05bc: 8d 0c 1c STA $1c0c $05bf: ce 03 1c DEC $1c03 ; CA data direction head (0->$ff: write) $05c2: a9 55 LDA #$55 ; $05c4: 8d 01 1c STA $1c01 ; write $55 byte $05c7: 50 fe BVC $05c7 ; $05c9: b8 CLV ; $05ca: c8 INY ; write $2000 times $05cb: d0 fa BNE $05c7 ; $05cd: ca DEX ; $05ce: d0 f7 BNE $05c7 ; $05d0: a9 ff LDA #$ff ; $05d2: 8d 01 1c STA $1c01 ; write $ff byte (Sync mark) $05d5: 50 fe BVC $05d5 ; $05d7: b8 CLV ; $05d8: e8 INX ; write 5 times (short Sync) $05d9: e0 05 CPX #$05 ; $05db: d0 f8 BNE $05d5 ; $05dd: a9 ee LDA #$ee $05df: 8d 0c 1c STA $1c0c $05e2: 8c 03 1c STY $1c03 ; CA data direction head ($ff->0: read) $05e5: ad 00 1c LDA $1c00 ; $05e8: 10 09 BPL $05f3 ; wait for Sync mark $05ea: 50 f9 BVC $05e5 ; $05ec: b8 CLV ; $05ed: e8 INX ; X/Y = counter: GCR bytes in one spin $05ee: d0 fa BNE $05ea ; $05f0: c8 INY ; $05f1: d0 f7 BNE $05e ; $05f3: 8a TXA ; (0) : Track 'too long' $05f4: 4c 3f 05 JMP $053f ; parallel-send data byte to C64 ---------------------------------------- ; initialise write track $05f7: a2 02 LDX #$02 ; $05f9: a9 ce LDA #$ce $05fb: 8d 0c 1c STA $1c0c $05fe: ce 03 1c DEC $1c03 ; CA data direction head (0->$ff: write) $0601: a9 55 LDA #$55 ; $0603: 8d 01 1c STA $1c01 ; write $55 byte $0606: 50 fe BVC $0606 ; $0608: b8 CLV ; $0609: c8 INY ; write $0200 times $060a: d0 fa BNE $0606 ; makes a clean start of track $060c: ca DEX ; $060d: d0 f7 BNE $0606 ; $060f: a9 ff LDA #$ff ; $0611: 8d 01 1c STA $1c01 ; write $ff byte (Sync mark) $0614: 50 fe BVC $0614 ; $0616: b8 CLV ; $0617: e8 INX ; $0618: e0 0a CPX #$0a ; write 10 times (long Sync mark) $061a: d0 f8 BNE $0614 ; $061c: a9 55 LDA #$55 ; $061e: 8d 01 1c STA $1c01 ; write $55 bytes $0621: a2 1d LDX #$1d ; $0623: 50 fe BVC $0623 ; $0625: b8 CLV ; write $1d00 GCR times $0626: c8 INY ; $0627: d0 fa BNE $0623 ; $0629: ca DEX ; $062a: d0 f7 BNE $0623 ; $062c: a9 ee LDA #$ee $062e: 8d 0c 1c STA $1c0c $0631: 8c 03 1c STY $1c03 ; CA data direction head ($ff->0: read) $0634: 60 RTS ---------------------------------------- ; find last GCR byte before 'hole' ; or next Sync $0635: 2c 00 1c BIT $1c00 ; $0638: 30 fb BMI $0635 ; wait for end of Sync $063a: ad 01 1c LDA $1c01 ; skip GCR byte $063d: b8 CLV ; $063e: 50 fe BVC $063e ; $0640: ad 01 1c LDA $1c01 ; read GCR byte $0643: a2 0a LDX #$0a ; minimum 'hole' length = 10 $0645: a8 TAY ; return with last read byte $0646: ca DEX ; $0647: f0 0a BEQ $0653 ; -> return with Y $0649: 50 fb BVC $0646 ; wait for next GCR byte $064b: b8 CLV ; $064c: ad 01 1c LDA $1c01 ; $064f: c9 ff CMP #$ff ; if next GCR byte == Sync, return $0651: d0 f0 BNE $0643 ; else, continue searching $0653: 60 RTS ; ---------------------------------------- ; read out track from MARKER BYTE $0654: 20 7b 05 JSR $057b ; read byte from parallel data port $0657: 8d 75 06 STA $0675 ; -> MARKER BYTE $065a: 20 3f 05 JSR $053f ; parallel-send data byte to C64 $065d: a9 ff LDA #$ff ; $065f: 8d 00 18 STA $1800 ; send handshake $0662: a2 20 LDX #$20 ; $0664: 86 c0 STX $c0 ; read $2000 GCR bytes $0666: 2c 00 1c BIT $1c00 ; wait for end of Sync $0669: 30 fb BMI $0666 ; $066b: ae 01 1c LDX $1c01 ; read GCR byte ($ff) $066e: b8 CLV ; $066f: 50 fe BVC $066f ; $0671: ae 01 1c LDX $1c01 ; read GCR byte $0674: e0 37 CPX #$37 ; check for MARKER BYTE $0676: d0 ee BNE $0666 ; wrong header mark, repeat $0678: 4c 4d 03 JMP $034d ; -> read out track ---------------------------------------- --- Jump table ---; return value: Y ---------------------------------------- $067b: aa 03 ; step motor to destination halftrack $067d: 07 04 ; set $1c00 bits (head/motor) $067f: b0 05 ; track $22 = 17, UI command: $eb22 $0681: 40 03 ; read out track after Sync $0683: 97 04 ; write track after variable Sync length $0685: e7 03 ; adjust read routines to density value $0687: 1c 04 ; detect 'killer tracks' $0689: 47 04 ; perform Density Scan $068b: 31 03 ; read out track w/out waiting for Sync $068d: 3a 05 ; read $1c00 motor/head status $068f: a8 05 ; send 0,1,2,...,$ff bytes to C64 $0691: f7 04 ; write a track on destination $0693: b7 05 ; measure destination track length $0695: f6 05 ; initialise write track (long Sync) $0697: 34 06 ; find GCR byte before 'hole' or 'Sync' $0699: 53 06 ; read out track from MARKER BYTE $069b: ff aa 55 00 ; command header code