Prev: 04AA Up: Map Next: 053F
04C2: THE 'SA-BYTES' SUBROUTINE
Used by the routine at SA_CONTRL.
This subroutine is called to save the header information and later the actual program/data block to tape.
Input
A +00 (header block) or +FF (data block)
DE Block length
IX Start address
SA_BYTES 04C2 LD HL,$053F Pre-load the machine stack with the address SA_LD_RET.
04C5 PUSH HL
04C6 LD HL,$1F80 This constant will give a leader of about 5 seconds for a 'header'.
04C9 BIT 7,A Jump forward if saving a header.
04CB JR Z,SA_FLAG
04CD LD HL,$0C98 This constant will give a leader of about 2 seconds for a program/data block.
SA_FLAG 04D0 EX AF,AF' The flag is saved.
04D1 INC DE The 'length' is incremented and the 'base address' reduced to allow for the flag.
04D2 DEC IX
04D4 DI The maskable interrupt is disabled during the save.
04D5 LD A,$02 Signal 'MIC on' and border to be red.
04D7 LD B,A Give a value to B.
A loop is now entered to create the pulses of the leader. Both the 'MIC on' and the 'MIC off' pulses are 2,168 T states in length. The colour of the border changes from red to cyan with each 'edge'.
Note: an 'edge' will be a transition either from 'on' to 'off', or from 'off' to 'on'.
SA_LEADER 04D8 DJNZ SA_LEADER The main timing period.
04DA OUT ($FE),A MIC on/off, border red/cyan, on each pass.
04DC XOR $0F
04DE LD B,$A4 The main timing constant.
04E0 DEC L Decrease the low counter.
04E1 JR NZ,SA_LEADER Jump back for another pulse.
04E3 DEC B Allow for the longer path (reduce by 13 T states).
04E4 DEC H Decrease the high counter.
04E5 JP P,SA_LEADER Jump back for another pulse until completion of the leader.
A sync pulse is now sent.
04E8 LD B,$2F
SA_SYNC_1 04EA DJNZ SA_SYNC_1 MIC off for 667 T states from 'OUT to OUT'.
04EC OUT ($FE),A MIC on and red.
04EE LD A,$0D Signal 'MIC off and cyan'.
04F0 LD B,$37 MIC on for 735 T States from 'OUT to OUT'.
SA_SYNC_2 04F2 DJNZ SA_SYNC_2
04F4 OUT ($FE),A Now MIC off and border cyan.
The header v. program/data flag will be the first byte to be saved.
04F6 LD BC,$3B0E +3B is a timing constant; +0E signals 'MIC off and yellow'.
04F9 EX AF,AF' Fetch the flag and pass it to the L register for 'sending'.
04FA LD L,A
04FB JP SA_START Jump forward into the saving loop.
The byte saving loop is now entered. The first byte to be saved is the flag; this is followed by the actual data bytes and the final byte sent is the parity byte that is built up by considering the values of all the earlier bytes.
SA_LOOP 04FE LD A,D The 'length' counter is tested and the jump taken when it has reached zero.
04FF OR E
0500 JR Z,SA_PARITY
0502 LD L,(IX+$00) Fetch the next byte that is to be saved.
SA_LOOP_P 0505 LD A,H Fetch the current 'parity'.
0506 XOR L Include the present byte.
SA_START 0507 LD H,A Restore the 'parity'. Note that on entry here the 'flag' value initialises 'parity'.
0508 LD A,$01 Signal 'MIC on and blue'.
050A SCF Set the carry flag. This will act as a 'marker' for the 8 bits of a byte.
050B JP SA_8_BITS Jump forward.
When it is time to send the 'parity' byte then it is transferred to the L register for saving.
SA_PARITY 050E LD L,H Get final 'parity' value.
050F JR SA_LOOP_P Jump back.
The following inner loop produces the actual pulses. The loop is entered at SA_BIT_1 with the type of the bit to be saved indicated by the carry flag. Two passes of the loop are made for each bit thereby making an 'off pulse' and an 'on pulse'. The pulses for a reset bit are shorter by 855 T states.
SA_BIT_2 0511 LD A,C Come here on the second pass and fetch 'MIC off and yellow'.
0512 BIT 7,B Set the zero flag to show 'second pass'.
SA_BIT_1 0514 DJNZ SA_BIT_1 The main timing loop; always 801 T states on a second pass.
0516 JR NC,SA_OUT Jump, taking the shorter path, if saving a '0'.
0518 LD B,$42 However if saving a '1' then add 855 T states.
SA_SET 051A DJNZ SA_SET
SA_OUT 051C OUT ($FE),A On the first pass 'MIC on and blue' and on the second pass 'MIC off and yellow'.
051E LD B,$3E Set the timing constant for the second pass.
0520 JR NZ,SA_BIT_2 Jump back at the end of the first pass; otherwise reclaim 13 T states.
0522 DEC B
0523 XOR A Clear the carry flag and set A to hold +01 (MIC on and blue) before continuing into the '8 bit loop'.
0524 INC A
The '8 bit loop' is entered initially with the whole byte in the L register and the carry flag set. However it is re-entered after each bit has been saved until the point is reached when the 'marker' passes to the carry flag leaving the L register empty.
SA_8_BITS 0525 RL L Move bit 7 to the carry and the 'marker' leftwards.
0527 JP NZ,SA_BIT_1 Save the bit unless finished with the byte.
052A DEC DE Decrease the 'counter'.
052B INC IX Advance the 'base address'.
052D LD B,$31 Set the timing constant for the first bit of the next byte.
052F LD A,$7F Return (to SA_LD_RET) if the BREAK key is being pressed.
0531 IN A,($FE)
0533 RRA
0534 RET NC
0535 LD A,D Otherwise test the 'counter' and jump back even if it has reached zero (so as to send the 'parity' byte).
0536 INC A
0537 JP NZ,SA_LOOP
053A LD B,$3B Exit when the 'counter' reaches +FFFF. But first give a short delay.
SA_DELAY 053C DJNZ SA_DELAY
053E RET
Note: a reset bit will give a 'MIC off' pulse of 855 T states followed by a 'MIC on' pulse of 855 T states, whereas a set bit will give pulses of exactly twice as long. Note also that there are no gaps either between the sync pulse and the first bit of the flag, or between bytes.
Prev: 04AA Up: Map Next: 053F