home *** CD-ROM | disk | FTP | other *** search
/ Outlet 52 / outlet-52.mgt / l1 < prev    next >
Text File  |  2021-04-18  |  20KB  |  1 lines

  1.     LD BREAK 056B (0556 LD BYTES)                                      Exit from:                                                       0556 LD BYTES through one of:                                   056C LD START                                                   0574 LD WAIT                                                    0580 LD LEADER                                                  058F LD SYNC                                                                                                                LD BYTES subroutine 0556                                            Reads a string of bytes from cassette tape. Used to readboth headers and program/data blocks.                                   Disables the maskable interrupt; because repeated calls to the KEYBOARD routines would interfere with the exact timing  of the tape reading routines, and also because the EAR port usedto read the tape is shared with the keyboard input. The BREAK/  SPACE key is frequently checked, but other keys are ignored     throughout the routine.                                                 The first part of the routine, up to the middle of LD   SYNC, is concerned with identifying the leader pulses on the    tape; see 04C2 SA BYTES. There should be a series of regular    pulses with 2168d T states of "off" followed by 2168d T states  of "on", ie 2168d T states between each on/off "edge"; the      series lasting 2 seconds for a header or 5 for a data block,    followed by a shorter "sync pulse".                                     When a pulse is detected, the routine waits for about a second, then checks again; if pulses are still being received,  it counts 256d pulses and then, still checking every pulse,     starts to look for the sync pulse. This begins with a shorter   "off" period of only 667d T states, and then has an "on" of 735dT states. If the short "off" is found but the "on" is too long, "Tape loading error" is reported. The sync pulse is the signal  for the routine to stop checking leader pulses and start readingthe bytes of the saved file.                                            The bytes are read one bit at a time by the LD 8 BITS   loop: a long on/off pulse, more than 2400d T states, signals    "one" and a short pulse signals "zero". As each byte is read, itis XORed with a parity matching byte, set initially at zero. Cf 0505 SA LOOP P; every byte of the data was XORed with the paritybyte, which started at zero, and the final result put on tape atthe end of the data block. Now each byte is XORed with the      parity matching byte, including the parity byte at the end, and if the result isn't zero something has gone wrong. Not an       infallible test, but quite a good one.                                  Detection of pulses is by calls to 05E7 LD EDGE 1 for a half pulse or or 05E3 LD EDGE 2 for a whole on/off pulse, see   their index entries; they look for an edge, or two edges, withinthe time allowed by the delay counter in the B register, which  is counted_upwards to 256d. They return with                           - NC and Z if time ran out                                      - NC and NZ if BREAK/SPACE is pressed; NC is referred to in the notes and this entry as the "Tape error" signal, but it  also signals a BREAK. The zero flag makes sure the "BREAK"      report is given instead of the "Tape error" report when         appropriate. Throughout this routine the SPACE key works as a   BREAK, with or without caps shift                                      - C if edge(s) found before time ran out.                        They also change the border colour, with the last three bits of the output going to port FE; for leader pulses it       changes the border from 101b/05 CYAN to 010b/02 RED and back on every edge. After the sync pulse has been received the colour isXORed with 00000011b/03, making the colours 110b/06 YELLOW and  001b/01 BLUE.                                                           For checking pulses, the time allowance in T states is  as explained in the index entry for 05E7 LD EDGE 1.                     A leader pulse should take 2 * 2168 = 4336d T states    from "off" to "off"; for leader pulses the counter is set to 9C/156d, allowing                                                                 15440 - 59 * 156 = 6236d T states                 as a maximum time for the on/off pulse, and on return from LD  EDGE 2 the counter is checked, and the double pulse rejected if it took less than C7 - 9C = 2Bh/43d turns of the counter, which is                                                                                     59 * 43 + 880 = 3417d T states            as a minimum.                                                          For the sync pulse, the "off" should be only 667d T     states, and "off" and "on" together should be 667 + 735 = 1402d T states. The counter for the "off" half-pulse is set to C9h/   201d, allowing                                                                 15415 - 59 * 201 = 3556d T states                 as a maximum; any longer "off" will make a "Tape error" report.On return from LD EDGE the "off" pulse is rejected if it took   more than D4 - C9 = 0Bh/11d turns of the counter, which is                       404 + 59 * 11 = 1053d T states                  and the search for a sync pulse is resumed.                            When the "off" sync pulse has been accepted, the end of the "on" pulse is looked for without resetting the counter, so  it must arrive within a total of 3556d T states from the start  of the "off", plus a few for the recall of the LD EDGE          subroutine, or "Tape error" will be reported.                           When loading bits from the saved file, a double pulse   longer than 2400 T states counts as a one, a shorter pulse as a zero. The delay counter is set at B0h/176d, allowing                           15446  - 59 * 176 = 5062d T states                maximum, and checked against CB on return; if the length of thepulse was less than CC - B0 = 1Ch/28d turns of the counter,     which is                                                                         830 + 28 * 59 = 2482d T states                  the bit is counted as zero.                                           Input parameters: DE holds the length, the number of     bytes to be read; 11h/17d for a header, otherwise a number read from the header                                                         - A holds the header/data index, 00 for a header, FF    otherwise.                                                              - IX holds the load pointer; the address to which the   first byte read from tape should be loaded, or in the case of   VERIFY, with which it should be compared                                - the carry flag signals C for LOAD, NC for VERIFY.            Action: increment D; no way this can make zero, so it    makes an NZ flag signalling "first byte"                                - save the header/data index in the AF' registers with  the LOAD/VERIFY flag and the first byte flag                            - restore D                                                     - disable the maskable interrupt                                - output 00001111b/0F to port FE; this makes the border WHITE and turns off the MIC socket, see ports                           - stack the return address 053F SA/LD RET                       - input from port FE; bit 6 will be zero if there is an incoming pulse from EAR                                                 - shift the bit right; now bit 5 gives the signal               - AND with 00100000b/20h and OR with 00000010b/02; the  result is 22h if there is no pulse, 02 if there is one. This is the first output byte for LD EDGE, sent to port FE if it finds  an edge. The 010b in the last three bits turns the border RED,  bit 5 is used for checking whether the edge has been changed            - set the Z flag.                                              _056B_LD_BREAK: if the flag shows NZ, return; this exit  point is repeatedly used when the BREAK/SPACE key might have    been pressed producing NZ.                                             _056C_LD_START: call 05E7 LD EDGE 1 to look for a half-  pulse; on the first call the delay counter may have any value           - if no pulse was found or BREAK was pressed jump back  to LD BREAK; the delay counter is now zero, so the timing limit for the half-pulse is 15418d T states                                   - (a pulse received) make a timer byte of 0415h.                _0574_LD_WAIT: as B is zero, make 100h turns of the     DJNZ; 0Dh T states per turn                                             - decrement HL and repeat till HL is zero; the decrementand zero check take 1Ah T states, so the whole waiting loop     takes                                                                       415h * (1Ah + 100h * 0Dh) = 415h * D1Ah                                                   = 1045d * 3354d                                                 = 3,504,930 T states              - call LD EDGE 2 with zero in the delay counter;        allowing maximum 15446d T states for the on/off pulse this time         - if there aren't two edges, jump back to LD BREAK to   start all over again.                                                   _0580_LD_LEADER: put 9C in the delay counter to check   for a leader pulse                                                      - call 05E3 LD EDGE 2 to look for an on/off; if it      doesn't come, jump back to LD BREAK and start again                     - if the delay counter is less than C5h jump back to LD START; it has gone up by less than C5 - 9C, this isn't a proper pulse, start again                                                      - increment H; it was zero on exit from LD WAIT                 - if it isn't yet zero loop back to LD LEADER.                 _058F_LD_SYNC (it is zero again; 256d pulses have been   checked. This only takes 512 * 2168 = 1,110,016d T states, about1/3 of a second): call LD EDGE 1 with C9 in the delay counter tolook for the "off" half-pulse of the sync pulse                         - if it returns with NC jump back to LD BREAK and start all over again; no edge was found                                       - (an edge was found) if the delay counter is more than D3 jump back to LD SYNC to test the next pulse; it has gone up  by more than D3 - C9, the pulse is too long for a sync pulse            - (sync pulse "off" found) call LD EDGE 1 again; the    second half-pulse of the sync pulse must arrive before the delaycounter gets to zero. If it doesn't, return with a "Tape error" signal                                                                  - (sync pulse received and checked) XOR the colour with 00000011b/03, making the colours 110b/06 YELLOW and 001b/01 BLUE        - zero a parity matching byte                                   - set the delay counter to B0h to read bits                     - jump into the byte-loading loop at LD MARKER.                _05A9_LD_LOOP (the loop returns here with the L register holding each new byte loaded from the tape): get AF', which was saved at the start with the header/data index, a LOAD/VERIFY    flag, and a "first byte" flag                                           - if this is the first byte jump on to LD FLAG                  - if this is verification jump on to LD VERIFY                  - (this is a LOAD) put the byte just read into RAM at   the load pointer                                                        - jump on to LD NEXT.                                          _05B3_LD_FLAG (the first byte, the header/data flag): if it doesn't match the header/data index just got in A return withthe "Tape error" signal                                                 - increment the length counter; the flag isn't recorded and doesn't count in the length                                         - jump on to LD DEC.                                           _05BD_LD_VERIFY: (verification) compare the byte from    tape with the byte at the load pointer                                  - if they don't match, return with the "Tape error"     signal.                                                                _05C2_LD_NEXT: move on the load pointer.                        _05C4_LD_DEC: decrement the length counter                       - save the flags in F'; A doesn't matter now                    - reset the delay counter; why now B2h instead of B0h?  But it makes little difference                                         _05C8_LD_MARKER: put one in the lo bit of an "8-bit loop"counter; see index entry after end of alphabet                         _05CA_LD_8_BITS: call LD EDGE 2 to look for the on/off   bit pulse                                                               - if two edges aren't found return with the "Tape error"signal                                                                  - if the delay counter is more than CB set the carry    flag; long pulse                                                        - rotate the loop counter, with the carry flag into its lo bit and its hi bit into carry                                        - reset the delay counter to B0                                 - if the loop counter still had a zero hi bit loop back to LD 8 BITS                                                            - (eight bits read; if the hi bit was one, it must be   the original lo bit having worked its way to hi bit through     eight turns of the loop) XOR the byte read from the tape with   the parity matching byte                                                - check the length counter                                      - if it isn't zero jump back to LD LOOP                         - (the loading is complete) if the parity matching byte isn't zero make an NC flag; the "Tape error" signal                     - return.                                                      Exit: RETs at:                                                   - LD BREAK; if BREAK pressed                                    - LD SYNC; if the sync pulse fails                              - LD VERIFY; if verification fails                              - LD 8 BITS; if the bit pulses fail or BREAK is pressed,or when loading is complete, with the result of testing the     parity byte.                                                            All these are indirect jumps to 053F SA/LD RET, the     address stacked at the start of the subroutine. It restores the original border colour, checks the BREAK key, enables the       interrupt, and gives the BREAK message or returns with a signal for "Tape error" if appropriate.                                       Output parameters: the C flag indicates that no error hasbeen detected                                                           - IX holds the address after the last byte loaded.             Called from:                                                     0767 LD LOOK H                                                  0802 LD BLOCK                                                                                                               LD CH PR 07AD (0605 SAVE ETC)                                      Jumps from:                                                      07A6 LD NAME                                                                                                                LD CONTRL 0808 (0605 SAVE ETC)                                     Jumps from:                                                      07AD LD CH PR                                                                                                               LD CONT 1 0819 (0605 SAVE ETC)                                     Jumps from:                                                      0808 LD CONTRL                                                                                                              LD CONT 2 0825 (0605 SAVE ETC)                                     Jumps from:                                                      0808 LD CONTRL                                                                                                              LD DATA 082E (0605 SAVE ETC)                                       Jumps from:                                                      0819 LD CONT 1                                                                                                              LD DATA 1 084C (0605 SAVE ETC)                                     Jumps from:                                                      082E LD DATA                                                                                                                LD DEC 05C4 (0556 LD BYTES)                                        Jumps from:                                                      05B3 LD FLAG                                                                                                                LD DELAY 05E9 (05E7 LD EDGE 1)                                     Jumps from:                                                      aut                                                                                                                         LD EDGE 1 subroutine 05E7 see also ports, timing, 0556 LD   BYTES                                                                   Reads the EAR port, bit 6 of port 7FFE, a prescribed    number of times, looking for an_edge, ie a change from EAR on ->off or EAR off -> on; these are the two_edge_types. Port 7FFE   also supplies a reading of the last half-row of keys on the     keyboard: its lo bit is zero if SPACE is being pressed, and if  CAPS SHIFT is also being pressed this means a BREAK. In fact theroutine doesn't check CAPS SHIFT, and either SPACE or BREAK keyswill produce a BREAK.                                                   The routine contains two timed loops, a "waiting loop"  LD DELAY and a_sampling_loop LD SAMPLE. The waiting loop is     always the same: the first 21d turns of the loop each take 16d Tstates, but the last turn only takes 11d, because JR Z takes    longer to jump than not to jump. To this must be added 7 for theinitial load of A and 4 for the AND A which follows, total                   21 * 16 + 11 + 7 + 4 = 358d T states.                      The number of times the sampling loop is turned is set  by the timing constant in the B register when the routine is    called. This constant is counted_upwards from its initial value,and if it reaches zero the subroutine returns signalling "no    edge found".                                                            Each turn of the loop takes 59d T states if it doesn't  RET for time-up or BREAK, except the last which only takes 54d. The notes count this wrong as 58d.                                      The "overhead" operations which follow the loop take 51dT states, but allowing 5 for the JR Z on leaving the loop cuts  this down to an effective 46d.                                          So the time taken for a call to LD EDGE 1 if it_doesn't find an edge is 358d waiting, plus 59d for each of 255d - B     turns of the loop, not counting the last, plus 15d for INC B andRET Z when B reaches zero, ie                                         358 + 59 * (255 - B) + 15 = 15418 - B * 59d T states              If it_does find an edge, it returns with B still not    counted up to zero; call this value b2. B2 indicates the length of time taken by the subroutine to find the edge: the time is   358d waiting, plus 59d for each of the b2 - B turns, plus the   overhead 46d, ie                                                    358 + 59 * (b2 - B) + 46 = 59 * (b2 - B) + 404d T states.          Input parameters: B holds the timing constant to control the number of turns made in the LD SAMPLE sampling loop; FF     makes no loops, 00 makes FFh/255d loops