Output parameters (from DIFFER): HL still holds the old start pointer - DE holds the new pointer - BC holds the length. Called from: 08DF ME OLD L1 0901 ME OLD V1 092C ME ENTER 093E ME ENT 1 155D MAIN ADD 17CE AUTO L 1 1974 LINE AD 1 292A V NEXT 2C15 D RUN NEXT O 1 19C7 (19B8 NEXT ONE) Jumps from: 19B8 NEXT ONE NEXT O 2 19CE (19B8 NEXT ONE) Jumps from: 19C7 NEXT O 1 auto NEXT O 3 19D5 (19B8 NEXT ONE) Jumps from: 19B8 NEXT ONE NEXT O 4 19D6 (19B8 NEXT ONE) Jumps from: 19B8 NEXT ONE NEXT O 5 19DB (19B8 NEXT ONE) Jumps from: 19CE NEXT O 2 next statement see 1BEE CHECK END NEXT 1 1DE2 (1DDA NEXT LOOP) Jumps from: 1DDA NEXT LOOP NEXT 2 1DE9 (1DDA NEXT LOOP) Jumps from: 1DE2 NEXT 1 NEXT 2NUM subroutine 1C79 Entry point for 1C7A CLASS 08 when the BASIC pointer is to be moved on before collecting two number parameters from BASIC and putting them on the calculator stack. Called from: 1FFC PR ITEM 1 2522 S 2 COORD NIL BYTES 3272 (3214 truncate) Jumps from: 3214 truncate 3233 T FIRST "ninth" line of character area see 0E88 CL ATTR NMI (non-maskable interrupt) see interrupts NMIADD system variable 5CB0 Bytes: 2 Cannot be used, see 0066 RESET. NMIADD makes a good "spare" system variable for use in m/c programs. Beware! most commercial peripheral producers are aware of this and may well already have used it. Read by: 0066 RESET n-mod-m subroutine 36A0 see also mod Called from 0028 FP CALC with literal 32; returns the integer quotient Q and remainder R on dividing N by M, so that N = Q * M + R. Then R is N mod M, the remainder on dividing N by M. There is no corresponding BASIC operator, and the subroutine is only called once from ROM, to calculate the remainder on dividing 75d*(SEED + 1) by 65537d for a random number; even in this case, Q is discarded. Presumably the subroutine is included mainly for the benefit of m/c programmers. It can also be called direct, but N and M cannot befreely located, they must be on the calculator stack. Q will always be an integer, and in the RND calculation N, M and R are integers also, but this isn't necessary for the subroutine to work. Input parameters: HL holds the first byte of N, second last on the calculator stack - DE holds the first byte of M, last value. Action: use the calculator to calculate successively N/M INT (N/M) = Q M * INT (N/M) N - M * INT (N/M) = N mod M = R Exit: RET. Output parameters: HL holds the first byte of Q, second last on the calculator stack - DE holds the first byte of R, last value. - mem-0 has been used and corrupted. Called from: 25F8 S RND N NEGTV 3705 (36C4 exp) Jumps from: 36C4 exp NO ADD 311B (30CA multiply) Jumps from: 3114 MULT LOOP no-gr-eql, no-grtr see 353B no-l-eql no-key see KEYBOARD SCANNING 'no key yet' see FLAGS bit 5 no-l-eql, etc subroutine 353B Called only from 0028 FP CALC with literals 09 -> 0Eh and 11h -> 16h as the executive routine for all the_comparison _operations listed below. Not otherwise called from ROM. Can be called from m/c, with the offset in B, but the expressions to be compared must beon the calculator stack, not freely located in RAM. The subroutine performs any one of twelve different comparison operations depending on the value of the offset on entry. In each case the comparison is between the two top valueson the calculator stack, which may be either numbers X and Y or the parameters of strings X$ and Y$. The result of the subroutine is always either zero for "false" or one for "true" as the last value on the calculator stack, replacing both X/X$ and Y/Y$; see logical values. The "true" value is returned: Offset Name Condition 09 no-l-eql if X <= Y 0A no-gr-eq if X >= Y 0B nos-neql if X <> Y 0C no-grtr if X > Y 0D no-less if X < Y 0E nos-eql if X = Y 11 str-l-eql if X$ <= Y$ 12 str-gr-eq if X$ >= Y$ 13 strs-neql if X$ <> Y$ 14 str-grtr if X$ > Y$ 15 str-less if X$ < Y$ 16 strs-eql if X$ = Y$ The actual comparison of X/X$ with Y/Y$ is relatively straightforward: the call to SUBTRACT in NU OR STR for numbers, the byte comparison loop in BYTE COMP and following for strings.The routine performs much more elaborate gyrations to produce the appropriate result by interpreting this comparison in terms of the individual offset. By the time END TESTS is reached, the AF on the machine stack and the value on top of the calculator stack are as follows for each of the number comparisons: no-l-eql A even, X - Y on calc stack, no carry no-gr-eq A even, Y - X " " " no carry nos-neql A even, X - Y " " " carry no-grtr A odd, X - Y " " " no carry no-less A odd, Y - X " " " no carry nos-eql A odd, X - Y " " " carry In the case of number comparisons, the odd/even flag A is zero or one. In the case of string comparisons, A is 2 or 3, still flagging the "odd" and "even" operations in the same way, but there is zero on the calculator stack in all cases, and the carry depends on X$ and Y$ as follows: X$ > Y$ X$ = Y$ X$ < Y$ str-l-eql carry no carry no carry str-gr-eq no carry no carry carry strs-neql no carry carry no carry str-grtr carry no carry no carry str-less no carry no carry carry strs-eql no carry carry no carry In the first three lines carry corresponds to "wrong" and no carry "right"; in the last three lines the reverse. A call to 3501 NOT if carry is set makes the last value one if it was zero and zero if it wasn't. Now - for numbers, one corresponds to "right answer" for eql and "wrong answer" for neql - for strings, with asterisks marking wrong answers, flag X$ > Y$ X$ = Y$ X$ < Y$ str-l-eql 2 one* zero* zero* str-gr-eq 2 zero* zero* one* strs-neql 2 zero* one* zero* str-grtr 3 one zero zero str-less 3 zero zero one strs-eql 3 zero one zero Next a call to 34F9 GREATER 0 if carry was_not set makesthe last value one if it was positive, zero if it was negative or zero. Now - for numbers, one means "right answer" for grtr and less, and eql from the NOT call, and "wrong answer" for l-eql and gr-eq, and neql from the NOT call. - for strings, there has been no change from the last table, because GREATER 0 makes one from one and zero from zero. Finally, another call to NOT if the odd/even flag was even (l-eql, gr-eq and neql) exchanges zero and one; now the result is correct in each case. Input parameters: B holds the offset - HL points to the first byte of X or the string parameters of X$, second last value on the calculator stack - DE points to the first byte of Y or the string parameters of Y$, the last value. Action: take 08 from the offset; making 1 -> 6 or 9 -> 0E - if bit 2 is zero decrement the result; 0001b/01 -> 0000b/00 1001b/09 -> 1000b/08 0010b/02 -> 0001b/01 1010b/0A -> 1001b/09 0011b/03 -> 0010b/02 1011b/0B -> 1010b/0A 0100b/04 -> 0100b/04 1100b/0C -> 1100b/0C 0101b/05 -> 0101b/05 1101b/0D -> 1101b/0D 0110b/06 -> 0110b/06 1110b/0E -> 1110b/0E _3543_EX_OR_NOT: rotate this result right, with lo bit into the carry - if this makes no carry jump on to NU OR STR; even numbers - (odd numbers) call 343C EXCHANGE to exchange X and Y on the calculator stack; only "gr-eql" and "less" are odd numbers, and this turns "gr-eql" into "less" and vice versa. _354E_NU_OR_STR: if bit 2, which was bit 3 before the rotation, is set jump on to STRINGS; the jump is made for operations in the right-hand column in the last table, all the string comparisons - (numbers, the left hand column) rotate the offset intothe carry again - save this "eql/l-gr" flag and the offset; the offset is now the odd/even flag, zero for l-eql, gr-eq and neql, one for grtr, less and eql. The carry will be C for eql and neql, NCfor all the others - call 300F subtract, which gives a positive, negative or zero result depending on X and Y - jump on to END TESTS. _3559_STRINGS (string comparisons): as before, rotate theoffset and save it with an eql/l-gr flag; the offset is now the odd/even flag, 2 for l-eql, gr-eq and neql, 3 for grtr, less andeql. The carry is as for the number comparisons - call 2BF1 STK FETCH twice to get the string parametersof both strings; this removes them from the stack. _3564_BYTE_COMP (loop back to here from SEC PLUS, counting down the lengths of both X$ and Y$, if the bytes of X$ and Y$ are all equal so far): if the length of Y$ isn't zero yetjump on to SEC PLUS - (it has reached zero; either X$ and Y$ are equal strings or they are equal except that Y$ is shorter than X$) check if the length of X$ is zero as well. _356B_SECND_LOW: if it too is zero jump on to BOTH NULL; the strings are equal - (Y$ is shorter; this counts as X$ > Y$) get the eql/ gr-l flag and reverse it - jump on to STR TEST. _3572_BOTH_NULL (the strings are equal): get the eql/gr-lflag and jump on to STR TEST. _3575_SEC_PLUS (Y$ isn't counted down yet): check the count on X$ - if it has reached zero jump on to FRST LESS; X$ is equal to but shorter than Y$ - (both strings are equal so far, but both have more bytes to come) compare the next bytes; DE is from X$, HL from Y$ - if Y$ has a higher value jump on to FRST LESS - if X$ has a higher value jump back to SECND LOW. - (X$ and Y$ are still equal so far) move both pointers on and decrement both length counters - jump back to BYTE COMP. _3585_FRST_LESS (X$ < Y$): get the eql/gr-l flag and clear its carry. _3588_STR_TEST: save the eql/gr-l flag - put a zero on the calculator stack. _358C_END_TESTS (see the description above): if carry is set, call 3501 NOT - if carry was_not set, call 34F9 GREATER 0 - rotate the odd/even flag to the right - if it was even call NOT again. Exit: RET. Output parameters: HL points to the last value on the calculator stack; zero for "false", one for "true", replacing both the values originally placed there for comparison - DE points to the stack end. Rems: 2E24 PF SMALL all string comparisons can give wrong answers due to mistake in ROM 338E ENT TABLE puts appropriate offset in B register no-less see 353B no-l-eql non-leading zero see 2DE3 PRINT FP NON-MASKABLE INTERRUPT see interrupts, 0066 RESET "Nonsense in BASIC" message see REPORT C NO RESET 0070 (0066 RESET) Jumps from: 0066 RESET normal form, normalisation of FP numbers see 3155 TEST NORM NORMALISE 316C (3155 TEST NORM) Jumps from: 3155 TEST NORM NORML NOW 3186 (3155 TEST NORM) Jumps from: 316E SHIFT ONE NO RSTORE 31F9 (31AF division) Jumps from: 31E2 DIV START nos-eql, nos-neql see 353B no-l-eql no-shift see KEYBOARD SCANNING no./string flag see expressions