zx81-rom

ZX81 rom source mirror
git clone http://frotz.net/git/zx81-rom.git
Log | Files | Refs

sg81.html (139466B)


      1 <HTML>
      2 <HEAD>
      3 <TITLE>
      4 Assembly Listing of the Shoulders of Giants ZX81 ROM.
      5 </TITLE>
      6 </HEAD>
      7 <BODY>
      8 <font face = "Courier">&nbsp;</font>
      9 <PRE>
     10 ; =========================================================
     11 ; An Assembly Listing of the "Shoulders of Giants" ZX81 ROM
     12 ; =========================================================
     13 ; -------------------------
     14 ; Last updated: 23-OCT-2003
     15 ; -------------------------
     16 ;
     17 ;   The "Shoulders of Giants" ZX81 ROM.
     18 ;   This file shows the altered sections of the ZX81/TS1000 ROM that produced 
     19 ;   the customized sg81.rom.
     20 ;   The main feature is the inclusion of Newton Raphson square roots.
     21 ;   The square roots are executed 3 times faster than those in the 
     22 ;   standard ROM. They are more accurate also and
     23 ;
     24 ;   PRINT SQR 100 = INT SQR 100 gives the result 1 (true) not 0 (false)
     25 ;
     26 ;   The input and storage of fractional numbers is improved
     27 ;
     28 ;   PRINT 1/2 = .5 gives the result 1 (true) and not 0 (false) 
     29 ;
     30 ;   The output of fractional numbers to the ZX Printer is corrected
     31 ;
     32 ;   LPRINT .00001 gives the output .00001 and not .0XYZ1
     33 ;
     34 ;   Other alterations have been made to create the space required by the
     35 ;   new square root routine and some are obscure and would not otherwise have 
     36 ;   been made.
     37 ;   Using uncompressed constants rectifies a logic error and improves speed.
     38 
     39 #define DEFB .BYTE      ; TASM cross-assembler definitions
     40 #define DEFW .WORD
     41 #define EQU  .EQU
     42 #define ORG  .ORG
     43 
     44 
     45 ;   the backward references
     46 					
     47 <a name="subtract"></a><b>subtract</b>   EQU     $174C           ; SUBTRACT
     48 <a name="multiply"></a><b>multiply</b>   EQU     $176C           ; multiply
     49 <a name="division"></a><b>division</b>   EQU     $1882           ; division
     50 <a name="addition"></a><b>addition</b>   EQU     $1755           ; addition
     51 <a name="truncate"></a><b>truncate</b>   EQU     $18E4           ; truncate
     52 <a name="e_to_fp"></a><b>e_to_fp</b>    EQU     $155A           ; e-to-fp
     53 <a name="TEST_ROOM"></a><b>TEST_ROOM</b>  EQU     $0EC5           ; TEST-ROOM
     54 <a name="FIND_INT"></a><b>FIND_INT</b>   EQU     $0EA7           ; FIND-INT
     55 <a name="STACK_A"></a><b>STACK_A</b>    EQU     $151D           ; STACK-A
     56 <a name="STACK_BC"></a><b>STACK_BC</b>   EQU     $1520           ; STACK-BC
     57 <a name="STK_FETCH"></a><b>STK_FETCH</b>  EQU     $13F8           ; STK-FETCH
     58 <a name="STK_STO_s"></a><b>STK_STO_s</b>  EQU     $12C3           ; STK-STO-$
     59 <a name="FP_TO_A"></a><b>FP_TO_A</b>    EQU     $15CD           ; FP-TO-A
     60 <a name="CLASS_06"></a><b>CLASS_06</b>   EQU     $0D92           ; CLASS-06
     61 <a name="CHECK_2"></a><b>CHECK_2</b>    EQU     $0D22           ; CHECK-2
     62 <a name="SCANNING"></a><b>SCANNING</b>   EQU     $0F55           ; SCANNING
     63 <a name="PRINT_FP"></a><b>PRINT_FP</b>   EQU     $15DB           ; PRINT-FP
     64 
     65 ; -----------------------------------------------------------------------------
     66 
     67 <a name="ORG"></a><b>ORG</b> $0010
     68 
     69 ;--------------------------------
     70 ; THE <b><font color=#333388>'PRINT A CHARACTER'</font></b> RESTART
     71 ;--------------------------------
     72 ; This restart prints the character in the accumulator using the alternate
     73 ; register set so there is no requirement to save the main registers.
     74 ; There is sufficient room available to separate a space (zero) from other
     75 ; characters as leading spaces need not be considered with a space.
     76 ; <font color=#9900FF>Note.</font> the accumulator is preserved only when printing to the screen.
     77 
     78 <a name="PRINT_A"></a><b>PRINT_A</b>   AND   A               ; test for zero - space.
     79           JP    NZ,<A href="#PRINT_CH">PRINT_CH</a>     ; jump forward if not to PRINT-CH.
     80 
     81           JP    <A href="#PRINT_SP">PRINT_SP</a>        ; jump forward to PRINT-SP.
     82 
     83 ; ---
     84 
     85  <font color=#3333FF>         DEFB  $01             ;+ unused location. Version. PRINT PEEK 23</font>
     86 
     87 ; -----------------------------------------------------------------------------
     88 
     89 <a name="ORG"></a><b>ORG</b> $0028
     90 
     91 
     92 ; -----------------------  
     93 ; THE <b><font color=#333388>'CALCULATE'</font></b> RESTART
     94 ; -----------------------  
     95 ;   An immediate jump is made to the CALCULATE routine the address of which 
     96 ;   has changed.
     97 
     98 <a name="FP_CALC"></a><b>FP_CALC</b> <font color=#3333FF>  JP    <A href="#CALCULATE">CALCULATE</a>       ;+ jump to the NEW calculate routine address.</font>
     99 
    100 <a name="end_calc"></a><b>end_calc</b>  POP   AF              ; drop the calculator return address RE-ENTRY
    101           EXX                   ; switch to the other set.
    102 
    103           EX    (SP),HL         ; transfer H'L' to machine stack for the
    104                                 ; return address.
    105                                 ; when exiting recursion then the previous
    106                                 ; pointer is transferred to H'L'.
    107 
    108           EXX                   ; back to main set.
    109           RET                   ; return.
    110 
    111 ; -----------------------------------------------------------------------------
    112 
    113 <a name="ORG"></a><b>ORG</b>	$13AE 
    114 
    115 ; ------------------------
    116 ; THE <b><font color=#333388>'L-ENTER'</font></b> SUBROUTINE
    117 ; ------------------------
    118 ;   Part of the LET command contains a natural subroutine which is a 
    119 ;   conditional LDIR. The copy only occurs of BC is non-zero.
    120 
    121 <a name="L_ENTER"></a><b>L_ENTER</b>   EX    DE,HL           ;
    122 
    123 
    124 <a name="COND_MV"></a><b>COND_MV</b>   LD    A,B             ;
    125           OR    C               ;
    126           RET   Z               ;
    127 
    128           PUSH  DE              ;
    129 
    130           LDIR                  ; Copy Bytes
    131 
    132           POP   HL              ;
    133           RET                   ; Return.
    134 
    135 ; -----------------------------------------------------------------------------
    136 
    137 <a name="ORG"></a><b>ORG</b> $14E5
    138 
    139 ; ---------------------
    140 ; THE <b><font color=#333388>'NEXT DIGIT'</font></b> LOOP
    141 ; ---------------------
    142 ;   Within the 'DECIMAL TO FLOATING POINT' routine, swapping the multiply and
    143 ;   divide literals preserves accuracy and ensures that .5 is evaluated 
    144 ;   as 5/10 and not as .1 * 5.
    145 
    146 <a name="NXT_DGT_1"></a><b>NXT_DGT_1</b> RST     20H             ; NEXT-CHAR
    147           CALL    $1514           ; routine STK-DIGIT
    148           JR      C,$14F5         ; forward to E-FORMAT
    149 
    150 
    151           RST     28H             ;; FP-CALC
    152           DEFB    $E0             ;;get-mem-0
    153           DEFB    $A4             ;;stk-ten
    154 <font color=#FF3333>;;;       DEFB    $05             ;;division</font>
    155  <font color=#3333FF>         DEFB    $04             ;;+multiply</font>
    156           DEFB    $C0             ;;st-mem-0
    157 <font color=#FF3333>;;;       DEFB    $04             ;;multiply</font>
    158  <font color=#3333FF>         DEFB    $05             ;;+division</font>
    159           DEFB    $0F             ;;addition
    160           DEFB    $34             ;;end-calc
    161 
    162           JR      NXT_DGT_1       ; loop back till exhausted to NXT-DGT-1
    163 
    164 ; -----------------------------------------------------------------------------
    165 
    166 <a name="ORG"></a><b>ORG</b> $16B2
    167 
    168 ; -------------------------------------
    169 ; THE <b><font color=#333388>'FLOATING POINT PRINT ZEROS'</font></b> LOOP
    170 ; -------------------------------------
    171 
    172 ; This branch deals with zeros after decimal point.
    173 ; e.g.      .01 or .0000999
    174 ; <font color=#9900FF>Note.</font> that printing to the ZX Printer destroys A and that A should be 
    175 ; initialized to '0' at each stage of the loop.
    176 ; Originally LPRINT .00001 printed as .0XYZ1
    177 
    178 <a name="PF_ZEROS"></a><b>PF_ZEROS</b>  NEG                   ; negate makes number positive 1 to 4.
    179           LD    B,A             ; zero count to B.
    180 
    181           LD    A,$1B           ; prepare character '.'
    182           RST   10H             ; PRINT-A
    183 
    184 <a name="PF_ZRO_LP"></a><b>PF_ZRO_LP</b> LD    A,$1C           ; prepare a '0' in the accumulator each time.
    185 
    186 <a name="PFZROLP"></a><b>PFZROLP</b>   RST   10H             ; PRINT-A
    187 
    188  <font color=#3333FF>         DJNZ  <A href="#PF_ZRO_LP">PF_ZRO_LP</a>       ;+ New loop back to PF-ZRO-LP</font>
    189 
    190 <font color=#FF3333>;;;       DJNZ  <A href="#PFZROLP">PFZROLP</a>         ; obsolete loop back to PFZROLP</font>
    191 
    192 
    193 ;   and continue with trailing fractional digits...
    194 
    195 ; -----------------------------------------------------------------------------
    196 
    197 <a name="ORG"></a><b>ORG</b>     $1915
    198 
    199 
    200 ;   Up to this point all routine addresses have been maintained so that the
    201 ;   modified ROM is compatible with any machine-code software that uses ROM
    202 ;   routines.
    203 ;   The final section does not maintain address entry points as the routines
    204 ;   within are not generally called directly.
    205 
    206 ;********************************
    207 ;**  FLOATING-POINT CALCULATOR **
    208 ;********************************
    209 
    210 ;   As a general rule the calculator avoids using the IY register.
    211 ;   The exception is the 'val' function.
    212 ;   So an assembly language programmer who has disabled interrupts to use IY
    213 ;   for other purposes can still use the calculator for mathematical
    214 ;   purposes.
    215 
    216 
    217 ; ------------------------
    218 ; THE <b><font color=#333388>'TABLE OF CONSTANTS'</font></b>
    219 ; ------------------------
    220 ;   The ZX81 has only floating-point number representation.
    221 ;   Both the ZX80 and the ZX Spectrum have integer numbers in some form.
    222 ;   This table has been modified so that the constants are held in their
    223 ;   uncompressed, ready-to-party, 5-byte form.
    224 
    225 <font color=#FF3333>;;; L1915:  DEFB    $00             ;;Bytes: 1</font>
    226 <font color=#FF3333>;;;         DEFB    $B0             ;;Exponent $00</font>
    227 <font color=#FF3333>;;;         DEFB    $00             ;;(+00,+00,+00)</font>
    228 <font color=#FF3333>;;; L1918:  DEFB    $31             ;;Exponent $81, Bytes: 1</font>
    229 <font color=#FF3333>;;;         DEFB    $00             ;;(+00,+00,+00)</font>
    230 <font color=#FF3333>;;; L191A:  DEFB    $30             ;;Exponent: $80, Bytes: 1</font>
    231 <font color=#FF3333>;;;         DEFB    $00             ;;(+00,+00,+00)</font>
    232 <font color=#FF3333>;;; L191C:  DEFB    $F1             ;;Exponent: $81, Bytes: 4</font>
    233 <font color=#FF3333>;;;         DEFB    $49,$0F,$DA,$A2 ;;</font>
    234 <font color=#FF3333>;;; L1921:  DEFB    $34             ;;Exponent: $84, Bytes: 1</font>
    235 <font color=#FF3333>;;;         DEFB    $20             ;;(+00,+00,+00)</font>
    236 
    237 <a name="TAB_CNST"></a><b>TAB_CNST</b>  DEFB  $00           ; the value zero.
    238           DEFB  $00           ;
    239           DEFB  $00           ;
    240           DEFB  $00           ;
    241           DEFB  $00           ;
    242 
    243           DEFB  $81           ; the floating point value 1.
    244           DEFB  $00           ;
    245           DEFB  $00           ;
    246           DEFB  $00           ;
    247           DEFB  $00           ;
    248 
    249           DEFB  $80           ; the floating point value 1/2.
    250           DEFB  $00           ;
    251           DEFB  $00           ;
    252           DEFB  $00           ;
    253           DEFB  $00           ;
    254 
    255           DEFB  $81           ; the floating point value pi/2.
    256           DEFB  $49           ;
    257           DEFB  $0F           ;
    258           DEFB  $DA           ;
    259           DEFB  $A2           ;
    260 
    261           DEFB  $84           ; the floating point value ten.
    262           DEFB  $20           ;
    263           DEFB  $00           ;
    264           DEFB  $00           ;
    265           DEFB  $00           ;
    266 
    267 ; ------------------------
    268 ; THE <b><font color=#333388>'TABLE OF ADDRESSES'</font></b>
    269 ; ------------------------
    270 ;
    271 ;   Starts with binary operations which have two operands and one result.
    272 ;   three pseudo binary operations first.
    273 
    274 <a name="tbl_addrs"></a><b>tbl_addrs</b> DEFW  jump_true       ; $00 Address: $1C2F - jump-true
    275           DEFW  exchange        ; $01 Address: $1A72 - exchange
    276           DEFW  delete          ; $02 Address: $19E3 - delete
    277 
    278 ;   true binary operations.
    279 
    280           DEFW  subtract        ; $03 Address: $174C - subtract
    281           DEFW  multiply        ; $04 Address: $176C - multiply
    282           DEFW  division        ; $05 Address: $1882 - division
    283           DEFW  to_power        ; $06 Address: $1DE2 - to-power
    284           DEFW  or              ; $07 Address: $1AED - or
    285 
    286           DEFW  no_v_no         ; $08 Address: $1B03 - no-&amp;-no
    287           DEFW  no_l_eql        ; $09 Address: $1B03 - no-l-eql
    288           DEFW  no_l_eql        ; $0A Address: $1B03 - no-gr-eql
    289           DEFW  no_l_eql        ; $0B Address: $1B03 - nos-neql
    290           DEFW  no_l_eql        ; $0C Address: $1B03 - no-grtr
    291           DEFW  no_l_eql        ; $0D Address: $1B03 - no-less
    292           DEFW  no_l_eql        ; $0E Address: $1B03 - nos-eql
    293           DEFW  addition        ; $0F Address: $1755 - addition
    294 
    295           DEFW  str_v_no        ; $10 Address: $1AF8 - str-&amp;-no
    296           DEFW  no_l_eql        ; $11 Address: $1B03 - str-l-eql
    297           DEFW  no_l_eql        ; $12 Address: $1B03 - str-gr-eql
    298           DEFW  no_l_eql        ; $13 Address: $1B03 - strs-neql
    299           DEFW  no_l_eql        ; $14 Address: $1B03 - str-grtr
    300           DEFW  no_l_eql        ; $15 Address: $1B03 - str-less
    301           DEFW  no_l_eql        ; $16 Address: $1B03 - strs-eql
    302           DEFW  strs_add        ; $17 Address: $1B62 - strs-add
    303 
    304 ;   unary follow
    305 
    306           DEFW  negate          ; $18 Address: $1AA0 - neg
    307 
    308           DEFW  code            ; $19 Address: $1C06 - code
    309           DEFW  val             ; $1A Address: $1BA4 - val
    310           DEFW  len             ; $1B Address: $1C11 - len
    311           DEFW  sin             ; $1C Address: $1D49 - sin
    312           DEFW  cos             ; $1D Address: $1D3E - cos
    313           DEFW  tan             ; $1E Address: $1D6E - tan
    314           DEFW  asn             ; $1F Address: $1DC4 - asn
    315           DEFW  acs             ; $20 Address: $1DD4 - acs
    316           DEFW  atn             ; $21 Address: $1D76 - atn
    317           DEFW  ln              ; $22 Address: $1CA9 - ln
    318           DEFW  exp             ; $23 Address: $1C5B - exp
    319           DEFW  int             ; $24 Address: $1C46 - int
    320           DEFW  sqr             ; $25 Address: $1DDB - sqr
    321           DEFW  sgn             ; $26 Address: $1AAF - sgn
    322           DEFW  abs             ; $27 Address: $1AAA - abs
    323           DEFW  peek            ; $28 Address: $1A1B - peek
    324           DEFW  usr_no          ; $29 Address: $1AC5 - usr-no
    325           DEFW  strS            ; $2A Address: $1BD5 - str$
    326           DEFW  chrS            ; $2B Address: $1B8F - chrs
    327           DEFW  not             ; $2C Address: $1AD5 - not
    328 
    329 ;   end of true unary
    330 
    331           DEFW  MOVE_FP         ; $2D Address: $19F6 - duplicate
    332           DEFW  n_mod_m         ; $2E Address: $1C37 - n-mod-m
    333 
    334           DEFW  JUMP            ; $2F Address: $1C23 - jump
    335           DEFW  stk_data        ; $30 Address: $19FC - stk-data
    336 
    337           DEFW  dec_jr_nz       ; $31 Address: $1C17 - dec-jr-nz
    338           DEFW  less_0          ; $32 Address: $1ADB - less-0
    339           DEFW  greater_0       ; $33 Address: $1ACE - greater-0
    340           DEFW  end_calc        ; $34 Address: $002B - end-calc
    341           DEFW  get_argt        ; $35 Address: $1D18 - get-argt
    342           DEFW  truncate        ; $36 Address: $18E4 - truncate
    343           DEFW  fp_calc_2       ; $37 Address: $19E4 - fp-calc-2
    344           DEFW  e_to_fp         ; $38 Address: $155A - e-to-fp
    345 
    346 ;   the following are just the next available slots for the 128 compound 
    347 ;   literals which are in range $80 - $FF.
    348 
    349           DEFW  seriesg_x       ; $39 Address: $1A7F - series-xx    $80 - $9F.
    350           DEFW  stk_con_x       ; $3A Address: $1A51 - stk-const-xx $A0 - $BF.
    351           DEFW  sto_mem_x       ; $3B Address: $1A63 - st-mem-xx    $C0 - $DF.
    352           DEFW  get_mem_x       ; $3C Address: $1A45 - get-mem-xx   $E0 - $FF.
    353 
    354 ; -------------------------------
    355 ; THE <b><font color=#333388>'FLOATING POINT CALCULATOR'</font></b>
    356 ; -------------------------------
    357 ;
    358 ;
    359 
    360 <a name="CALCULATE"></a><b>CALCULATE</b> CALL  <A href="#STK_PNTRS">STK_PNTRS</a>       ; routine STK-PNTRS is called to set up the
    361                                 ; calculator stack pointers for a default
    362                                 ; unary operation. HL = last value on stack.
    363                                 ; DE = STKEND first location after stack.
    364 
    365 ;   the calculate routine is called at this point by the series generator...
    366 
    367 <a name="GEN_ENT_1"></a><b>GEN_ENT_1</b> LD    A,B             ; fetch the Z80 B register to A
    368           LD    ($401E),A       ; and store value in system variable BREG.
    369                                 ; this will be the counter for dec-jr-nz
    370                                 ; or if used from fp-calc2 the calculator
    371                                 ; instruction.
    372 
    373 ;   ... and again later at this point
    374 
    375 <a name="GEN_ENT_2"></a><b>GEN_ENT_2</b> EXX                   ; switch sets
    376           EX    (SP),HL         ; and store the address of next instruction,
    377                                 ; the return address, in H'L'.
    378                                 ; If this is a recursive call then the H'L'
    379                                 ; of the previous invocation goes on stack.
    380                                 ; c.f. end-calc.
    381           EXX                   ; switch back to main set.
    382 
    383 ;   this is the re-entry looping point when handling a string of literals.
    384 
    385 <a name="RE_ENTRY"></a><b>RE_ENTRY</b>  LD    ($401C),DE      ; save end of stack in system variable STKEND
    386           EXX                   ; switch to alt
    387           LD    A,(HL)          ; get next literal
    388           INC   HL              ; increase pointer'
    389 
    390 ;   single operation jumps back to here
    391 
    392 <a name="SCAN_ENT"></a><b>SCAN_ENT</b>  PUSH  HL              ; save pointer on stack   *
    393           AND   A               ; now test the literal
    394           JP    P,<A href="#FIRST_3D">FIRST_3D</a>      ; forward to FIRST-3D if in range $00 - $3D
    395                                 ; anything with bit 7 set will be one of
    396                                 ; 128 compound literals.
    397 
    398 ;   Compound literals have the following format.
    399 ;   bit 7 set indicates compound.
    400 ;   bits 6-5 the subgroup 0-3.
    401 ;   bits 4-0 the embedded parameter $00 - $1F.
    402 ;   The subgroup 0-3 needs to be manipulated to form the next available four
    403 ;   address places after the simple literals in the address table.
    404 
    405           LD    D,A             ; save literal in D
    406           AND   $60             ; and with 01100000 to isolate subgroup
    407           RRCA                  ; rotate bits
    408           RRCA                  ; 4 places to right
    409           RRCA                  ; not five as we need offset * 2
    410           RRCA                  ; 00000xx0
    411           ADD   A,$72           ; add ($39 * 2) to give correct offset.
    412                                 ; alter above if you add more literals.
    413           LD    L,A             ; store in L for later indexing.
    414           LD    A,D             ; bring back compound literal
    415           AND   $1F             ; use mask to isolate parameter bits
    416           JR    <A href="#ENT_TABLE">ENT_TABLE</a>       ; forward to ENT-TABLE
    417 
    418 ; ---
    419 
    420 ;   the branch was here with simple literals.
    421 
    422 <a name="FIRST_3D"></a><b>FIRST_3D</b>  CP    $18             ; compare with first unary operations.
    423           JR    NC,<A href="#DOUBLE_A">DOUBLE_A</a>     ; to DOUBLE-A with unary operations
    424 
    425 ;   it is binary so adjust pointers.
    426 
    427           EXX                   ;
    428           LD    BC,$FFFB        ; the value -5
    429           LD    D,H             ; transfer HL, the last value, to DE.
    430           LD    E,L             ;
    431           ADD   HL,BC           ; subtract 5 making HL point to second
    432                                 ; value.
    433           EXX                   ;
    434 
    435 <a name="DOUBLE_A"></a><b>DOUBLE_A</b>  RLCA                  ; double the literal
    436           LD    L,A             ; and store in L for indexing
    437 
    438 <a name="ENT_TABLE"></a><b>ENT_TABLE</b> LD    DE,tbl_addrs    ; Address: tbl-addrs
    439           LD    H,$00           ; prepare to index
    440           ADD   HL,DE           ; add to get address of routine
    441           LD    E,(HL)          ; low byte to E
    442           INC   HL              ;
    443           LD    D,(HL)          ; high byte to D
    444 
    445           LD    HL,RE_ENTRY     ; Address: RE-ENTRY
    446           EX    (SP),HL         ; goes on machine stack
    447                                 ; address of next literal goes to HL. *
    448 
    449 
    450           PUSH  DE              ; now the address of routine is stacked.
    451           EXX                   ; back to main set
    452                                 ; avoid using IY register.
    453           LD    BC,($401D)      ; STKEND_hi
    454                                 ; nothing much goes to C but BREG to B
    455                                 ; and continue into next ret instruction
    456                                 ; which has a dual identity
    457 
    458 
    459 ; -----------------------
    460 ; THE <b><font color=#333388>'DELETE'</font></b> SUBROUTINE
    461 ; -----------------------
    462 ; <font color=#339933>(offset $02: 'delete')</font>
    463 ;   A simple return but when used as a calculator literal this
    464 ;   deletes the last value from the calculator stack.
    465 ;   On entry, as always with binary operations,
    466 ;   HL=first number, DE=second number
    467 ;   On exit, HL=result, DE=stkend.
    468 ;   So nothing to do
    469 
    470 <a name="delete"></a><b>delete</b>    RET                   ; return - indirect jump if from above.
    471 
    472 ; ---------------------------------
    473 ; THE <b><font color=#333388>'SINGLE OPERATION'</font></b> SUBROUTINE
    474 ; ---------------------------------
    475 ;   offset $37: 'fp-calc-2'
    476 ;   this single operation is used, in the first instance, to evaluate most
    477 ;   of the mathematical and string functions found in BASIC expressions.
    478 
    479 <a name="fp_calc_2"></a><b>fp_calc_2</b> POP   AF              ; drop return address.
    480           LD    A,($401E)       ; load accumulator from system variable BREG
    481                                 ; value will be literal eg. 'tan'
    482           EXX                   ; switch to alt
    483           JR    <A href="#SCAN_ENT">SCAN_ENT</a>        ; back to SCAN-ENT
    484                                 ; next literal will be end-calc in scanning
    485 
    486 ; ------------------------------
    487 ; THE <b><font color=#333388>'TEST 5 SPACES'</font></b> SUBROUTINE
    488 ; ------------------------------
    489 ;   This routine is called from MOVE-FP, STK-CONST and STK-STORE to
    490 ;   test that there is enough space between the calculator stack and the
    491 ;   machine stack for another five-byte value. It returns with BC holding
    492 ;   the value 5 ready for any subsequent LDIR.
    493 
    494 <a name="TEST_5_SP"></a><b>TEST_5_SP</b> PUSH  DE              ; save
    495           PUSH  HL              ; registers
    496           LD    BC,$0005        ; an overhead of five bytes
    497           CALL  <A href="#TEST_ROOM">TEST_ROOM</a>       ; routine TEST-ROOM tests free RAM raising
    498                                 ; an error if not.
    499           POP   HL              ; else restore
    500           POP   DE              ; registers.
    501           RET                   ; return with BC set at 5.
    502 
    503 
    504 ; ---------------------------------------------
    505 ; THE <b><font color=#333388>'MOVE A FLOATING POINT NUMBER'</font></b> SUBROUTINE
    506 ; ---------------------------------------------
    507 ; offset $2D: 'duplicate'
    508 ;   This simple routine is a 5-byte LDIR instruction
    509 ;   that incorporates a memory check.
    510 ;   When used as a calculator literal it duplicates the last value on the
    511 ;   calculator stack.
    512 ;   Unary so on entry HL points to last value, DE to stkend
    513 
    514 <a name="MOVE_FP"></a><b>MOVE_FP</b>   CALL  <A href="#TEST_5_SP">TEST_5_SP</a>       ; routine TEST-5-SP test free memory
    515                                 ; and sets BC to 5.
    516 
    517           LDIR                  ; copy the five bytes.
    518           RET                   ; return with DE addressing new STKEND
    519                                 ; and HL addressing new last value.
    520 
    521 ; -------------------------------
    522 ; THE <b><font color=#333388>'STACK LITERALS'</font></b> SUBROUTINE
    523 ; -------------------------------
    524 ; offset $30: 'stk-data'
    525 ;   When a calculator subroutine needs to put a value on the calculator
    526 ;   stack that is not a regular constant this routine is called with a
    527 ;   variable number of following data bytes that convey to the routine
    528 ;   the floating point form as succinctly as is possible.
    529 
    530 <a name="stk_data"></a><b>stk_data</b>  LD    H,D             ; transfer STKEND
    531           LD    L,E             ; to HL for result.
    532 
    533 <a name="STK_CONST"></a><b>STK_CONST</b> CALL  <A href="#TEST_5_SP">TEST_5_SP</a>       ; routine TEST-5-SP tests that room exists
    534                                 ; and sets BC to $05.
    535 
    536           EXX                   ; switch to alternate set
    537           PUSH  HL              ; save the pointer to next literal on stack
    538           EXX                   ; switch back to main set
    539 
    540           EX    (SP),HL         ; pointer to HL, destination to stack.
    541 
    542 <font color=#FF3333>;;;       PUSH  BC              ; save BC - value 5 from test room. No need.</font>
    543 
    544           LD    A,(HL)          ; fetch the byte following 'stk-data'
    545           AND   $C0             ; isolate bits 7 and 6
    546           RLCA                  ; rotate
    547           RLCA                  ; to bits 1 and 0  range $00 - $03.
    548           LD    C,A             ; transfer to C
    549           INC   C               ; and increment to give number of bytes
    550                                 ; to read. $01 - $04
    551           LD    A,(HL)          ; reload the first byte
    552           AND   $3F             ; mask off to give possible exponent.
    553           JR    NZ,<A href="#FORM_EXP">FORM_EXP</a>     ; forward to FORM-EXP if it was possible to
    554                                 ; include the exponent.
    555 
    556 ; else byte is just a byte count and exponent comes next.
    557 
    558           INC   HL              ; address next byte and
    559           LD    A,(HL)          ; pick up the exponent ( - $50).
    560 
    561 <a name="FORM_EXP"></a><b>FORM_EXP</b>  ADD   A,$50           ; now add $50 to form actual exponent
    562           LD    (DE),A          ; and load into first destination byte.
    563           LD    A,$05           ; load accumulator with $05 and
    564           SUB   C               ; subtract C to give count of trailing
    565                                 ; zeros plus one.
    566           INC   HL              ; increment source
    567           INC   DE              ; increment destination
    568 <font color=#FF3333>;;;       LD    B,$00           ; prepare to copy. <font color=#9900FF>Note.</font> B is zero.</font>
    569           LDIR                  ; copy C bytes
    570 
    571 <font color=#FF3333>;;;       POP   BC              ; restore 5 counter to BC.</font>
    572 
    573           EX    (SP),HL         ; put HL on stack as next literal pointer
    574                                 ; and the stack value - result pointer -
    575                                 ; to HL.
    576 
    577           EXX                   ; switch to alternate set.
    578           POP   HL              ; restore next literal pointer from stack
    579                                 ; to H'L'.
    580           EXX                   ; switch back to main set.
    581 
    582           LD    B,A             ; zero count to B
    583           XOR   A               ; clear accumulator
    584 
    585 <a name="STK_ZEROS"></a><b>STK_ZEROS</b> DEC   B               ; decrement B counter
    586           RET   Z               ; return if zero.          &gt;&gt;
    587                                 ; DE points to new STKEND
    588                                 ; HL to new number.
    589 
    590           LD    (DE),A          ; else load zero to destination
    591           INC   DE              ; increase destination
    592           JR    <A href="#STK_ZEROS">STK_ZEROS</a>       ; loop back to STK-ZEROS until done.
    593 
    594 ; -------------------------------
    595 ; THE <b><font color=#333388>'SKIP CONSTANTS'</font></b> SUBROUTINE
    596 ; -------------------------------
    597 ; This routine traversed variable-length entries in the table of constants,
    598 ; stacking intermediate, unwanted constants onto a dummy calculator stack,
    599 ; in the first five bytes of the ZX81 ROM.
    600 ; Since the table now uses uncompressed values, some extra ROM space is 
    601 ; required for the table but much more is released by getting rid of routines
    602 ; like this.
    603 
    604 <font color=#FF3333>;;; L1A2D:  AND     A               ; test if initially zero.</font>
    605 <font color=#FF3333>;;; L1A2E:  RET     Z               ; return if zero.          &gt;&gt;</font>
    606 <font color=#FF3333>;;;         PUSH    AF              ; save count.</font>
    607 <font color=#FF3333>;;;         PUSH    DE              ; and normal STKEND</font>
    608 <font color=#FF3333>;;;         LD      DE,$0000        ; dummy value for STKEND at start of ROM</font>
    609 <font color=#FF3333>;;;         CALL    STK_CONST       ; routine STK-CONST works through variable</font>
    610 <font color=#FF3333>;;;                                 ; length records.</font>
    611 <font color=#FF3333>;;;         POP     DE              ; restore real STKEND</font>
    612 <font color=#FF3333>;;;         POP     AF              ; restore count</font>
    613 <font color=#FF3333>;;;         DEC     A               ; decrease</font>
    614 <font color=#FF3333>;;;         JR      L1A2E           ; loop back to SKIP-NEXT</font>
    615 
    616 ; --------------------------------
    617 ; THE <b><font color=#333388>'MEMORY LOCATION'</font></b> SUBROUTINE
    618 ; --------------------------------
    619 ; This routine, when supplied with a base address in HL and an index in A,
    620 ; will calculate the address of the A'th entry, where each entry occupies
    621 ; five bytes. It is used for addressing floating-point numbers in the
    622 ; calculator's memory area.
    623 
    624 <a name="LOC_MEM"></a><b>LOC_MEM</b>   LD    C,A             ; store the original number $00-$1F.
    625           RLCA                  ; double.
    626           RLCA                  ; quadruple.
    627           ADD   A,C             ; now add original value to multiply by five.
    628 
    629           LD    C,A             ; place the result in C.
    630           LD    B,$00           ; set B to 0.
    631           ADD   HL,BC           ; add to form address of start of number in HL.
    632 
    633           RET                   ; return.
    634 
    635 ; -------------------------------------
    636 ; THE <b><font color=#333388>'GET FROM MEMORY AREA'</font></b> SUBROUTINE
    637 ; -------------------------------------
    638 ; offsets $E0 to $FF: 'get-mem-0', 'get-mem-1' etc.
    639 ; A holds $00-$1F offset.
    640 ; The calculator stack increases by 5 bytes.
    641 ; <font color=#9900FF>Note.</font> first two instructions have been swapped to create a subroutine.
    642 
    643 <a name="get_mem_x"></a><b>get_mem_x</b> LD    HL,($401F)      ; MEM is base address of the memory cells.
    644 
    645 <a name="INDEX_5"></a><b>INDEX_5</b>   PUSH  DE              ; save STKEND
    646 
    647           CALL  <A href="#LOC_MEM">LOC_MEM</a>         ; routine LOC-MEM so that HL = first byte
    648           CALL  <A href="#MOVE_FP">MOVE_FP</a>         ; routine MOVE-FP moves 5 bytes with memory
    649                                 ; check.
    650                                 ; DE now points to new STKEND.
    651           POP   HL              ; the original STKEND is now RESULT pointer.
    652           RET                   ; return.
    653 
    654 ; ---------------------------------
    655 ; THE <b><font color=#333388>'STACK A CONSTANT'</font></b> SUBROUTINE
    656 ; ---------------------------------
    657 ; <font color=#339933>(offset $A0: 'stk-zero')</font>
    658 ; <font color=#339933>(offset $A1: 'stk-one')</font>
    659 ; <font color=#339933>(offset $A2: 'stk-half')</font>
    660 ; <font color=#339933>(offset $A3: 'stk-pi/2')</font>
    661 ; <font color=#339933>(offset $A4: 'stk-ten')</font>
    662 ; This routine allows a one-byte instruction to stack up to 32 constants
    663 ; held in short form in a table of constants. In fact only 5 constants are
    664 ; required. On entry the A register holds the literal ANDed with $1F.
    665 ;
    666 ; It wasn't very efficient and it is better to hold the
    667 ; numbers in full, five byte form and stack them in a similar manner
    668 ; to that which which is used by the above routine.
    669 
    670 <a name="stk_con_x"></a><b>stk_con_x</b> LD    HL,TAB_CNST     ; Address: Table of constants.
    671 
    672           JR    <A href="#INDEX_5">INDEX_5</a>         ; and join subsroutine above.
    673 
    674 ; ---
    675 
    676 <font color=#FF3333>;;;     LD      H,D             ; save STKEND - required for result</font>
    677 <font color=#FF3333>;;;     LD      L,E             ;</font>
    678 <font color=#FF3333>;;;     EXX                     ; swap</font>
    679 <font color=#FF3333>;;;     PUSH    HL              ; save pointer to next literal</font>
    680 <font color=#FF3333>;;;     LD      HL,L1515        ; Address: stk-zero - start of table of</font>
    681 <font color=#FF3333>;;;                             ; constants</font>
    682 <font color=#FF3333>;;;     EXX                     ;</font>
    683 <font color=#FF3333>;;;     CALL    SKIP_CONS       ; routine SKIP-CONS</font>
    684 <font color=#FF3333>;;;     CALL    STK_CONST       ; routine STK-CONST</font>
    685 <font color=#FF3333>;;;     EXX                     ;</font>
    686 <font color=#FF3333>;;;     POP     HL              ; restore pointer to next literal.</font>
    687 <font color=#FF3333>;;;     EXX                     ;</font>
    688 <font color=#FF3333>;;;     RET                     ; return.</font>
    689 
    690 ; ---------------------------------------
    691 ; THE <b><font color=#333388>'STORE IN A MEMORY AREA'</font></b> SUBROUTINE
    692 ; ---------------------------------------
    693 ; Offsets $C0 to $DF: 'st-mem-0', 'st-mem-1' etc.
    694 ; Although 32 memory storage locations can be addressed, only six
    695 ; $C0 to $C5 are required by the ROM and only the thirty bytes (6*5)
    696 ; required for these are allocated. ZX81 programmers who wish to
    697 ; use the floating point routines from assembly language may wish to
    698 ; alter the system variable MEM to point to 160 bytes of RAM to have
    699 ; use the full range available.
    700 ; A holds derived offset $00-$1F.
    701 ; Unary so on entry HL points to last value, DE to STKEND.
    702 
    703 <a name="sto_mem_x"></a><b>sto_mem_x</b> PUSH  HL              ; save the result pointer.
    704           EX    DE,HL           ; transfer to DE.
    705           LD    HL,($401F)      ; fetch MEM the base of memory area.
    706           CALL  <A href="#LOC_MEM">LOC_MEM</a>         ; routine LOC-MEM sets HL to the destination.
    707           EX    DE,HL           ; swap - HL is start, DE is destination.
    708 
    709 <font color=#FF3333>;;;       CALL  <A href="#MOVE_FP">MOVE_FP</a>         ; routine MOVE-FP.</font>
    710 <font color=#FF3333>;;;                             ; <font color=#9900FF>Note.</font> a short ld bc,5; ldir</font>
    711 <font color=#FF3333>;;;                             ; the embedded memory check is not required</font>
    712 <font color=#FF3333>;;;                             ; so these instructions would be faster!</font>
    713 
    714  <font color=#3333FF>         LD    C,$05           ;+ one extra byte but </font>
    715  <font color=#3333FF>         LDIR                  ;+ faster and no memory check.</font>
    716 
    717           EX    DE,HL           ; DE = STKEND
    718           POP   HL              ; restore original result pointer
    719           RET                   ; return.
    720 
    721 ; -------------------------
    722 ; THE <b><font color=#333388>'EXCHANGE'</font></b> SUBROUTINE
    723 ; -------------------------
    724 ; offset $01: 'exchange'
    725 ; This routine exchanges the last two values on the calculator stack
    726 ; On entry, as always with binary operations,
    727 ; HL=first number, DE=second number
    728 ; On exit, HL=result, DE=stkend.
    729 
    730 <a name="exchange"></a><b>exchange</b>  LD    B,$05           ; there are five bytes to be swapped
    731 
    732 ; start of loop.
    733 
    734 <a name="SWAP_BYTE"></a><b>SWAP_BYTE</b> LD    A,(DE)          ; each byte of second
    735 <font color=#FF3333>;;;       LD    C,(HL)          ; each byte of first</font>
    736 <font color=#FF3333>;;;       EX    DE,HL           ; swap pointers</font>
    737  <font color=#3333FF>         ld    c,a             ;+</font>
    738  <font color=#3333FF>         ld    a,(hl)          ;+</font>
    739           LD    (DE),A          ; store each byte of first
    740           LD    (HL),C          ; store each byte of second
    741           INC   HL              ; advance both
    742           INC   DE              ; pointers.
    743           DJNZ  <A href="#SWAP_BYTE">SWAP_BYTE</a>       ; loop back to SWAP-BYTE until all 5 done.
    744 
    745 <font color=#FF3333>;;;       EX    DE,HL           ; even up the exchanges (one byte saved)</font>
    746 
    747           RET                   ; return.
    748 
    749 ; ---------------------------------
    750 ; THE <b><font color=#333388>'SERIES GENERATOR'</font></b> SUBROUTINE
    751 ; ---------------------------------
    752 ; offset $86: 'series-06'
    753 ; offset $88: 'series-08'
    754 ; offset $8C: 'series-0C'
    755 ; The ZX81 uses Chebyshev polynomials to generate approximations for
    756 ; SIN, ATN, LN and EXP. These are named after the Russian mathematician
    757 ; Pafnuty Chebyshev, born in 1821, who did much pioneering work on numerical
    758 ; series. As far as calculators are concerned, Chebyshev polynomials have an
    759 ; advantage over other series, for example the Taylor series, as they can
    760 ; reach an approximation in just six iterations for SIN, eight for EXP and
    761 ; twelve for LN and ATN. The mechanics of the routine are interesting but
    762 ; for full treatment of how these are generated with demonstrations in
    763 ; Sinclair BASIC see "The Complete Spectrum ROM Disassembly" by Dr Ian Logan
    764 ; and Dr Frank O'Hara, published 1983 by Melbourne House.
    765 
    766 <a name="seriesg_x"></a><b>seriesg_x</b> LD    B,A             ; parameter $00 - $1F to B counter
    767           CALL  <A href="#GEN_ENT_1">GEN_ENT_1</a>       ; routine GEN-ENT-1 is called.
    768                                 ; A recursive call to a special entry point
    769                                 ; in the calculator that puts the B register
    770                                 ; in the system variable BREG. The return
    771                                 ; address is the next location and where
    772                                 ; the calculator will expect its first
    773                                 ; instruction - now pointed to by HL'.
    774                                 ; The previous pointer to the series of
    775                                 ; five-byte numbers goes on the machine stack.
    776 
    777 ; The initialization phase.
    778 
    779           DEFB  $2D             ;;duplicate       x,x
    780           DEFB  $0F             ;;addition        x+x
    781           DEFB  $C0             ;;st-mem-0        x+x
    782           DEFB  $02             ;;delete          .
    783           DEFB  $A0             ;;stk-zero        0
    784           DEFB  $C2             ;;st-mem-2        0
    785 
    786 ; a loop is now entered to perform the algebraic calculation for each of
    787 ; the numbers in the series
    788 
    789 <a name="G_LOOP"></a><b>G_LOOP</b>    DEFB  $2D             ;;duplicate       v,v.
    790           DEFB  $E0             ;;get-mem-0       v,v,x+2
    791           DEFB  $04             ;;multiply        v,v*x+2
    792           DEFB  $E2             ;;get-mem-2       v,v*x+2,v
    793           DEFB  $C1             ;;st-mem-1
    794           DEFB  $03             ;;subtract
    795           DEFB  $34             ;;end-calc
    796 
    797 ; the previous pointer is fetched from the machine stack to H'L' where it
    798 ; addresses one of the numbers of the series following the series literal.
    799 
    800           CALL  stk_data        ; routine STK-DATA is called directly to
    801                                 ; push a value and advance H'L'.
    802           CALL  <A href="#GEN_ENT_2">GEN_ENT_2</a>       ; routine GEN-ENT-2 recursively re-enters
    803                                 ; the calculator without disturbing
    804                                 ; system variable BREG
    805                                 ; H'L' value goes on the machine stack and is
    806                                 ; then loaded as usual with the next address.
    807 
    808           DEFB  $0F             ;;addition
    809           DEFB  $01             ;;exchange
    810           DEFB  $C2             ;;st-mem-2
    811           DEFB  $02             ;;delete
    812 
    813           DEFB  $31             ;;dec-jr-nz
    814           DEFB  G_LOOP - $      ;;back to L1A89, G-LOOP
    815 
    816 ; when the counted loop is complete the final subtraction yields the result
    817 ; for example SIN X.
    818 
    819           DEFB  $E1             ;;get-mem-1
    820           DEFB  $03             ;;subtract
    821           DEFB  $34             ;;end-calc
    822 
    823           RET                   ; return with H'L' pointing to location
    824                                 ; after last number in series.
    825 
    826 ; -----------------------
    827 ; Handle unary minus (18)
    828 ; -----------------------
    829 ; Unary so on entry HL points to last value, DE to STKEND.
    830 
    831 <a name="negate"></a><b>negate</b>    LD    A,(HL)          ; fetch exponent of last value on the
    832                                 ; calculator stack.
    833           AND   A               ; test it.
    834           RET   Z               ; return if zero.
    835 
    836           INC   HL              ; address the byte with the sign bit.
    837           LD    A,(HL)          ; fetch to accumulator.
    838           XOR   $80             ; toggle the sign bit.
    839           LD    (HL),A          ; put it back.
    840           DEC   HL              ; point to last value again.
    841           RET                   ; return.
    842 
    843 ; -----------------------
    844 ; Absolute magnitude (27)
    845 ; -----------------------
    846 ; This calculator literal finds the absolute value of the last value,
    847 ; floating point, on calculator stack.
    848 
    849 <a name="abs"></a><b>abs</b>       INC   HL              ; point to byte with sign bit.
    850           RES   7,(HL)          ; make the sign positive.
    851           DEC   HL              ; point to last value again.
    852           RET                   ; return.
    853 
    854 ; -----------
    855 ; Signum (26)
    856 ; -----------
    857 ; This routine replaces the last value on the calculator stack,
    858 ; (which is in floating point form), with one if positive and with minus one
    859 ; if it is negative. If it is zero then it is left unchanged.
    860 
    861 <a name="sgn"></a><b>sgn</b>       INC   HL              ; point to first byte of 4-byte mantissa.
    862           LD    A,(HL)          ; pick up the byte with the sign bit.
    863           DEC   HL              ; point to exponent.
    864           DEC   (HL)            ; test the exponent for
    865           INC   (HL)            ; the value zero.
    866 
    867           SCF                   ; Set the carry flag.
    868           CALL  NZ,<A href="#FP_0_1">FP_0_1</a>       ; Routine FP-0/1  replaces last value with one
    869                                 ; if exponent indicates the value is non-zero.
    870                                 ; In either case mantissa is now four zeros.
    871 
    872           INC   HL              ; Point to first byte of 4-byte mantissa.
    873           RLCA                  ; Rotate original sign bit to carry.
    874           RR    (HL)            ; Rotate the carry into sign.
    875           DEC   HL              ; Point to last value.
    876           RET                   ; Return.
    877 
    878 
    879 ; -------------------------
    880 ; Handle PEEK function (28)
    881 ; -------------------------
    882 ; This function returns the contents of a memory address.
    883 ; The entire address space can be peeked including the ROM.
    884 
    885 <a name="peek"></a><b>peek</b>      CALL  <A href="#FIND_INT">FIND_INT</a>        ; routine FIND-INT puts address in BC.
    886           LD    A,(BC)          ; load contents into A register.
    887 
    888 <a name="IN_PK_STK"></a><b>IN_PK_STK</b> JP    <A href="#STACK_A">STACK_A</a>         ; exit via STACK-A to put value on the
    889                                 ; calculator stack.
    890 
    891 ; ---------------
    892 ; USR number (29)
    893 ; ---------------
    894 ; The USR function followed by a number 0-65535 is the method by which
    895 ; the ZX81 invokes machine code programs. This function returns the
    896 ; contents of the BC register pair.
    897 ; <font color=#9900FF>Note.</font> that STACK-BC re-initializes the IY register to $4000 if a user-written
    898 ; program has altered it.
    899 
    900 <a name="usr_no"></a><b>usr_no</b>    CALL  <A href="#FIND_INT">FIND_INT</a>        ; routine FIND-INT to fetch the
    901                                 ; supplied address into BC.
    902 
    903           LD    HL,STACK_BC     ; address: STACK-BC is
    904           PUSH  HL              ; pushed onto the machine stack.
    905           PUSH  BC              ; then the address of the machine code
    906                                 ; routine.
    907 
    908           RET                   ; make an indirect jump to the user's routine
    909                                 ; and, hopefully, to STACK-BC also.
    910 
    911 
    912 ; -----------------------
    913 ; Greater than zero ($33)
    914 ; -----------------------
    915 ; Test if the last value on the calculator stack is greater than zero.
    916 ; This routine is also called directly from the end-tests of the comparison
    917 ; routine.
    918 
    919 <a name="greater_0"></a><b>greater_0</b> LD    A,(HL)          ; fetch exponent.
    920           AND   A               ; test it for zero.
    921           RET   Z               ; return if so.
    922 
    923 
    924           LD    A,$FF           ; prepare XOR mask for sign bit
    925           JR    <A href="#SIGN_TO_C">SIGN_TO_C</a>       ; forward to SIGN-TO-C
    926                                 ; to put sign in carry
    927                                 ; (carry will become set if sign is positive)
    928                                 ; and then overwrite location with 1 or 0
    929                                 ; as appropriate.
    930 
    931 ; ------------------------
    932 ; Handle NOT operator ($2C)
    933 ; ------------------------
    934 ; This overwrites the last value with 1 if it was zero else with zero
    935 ; if it was any other value.
    936 ;
    937 ; e.g. NOT 0 returns 1, NOT 1 returns 0, NOT -3 returns 0.
    938 ;
    939 ; The subroutine is also called directly from the end-tests of the comparison
    940 ; operator.
    941 
    942 <a name="not"></a><b>not</b>       LD    A,(HL)          ; get exponent byte.
    943           NEG                   ; negate - sets carry if non-zero.
    944           CCF                   ; complement so carry set if zero, else reset.
    945           JR    <A href="#FP_0_1">FP_0_1</a>          ; forward to FP-0/1.
    946 
    947 ; -------------------
    948 ; Less than zero (32)
    949 ; -------------------
    950 ; Destructively test if last value on calculator stack is less than zero.
    951 ; Bit 7 of second byte will be set if so.
    952 
    953 <a name="less_0"></a><b>less_0</b>    XOR   A               ; set xor mask to zero
    954                                 ; (carry will become set if sign is negative).
    955 
    956 ; transfer sign of mantissa to Carry Flag.
    957 
    958 <a name="SIGN_TO_C"></a><b>SIGN_TO_C</b> INC   HL              ; address 2nd byte.
    959           XOR   (HL)            ; bit 7 of HL will be set if number is negative.
    960           DEC   HL              ; address 1st byte again.
    961           RLCA                  ; rotate bit 7 of A to carry.
    962 
    963 ; -----------
    964 ; Zero or one
    965 ; -----------
    966 ; This routine places an integer value zero or one at the addressed location
    967 ; of calculator stack or MEM area. The value one is written if carry is set on
    968 ; entry else zero.
    969 
    970 <a name="FP_0_1"></a><b>FP_0_1</b>    PUSH  HL              ; save pointer to the first byte
    971           LD    B,$05           ; five bytes to do.
    972 
    973 <a name="FP_loop"></a><b>FP_loop</b>   LD    (HL),$00        ; insert a zero.
    974           INC   HL              ;
    975           DJNZ  <A href="#FP_loop">FP_loop</a>         ; repeat.
    976 
    977           POP   HL              ;
    978           RET   NC              ;
    979 
    980           LD    (HL),$81        ; make value 1
    981           RET                   ; return.
    982 
    983 
    984 ; -----------------------
    985 ; Handle OR operator (07)
    986 ; -----------------------
    987 ; The Boolean OR operator. eg. X OR Y
    988 ; The result is zero if both values are zero else a non-zero value.
    989 ;
    990 ; e.g.    0 OR 0  returns 0.
    991 ;        -3 OR 0  returns -3.
    992 ;         0 OR -3 returns 1.
    993 ;        -3 OR 2  returns 1.
    994 ;
    995 ; A binary operation.
    996 ; On entry HL points to first operand (X) and DE to second operand (Y).
    997 
    998 <a name="or"></a><b>or</b>        LD    A,(DE)          ; fetch exponent of second number
    999           AND   A               ; test it.
   1000           RET   Z               ; return if zero.
   1001 
   1002           SCF                   ; set carry flag
   1003           JR    <A href="#FP_0_1">FP_0_1</a>          ; back to FP-0/1 to overwrite the first operand
   1004                                 ; with the value 1.
   1005 
   1006 
   1007 ; -----------------------------
   1008 ; Handle number AND number (08)
   1009 ; -----------------------------
   1010 ; The Boolean AND operator.
   1011 ;
   1012 ; e.g.    -3 AND 2  returns -3.
   1013 ;         -3 AND 0  returns 0.
   1014 ;          0 and -2 returns 0.
   1015 ;          0 and 0  returns 0.
   1016 ;
   1017 ; Compare with OR routine above.
   1018 
   1019 <a name="no_v_no"></a><b>no_v_no</b>   LD    A,(DE)          ; fetch exponent of second number.
   1020           AND   A               ; test it.
   1021           RET   NZ              ; return if not zero.
   1022 
   1023           JR    <A href="#FP_0_1">FP_0_1</a>          ; back to FP-0/1 to overwrite the first operand
   1024                                 ; with zero for return value.
   1025 
   1026 ; -----------------------------
   1027 ; Handle string AND number (10)
   1028 ; -----------------------------
   1029 ; e.g. "YOU WIN" AND SCORE&gt;99 will return the string if condition is true
   1030 ; or the null string if false.
   1031 
   1032 <a name="str_v_no"></a><b>str_v_no</b>  LD    A,(DE)          ; fetch exponent of second number.
   1033           AND   A               ; test it.
   1034           RET   NZ              ; return if number was not zero - the string
   1035                                 ; is the result.
   1036 
   1037 ; if the number was zero (false) then the null string must be returned by
   1038 ; altering the length of the string on the calculator stack to zero.
   1039 
   1040           PUSH  DE              ; save pointer to the now obsolete number
   1041                                 ; (which will become the new STKEND)
   1042 
   1043           DEC   DE              ; point to the 5th byte of string descriptor.
   1044           XOR   A               ; clear the accumulator.
   1045           LD    (DE),A          ; place zero in high byte of length.
   1046           DEC   DE              ; address low byte of length.
   1047           LD    (DE),A          ; place zero there - now the null string.
   1048 
   1049           POP   DE              ; restore pointer - new STKEND.
   1050           RET                   ; return.
   1051 
   1052 ; -------------------------------------
   1053 ; Perform comparison ($09-$0E, $11-$16)
   1054 ; -------------------------------------
   1055 ; True binary operations.
   1056 ;
   1057 ; A single entry point is used to evaluate six numeric and six string
   1058 ; comparisons. On entry, the calculator literal is in the B register and
   1059 ; the two numeric values, or the two string parameters, are on the
   1060 ; calculator stack.
   1061 ; The individual bits of the literal are manipulated to group similar
   1062 ; operations although the SUB 8 instruction does nothing useful and merely
   1063 ; alters the string test bit.
   1064 ; Numbers are compared by subtracting one from the other, strings are
   1065 ; compared by comparing every character until a mismatch, or the end of one
   1066 ; or both, is reached.
   1067 ;
   1068 ; Numeric Comparisons.
   1069 ; --------------------
   1070 ; The <b><font color=#333388>'x&gt;y'</font></b> example is the easiest as it employs straight-thru logic.
   1071 ; Number y is subtracted from x and the result tested for greater-0 yielding
   1072 ; a final value 1 (true) or 0 (false).
   1073 ; For 'x&lt;y' the same logic is used but the two values are first swapped on the
   1074 ; calculator stack.
   1075 ; For 'x=y' NOT is applied to the subtraction result yielding true if the
   1076 ; difference was zero and false with anything else.
   1077 ; The first three numeric comparisons are just the opposite of the last three
   1078 ; so the same processing steps are used and then a final NOT is applied.
   1079 ;
   1080 ; literal    Test   No  sub 8       ExOrNot  1st RRCA  exch sub  ?   End-Tests
   1081 ; =========  ====   == ======== === ======== ========  ==== ===  =  === === ===
   1082 ; no-l-eql   x&lt;=y   09 00000001 dec 00000000 00000000  ---- x-y  ?  --- &gt;0? NOT
   1083 ; no-gr-eql  x&gt;=y   0A 00000010 dec 00000001 10000000c swap y-x  ?  --- &gt;0? NOT
   1084 ; nos-neql   x&lt;&gt;y   0B 00000011 dec 00000010 00000001  ---- x-y  ?  NOT --- NOT
   1085 ; no-grtr    x&gt;y    0C 00000100  -  00000100 00000010  ---- x-y  ?  --- &gt;0? ---
   1086 ; no-less    x&lt;y    0D 00000101  -  00000101 10000010c swap y-x  ?  --- &gt;0? ---
   1087 ; nos-eql    x=y    0E 00000110  -  00000110 00000011  ---- x-y  ?  NOT --- ---
   1088 ;
   1089 ;                                                           comp -&gt; C/F
   1090 ;                                                           ====    ===
   1091 ; str-l-eql  x$&lt;=y$ 11 00001001 dec 00001000 00000100  ---- x$y$ 0  !or &gt;0? NOT
   1092 ; str-gr-eql x$&gt;=y$ 12 00001010 dec 00001001 10000100c swap y$x$ 0  !or &gt;0? NOT
   1093 ; strs-neql  x$&lt;&gt;y$ 13 00001011 dec 00001010 00000101  ---- x$y$ 0  !or &gt;0? NOT
   1094 ; str-grtr   x$&gt;y$  14 00001100  -  00001100 00000110  ---- x$y$ 0  !or &gt;0? ---
   1095 ; str-less   x$&lt;y$  15 00001101  -  00001101 10000110c swap y$x$ 0  !or &gt;0? ---
   1096 ; strs-eql   x$=y$  16 00001110  -  00001110 00000111  ---- x$y$ 0  !or &gt;0? ---
   1097 ;
   1098 ; String comparisons are a little different in that the eql/neql carry flag
   1099 ; from the 2nd RRCA is, as before, fed into the first of the end tests but
   1100 ; along the way it gets modified by the comparison process. The result on the
   1101 ; stack always starts off as zero and the carry fed in determines if NOT is
   1102 ; applied to it. So the only time the greater-0 test is applied is if the
   1103 ; stack holds zero which is not very efficient as the test will always yield
   1104 ; zero. The most likely explanation is that there were once separate end tests
   1105 ; for numbers and strings.
   1106 
   1107 <a name="no_l_eql"></a><b>no_l_eql</b>  LD    A,B             ; transfer literal to accumulator.
   1108 
   1109 <font color=#FF3333>;;;       SUB   $08             ; subtract eight - which is not useful.</font>
   1110 
   1111           BIT   2,A             ; isolate '&gt;', '&lt;', '='.
   1112 
   1113           JR    NZ,<A href="#EX_OR_NOT">EX_OR_NOT</a>    ; skip to EX-OR-NOT with these.
   1114 
   1115           DEC   A               ; else make $00-$02, $08-$0A to match bits 0-2.
   1116 
   1117 <a name="EX_OR_NOT"></a><b>EX_OR_NOT</b> RRCA                  ; the first RRCA sets carry for a swap.
   1118           JR    NC,<A href="#NU_OR_STR">NU_OR_STR</a>    ; forward to NU-OR-STR with other 8 cases
   1119 
   1120 ; for the other 4 cases the two values on the calculator stack are exchanged.
   1121 
   1122           PUSH  AF              ; save A and carry.
   1123           PUSH  HL              ; save HL - pointer to first operand.
   1124                                 ; (DE points to second operand).
   1125 
   1126           CALL  exchange        ; routine exchange swaps the two values.
   1127                                 ; (HL = second operand, DE = STKEND)
   1128 
   1129           POP   DE              ; DE = first operand
   1130           EX    DE,HL           ; as we were.
   1131           POP   AF              ; restore A and carry.
   1132 
   1133 ; <font color=#9900FF>Note.</font> it would be better if the 2nd RRCA preceded the string test.
   1134 ; It would save two duplicate bytes and if we also got rid of that sub 8
   1135 ; at the beginning we wouldn't have to alter which bit we test.
   1136 
   1137 <a name="NU_OR_STR"></a><b>NU_OR_STR</b> <font color=#3333FF>RRCA                  ;+ causes 'eql/neql' to set carry.</font>
   1138  <font color=#3333FF>         PUSH  AF              ;+ save the carry flag.</font>
   1139           BIT   2,A             ; test if a string comparison.
   1140           JR    NZ,<A href="#STRINGS">STRINGS</a>      ; forward to STRINGS if so.
   1141 
   1142 ; continue with numeric comparisons.
   1143 
   1144 <font color=#FF3333>;;;       RRCA                  ; 2nd RRCA causes eql/neql to set carry.</font>
   1145 <font color=#FF3333>;;;       PUSH    AF            ; save A and carry</font>
   1146 
   1147           CALL  subtract        ; routine subtract leaves result on stack.
   1148           JR    <A href="#END_TESTS">END_TESTS</a>       ; forward to END-TESTS
   1149 
   1150 ; ---
   1151 
   1152 <a name="STRINGS"></a><b>STRINGS</b>     
   1153 <font color=#FF3333>;;;       RRCA                  ; 2nd RRCA causes eql/neql to set carry.</font>
   1154 <font color=#FF3333>;;;       PUSH    AF            ; save A and carry.</font>
   1155 
   1156           CALL  <A href="#STK_FETCH">STK_FETCH</a>       ; routine STK-FETCH gets 2nd string params
   1157           PUSH  DE              ; save start2 *.
   1158           PUSH  BC              ; and the length.
   1159 
   1160           CALL  <A href="#STK_FETCH">STK_FETCH</a>       ; routine STK-FETCH gets 1st string
   1161                                 ; parameters - start in DE, length in BC.
   1162           POP   HL              ; restore length of second to HL.
   1163 
   1164 ; A loop is now entered to compare, by subtraction, each corresponding character
   1165 ; of the strings. For each successful match, the pointers are incremented and
   1166 ; the lengths decreased and the branch taken back to here. If both string
   1167 ; remainders become null at the same time, then an exact match exists.
   1168 
   1169 <a name="BYTE_COMP"></a><b>BYTE_COMP</b> LD    A,H             ; test if the second string
   1170           OR    L               ; is the null string and hold flags.
   1171 
   1172           EX    (SP),HL         ; put length2 on stack, bring start2 to HL *.
   1173           LD    A,B             ; hi byte of length1 to A
   1174 
   1175           JR    NZ,<A href="#SEC_PLUS">SEC_PLUS</a>     ; forward to SEC-PLUS if second not null.
   1176 
   1177           OR    C               ; test length of first string.
   1178 
   1179 <a name="SECND_LOW"></a><b>SECND_LOW</b> POP   BC              ; pop the second length off stack.
   1180           JR    Z,<A href="#BOTH_NULL">BOTH_NULL</a>     ; forward to BOTH-NULL if first string is also
   1181                                 ; of zero length.
   1182 
   1183 ; the true condition - first is longer than second (SECND-LESS)
   1184 
   1185           POP   AF              ; restore carry (set if eql/neql)
   1186           CCF                   ; complement carry flag.
   1187                                 ; <font color=#9900FF>Note.</font> equality becomes false.
   1188                                 ; Inequality is true. By swapping or applying
   1189                                 ; a terminal 'not', all comparisons have been
   1190                                 ; manipulated so that this is success path.
   1191           JR    <A href="#STR_TEST">STR_TEST</a>        ; forward to leave via STR-TEST
   1192 
   1193 ; ---
   1194 ; the branch was here with a match
   1195 
   1196 <a name="BOTH_NULL"></a><b>BOTH_NULL</b> POP   AF              ; restore carry - set for eql/neql
   1197           JR    <A href="#STR_TEST">STR_TEST</a>        ; forward to STR-TEST
   1198 
   1199 ; ---
   1200 ; the branch was here when 2nd string not null and low byte of first is yet
   1201 ; to be tested.
   1202 
   1203 
   1204 <a name="SEC_PLUS"></a><b>SEC_PLUS</b>  OR    C               ; test the length of first string.
   1205           JR    Z,<A href="#FRST_LESS">FRST_LESS</a>     ; forward to FRST-LESS if length is zero.
   1206 
   1207 ; both strings have at least one character left.
   1208 
   1209           LD    A,(DE)          ; fetch character of first string.
   1210           SUB   (HL)            ; subtract with that of 2nd string.
   1211           JR    C,<A href="#FRST_LESS">FRST_LESS</a>     ; forward to FRST-LESS if carry set
   1212 
   1213           JR    NZ,<A href="#SECND_LOW">SECND_LOW</a>    ; back to SECND-LOW and then STR-TEST
   1214                                 ; if not exact match.
   1215 
   1216           DEC   BC              ; decrease length of 1st string.
   1217           INC   DE              ; increment 1st string pointer.
   1218 
   1219           INC   HL              ; increment 2nd string pointer.
   1220           EX    (SP),HL         ; swap with length on stack
   1221           DEC   HL              ; decrement 2nd string length
   1222           JR    <A href="#BYTE_COMP">BYTE_COMP</a>       ; back to BYTE-COMP
   1223 
   1224 ; ---
   1225 ; the false condition.
   1226 
   1227 <a name="FRST_LESS"></a><b>FRST_LESS</b> POP   BC              ; discard length
   1228           POP   AF              ; pop A
   1229           AND   A               ; clear the carry for false result.
   1230 
   1231 ; ---
   1232 ; exact match and x$&gt;y$ rejoin here
   1233 
   1234 <a name="STR_TEST"></a><b>STR_TEST</b>  PUSH  AF              ; save A and carry
   1235 
   1236           RST   28H             ;; FP-CALC
   1237           DEFB  $A0             ;;stk-zero      an initial false value.
   1238           DEFB  $34             ;;end-calc
   1239 
   1240 ; both numeric and string paths converge here.
   1241 
   1242 <a name="END_TESTS"></a><b>END_TESTS</b> POP   AF              ; pop carry  - will be set if eql/neql
   1243           PUSH  AF              ; save it again.
   1244 
   1245           CALL  C,not           ; routine NOT sets true(1) if equal(0)
   1246                                 ; or, for strings, applies true result.
   1247           CALL  greater_0       ; greater-0 
   1248 
   1249 
   1250           POP   AF              ; pop A
   1251           RRCA                  ; the third RRCA - test for '&lt;=', '&gt;=' or '&lt;&gt;'.
   1252           CALL  NC,not          ; apply a terminal NOT if so.
   1253           RET                   ; return.
   1254 
   1255 ; -----------------------------------
   1256 ; THE <b><font color=#333388>'STRING CONCATENATION'</font></b> OPERATOR
   1257 ; -----------------------------------
   1258 ; <font color=#339933>(offset $17: 'strs_add')</font>
   1259 ; This literal combines two strings into one e.g. LET A$ = B$ + C$
   1260 ; The two parameters of the two strings to be combined are on the stack.
   1261 
   1262 <a name="strs_add"></a><b>strs_add</b>    
   1263           CALL  <A href="#STK_FETCH">STK_FETCH</a>       ; routine STK-FETCH fetches string parameters
   1264                                 ; and deletes calculator stack entry.
   1265           PUSH  DE              ; save start address.
   1266           PUSH  BC              ; and length.
   1267 
   1268           CALL  <A href="#STK_FETCH">STK_FETCH</a>       ; routine STK-FETCH for first string
   1269           POP   HL              ; re-fetch first length
   1270           PUSH  HL              ; and save again
   1271           PUSH  DE              ; save start of second string
   1272           PUSH  BC              ; and its length.
   1273 
   1274           ADD   HL,BC           ; add the two lengths.
   1275           LD    B,H             ; transfer to BC
   1276           LD    C,L             ; and create
   1277           RST   30H             ; BC-SPACES in workspace.
   1278                                 ; DE points to start of space.
   1279 
   1280           CALL  <A href="#STK_STO_s">STK_STO_s</a>       ; routine STK-STO-$ stores parameters
   1281                                 ; of new string updating STKEND.
   1282 
   1283           POP   BC              ; length of first
   1284           POP   HL              ; address of start
   1285 
   1286 <font color=#FF3333>;;;       LD      A,B           ; test for</font>
   1287 <font color=#FF3333>;;;       OR      C             ; zero length.</font>
   1288 <font color=#FF3333>;;;       JR      Z,OTHER_STR   ; to OTHER-STR if null string</font>
   1289 <font color=#FF3333>;;;       LDIR                  ; copy string to workspace.</font>
   1290 
   1291  <font color=#3333FF>         CALL  <A href="#COND_MV">COND_MV</a>         ;+ a conditional (NZ) ldir routine. </font>
   1292 
   1293 <a name="OTHER_STR"></a><b>OTHER_STR</b> POP   BC              ; now second length
   1294           POP   HL              ; and start of string
   1295 
   1296 <font color=#FF3333>;;;       LD    A,B             ; test this one</font>
   1297 <font color=#FF3333>;;;       OR    C               ; for zero length</font>
   1298 <font color=#FF3333>;;;       JR    Z,<A href="#STK_PNTRS">STK_PNTRS</a>     ; skip forward to STK-PNTRS if so as complete.</font>
   1299 <font color=#FF3333>;;;       LDIR                  ; else copy the bytes.</font>
   1300 
   1301  <font color=#3333FF>         CALL  <A href="#COND_MV">COND_MV</a>         ;+ a conditional (NZ) ldir routine. </font>
   1302 
   1303 ;   Continue into next routine which sets the calculator stack pointers.
   1304 
   1305 ; ----------------------------
   1306 ; THE <b><font color=#333388>'STACK POINTERS'</font></b> ROUTINE
   1307 ; ----------------------------
   1308 ;   Register DE is set to STKEND and HL, the result pointer, is set to five
   1309 ;   locations below this - the 'last value'.
   1310 ;   This routine is used when it is inconvenient to save these values at the
   1311 ;   time the calculator stack is manipulated due to other activity on the
   1312 ;   machine stack.
   1313 ;   This routine is also used to terminate the VAL routine for
   1314 ;   the same reason and to initialize the calculator stack at the start of
   1315 ;   the CALCULATE routine.
   1316 
   1317 <a name="STK_PNTRS"></a><b>STK_PNTRS</b> LD    HL,($401C)      ; fetch STKEND value from system variable.
   1318           LD    DE,$FFFB        ; the value -5
   1319           PUSH  HL              ; push STKEND value.
   1320 
   1321           ADD   HL,DE           ; subtract 5 from HL.
   1322 
   1323           POP   DE              ; pop STKEND to DE.
   1324           RET                   ; return.
   1325 
   1326 ; -------------------
   1327 ; THE <b><font color=#333388>'CHR$'</font></b> FUNCTION
   1328 ; -------------------
   1329 ; <font color=#339933>(offset $2B: 'chr$')</font>
   1330 ;   This function returns a single character string that is a result of
   1331 ;   converting a number in the range 0-255 to a string e.g. CHR$ 38 = "A".
   1332 ;   <font color=#9900FF>Note.</font> the ZX81 does not have an ASCII character set.
   1333 
   1334 <a name="chrS"></a><b>chrS</b>      CALL  <A href="#FP_TO_A">FP_TO_A</a>         ; routine FP-TO-A puts the number in A.
   1335 
   1336           JR    C,<A href="#REPORT_Bd">REPORT_Bd</a>     ; forward to REPORT-Bd if overflow
   1337           JR    NZ,<A href="#REPORT_Bd">REPORT_Bd</a>    ; forward to REPORT-Bd if negative
   1338 
   1339 <font color=#FF3333>;;;       PUSH  AF              ; save the argument.</font>
   1340 
   1341           LD    BC,$0001        ; one space required.
   1342           RST   30H             ; BC-SPACES makes DE point to start
   1343 
   1344 <font color=#FF3333>;;;       POP   AF              ; restore the number.</font>
   1345 
   1346           LD    (DE),A          ; and store in workspace
   1347 
   1348  <font color=#3333FF>         JR    str_STK         ;+ relative jump to similar sequence in str$.</font>
   1349 
   1350 <font color=#FF3333>;;;       CALL  <A href="#STK_STO_s">STK_STO_s</a>       ; routine STK-STO-$ stacks descriptor.</font>
   1351 <font color=#FF3333>;;;       EX    DE,HL           ; make HL point to result and DE to STKEND.</font>
   1352 <font color=#FF3333>;;;       RET                   ; return.</font>
   1353 
   1354 ; ---
   1355 
   1356 <a name="REPORT_Bd"></a><b>REPORT_Bd</b> RST   08H             ; ERROR-1
   1357           DEFB  $0A             ; Error Report: Integer out of range
   1358 
   1359 ; ------------------
   1360 ; THE <b><font color=#333388>'VAL'</font></b> FUNCTION
   1361 ; ------------------
   1362 ; <font color=#339933>(offset $1A: 'val')</font>
   1363 ;   VAL treats the characters in a string as a numeric expression.
   1364 ;   e.g. VAL "2.3" = 2.3, VAL "2+4" = 6, VAL ("2" + "4") = 24.
   1365 
   1366 <a name="val"></a><b>val</b> <font color=#3333FF>      RST   18H             ;+ shorter way to fetch CH_ADD.</font>
   1367 
   1368 <font color=#FF3333>;;;       LD    HL,($4016)      ; fetch value of system variable CH_ADD</font>
   1369           PUSH  HL              ; and save on the machine stack.
   1370 
   1371           CALL  <A href="#STK_FETCH">STK_FETCH</a>       ; routine STK-FETCH fetches the string operand
   1372                                 ; from calculator stack.
   1373 
   1374           PUSH  DE              ; save the address of the start of the string.
   1375           INC   BC              ; increment the length for a carriage return.
   1376 
   1377           RST   30H             ; BC-SPACES creates the space in workspace.
   1378           POP   HL              ; restore start of string to HL.
   1379           LD    ($4016),DE      ; load CH_ADD with start DE in workspace.
   1380 
   1381           PUSH  DE              ; save the start in workspace
   1382           LDIR                  ; copy string from program or variables or
   1383                                 ; workspace to the workspace area.
   1384           EX    DE,HL           ; end of string + 1 to HL
   1385           DEC   HL              ; decrement HL to point to end of new area.
   1386           LD    (HL),$76        ; insert a carriage return at end.
   1387                                 ; ZX81 has a non-ASCII character set
   1388           RES   7,(IY+$01)      ; update FLAGS  - signal checking syntax.
   1389           CALL  <A href="#CLASS_06">CLASS_06</a>        ; routine CLASS-06 - SCANNING evaluates string
   1390                                 ; expression and checks for integer result.
   1391 
   1392           CALL  <A href="#CHECK_2">CHECK_2</a>         ; routine CHECK-2 checks for carriage return.
   1393 
   1394 
   1395           POP   HL              ; restore start of string in workspace.
   1396 
   1397           LD    ($4016),HL      ; set CH_ADD to the start of the string again.
   1398           SET   7,(IY+$01)      ; update FLAGS  - signal running program.
   1399           CALL  <A href="#SCANNING">SCANNING</a>        ; routine SCANNING evaluates the string
   1400                                 ; in full leaving result on calculator stack.
   1401 
   1402           POP   HL              ; restore saved character address in program.
   1403           LD    ($4016),HL      ; and reset the system variable CH_ADD.
   1404 
   1405           JR    <A href="#STK_PNTRS">STK_PNTRS</a>       ; back to exit via STK-PNTRS.
   1406                                 ; resetting the calculator stack pointers
   1407                                 ; HL and DE from STKEND as it wasn't possible
   1408                                 ; to preserve them during this routine.
   1409 
   1410 ; -------------------
   1411 ; THE <b><font color=#333388>'STR$'</font></b> FUNCTION
   1412 ; -------------------
   1413 ; <font color=#339933>(offset $2A: 'str$')</font>
   1414 ; This function returns a string representation of a numeric argument.
   1415 ; The method used is to trick the PRINT-FP routine into thinking it
   1416 ; is writing to a collapsed display file when in fact it is writing to
   1417 ; string workspace.
   1418 ; If there is already a newline at the intended print position and the
   1419 ; column count has not been reduced to zero then the print routine
   1420 ; assumes that there is only 1K of RAM and the screen memory, like the rest
   1421 ; of dynamic memory, expands as necessary using calls to the ONE-SPACE
   1422 ; routine. The screen is character-mapped not bit-mapped.
   1423 
   1424 <a name="strS"></a><b>strS</b>      LD    BC,$0001        ; create an initial byte in workspace
   1425           RST   30H             ; using BC-SPACES restart.
   1426 
   1427           LD    (HL),$76        ; place a carriage return there.
   1428 
   1429           LD    HL,($4039)      ; fetch value of S_POSN column/line
   1430           PUSH  HL              ; and preserve on stack.
   1431 
   1432           LD    L,$FF           ; make column value high to create a
   1433                                 ; contrived buffer of length 254.
   1434           LD    ($4039),HL      ; and store in system variable S_POSN.
   1435 
   1436           LD    HL,($400E)      ; fetch value of DF_CC
   1437           PUSH  HL              ; and preserve on stack also.
   1438 
   1439           LD    ($400E),DE      ; now set DF_CC which normally addresses
   1440                                 ; somewhere in the display file to the start
   1441                                 ; of workspace.
   1442           PUSH  DE              ; save the start of new string.
   1443 
   1444           CALL  <A href="#PRINT_FP">PRINT_FP</a>        ; routine PRINT-FP.
   1445 
   1446           POP   DE              ; retrieve start of string.
   1447 
   1448           LD    HL,($400E)      ; fetch end of string from DF_CC.
   1449           AND   A               ; prepare for true subtraction.
   1450           SBC   HL,DE           ; subtract to give length.
   1451 
   1452           LD    B,H             ; and transfer to the BC
   1453           LD    C,L             ; register.
   1454 
   1455           POP   HL              ; restore original
   1456           LD    ($400E),HL      ; DF_CC value
   1457 
   1458           POP   HL              ; restore original
   1459           LD    ($4039),HL      ; S_POSN values.
   1460 
   1461 ;   New entry-point to exploit similarities and save 3 bytes of code.
   1462 
   1463 <a name="str_STK"></a><b>str_STK</b> CALL    STK_STO_s       ; routine STK-STO-$ stores the string
   1464                                 ; descriptor on the calculator stack.
   1465 
   1466           EX    DE,HL           ; HL = last value, DE = STKEND.
   1467           RET                   ; return.
   1468 
   1469 
   1470 ; -------------------
   1471 ; THE <b><font color=#333388>'CODE'</font></b> FUNCTION
   1472 ; -------------------
   1473 ; <font color=#339933>(offset $19: 'code')</font>
   1474 ; Returns the code of a character or first character of a string
   1475 ; e.g. CODE "AARDVARK" = 38  (not 65 as the ZX81 does not have an ASCII
   1476 ; character set).
   1477 
   1478 
   1479 <a name="code"></a><b>code</b>      CALL  <A href="#STK_FETCH">STK_FETCH</a>       ; routine STK-FETCH to fetch and delete the
   1480                                 ; string parameters.
   1481                                 ; DE points to the start, BC holds the length.
   1482           LD    A,B             ; test length
   1483           OR    C               ; of the string.
   1484           JR    Z,<A href="#STK_CODE">STK_CODE</a>      ; skip to STK-CODE with zero if the null string.
   1485 
   1486           LD    A,(DE)          ; else fetch the first character.
   1487 
   1488 <a name="STK_CODE"></a><b>STK_CODE</b>  JP    <A href="#STACK_A">STACK_A</a>         ; jump back to STACK-A (with memory check)
   1489 
   1490 ; --------------------
   1491 ; THE <b><font color=#333388>'LEN'</font></b> SUBROUTINE
   1492 ; --------------------
   1493 ; <font color=#339933>(offset $1b: 'len')</font>
   1494 ; Returns the length of a string.
   1495 ; In Sinclair BASIC strings can be more than twenty thousand characters long
   1496 ; so a sixteen-bit register is required to store the length
   1497 
   1498 <a name="len"></a><b>len</b>       CALL  <A href="#STK_FETCH">STK_FETCH</a>       ; routine STK-FETCH to fetch and delete the
   1499                                 ; string parameters from the calculator stack.
   1500                                 ; register BC now holds the length of string.
   1501 
   1502           JP    <A href="#STACK_BC">STACK_BC</a>        ; jump back to STACK-BC to save result on the
   1503                                 ; calculator stack (with memory check).
   1504 
   1505 ; -------------------------------------
   1506 ; THE <b><font color=#333388>'DECREASE THE COUNTER'</font></b> SUBROUTINE
   1507 ; -------------------------------------
   1508 ; <font color=#339933>(offset $31: 'dec-jr-nz')</font>
   1509 ; The calculator has an instruction that decrements a single-byte
   1510 ; pseudo-register and makes consequential relative jumps just like
   1511 ; the Z80's DJNZ instruction.
   1512 
   1513 <a name="dec_jr_nz"></a><b>dec_jr_nz</b> EXX                   ; switch in set that addresses code
   1514 
   1515           PUSH  HL              ; save pointer to offset byte
   1516           LD    HL,$401E        ; address BREG in system variables
   1517           DEC   (HL)            ; decrement it
   1518           POP   HL              ; restore pointer
   1519 
   1520           JR    NZ,<A href="#JUMP_2">JUMP_2</a>       ; to JUMP-2 if not zero
   1521 
   1522           INC   HL              ; step past the jump length.
   1523           EXX                   ; switch in the main set.
   1524           RET                   ; return.
   1525 
   1526 ; <font color=#9900FF>Note.</font> as a general rule the calculator avoids using the IY register
   1527 ; otherwise the cumbersome 4 instructions in the middle could be replaced by
   1528 ; dec (iy+$xx) - using three instruction bytes instead of six.
   1529 
   1530 
   1531 ; ---------------------
   1532 ; THE <b><font color=#333388>'JUMP'</font></b> SUBROUTINE
   1533 ; ---------------------
   1534 ; <font color=#339933>(Offset $2F; 'jump')</font>
   1535 ; This enables the calculator to perform relative jumps just like
   1536 ; the Z80 chip's JR instruction.
   1537 ; This is one of the few routines that was polished for the ZX Spectrum.
   1538 
   1539 <a name="JUMP"></a><b>JUMP</b>      EXX                   ;switch in pointer set
   1540 
   1541 <a name="JUMP_2"></a><b>JUMP_2</b>    LD    E,(HL)          ; the jump byte 0-127 forward, 128-255 back.
   1542 
   1543 ;   <font color=#9900FF>Note.</font> Elegance from the ZX Spectrum.
   1544 
   1545  <font color=#3333FF>         LD    A,E             ;+</font>
   1546  <font color=#3333FF>         RLA                   ;+</font>
   1547  <font color=#3333FF>         SBC   A,A             ;+</font>
   1548 
   1549 ;   The original ZX81 code.
   1550 
   1551 <font color=#FF3333>;;;       XOR   A               ; clear accumulator.</font>
   1552 <font color=#FF3333>;;;       BIT   7,E             ; test if negative jump</font>
   1553 <font color=#FF3333>;;;       JR    Z,<A href="#JUMP_3">JUMP_3</a>        ; skip, if positive, to JUMP-3.</font>
   1554 <font color=#FF3333>;;;       CPL                   ; else change to $FF.</font>
   1555 
   1556 <a name="JUMP_3"></a><b>JUMP_3</b>    LD    D,A             ; transfer to high byte.
   1557           ADD   HL,DE           ; advance calculator pointer forward or back.
   1558 
   1559           EXX                   ; switch out pointer set.
   1560           RET                   ; return.
   1561 
   1562 ; -----------------------------
   1563 ; THE <b><font color=#333388>'JUMP ON TRUE'</font></b> SUBROUTINE
   1564 ; -----------------------------
   1565 ; <font color=#339933>(Offset $00; 'jump-true')</font>
   1566 ; This enables the calculator to perform conditional relative jumps
   1567 ; dependent on whether the last test gave a true result
   1568 ; On the ZX81, the exponent will be zero for zero or else $81 for one.
   1569 
   1570 <a name="jump_true"></a><b>jump_true</b> LD    A,(DE)          ; collect exponent byte
   1571 
   1572           AND   A               ; is result 0 or 1 ?
   1573           JR    NZ,<A href="#JUMP">JUMP</a>         ; back to JUMP if true (1).
   1574 
   1575           EXX                   ; else switch in the pointer set.
   1576           INC   HL              ; step past the jump length.
   1577           EXX                   ; switch in the main set.
   1578           RET                   ; return.
   1579 
   1580 
   1581 ; ------------------------
   1582 ; THE <b><font color=#333388>'MODULUS'</font></b> SUBROUTINE
   1583 ; ------------------------
   1584 ; ( Offset $2E: 'n-mod-m' )
   1585 ; <font color=#CC00FF>( i1, i2 -- i3, i4 )</font>
   1586 ; The subroutine calculate N mod M where M is the positive integer, the
   1587 ; 'last value' on the calculator stack and N is the integer beneath.
   1588 ; The subroutine returns the integer quotient as the last value and the
   1589 ; remainder as the value beneath.
   1590 ; e.g.    17 MOD 3 = 5 remainder 2
   1591 ; It is invoked during the calculation of a random number and also by
   1592 ; the PRINT-FP routine.
   1593 
   1594 <a name="n_mod_m"></a><b>n_mod_m</b>   RST   28H             ;; FP-CALC          17, 3.
   1595           DEFB  $C0             ;;st-mem-0          17, 3.
   1596           DEFB  $02             ;;delete            17.
   1597           DEFB  $2D             ;;duplicate         17, 17.
   1598           DEFB  $E0             ;;get-mem-0         17, 17, 3.
   1599           DEFB  $05             ;;division          17, 17/3.
   1600           DEFB  $24             ;;int               17, 5.
   1601           DEFB  $E0             ;;get-mem-0         17, 5, 3.
   1602           DEFB  $01             ;;exchange          17, 3, 5.
   1603           DEFB  $C0             ;;st-mem-0          17, 3, 5.
   1604           DEFB  $04             ;;multiply          17, 15.
   1605           DEFB  $03             ;;subtract          2.
   1606           DEFB  $E0             ;;get-mem-0         2, 5.
   1607           DEFB  $34             ;;end-calc          2, 5.
   1608 
   1609           RET                   ; return.
   1610 
   1611 
   1612 ; ----------------------
   1613 ; THE <b><font color=#333388>'INTEGER'</font></b> FUNCTION
   1614 ; ----------------------
   1615 ; <font color=#339933>(offset $24: 'int')</font>
   1616 ; This function returns the integer of x, which is just the same as truncate
   1617 ; for positive numbers. The truncate literal truncates negative numbers
   1618 ; upwards so that -3.4 gives -3 whereas the BASIC INT function has to
   1619 ; truncate negative numbers down so that INT -3.4 is 4.
   1620 ; It is best to work through using, say, plus and minus 3.4 as examples.
   1621 
   1622 <a name="int"></a><b>int</b>       RST   28H             ;; FP-CALC              x.    (= 3.4 or -3.4).
   1623           DEFB  $2D             ;;duplicate             x, x.
   1624           DEFB  $32             ;;less-0                x, (1/0)
   1625           DEFB  $00             ;;jump-true             x, (1/0)
   1626           DEFB  $04             ;;to L1C46, X-NEG
   1627 
   1628           DEFB  $36             ;;truncate              trunc 3.4 = 3.
   1629           DEFB  $34             ;;end-calc              3.
   1630 
   1631           RET                   ; return with + int x on stack.
   1632 
   1633 
   1634 <a name="X_NEG"></a><b>X_NEG</b>     DEFB  $2D             ;;duplicate             -3.4, -3.4.
   1635           DEFB  $36             ;;truncate              -3.4, -3.
   1636           DEFB  $C0             ;;st-mem-0              -3.4, -3.
   1637           DEFB  $03             ;;subtract              -.4
   1638           DEFB  $E0             ;;get-mem-0             -.4, -3.
   1639           DEFB  $01             ;;exchange              -3, -.4.
   1640           DEFB  $2C             ;;not                   -3, (0).
   1641           DEFB  $00             ;;jump-true             -3.
   1642           DEFB  $03             ;;to L1C59, EXIT        -3.
   1643 
   1644           DEFB  $A1             ;;stk-one               -3, 1.
   1645           DEFB  $03             ;;subtract              -4.
   1646 
   1647 <a name="EXIT"></a><b>EXIT</b>      DEFB  $34             ;;end-calc              -4.
   1648 
   1649           RET                   ; return.
   1650 
   1651 
   1652 ; --------------------------
   1653 ; THE <b><font color=#333388>'EXPONENTIAL'</font></b> FUNCTION
   1654 ; --------------------------
   1655 ; <font color=#339933>(Offset $23: 'exp')</font>
   1656 ;   The exponential function returns the exponential of the argument, or the
   1657 ;   value of 'e' (2.7182818...) raised to the power of the argument.
   1658 ;   PRINT EXP 1 gives 2.7182818
   1659 ;
   1660 ;   EXP is the opposite of the LN function (see below) and is equivalent to 
   1661 ;   the 'antiln' function found on pocket calculators or the 'Inverse ln'
   1662 ;   function found on the Windows scientific calculator.
   1663 ;   So PRINT EXP LN 5.3 will give 5.3 as will PRINT LN EXP 5.3 or indeed
   1664 ;   any number e.g. PRINT EXP LN PI.
   1665 ;
   1666 ;   The applications of the exponential function are in areas where exponential
   1667 ;   growth is experienced, calculus, population growth and compound interest.
   1668 ;
   1669 ;   Error 6 if the argument is above 88.
   1670 
   1671 <a name="exp"></a><b>exp</b>       RST   28H             ;; FP-CALC
   1672           DEFB  $30             ;;stk-data			1/LN 2
   1673           DEFB  $F1             ;;Exponent: $81, Bytes: 4
   1674           DEFB  $38,$AA,$3B,$29 ;;
   1675           DEFB  $04             ;;multiply
   1676           DEFB  $2D             ;;duplicate
   1677           DEFB  $24             ;;int
   1678           DEFB  $C3             ;;st-mem-3
   1679           DEFB  $03             ;;subtract
   1680           DEFB  $2D             ;;duplicate
   1681           DEFB  $0F             ;;addition
   1682           DEFB  $A1             ;;stk-one
   1683           DEFB  $03             ;;subtract
   1684           DEFB  $88             ;;series-08
   1685           DEFB  $13             ;;Exponent: $63, Bytes: 1
   1686           DEFB  $36             ;;(+00,+00,+00)
   1687           DEFB  $58             ;;Exponent: $68, Bytes: 2
   1688           DEFB  $65,$66         ;;(+00,+00)
   1689           DEFB  $9D             ;;Exponent: $6D, Bytes: 3
   1690           DEFB  $78,$65,$40     ;;(+00)
   1691           DEFB  $A2             ;;Exponent: $72, Bytes: 3
   1692           DEFB  $60,$32,$C9     ;;(+00)
   1693           DEFB  $E7             ;;Exponent: $77, Bytes: 4
   1694           DEFB  $21,$F7,$AF,$24 ;;
   1695           DEFB  $EB             ;;Exponent: $7B, Bytes: 4
   1696           DEFB  $2F,$B0,$B0,$14 ;;
   1697           DEFB  $EE             ;;Exponent: $7E, Bytes: 4
   1698           DEFB  $7E,$BB,$94,$58 ;;
   1699           DEFB  $F1             ;;Exponent: $81, Bytes: 4
   1700           DEFB  $3A,$7E,$F8,$CF ;;
   1701           DEFB  $E3             ;;get-mem-3
   1702           DEFB  $34             ;;end-calc
   1703 
   1704           CALL  <A href="#FP_TO_A">FP_TO_A</a>         ; routine FP-TO-A
   1705           JR    NZ,<A href="#N_NEGTV">N_NEGTV</a>      ; to N-NEGTV
   1706 
   1707           JR    C,<A href="#REPORT_6b">REPORT_6b</a>     ; to REPORT-6b
   1708 
   1709           ADD   A,(HL)          ;
   1710           JR    NC,<A href="#RESULT_OK">RESULT_OK</a>    ; to RESULT-OK
   1711 
   1712 
   1713 <a name="REPORT_6b"></a><b>REPORT_6b</b> RST   08H             ; ERROR-1
   1714           DEFB  $05             ; Error Report: Number too big
   1715 
   1716 <a name="N_NEGTV"></a><b>N_NEGTV</b>   JR    C,<A href="#RSLT_ZERO">RSLT_ZERO</a>     ; to RSLT-ZERO
   1717 
   1718           SUB   (HL)            ;
   1719           JR    NC,<A href="#RSLT_ZERO">RSLT_ZERO</a>    ; to RSLT-ZERO
   1720 
   1721           NEG                   ; Negate
   1722 
   1723 <a name="RESULT_OK"></a><b>RESULT_OK</b> LD    (HL),A          ;
   1724           RET                   ; return.
   1725 
   1726 
   1727 <a name="RSLT_ZERO"></a><b>RSLT_ZERO</b> RST   28H             ;; FP-CALC
   1728           DEFB  $02             ;;delete
   1729           DEFB  $A0             ;;stk-zero
   1730           DEFB  $34             ;;end-calc
   1731 
   1732           RET                   ; return.
   1733 
   1734 
   1735 ; --------------------------------
   1736 ; THE <b><font color=#333388>'NATURAL LOGARITHM'</font></b> FUNCTION
   1737 ; --------------------------------
   1738 ; <font color=#339933>(offset $22: 'ln')</font>
   1739 ;   Like the ZX81 itself, 'natural' logarithms came from Scotland.
   1740 ;   They were devised in 1614 by well-traveled Scotsman John Napier who noted
   1741 ;   "Nothing doth more molest and hinder calculators than the multiplications,
   1742 ;    divisions, square and cubical extractions of great numbers".
   1743 ;   Napier's logarithms enabled the above operations to be accomplished by 
   1744 ;   simple addition and subtraction simplifying the navigational and 
   1745 ;   astronomical calculations which beset his age.
   1746 ;   Napier's logarithms were quickly overtaken by logarithms to the base 10
   1747 ;   devised, in conjunction with Napier, by Henry Briggs a Cambridge-educated 
   1748 ;   professor of Geometry at Oxford University. These simplified the layout
   1749 ;   of the tables enabling humans to easily scale calculations.
   1750 ;
   1751 ;   It is only recently with the introduction of pocket calculators and
   1752 ;   computers like the ZX81 that natural logarithms are once more at the fore,
   1753 ;   although some computers retain logarithms to the base ten.
   1754 ;   'Natural' logarithms are powers to the base 'e', which like 'pi' is a 
   1755 ;   naturally occurring number in branches of mathematics.
   1756 ;   Like 'pi' also, 'e' is an irrational number and starts 2.718281828...
   1757 ;
   1758 ;   The tabular use of logarithms was that to multiply two numbers one looked
   1759 ;   up their two logarithms in the tables, added them together and then looked 
   1760 ;   for the result in a table of antilogarithms to give the desired product.
   1761 ;
   1762 ;   The EXP function is the BASIC equivalent of a calculator's 'antiln' function 
   1763 ;   and by picking any two numbers, 1.72 and 6.89 say,
   1764 ;     10 PRINT EXP ( LN 1.72 + LN 6.89 ) 
   1765 ;   will give just the same result as
   1766 ;     20 PRINT 1.72 * 6.89.
   1767 ;   Division is accomplished by subtracting the two logs.
   1768 ;
   1769 ;   Napier also mentioned "square and cubicle extractions". 
   1770 ;   To raise a number to the power 3, find its 'ln', multiply by 3 and find the 
   1771 ;   'antiln'.  e.g. PRINT EXP( LN 4 * 3 )  gives 64.
   1772 ;   Similarly to find the n'th root divide the logarithm by 'n'.
   1773 ;   The ZX81 ROM used PRINT EXP ( LN 9 / 2 ) to find the square root of the 
   1774 ;   number 9. The Napieran square root function is just a special case of 
   1775 ;   the 'to_power' function. A cube root or indeed any root/power would be just
   1776 ;   as simple.
   1777 
   1778 ;   First test that the argument to LN is a positive, non-zero number.
   1779 
   1780 
   1781 <a name="ln"></a><b>ln</b>        RST   28H             ;; FP-CALC		x.
   1782           DEFB  $2D             ;;duplicate		x,x.
   1783           DEFB  $33             ;;greater-0		x,(0/1).
   1784           DEFB  $00             ;;jump-true		x.
   1785           DEFB  $04             ;;to L1CB1, VALID
   1786 
   1787           DEFB  $34             ;;end-calc		x.
   1788 
   1789 
   1790 <a name="REPORT_Ab"></a><b>REPORT_Ab</b> RST   08H             ; ERROR-1
   1791           DEFB  $09             ; Error Report: Invalid argument
   1792 
   1793 <a name="VALID"></a><b>VALID</b>      	 
   1794 <font color=#FF3333>;;;       DEFB  $A0             ;;stk-zero	</font>
   1795 <font color=#FF3333>;;;       DEFB  $02             ;;delete</font>
   1796           DEFB  $34             ;;end-calc		x.
   1797 
   1798 ;   Register HL addresses the 'last value' x.
   1799 
   1800           LD    A,(HL)          ; Fetch exponent to A.
   1801 
   1802           LD    (HL),$80        ; Insert 'plus zero' as exponent.
   1803           CALL  <A href="#STACK_A">STACK_A</a>         ; routine STACK-A stacks true binary exponent.
   1804 		
   1805           RST   28H             ;; FP-CALC
   1806           DEFB  $30             ;;stk-data
   1807           DEFB  $38             ;;Exponent: $88, Bytes: 1
   1808           DEFB  $00             ;;(+00,+00,+00)
   1809           DEFB  $03             ;;subtract
   1810           DEFB  $01             ;;exchange
   1811           DEFB  $2D             ;;duplicate
   1812           DEFB  $30             ;;stk-data
   1813           DEFB  $F0             ;;Exponent: $80, Bytes: 4
   1814           DEFB  $4C,$CC,$CC,$CD ;;
   1815           DEFB  $03             ;;subtract
   1816           DEFB  $33             ;;greater-0
   1817           DEFB  $00             ;;jump-true
   1818           DEFB  $08             ;;to L1CD2, GRE.8
   1819 
   1820           DEFB  $01             ;;exchange
   1821           DEFB  $A1             ;;stk-one
   1822           DEFB  $03             ;;subtract
   1823           DEFB  $01             ;;exchange
   1824           DEFB  $34             ;;end-calc
   1825 
   1826           INC   (HL)            ;
   1827 
   1828           RST   28H             ;; FP-CALC
   1829 
   1830 <a name="GRE_8"></a><b>GRE_8</b>     DEFB  $01             ;;exchange
   1831           DEFB  $30             ;;stk-data			LN 2
   1832           DEFB  $F0             ;;Exponent: $80, Bytes: 4
   1833           DEFB  $31,$72,$17,$F8 ;;
   1834           DEFB  $04             ;;multiply
   1835           DEFB  $01             ;;exchange
   1836           DEFB  $A2             ;;stk-half
   1837           DEFB  $03             ;;subtract
   1838           DEFB  $A2             ;;stk-half
   1839           DEFB  $03             ;;subtract
   1840           DEFB  $2D             ;;duplicate
   1841           DEFB  $30             ;;stk-data
   1842           DEFB  $32             ;;Exponent: $82, Bytes: 1
   1843           DEFB  $20             ;;(+00,+00,+00)
   1844           DEFB  $04             ;;multiply
   1845           DEFB  $A2             ;;stk-half
   1846           DEFB  $03             ;;subtract
   1847           DEFB  $8C             ;;series-0C
   1848           DEFB  $11             ;;Exponent: $61, Bytes: 1
   1849           DEFB  $AC             ;;(+00,+00,+00)
   1850           DEFB  $14             ;;Exponent: $64, Bytes: 1
   1851           DEFB  $09             ;;(+00,+00,+00)
   1852           DEFB  $56             ;;Exponent: $66, Bytes: 2
   1853           DEFB  $DA,$A5         ;;(+00,+00)
   1854           DEFB  $59             ;;Exponent: $69, Bytes: 2
   1855           DEFB  $30,$C5         ;;(+00,+00)
   1856           DEFB  $5C             ;;Exponent: $6C, Bytes: 2
   1857           DEFB  $90,$AA         ;;(+00,+00)
   1858           DEFB  $9E             ;;Exponent: $6E, Bytes: 3
   1859           DEFB  $70,$6F,$61     ;;(+00)
   1860           DEFB  $A1             ;;Exponent: $71, Bytes: 3
   1861           DEFB  $CB,$DA,$96     ;;(+00)
   1862           DEFB  $A4             ;;Exponent: $74, Bytes: 3
   1863           DEFB  $31,$9F,$B4     ;;(+00)
   1864           DEFB  $E7             ;;Exponent: $77, Bytes: 4
   1865           DEFB  $A0,$FE,$5C,$FC ;;
   1866           DEFB  $EA             ;;Exponent: $7A, Bytes: 4
   1867           DEFB  $1B,$43,$CA,$36 ;;
   1868           DEFB  $ED             ;;Exponent: $7D, Bytes: 4
   1869           DEFB  $A7,$9C,$7E,$5E ;;
   1870           DEFB  $F0             ;;Exponent: $80, Bytes: 4
   1871           DEFB  $6E,$23,$80,$93 ;;
   1872           DEFB  $04             ;;multiply
   1873           DEFB  $0F             ;;addition
   1874           DEFB  $34             ;;end-calc
   1875 
   1876           RET                   ; return.
   1877 
   1878 ; ------------------------------
   1879 ; THE NEW <b><font color=#333388>'SQUARE ROOT'</font></b> FUNCTION
   1880 ; ------------------------------
   1881 ; <font color=#339933>(Offset $25: 'sqr')</font>
   1882 ;   "If I have seen further, it is by standing on the shoulders of giants" -
   1883 ;   Sir Isaac Newton, Cambridge 1676.
   1884 ;   The sqr function has been re-written to use the Newton-Raphson method.
   1885 ;   Joseph Raphson was a student of Sir Isaac Newton at Cambridge University
   1886 ;   and helped publicize his work.
   1887 ;   Although Newton's method is centuries old, this routine, appropriately, is 
   1888 ;   based on a FORTH word written by Steven Vickers in the Jupiter Ace manual.
   1889 ;   Whereas that method uses an initial guess of one, this one manipulates 
   1890 ;   the exponent byte to obtain a better starting guess. 
   1891 ;   First test for zero and return zero, if so, as the result.
   1892 ;   If the argument is negative, then produce an error.
   1893 
   1894 <a name="sqr"></a><b>sqr</b>       RST   28H             ;; FP-CALC              x
   1895           DEFB  $C3             ;;st-mem-3              x.   (seed for guess)
   1896           DEFB  $34             ;;end-calc		x.
   1897 
   1898 ;   HL now points to exponent of argument on calculator stack.
   1899 
   1900           LD    A,(HL)          ; Test for zero argument
   1901           AND   A               ; 
   1902 
   1903           RET   Z               ; Return with zero on the calculator stack.
   1904 
   1905 ;   Test for a positive argument
   1906 
   1907           INC   HL              ; Address byte with sign bit.
   1908           BIT   7,(HL)          ; Test the bit.
   1909 
   1910           JR    NZ,<A href="#REPORT_Ab">REPORT_Ab</a>    ; back to REPORT_A 
   1911                                 ; 'Invalid argument'
   1912  
   1913 ;   This guess is based on a Usenet discussion.
   1914 ;   Halve the exponent to achieve a good guess.(accurate with .25 16 64 etc.)
   1915 
   1916           LD    HL,$4071        ; Address first byte of mem-3
   1917 
   1918           LD    A,(HL)          ; fetch exponent of mem-3
   1919           XOR   $80             ; toggle sign of exponent of mem-3
   1920           SRA   A               ; shift right, bit 7 unchanged.
   1921           INC   A               ;
   1922           JR    Z,<A href="#ASIS">ASIS</a>          ; forward with say .25 -&gt; .5
   1923           JP    P,<A href="#ASIS">ASIS</a>          ; leave increment if value &gt; .5
   1924           DEC   A               ; restore to shift only.
   1925 <a name="ASIS"></a><b>ASIS</b>      XOR   $80             ; restore sign.
   1926           LD    (HL),A          ; and put back 'halved' exponent.
   1927 
   1928 ;   Now re-enter the calculator.
   1929 
   1930           RST   28H             ;; FP-CALC              x
   1931 
   1932 <a name="SLOOP"></a><b>SLOOP</b>     DEFB  $2D             ;;duplicate             x,x.
   1933           DEFB  $E3             ;;get-mem-3             x,x,guess
   1934           DEFB  $C4             ;;st-mem-4              x,x,guess
   1935           DEFB  $05             ;;div                   x,x/guess.
   1936           DEFB  $E3             ;;get-mem-3             x,x/guess,guess
   1937           DEFB  $0F             ;;addition              x,x/guess+guess
   1938           DEFB  $A2             ;;stk-half              x,x/guess+guess,.5
   1939           DEFB  $04             ;;multiply              x,(x/guess+guess)*.5
   1940           DEFB  $C3             ;;st-mem-3              x,newguess
   1941           DEFB  $E4             ;;get-mem-4             x,newguess,oldguess
   1942           DEFB  $03             ;;subtract              x,newguess-oldguess
   1943           DEFB  $27             ;;abs                   x,difference.
   1944           DEFB  $33             ;;greater-0             x,(0/1).
   1945           DEFB  $00             ;;jump-true             x.
   1946 
   1947           DEFB  SLOOP - $       ;;to sloop              x.
   1948 
   1949           DEFB  $02             ;;delete                .
   1950           DEFB  $E3             ;;get-mem-3             retrieve final guess.
   1951           DEFB  $34             ;;end-calc              sqr x.
   1952 
   1953           RET                  ; return with square root on stack
   1954 
   1955 ;   or in ZX81 BASIC
   1956 ;
   1957 ;      5 PRINT "NEWTON RAPHSON SQUARE ROOTS"
   1958 ;     10 INPUT "NUMBER ";N
   1959 ;     20 INPUT "GUESS ";G
   1960 ;     30 PRINT " NUMBER "; N ;" GUESS "; G
   1961 ;     40 FOR I = 1 TO 10
   1962 ;     50  LET B = N/G
   1963 ;     60  LET C = B+G
   1964 ;     70  LET G = C/2
   1965 ;     80  PRINT I; " VALUE "; G
   1966 ;     90 NEXT I
   1967 ;    100 PRINT "NAPIER METHOD"; SQR N
   1968 
   1969 ; -----------------------------
   1970 ; THE <b><font color=#333388>'TRIGONOMETRIC'</font></b> FUNCTIONS
   1971 ; -----------------------------
   1972 ;   Trigonometry is rocket science. It is also used by carpenters and pyramid
   1973 ;   builders. 
   1974 ;   Some uses can be quite abstract but the principles can be seen in simple
   1975 ;   right-angled triangles. Triangles have some special properties -
   1976 ;
   1977 ;   1) The sum of the three angles is always PI radians (180 degrees).
   1978 ;      Very helpful if you know two angles and wish to find the third.
   1979 ;   2) In any right-angled triangle the sum of the squares of the two shorter
   1980 ;      sides is equal to the square of the longest side opposite the right-angle.
   1981 ;      Very useful if you know the length of two sides and wish to know the
   1982 ;      length of the third side.
   1983 ;   3) Functions sine, cosine and tangent enable one to calculate the length 
   1984 ;      of an unknown side when the length of one other side and an angle is 
   1985 ;      known.
   1986 ;   4) Functions arcsin, arccosine and arctan enable one to calculate an unknown
   1987 ;      angle when the length of two of the sides is known.
   1988 
   1989 ; --------------------------------
   1990 ; THE <b><font color=#333388>'REDUCE ARGUMENT'</font></b> SUBROUTINE
   1991 ; --------------------------------
   1992 ; <font color=#339933>(offset $35: 'get-argt')</font>
   1993 ;
   1994 ;   This routine performs two functions on the angle, in radians, that forms
   1995 ;   the argument to the sine and cosine functions.
   1996 ;   First it ensures that the angle 'wraps round'. That if a ship turns through 
   1997 ;   an angle of, say, 3*PI radians (540 degrees) then the net effect is to turn 
   1998 ;   through an angle of PI radians (180 degrees).
   1999 ;   Secondly it converts the angle in radians to a fraction of a right angle,
   2000 ;   depending within which quadrant the angle lies, with the periodicity 
   2001 ;   resembling that of the desired sine value.
   2002 ;   The result lies in the range -1 to +1.              
   2003 ;
   2004 ;                       90 deg.
   2005 ; 
   2006 ;                       (pi/2)
   2007 ;                II       +1        I
   2008 ;                         |
   2009 ;<font color=#339933>          sin+      |\   |   /|    sin+</font>
   2010 ;<font color=#339933>          cos-      | \  |  / |    cos+</font>
   2011 ;<font color=#339933>          tan-      |  \ | /  |    tan+</font>
   2012 ;<font color=#339933>                    |   \|/)  |           </font>
   2013 ;<font color=#339933>   180 deg. (pi) 0 -|----+----|-- 0  (0)   0 degrees</font>
   2014 ;<font color=#339933>                    |   /|\   |</font>
   2015 ;<font color=#339933>          sin-      |  / | \  |    sin-</font>
   2016 ;<font color=#339933>          cos-      | /  |  \ |    cos+</font>
   2017 ;<font color=#339933>          tan+      |/   |   \|    tan-</font>
   2018 ;<font color=#339933>                         |</font>
   2019 ;<font color=#339933>                III      -1       IV</font>
   2020 ;<font color=#339933>                       (3pi/2)</font>
   2021 ;<font color=#339933></font>
   2022 ;                       270 deg.
   2023 
   2024 
   2025 <a name="get_argt"></a><b>get_argt</b>  RST   28H             ;; FP-CALC         X.
   2026           DEFB  $30             ;;stk-data
   2027           DEFB  $EE             ;;Exponent: $7E, 
   2028                                 ;;Bytes: 4
   2029           DEFB  $22,$F9,$83,$6E ;;                 X, 1/(2*PI)             
   2030           DEFB  $04             ;;multiply         X/(2*PI) = fraction
   2031 
   2032           DEFB  $2D             ;;duplicate             
   2033           DEFB  $A2             ;;stk-half
   2034           DEFB  $0F             ;;addition
   2035           DEFB  $24             ;;int
   2036 
   2037           DEFB  $03             ;;subtract         now range -.5 to .5
   2038 
   2039           DEFB  $2D             ;;duplicate
   2040           DEFB  $0F             ;;addition         now range -1 to 1.
   2041           DEFB  $2D             ;;duplicate
   2042           DEFB  $0F             ;;addition         now range -2 to 2.
   2043 
   2044 ;   quadrant I (0 to +1) and quadrant IV (-1 to 0) are now correct.
   2045 ;   quadrant II ranges +1 to +2.
   2046 ;   quadrant III ranges -2 to -1.
   2047 
   2048           DEFB  $2D             ;;duplicate        Y, Y.
   2049           DEFB  $27             ;;abs              Y, abs(Y).    range 1 to 2
   2050           DEFB  $A1             ;;stk-one          Y, abs(Y), 1.
   2051           DEFB  $03             ;;subtract         Y, abs(Y)-1.  range 0 to 1
   2052           DEFB  $2D             ;;duplicate        Y, Z, Z.
   2053           DEFB  $33             ;;greater-0        Y, Z, (1/0).
   2054 
   2055           DEFB  $C0             ;;st-mem-0         store as possible sign 
   2056                                 ;;                 for cosine function.
   2057 
   2058           DEFB  $00             ;;jump-true
   2059           DEFB  $04             ;;to L1D35, ZPLUS  with quadrants II and III
   2060 
   2061 ;   else the angle lies in quadrant I or IV and value Y is already correct.
   2062 
   2063           DEFB  $02             ;;delete          Y    delete test value.
   2064           DEFB  $34             ;;end-calc        Y.
   2065 
   2066           RET                   ; return.         with Q1 and Q4 &gt;&gt;&gt;
   2067 
   2068 ;   The branch was here with quadrants II (0 to 1) and III (1 to 0).
   2069 ;   Y will hold -2 to -1 if this is quadrant III.
   2070 
   2071 <a name="ZPLUS"></a><b>ZPLUS</b>     DEFB  $A1             ;;stk-one         Y, Z, 1
   2072           DEFB  $03             ;;subtract        Y, Z-1.       Q3 = 0 to -1
   2073           DEFB  $01             ;;exchange        Z-1, Y.
   2074           DEFB  $32             ;;less-0          Z-1, (1/0).
   2075           DEFB  $00             ;;jump-true       Z-1.
   2076           DEFB  $02             ;;to L1D3C, YNEG
   2077                                 ;;if angle in quadrant III
   2078 
   2079 ;   else angle is within quadrant II (-1 to 0)
   2080 
   2081           DEFB  $18             ;;negate          range +1 to 0
   2082 
   2083 
   2084 <a name="YNEG"></a><b>YNEG</b>      DEFB  $34             ;;end-calc        quadrants II and III correct.
   2085 
   2086           RET                   ; return.
   2087 
   2088 
   2089 ; ---------------------
   2090 ; THE <b><font color=#333388>'COSINE'</font></b> FUNCTION
   2091 ; ---------------------
   2092 ; <font color=#339933>(offset $1D: 'cos')</font>
   2093 ;   Cosines are calculated as the sine of the opposite angle rectifying the 
   2094 ;   sign depending on the quadrant rules. 
   2095 ;
   2096 ;
   2097 ;<font color=#339933>             /|</font>
   2098 ;<font color=#339933>          h /y|</font>
   2099 ;<font color=#339933>           /  |o</font>
   2100 ;<font color=#339933>          /x  |</font>
   2101 ;<font color=#339933>         /----|    </font>
   2102 ;<font color=#339933>           a</font>
   2103 ;<font color=#339933></font>
   2104 ;   The cosine of angle x is the adjacent side (a) divided by the hypotenuse 1.
   2105 ;   However if we examine angle y then a/h is the sine of that angle.
   2106 ;   Since angle x plus angle y equals a right-angle, we can find angle y by 
   2107 ;   subtracting angle x from pi/2.
   2108 ;   However it's just as easy to reduce the argument first and subtract the
   2109 ;   reduced argument from the value 1 (a reduced right-angle).
   2110 ;   It's even easier to subtract 1 from the angle and rectify the sign.
   2111 ;   In fact, after reducing the argument, the absolute value of the argument
   2112 ;   is used and rectified using the test result stored in mem-0 by 'get-argt'
   2113 ;   for that purpose.
   2114 
   2115 <a name="cos"></a><b>cos</b>       RST   28H             ;; FP-CALC              angle in radians.
   2116           DEFB  $35             ;;get-argt              X       reduce -1 to +1
   2117 
   2118           DEFB  $27             ;;abs                   ABS X   0 to 1
   2119           DEFB  $A1             ;;stk-one               ABS X, 1.
   2120           DEFB  $03             ;;subtract              now opposite angle 
   2121                                 ;;                      though negative sign.
   2122           DEFB  $E0             ;;get-mem-0             fetch sign indicator.
   2123           DEFB  $00             ;;jump-true
   2124           DEFB  $06             ;;fwd to L1D4B, C-ENT
   2125                                 ;;forward to common code if in QII or QIII 
   2126 
   2127 
   2128           DEFB  $18             ;;negate                else make positive.
   2129           DEFB  $2F             ;;jump
   2130           DEFB  $03             ;;fwd to L1D4B, C-ENT
   2131                                 ;;with quadrants QI and QIV 
   2132 
   2133 ; -------------------
   2134 ; THE <b><font color=#333388>'SINE'</font></b> FUNCTION
   2135 ; -------------------
   2136 ; <font color=#339933>(offset $1C: 'sin')</font>
   2137 ;   This is a fundamental transcendental function from which others such as cos
   2138 ;   and tan are directly, or indirectly, derived.
   2139 ;   It uses the series generator to produce Chebyshev polynomials.
   2140 ;
   2141 ;
   2142 ;<font color=#339933>             /|</font>
   2143 ;<font color=#339933>          1 / |</font>
   2144 ;<font color=#339933>           /  |x</font>
   2145 ;<font color=#339933>          /a  |</font>
   2146 ;<font color=#339933>         /----|    </font>
   2147 ;<font color=#339933>           y</font>
   2148 ;<font color=#339933></font>
   2149 ;   The 'get-argt' function is designed to modify the angle and its sign 
   2150 ;   in line with the desired sine value and afterwards it can launch straight
   2151 ;   into common code.
   2152 
   2153 <a name="sin"></a><b>sin</b>       RST   28H             ;; FP-CALC      angle in radians
   2154           DEFB  $35             ;;get-argt      reduce - sign now correct.
   2155 
   2156 <a name="C_ENT"></a><b>C_ENT</b>     DEFB  $2D             ;;duplicate
   2157           DEFB  $2D             ;;duplicate
   2158           DEFB  $04             ;;multiply
   2159           DEFB  $2D             ;;duplicate
   2160           DEFB  $0F             ;;addition
   2161           DEFB  $A1             ;;stk-one
   2162           DEFB  $03             ;;subtract
   2163 
   2164           DEFB  $86             ;;series-06
   2165           DEFB  $14             ;;Exponent: $64, Bytes: 1
   2166           DEFB  $E6             ;;(+00,+00,+00)
   2167           DEFB  $5C             ;;Exponent: $6C, Bytes: 2
   2168           DEFB  $1F,$0B         ;;(+00,+00)
   2169           DEFB  $A3             ;;Exponent: $73, Bytes: 3
   2170           DEFB  $8F,$38,$EE     ;;(+00)
   2171           DEFB  $E9             ;;Exponent: $79, Bytes: 4
   2172           DEFB  $15,$63,$BB,$23 ;;
   2173           DEFB  $EE             ;;Exponent: $7E, Bytes: 4
   2174           DEFB  $92,$0D,$CD,$ED ;;
   2175           DEFB  $F1             ;;Exponent: $81, Bytes: 4
   2176           DEFB  $23,$5D,$1B,$EA ;;
   2177 
   2178           DEFB  $04             ;;multiply
   2179           DEFB  $34             ;;end-calc
   2180 
   2181           RET                   ; return.
   2182 
   2183 
   2184 ; ----------------------
   2185 ; THE <b><font color=#333388>'TANGENT'</font></b> FUNCTION
   2186 ; ----------------------
   2187 ; <font color=#339933>(offset $1E: 'tan')</font>
   2188 ;
   2189 ;   Evaluates tangent x as    sin(x) / cos(x).
   2190 ;
   2191 ;
   2192 ;<font color=#339933>             /|</font>
   2193 ;<font color=#339933>          h / |</font>
   2194 ;<font color=#339933>           /  |o</font>
   2195 ;<font color=#339933>          /x  |</font>
   2196 ;<font color=#339933>         /----|    </font>
   2197 ;<font color=#339933>           a</font>
   2198 ;<font color=#339933></font>
   2199 ;   The tangent of angle x is the ratio of the length of the opposite side 
   2200 ;   divided by the length of the adjacent side.  As the opposite length can 
   2201 ;   be calculates using sin(x) and the adjacent length using cos(x) then 
   2202 ;   the tangent can be defined in terms of the previous two functions.
   2203 
   2204 ;   Error 6 if the argument, in radians, is too close to one like pi/2
   2205 ;   which has an infinite tangent. e.g. PRINT TAN (PI/2)  evaluates as 1/0.
   2206 ;   Similarly PRINT TAN (3*PI/2), TAN (5*PI/2) etc.
   2207 
   2208 <a name="tan"></a><b>tan</b>       RST   28H             ;; FP-CALC          x.
   2209           DEFB  $2D             ;;duplicate         x, x.
   2210           DEFB  $1C             ;;sin               x, sin x.
   2211           DEFB  $01             ;;exchange          sin x, x.
   2212           DEFB  $1D             ;;cos               sin x, cos x.
   2213           DEFB  $05             ;;division          sin x/cos x (= tan x).
   2214           DEFB  $34             ;;end-calc          tan x.
   2215 
   2216           RET                   ; return.
   2217 
   2218 ; ---------------------
   2219 ; THE <b><font color=#333388>'ARCTAN'</font></b> FUNCTION
   2220 ; ---------------------
   2221 ; <font color=#339933>(Offset $21: 'atn')</font>
   2222 ;   The inverse tangent function with the result in radians.
   2223 ;   This is a fundamental transcendental function from which others such as asn
   2224 ;   and acs are directly, or indirectly, derived.
   2225 ;   It uses the series generator to produce Chebyshev polynomials.
   2226 
   2227 <a name="atn"></a><b>atn</b>       LD    A,(HL)          ; fetch exponent
   2228           CP    $81             ; compare to that for 'one'
   2229           JR    C,<A href="#SMALL">SMALL</a>         ; forward, if less, to SMALL
   2230 
   2231           RST   28H             ;; FP-CALC      X.
   2232           DEFB  $A1             ;;stk-one
   2233           DEFB  $18             ;;negate
   2234           DEFB  $01             ;;exchange
   2235           DEFB  $05             ;;division
   2236           DEFB  $2D             ;;duplicate
   2237           DEFB  $32             ;;less-0
   2238           DEFB  $A3             ;;stk-pi/2
   2239           DEFB  $01             ;;exchange
   2240           DEFB  $00             ;;jump-true
   2241           DEFB  $06             ;;to L1D8B, CASES
   2242 
   2243           DEFB  $18             ;;negate
   2244           DEFB  $2F             ;;jump
   2245           DEFB  $03             ;;to L1D8B, CASES
   2246 
   2247 ; ---
   2248 
   2249 <a name="SMALL"></a><b>SMALL</b>     RST   28H             ;; FP-CALC
   2250           DEFB  $A0             ;;stk-zero
   2251 
   2252 <a name="CASES"></a><b>CASES</b>     DEFB  $01             ;;exchange
   2253           DEFB  $2D             ;;duplicate
   2254           DEFB  $2D             ;;duplicate
   2255           DEFB  $04             ;;multiply
   2256           DEFB  $2D             ;;duplicate
   2257           DEFB  $0F             ;;addition
   2258           DEFB  $A1             ;;stk-one
   2259           DEFB  $03             ;;subtract
   2260 
   2261           DEFB  $8C             ;;series-0C
   2262           DEFB  $10             ;;Exponent: $60, Bytes: 1
   2263           DEFB  $B2             ;;(+00,+00,+00)
   2264           DEFB  $13             ;;Exponent: $63, Bytes: 1
   2265           DEFB  $0E             ;;(+00,+00,+00)
   2266           DEFB  $55             ;;Exponent: $65, Bytes: 2
   2267           DEFB  $E4,$8D         ;;(+00,+00)
   2268           DEFB  $58             ;;Exponent: $68, Bytes: 2
   2269           DEFB  $39,$BC         ;;(+00,+00)
   2270           DEFB  $5B             ;;Exponent: $6B, Bytes: 2
   2271           DEFB  $98,$FD         ;;(+00,+00)
   2272           DEFB  $9E             ;;Exponent: $6E, Bytes: 3
   2273           DEFB  $00,$36,$75     ;;(+00)
   2274           DEFB  $A0             ;;Exponent: $70, Bytes: 3
   2275           DEFB  $DB,$E8,$B4     ;;(+00)
   2276           DEFB  $63             ;;Exponent: $73, Bytes: 2
   2277           DEFB  $42,$C4         ;;(+00,+00)
   2278           DEFB  $E6             ;;Exponent: $76, Bytes: 4
   2279           DEFB  $B5,$09,$36,$BE ;;
   2280           DEFB  $E9             ;;Exponent: $79, Bytes: 4
   2281           DEFB  $36,$73,$1B,$5D ;;
   2282           DEFB  $EC             ;;Exponent: $7C, Bytes: 4
   2283           DEFB  $D8,$DE,$63,$BE ;;
   2284           DEFB  $F0             ;;Exponent: $80, Bytes: 4
   2285           DEFB  $61,$A1,$B3,$0C ;;
   2286 
   2287           DEFB  $04             ;;multiply
   2288           DEFB  $0F             ;;addition
   2289           DEFB  $34             ;;end-calc
   2290 
   2291           RET                   ; return.
   2292 
   2293 
   2294 ; ---------------------
   2295 ; THE <b><font color=#333388>'ARCSIN'</font></b> FUNCTION
   2296 ; ---------------------
   2297 ; <font color=#339933>(Offset $1F: 'asn')</font>
   2298 ;   The inverse sine function with result in radians.
   2299 ;   Derived from arctan function above.
   2300 ;   Error A unless the argument is between -1 and +1 inclusive.
   2301 ;   Uses an adaptation of the formula asn(x) = atn(x/sqr(1-x*x))
   2302 ;
   2303 ;
   2304 ;<font color=#339933>                 /|</font>
   2305 ;<font color=#339933>                / |</font>
   2306 ;<font color=#339933>              1/  |x</font>
   2307 ;<font color=#339933>              /a  |</font>
   2308 ;<font color=#339933>             /----|    </font>
   2309 ;<font color=#339933>               y</font>
   2310 ;<font color=#339933></font>
   2311 ;   e.g. We know the opposite side (x) and hypotenuse (1) 
   2312 ;   and we wish to find angle a in radians.
   2313 ;   We can derive length y by Pythagoras and then use ATN instead. 
   2314 ;   Since y*y + x*x = 1*1 (Pythagoras Theorem) then
   2315 ;   y=sqr(1-x*x)                         - no need to multiply 1 by itself.
   2316 ;   So, asn(a) = atn(x/y)
   2317 ;   or more fully,
   2318 ;   asn(a) = atn(x/sqr(1-x*x))
   2319 
   2320 ;   Close but no cigar.
   2321 
   2322 ;   While PRINT ATN (x/SQR (1-x*x)) gives the same results as PRINT ASN x,
   2323 ;   it leads to division by zero when x is 1 or -1.
   2324 ;   To overcome this, 1 is added to y giving half the required angle and the 
   2325 ;   result is then doubled. 
   2326 ;   That is, PRINT ATN (x/(SQR (1-x*x) +1)) *2
   2327 ;
   2328 ;
   2329 ;<font color=#339933>               . /|</font>
   2330 ;<font color=#339933>            .  c/ |</font>
   2331 ;<font color=#339933>         .     /1 |x</font>
   2332 ;<font color=#339933>      . c   b /a  |</font>
   2333 ;<font color=#339933>    ---------/----|    </font>
   2334 ;<font color=#339933>      1      y</font>
   2335 ;<font color=#339933></font>
   2336 ;   By creating an isosceles triangle with two equal sides of 1, angles c and 
   2337 ;   c are also equal. If b+c+c = 180 degrees and b+a = 180 degress then c=a/2.
   2338 ;
   2339 ;   A value higher than 1 gives the required error as attempting to find  the
   2340 ;   square root of a negative number generates an error in Sinclair BASIC.
   2341 
   2342 <a name="asn"></a><b>asn</b>       RST   28H             ;; FP-CALC      x.
   2343           DEFB  $2D             ;;duplicate     x, x.
   2344           DEFB  $2D             ;;duplicate     x, x, x.
   2345           DEFB  $04             ;;multiply      x, x*x.
   2346           DEFB  $A1             ;;stk-one       x, x*x, 1.
   2347           DEFB  $03             ;;subtract      x, x*x-1.
   2348           DEFB  $18             ;;negate        x, 1-x*x.
   2349           DEFB  $25             ;;sqr           x, sqr(1-x*x) = y.
   2350           DEFB  $A1             ;;stk-one       x, y, 1.
   2351           DEFB  $0F             ;;addition      x, y+1.
   2352           DEFB  $05             ;;division      x/y+1.
   2353           DEFB  $21             ;;atn           a/2     (half the angle)
   2354           DEFB  $2D             ;;duplicate     a/2, a/2.
   2355           DEFB  $0F             ;;addition      a.
   2356           DEFB  $34             ;;end-calc      a.
   2357 
   2358           RET                   ; return.
   2359 
   2360 
   2361 ; ------------------------
   2362 ; THE <b><font color=#333388>'ARCCOS'</font></b> FUNCTION
   2363 ; ------------------------
   2364 ; <font color=#339933>(Offset $20: 'acs')</font>
   2365 ; the inverse cosine function with the result in radians.
   2366 ; Error A unless the argument is between -1 and +1.
   2367 ; Result in range 0 to pi.
   2368 ; Derived from asn above which is in turn derived from the preceding atn.
   2369 ; It could have been derived directly from atn using acs(x) = atn(sqr(1-x*x)/x).
   2370 ; However, as sine and cosine are horizontal translations of each other,
   2371 ; uses acs(x) = pi/2 - asn(x)
   2372 
   2373 ; e.g. the arccosine of a known x value will give the required angle b in 
   2374 ; radians.
   2375 ; We know, from above, how to calculate the angle a using asn(x). 
   2376 ; Since the three angles of any triangle add up to 180 degrees, or pi radians,
   2377 ; and the largest angle in this case is a right-angle (pi/2 radians), then
   2378 ; we can calculate angle b as pi/2 (both angles) minus asn(x) (angle a).
   2379 ; 
   2380 ;
   2381 ;<font color=#339933>           /|</font>
   2382 ;<font color=#339933>        1 /b|</font>
   2383 ;<font color=#339933>         /  |x</font>
   2384 ;<font color=#339933>        /a  |</font>
   2385 ;<font color=#339933>       /----|    </font>
   2386 ;<font color=#339933>         y</font>
   2387 ;<font color=#339933></font>
   2388 
   2389 <a name="acs"></a><b>acs</b>       RST   28H             ;; FP-CALC      x.
   2390           DEFB  $1F             ;;asn           asn(x).
   2391           DEFB  $A3             ;;stk-pi/2      asn(x), pi/2.
   2392           DEFB  $03             ;;subtract      asn(x) - pi/2.
   2393           DEFB  $18             ;;negate        pi/2 - asn(x) = acs(x).
   2394           DEFB  $34             ;;end-calc      acs(x)
   2395 
   2396           RET                   ; return.
   2397 
   2398 
   2399 ; --------------------------
   2400 ; THE OLD <b><font color=#333388>'SQUARE ROOT'</font></b> FUNCTION
   2401 ; --------------------------
   2402 ; <font color=#339933>(Offset $25: 'sqr')</font>
   2403 ; Error A if argument is negative.
   2404 ; This routine is remarkable for its brevity - 7 bytes.
   2405 ; This routine uses Napier's method for calculating square roots which was 
   2406 ; devised in 1614 and calculates the value as EXP (LN 'x' * 0.5).
   2407 ;
   2408 ; This is a little on the slow side as it involves two polynomial series.
   2409 ; A series of 12 for LN and a series of 8 for EXP.  This was of no concern
   2410 ; to John Napier since his tables were 'compiled forever'.
   2411 ;
   2412 <font color=#FF3333>;;; L1DDB:  RST     28H             ;; FP-CALC              x.</font>
   2413 <font color=#FF3333>;;;         DEFB    $2D             ;;duplicate             x, x.</font>
   2414 <font color=#FF3333>;;;         DEFB    $2C             ;;not                   x, 1/0</font>
   2415 <font color=#FF3333>;;;         DEFB    $00             ;;jump-true             x, (1/0).</font>
   2416 <font color=#FF3333>;;;         DEFB    $1E             ;;to L1DFD, LAST        exit if argument zero</font>
   2417 <font color=#FF3333>;;;                                 ;;                      with zero result.</font>
   2418 ;;;
   2419 <font color=#FF3333>;;; else continue to calculate as x ** .5</font>
   2420 ;;;
   2421 <font color=#FF3333>;;;         DEFB    $A2             ;;stk-half              x, .5.</font>
   2422 <font color=#FF3333>;;;         DEFB    $34             ;;end-calc              x, .5.</font>
   2423 
   2424 
   2425 ; ------------------------
   2426 ; THE <b><font color=#333388>'TO POWER'</font></b> OPERATION
   2427 ; ------------------------
   2428 ; <font color=#339933>(Offset $06: 'to-power')</font>
   2429 ;   The 'Exponential' operation.
   2430 ;   This raises the first number X to the power of the second number Y.
   2431 ;   e.g. PRINT 2 ** 3 gives the result 8
   2432 ;   As with the ZX80,
   2433 ;   0 ** 0 = 1
   2434 ;   0 ** +n = 0
   2435 ;   0 ** -n = arithmetic overflow.
   2436 
   2437 <a name="to_power"></a><b>to_power</b>  RST   28H             ;; FP-CALC              X,Y.
   2438           DEFB  $01             ;;exchange              Y,X.
   2439           DEFB  $2D             ;;duplicate             Y,X,X.
   2440           DEFB  $2C             ;;not                   Y,X,(1/0).
   2441           DEFB  $00             ;;jump-true
   2442           DEFB  $07             ;;forward to L1DEE, XISO if X is zero.
   2443 
   2444 ;   else X is non-zero. function 'ln' will catch a negative value of X.
   2445 
   2446           DEFB  $22             ;;ln                    Y, LN X.
   2447 
   2448 ;   Multiply the power by the logarithm of the argument.
   2449 
   2450           DEFB  $04             ;;multiply              Y * LN X
   2451           DEFB  $34             ;;end-calc
   2452 
   2453           JP    exp             ; jump back to EXP routine             -&gt;&gt; 
   2454 				; to find the 'antiln'
   2455 
   2456 ; ---
   2457 
   2458 ;   these routines form the three simple results when the number is zero.
   2459 ;   begin by deleting the known zero to leave Y the power factor.
   2460 
   2461 <a name="XISO"></a><b>XISO</b>      DEFB  $02             ;;delete                Y.
   2462           DEFB  $2D             ;;duplicate             Y, Y.
   2463           DEFB  $2C             ;;not                   Y, (1/0).
   2464           DEFB  $00             ;;jump-true     
   2465           DEFB  $09             ;;forward to L1DFB, ONE if Y is zero.
   2466 
   2467 ;   the power factor is not zero. If negative then an error exists.
   2468 
   2469           DEFB  $A0             ;;stk-zero              Y, 0.
   2470           DEFB  $01             ;;exchange              0, Y.
   2471           DEFB  $33             ;;greater-0             0, (1/0).
   2472           DEFB  $00             ;;jump-true             0
   2473           DEFB  $06             ;;to L1DFD, LAST        if Y was any positive 
   2474                                 ;;                      number.
   2475 
   2476 ;   else force division by zero thereby raising an Arithmetic overflow error.
   2477 ;   As an alternative, this now raises an error directly.
   2478 
   2479 <font color=#FF3333>;;;       DEFB  $A1             ;;stk-one               0, 1.</font>
   2480 <font color=#FF3333>;;;       DEFB  $01             ;;exchange              1, 0.</font>
   2481 <font color=#FF3333>;;;       DEFB  $05             ;;division              1/0    &gt;&gt; error </font>
   2482 
   2483  <font color=#3333FF>         DEFB  $34             ;+ end-calc</font>
   2484 <a name="REPORT_6c"></a><b>REPORT_6c</b> <font color=#3333FF>RST   08H             ;+ ERROR-1</font>
   2485  <font color=#3333FF>         DEFB  $05             ;+ Error Report: Number too big</font>
   2486 
   2487 ; ---
   2488 
   2489 <a name="ONE"></a><b>ONE</b>       DEFB  $02             ;;delete                .
   2490           DEFB  $A1             ;;stk-one               1.
   2491 
   2492 <a name="LAST"></a><b>LAST</b>      DEFB  $34             ;;end-calc              last value 1 or 0.
   2493 
   2494           RET                   ; return.
   2495 
   2496 ; ---------------------
   2497 ; THE <b><font color=#333388>'SPARE LOCATIONS'</font></b>
   2498 ; ---------------------
   2499 
   2500 <a name="L1DFE:"></a><b>L1DFE:</b>
   2501 
   2502           DEFB  $FF, $FF	; Two spare bytes.
   2503 
   2504 
   2505 <a name="ORG"></a><b>ORG</b>    $1E00
   2506 
   2507 ; ------------------------
   2508 ; THE <b><font color=#333388>'ZX81 CHARACTER SET'</font></b>
   2509 ; ------------------------
   2510 
   2511 
   2512 ; $00 - <b>Character: ' '          </b>CHR$(0)
   2513 
   2514 <a name="char_set"></a><b>char_set</b>  DEFB  %00000000
   2515           DEFB  %00000000
   2516           DEFB  %00000000
   2517           DEFB  %00000000
   2518           DEFB  %00000000
   2519           DEFB  %00000000
   2520           DEFB  %00000000
   2521           DEFB  %00000000
   2522 
   2523 ; $01 - <b>Character: mosaic       </b>CHR$(1)
   2524 
   2525           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2526           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2527           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2528           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2529           DEFB  %00000000
   2530           DEFB  %00000000
   2531           DEFB  %00000000
   2532           DEFB  %00000000
   2533 
   2534 
   2535 ; $02 - <b>Character: mosaic       </b>CHR$(2)
   2536 
   2537           DEFB  %0000<B>1</B><B>1</B><B>1</B><B>1</B>
   2538           DEFB  %0000<B>1</B><B>1</B><B>1</B><B>1</B>
   2539           DEFB  %0000<B>1</B><B>1</B><B>1</B><B>1</B>
   2540           DEFB  %0000<B>1</B><B>1</B><B>1</B><B>1</B>
   2541           DEFB  %00000000
   2542           DEFB  %00000000
   2543           DEFB  %00000000
   2544           DEFB  %00000000
   2545 
   2546 
   2547 ; $03 - <b>Character: mosaic       </b>CHR$(3)
   2548 
   2549           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>
   2550           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>
   2551           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>
   2552           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>
   2553           DEFB  %00000000
   2554           DEFB  %00000000
   2555           DEFB  %00000000
   2556           DEFB  %00000000
   2557 
   2558 ; $04 - <b>Character: mosaic       </b>CHR$(4)
   2559 
   2560           DEFB  %00000000
   2561           DEFB  %00000000
   2562           DEFB  %00000000
   2563           DEFB  %00000000
   2564           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2565           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2566           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2567           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2568 
   2569 ; $05 - <b>Character: mosaic       </b>CHR$(1)
   2570 
   2571           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2572           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2573           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2574           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2575           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2576           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2577           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2578           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2579 
   2580 ; $06 - <b>Character: mosaic       </b>CHR$(1)
   2581 
   2582           DEFB  %0000<B>1</B><B>1</B><B>1</B><B>1</B>
   2583           DEFB  %0000<B>1</B><B>1</B><B>1</B><B>1</B>
   2584           DEFB  %0000<B>1</B><B>1</B><B>1</B><B>1</B>
   2585           DEFB  %0000<B>1</B><B>1</B><B>1</B><B>1</B>
   2586           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2587           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2588           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2589           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2590 
   2591 ; $07 - <b>Character: mosaic       </b>CHR$(1)
   2592 
   2593           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>
   2594           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>
   2595           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>
   2596           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>
   2597           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2598           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2599           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2600           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B>0000
   2601 
   2602 ; $08 - <b>Character: mosaic       </b>CHR$(1)
   2603 
   2604           DEFB  %<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>0
   2605           DEFB  %0<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>
   2606           DEFB  %<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>0
   2607           DEFB  %0<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>
   2608           DEFB  %<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>0
   2609           DEFB  %0<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>
   2610           DEFB  %<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>0
   2611           DEFB  %0<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>
   2612 
   2613 ; $09 - <b>Character: mosaic       </b>CHR$(1)
   2614 
   2615           DEFB  %00000000
   2616           DEFB  %00000000
   2617           DEFB  %00000000
   2618           DEFB  %00000000
   2619           DEFB  %<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>0
   2620           DEFB  %0<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>
   2621           DEFB  %<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>0
   2622           DEFB  %0<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>
   2623 
   2624 ; $0A - <b>Character: mosaic       </b>CHR$(10)
   2625 
   2626           DEFB  %<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>0
   2627           DEFB  %0<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>
   2628           DEFB  %<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>0
   2629           DEFB  %0<B>1</B>0<B>1</B>0<B>1</B>0<B>1</B>
   2630           DEFB  %00000000
   2631           DEFB  %00000000
   2632           DEFB  %00000000
   2633           DEFB  %00000000
   2634 
   2635 ; $0B - <b>Character: '"'          </b>CHR$(11)
   2636 
   2637           DEFB  %00000000
   2638           DEFB  %00<B>1</B>00<B>1</B>00
   2639           DEFB  %00<B>1</B>00<B>1</B>00
   2640           DEFB  %00000000
   2641           DEFB  %00000000
   2642           DEFB  %00000000
   2643           DEFB  %00000000
   2644           DEFB  %00000000
   2645 
   2646 ; $0B - <b>Character: 'œ'          </b>CHR$(12)
   2647 
   2648           DEFB  %00000000
   2649           DEFB  %000<B>1</B><B>1</B><B>1</B>00
   2650           DEFB  %00<B>1</B>000<B>1</B>0
   2651           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B>000
   2652           DEFB  %00<B>1</B>00000
   2653           DEFB  %00<B>1</B>00000
   2654           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2655           DEFB  %00000000
   2656 
   2657 ; $0B - <b>Character: '$'          </b>CHR$(13)
   2658 
   2659           DEFB  %00000000
   2660           DEFB  %0000<B>1</B>000
   2661           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2662           DEFB  %00<B>1</B>0<B>1</B>000
   2663           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2664           DEFB  %0000<B>1</B>0<B>1</B>0
   2665           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2666           DEFB  %0000<B>1</B>000
   2667 
   2668 ; $0B - <b>Character: ':'          </b>CHR$(14)
   2669 
   2670           DEFB  %00000000
   2671           DEFB  %00000000
   2672           DEFB  %00000000
   2673           DEFB  %000<B>1</B>0000
   2674           DEFB  %00000000
   2675           DEFB  %00000000
   2676           DEFB  %000<B>1</B>0000
   2677           DEFB  %00000000
   2678 
   2679 ; $0B - <b>Character: '?'          </b>CHR$(15)
   2680 
   2681           DEFB  %00000000
   2682           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2683           DEFB  %0<B>1</B>0000<B>1</B>0
   2684           DEFB  %00000<B>1</B>00
   2685           DEFB  %0000<B>1</B>000
   2686           DEFB  %00000000
   2687           DEFB  %0000<B>1</B>000
   2688           DEFB  %00000000
   2689 
   2690 ; $10 - <b>Character: '('          </b>CHR$(16)
   2691 
   2692           DEFB  %00000000
   2693           DEFB  %00000<B>1</B>00
   2694           DEFB  %0000<B>1</B>000
   2695           DEFB  %0000<B>1</B>000
   2696           DEFB  %0000<B>1</B>000
   2697           DEFB  %0000<B>1</B>000
   2698           DEFB  %00000<B>1</B>00
   2699           DEFB  %00000000
   2700 
   2701 ; $11 - <b>Character: ')'          </b>CHR$(17)
   2702 
   2703           DEFB  %00000000
   2704           DEFB  %00<B>1</B>00000
   2705           DEFB  %000<B>1</B>0000
   2706           DEFB  %000<B>1</B>0000
   2707           DEFB  %000<B>1</B>0000
   2708           DEFB  %000<B>1</B>0000
   2709           DEFB  %00<B>1</B>00000
   2710           DEFB  %00000000
   2711 
   2712 ; $12 - <b>Character: '&gt;'          </b>CHR$(18)
   2713 
   2714           DEFB  %00000000
   2715           DEFB  %00000000
   2716           DEFB  %000<B>1</B>0000
   2717           DEFB  %0000<B>1</B>000
   2718           DEFB  %00000<B>1</B>00
   2719           DEFB  %0000<B>1</B>000
   2720           DEFB  %000<B>1</B>0000
   2721           DEFB  %00000000
   2722 
   2723 ; $13 - <b>Character: '&lt;'          </b>CHR$(19)
   2724 
   2725           DEFB  %00000000
   2726           DEFB  %00000000
   2727           DEFB  %00000<B>1</B>00
   2728           DEFB  %0000<B>1</B>000
   2729           DEFB  %000<B>1</B>0000
   2730           DEFB  %0000<B>1</B>000
   2731           DEFB  %00000<B>1</B>00
   2732           DEFB  %00000000
   2733 
   2734 ; $14 - <b>Character: '='          </b>CHR$(20)
   2735 
   2736           DEFB  %00000000
   2737           DEFB  %00000000
   2738           DEFB  %00000000
   2739           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2740           DEFB  %00000000
   2741           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2742           DEFB  %00000000
   2743           DEFB  %00000000
   2744 
   2745 ; $15 - <b>Character: '+'          </b>CHR$(21)
   2746 
   2747           DEFB  %00000000
   2748           DEFB  %00000000
   2749           DEFB  %0000<B>1</B>000
   2750           DEFB  %0000<B>1</B>000
   2751           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2752           DEFB  %0000<B>1</B>000
   2753           DEFB  %0000<B>1</B>000
   2754           DEFB  %00000000
   2755 
   2756 ; $16 - <b>Character: '-'          </b>CHR$(22)
   2757 
   2758           DEFB  %00000000
   2759           DEFB  %00000000
   2760           DEFB  %00000000
   2761           DEFB  %00000000
   2762           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2763           DEFB  %00000000
   2764           DEFB  %00000000
   2765           DEFB  %00000000
   2766 
   2767 ; $17 - <b>Character: '*'          </b>CHR$(23)
   2768 
   2769           DEFB  %00000000
   2770           DEFB  %00000000
   2771           DEFB  %000<B>1</B>0<B>1</B>00
   2772           DEFB  %0000<B>1</B>000
   2773           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2774           DEFB  %0000<B>1</B>000
   2775           DEFB  %000<B>1</B>0<B>1</B>00
   2776           DEFB  %00000000
   2777 
   2778 ; $18 - <b>Character: '/'          </b>CHR$(24)
   2779 
   2780           DEFB  %00000000
   2781           DEFB  %00000000
   2782           DEFB  %000000<B>1</B>0
   2783           DEFB  %00000<B>1</B>00
   2784           DEFB  %0000<B>1</B>000
   2785           DEFB  %000<B>1</B>0000
   2786           DEFB  %00<B>1</B>00000
   2787           DEFB  %00000000
   2788 
   2789 ; $19 - <b>Character: ';'          </b>CHR$(25)
   2790 
   2791           DEFB  %00000000
   2792           DEFB  %00000000
   2793           DEFB  %000<B>1</B>0000
   2794           DEFB  %00000000
   2795           DEFB  %00000000
   2796           DEFB  %000<B>1</B>0000
   2797           DEFB  %000<B>1</B>0000
   2798           DEFB  %00<B>1</B>00000
   2799 
   2800 ; $1A - <b>Character: ','          </b>CHR$(26)
   2801 
   2802           DEFB  %00000000
   2803           DEFB  %00000000
   2804           DEFB  %00000000
   2805           DEFB  %00000000
   2806           DEFB  %00000000
   2807           DEFB  %0000<B>1</B>000
   2808           DEFB  %0000<B>1</B>000
   2809           DEFB  %000<B>1</B>0000
   2810 
   2811 ; $1B - <b>Character: '"'          </b>CHR$(27)
   2812 
   2813           DEFB  %00000000
   2814           DEFB  %00000000
   2815           DEFB  %00000000
   2816           DEFB  %00000000
   2817           DEFB  %00000000
   2818           DEFB  %000<B>1</B><B>1</B>000
   2819           DEFB  %000<B>1</B><B>1</B>000
   2820           DEFB  %00000000
   2821 
   2822 ; $1C - <b>Character: '0'          </b>CHR$(28)
   2823 
   2824           DEFB  %00000000
   2825           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2826           DEFB  %0<B>1</B>000<B>1</B><B>1</B>0
   2827           DEFB  %0<B>1</B>00<B>1</B>0<B>1</B>0
   2828           DEFB  %0<B>1</B>0<B>1</B>00<B>1</B>0
   2829           DEFB  %0<B>1</B><B>1</B>000<B>1</B>0
   2830           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2831           DEFB  %00000000
   2832 
   2833 ; $1D - <b>Character: '1'          </b>CHR$(29)
   2834 
   2835           DEFB  %00000000
   2836           DEFB  %000<B>1</B><B>1</B>000
   2837           DEFB  %00<B>1</B>0<B>1</B>000
   2838           DEFB  %0000<B>1</B>000
   2839           DEFB  %0000<B>1</B>000
   2840           DEFB  %0000<B>1</B>000
   2841           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2842           DEFB  %00000000
   2843 
   2844 ; $1E - <b>Character: '2'          </b>CHR$(30)
   2845 
   2846           DEFB  %00000000
   2847           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2848           DEFB  %0<B>1</B>0000<B>1</B>0
   2849           DEFB  %000000<B>1</B>0
   2850           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2851           DEFB  %0<B>1</B>000000
   2852           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2853           DEFB  %00000000
   2854 
   2855 ; $1F - <b>Character: '3'          </b>CHR$(31)
   2856 
   2857           DEFB  %00000000
   2858           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2859           DEFB  %0<B>1</B>0000<B>1</B>0
   2860           DEFB  %0000<B>1</B><B>1</B>00
   2861           DEFB  %000000<B>1</B>0
   2862           DEFB  %0<B>1</B>0000<B>1</B>0
   2863           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2864           DEFB  %00000000
   2865 
   2866 ; $20 - <b>Character: '4'          </b>CHR$(32)
   2867 
   2868           DEFB  %00000000
   2869           DEFB  %0000<B>1</B>000
   2870           DEFB  %000<B>1</B><B>1</B>000
   2871           DEFB  %00<B>1</B>0<B>1</B>000
   2872           DEFB  %0<B>1</B>00<B>1</B>000
   2873           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2874           DEFB  %0000<B>1</B>000
   2875           DEFB  %00000000
   2876 
   2877 ; $21 - <b>Character: '5'          </b>CHR$(33)
   2878 
   2879           DEFB  %00000000
   2880           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2881           DEFB  %0<B>1</B>000000
   2882           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   2883           DEFB  %000000<B>1</B>0
   2884           DEFB  %0<B>1</B>0000<B>1</B>0
   2885           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2886           DEFB  %00000000
   2887 
   2888 ; $22 - <b>Character: '6'          </b>CHR$(34)
   2889 
   2890           DEFB  %00000000
   2891           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2892           DEFB  %0<B>1</B>000000
   2893           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   2894           DEFB  %0<B>1</B>0000<B>1</B>0
   2895           DEFB  %0<B>1</B>0000<B>1</B>0
   2896           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2897           DEFB  %00000000
   2898 
   2899 ; $23 - <b>Character: '7'          </b>CHR$(35)
   2900 
   2901           DEFB  %00000000
   2902           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2903           DEFB  %000000<B>1</B>0
   2904           DEFB  %00000<B>1</B>00
   2905           DEFB  %0000<B>1</B>000
   2906           DEFB  %000<B>1</B>0000
   2907           DEFB  %000<B>1</B>0000
   2908           DEFB  %00000000
   2909 
   2910 ; $24 - <b>Character: '8'          </b>CHR$(36)
   2911 
   2912           DEFB  %00000000
   2913           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2914           DEFB  %0<B>1</B>0000<B>1</B>0
   2915           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2916           DEFB  %0<B>1</B>0000<B>1</B>0
   2917           DEFB  %0<B>1</B>0000<B>1</B>0
   2918           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2919           DEFB  %00000000
   2920 
   2921 ; $25 - <b>Character: '9'          </b>CHR$(37)
   2922 
   2923           DEFB  %00000000
   2924           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2925           DEFB  %0<B>1</B>0000<B>1</B>0
   2926           DEFB  %0<B>1</B>0000<B>1</B>0
   2927           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2928           DEFB  %000000<B>1</B>0
   2929           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2930           DEFB  %00000000
   2931 
   2932 ; $26 - <b>Character: 'A'          </b>CHR$(38)
   2933 
   2934           DEFB  %00000000
   2935           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2936           DEFB  %0<B>1</B>0000<B>1</B>0
   2937           DEFB  %0<B>1</B>0000<B>1</B>0
   2938           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2939           DEFB  %0<B>1</B>0000<B>1</B>0
   2940           DEFB  %0<B>1</B>0000<B>1</B>0
   2941           DEFB  %00000000
   2942 
   2943 ; $27 - <b>Character: 'B'          </b>CHR$(39)
   2944 
   2945           DEFB  %00000000
   2946           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   2947           DEFB  %0<B>1</B>0000<B>1</B>0
   2948           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   2949           DEFB  %0<B>1</B>0000<B>1</B>0
   2950           DEFB  %0<B>1</B>0000<B>1</B>0
   2951           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   2952           DEFB  %00000000
   2953 
   2954 ; $28 - <b>Character: 'C'          </b>CHR$(40)
   2955 
   2956           DEFB  %00000000
   2957           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2958           DEFB  %0<B>1</B>0000<B>1</B>0
   2959           DEFB  %0<B>1</B>000000
   2960           DEFB  %0<B>1</B>000000
   2961           DEFB  %0<B>1</B>0000<B>1</B>0
   2962           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   2963           DEFB  %00000000
   2964 
   2965 ; $29 - <b>Character: 'D'          </b>CHR$(41)
   2966 
   2967           DEFB  %00000000
   2968           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B>000
   2969           DEFB  %0<B>1</B>000<B>1</B>00
   2970           DEFB  %0<B>1</B>0000<B>1</B>0
   2971           DEFB  %0<B>1</B>0000<B>1</B>0
   2972           DEFB  %0<B>1</B>000<B>1</B>00
   2973           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B>000
   2974           DEFB  %00000000
   2975 
   2976 ; $2A - <b>Character: 'E'          </b>CHR$(42)
   2977 
   2978           DEFB  %00000000
   2979           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2980           DEFB  %0<B>1</B>000000
   2981           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   2982           DEFB  %0<B>1</B>000000
   2983           DEFB  %0<B>1</B>000000
   2984           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2985           DEFB  %00000000
   2986 
   2987 ; $2B - <b>Character: 'F'          </b>CHR$(43)
   2988 
   2989           DEFB  %00000000
   2990           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   2991           DEFB  %0<B>1</B>000000
   2992           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   2993           DEFB  %0<B>1</B>000000
   2994           DEFB  %0<B>1</B>000000
   2995           DEFB  %0<B>1</B>000000
   2996           DEFB  %00000000
   2997 
   2998 ; $2C - <b>Character: 'G'          </b>CHR$(44)
   2999 
   3000           DEFB  %00000000
   3001           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3002           DEFB  %0<B>1</B>0000<B>1</B>0
   3003           DEFB  %0<B>1</B>000000
   3004           DEFB  %0<B>1</B>00<B>1</B><B>1</B><B>1</B>0
   3005           DEFB  %0<B>1</B>0000<B>1</B>0
   3006           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3007           DEFB  %00000000
   3008 
   3009 ; $2D - <b>Character: 'H'          </b>CHR$(45)
   3010 
   3011           DEFB  %00000000
   3012           DEFB  %0<B>1</B>0000<B>1</B>0
   3013           DEFB  %0<B>1</B>0000<B>1</B>0
   3014           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   3015           DEFB  %0<B>1</B>0000<B>1</B>0
   3016           DEFB  %0<B>1</B>0000<B>1</B>0
   3017           DEFB  %0<B>1</B>0000<B>1</B>0
   3018           DEFB  %00000000
   3019 
   3020 ; $2E - <b>Character: 'I'          </b>CHR$(46)
   3021 
   3022           DEFB  %00000000
   3023           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   3024           DEFB  %0000<B>1</B>000
   3025           DEFB  %0000<B>1</B>000
   3026           DEFB  %0000<B>1</B>000
   3027           DEFB  %0000<B>1</B>000
   3028           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   3029           DEFB  %00000000
   3030 
   3031 ; $2F - <b>Character: 'J'          </b>CHR$(47)
   3032 
   3033           DEFB  %00000000
   3034           DEFB  %000000<B>1</B>0
   3035           DEFB  %000000<B>1</B>0
   3036           DEFB  %000000<B>1</B>0
   3037           DEFB  %0<B>1</B>0000<B>1</B>0
   3038           DEFB  %0<B>1</B>0000<B>1</B>0
   3039           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3040           DEFB  %00000000
   3041 
   3042 ; $30 - <b>Character: 'K'          </b>CHR$(48)
   3043 
   3044           DEFB  %00000000
   3045           DEFB  %0<B>1</B>000<B>1</B>00
   3046           DEFB  %0<B>1</B>00<B>1</B>000
   3047           DEFB  %0<B>1</B><B>1</B><B>1</B>0000
   3048           DEFB  %0<B>1</B>00<B>1</B>000
   3049           DEFB  %0<B>1</B>000<B>1</B>00
   3050           DEFB  %0<B>1</B>0000<B>1</B>0
   3051           DEFB  %00000000
   3052 
   3053 ; $31 - <b>Character: 'L'          </b>CHR$(49)
   3054 
   3055           DEFB  %00000000
   3056           DEFB  %0<B>1</B>000000
   3057           DEFB  %0<B>1</B>000000
   3058           DEFB  %0<B>1</B>000000
   3059           DEFB  %0<B>1</B>000000
   3060           DEFB  %0<B>1</B>000000
   3061           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   3062           DEFB  %00000000
   3063 
   3064 ; $32 - <b>Character: 'M'          </b>CHR$(50)
   3065 
   3066           DEFB  %00000000
   3067           DEFB  %0<B>1</B>0000<B>1</B>0
   3068           DEFB  %0<B>1</B><B>1</B>00<B>1</B><B>1</B>0
   3069           DEFB  %0<B>1</B>0<B>1</B><B>1</B>0<B>1</B>0
   3070           DEFB  %0<B>1</B>0000<B>1</B>0
   3071           DEFB  %0<B>1</B>0000<B>1</B>0
   3072           DEFB  %0<B>1</B>0000<B>1</B>0
   3073           DEFB  %00000000
   3074 
   3075 ; $33 - <b>Character: 'N'          </b>CHR$(51)
   3076 
   3077           DEFB  %00000000
   3078           DEFB  %0<B>1</B>0000<B>1</B>0
   3079           DEFB  %0<B>1</B><B>1</B>000<B>1</B>0
   3080           DEFB  %0<B>1</B>0<B>1</B>00<B>1</B>0
   3081           DEFB  %0<B>1</B>00<B>1</B>0<B>1</B>0
   3082           DEFB  %0<B>1</B>000<B>1</B><B>1</B>0
   3083           DEFB  %0<B>1</B>0000<B>1</B>0
   3084           DEFB  %00000000
   3085 
   3086 ; $34 - <b>Character: 'O'          </b>CHR$(52)
   3087 
   3088           DEFB  %00000000
   3089           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3090           DEFB  %0<B>1</B>0000<B>1</B>0
   3091           DEFB  %0<B>1</B>0000<B>1</B>0
   3092           DEFB  %0<B>1</B>0000<B>1</B>0
   3093           DEFB  %0<B>1</B>0000<B>1</B>0
   3094           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3095           DEFB  %00000000
   3096 
   3097 ; $35 - <b>Character: 'P'          </b>CHR$(53)
   3098 
   3099           DEFB  %00000000
   3100           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   3101           DEFB  %0<B>1</B>0000<B>1</B>0
   3102           DEFB  %0<B>1</B>0000<B>1</B>0
   3103           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   3104           DEFB  %0<B>1</B>000000
   3105           DEFB  %0<B>1</B>000000
   3106           DEFB  %00000000
   3107 
   3108 ; $36 - <b>Character: 'Q'          </b>CHR$(54)
   3109 
   3110           DEFB  %00000000
   3111           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3112           DEFB  %0<B>1</B>0000<B>1</B>0
   3113           DEFB  %0<B>1</B>0000<B>1</B>0
   3114           DEFB  %0<B>1</B>0<B>1</B>00<B>1</B>0
   3115           DEFB  %0<B>1</B>00<B>1</B>0<B>1</B>0
   3116           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3117           DEFB  %00000000
   3118 
   3119 ; $37 - <b>Character: 'R'          </b>CHR$(55)
   3120 
   3121           DEFB  %00000000
   3122           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   3123           DEFB  %0<B>1</B>0000<B>1</B>0
   3124           DEFB  %0<B>1</B>0000<B>1</B>0
   3125           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>00
   3126           DEFB  %0<B>1</B>000<B>1</B>00
   3127           DEFB  %0<B>1</B>0000<B>1</B>0
   3128           DEFB  %00000000
   3129 
   3130 ; $38 - <b>Character: 'S'          </b>CHR$(56)
   3131 
   3132           DEFB  %00000000
   3133           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3134           DEFB  %0<B>1</B>000000
   3135           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3136           DEFB  %000000<B>1</B>0
   3137           DEFB  %0<B>1</B>0000<B>1</B>0
   3138           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3139           DEFB  %00000000
   3140 
   3141 ; $39 - <b>Character: 'T'          </b>CHR$(57)
   3142 
   3143           DEFB  %00000000
   3144           DEFB  %<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   3145           DEFB  %000<B>1</B>0000
   3146           DEFB  %000<B>1</B>0000
   3147           DEFB  %000<B>1</B>0000
   3148           DEFB  %000<B>1</B>0000
   3149           DEFB  %000<B>1</B>0000
   3150           DEFB  %00000000
   3151 
   3152 ; $3A - <b>Character: 'U'          </b>CHR$(58)
   3153 
   3154           DEFB  %00000000
   3155           DEFB  %0<B>1</B>0000<B>1</B>0
   3156           DEFB  %0<B>1</B>0000<B>1</B>0
   3157           DEFB  %0<B>1</B>0000<B>1</B>0
   3158           DEFB  %0<B>1</B>0000<B>1</B>0
   3159           DEFB  %0<B>1</B>0000<B>1</B>0
   3160           DEFB  %00<B>1</B><B>1</B><B>1</B><B>1</B>00
   3161           DEFB  %00000000
   3162 
   3163 ; $3B - <b>Character: 'V'          </b>CHR$(59)
   3164 
   3165           DEFB  %00000000
   3166           DEFB  %0<B>1</B>0000<B>1</B>0
   3167           DEFB  %0<B>1</B>0000<B>1</B>0
   3168           DEFB  %0<B>1</B>0000<B>1</B>0
   3169           DEFB  %0<B>1</B>0000<B>1</B>0
   3170           DEFB  %00<B>1</B>00<B>1</B>00
   3171           DEFB  %000<B>1</B><B>1</B>000
   3172           DEFB  %00000000
   3173 
   3174 ; $3C - <b>Character: 'W'          </b>CHR$(60)
   3175 
   3176           DEFB  %00000000
   3177           DEFB  %0<B>1</B>0000<B>1</B>0
   3178           DEFB  %0<B>1</B>0000<B>1</B>0
   3179           DEFB  %0<B>1</B>0000<B>1</B>0
   3180           DEFB  %0<B>1</B>0000<B>1</B>0
   3181           DEFB  %0<B>1</B>0<B>1</B><B>1</B>0<B>1</B>0
   3182           DEFB  %00<B>1</B>00<B>1</B>00
   3183           DEFB  %00000000
   3184 
   3185 ; $3D - <b>Character: 'X'          </b>CHR$(61)
   3186 
   3187           DEFB  %00000000
   3188           DEFB  %0<B>1</B>0000<B>1</B>0
   3189           DEFB  %00<B>1</B>00<B>1</B>00
   3190           DEFB  %000<B>1</B><B>1</B>000
   3191           DEFB  %000<B>1</B><B>1</B>000
   3192           DEFB  %00<B>1</B>00<B>1</B>00
   3193           DEFB  %0<B>1</B>0000<B>1</B>0
   3194           DEFB  %00000000
   3195 
   3196 ; $3E - <b>Character: 'Y'          </b>CHR$(62)
   3197 
   3198           DEFB  %00000000
   3199           DEFB  %<B>1</B>00000<B>1</B>0
   3200           DEFB  %0<B>1</B>000<B>1</B>00
   3201           DEFB  %00<B>1</B>0<B>1</B>000
   3202           DEFB  %000<B>1</B>0000
   3203           DEFB  %000<B>1</B>0000
   3204           DEFB  %000<B>1</B>0000
   3205           DEFB  %00000000
   3206 
   3207 ; $3F - <b>Character: 'Z'          </b>CHR$(63)
   3208 
   3209           DEFB  %00000000
   3210           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   3211           DEFB  %00000<B>1</B>00
   3212           DEFB  %0000<B>1</B>000
   3213           DEFB  %000<B>1</B>0000
   3214           DEFB  %00<B>1</B>00000
   3215           DEFB  %0<B>1</B><B>1</B><B>1</B><B>1</B><B>1</B><B>1</B>0
   3216           DEFB  %00000000
   3217 
   3218 .END                                ;TASM assembler instruction.
   3219 
   3220 
   3221 
   3222 </PRE>
   3223 </BODY>
   3224 </HTML>