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

  1.     PRINT A FLOATING POINT NUMBER SUBROUTINE see 2DE3 PRINT FP                                                                      PRINT ALL CHARACTERS SUBROUTINE see 0B7F PR ALL (0B24 PO    ANY)                                                                                                                                PRINT ANY CHARACTERS SUBROUTINE see 0B24 PO ANY                                                                                 PRINT A QUESTION MARK SUBROUTINE see 0A69 PO QUEST                                                                              PRINT A WHOLE BASIC LINE SUBROUTINE see 1855 OUT LINE                                                                           PRINT A 1 subroutine (restart) 0010                                 Sends a single byte to output.                                  The output routine of the Spectrum system; although we  usually call it "printing", what actually happens to the bytes  output depends on the channel selected at the moment. Channel S will put them on the main screen, channel K into the lower      screen, channel P will send them to the ZX printer, channel R   will copy them to the work space; other channels selected       through Interface 1 etc will send them to a network, to a DATA  file on Microdrive, etc. Even when printing to the screen, thereis an important distinction between this output routine and the PRINT command routine, see under_printing.                              The routine makes in effect a "computed GO SUB" call by going into CALL SUB with a pointer to the current output addressfrom the channel data, which will be                                  09F4 PRINT OUT for channels 'K', 'S' and 'P'                    150F ADD CHAR for channel 'R'; only available to ROM              See 15AF INITIAL CHANNEL INFORMATION. The output        subroutine address is pointed to by 5C51 CURCHL; from m/c,      though not from BASIC, you can put any address you like in this system variable, and this is no doubt how Interface 1 and other peripherals manipulate the output of the Spectrum.                      PRINT A 1 operates with the alternate registers, and as a consequence cannot be called "recursively", ie from within itsown routines, without getting the main registers back and       probably corrupting them: this is handled by calling 0C3B PO    SAVE instead of PRINT A 1 whenever recursive printing is        required, see the index entry.                                         Input parameters: A holds the byte to be output.                Action: jump on to PRINT A 2; only eight bytes are       available for a restart. [The five bytes of PRINT A 2 could wellhave been put here, followed by a jump to CALL SUB.]                   _15F2_PRINT_A_2: save all the main registers by EXX              - put HL' on the stack; very often the vital return     address from calculator operations                                      - get a pointer to the current channel output routine   address in 5C51 CURCHL                                                 _15F7_CALL_SUB: read the address from the channel        information                                                             - call 162C CALL JUMP, which is just a JP (HL); thus in effect it calls the subroutine addressed in 5C51 CURCHL                 - restore the registers.                                       Exit: RET, from 15F7 CALL SUB.                                  Output parameters: none                                          - the main registers, provided the output routine       doesn't use EXX, and HL' are saved, but not the A register.            Called from:                                                     07AD LD CH PR (twice)                                           0C3B PO SAVE                                                    133C MAIN 5 (twice)                                             1835 LIST ALL                                                   1865 OUT LINE1                                                  196D OUT CH 3                                                   1FF5 PRINT CR                                                   201E PR AT TAB (3 times)                                        203C PR STRING                                                  204E PR POSN 1                                                  21FC CO TEMP 4 (twice)                                          2DE3 PRINT FP                                                   2DF2 PF NEGTVE                                                  2F64 PF DEC 0$                                                  2F6C PF E FRMT                                                  2F85 PF E SGN                                                                                                               PRINT A 2 15F2 (0010 PRINT A 1)                                    Jumps from:                                                      0010 PRINT A 1                                                                                                              print buffer (ad hoc) see 2DE3 PRINT FP                                                                                         PRINT comma (06) see control characters                                                                                         PRINT COMMA SUBROUTINE see 0A5F PO COMMA                                                                                        PRINT CR subroutine 1FF5                                            See 1FCD PRINT.                                                Called from:                                                     2061 PR POSN 2                                                 Exit from:                                                       1FF2 PRINT 4                                                                                                                printer (ZX printer), printer buffer, printer 'column',      printer motor, printer position                                        Output to the ZX printer is executed by opening channel P and using 0010 PRINT A 1, which calls 09F4 PRINT OUT. The     pixels picked up by 0B65 PO CHAR and following are output by    0BD3 PR ALL 6 to the print column position kept in 5C80 PR CC,  in the print buffer, instead of to the screen. For the OUT      commands of 0EF4 COPY LINE etc used to operate the motor and    stylus, see ports.                                                      The ZX printer is much more a toy printer than the      Spectrum is a toy computer. Many more sophisticated, but more   expensive, printers can be bought, with interfaces which divert the output of channel P to their own routines, so that LPRINT,  LLIST and even COPY are effective with them.                            The print buffer is a blank space of 100h/256d bytes at 5B00h/23296d in RAM; enough for 20h/32d characters each of 8    pixels. It is undisturbed by all operations of the Spectrum     except those concerned with the ZX printer, which leaves it     available for m/c programs not using the printer; a good place  to keep variables, flags etc. If IX is placed at 5B7Fh, all its bytes are accessible to the IX indexing system.                         Every time the buffer is filled, or a newline is output,its bits are output to the printer by 0ECD COPY BUFF, and it is blanked to zeroes by 0EDF CLEAR PRB; this is also done by 1303  MAIN 4 on completion of any command, even if the buffer isn't   full, providing bit 2 of FLAGS2 signals it has been used.               09F4 PRINT OUT handles output to printer or screen              0A23 PO BACK 1 cannot backspace to last line on printer         0A4F PO ENTER carriage return clears print buffer               0A87 PO CONT line numbers ignored in output to printer          0ADC PO STORE position values read differently                  0AFC PO ST PR stores position values for printer                0B03 PO FETCH position values read differently                  0B1D PO F PR fetches position values for printer                0B7F PR ALL print buffer cleared after 20h characters           0BA4 PR ALL 2 flags signalling use of printer                   0BB7 PR ALL 4 pixel prepared for in print buffer                0BD3 PR ALL 6 pixel put in print buffer                         0C55 PO SCR skipped when outputting to printer                  0DD9 CL SET prepares position value for PO STORE                0ECD COPY BUFF copies eight pixel lines to printer              0EDA COPY END stops motor                                       0EDF CLEAR PRB prepares to blank printer buffer                 0EE7 PRB BYTES blanks printer buffer                            0EF4 COPY LINE slows motor for last two lines                   0EFD COPY L 1 handles BREAK during line printing                0F0C COPY L 2 checks that printer present and ready             0F1E COPY L 5 outputs bits to printer                           1219 RAM SET clears printer buffer                              1303 MAIN 4 empties printer buffer after execution              1646 CHAN S 1 signals "not using printer"                       164D CHAN P signals "using printer"                                                                                         print format for numbers see 2DE3 PRINT FP below                                                                                PRINT FP subroutine 2DE3                                            Part of the PRINT command routine: converts the last    value on the calculator stack, which can be any kind of number  handled by the floating-point calculator, to the standard_14-   _character_number_format, and outputs this version to screen,   printer etc, through the current output channel.                        For the format, see page 46 of the old Spectrum         handbook, page 59-60 of the Plus 2 book; or try this demo       program:                                                                 100 LET x=EXP 1: REM the number e, 2.718281828                  200 PRINT 1/x/100, x: LET x = -10*x: GO TO 200                 Another demonstration program is given on page 167 of   "ROM Disassembled".                                                     You will observe that when numbers are shown on screen,        - only 8 significant figures are shown                          - numbers greater than 100,000,000d or less than 0.00001dare shown in E format                                                  - numbers greater than 10**38 or less than 10**-39 cause over- or underflow.                                                     Thus the maximum number of characters required to outputany number is 8 digits + 1 decimal point + 1 minus sign + 4 (eg "E-38"), 14 characters in all.                                          Most of the subroutine deals only with positive values; if the number is negative, a minus sign is printed and the      subroutine continues with the absolute value of the number.             Nine significant digits of the number to be output are  first compiled in the calculator memory's mem-3 and mem-4, the  ten bytes starting at 5CA1h/23713d, and two counters are set up in mem-5; mem-3 to mem-5 are called the_ad_hoc_print_buffer,    nothing to do with the main print buffer, see_printer. The      counters are                                                           - the significant figures counter: the overall number of digits to be output excluding leading or trailing zeroes               - the magnitude counter: a positive number shows the     number of digits before the decimal point, a negative number thenumber of_leading_zeroes, ie zeroes after the decimal point and before the significant figures of the number.                           The magnitude counter is calculated from the logarithm  of X to the base ten, using its integer part only: ie INT log X,or strictly speaking INT ABS log X. If X has N digits before thedecimal point, N must be between 10**(N - 1) and 10**N; for     example 69.7 is between 10**1 = 10 and 10**2 = 100. So log X is between N - 1 and N; log 69.7 is 1.8432328.                             If X has N leading zeroes after the decimal point, N    must be between 10**-(N + 1) and 10**-N; for example 0.00697 is between 10**-3 = 0.001 and 10**-2 = 0.01. Now ABS log X is      between N and N + 1; log 0.00697 is -3 + 0.8432328, so ABS log  0.00697 is 2.1567672.                                                   The log calculations are performed by calls to LOG      (2**A), which works from the binary exponent B of X. For a      number X greater than one, B is positive or zero, and the       logarithm of X to the base 2 is B plus a fraction; then log X tothe base ten is B * log 2 to base 10 = 0.3010d * B plus a       fraction; see under the subroutine LOG(2**A). For X less than   one, B is negative, but the essential calculation is the same.  Actually the routine sometimes works with the normalized versionof B, but the effect is as described here.                              LOG (2**A) gives results which are often one off,       because they take no account of the fractions; the adjustment   required is usually plus one for positive B, minus one for      negative, but this is simplified by using B + 2 for negative B, so the later correction is always in the same direction.                The nine digits are assembled by PF LOOP to PF FR EXX,  rounded to eight by PF ROUND to PF R BACK and output from the   buffer by PF E SBRN and following.                                      If the number is less than one, its representation      should have an_initial_zero before the decimal point; the       routine fails to output this in some cases, see PF NOT E below.         The subroutine can readily be used by m/c programmers;  its length and complexity make this extremely worth while!      However, much simpler and faster routines can be devised for    outputting restricted classes of numbers, eg integers or        positive numbers only; there are some in the ROM. Much of the   complexity is the consequence of the restriction to 14d output  characters.                                                            Input parameters: none                                           - the number X to be output is on the calculator stack.        Action: use the less-0 and greater-0 routines of the     calculator to check the sign of X                                       - if X is negative, jump on to PF NEGTVE                        - if positive to PF POSTVE                                      - (that leaves zero) output 30h "zero" and return.             _2DF2_PF_NEGTVE: use the calculator to replace X by ABS X        - output 2D -.                                                 _2DF8_PF_POSTVE: put zeroes in mem-3, mem-4 and mem-5;   this creates an ad hoc print buffer of 15d bytes in the         calculator memory area                                                  - save HL'; this routine is called by the calculator,   from 361F str$, and using it "recursively" could corrupt the    saved return address in HL'.                                           _2E01_PF_LOOP: use the calculator to split X into an     integer part iX and a fractional part fX                                - if the exponent byte of iX isn't zero jump on to PF   LARGE; iX is more than 10000h/65536d, otherwise 36AF int would  return it in small integer form, with zero exponent byte                - (iX is a small integer) make a bit counter 10h/16d forthe binary digits of iX                                                 - call 2D7F INT FETCH to get iX into DE                         - if its hi byte isn't zero jump on to PF SAVE                  - (hi byte is zero) if both its bytes are zero jump on  to PF SMALL; iX is zero, X is a pure fraction                           - (iX is a one-byte integer) move the lo byte to the hi byte of the register                                                    - reduce the bit counter to 08.                                _2E1E_PF_SAVE: save iX in the alternate registers                - jump on to PF BITS.                                          _2E24_PF_SMALL (iX is zero, ie X is a pure fraction) readthe exponent of fX [an error here: the zero iX ought to have    been cleared from the stack before proceeding. For its          unfortunate effects see under 361F str$]                                - subtract 7Eh/126d; this makes B + 2, two more than thenormalized binary exponent of fX. B is negative, ie a byte 01 ->7F, because X is a pure fraction, so B + 2 is 03 -> 81h                 - call 2DC1 LOG(2**A) which returns the number N of     leading zeroes required after the decimal point                         - subtract N from the twelfth byte of the ad hoc print  buffer, mem-5 byte 2; it was zeroed at the start of the routine,but if this isn't the first turn round from PF LOOP there may bea number in it. This is the magnitude counter, now zero or      negative, indicating zeroes after the decimal point                     - call 2D4F E TO FP to get fX * 10**N from the last     value on the stack fX and N in the A register; this ought to be fX decimal shifted left until it has no leading zeroes, but N   may be one too large. The notes call it y                               - use the calculator to separate y into its integer and fractional parts; the notes call them i2 and f2. If N was too   large i2 won't be zero, but it can only be a single decimal     digit                                                                   - put i2 in the first byte of the print buffer; it will be the first to be output after the leading zeroes, unless it iszero                                                                    - decrement it, shift its hi bit into the carry, then   subtract it from itself with carry and increment it again. This produces zero from zero:                                                     00 -> FF -> FE with carry -> FF -> 00               and one from anything else:                                           X -> (X - 1) -> 2(X - 1) without carry -> 00 -> 01               Doubling X - 1 can't produce carry when X is just a     decimal digit                                                           - put this zero or one in byte 11d of the buffer, the   significant figures counter, and add it to the number in the    magnitude counter, which presumably is negative                         - jump on to PF FRACTN with a pointer to f2, the last   value on the stack.                                                    _2E56_PF_LARGE (X is in full FP format, and so more than 65535d): take 80h/128d from the exponent of iX; now a true      exponent                                                                - if this leaves less than 1Ch/28d jump on to PF MEDIUM         - (iX is more than 2**27 = 134,217,728d, nine or more   decimal digits) call 2DC1 LOG(2**A) to get the number N of      decimal digits; 9 -> 38d                                                - subtract seven; N - 7                                         - add the result to the magnitude counter                       - negate it; now -(N - 7)                                       - call 2D4F E TO FP to get iX/10**(N - 7) on the stack  from iX on the stack and -(N - 7) in A; this is a number,       probably not an integer, of eight or possibly seven decimal     digits                                                                  - jump back to PF LOOP to go round again; the reduced   number will be split again into integer and fractional parts.   The old fractional part gets lost, but it couldn't be output in the 14-character format anyway.