OpenCores
URL https://opencores.org/ocsvn/t51/t51/trunk

Subversion Repositories t51

[/] [t51/] [trunk/] [sw/] [BASIC-52.asm] - Blame information for rev 52

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 6 jesus
;*****************************************************************************
2
;*                                                                           *
3
;*                      MCS BASIC-52 (tm) Source Listing                     *
4
;*                             December 18, 1986                             *
5
;*        The original source code of V1.1 (BASIC.SRC and FP52.SRC) by       *
6
;*             Intel Corporation, Embedded Controller Operations             *
7
;*                              is public donain                             *
8
;*                                                                           *
9
;*---------------------------------------------------------------------------*
10
;*              Alterations made by D. Wulf , December 18, 1999              *
11 7 jesus
;*              Alterations made by D. Wallner , May 4, 2002                 *
12 6 jesus
;*                                                                           *
13
;*****************************************************************************
14
;
15 7 jesus
;  The BASIC.a51 source listing, when compiled without modification,
16
;  create the same object code that is found on the MCS BASIC-52
17
;  Version 1.1 microcontrollers but with a timing independent baud rate
18
;  recognition routine and a shorter ego message.
19 6 jesus
;
20
;  The following alterations are made to the original source code:
21
;
22
;  The original source code had 2 files BASIC.SRC and FP52.SRC those have
23
;  been incorporated into this file for ease of assembly.
24
;
25
;  All absolute and relativ jumps and calls without labels were providet
26
;  with labels.
27
;
28
;  All machine code in the original source, codet in databytes is replaced
29
;  by the menomics.
30
;
31
;  One routine in the source was different to the ROM code and is replaced
32
;  by the ROM code.
33
;
34 7 jesus
;  Daniel Wallner , May 4, 2002:
35
;  Part of ego message replaced with a different baud recognition routine.
36
;
37 6 jesus
;*****************************************************************************
38
;
39
T2CON   EQU     0C8H ; This three lines are necessary for MS-DOS freeware
40
TL2     EQU     0CCH ; MCS-51 Family Cross Assembler  ASEM-51 V1.2
41
TH2     EQU     0CDH ; from W.W. Heinz (e-mail: ww@andiunx.m.isar.de)
42
;
43
;*****************************************************************************
44
;
45
$EJECT
46
        ;**************************************************************
47
        ;
48
        ; TRAP VECTORS TO MONITOR
49
        ;
50
        ; RESET TAG (0AAH) ---------2001H
51
        ;
52
        ; TAG LOCATION (5AH) ------ 2002H
53
        ;
54
        ; EXTERNAL INTERRUPT 0 ---- 2040H
55
        ;
56
        ; COMMAND MODE ENTRY ------ 2048H
57
        ;
58
        ; SERIAL PORT ------------- 2050H
59
        ;
60
        ; MONITOR (BUBBLE) OUTPUT - 2058H
61
        ;
62
        ; MONITOR (BUBBLE) INPUT -- 2060H
63
        ;
64
        ; MONITOR (BUBBLE) CSTS --- 2068H
65
        ;
66
        ; GET USER JUMP VECTOR ---- 2070H
67
        ;
68
        ; GET USER LOOKUP VECTOR -- 2078H
69
        ;
70
        ; PRINT AT VECTOR --------- 2080H
71
        ;
72
        ; INTERRUPT PWM ----------- 2088H
73
        ;
74
        ; EXTERNAL RESET ---------- 2090H
75
        ;
76
        ; USER OUTPUT-------------- 4030H
77
        ;
78
        ; USER INPUT -------------- 4033H
79
        ;
80
        ; USER CSTS --------------- 4036H
81
        ;
82
        ; USER RESET -------------- 4039H
83
        ;
84
        ; USER DEFINED PRINT @ ---  403CH
85
        ;
86
        ;***************************************************************
87
        ;
88
$EJECT
89
        ;***************************************************************
90
        ;
91
        ; MCS - 51  -  8K BASIC VERSION 1.1
92
        ;
93
        ;***************************************************************
94
        ;
95
        AJMP    CRST            ;START THE PROGRAM
96
        ADDC    A,@R1
97
        ;
98
        ORG     3H
99
        ;
100
        ;***************************************************************
101
        ;
102
        ;EXTERNAL INTERRUPT 0
103
        ;
104
        ;***************************************************************
105
        ;
106
        JB      DRQ,STQ         ;SEE IF DMA IS SET
107
        PUSH    PSW             ;SAVE THE STATUS
108
        LJMP    4003H           ;JUMP TO USER IF NOT SET
109
        ;
110
        ORG     0BH
111
        ;
112
        ;***************************************************************
113
        ;
114
        ;TIMER 0 OVERFLOW INTERRUPT
115
        ;
116
        ;***************************************************************
117
        ;
118
        PUSH    PSW             ;SAVE THE STATUS
119
        JB      C_BIT,STJ       ;SEE IF USER WANTS INTERRUPT
120
        LJMP    400BH           ;EXIT IF USER WANTS INTERRUPTS
121
        ;
122
        ORG     13H
123
        ;
124
        ;***************************************************************
125
        ;
126
        ;EXTERNAL INTERRUPT 1
127
        ;
128
        ;***************************************************************
129
        ;
130
        JB      INTBIT,STK
131
        PUSH    PSW
132
        LJMP    4013H
133
        ;
134
$EJECT
135
        ;
136
        ORG     1BH
137
        ;
138
        ;***************************************************************
139
        ;
140
        ;TIMER 1 OVERFLOW INTERRUPT
141
        ;
142
        ;***************************************************************
143
        ;
144
        PUSH    PSW
145
        LJMP    CKS_I
146
        ;
147
STJ:    LJMP    I_DR            ;DO THE INTERRUPT
148
        ;
149
        ;***************************************************************
150
        ;
151
        ;SERIAL PORT INTERRUPT
152
        ;
153
        ;***************************************************************
154
        ;
155
        ORG     23H
156
        ;
157
        PUSH    PSW
158
        JB      SPINT,STU       ;SEE IF MONITOR EANTS INTERRUPT
159
        LJMP    4023H
160
        ;
161
        ORG     2BH
162
        ;
163
        ;**************************************************************
164
        ;
165
        ;TIMER 2 OVERFLOW INTERRUPT
166
        ;
167
        ;**************************************************************
168
        ;
169
        PUSH    PSW
170
        LJMP    402BH
171
        ;
172
$EJECT
173
        ;**************************************************************
174
        ;
175
        ;USER ENTRY
176
        ;
177
        ;**************************************************************
178
        ;
179
        ORG     30H
180
        ;
181
        LJMP    IBLK            ;LINK TO USER BLOCK
182
        ;
183
STQ:    JB      I_T0,STS        ;SEE IF MONITOR WANTS IT
184
        CLR     DACK
185
        JNB     P3.2,$          ;WAIT FOR DMA TO END
186
        SETB    DACK
187
        RETI
188
        ;
189
STS:    LJMP    2040H           ;GO TO THE MONITOR
190
        ;
191
STK:    SETB    INTPEN          ;TELL BASIC AN INTERRUPT WAS RECEIVED
192
        RETI
193
        ;
194
STU:    LJMP    2050H           ;SERIAL PORT INTERRUPT
195
        ;
196
$EJECT
197
 
198
;$INCLUDE(:F2:LOOK52.SRC)
199
; INCLUDED BELOW
200
 
201
        ;
202
        ;**************************************************************
203
        ;
204
        ; This is the equate table for 8052 basic.
205
        ;
206
        ;**************************************************************
207
        ;
208
        ; The register to direct equates for CJNE instructions.
209
        ;
210
R0B0    EQU     0
211
R1B0    EQU     1
212
R2B0    EQU     2
213
R3B0    EQU     3
214
R4B0    EQU     4
215
R5B0    EQU     5
216
R6B0    EQU     6
217
R7B0    EQU     7
218
        ;
219
        ; Register bank 1 contains the text pointer
220
        ; and the arg stack pointer.
221
        ;
222
TXAL    EQU     8               ;R0 BANK 1 = TEXT POINTER LOW
223
ASTKA   EQU     9               ;R1 BANK 1 = ARG STACK
224
TXAH    EQU     10              ;R2 BANK 1 = TEXT POINTER HIGH
225
        ;
226
        ; Now five temporary locations that are used by basic.
227
        ;
228
TEMP1   EQU     11
229
TEMP2   EQU     12
230
TEMP3   EQU     13
231
TEMP4   EQU     14
232
TEMP5   EQU     15
233
        ;
234
$EJECT
235
        ; Register bank 2 contains the read text pointer
236
        ; and the control stack pointer.
237
        ;
238
RTXAL   EQU     16              ;R0 BANK 2 = READ TEXT POINTER LOW
239
CSTKA   EQU     17              ;R1 BANK 2 = CONTROL STACK POINTER
240
RTXAH   EQU     18              ;R2 BANK 2 = READ TEXT POINTER HIGH
241
        ;
242
        ; Now some internal system equates.
243
        ;
244
BOFAH   EQU     19              ;START OF THE BASIC PROGRAM, HIGH BYTE
245
BOFAL   EQU     20              ;START OF THE BASIC PROGRAM, LOW BYTE
246
NULLCT  EQU     21              ;NULL COUNT
247
PHEAD   EQU     22              ;PRINT HEAD POSITION
248
FORMAT  EQU     23
249
        ;
250
        ; Register bank 3 is for the user and can be loaded
251
        ; by basic
252
        ;
253
        ;
254
        ;
255
        ; Now everything else is used by basic.
256
        ; First the bit locations, these use bytes 34, 35, 36, 37 and 38
257
        ;
258
$EJECT
259
OTS             BIT     16      ;34.0-ON TIME INSTRUCTION EXECUTED
260
INPROG          BIT     17      ;34.1-INTERRUPT IN PROCESS
261
INTBIT          BIT     18      ;34.2-INTERRUPT SET BIT
262
ON_ERR          BIT     19      ;34.3-ON ERROR EXECUTED
263
OTI             BIT     20      ;34.4-ON TIME INTERRUPT IN PROGRESS
264
LINEB           BIT     21      ;34.5-LINE CHANGE OCCURED
265
INTPEN          BIT     22      ;34.6-INTERRUPT PENDING BIT
266
CONB            BIT     23      ;34.7-CAN CONTINUE IF SET
267
GTRD            BIT     24      ;35.0-READ GET LOCATION
268
LPB             BIT     25      ;35.1-PRINT TO LINE PRINTER PORT
269
CKS_B           BIT     26      ;35.2-FOR PWM INTERRUPT
270
COB             BIT     27      ;35.3-CONSOLE OUT BIT
271
                                ;     0 = SERIAL PORT
272
                                ;     1 = LINE PRINTER
273
COUB            BIT     28      ;35.4-USER CONSOLE OUT BIT
274
                                ;     0 = SERIAL PORT
275
                                ;     1 = USER DRIVER
276
INBIT           BIT     29      ;35.5-INITIALIZATION BIT
277
CIUB            BIT     30      ;35.6-USER CONSOLE IN BIT
278
                                ;     0 = SERIAL PORT
279
                                ;     1 = USER ROUTINE
280
SPINT           BIT     31      ;35.7-SERIAL PORT INTERRUPT
281
STOPBIT         BIT     32      ;36.0-PROGRAM STOP ENCOUNTERED
282
U_IDL           BIT     33      ;36.1-USER IDLE BREAK
283
INP_B           BIT     34      ;36.2-SET DURING INPUT INSTRUCTION
284
;DCMPXZ         BIT     35      ;36.3-DCMPX ZERO FLAG
285
ARGF            BIT     36      ;36.4-ARG STACK HAS A VALUE
286
RETBIT          BIT     37      ;36.5-RET FROM INTERRUPT EXECUTED
287
I_T0            BIT     38      ;36.6-TRAP INTERRUPT ZERO TO MON
288
UPB             BIT     39      ;36.7-SET WHEN @ IS VALID
289
JKBIT           BIT     40      ;37.0-WB TRIGGER
290
ENDBIT          BIT     41      ;37.1-GET END OF PROGRAM
291
UBIT            BIT     42      ;37.2-FOR DIM STATEMENT
292
ISAV            BIT     43      ;37.3-SAVE INTERRUPT STATUS
293
BO              BIT     44      ;37.4-BUBBLE OUTPUT
294
XBIT            BIT     45      ;37.5-EXTERNAL PROGRAM PRESENT
295
C_BIT           BIT     46      ;37.6-SET WHEN CLOCK RUNNING
296
DIRF            BIT     47      ;37.7-DIRECT INPUT MODE
297
NO_C            BIT     48      ;38.0-NO CONTROL C
298
DRQ             BIT     49      ;38.1-DMA ENABLED
299
BI              BIT     50      ;38.2-BUBBLE INPUT
300
INTELB          BIT     51      ;38.3-INTELLIGENT PROM PROGRAMMING
301
C0ORX1          BIT     52      ;38.4-PRINT FROM ROM OR RAM
302
CNT_S           BIT     53      ;38.5-CONTROL S ENCOUNTERED
303
ZSURP           BIT     54      ;38.6-ZERO SUPRESS
304
HMODE           BIT     55      ;38.7-HEX MODE PRINT
305
LP              BIT     P1.7    ;SOFTWARE LINE PRINTER
306
DACK            BIT     P1.6    ;DMA ACK
307
PROMV           BIT     P1.5    ;TURN ON PROM VOLTAGE
308
PROMP           BIT     P1.4    ;PROM PULSE
309
ALED            BIT     P1.3    ;ALE DISABLE
310
T_BIT           BIT     P1.2    ;I/O TOGGLE BIT
311
        ;
312
$EJECT
313
        ;
314
        ; The next location is a bit addressable byte counter
315
        ;
316
BABC    EQU     39
317
        ;
318
        ; Now floating point and the other temps
319
        ;
320
        ; FP Uses to locations 03CH
321
        ;
322
        ; Now the stack designators.
323
        ;
324
SPSAV   EQU     3EH
325
S_LEN   EQU     3FH
326
T_HH    EQU     40H
327
T_LL    EQU     41H
328
INTXAH  EQU     42H
329
INTXAL  EQU     43H
330
MT1     EQU     45H
331
MT2     EQU     46H
332
MILLIV  EQU     47H             ;TIMER LOCATIONS
333
TVH     EQU     48H
334
TVL     EQU     49H
335
SAVE_T  EQU     4AH
336
SP_H    EQU     4BH             ;SERIAL PORT TIME OUT
337
SP_L    EQU     4CH
338
CMNDSP  EQU     4DH             ;SYSTEM STACK POINTER
339
RCAPH2  EQU     0CBH
340
RCAPL2  EQU     0CAH
341
IRAMTOP EQU     0FFH            ;TOP OF RAM
342
STACKTP EQU     0FEH            ;ARG AND CONTROL STACK TOPS
343
        ;
344
        ; The character equates
345
        ;
346
CR      EQU     0DH             ;CARRIAGE RETURN
347
LF      EQU     0AH             ;LINE FEED
348
BELL    EQU     07H             ;BELL CHARACTER
349
BS      EQU     08H             ;BACK SPACE
350
CNTRLC  EQU     03H             ;CONTROL C
351
CNTRLD  EQU     04H             ;CONTROL D
352
NULL    EQU     00H             ;NULL
353
        ;
354
$EJECT
355
        ;
356
        ; The internal system equates
357
        ;
358
LINLEN  EQU     73              ;THE LENGTH OF AN INPUT LINE
359
EOF     EQU     01              ;END OF FILE CHARACTER
360
ASTKAH  EQU     01              ;ASTKA IS IN PAGE 1 OF RAM
361
CSTKAH  EQU     00              ;CSTKA IS IN PAGE 0 OF RAM
362
FTYPE   EQU     01              ;CONTROL STACK "FOR"
363
GTYPE   EQU     02              ;CONTROL STACK "GOSUB"
364
DTYPE   EQU     03              ;DO-WHILE/UNTIL TYPE
365
ROMADR  EQU     8000H           ;LOCATION OF ROM
366
        ;
367
        ; The floating point equates
368
        ;
369
FPSIZ   EQU     6               ;NO. OF BYTES IN A FLOATING NUM
370
DIGIT   EQU     FPSIZ-2         ;THE MANTISSA OF A FLOATING NUM
371
STESIZ  EQU     FPSIZ+3         ;SIZE OF SYMBOL ADJUSTED TABLE ELEMENT
372
;FP_BASE EQU     1993H           ;BASE OF FLOATING POINT ROUTINES
373
PSTART  EQU     512             ;START OF A PROGRAM IN RAM
374
FSIZE   EQU     FPSIZ+FPSIZ+2+2+1
375
        ;
376
$EJECT
377
        ;**************************************************************
378
        ;
379
USENT:  ; User entry jump table
380
        ;
381
        ;**************************************************************
382
        ;
383
        DW      CMND1           ;(00, 00H)COMMAND MODE JUMP
384
        DW      IFIX            ;(01, 01H)CONVERT FP TO INT
385
        DW      PUSHAS          ;(02, 02H)PUSH VALUE ONTO ARG STACK
386
        DW      POPAS           ;(03, 03H)POP VALUE OFF ARG STACK
387
        DW      PG1             ;(04, 04H)PROGRAM A PROM
388
        DW      INLINE          ;(05, 05H)INPUT A LINE
389
        DW      UPRNT           ;(06, 06H)PRINT A LINR
390
        DW      CRLF            ;(07, 07H)OUTPUT A CRLF
391
        ;
392
        ;**************************************************************
393
        ;
394
        ; This is the operation jump table for arithmetics
395
        ;
396
        ;**************************************************************
397
        ;
398
OPTAB:  DW      ALPAR           ;(08, 08H)LEFT PAREN
399
        DW      AEXP            ;(09, 09H)EXPONENTAION
400
        DW      AMUL            ;(10, 0AH)FP MUL
401
        DW      AADD            ;(11, 0BH)FLOATING POINT ADD
402
        DW      ADIV            ;(12, 0CH)FLOATING POINT DIVIDE
403
        DW      ASUB            ;(13, 0DH)FLOATING POINT SUBTRACTION
404
        DW      AXRL            ;(14, 0EH)XOR
405
        DW      AANL            ;(15, 0FH)AND
406
        DW      AORL            ;(16, 10H)OR
407
        DW      ANEG            ;(17, 11H)NEGATE
408
        DW      AEQ             ;(18, 12H)EQUAL
409
        DW      AGE             ;(19, 13H)GREATER THAN OR EQUAL
410
        DW      ALE             ;(20, 14H)LESS THAN OR EQUAL
411
        DW      ANE             ;(21, 15H)NOT EQUAL
412
        DW      ALT             ;(22, 16H)LESS THAN
413
        DW      AGT             ;(23, 17H)GREATER THAN
414
        ;
415
$EJECT
416
        ;***************************************************************
417
        ;
418
        ; This is the jump table for unary operators
419
        ;
420
        ;***************************************************************
421
        ;
422
        DW      AABS            ;(24, 18H)ABSOLUTE VALUE
423
        DW      AINT            ;(25, 19H)INTEGER OPERATOR
424
        DW      ASGN            ;(26, 1AH)SIGN OPERATOR
425
        DW      ANOT            ;(27, 1BH)ONE'S COMPLEMENT
426
        DW      ACOS            ;(28, 1CH)COSINE
427
        DW      ATAN            ;(29, 1DH)TANGENT
428
        DW      ASIN            ;(30, 1EH)SINE
429
        DW      ASQR            ;(31, 1FH)SQUARE ROOT
430
        DW      ACBYTE          ;(32, 20H)READ CODE
431
        DW      AETOX           ;(33, 21H)E TO THE X
432
        DW      AATAN           ;(34, 22H)ARC TANGENT
433
        DW      ALN             ;(35, 23H)NATURAL LOG
434
        DW      ADBYTE          ;(36, 24H)READ DATA MEMORY
435
        DW      AXBYTE          ;(37, 25H)READ EXTERNAL MEMORY
436
        DW      PIPI            ;(38, 26H)PI
437
        DW      ARND            ;(39, 27H)RANDOM NUMBER
438
        DW      AGET            ;(40, 28H)GET INPUT CHARACTER
439
        DW      AFREE           ;(41, 29H)COMPUTE #BYTES FREE
440
        DW      ALEN            ;(42, 2AH) COMPUTE LEN OF PORGRAM
441
        DW      AXTAL           ;(43, 2BH) CRYSTAL
442
        DW      PMTOP           ;(44, 2CH)TOP OF MEMORY
443
        DW      ATIME           ;(45, 2DH) TIME
444
        DW      A_IE            ;(46, 2EH) IE
445
        DW      A_IP            ;(47, 2FH) IP
446
        DW      ATIM0           ;(48, 30H) TIMER 0
447
        DW      ATIM1           ;(49, 31H) TIMER 1
448
        DW      ATIM2           ;(50, 32H) TIMER 2
449
        DW      AT2CON          ;(51, 33H) T2CON
450
        DW      ATCON           ;(52, 34H) TCON
451
        DW      ATMOD           ;(53, 35H) ATMOD
452
        DW      ARCAP2          ;(54, 36H) RCAP2
453
        DW      AP1             ;(55, 37H) P1
454
        DW      APCON           ;(56, 38H) PCON
455
        DW      EXPRB           ;(57, 39H) EVALUATE AN EXPRESSION
456
        DW      AXTAL1          ;(58, 3AH) CALCULATE CRYSTAL
457
        DW      LINE            ;(59, 3BH) EDIT A LINE
458
        DW      PP              ;(60, 3CH) PROCESS A LINE
459
        DW      UPPL0           ;(61, 3DH) UNPROCESS A LINE
460
        DW      VAR             ;(62, 3EH) FIND A VARIABLE
461
        DW      GC              ;(63, 3FH) GET A CHARACTER
462
        DW      GCI             ;(64, 40H) GET CHARACTER AND INCREMENT
463
        DW      INCHAR          ;(65, 41H) INPUT A CHARACTER
464
        DW      CRUN            ;(66, 42H) RUN A PROGRAM
465
$EJECT
466
OPBOL:  DB      1               ;
467
        ;
468
        DB      15              ;LEFT PAREN
469
        DB      14              ;EXPONENTIAN **
470
        DB      10              ;MUL
471
        DB      8               ;ADD
472
        DB      10              ;DIVIDE
473
        DB      8               ;SUB
474
        DB      3               ;XOR
475
        DB      5               ;AND
476
        DB      4               ;OR
477
        DB      12              ;NEGATE
478
        DB      6               ;EQ
479
        DB      6               ;GT
480
        DB      6               ;LT
481
        DB      6               ;NE
482
        DB      6               ;LE
483
        DB      6               ;GE
484
        ;
485
UOPBOL: DB      15              ;AABS
486
        DB      15              ;AAINT
487
        DB      15              ;ASGN
488
        DB      15              ;ANOT
489
        DB      15              ;ACOS
490
        DB      15              ;ATAN
491
        DB      15              ;ASIN
492
        DB      15              ;ASQR
493
        DB      15              ;ACBYTE
494
        DB      15              ;E TO THE X
495
        DB      15              ;AATAN
496
        DB      15              ;NATURAL LOG
497
        DB      15              ;DBYTE
498
        DB      15              ;XBYTE
499
        ;
500
$EJECT
501
        ;***************************************************************
502
        ;
503
        ; The ASCII printed messages.
504
        ;
505
        ;***************************************************************
506
        ;
507
STP:    DB      'STOP"'
508
        ;
509
IAN:    DB      'TRY AGAIN"'
510
        ;
511
RDYS:   DB      'READY"'
512
        ;
513
INS:    DB      ' - IN LINE "'
514
        ;
515
        ;**************************************************************
516
        ;
517
        ; This is the command jump table
518
        ;
519
        ;**************************************************************
520
        ;
521
CMNDD:  DW      CRUN            ;RUN
522
        DW      CLIST           ;LIST
523
        DW      CNULL           ;NULL
524
        DW      CNEW            ;NEW
525
        DW      CCONT           ;CONTINUE
526
        DW      CPROG           ;PROGRAM A PROM
527
        DW      CXFER           ;TRANSFER FROM ROM TO RAM
528
        DW      CRAM            ;RAM MODE
529
        DW      CROM            ;ROM MODE
530
        DW      CIPROG          ;INTELLIGENT PROM PROGRAMMING
531
        ;
532
$EJECT
533
        ;***************************************************************
534
        ;
535
        ; This is the statement jump table.
536
        ;
537
        ;**************************************************************
538
        ;
539
STATD:  ;
540
        DW      SLET            ;LET            80H
541
        DW      SCLR            ;CLEAR          81H
542
        DW      SPUSH           ;PUSH VAR       82H
543
        DW      SGOTO           ;GO TO          83H
544
        DW      STONE           ;TONE           84H
545
        DW      SPH0            ;PRINT MODE 0   85H
546
        DW      SUI             ;USER INPUT     86H
547
        DW      SUO             ;USER OUTPUT    87H
548
        DW      SPOP            ;POP VAR        88H
549
        DW      SPRINT          ;PRINT          89H
550
        DW      SCALL           ;CALL           8AH
551
        DW      SDIMX           ;DIMENSION      8BH
552
        DW      STRING          ;STRING ALLO    8CH
553
        DW      SBAUD           ;SET BAUD       8DH
554
        DW      SCLOCK          ;CLOCK          8EH
555
        DW      SPH1            ;PRINT MODE 1   8FH
556
        ;
557
        ; No direct mode from here on
558
        ;
559
        DW      SSTOP           ;STOP           90H
560
        DW      SOT             ;ON TIME        91H
561
        DW      SONEXT          ;ON EXT INT     92H
562
        DW      SRETI           ;RET FROM INT   93H
563
        DW      S_DO            ;DO             94H
564
        DW      SRESTR          ;RESTOR         95H
565
        DW      WCR             ;REM            96H
566
        DW      SNEXT           ;NEXT           97H
567
        DW      SONERR          ;ON ERROR       98H
568
        DW      S_ON            ;ON             99H
569
        DW      SINPUT          ;INPUT          9AH
570
        DW      SREAD           ;READ           9BH
571
        DW      FINDCR          ;DATA           9CH
572
        DW      SRETRN          ;RETURN         9DH
573
        DW      SIF             ;IF             9EH
574
        DW      SGOSUB          ;GOSUB          9FH
575
        DW      SFOR            ;FOR            A0H
576
        DW      SWHILE          ;WHILE          A1H
577
        DW      SUNTIL          ;UNTIL          A2H
578
        DW      CMND1           ;END            A3H
579
        DW      I_DL            ;IDLE           A4H
580
        DW      ST_A            ;STORE AT       A5H
581
        DW      LD_A            ;LOAD AT        A6H
582
        DW      PGU             ;PGM            A7H
583
        DW      RROM            ;RUN A ROM      A9H
584
        ;
585
$EJECT
586
        ;**************************************************************
587
        ;
588
TOKTAB: ; This is the basic token table
589
        ;
590
        ;**************************************************************
591
        ;
592
        ; First the tokens for statements
593
        ;
594
        DB      80H             ;LET TOKEN
595
        DB      'LET'
596
        ;
597
        DB      81H             ;CLEAR TOKEN
598
        DB      'CLEAR'
599
        ;
600
        DB      82H             ;PUSH TOKEN
601
        DB      'PUSH'
602
        ;
603
T_GOTO  EQU     83H
604
        ;
605
        DB      83H             ;GO TO TOKEN
606
        DB      'GOTO'
607
        ;
608
        DB      84H             ;TOGGLE TOKEN
609
        DB      'PWM'
610
        ;
611
        DB      85H             ;PRINT HEX MODE 0
612
        DB      'PH0.'
613
        ;
614
        DB      86H             ;USER IN TOKEN
615
        DB      'UI'
616
        ;
617
        DB      87H             ;USER OUT TOKEN
618
        DB      'UO'
619
        ;
620
        DB      88H             ;POP TOKEN
621
        DB      'POP'
622
        ;
623
$EJECT
624
        DB      89H             ;PRINT TOKEN
625
        DB      'PRINT'
626
        DB      89H
627
        DB      'P.'            ;P. ALSO MEANS PRINT
628
        DB      89H             ;? ALSO
629
        DB      '?'
630
        ;
631
        DB      8AH             ;CALL TOKEN
632
        DB      'CALL'
633
        ;
634
        DB      8BH             ;DIMENSION TOKEN
635
        DB      'DIM'
636
        ;
637
        DB      8CH             ;STRING TOKEN
638
        DB      'STRING'
639
        ;
640
        DB      8DH             ;SET BAUD RATE
641
        DB      'BAUD'
642
        ;
643
        DB      8EH             ;CLOCK
644
        DB      'CLOCK'
645
        ;
646
        DB      8FH             ;PRINT HEX MODE 1
647
        DB      'PH1.'
648
        ;
649
T_STOP  EQU     90H             ;STOP TOKEN
650
        DB      T_STOP
651
        DB      'STOP'
652
        ;
653
T_DIR   EQU     T_STOP          ;NO DIRECT FROM HERE ON
654
        ;
655
        DB      T_STOP+1        ;ON TIMER INTERRUPT
656
        DB      'ONTIME'
657
        ;
658
        DB      T_STOP+2        ;ON EXTERNAL INTERRUPT
659
        DB      'ONEX1'
660
        ;
661
        DB      T_STOP+3        ;RETURN FROM INTERRUPT
662
        DB      'RETI'
663
        ;
664
        DB      T_STOP+4        ;DO TOKEN
665
        DB      'DO'
666
        ;
667
        DB      T_STOP+5        ;RESTORE TOKEN
668
        DB      'RESTORE'
669
        ;
670
$EJECT
671
T_REM   EQU     T_STOP+6        ;REMARK TOKEN
672
        DB      T_REM
673
        DB      'REM'
674
        ;
675
        DB      T_REM+1         ;NEXT TOKEN
676
        DB      'NEXT'
677
        ;
678
        DB      T_REM+2         ;ON ERROR TOKEN
679
        DB      'ONERR'
680
        ;
681
        DB      T_REM+3         ;ON TOKEN
682
        DB      'ON'
683
        ;
684
        DB      T_REM+4         ;INPUT
685
        DB      'INPUT'
686
        ;
687
        DB      T_REM+5         ;READ
688
        DB      'READ'
689
        ;
690
T_DATA  EQU     T_REM+6         ;DATA
691
        DB      T_DATA
692
        DB      'DATA'
693
        ;
694
        DB      T_DATA+1        ;RETURN
695
        DB      'RETURN'
696
        ;
697
        DB      T_DATA+2        ;IF
698
        DB      'IF'
699
        ;
700
T_GOSB  EQU     T_DATA+3        ;GOSUB
701
        DB      T_GOSB
702
        DB      'GOSUB'
703
        ;
704
        DB      T_GOSB+1        ;FOR
705
        DB      'FOR'
706
        ;
707
        DB      T_GOSB+2        ;WHILE
708
        DB      'WHILE'
709
        ;
710
        DB      T_GOSB+3        ;UNTIL
711
        DB      'UNTIL'
712
        ;
713
        DB      T_GOSB+4        ;END
714
        DB      'END'
715
        ;
716
$EJECT
717
T_LAST  EQU     T_GOSB+5        ;LAST INITIAL TOKEN
718
        ;
719
T_TAB   EQU     T_LAST          ;TAB TOKEN
720
        DB      T_TAB
721
        DB      'TAB'
722
        ;
723
T_THEN  EQU     T_LAST+1        ;THEN TOKEN
724
        DB      T_THEN
725
        DB      'THEN'
726
        ;
727
T_TO    EQU     T_LAST+2        ;TO TOKEN
728
        DB      T_TO
729
        DB      'TO'
730
        ;
731
T_STEP  EQU     T_LAST+3        ;STEP TOKEN
732
        DB      T_STEP
733
        DB      'STEP'
734
        ;
735
T_ELSE  EQU     T_LAST+4        ;ELSE TOKEN
736
        DB      T_ELSE
737
        DB      'ELSE'
738
        ;
739
T_SPC   EQU     T_LAST+5        ;SPACE TOKEN
740
        DB      T_SPC
741
        DB      'SPC'
742
        ;
743
T_CR    EQU     T_LAST+6
744
        DB      T_CR
745
        DB      'CR'
746
        ;
747
        DB      T_CR+1
748
        DB      'IDLE'
749
        ;
750
        DB      T_CR+2
751
        DB      'ST@'
752
        ;
753
        DB      T_CR+3
754
        DB      'LD@'
755
        ;
756
        DB      T_CR+4
757
        DB      'PGM'
758
        ;
759
        DB      T_CR+5
760
        DB      'RROM'
761
        ;
762
$EJECT
763
        ; Operator tokens
764
        ;
765
T_LPAR  EQU     0E0H            ;LEFT PAREN
766
        DB      T_LPAR
767
        DB      '('
768
        ;
769
        DB      T_LPAR+1        ;EXPONENTIAN
770
        DB      '**'
771
        ;
772
        DB      T_LPAR+2        ;FP MULTIPLY
773
        DB      '*'
774
        ;
775
T_ADD   EQU     T_LPAR+3
776
        DB      T_LPAR+3        ;ADD TOKEN
777
        DB      '+'
778
        ;
779
        DB      T_LPAR+4        ;DIVIDE TOKEN
780
        DB      '/'
781
        ;
782
T_SUB   EQU     T_LPAR+5        ;SUBTRACT TOKEN
783
        DB      T_SUB
784
        DB      '-'
785
        ;
786
        DB      T_LPAR+6        ;LOGICAL EXCLUSIVE OR
787
        DB      '.XOR.'
788
        ;
789
        DB      T_LPAR+7        ;LOGICAL AND
790
        DB      '.AND.'
791
        ;
792
        DB      T_LPAR+8        ;LOGICAL OR
793
        DB      '.OR.'
794
        ;
795
T_NEG   EQU     T_LPAR+9
796
        ;
797
T_EQU   EQU     T_LPAR+10       ;EQUAL
798
        DB      T_EQU
799
        DB      '='
800
        ;
801
        DB      T_LPAR+11       ;GREATER THAN OR EQUAL
802
        DB      '>='
803
        ;
804
        DB      T_LPAR+12       ;LESS THAN OR EQUAL
805
        DB      '<='
806
        ;
807
        DB      T_LPAR+13       ;NOT EQUAL
808
        DB      '<>'
809
        ;
810
        DB      T_LPAR+14       ;LESS THAN
811
        DB      '<'
812
        ;
813
        DB      T_LPAR+15       ;GREATER THAN
814
        DB      '>'
815
        ;
816
        ;
817
T_UOP   EQU     0B0H            ;UNARY OP BASE TOKEN
818
        ;
819
        DB      T_UOP           ;ABS TOKEN
820
        DB      'ABS'
821
        ;
822
        DB      T_UOP+1         ;INTEGER TOKEN
823
        DB      'INT'
824
        ;
825
        DB      T_UOP+2         ;SIGN TOKEN
826
        DB      'SGN'
827
        ;
828
        DB      T_UOP+3         ;GET TOKEN
829
        DB      'NOT'
830
        ;
831
        DB      T_UOP+4         ;COSINE TOKEN
832
        DB      'COS'
833
        ;
834
        DB      T_UOP+5         ;TANGENT TOKEN
835
        DB      'TAN'
836
        ;
837
        DB      T_UOP+6         ;SINE TOKEN
838
        DB      'SIN'
839
        ;
840
        DB      T_UOP+7         ;SQUARE ROOT TOKEN
841
        DB      'SQR'
842
        ;
843
        DB      T_UOP+8         ;CBYTE TOKEN
844
        DB      'CBY'
845
        ;
846
        DB      T_UOP+9         ;EXP (E TO THE X) TOKEN
847
        DB      'EXP'
848
        ;
849
        DB      T_UOP+10
850
        DB      'ATN'
851
        ;
852
        DB      T_UOP+11
853
        DB      'LOG'
854
        ;
855
        DB      T_UOP+12        ;DBYTE TOKEN
856
        DB      'DBY'
857
        ;
858
        DB      T_UOP+13        ;XBYTE TOKEN
859
        DB      'XBY'
860
        ;
861
T_ULAST EQU     T_UOP+14        ;LAST OPERATOR NEEDING PARENS
862
        ;
863
        DB      T_ULAST
864
        DB      'PI'
865
        ;
866
        DB      T_ULAST+1       ;RND TOKEN
867
        DB      'RND'
868
        ;
869
        DB      T_ULAST+2       ;GET TOKEN
870
        DB      'GET'
871
        ;
872
        DB      T_ULAST+3       ;FREE TOKEN
873
        DB      'FREE'
874
        ;
875
        DB      T_ULAST+4       ;LEN TOKEN
876
        DB      'LEN'
877
        ;
878
T_XTAL  EQU     T_ULAST+5       ;CRYSTAL TOKEN
879
        DB      T_XTAL
880
        DB      'XTAL'
881
        ;
882
T_MTOP  EQU     T_ULAST+6       ;MTOP
883
        DB      T_MTOP
884
        DB      'MTOP'
885
        ;
886
T_IE    EQU     T_ULAST+8       ;IE REGISTER
887
        DB      T_IE
888
        DB      'IE'
889
        ;
890
T_IP    EQU     T_ULAST+9       ;IP REGISTER
891
        DB      T_IP
892
        DB      'IP'
893
        ;
894
TMR0    EQU     T_ULAST+10      ;TIMER 0
895
        DB      TMR0
896
        DB      'TIMER0'
897
        ;
898
TMR1    EQU     T_ULAST+11      ;TIMER 1
899
        DB      TMR1
900
        DB      'TIMER1'
901
        ;
902
TMR2    EQU     T_ULAST+12      ;TIMER 2
903
        DB      TMR2
904
        DB      'TIMER2'
905
        ;
906
T_TIME  EQU     T_ULAST+7       ;TIME
907
        DB      T_TIME
908
        DB      'TIME'
909
        ;
910
TT2C    EQU     T_ULAST+13      ;T2CON
911
        DB      TT2C
912
        DB      'T2CON'
913
        ;
914
TTC     EQU     T_ULAST+14      ;TCON
915
        DB      TTC
916
        DB      'TCON'
917
        ;
918
TTM     EQU     T_ULAST+15      ;TMOD
919
        DB      TTM
920
        DB      'TMOD'
921
        ;
922
TRC2    EQU     T_ULAST+16      ;RCAP2
923
        DB      TRC2
924
        DB      'RCAP2'
925
        ;
926
T_P1    EQU     T_ULAST+17      ;P1
927
        DB      T_P1
928
        DB      'PORT1'
929
        ;
930
T_PC    EQU     T_ULAST+18      ;PCON
931
        DB      T_PC
932
        DB      'PCON'
933
        ;
934
T_ASC   EQU     T_ULAST+19      ;ASC TOKEN
935
        DB      T_ASC
936
        DB      'ASC('
937
        ;
938
T_USE   EQU     T_ULAST+20      ;USING TOKEN
939
        DB      T_USE
940
        DB      'USING('
941
        DB      T_USE
942
        DB      'U.('
943
        ;
944
T_CHR   EQU     T_ULAST+21      ;CHR TOKEN
945
        DB      T_CHR
946
        DB      'CHR('
947
        ;
948
$EJECT
949
T_CMND  EQU     0F0H            ;COMMAND BASE
950
        ;
951
        DB      0F0H            ;RUN TOKEN
952
        DB      'RUN'
953
        ;
954
        DB      0F1H            ;LIST TOKEN
955
        DB      'LIST'
956
        ;
957
        DB      0F2H            ;NULL TOKEN
958
        DB      'NULL'
959
        ;
960
        DB      0F3H            ;NEW TOKEN
961
        DB      'NEW'
962
        ;
963
        DB      0F4H            ;CONTINUE TOKEN
964
        DB      'CONT'
965
        ;
966
        DB      0F5H            ;PROGRAM TOKEN
967
        DB      'PROG'
968
        ;
969
        DB      0F6H            ;TRANSFER TOKEN
970
        DB      'XFER'
971
        ;
972
        DB      0F7H            ;RAM MODE
973
        DB      'RAM'
974
        ;
975
        DB      0F8H            ;ROM MODE
976
        DB      'ROM'
977
        ;
978
        DB      0F9H            ;INTELLIGENT PROM PROGRAMMING
979
        DB      'FPROG'
980
        ;
981
        DB      0FFH            ;END OF TABLE
982
        ;
983
 
984
; END OF INCLUDE LOOK52
985
;$INCLUDE(:F2:LOOK52.SRC)
986
        ;
987
EIG:    DB      'EXTRA IGNORED"'
988
        ;
989
EXA:    DB      'A-STACK"'
990
        ;
991
EXC:    DB      'C-STACK"'
992
        ;
993
$EJECT
994
;$INCLUDE(:F2:BAS52.RST)
995
; BEGINNING
996
 
997
        ;**************************************************************
998
        ;
999
CRST:   ; This performs system initialzation, it was moved here so the
1000
        ; new power on reset functions could be tested in an 8751.
1001
        ;
1002
        ;**************************************************************
1003
        ;
1004
        ; First, initialize SFR's
1005
        ;
1006
        MOV     SCON,#5AH       ;INITIALIZE SFR'S
1007
        MOV     TMOD,#10H
1008
        MOV     TCON,#54H
1009 7 jesus
        MOV     T2CON,#34H
1010 6 jesus
;       DB      75H             ;MOV DIRECT, # OP CODE
1011
;       DB      0C8H            ;T2CON LOCATION
1012
;       DB      34H             ;CONFIGURATION BYTE
1013
        ;
1014
        MOV     DPTR,#2001H     ;READ CODE AT 2001H
1015
        CLR     A
1016
        MOVC    A,@A+DPTR
1017
        CJNE    A,#0AAH,CRST1   ;IF IT IS AN AAH, DO USER RESET
1018
        LCALL   2090H
1019
        ;
1020
CRST1:  MOV     R0,#IRAMTOP     ;PUT THE TOP OF RAM IN R0
1021
        CLR     A               ;ZERO THE ACC
1022
        ;
1023
CRST2:  MOV     @R0,A           ;CLEAR INTERNAL MEMORY
1024
        DJNZ    R0,CRST2        ;LOOP TIL DONE
1025
        ;
1026
        ; Now, test the external memory
1027
        ;
1028
        MOV     SPSAV,#CMNDSP   ;SET UP THE STACK
1029
        MOV     SP,SPSAV
1030
        ;
1031
        MOV     BOFAH,#HIGH ROMADR
1032
        MOV     BOFAL,#LOW ROMADR+17
1033
        MOV     DPTR,#ROMADR    ;GET THE BYTE AT 8000H
1034
        MOVX    A,@DPTR
1035
        CLR     C
1036
        SUBB    A,#31H          ;FOR BIAS
1037
        MOV     MT1,A           ;SAVE IN DIRECT MATH LOC
1038
        CLR     ACC.2           ;SAVE FOR RESET
1039
        MOV     R7,A            ;SAVE IT IN R7
1040
        INC     DPTR
1041
        ACALL   L31DPI          ;SAVE BAUD RATE
1042
        LCALL   RCL
1043
        INC     DPTR            ;GET MEMTOP
1044
        ACALL   L31DPI
1045
        MOV     DPTR,#5FH       ;READ THE EXTERNAL BYTE
1046
        MOVX    A,@DPTR
1047
        MOV     DPTR,#0         ;ESTABLISH BASE FOR CLEAR
1048
        CJNE    A,#0A5H,CRS
1049
        MOV     A,MT1
1050
        CLR     ACC.0           ;CLEAR BIT ONE
1051
        XRL     A,#4H
1052
        JZ      CR2
1053
        ;
1054
CRS:    CJNE    R7,#2,CRS1
1055
        SJMP    CRS2
1056
CRS1:   CJNE    R7,#3,CR0
1057
CRS2:   ACALL   CL_1
1058
        SJMP    CR1
1059
        ;
1060
CR0:    MOV     R3,DPH          ;SAVE THE DPTR
1061
        MOV     R1,DPL
1062
        INC     DPTR
1063
        MOV     A,#5AH
1064
        MOVX    @DPTR,A
1065
        MOVX    A,@DPTR
1066
        CJNE    A,#5AH,CR1
1067
        CLR     A
1068
        MOVX    @DPTR,A
1069
        CJNE    R3,#0E0H,CR0
1070
        ;
1071
CR1:    CJNE    R3,#03H,CR11    ;NEED THIS MUCH RAM
1072
CR11:   JC      CRST
1073
        MOV     DPTR,#MEMTOP    ;SAVE MEMTOP
1074
        ACALL   S31DP2          ;SAVE MEMTOP AND SEED RCELL
1075
        ACALL   CNEW            ;CLEAR THE MEMORY AND SET UP POINTERS
1076
        ;
1077
CR2:    ACALL   RC1             ;SET UP STACKS IF NOT DONE
1078
        ;
1079
        LCALL   AXTAL0          ;DO THE CRYSTAL
1080
        MOV     A,MT1           ;GET THE RESET BYTE
1081
        CJNE    A,#5,CR20
1082
        LCALL   4039H
1083
CR20:   JNC     BG1             ;CHECK FOR 0,1,2,3, OR 4
1084
        JNB     ACC.0,BG3       ;NO RUN IF WRONG TYPE
1085
        MOV     DPTR,#ROMADR+16
1086
        MOVX    A,@DPTR         ;READ THE BYTE
1087
        CJNE    A,#55H,BG3
1088
        LJMP    CRUN
1089 7 jesus
 
1090
        ; START OF BAUD RATE MODIFICATIONS BY DANIEL WALLNER
1091
 
1092 6 jesus
BG1:    CLR     A               ;DO BAUD RATE
1093
        MOV     R3,A
1094
        MOV     R1,A
1095 7 jesus
        MOV     TL2,A
1096
        CLR     T2CON.2
1097 6 jesus
        JB      RXD,$           ;LOOP UNTIL A CHARACTER IS RECEIVED
1098 7 jesus
        MOV     T2CON,#5
1099
        CALL    TIB2
1100 6 jesus
        JNB     RXD,$
1101 7 jesus
        MOV     T2CON,#34H
1102 6 jesus
        CALL    RCL             ;LOAD THE TIMER
1103 7 jesus
        NOP
1104
        NOP
1105
 
1106
        ; END OF BAUD RATE MODIFICATIONS BY DANIEL WALLNER
1107
 
1108
 
1109 6 jesus
BG3:    MOV     DPTR,#S_N       ;GET THE MESSAGE
1110
        ACALL   CRP             ;PRINT IT
1111
        LJMP    CRAM
1112
 
1113
; END
1114
;$INCLUDE(:F2:BAS52.RST)
1115
        ;
1116
$EJECT
1117
        ;***************************************************************
1118
        ;
1119
        ; CIPROG AND CPROG - Program a prom
1120
        ;
1121
        ;***************************************************************
1122
        ;
1123
;$INCLUDE(:F2:BAS52.PGM)
1124
;BEGINNING
1125
 
1126
PG8:    MOV     R7,#00H         ;PROGRAM ONE BYTE AT A TIME
1127
        MOV     R6,#01H
1128
        MOV     R2,#HIGH ROMADR-1
1129
        MOV     R0,#LOW ROMADR-1;LOAD PROM ADDRESS
1130
        ACALL   PG101
1131
        INC     R6
1132
        MOV     A,RCAPH2
1133
;       DB      0E5H            ;MOV A DIRECT OP CODE
1134
;       DB      0CBH            ;ADDRESS OF R2CAP HIGH
1135
        ACALL   PG101
1136
        MOV     A,RCAPL2
1137
;       DB      0E5H            ;MOV A, DIRECT OP CODE
1138
;       DB      0CAH            ;R2CAP LOW
1139
        MOV     R6,#3
1140
        MOV     R1,#LOW MEMTOP-1
1141
        MOV     R3,#HIGH MEMTOP
1142
        ACALL   PG101           ;SAVE MEMTOP
1143
        SJMP    PGR
1144
        ;
1145
CIPROG: MOV     DPTR,#IPROGS    ;LOAD IPROG LOCATION
1146
        SETB    INTELB
1147
        SJMP    CPROG1          ;GO DO PROG
1148
        ;
1149
CPROG:  MOV     DPTR,#PROGS     ;LOAD PROG LOCATION
1150
        CLR     INTELB
1151
        ;
1152
CPROG1: ACALL   LD_T            ;LOAD THE TIMER
1153
        CLR     PROMV           ;TURN ON THE PROM VOLTAGE
1154
        CALL    DELTST          ;SEE IF A CR
1155
        JNZ     PG8             ;SAVE TIMER IF SO
1156
        MOV     R4,#0FEH
1157
        SETB    INBIT
1158
        ACALL   ROMFD           ;GET THE ROM ADDRESS OF THE LAST LOCATION
1159
        CALL    TEMPD           ;SAVE THE ADDRESS
1160
        MOV     A,R4            ;GET COUNT
1161
        CPL     A
1162
        CALL    TWO_R2          ;PUT IT ON THE STACK
1163
        CALL    FP_BASE7        ;OUTPUT IT
1164
        ACALL   CCAL            ;GET THE PROGRAM
1165
        ACALL   CRLF            ;DO CRLF
1166
        MOV     R0,TEMP4        ;GET ADDRESS
1167
        MOV     R2,TEMP5
1168
        MOV     A,#55H          ;LOAD SIGNIFIER
1169
        INC     R6              ;LOAD LEN + 1
1170
        CJNE    R6,#00,CPROG2
1171
        INC     R7
1172
CPROG2: ACALL   PG102
1173
        ;
1174
$EJECT
1175
PGR:    SETB    PROMV
1176
        AJMP    C_K
1177
        ;
1178
PG1:    MOV     P2,R3           ;GET THE BYTE TO PROGRAM
1179
        MOVX    A,@R1
1180
PG101:  LCALL   INC3210         ;BUMP POINTERS
1181
PG102:  MOV     R5,#1           ;SET UP INTELLIGENT COUMTER
1182
        ;
1183
PG2:    MOV     R4,A            ;SAVE THE BYTE IN R4
1184
        ACALL   PG7             ;PROGRAM THE BYTE
1185
        ACALL   PG9
1186
        JB      INTELB,PG4      ;SEE IF INTELLIGENT PROGRAMMING
1187
        ;
1188
PG3:    XRL     A,R4
1189
        JNZ     PG6             ;ERROR IF NOT THE SAME
1190
        CALL    DEC76           ;BUMP THE COUNTERS
1191
        JNZ     PG1             ;LOOP IF NOT DONE
1192
        ANL     PSW,#11100111B  ;INSURE RB0
1193
PG31:   RET
1194
        ;
1195
PG4:    XRL     A,R4            ;SEE IF PROGRAMMED
1196
        JNZ     PG5             ;JUMP IF NOT
1197
        MOV     A,R4            ;GET THE DATA BACK
1198
        ACALL   PG7             ;PROGRAM THE LOCATION
1199
PG41:   ACALL   ZRO             ;AGAIN
1200
        ACALL   ZRO             ;AND AGAIN
1201
        ACALL   ZRO             ;AND AGAIN
1202
        DJNZ    R5,PG41         ;KEEP DOING IT
1203
        ACALL   PG9             ;RESET PROG
1204
        SJMP    PG3             ;FINISH THE LOOP
1205
        ;
1206
PG5:    INC     R5              ;BUMP THE COUNTER
1207
        MOV     A,R4            ;GET THE BYTE
1208
        CJNE    R5,#25,PG2      ;SEE IF TRIED 25 TIMES
1209
        ;
1210
PG6:    SETB    PROMV           ;TURN OFF PROM VOLTAGE
1211
        MOV     PSW,#0          ;INSURE RB0
1212
        JNB     DIRF,PG31       ;EXIT IF IN RUN MODE
1213
        MOV     DPTR,#E16X      ;PROGRAMMING ERROR
1214
        ;
1215
ERRLK:  LJMP    ERROR           ;PROCESS THE ERROR
1216
        ;
1217
$EJECT
1218
PG7:    MOV     P0,R0           ;SET UP THE PORTS
1219
        MOV     P2,R2           ;LATCH LOW ORDER ADDRESS
1220
        ACALL   PG11            ;DELAY FOR 8748/9
1221
        CLR     ALED
1222
        MOV     P0,A            ;PUT DATA ON THE PORT
1223
        ;
1224
ZRO:    NOP                     ;SETTLEING TIME + FP ZERO
1225
        NOP
1226
        NOP
1227
        NOP
1228
        NOP
1229
        NOP
1230
        ACALL   PG11            ;DELAY A WHILE
1231
        CLR     PROMP           ;START PROGRAMMING
1232
        ACALL   TIMER_LOAD      ;START THE TIMER
1233
        JNB     TF1,$           ;WAIT FOR PART TO PROGRAM
1234
        RET                     ;EXIT
1235
        ;
1236
PG9:    SETB    PROMP
1237
        ACALL   PG11            ;DELAY FOR A WHILE
1238
        JNB     P3.2,$          ;LOOP FOR EEPROMS
1239
        MOV     P0,#0FFH
1240
        CLR     P3.7            ;LOWER READ
1241
        ACALL   PG11
1242
        MOV     A,P0            ;READ THE PORT
1243
        SETB    P3.7
1244
        SETB    ALED
1245
        RET
1246
        ;
1247
PG11:   MOV     TEMP5,#12       ;DELAY 30uS AT 12 MHZ
1248
        DJNZ    TEMP5,$
1249
        RET
1250
        ;
1251
 
1252
;END
1253
;$INCLUDE(:F2:BAS52.PGM)
1254
$EJECT
1255
        ;**************************************************************
1256
        ;
1257
PGU:    ;PROGRAM A PROM FOR THE USER
1258
        ;
1259
        ;**************************************************************
1260
        ;
1261
        CLR     PROMV           ;TURN ON THE VOLTAGE
1262
        MOV     PSW,#00011000B  ;SELECT RB3
1263
        ACALL   PG1             ;DO IT
1264
        SETB    PROMV           ;TURN IT OFF
1265
        RET
1266
        ;
1267
        ;
1268
        ;*************************************************************
1269
        ;
1270
CCAL:   ; Set up for prom moves
1271
        ; R3:R1 gets source
1272
        ; R7:R6 gets # of bytes
1273
        ;
1274
        ;*************************************************************
1275
        ;
1276
        ACALL   GETEND          ;GET THE LAST LOCATION
1277
        INC     DPTR            ;BUMP TO LOAD EOF
1278
        MOV     R3,BOFAH
1279
        MOV     R1,BOFAL        ;RESTORE START
1280
        CLR     C               ;PREPARE FOR SUBB
1281
        MOV     A,DPL           ;SUB DPTR - BOFA > R7:R6
1282
        SUBB    A,R1
1283
        MOV     R6,A
1284
        MOV     A,DPH
1285
        SUBB    A,R3
1286
        MOV     R7,A
1287
CCAL1:  RET
1288
        ;
1289
        ;
1290
;$INCLUDE(:F2:BAS52.TL)
1291
;BEGINNING
1292
 
1293
        ;**************************************************************
1294
        ;
1295
TIMER_LOAD:; Load the timer
1296
        ;
1297
        ;*************************************************************
1298
        ;
1299
        ACALL   CCAL1           ;DELAY FOUR CLOCKS
1300
TIMER_LOAD1:
1301
        CLR     TR1             ;STOP IT WHILE IT'S LOADED
1302
        MOV     TH1,T_HH
1303
        MOV     TL1,T_LL
1304
        CLR     TF1             ;CLEAR THE OVERFLOW FLAG
1305
        SETB    TR1             ;START IT NOW
1306
        RET
1307
        ;
1308
 
1309
;END
1310
;$INCLUDE(:F2:BAS52.TL)
1311
$EJECT
1312
        ;***************************************************************
1313
        ;
1314
CROM:   ; The command action routine - ROM - Run out of rom
1315
        ;
1316
        ;***************************************************************
1317
        ;
1318
        CLR     CONB            ;CAN'T CONTINUE IF MODE CHANGE
1319
        ACALL   RO1             ;DO IT
1320
        ;
1321
C_K:    LJMP    CL3             ;EXIT
1322
        ;
1323
;RO1:    CALL    INTGER          ;SEE IF INTGER PRESENT
1324
;        MOV     R4,R0B0         ;SAVE THE NUMBER
1325
;        JNC     $+4
1326
;        MOV     R4,#01H         ;ONE IF NO INTEGER PRESENT
1327
;        CALL   ROMFD           ;FIND THE PROGRAM
1328
;       ACALL   ROMFD           ;FIND THE PROGRAM
1329
 
1330
RO1:    CALL    DELTST
1331
        MOV     R4,#1
1332
        JNC     RO11
1333
        CALL    ONE
1334
        MOV     R4,A
1335
RO11:   ACALL   ROMFD
1336
        CJNE    R4,#0,RFX       ;EXIT IF R4 <> 0
1337
        INC     DPTR            ;BUMP PAST TAG
1338
        MOV     BOFAH,DPH       ;SAVE THE ADDRESS
1339
        MOV     BOFAL,DPL
1340
        RET
1341
        ;
1342
ROMFD:  MOV     DPTR,#ROMADR+16 ;START OF USER PROGRAM
1343
        ;
1344
RF1:    MOVX    A,@DPTR         ;GET THE BYTE
1345
        CJNE    A,#55H,RF3      ;SEE IF PROPER TAG
1346
        DJNZ    R4,RF2          ;BUMP COUNTER
1347
        ;
1348
RFX:    RET                     ;DPTR HAS THE START ADDRESS
1349
        ;
1350
RF2:    INC     DPTR            ;BUMP PAST TAG
1351
        ACALL   G5
1352
        INC     DPTR            ;BUMP TO NEXT PROGRAM
1353
        SJMP    RF1             ;DO IT AGAIN
1354
        ;
1355
RF3:    JBC     INBIT,RFX       ;EXIT IF SET
1356
        ;
1357
NOGO:   MOV     DPTR,#NOROM
1358
        AJMP    ERRLK
1359
        ;
1360
$EJECT
1361
        ;***************************************************************
1362
        ;
1363
L20DPI: ; load R2:R0 with the location the DPTR is pointing to
1364
        ;
1365
        ;***************************************************************
1366
        ;
1367
        MOVX    A,@DPTR
1368
        MOV     R2,A
1369
        INC     DPTR
1370
        MOVX    A,@DPTR
1371
        MOV     R0,A
1372
        RET                     ;DON'T BUMP DPTR
1373
        ;
1374
        ;***************************************************************
1375
        ;
1376
X31DP:  ; swap R3:R1 with DPTR
1377
        ;
1378
        ;***************************************************************
1379
        ;
1380
        XCH     A,R3
1381
        XCH     A,DPH
1382
        XCH     A,R3
1383
        XCH     A,R1
1384
        XCH     A,DPL
1385
        XCH     A,R1
1386
        RET
1387
        ;
1388
        ;***************************************************************
1389
        ;
1390
LD_T:   ; Load the timer save location with the value the DPTR is
1391
        ; pointing to.
1392
        ;
1393
        ;****************************************************************
1394
        ;
1395
        MOVX    A,@DPTR
1396
        MOV     T_HH,A
1397
        INC     DPTR
1398
        MOVX    A,@DPTR
1399
        MOV     T_LL,A
1400
        RET
1401
        ;
1402
$EJECT
1403
        ;
1404
        ;***************************************************************
1405
        ;
1406
        ;GETLIN - FIND THE LOCATION OF THE LINE NUMBER IN R3:R1
1407
        ;         IF ACC = 0 THE LINE WAS NOT FOUND I.E. R3:R1
1408
        ;         WAS TOO BIG, ELSE ACC <> 0 AND THE DPTR POINTS
1409
        ;         AT THE LINE THAT IS GREATER THAN OR EQUAL TO THE
1410
        ;         VALUE IN R3:R1.
1411
        ;
1412
        ;***************************************************************
1413
        ;
1414
GETEND: SETB    ENDBIT          ;GET THE END OF THE PROGRAM
1415
        ;
1416
GETLIN: CALL    DP_B            ;GET BEGINNING ADDRESS
1417
        ;
1418
G1:     CALL    B_C
1419
        JZ      G3              ;EXIT WITH A ZERO IN A IF AT END
1420
        INC     DPTR            ;POINT AT THE LINE NUMBER
1421
        JB      ENDBIT,G2       ;SEE IF WE WANT TO FIND THE END
1422
        ACALL   DCMPX           ;SEE IF (DPTR) = R3:R1
1423
        ACALL   DECDP           ;POINT AT LINE COUNT
1424
        MOVX    A,@DPTR         ;PUT LINE LENGTH INTO ACC
1425
        JB      UBIT,G3         ;EXIT IF EQUAL
1426
        JC      G3              ;SEE IF LESS THAN OR ZERO
1427
        ;
1428
G2:     ACALL   ADDPTR          ;ADD IT TO DPTR
1429
        SJMP    G1              ;LOOP
1430
        ;
1431
G3:     CLR     ENDBIT          ;RESET ENDBIT
1432
        RET                     ;EXIT
1433
        ;
1434
G4:     MOV     DPTR,#PSTART    ;DO RAM
1435
        ;
1436
G5:     SETB    ENDBIT
1437
        SJMP    G1              ;NOW DO TEST
1438
        ;
1439
$EJECT
1440
        ;***************************************************************
1441
        ;
1442
        ; LDPTRI - Load the DATA POINTER with the value it is pointing
1443
        ;          to - DPH = (DPTR) , DPL = (DPTR+1)
1444
        ;
1445
        ; acc gets wasted
1446
        ;
1447
        ;***************************************************************
1448
        ;
1449
LDPTRI: MOVX    A,@DPTR         ;GET THE HIGH BYTE
1450
        PUSH    ACC             ;SAVE IT
1451
        INC     DPTR            ;BUMP THE POINTER
1452
        MOVX    A,@DPTR         ;GET THE LOW BYTE
1453
        MOV     DPL,A           ;PUT IT IN DPL
1454
        POP     DPH             ;GET THE HIGH BYTE
1455
        RET                     ;GO BACK
1456
        ;
1457
        ;***************************************************************
1458
        ;
1459
        ;L31DPI - LOAD R3 WITH (DPTR) AND R1 WITH (DPTR+1)
1460
        ;
1461
        ;ACC GETS CLOBBERED
1462
        ;
1463
        ;***************************************************************
1464
        ;
1465
L31DPI: MOVX    A,@DPTR         ;GET THE HIGH BYTE
1466
        MOV     R3,A            ;PUT IT IN THE REG
1467
        INC     DPTR            ;BUMP THE POINTER
1468
        MOVX    A,@DPTR         ;GET THE NEXT BYTE
1469
        MOV     R1,A            ;SAVE IT
1470
        RET
1471
        ;
1472
        ;***************************************************************
1473
        ;
1474
        ;DECDP - DECREMENT THE DATA POINTER - USED TO SAVE SPACE
1475
        ;
1476
        ;***************************************************************
1477
        ;
1478
DECDP2: ACALL   DECDP
1479
        ;
1480
DECDP:  XCH     A,DPL           ;GET DPL
1481
        JNZ     DECDP1          ;BUMP IF ZERO
1482
        DEC     DPH
1483
DECDP1: DEC     A               ;DECREMENT IT
1484
        XCH     A,DPL           ;GET A BACK
1485
        RET                     ;EXIT
1486
        ;
1487
$EJECT
1488
        ;***************************************************************
1489
        ;
1490
        ;DCMPX - DOUBLE COMPARE - COMPARE (DPTR) TO R3:R1
1491
        ;R3:R1 - (DPTR) = SET CARRY FLAG
1492
        ;
1493
        ;IF R3:R1 > (DPTR) THEN C = 0
1494
        ;IF R3:R1 < (DPTR) THEN C = 1
1495
        ;IF R3:R1 = (DPTR) THEN C = 0
1496
        ;
1497
        ;***************************************************************
1498
        ;
1499
DCMPX:  CLR     UBIT            ;ASSUME NOT EQUAL
1500
        MOVX    A,@DPTR         ;GET THE BYTE
1501
        CJNE    A,R3B0,D1       ;IF A IS GREATER THAN R3 THEN NO CARRY
1502
                                ;WHICH IS R3<@DPTR = NO CARRY AND
1503
                                ;R3>@DPTR CARRY IS SET
1504
        INC     DPTR            ;BUMP THE DATA POINTER
1505
        MOVX    A,@DPTR         ;GET THE BYTE
1506
        ACALL   DECDP           ;PUT DPTR BACK
1507
        CJNE    A,R1B0,D1       ;DO THE COMPARE
1508
        CPL     C               ;FLIP CARRY
1509
        ;
1510
        CPL     UBIT            ;SET IT
1511
D1:     CPL     C               ;GET THE CARRY RIGHT
1512
        RET                     ;EXIT
1513
        ;
1514
        ;***************************************************************
1515
        ;
1516
        ; ADDPTR - Add acc to the dptr
1517
        ;
1518
        ; acc gets wasted
1519
        ;
1520
        ;***************************************************************
1521
        ;
1522
ADDPTR: ADD     A,DPL           ;ADD THE ACC TO DPL
1523
        MOV     DPL,A           ;PUT IT IN DPL
1524
        JNC     ADDPTR1         ;JUMP IF NO CARRY
1525
        INC     DPH             ;BUMP DPH
1526
ADDPTR1:RET                     ;EXIT
1527
        ;
1528
$EJECT
1529
        ;*************************************************************
1530
        ;
1531
LCLR:   ; Set up the storage allocation
1532
        ;
1533
        ;*************************************************************
1534
        ;
1535
        ACALL   ICLR            ;CLEAR THE INTERRUPTS
1536
        ACALL   G4              ;PUT END ADDRESS INTO DPTR
1537
        MOV     A,#6            ;ADJUST MATRIX SPACE
1538
        ACALL   ADDPTR          ;ADD FOR PROPER BOUNDS
1539
        ACALL   X31DP           ;PUT MATRIX BOUNDS IN R3:R1
1540
        MOV     DPTR,#MT_ALL    ;SAVE R3:R1 IN MATRIX FREE SPACE
1541
        ACALL   S31DP           ;DPTR POINTS TO MEMTOP
1542
        ACALL   L31DPI          ;LOAD MEMTOP INTO R3:R1
1543
        MOV     DPTR,#STR_AL    ;GET MEMORY ALLOCATED FOR STRINGS
1544
        ACALL   LDPTRI
1545
        CALL    DUBSUB          ;R3:R1 = MEMTOP - STRING ALLOCATION
1546
        MOV     DPTR,#VARTOP    ;SAVE R3:R1 IN VARTOP
1547
        ;
1548
        ; FALL THRU TO S31DP2
1549
        ;
1550
        ;***************************************************************
1551
        ;
1552
        ;S31DP - STORE R3 INTO (DPTR) AND R1 INTO (DPTR+1)
1553
        ;
1554
        ;ACC GETS CLOBBERED
1555
        ;
1556
        ;***************************************************************
1557
        ;
1558
S31DP2: ACALL   S31DP           ;DO IT TWICE
1559
        ;
1560
S31DP:  MOV     A,R3            ;GET R3 INTO ACC
1561
        MOVX    @DPTR,A         ;STORE IT
1562
        INC     DPTR            ;BUMP DPTR
1563
        MOV     A,R1            ;GET R1
1564
        MOVX    @DPTR,A         ;STORE IT
1565
        INC     DPTR            ;BUMP IT AGAIN TO SAVE PROGRAM SPACE
1566
        RET                     ;GO BACK
1567
        ;
1568
        ;
1569
        ;***************************************************************
1570
        ;
1571
STRING: ; Allocate memory for strings
1572
        ;
1573
        ;***************************************************************
1574
        ;
1575
        LCALL   TWO             ;R3:R1 = NUMBER, R2:R0 = LEN
1576
        MOV     DPTR,#STR_AL    ;SAVE STRING ALLOCATION
1577
        ACALL   S31DP
1578
        INC     R6              ;BUMP
1579
        MOV     S_LEN,R6        ;SAVE STRING LENGTH
1580
        AJMP    RCLEAR          ;CLEAR AND SET IT UP
1581
        ;
1582
$EJECT
1583
        ;***************************************************************
1584
        ;
1585
        ; F_VAR - Find  the variable in symbol table
1586
        ;         R7:R6 contain the variable name
1587
        ;         If not found create a zero entry and set the carry
1588
        ;         R2:R0 has the address of variable on return
1589
        ;
1590
        ;***************************************************************
1591
        ;
1592
F_VAR:  MOV     DPTR,#VARTOP    ;PUT VARTOP IN DPTR
1593
        ACALL   LDPTRI
1594
        ACALL   DECDP2          ;ADJUST DPTR FOR LOOKUP
1595
        ;
1596
F_VAR0: MOVX    A,@DPTR         ;LOAD THE VARIABLE
1597
        JZ      F_VAR2          ;TEST IF AT THE END OF THE TABLE
1598
        INC     DPTR            ;BUMP FOR NEXT BYTE
1599
        CJNE    A,R7B0,F_VAR1   ;SEE IF MATCH
1600
        MOVX    A,@DPTR         ;LOAD THE NAME
1601
        CJNE    A,R6B0,F_VAR1
1602
        ;
1603
        ; Found the variable now adjust and put in R2:R0
1604
        ;
1605
DLD:    MOV     A,DPL           ;R2:R0 = DPTR-2
1606
        SUBB    A,#2
1607
        MOV     R0,A
1608
        MOV     A,DPH
1609
        SUBB    A,#0            ;CARRY IS CLEARED
1610
        MOV     R2,A
1611
        RET
1612
        ;
1613
F_VAR1: MOV     A,DPL           ;SUBTRACT THE STACK SIZE+ADJUST
1614
        CLR     C
1615
        SUBB    A,#STESIZ
1616
        MOV     DPL,A           ;RESTORE DPL
1617
        JNC     F_VAR0
1618
        DEC     DPH
1619
        SJMP    F_VAR0          ;CONTINUE COMPARE
1620
        ;
1621
$EJECT
1622
        ;
1623
        ; Add the entry to the symbol table
1624
        ;
1625
F_VAR2: LCALL   R76S            ;SAVE R7 AND R6
1626
        CLR     C
1627
        ACALL   DLD             ;BUMP THE POINTER TO GET ENTRY ADDRESS
1628
        ;
1629
        ; Adjust pointer and save storage allocation
1630
        ; and make sure we aren't wiping anything out
1631
        ; First calculate new storage allocation
1632
        ;
1633
        MOV     A,R0
1634
        SUBB    A,#STESIZ-3     ;NEED THIS MUCH RAM
1635
        MOV     R1,A
1636
        MOV     A,R2
1637
        SUBB    A,#0
1638
        MOV     R3,A
1639
        ;
1640
        ; Now save the new storage allocation
1641
        ;
1642
        MOV     DPTR,#ST_ALL
1643
        CALL    S31DP           ;SAVE STORAGE ALLOCATION
1644
        ;
1645
        ; Now make sure we didn't blow it, by wiping out MT_ALL
1646
        ;
1647
        ACALL   DCMPX           ;COMPARE STORAGE ALLOCATION
1648
        JC      CCLR3           ;ERROR IF CARRY
1649
        SETB    C               ;DID NOT FIND ENTRY
1650
        RET                     ;EXIT IF TEST IS OK
1651
        ;
1652
$EJECT
1653
        ;***************************************************************
1654
        ;
1655
        ; Command action routine - NEW
1656
        ;
1657
        ;***************************************************************
1658
        ;
1659
CNEW:   MOV     DPTR,#PSTART    ;SAVE THE START OF PROGRAM
1660
        MOV     A,#EOF          ;END OF FILE
1661
        MOVX    @DPTR,A         ;PUT IT IN MEMORY
1662
        ;
1663
        ; falls thru
1664
        ;
1665
        ;*****************************************************************
1666
        ;
1667
        ; The statement action routine - CLEAR
1668
        ;
1669
        ;*****************************************************************
1670
        ;
1671
CNEW1:  CLR     LINEB           ;SET UP FOR RUN AND GOTO
1672
        ;
1673
RCLEAR: ACALL   LCLR            ;CLEAR THE INTERRUPTS, SET UP MATRICES
1674
        MOV     DPTR,#MEMTOP    ;PUT MEMTOP IN R3:R1
1675
        ACALL   L31DPI
1676
        ACALL   G4              ;DPTR GETS END ADDRESS
1677
        ACALL   CL_1            ;CLEAR THE MEMORY
1678
        ;
1679
RC1:    MOV     DPTR,#STACKTP   ;POINT AT CONTROL STACK TOP
1680
        CLR     A               ;CONTROL UNDERFLOW
1681
        ;
1682
RC2:    MOVX    @DPTR,A         ;SAVE IN MEMORY
1683
        MOV     CSTKA,#STACKTP
1684
        MOV     ASTKA,#STACKTP
1685
        CLR     CONB            ;CAN'T CONTINUE
1686
        RET
1687
        ;
1688
$EJECT
1689
        ;***************************************************************
1690
        ;
1691
        ; Loop until the memory is cleared
1692
        ;
1693
        ;***************************************************************
1694
        ;
1695
CL_1:   INC     DPTR            ;BUMP MEMORY POINTER
1696
        CLR     A               ;CLEAR THE MEMORY
1697
        MOVX    @DPTR,A         ;CLEAR THE RAM
1698
        MOVX    A,@DPTR         ;READ IT
1699
        JNZ     CCLR3           ;MAKE SURE IT IS CLEARED
1700
        MOV     A,R3            ;GET POINTER FOR COMPARE
1701
        CJNE    A,DPH,CL_1      ;SEE TO LOOP
1702
        MOV     A,R1            ;NOW TEST LOW BYTE
1703
        CJNE    A,DPL,CL_1
1704
        ;
1705
CL_2:   RET
1706
        ;
1707
CCLR3:  JMP     TB              ;ALLOCATED MEMORY DOESN'T EXSIST
1708
        ;
1709
        ;**************************************************************
1710
        ;
1711
SCLR:   ;Entry point for clear return
1712
        ;
1713
        ;**************************************************************
1714
        ;
1715
        CALL    DELTST          ;TEST FOR A CR
1716
        JNC     RCLEAR
1717
        CALL    GCI1            ;BUMP THE TEST POINTER
1718
        CJNE    A,#'I',RC1      ;SEE IF I, ELSE RESET THE STACK
1719
        ;
1720
        ;**************************************************************
1721
        ;
1722
ICLR:   ; Clear interrupts and system garbage
1723
        ;
1724
        ;**************************************************************
1725
        ;
1726
        JNB     INTBIT,ICLR1    ;SEE IF BASIC HAS INTERRUPTS
1727
        CLR     EX1             ;IF SO, CLEAR INTERRUPTS
1728
ICLR1:  ANL     34,#00100000B   ;SET INTERRUPTS + CONTINUE
1729
        RETI
1730
        ;
1731
$EJECT
1732
        ;***************************************************************
1733
        ;
1734
        ;OUTPUT ROUTINES
1735
        ;
1736
        ;***************************************************************
1737
        ;
1738
CRLF2:  ACALL   CRLF            ;DO TWO CRLF'S
1739
        ;
1740
CRLF:   MOV     R5,#CR          ;LOAD THE CR
1741
        ACALL   TEROT           ;CALL TERMINAL OUT
1742
        MOV     R5,#LF          ;LOAD THE LF
1743
        AJMP    TEROT           ;OUTPUT IT AND RETURN
1744
        ;
1745
        ;PRINT THE MESSAGE ADDRESSED IN ROM OR RAM BY THE DPTR
1746
        ;ENDS WITH THE CHARACTER IN R4
1747
        ;DPTR HAS THE ADDRESS OF THE TERMINATOR
1748
        ;
1749
CRP:    ACALL   CRLF            ;DO A CR THEN PRINT ROM
1750
        ;
1751
ROM_P:  CLR     A               ;CLEAR A FOR LOOKUP
1752
        MOVC    A,@A+DPTR       ;GET THE CHARACTER
1753
        CLR     ACC.7           ;CLEAR MS BIT
1754
        CJNE    A,#'"',ROM_P1   ;EXIT IF TERMINATOR
1755
        RET
1756
ROM_P1: SETB    C0ORX1
1757
        ;
1758
PN1:    MOV     R5,A            ;OUTPUT THE CHARACTER
1759
        ACALL   TEROT
1760
        INC     DPTR            ;BUMP THE POINTER
1761
        SJMP    PN0
1762
        ;
1763
UPRNT:  ACALL   X31DP
1764
        ;
1765
PRNTCR: MOV     R4,#CR          ;OUTPUT UNTIL A CR
1766
        ;
1767
PN0:    JBC     C0ORX1,ROM_P
1768
        MOVX    A,@DPTR         ;GET THE RAM BYTE
1769
        JZ      PN01
1770
        CJNE    A,R4B0,PN02     ;SEE IF THE SAME AS TERMINATOR
1771
PN01:   RET                     ;EXIT IF THE SAME
1772
PN02:   CJNE    A,#CR,PN1       ;NEVER PRINT A CR IN THIS ROUTINE
1773
        LJMP    E1XX            ;BAD SYNTAX
1774
        ;
1775
$EJECT
1776
        ;***************************************************************
1777
        ;
1778
        ; INLINE - Input a line to IBUF, exit when a CR is received
1779
        ;
1780
        ;***************************************************************
1781
        ;
1782
INL2:   CJNE    A,#CNTRLD,INL2B ;SEE IF A CONTROL D
1783
        ;
1784
INL0:   ACALL   CRLF            ;DO A CR
1785
        ;
1786
INLINE: MOV     P2,#HIGH IBUF   ;IBUF IS IN THE ZERO PAGE
1787
        MOV     R0,#LOW IBUF    ;POINT AT THE INPUT BUFFER
1788
        ;
1789
INL1:   ACALL   INCHAR          ;GET A CHARACTER
1790
        MOV     R5,A            ;SAVE IN R5 FOR OUTPUT
1791
        CJNE    A,#7FH,INL2     ;SEE IF A DELETE CHARACTER
1792
        CJNE    R0,#LOW IBUF,INL6
1793
INL11:  MOV     R5,#BELL        ;OUTPUT A BELL
1794
        ;
1795
INLX:   ACALL   TEROT           ;OUTPUT CHARACTER
1796
        SJMP    INL1            ;DO IT AGAIN
1797
        ;
1798
INL2B:  MOVX    @R0,A           ;SAVE THE CHARACTER
1799
        CJNE    A,#CR,INL2B1    ;IS IT A CR
1800
        AJMP    CRLF            ;OUTPUT A CRLF AND EXIT
1801
INL2B1: CJNE    A,#20H,INL2B2
1802
INL2B2: JC      INLX            ;ONLY ECHO CONTROL CHARACTERS
1803
        INC     R0              ;BUMP THE POINTER
1804
        CJNE    R0,#IBUF+79,INLX
1805
        DEC     R0              ;FORCE 79
1806
        SJMP    INL11           ;OUTPUT A BELL
1807
        ;
1808
INL6:   DEC     R0              ;DEC THE RAM POINTER
1809
        MOV     R5,#BS          ;OUTPUT A BACK SPACE
1810
        ACALL   TEROT
1811
        ACALL   STEROT          ;OUTPUT A SPACE
1812
        MOV     R5,#BS          ;ANOTHER BACK SPACE
1813
        SJMP    INLX            ;OUTPUT IT
1814
        ;
1815
PTIME:  DB      128-2           ; PROM PROGRAMMER TIMER
1816
        DB      00H
1817
        DB      00H
1818
        DB      50H
1819
        DB      67H
1820
        DB      41H
1821
        ;
1822
$EJECT
1823
;$INCLUDE(:F2:BAS52.OUT)
1824
;BEGINNING
1825
        ;***************************************************************
1826
        ;
1827
        ; TEROT - Output a character to the system console
1828
        ;         update PHEAD position.
1829
        ;
1830
        ;***************************************************************
1831
        ;
1832
STEROT: MOV     R5,#' '         ;OUTPUT A SPACE
1833
        ;
1834
TEROT:  PUSH    ACC             ;SAVE THE ACCUMULATOR
1835
        PUSH    DPH             ;SAVE THE DPTR
1836
        PUSH    DPL
1837
TEROT01:JNB     CNT_S,TEROT02   ;WAIT FOR A CONTROL Q
1838
        ACALL   BCK             ;GET SERIAL STATUS
1839
        SJMP    TEROT01
1840
TEROT02:MOV     A,R5            ;PUT OUTPUT BYTE IN A
1841
        JNB     BO,TEROT03      ;CHECK FOR MONITOR
1842
        LCALL   2040H           ;DO THE MONITOR
1843
        AJMP    TEROT1          ;CLEAN UP
1844
TEROT03:JNB     COUB,TEROT04    ;SEE IF USER WANTS OUTPUT
1845
        LCALL   4030H
1846
        AJMP    TEROT1
1847
TEROT04:JNB     UPB,T_1         ;NO AT IF NO XBIT
1848
        JNB     LPB,T_1         ;AT PRINT
1849
        LCALL   403CH           ;CALL AT LOCATION
1850
        AJMP    TEROT1          ;FINISH OFF OUTPUT
1851
        ;
1852
T_1:    JNB     COB,TXX         ;SEE IF LIST SET
1853
        MOV     DPTR,#SPV       ;LOAD BAUD RATE
1854
        ACALL   LD_T
1855
        CLR     LP              ;OUTPUT START BIT
1856
        ACALL   TIMER_LOAD      ;LOAD AND START THE TIMER
1857
        MOV     A,R5            ;GET THE OUTPUT BYTE
1858
        SETB    C               ;SET CARRY FOR LAST OUTPUT
1859
        MOV     R5,#9           ;LOAD TIMER COUNTDOWN
1860
        ;
1861
LTOUT1: RRC     A               ;ROTATE A
1862
        JNB     TF1,$           ;WAIT TILL TIMER READY
1863
        MOV     LP,C            ;OUTPUT THE BIT
1864
        ACALL   TIMER_LOAD      ;DO THE NEXT BIT
1865
        DJNZ    R5,LTOUT1       ;LOOP UNTIL DONE
1866
        JNB     TF1,$           ;FIRST STOP BIT
1867
        ACALL   TIMER_LOAD
1868
        JNB     TF1,$           ;SECOND STOP BIT
1869
        MOV     R5,A            ;RESTORE R5
1870
        SJMP    TEROT1          ;BACK TO TEROT
1871
        ;
1872
$EJECT
1873
TXX:    JNB     TI,$            ;WAIT FOR TRANSMIT READY
1874
        CLR     TI
1875
        MOV     SBUF,R5         ;SEND OUT THE CHARACTER
1876
        ;
1877
TEROT1: CJNE    R5,#CR,TEROT11  ;SEE IF A CR
1878
        MOV     PHEAD,#00H      ;IF A CR, RESET PHEAD AND
1879
        ;
1880
TEROT11:CJNE    R5,#LF,NLC      ;SEE IF A LF
1881
        MOV     A,NULLCT        ;GET THE NULL COUNT
1882
        JZ      NLC             ;NO NULLS IF ZERO
1883
        ;
1884
TEROT2: MOV     R5,#NULL        ;PUT THE NULL IN THE OUTPUT REGISTER
1885
        ACALL   TEROT           ;OUTPUT THE NULL
1886
        DEC     A               ;DECREMENT NULL COUNT
1887
        JNZ     TEROT2          ;LOOP UNTIL DONE
1888
        ;
1889
NLC:    CJNE    R5,#BS,NLC1     ;DEC PHEAD IF A BACKSPACE
1890
        DEC     PHEAD
1891
NLC1:   CJNE    R5,#20H,NLC2    ;IS IT A PRINTABLE CHARACTER?
1892
NLC2:   JC      NLC3            ;DON'T INCREMENT PHEAD IF NOT PRINTABLE
1893
        INC     PHEAD           ;BUMP PRINT HEAD
1894
NLC3:   POP     DPL             ;RESTORE DPTR
1895
        POP     DPH
1896
        POP     ACC             ;RESTORE ACC
1897
        RET                     ;EXIT
1898
        ;
1899
 
1900
;END
1901
;$INCLUDE(:F2:BAS52.OUT)
1902
        ;
1903
BCK:    ACALL   CSTS            ;CHECK STATUS
1904
        JNC     CI_RET1         ;EXIT IF NO CHARACTER
1905
        ;
1906
$EJECT
1907
        ;***************************************************************
1908
        ;
1909
        ;INPUTS A CHARACTER FROM THE SYSTEM CONSOLE.
1910
        ;
1911
        ;***************************************************************
1912
        ;
1913
INCHAR: JNB     BI,INCHAR1      ;CHECK FOR MONITOR (BUBBLE)
1914
        LCALL   2060H
1915
        SJMP    INCH1
1916
INCHAR1:JNB     CIUB,INCHAR2    ;CHECK FOR USER
1917
        LCALL   4033H
1918
        SJMP    INCH1
1919
INCHAR2:JNB     RI,$            ;WAIT FOR RECEIVER READY.
1920
        MOV     A,SBUF
1921
        CLR     RI              ;RESET READY
1922
        CLR     ACC.7           ;NO BIT 7
1923
        ;
1924
INCH1:  CJNE    A,#13H,INCH11
1925
        SETB    CNT_S
1926
INCH11: CJNE    A,#11H,INCH12
1927
        CLR     CNT_S
1928
INCH12: CJNE    A,#CNTRLC,INCH13
1929
        JNB     NO_C,C_EX       ;TRAP NO CONTROL C
1930
        RET
1931
        ;
1932
INCH13: CLR     JKBIT
1933
        CJNE    A,#17H,CI_RET   ;CONTROL W
1934
        SETB    JKBIT
1935
        ;
1936
CI_RET: SETB    C               ;CARRY SET IF A CHARACTER
1937
CI_RET1:RET                     ;EXIT
1938
        ;
1939
        ;*************************************************************
1940
        ;
1941
        ;RROM - The Statement Action Routine RROM
1942
        ;
1943
        ;*************************************************************
1944
        ;
1945
RROM:   SETB    INBIT           ;SO NO ERRORS
1946
        ACALL   RO1             ;FIND THE LINE NUMBER
1947
        JBC     INBIT,CRUN
1948
        RET                     ;EXIT
1949
        ;
1950
$EJECT
1951
        ;***************************************************************
1952
        ;
1953
CSTS:   ;       RETURNS CARRY = 1 IF THERE IS A CHARACTER WAITING FROM
1954
        ;       THE SYSTEM CONSOLE. IF NO CHARACTER THE READY CHARACTER
1955
        ;       WILL BE CLEARED
1956
        ;
1957
        ;***************************************************************
1958
        ;
1959
        JNB     BI,CSTS1        ;BUBBLE STATUS
1960
        LJMP    2068H
1961
CSTS1:  JNB     CIUB,CSTS2      ;SEE IF EXTERNAL CONSOLE
1962
        LJMP    4036H
1963
CSTS2:  MOV     C,RI
1964
        RET
1965
        ;
1966
C_EX0:  MOV     DPTR,#WB        ;EGO MESSAGE
1967
        ACALL   ROM_P
1968
        ;
1969
C_EX:   CLR     CNT_S           ;NO OUTPUT STOP
1970
        LCALL   SPRINT1         ;ASSURE CONSOLE
1971
        ACALL   CRLF
1972
        JBC     JKBIT,C_EX0
1973
        ;
1974
        JNB     DIRF,SSTOP0
1975
        AJMP    C_K             ;CLEAR COB AND EXIT
1976
        ;
1977
T_CMP:  MOV     A,TVH           ;COMPARE TIMER TO SP_H AND SP_L
1978
        MOV     R1,TVL
1979
        CJNE    A,TVH,T_CMP
1980
        XCH     A,R1
1981
        SUBB    A,SP_L
1982
        MOV     A,R1
1983
        SUBB    A,SP_H
1984
        RET
1985
        ;
1986
        ;*************************************************************
1987
        ;
1988
BR0:    ; Trap the timer interrupt
1989
        ;
1990
        ;*************************************************************
1991
        ;
1992
        CALL    T_CMP           ;COMPARE TIMER
1993
        JC      BCHR1           ;EXIT IF TEST FAILS
1994
        SETB    OTI             ;DOING THE TIMER INTERRUPT
1995
        CLR     OTS             ;CLEAR TIMER BIT
1996
        MOV     C,INPROG        ;SAVE IN PROGRESS
1997
        MOV     ISAV,C
1998
        MOV     DPTR,#TIV
1999
        SJMP    BR2
2000
        ;
2001
$EJECT
2002
        ;***************************************************************
2003
        ;
2004
        ; The command action routine - RUN
2005
        ;
2006
        ;***************************************************************
2007
        ;
2008
CRUN:   LCALL   CNEW1           ;CLEAR THE STORAGE ARRAYS
2009
        ACALL   SRESTR1         ;GET THE STARTING ADDRESS
2010
        ACALL   B_C
2011
        JZ      CMNDLK          ;IF NULL GO TO COMMAND MODE
2012
        ;
2013
        ACALL   T_DP
2014
        ACALL   B_TXA           ;BUMP TO STARTING LINE
2015
        ;
2016
CILOOP: ACALL   SP0             ;DO A CR AND A LF
2017
CILOOP1:CLR     DIRF            ;NOT IN DIRECT MODE
2018
        ;
2019
        ;INTERPERTER DRIVER
2020
        ;
2021
ILOOP:  MOV     SP,SPSAV        ;RESTORE THE STACK EACH TIME
2022
        JB      DIRF,ILOOP1     ;NO INTERRUPTS IF IN DIRECT MODE
2023
        MOV     INTXAH,TXAH     ;SAVE THE TEXT POINTER
2024
        MOV     INTXAL,TXAL
2025
ILOOP1: LCALL   BCK             ;GET CONSOLE STATUS
2026
        JB      DIRF,I_L        ;DIRECT MODE
2027
        ANL     C,/GTRD         ;SEE IF CHARACTER READY
2028
        JNC     BCHR            ;NO CHARACTER = NO CARRY
2029
        ;
2030
        ; DO TRAP OPERATION
2031
        ;
2032
        MOV     DPTR,#GTB       ;SAVE TRAP CHARACTER
2033
        MOVX    @DPTR,A
2034
        SETB    GTRD            ;SAYS READ A BYTE
2035
        ;
2036
BCHR:   JB      OTI,I_L         ;EXIT IF TIMER INTERRUPT IN PROGRESS
2037
        JB      OTS,BR0         ;TEST TIMER VALUE IF SET
2038
BCHR1:  JNB     INTPEN,I_L      ;SEE IF INTERRUPT PENDING
2039
        JB      INPROG,I_L      ;DON'T DO IT AGAIN IF IN PROGRESS
2040
        MOV     DPTR,#INTLOC    ;POINT AT INTERRUPT LOCATION
2041
        ;
2042
BR2:    MOV     R4,#GTYPE       ;SETUP FOR A FORCED GOSUB
2043
        ACALL   SGS1            ;PUT TXA ON STACK
2044
        SETB    INPROG          ;INTERRUPT IN PROGRESS
2045
        ;
2046
ERL4:   CALL    L20DPI
2047
        AJMP    D_L1            ;GET THE LINE NUMBER
2048
        ;
2049
I_L:    ACALL   ISTAT           ;LOOP
2050
        ACALL   CLN_UP          ;FINISH IT OFF
2051
        JNC     ILOOP           ;LOOP ON THE DRIVER
2052
        JNB     DIRF,CMNDLK     ;CMND1 IF IN RUN MODE
2053
        LJMP    CMNDR           ;DON'T PRINT READY
2054
        ;
2055
CMNDLK: JMP     CMND1           ;DONE
2056
$EJECT
2057
        ;**************************************************************
2058
        ;
2059
        ; The Statement Action Routine - STOP
2060
        ;
2061
        ;**************************************************************
2062
        ;
2063
SSTOP:  ACALL   CLN_UP          ;FINISH OFF THIS LINE
2064
        MOV     INTXAH,TXAH     ;SAVE TEXT POINTER FOR CONT
2065
        MOV     INTXAL,TXAL
2066
        ;
2067
SSTOP0: SETB    CONB            ;CONTINUE WILL WORK
2068
        MOV     DPTR,#STP       ;PRINT THE STOP MESSAGE
2069
        SETB    STOPBIT         ;SET FOR ERROR ROUTINE
2070
        JMP     ERRS            ;JUMP TO ERROR ROUTINE
2071
        ;
2072
$EJECT
2073
        ;**************************************************************
2074
        ;
2075
        ; ITRAP - Trap special function register operators
2076
        ;
2077
        ;**************************************************************
2078
        ;
2079
ITRAP:  CJNE    A,#TMR0,ITRAP1  ;TIMER 0
2080
        MOV     TH0,R3
2081
        MOV     TL0,R1
2082
        RET
2083
        ;
2084
ITRAP1: CJNE    A,#TMR1,ITRAP2  ;TIMER 1
2085
        MOV     TH1,R3
2086
        MOV     TL1,R1
2087
        RET
2088
        ;
2089
ITRAP2: CJNE    A,#TMR2,ITRAP3  ;TIMER 2
2090
        MOV     TH2,R3
2091
        MOV     TL2,R1
2092
;       DB      8BH             ;MOV R3 DIRECT OP CODE
2093
;       DB      0CDH            ;T2H LOCATION
2094
;       DB      89H             ;MOV R1 DIRECT OP CODE
2095
;       DB      0CCH            ;T2L LOCATION
2096
        RET
2097
        ;
2098
ITRAP3: CJNE    A,#TRC2,RCL1    ;RCAP2 TOKEN
2099
RCL:    MOV     RCAPH2,R3
2100
        MOV     RCAPL2,R1
2101
;       DB      8BH             ;MOV R3 DIRECT OP CODE
2102
;       DB      0CBH            ;RCAP2H LOCATION
2103
;       DB      89H             ;MOV R1 DIRECT OP CODE
2104
;       DB      0CAH            ;RCAP2L LOCATION
2105
        RET
2106
        ;
2107
RCL1:   ACALL   R3CK            ;MAKE SURE THAT R3 IS ZERO
2108
        CJNE    A,#TT2C,RCL2
2109
        MOV     T2CON,R1
2110
;       DB      89H             ;MOV R1 DIRECT OP CODE
2111
;       DB      0C8H            ;T2CON LOCATION
2112
        RET
2113
        ;
2114
RCL2:   CJNE    A,#T_IE,RCL3    ;IE TOKEN
2115
        MOV     IE,R1
2116
        RET
2117
        ;
2118
RCL3:   CJNE    A,#T_IP,RCL4    ;IP TOKEN
2119
        MOV     IP,R1
2120
        RET
2121
        ;
2122
RCL4:   CJNE    A,#TTC,RCL5     ;TCON TOKEN
2123
        MOV     TCON,R1
2124
        RET
2125
        ;
2126
RCL5:   CJNE    A,#TTM,RCL6     ;TMOD TOKEN
2127
        MOV     TMOD,R1
2128
        RET
2129
        ;
2130
RCL6:   CJNE    A,#T_P1,T_T2    ;P1 TOKEN
2131
        MOV     P1,R1
2132
        RET
2133
        ;
2134
        ;***************************************************************
2135
        ;
2136
        ; T_TRAP - Trap special operators
2137
        ;
2138
        ;***************************************************************
2139
        ;
2140
T_T:    MOV     TEMP5,A         ;SAVE THE TOKEN
2141
        ACALL   GCI1            ;BUMP POINTER
2142
        ACALL   SLET2           ;EVALUATE AFTER =
2143
        MOV     A,TEMP5         ;GET THE TOKEN BACK
2144
        CJNE    A,#T_XTAL,T_T01
2145
        LJMP    AXTAL1          ;SET UP CRYSTAL
2146
        ;
2147
T_T01:  ACALL   IFIXL           ;R3:R1 HAS THE TOS
2148
        MOV     A,TEMP5         ;GET THE TOKEN AGAIN
2149
        CJNE    A,#T_MTOP,T_T1  ;SEE IF MTOP TOKEN
2150
        MOV     DPTR,#MEMTOP
2151
        CALL    S31DP
2152
        JMP     RCLEAR          ;CLEAR THE MEMORY
2153
        ;
2154
T_T1:   CJNE    A,#T_TIME,ITRAP ;SEE IF A TIME TOKEN
2155
        MOV     C,EA            ;SAVE INTERRUPTS
2156
        CLR     EA              ;NO TIMER 0 INTERRUPTS DURING LOAD
2157
        MOV     TVH,R3          ;SAVE THE TIME
2158
        MOV     TVL,R1
2159
        MOV     EA,C            ;RESTORE INTERRUPTS
2160
        RET                     ;EXIT
2161
        ;
2162
T_T2:   CJNE    A,#T_PC,INTERX  ;PCON TOKEN
2163
        MOV     PCON,R1
2164
;       DB      89H             ;MOV DIRECT, R1 OP CODE
2165
;       DB      87H             ;ADDRESS OF PCON
2166
        RET                     ;EXIT
2167
        ;
2168
T_TRAP: CJNE    A,#T_ASC,T_T    ;SEE IF ASC TOKEN
2169
        ACALL   IGC             ;EAT IT AND GET THE NEXT CHARACTER
2170
        CJNE    A,#'$',INTERX   ;ERROR IF NOT A STRING
2171
        ACALL   CSY             ;CALCULATE ADDRESS
2172
        ACALL   X3120
2173
        CALL    TWO_EY
2174
        ACALL   SPEOP1          ;EVALUATE AFTER EQUALS
2175
        AJMP    ISTAX1          ;SAVE THE CHARACTER
2176
        ;
2177
$EJECT
2178
        ;**************************************************************
2179
        ;
2180
        ;INTERPERT THE STATEMENT POINTED TO BY TXAL AND TXAH
2181
        ;
2182
        ;**************************************************************
2183
        ;
2184
ISTAT:  ACALL   GC              ;GET THR FIRST CHARACTER
2185
        JNB     XBIT,IAT        ;TRAP TO EXTERNAL RUN PACKAGE
2186
        CJNE    A,#20H,ISTAT1
2187
ISTAT1: JNC     IAT
2188
        LCALL   2070H           ;LET THE USER SET UP THE DPTR
2189
        ACALL   GCI1
2190
        ANL     A,#0FH          ;STRIP OFF BIAS
2191
        SJMP    ISTA1
2192
        ;
2193
IAT:    CJNE    A,#T_XTAL,IAT1
2194
IAT1:   JNC     T_TRAP
2195
        JNB     ACC.7,SLET      ;IMPLIED LET IF BIT 7 NOT SET
2196
        CJNE    A,#T_UOP+12,ISTAX       ;DBYTE TOKEN
2197
        ACALL   SPEOP           ;EVALUATE SPECIAL OPERATOR
2198
        ACALL   R3CK            ;CHECK LOCATION
2199
        MOV     @R1,A           ;SAVE IT
2200
        RET
2201
        ;
2202
ISTAX:  CJNE    A,#T_UOP+13,ISTAY       ;XBYTE TOKEN
2203
        ACALL   SPEOP
2204
        ;
2205
ISTAX1: MOV     P2,R3
2206
        MOVX    @R1,A
2207
        RET
2208
        ;
2209
ISTAY:  CJNE    A,#T_CR+1,ISTAY1;TRAP NEW OPERATORS
2210
ISTAY1: JC      I_S
2211
        CJNE    A,#0B0H,ISTAY2  ;SEE IF TOO BIG
2212
ISTAY2: JNC     INTERX
2213
        ADD     A,#0F9H         ;BIAS FOR LOOKUP TABLE
2214
        SJMP    ISTA0           ;DO THE OPERATION
2215
        ;
2216
I_S:    CJNE    A,#T_LAST,I_S1  ;MAKE SURE AN INITIAL RESERVED WORD
2217
I_S1:   JC      INTERX1         ;ERROR IF NOT
2218
        ;
2219
INTERX: LJMP    E1XX            ;SYNTAX ERROR
2220
        ;
2221
INTERX1:JNB     DIRF,ISTA0      ;EXECUTE ALL STATEMENTS IF IN RUN MODE
2222
        CJNE    A,#T_DIR,INTERX2;SEE IF ON TOKEN
2223
INTERX2:JC      ISTA0           ;OK IF DIRECT
2224
        CJNE    A,#T_GOSB+1,INTERX3;SEE IF FOR
2225
        SJMP    ISTA0           ;FOR IS OK
2226
INTERX3:CJNE    A,#T_REM+1,INTERX4      ;NEXT IS OK
2227
        SJMP    ISTA0
2228
INTERX4:CJNE    A,#T_STOP+6,INTERX      ;SO IS REM
2229
        ;
2230
$EJECT
2231
ISTA0:  ACALL   GCI1            ;ADVANCE THE TEXT POINTER
2232
        MOV     DPTR,#STATD     ;POINT DPTR TO LOOKUP TABLE
2233
        CJNE    A,#T_GOTO-3,ISTA01;SEE IF LET TOKEN
2234
        SJMP    ISTAT           ;WASTE LET TOKEN
2235
ISTA01: ANL     A,#3FH          ;STRIP OFF THE GARBAGE
2236
        ;
2237
ISTA1:  RL      A               ;ROTATE FOR OFFSET
2238
        ADD     A,DPL           ;BUMP
2239
        MOV     DPL,A           ;SAVE IT
2240
        CLR     A
2241
        MOVC    A,@A+DPTR       ;GET HIGH BYTE
2242
        PUSH    ACC             ;SAVE IT
2243
        INC     DPTR
2244
        CLR     A
2245
        MOVC    A,@A+DPTR       ;GET LOW BYTE
2246
        POP     DPH
2247
        MOV     DPL,A
2248
        ;
2249
AC1:    CLR     A
2250
        JMP     @A+DPTR         ;GO DO IT
2251
        ;
2252
$EJECT
2253
        ;***************************************************************
2254
        ;
2255
        ; The statement action routine - LET
2256
        ;
2257
        ;***************************************************************
2258
        ;
2259
SLET:   ACALL   S_C             ;CHECK FOR POSSIBLE STRING
2260
        JC      SLET0           ;NO STRING
2261
        CLR     LINEB           ;USED STRINGS
2262
        ;
2263
        CALL    X31DP           ;PUT ADDRESS IN DPTR
2264
        MOV     R7,#T_EQU       ;WASTE =
2265
        ACALL   EATC
2266
        ACALL   GC              ;GET THE NEXT CHARACTER
2267
        CJNE    A,#'"',S_3      ;CHECK FOR A "
2268
        MOV     R7,S_LEN        ;GET THE STRING LENGTH
2269
        ;
2270
S_0:    ACALL   GCI1            ;BUMP PAST "
2271
        ACALL   DELTST          ;CHECK FOR DELIMITER
2272
        JZ      INTERX          ;EXIT IF CARRIAGE RETURN
2273
        MOVX    @DPTR,A         ;SAVE THE CHARACTER
2274
        CJNE    A,#'"',S_1      ;SEE IF DONE
2275
        ;
2276
S_E:    MOV     A,#CR           ;PUT A CR IN A
2277
        MOVX    @DPTR,A         ;SAVE CR
2278
        AJMP    GCI1
2279
        ;
2280
S_3:    PUSH    DPH
2281
        PUSH    DPL             ;SAVE DESTINATION
2282
        ACALL   S_C             ;CALCULATE SOURCE
2283
        JC      INTERX          ;ERROR IF CARRY
2284
        POP     R0B0            ;GET DESTINATION BACK
2285
        POP     R2B0
2286
        ;
2287
SSOOP:  MOV     R7,S_LEN        ;SET UP COUNTER
2288
        ;
2289
S_4:    CALL    TBYTE           ;TRANSFER THE BYTE
2290
        CJNE    A,#CR,S_41      ;EXIT IF A CR
2291
        RET
2292
S_41:   DJNZ    R7,S_5          ;BUMP COUNTER
2293
        MOV     A,#CR           ;SAVE A CR
2294
        MOVX    @R0,A
2295
        AJMP    EIGP            ;PRINT EXTRA IGNORED
2296
        ;
2297
$EJECT
2298
        ;
2299
S_5:    CALL    INC3210         ;BUMP POINTERS
2300
        SJMP    S_4             ;LOOP
2301
        ;
2302
S_1:    DJNZ    R7,S_11         ;SEE IF DONE
2303
        ACALL   S_E
2304
        ACALL   EIGP            ;PRINT EXTRA IGNORED
2305
        AJMP    FINDCR          ;GO FIND THE END
2306
S_11:   INC     DPTR            ;BUMP THE STORE POINTER
2307
        SJMP    S_0             ;CONTINUE TO LOOP
2308
        ;
2309
E3XX:   MOV     DPTR,#E3X       ;BAD ARG ERROR
2310
        AJMP    EK
2311
        ;
2312
SLET0:  ACALL   SLET1
2313
        AJMP    POPAS           ;COPY EXPRESSION TO VARIABLE
2314
        ;
2315
SLET1:  ACALL   VAR_ER          ;CHECK FOR A"VARIABLE"
2316
        ;
2317
SLET2:  PUSH    R2B0            ;SAVE THE VARIABLE ADDRESS
2318
        PUSH    R0B0
2319
        MOV     R7,#T_EQU       ;GET EQUAL TOKEN
2320
        ACALL   WE
2321
        POP     R1B0            ;POP VARIABLE TO R3:R1
2322
        POP     R3B0
2323
        RET                     ;EXIT
2324
        ;
2325
R3CK:   CJNE    R3,#00H,E3XX    ;CHECK TO SEE IF R3 IS ZERO
2326
        RET
2327
        ;
2328
SPEOP:  ACALL   GCI1            ;BUMP TXA
2329
        ACALL   P_E             ;EVALUATE PAREN
2330
SPEOP1: ACALL   SLET2           ;EVALUATE AFTER =
2331
        CALL    TWOL            ;R7:R6 GETS VALUE, R3:R1 GETS LOCATION
2332
        MOV     A,R6            ;SAVE THE VALUE
2333
        ;
2334
        CJNE    R7,#00H,E3XX    ;R2 MUST BE = 0
2335
        RET
2336
        ;
2337
$EJECT
2338
        ;**************************************************************
2339
        ;
2340
        ; ST_CAL - Calculate string Address
2341
        ;
2342
        ;**************************************************************
2343
        ;
2344
IST_CAL:;
2345
        ;
2346
        ACALL   I_PI            ;BUMP TEXT, THEN EVALUATE
2347
        ACALL   R3CK            ;ERROR IF R3 <> 0
2348
        INC     R1              ;BUMP FOR OFFSET
2349
        MOV     A,R1            ;ERROR IF R1 = 255
2350
        JZ      E3XX
2351
        MOV     DPTR,#VARTOP    ;GET TOP OF VARIABLE STORAGE
2352
        MOV     B,S_LEN         ;MULTIPLY FOR LOCATION
2353
        ACALL   VARD            ;CALCULATE THE LOCATION
2354
        MOV     DPTR,#MEMTOP    ;SEE IF BLEW IT
2355
        CALL    FUL1
2356
        MOV     DPL,S_LEN       ;GET STRING LENGTH, DPH = 00H
2357
        DEC     DPH             ;DPH = 0
2358
        ;
2359
DUBSUB: CLR     C
2360
        MOV     A,R1
2361
        SUBB    A,DPL
2362
        MOV     R1,A
2363
        MOV     A,R3
2364
        SUBB    A,DPH
2365
        MOV     R3,A
2366
        ORL     A,R1
2367
        RET
2368
        ;
2369
        ;***************************************************************
2370
        ;
2371
        ;VARD - Calculate the offset base
2372
        ;
2373
        ;***************************************************************
2374
        ;
2375
VARB:   MOV     B,#FPSIZ        ;SET UP FOR OPERATION
2376
        ;
2377
VARD:   CALL    LDPTRI          ;LOAD DPTR
2378
        MOV     A,R1            ;MULTIPLY BASE
2379
        MUL     AB
2380
        ADD     A,DPL
2381
        MOV     R1,A
2382
        MOV     A,B
2383
        ADDC    A,DPH
2384
        MOV     R3,A
2385
        RET
2386
        ;
2387
$EJECT
2388
        ;*************************************************************
2389
        ;
2390
CSY:    ; Calculate a biased string address and put in R3:R1
2391
        ;
2392
        ;*************************************************************
2393
        ;
2394
        ACALL   IST_CAL         ;CALCULATE IT
2395
        PUSH    R3B0            ;SAVE IT
2396
        PUSH    R1B0
2397
        MOV     R7,#','         ;WASTE THE COMMA
2398
        ACALL   EATC
2399
        ACALL   ONE             ;GET THE NEXT EXPRESSION
2400
        MOV     A,R1            ;CHECK FOR BOUNDS
2401
        CJNE    A,S_LEN,CSY1
2402
CSY1:   JNC     E3XX            ;MUST HAVE A CARRY
2403
        DEC     R1              ;BIAS THE POINTER
2404
        POP     ACC             ;GET VALUE LOW
2405
        ADD     A,R1            ;ADD IT TO BASE
2406
        MOV     R1,A            ;SAVE IT
2407
        POP     R3B0            ;GET HIGH ADDRESS
2408
        JNC     CSY2            ;PROPAGATE THE CARRY
2409
        INC     R3
2410
CSY2:   AJMP    ERPAR           ;WASTE THE RIGHT PAREN
2411
        ;
2412
$EJECT
2413
        ;***************************************************************
2414
        ;
2415
        ; The statement action routine FOR
2416
        ;
2417
        ;***************************************************************
2418
        ;
2419
SFOR:   ACALL   SLET1           ;SET UP CONTROL VARIABLE
2420
        PUSH    R3B0            ;SAVE THE CONTROL VARIABLE LOCATION
2421
        PUSH    R1B0
2422
        ACALL   POPAS           ;POP ARG STACK AND COPY CONTROL VAR
2423
        MOV     R7,#T_TO        ;GET TO TOKEN
2424
        ACALL   WE
2425
        ACALL   GC              ;GET NEXT CHARACTER
2426
        CJNE    A,#T_STEP,SF2
2427
        ACALL   GCI1            ;EAT THE TOKEN
2428
        ACALL   EXPRB           ;EVALUATE EXPRESSION
2429
        SJMP    SF21            ;JUMP OVER
2430
        ;
2431
SF2:    LCALL   PUSH_ONE        ;PUT ONE ON THE STACK
2432
        ;
2433
SF21:   MOV     A,#-FSIZE       ;ALLOCATE FSIZE BYTES ON THE CONTROL STACK
2434
        ACALL   PUSHCS          ;GET CS IN R0
2435
        ACALL   CSC             ;CHECK CONTROL STACK
2436
        MOV     R3,#CSTKAH      ;IN CONTROL STACK
2437
        MOV     R1,R0B0         ;STACK ADDRESS
2438
        ACALL   POPAS           ;PUT STEP ON STACK
2439
        ACALL   POPAS           ;PUT LIMIT ON STACK
2440
        ACALL   DP_T            ;DPTR GETS TEXT
2441
        MOV     R0,R1B0         ;GET THE POINTER
2442
        ACALL   T_X_S           ;SAVE THE TEXT
2443
        POP     TXAL            ;GET CONTROL VARIABLE
2444
        POP     TXAH
2445
        MOV     R4,#FTYPE       ;AND THE TYPE
2446
        ACALL   T_X_S           ;SAVE IT
2447
        ;
2448
SF3:    ACALL   T_DP            ;GET THE TEXT POINTER
2449
        AJMP    ILOOP           ;CONTINUE TO PROCESS
2450
        ;
2451
$EJECT
2452
        ;**************************************************************
2453
        ;
2454
        ; The statement action routines - PUSH and POP
2455
        ;
2456
        ;**************************************************************
2457
        ;
2458
SPUSH:  ACALL   EXPRB           ;PUT EXPRESSION ON STACK
2459
        ACALL   C_TST           ;SEE IF MORE TO DO
2460
        JNC     SPUSH           ;IF A COMMA PUSH ANOTHER
2461
        RET
2462
        ;
2463
        ;
2464
SPOP:   ACALL   VAR_ER          ;GET VARIABLE
2465
        ACALL   XPOP            ;FLIP THE REGISTERS FOR POPAS
2466
        ACALL   C_TST           ;SEE IF MORE TO DO
2467
        JNC     SPOP
2468
        ;
2469
SPOP1:  RET
2470
        ;
2471
        ;***************************************************************
2472
        ;
2473
        ; The statement action routine - IF
2474
        ;
2475
        ;***************************************************************
2476
        ;
2477
SIF:    ACALL   RTST            ;EVALUATE THE EXPRESSION
2478
        MOV     R1,A            ;SAVE THE RESULT
2479
        ACALL   GC              ;GET THE CHARACTER AFTER EXPR
2480
        CJNE    A,#T_THEN,SIF1  ;SEE IF THEN TOKEN
2481
        ACALL   GCI1            ;WASTE THEN TOKEN
2482
SIF1:   CJNE    R1,#0,T_F1      ;CHECK R_OP RESULT
2483
        ;
2484
E_FIND: MOV     R7,#T_ELSE      ;FIND ELSE TOKEN
2485
        ACALL   FINDC
2486
        JZ      SPOP1           ;EXIT IF A CR
2487
        ACALL   GCI1            ;BUMP PAST TOKEN
2488
        CJNE    A,#T_ELSE,E_FIND;WASTE IF NO ELSE
2489
        ;
2490
T_F1:   ACALL   INTGER          ;SEE IF NUMBER
2491
        JNC     D_L1            ;EXECUTE LINE NUMBER
2492
        AJMP    ISTAT           ;EXECUTE STATEMENT IN NOT
2493
        ;
2494
B_C:    MOVX    A,@DPTR
2495
        DEC     A
2496
        JB      ACC.7,FL11
2497
        RET
2498
        ;
2499
$EJECT
2500
        ;***************************************************************
2501
        ;
2502
        ; The statement action routine - GOTO
2503
        ;
2504
        ;***************************************************************
2505
        ;
2506
SGOTO:  ACALL   RLINE           ;R2:R0 AND DPTR GET INTGER
2507
        ;
2508
SGT1:   ACALL   T_DP            ;TEXT POINTER GETS DPTR
2509
        ;
2510
        JBC     RETBIT,SGT2     ;SEE IF RETI EXECUTED
2511
        ;
2512
        JNB     LINEB,SGT11     ;SEE IF A LINE WAS EDITED
2513
        LCALL   CNEW1           ;CLEAR THE MEMORY IF SET
2514
SGT11:  AJMP    CILOOP1         ;CLEAR DIRF AND LOOP
2515
        ;
2516
SGT2:   JBC     OTI,SGT21       ;SEE IF TIMER INTERRUPT
2517
        ANL     34,#10111101B   ;CLEAR INTERRUPTS
2518
        AJMP    ILOOP           ;EXECUTE
2519
SGT21:  MOV     C,ISAV
2520
        MOV     INPROG,C
2521
        AJMP    ILOOP           ;RESTORE INTERRUPTS AND RET
2522
        ;
2523
        ;
2524
        ;*************************************************************
2525
        ;
2526
RTST:   ; Test for ZERO
2527
        ;
2528
        ;*************************************************************
2529
        ;
2530
        ACALL   EXPRB           ;EVALUATE EXPRESSION
2531
        CALL    INC_ASTKA       ;BUMP ARG STACK
2532
        JZ      RTST1           ;EXIT WITH ZERO OR 0FFH
2533
        MOV     A,#0FFH
2534
RTST1:  RET
2535
        ;
2536
$EJECT
2537
        ;
2538
        ;**************************************************************
2539
        ;
2540
        ; GLN - get the line number in R2:R0, return in DPTR
2541
        ;
2542
        ;**************************************************************
2543
        ;
2544
GLN:    ACALL   DP_B            ;GET THE BEGINNING ADDRESS
2545
        ;
2546
FL1:    MOVX    A,@DPTR         ;GET THE LENGTH
2547
        MOV     R7,A            ;SAVE THE LENGTH
2548
        DJNZ    R7,FL3          ;SEE IF END OF FILE
2549
        ;
2550
FL11:   MOV     DPTR,#E10X      ;NO LINE NUMBER
2551
        AJMP    EK              ;HANDLE THE ERROR
2552
        ;
2553
FL3:    JB      ACC.7,FL11      ;CHECK FOR BIT 7
2554
        INC     DPTR            ;POINT AT HIGH BYTE
2555
        MOVX    A,@DPTR         ;GET HIGH BYTE
2556
        CJNE    A,R2B0,FL2      ;SEE IF MATCH
2557
        INC     DPTR            ;BUMP TO LOW BYTE
2558
        DEC     R7              ;ADJUST AGAIN
2559
        MOVX    A,@DPTR         ;GET THE LOW BYTE
2560
        CJNE    A,R0B0,FL2      ;SEE IF LOW BYTE MATCH
2561
        INC     DPTR            ;POINT AT FIRST CHARACTER
2562
        RET                     ;FOUND IT
2563
        ;
2564
FL2:    MOV     A,R7            ;GET THE LENGTH COUNTER
2565
        CALL    ADDPTR          ;ADD A TO DATA POINTER
2566
        SJMP    FL1             ;LOOP
2567
        ;
2568
        ;
2569
        ;*************************************************************
2570
        ;
2571
        ;RLINE - Read in ASCII string, get line, and clean it up
2572
        ;
2573
        ;*************************************************************
2574
        ;
2575
RLINE:  ACALL   INTERR          ;GET THE INTEGER
2576
        ;
2577
RL1:    ACALL   GLN
2578
        AJMP    CLN_UP
2579
        ;
2580
        ;
2581
D_L1:   ACALL   GLN             ;GET THE LINE
2582
        AJMP    SGT1            ;EXECUTE THE LINE
2583
        ;
2584
$EJECT
2585
        ;***************************************************************
2586
        ;
2587
        ; The statement action routines WHILE and UNTIL
2588
        ;
2589
        ;***************************************************************
2590
        ;
2591
SWHILE: ACALL   RTST            ;EVALUATE RELATIONAL EXPRESSION
2592
        CPL     A
2593
        SJMP    S_WU
2594
        ;
2595
SUNTIL: ACALL   RTST            ;EVALUATE RELATIONAL EXPRESSION
2596
        ;
2597
S_WU:   MOV     R4,#DTYPE       ;DO EXPECTED
2598
        MOV     R5,A            ;SAVE R_OP RESULT
2599
        SJMP    SR0             ;GO PROCESS
2600
        ;
2601
        ;
2602
        ;***************************************************************
2603
        ;
2604
CNULL:  ; The Command Action Routine - NULL
2605
        ;
2606
        ;***************************************************************
2607
        ;
2608
        ACALL   INTERR          ;GET AN INTEGER FOLLOWING NULL
2609
        MOV     NULLCT,R0       ;SAVE THE NULLCOUNT
2610
        AJMP    CMNDLK          ;JUMP TO COMMAND MODE
2611
        ;
2612
$EJECT
2613
        ;***************************************************************
2614
        ;
2615
        ; The statement action routine - RETI
2616
        ;
2617
        ;***************************************************************
2618
        ;
2619
SRETI:  SETB    RETBIT          ;SAYS THAT RETI HAS BEEN EXECUTED
2620
        ;
2621
        ;***************************************************************
2622
        ;
2623
        ; The statement action routine - RETURN
2624
        ;
2625
        ;***************************************************************
2626
        ;
2627
SRETRN: MOV     R4,#GTYPE       ;MAKE SURE OF GOSUB
2628
        MOV     R5,#55H         ;TYPE RETURN TYPE
2629
        ;
2630
SR0:    ACALL   CSETUP          ;SET UP CONTROL STACK
2631
        MOVX    A,@R0           ;GET RETURN TEXT ADDRESS
2632
        MOV     DPH,A
2633
        INC     R0
2634
        MOVX    A,@R0
2635
        MOV     DPL,A
2636
        INC     R0              ;POP CONTROL STACK
2637
        MOVX    A,@DPTR         ;SEE IF GOSUB WAS THE LAST STATEMENT
2638
        CJNE    A,#EOF,SR01
2639
        AJMP    CMNDLK
2640
SR01:   MOV     A,R5            ;GET TYPE
2641
        JZ      SGT1            ;EXIT IF ZERO
2642
        MOV     CSTKA,R0        ;POP THE STACK
2643
        CPL     A               ;OPTION TEST, 00H, 55H, 0FFH, NOW 55H
2644
        JNZ     SGT1            ;MUST BE GOSUB
2645
        RET                     ;NORMAL FALL THRU EXIT FOR NO MATCH
2646
        ;
2647
$EJECT
2648
        ;***************************************************************
2649
        ;
2650
        ; The statement action routine - GOSUB
2651
        ;
2652
        ;***************************************************************
2653
        ;
2654
SGOSUB: ACALL   RLINE           ;NEW TXA IN DPTR
2655
        ;
2656
SGS0:   MOV     R4,#GTYPE
2657
        ACALL   SGS1            ;SET EVERYTHING UP
2658
        AJMP    SF3             ;EXIT
2659
        ;
2660
SGS1:   MOV     A,#-3           ;ALLOCATE 3 BYTES ON CONTROL STACK
2661
        ACALL   PUSHCS
2662
        ;
2663
T_X_S:  MOV     P2,#CSTKAH      ;SET UP PORT FOR CONTROL STACK
2664
        MOV     A,TXAL          ;GET RETURN ADDRESS AND SAVE IT
2665
        MOVX    @R0,A
2666
        DEC     R0
2667
        MOV     A,TXAH
2668
        MOVX    @R0,A
2669
        DEC     R0
2670
        MOV     A,R4            ;GET TYPE
2671
        MOVX    @R0,A           ;SAVE TYPE
2672
        RET                     ;EXIT
2673
        ;
2674
        ;
2675
CS1:    MOV     A,#3            ;POP 3 BYTES
2676
        ACALL   PUSHCS
2677
        ;
2678
CSETUP: MOV     R0,CSTKA        ;GET CONTROL STACK
2679
        MOV     P2,#CSTKAH
2680
        MOVX    A,@R0           ;GET BYTE
2681
        CJNE    A,R4B0,CSETUP1  ;SEE IF TYPE MATCH
2682
        INC     R0
2683
        RET
2684
CSETUP1:JZ      E4XX            ;EXIT IF STACK UNDERFLOW
2685
        CJNE    A,#FTYPE,CS1    ;SEE IF FOR TYPE
2686
        ACALL   XXI3            ;WASTE THE FOR TYPE
2687
        SJMP    CSETUP          ;LOOP
2688
        ;
2689
$EJECT
2690
        ;***************************************************************
2691
        ;
2692
        ; The statement action routine - NEXT
2693
        ;
2694
        ;***************************************************************
2695
        ;
2696
SNEXT:  MOV     R4,#FTYPE       ;FOR TYPE
2697
        ACALL   CSETUP          ;SETUP CONTROL STACK
2698
        MOV     TEMP5,R0        ;SAVE CONTROL VARIABLE ADDRESS
2699
        MOV     R1,#TEMP1       ;SAVE VAR + RETURN IN TEMP1-4
2700
        ;
2701
XXI:    MOVX    A,@R0           ;LOOP UNTIL DONE
2702
        MOV     @R1,A
2703
        INC     R1
2704
        INC     R0
2705
        CJNE    R1,#TEMP5,XXI
2706
        ;
2707
        ACALL   VAR             ;SEE IF THE USER HAS A VARIABLE
2708
        JNC     XXI1
2709
        MOV     R2,TEMP1
2710
        MOV     R0,TEMP2
2711
XXI1:   MOV     A,R2            ;SEE IF VAR'S AGREE
2712
        CJNE    A,TEMP1,E4XX
2713
        MOV     A,R0
2714
        CJNE    A,TEMP2,E4XX
2715
        ACALL   PUSHAS          ;PUT CONTROL VARIABLE ON STACK
2716
        MOV     A,#FPSIZ+FPSIZ+2;COMPUTE ADDRESS TO STEP VALUE SIGN
2717
        ADD     A,TEMP5         ;ADD IT TO BASE OF STACK
2718
        MOV     R0,A            ;SAVE IN R0
2719
        MOV     R2,#CSTKAH      ;SET UP TO PUSH STEP VALUE
2720
        MOV     P2,R2           ;SET UP PORT
2721
        MOVX    A,@R0           ;GET SIGN
2722
        INC     R0              ;BACK TO EXPONENT
2723
        PUSH    ACC             ;SAVE SIGN OF STEP
2724
        ACALL   PUSHAS          ;PUT STEP VALUE ON STACK
2725
        PUSH    R0B0            ;SAVE LIMIT VALUE LOCATION
2726
        CALL    AADD            ;ADD STEP VALUE TO VARIABLE
2727
        CALL    CSTAKA          ;COPY STACK
2728
        MOV     R3,TEMP1        ;GET CONTROL VARIABLE
2729
        MOV     R1,TEMP2
2730
        ACALL   POPAS           ;SAVE THE RESULT
2731
        MOV     R2,#CSTKAH      ;RESTORE LIMIT LOCATION
2732
        POP     R0B0
2733
        ACALL   PUSHAS          ;PUT LIMIT ON STACK
2734
        CALL    FP_BASE2        ;DO THE COMPARE
2735
        POP     ACC             ;GET LIMIT SIGN BACK
2736
        JZ      XXI2            ;IF SIGN NEGATIVE, TEST "BACKWARDS"
2737
        CPL     C
2738
XXI2:   ORL     C,F0            ;SEE IF EQUAL
2739
        JC      N4              ;STILL SMALLER THAN LIMIT?
2740
XXI3:   MOV     A,#FSIZE        ;REMOVE CONTROL STACK ENTRY
2741
        ;
2742
        ; Fall thru to PUSHCS
2743
        ;
2744
$EJECT
2745
        ;***************************************************************
2746
        ;
2747
        ; PUSHCS - push frame onto control stack
2748
        ;          acc has - number of bytes, also test for overflow
2749
        ;
2750
        ;***************************************************************
2751
        ;
2752
PUSHCS: ADD     A,CSTKA         ;BUMP CONTROL STACK
2753
        CJNE    A,#CONVT+17,PUSHCS1 ;SEE IF OVERFLOWED
2754
PUSHCS1:JC      E4XX            ;EXIT IF STACK OVERFLOW
2755
        XCH     A,CSTKA         ;STORE NEW CONTROL STACK VALUE, GET OLD
2756
        DEC     A               ;BUMP OLD VALUE
2757
        MOV     R0,A            ;PUT OLD-1 IN R0
2758
        ;
2759
PUSHCS2:RET                     ;EXIT
2760
        ;
2761
CSC:    ACALL   CLN_UP          ;FINISH OFF THE LINE
2762
        JNC     PUSHCS2         ;EXIT IF NO TERMINATOR
2763
        ;
2764
E4XX:   MOV     DPTR,#EXC       ;CONTROL STACK ERROR
2765
        AJMP    EK              ;STACK ERROR
2766
        ;
2767
N4:     MOV     TXAH,TEMP3      ;GET TEXT POINTER
2768
        MOV     TXAL,TEMP4
2769
        AJMP    ILOOP           ;EXIT
2770
        ;
2771
        ;***************************************************************
2772
        ;
2773
        ; The statement action routine - RESTORE
2774
        ;
2775
        ;***************************************************************
2776
        ;
2777
SRESTR: ACALL   X_TR            ;SWAP POINTERS
2778
SRESTR1:ACALL   DP_B            ;GET THE STARTING ADDRESS
2779
        ACALL   T_DP            ;PUT STARTING ADDRESS IN TEXT POINTER
2780
        ACALL   B_TXA           ;BUMP TXA
2781
        ;
2782
        ; Fall thru
2783
        ;
2784
X_TR:   ;swap txa and rtxa
2785
        ;
2786
        XCH     A,TXAH
2787
        XCH     A,RTXAH
2788
        XCH     A,TXAH
2789
        XCH     A,TXAL
2790
        XCH     A,RTXAL
2791
        XCH     A,TXAL
2792
        RET                     ;EXIT
2793
        ;
2794
$EJECT
2795
        ;***************************************************************
2796
        ;
2797
        ; The statement action routine - READ
2798
        ;
2799
        ;***************************************************************
2800
        ;
2801
SREAD:  ACALL   X_TR            ;SWAP POINTERS
2802
        ;
2803
SRD0:   ACALL   C_TST           ;CHECK FOR COMMA
2804
        JC      SRD4            ;SEE WHAT IT IS
2805
        ;
2806
SRD:    ACALL   EXPRB           ;EVALUATE THE EXPRESSION
2807
        ACALL   GC              ;GET THE CHARACTER AFTER EXPRESSION
2808
        CJNE    A,#',',SRD1     ;SEE IF MORE DATA
2809
        SJMP    SRD2            ;BYBASS CLEAN UP IF A COMMA
2810
        ;
2811
SRD1:   ACALL   CLN_UP          ;FINISH OFF THE LINE, IF AT END
2812
        ;
2813
SRD2:   ACALL   X_TR            ;RESTORE POINTERS
2814
        ACALL   VAR_ER          ;GET VARIABLE ADDRESS
2815
        ACALL   XPOP            ;FLIP THE REGISTERS FOR POPAS
2816
        ACALL   C_TST           ;SEE IF A COMMA
2817
        JNC     SREAD           ;READ AGAIN IF A COMMA
2818
SRD21:  RET                     ;EXIT IF NOT
2819
        ;
2820
SRD4:   CJNE    A,#T_DATA,SRD5  ;SEE IF DATA
2821
        ACALL   GCI1            ;BUMP POINTER
2822
        SJMP    SRD
2823
        ;
2824
SRD5:   CJNE    A,#EOF,SRD6     ;SEE IF YOU BLEW IT
2825
SRD51:  ACALL   X_TR            ;GET THE TEXT POINTER BACK
2826
        MOV     DPTR,#E14X      ;READ ERROR
2827
        ;
2828
EK:     LJMP    ERROR
2829
        ;
2830
SRD6:   ACALL   FINDCR          ;WASTE THIS LINE
2831
        ACALL   CLN_UP          ;CLEAN IT UP
2832
        JC      SRD51           ;ERROR IF AT END
2833
        SJMP    SRD0
2834
        ;
2835
NUMC:   ACALL   GC              ;GET A CHARACTER
2836
        CJNE    A,#'#',NUMC1    ;SEE IF A #
2837
        SETB    COB             ;VALID LINE PRINT
2838
        AJMP    IGC             ;BUMP THE TEXT POINTER
2839
        ;
2840
NUMC1:  CJNE    A,#'@',SRD21    ;EXIT IF NO GOOD
2841
        SETB    LPB
2842
        AJMP    IGC
2843
        ;
2844
$EJECT
2845
        ;***************************************************************
2846
        ;
2847
        ; The statement action routine - PRINT
2848
        ;
2849
        ;***************************************************************
2850
        ;
2851
SPH0:   SETB    ZSURP           ;NO ZEROS
2852
        ;
2853
SPH1:   SETB    HMODE           ;HEX MODE
2854
        ;
2855
SPRINT: ACALL   NUMC            ;TEST FOR A LINE PRINT
2856
        ACALL   SPRINT2         ;PROCEED
2857
SPRINT1:ANL     35,#11110101B   ;CLEAR COB AND LPB
2858
        ANL     38,#00111111B   ;NO HEX MODE
2859
        ;
2860
        RET
2861
        ;
2862
SPRINT2:ACALL   DELTST          ;CHECK FOR A DELIMITER
2863
        JC      SP1
2864
        ;
2865
SP0:    JMP     CRLF            ;EXIT WITH A CR IF SO
2866
        ;
2867
SP2:    ACALL   C_TST           ;CHECK FOR A COMMA
2868
        JC      SP0             ;EXIT IF NO COMMA
2869
        ;
2870
SP1:    ACALL   CPS             ;SEE IF A STRING TO PRINT
2871
        JNC     SP2             ;IF A STRING, CHECK FOR A COMMA
2872
        ;
2873
SP4:    CJNE    A,#T_TAB,SP6
2874
        ACALL   I_PI            ;ALWAYS CLEARS CARRY
2875
        SUBB    A,PHEAD         ;TAKE DELTA BETWEEN TAB AND PHEAD
2876
        JC      SP2             ;EXIT IF PHEAD > TAB
2877
        SJMP    SP7             ;OUTPUT SPACES
2878
        ;
2879
SP6:    CJNE    A,#T_SPC,SM
2880
        ACALL   I_PI            ;SET UP PAREN VALUE
2881
        ;
2882
SP7:    JZ      SP2
2883
        LCALL   STEROT          ;OUTPUT A SPACE
2884
        DEC     A               ;DECREMENT COUNTER
2885
        SJMP    SP7             ;LOOP
2886
        ;
2887
$EJECT
2888
SM:     CJNE    A,#T_CHR,SP8
2889
        ACALL   IGC
2890
        CJNE    A,#'$',SM01
2891
        ACALL   CNX             ;PUT THE CHARACTER ON THE STACK
2892
        ACALL   IFIXL           ;PUT THE CHARACTER IN R1
2893
        SJMP    SM02
2894
SM01:   ACALL   ONE             ;EVALUATE THE EXPRESSION, PUT IN R3:R1
2895
        ACALL   ERPAR
2896
SM02:   MOV     R5,R1B0         ;BYTE TO OUTPUT
2897
        SJMP    SQ
2898
        ;
2899
SP8:    CJNE    A,#T_CR,SX
2900
        ACALL   GCI1            ;EAT THE TOKEN
2901
        MOV     R5,#CR
2902
        ;
2903
SQ:     CALL    TEROT
2904
        SJMP    SP2             ;OUTPUT A CR AND DO IT AGAIN
2905
        ;
2906
SX:     CJNE    A,#T_USE,SP9    ;USING TOKEN
2907
        ACALL   IGC             ;GE THE CHARACTER AFTER THE USING TOKEN
2908
        CJNE    A,#'F',U4       ;SEE IF FLOATING
2909
        MOV     FORMAT,#0F0H    ;SET FLOATING
2910
        ACALL   IGC             ;BUMP THE POINTER AND GET THE CHARACTER
2911
        ACALL   GCI1            ;BUMP IT AGAIN
2912
        ANL     A,#0FH          ;STRIP OFF ASCII BIAS
2913
        JZ      U3              ;EXIT IF ZERO
2914
        CJNE    A,#3,SX1        ;SEE IF AT LEAST A THREE
2915
SX1:    JNC     U3              ;FORCE A THREE IF NOT A THREE
2916
        MOV     A,#3
2917
        ;
2918
U3:     ORL     FORMAT,A        ;PUT DIGIT IN FORMAT
2919
        SJMP    U8              ;CLEAN UP END
2920
        ;
2921
U4:     CJNE    A,#'0',U5
2922
        MOV     FORMAT,#0       ;FREE FORMAT
2923
        ACALL   GCI1            ;BUMP THE POINTER
2924
        SJMP    U8
2925
        ;
2926
U5:     CJNE    A,#'#',U8       ;SEE IF INTGER FORMAT
2927
        ACALL   U6
2928
        MOV     FORMAT,R7       ;SAVE THE FORMAT
2929
        CJNE    A,#'.',U8A      ;SEE IF TERMINATOR WAS RADIX
2930
        ACALL   IGC             ;BUMP PAST .
2931
        ACALL   U6              ;LOOP AGAIN
2932
        MOV     A,R7            ;GET COUNT
2933
        ADD     A,FORMAT        ;SEE IF TOO BIG
2934
        ADD     A,#0F7H
2935
        JNC     U5A
2936
        ;
2937
$EJECT
2938
SE0:    AJMP    INTERX          ;ERROR, BAD SYNTAX
2939
        ;
2940
U5A:    MOV     A,R7            ;GET THE COUNT BACK
2941
        SWAP    A               ;ADJUST
2942
        ORL     FORMAT,A        ;GET THE COUNT
2943
        ;
2944
U8A:    MOV     A,FORMAT
2945
        ;
2946
U8B:    SWAP    A               ;GET THE FORMAT RIGHT
2947
        MOV     FORMAT,A
2948
        ;
2949
U8:     ACALL   ERPAR
2950
        AJMP    SP2             ;DONE
2951
        ;
2952
U6:     MOV     R7,#0           ;SET COUNTER
2953
        ;
2954
U7:     CJNE    A,#'#',SP9A     ;EXIT IF NOT A #
2955
        INC     R7              ;BUMP COUNTER
2956
        ACALL   IGC             ;GET THE NEXT CHARACTER
2957
        SJMP    U7              ;LOOP
2958
        ;
2959
SP9:    ACALL   DELTST1         ;CHECK FOR DELIMITER
2960
        JNC     SP9A            ;EXIT IF A DELIMITER
2961
        ;
2962
        CJNE    A,#T_ELSE,SS
2963
        ;
2964
SP9A:   RET                     ;EXIT IF ELSE TOKEN
2965
        ;
2966
        ;**************************************************************
2967
        ;
2968
        ; P_E - Evaluate an expression in parens ( )
2969
        ;
2970
        ;**************************************************************
2971
        ;
2972
P_E:    MOV     R7,#T_LPAR
2973
        ACALL   WE
2974
        ;
2975
ERPAR:  MOV     R7,#')'         ;EAT A RIGHT PAREN
2976
        ;
2977
EATC:   ACALL   GCI             ;GET THE CHARACTER
2978
        CJNE    A,R7B0,SE0      ;ERROR IF NOT THE SAME
2979
        RET
2980
        ;
2981
$EJECT
2982
        ;***************************************************************
2983
        ;
2984
S_ON:   ; ON Statement
2985
        ;
2986
        ;***************************************************************
2987
        ;
2988
        ACALL   ONE             ;GET THE EXPRESSION
2989
        ACALL   GCI             ;GET THE NEXT CHARACTER
2990
        CJNE    A,#T_GOTO,C0
2991
        ACALL   C1              ;EAT THE COMMAS
2992
        AJMP    SF3             ;DO GOTO
2993
        ;
2994
C0:     CJNE    A,#T_GOSB,SE0
2995
        ACALL   C1
2996
        AJMP    SGS0            ;DO GOSUB
2997
        ;
2998
C1:     CJNE    R1,#0,C2
2999
        ACALL   INTERR          ;GET THE LINE NUMBER
3000
        ACALL   FINDCR
3001
        AJMP    RL1             ;FINISH UP THIS LINE
3002
        ;
3003
C2:     MOV     R7,#','
3004
        ACALL   FINDC
3005
        CJNE    A,#',',SE0      ;ERROR IF NOT A COMMA
3006
        DEC     R1
3007
        ACALL   GCI1            ;BUMP PAST COMMA
3008
        SJMP    C1
3009
        ;
3010
$EJECT
3011
        ;
3012
SS:     ACALL   S_C             ;SEE IF A STRING
3013
        JC      SA              ;NO STRING IF CARRY IS SET
3014
        LCALL   UPRNT           ;PUT POINTER IN DPTR
3015
        AJMP    SP2             ;SEE IF MORE
3016
        ;
3017
SA:     ACALL   EXPRB           ;MUST BE AN EXPRESSION
3018
        MOV     A,#72
3019
        CJNE    A,PHEAD,SA1     ;CHECK PHEAD POSITION
3020
SA1:    JNC     SA2
3021
        ACALL   SP0             ;FORCE A CRLF
3022
SA2:    JNB     HMODE,S13       ;HEX MODE?
3023
        CALL    FCMP            ;SEE IF TOS IS < 0FFFH
3024
        JC      S13             ;EXIT IF GREATER
3025
        CALL    AABS            ;GET THE SIGN
3026
        JNZ     OOPS            ;WASTE IF NEGATIVE
3027
        ACALL   IFIXL
3028
        CALL    FP_BASE11       ;PRINT HEXMODE
3029
        AJMP    SP2
3030
OOPS:   CALL    ANEG            ;MAKE IT NEGATIVE
3031
        ;
3032
S13:    CALL    FP_BASE7        ;DO FP OUTPUT
3033
        MOV     A,#1            ;OUTPUT A SPACE
3034
        AJMP    SP7
3035
        ;
3036
$EJECT
3037
        ;***************************************************************
3038
        ;
3039
        ; ANU -  Get variable name from text - set carry if not found
3040
        ;        if succeeds returns variable in R7:R6
3041
        ;        R6 = 0 if no digit in name
3042
        ;
3043
        ;***************************************************************
3044
        ;
3045
ANU:    ACALL   IGC             ;INCREMENT AND GET CHARACTER
3046
        LCALL   DIGIT_CHECK     ;CHECK FOR DIGIT
3047
        JC      AL2             ;EXIT IF VALID DIGIT
3048
        CJNE    A,#'_',AL       ;SEE IF A _
3049
        RET
3050
        ;
3051
AL:     CJNE    A,#'A',AL1      ;IS IT AN ASCII A?
3052
AL1:    JC      AL3             ;EXIT IF CARRY IS SET
3053
        CJNE    A,#'Z'+1,AL2    ;IS IT LESS THAN AN ASCII Z
3054
AL2:    CPL     C               ;FLIP CARRY
3055
AL3:    RET
3056
        ;
3057
SD01:   JNB     F0,VAR2
3058
        ;
3059
SD0:    MOV     DPTR,#E6X
3060
        AJMP    EK
3061
        ;
3062
SDIMX:  SETB    F0              ;SAYS DOING A DIMENSION
3063
        SJMP    VAR1
3064
        ;
3065
VAR:    CLR     F0              ;SAYS DOING A VARIABLE
3066
        ;
3067
VAR1:   ACALL   GC              ;GET THE CHARACTER
3068
        ACALL   AL              ;CHECK FOR ALPHA
3069
        JNC     VAR11           ;ERROR IF IN DIM
3070
        JB      F0,SD0
3071
        RET
3072
VAR11:  MOV     R7,A            ;SAVE ALPHA CHARACTER
3073
        CLR     A               ;ZERO IN CASE OF FAILURE
3074
        MOV     R5,A            ;SAVE IT
3075
        ;
3076
VY:     MOV     R6,A
3077
        ACALL   ANU             ;CHECK FOR ALPHA OR NUMBER
3078
        JC      VX              ;EXIT IF NO ALPHA OR NUM
3079
        ;
3080
        XCH     A,R7
3081
        ADD     A,R5            ;NUMBER OF CHARACTERS IN ALPHABET
3082
        XCH     A,R7            ;PUT IT BACK
3083
        MOV     R5,#26          ;FOR THE SECOND TIME AROUND
3084
        SJMP    VY
3085
        ;
3086
VX:     CLR     LINEB           ;TELL EDITOR A VARIABLE IS DECLARED
3087
        CJNE    A,#T_LPAR,V4    ;SEE IF A LEFT PAREN
3088
        ;
3089
        ORL     R6B0,#80H       ;SET BIT 7 TO SIGINIFY MATRIX
3090
        CALL    F_VAR           ;FIND THE VARIABLE
3091
        PUSH    R2B0            ;SAVE THE LOCATION
3092
        PUSH    R0B0
3093
        JNC     SD01            ;DEFAULT IF NOT IN TABLE
3094
        JB      F0,SDI          ;NO DEFAULT FOR DIMENSION
3095
        MOV     R1,#10
3096
        MOV     R3,#0
3097
        ACALL   D_CHK
3098
        ;
3099
VAR2:   ACALL   PAREN_INT       ;EVALUATE INTEGER IN PARENS
3100
        CJNE    R3,#0,SD0       ;ERROR IF R3<>0
3101
        POP     DPL             ;GET VAR FOR LOOKUP
3102
        POP     DPH
3103
        MOVX    A,@DPTR         ;GET DIMENSION
3104
        DEC     A               ;BUMP OFFSET
3105
        SUBB    A,R1            ;A MUST BE > R1
3106
        JC      SD0
3107
        LCALL   DECDP2          ;BUMP POINTER TWICE
3108
        ACALL   VARB            ;CALCULATE THE BASE
3109
        ;
3110
X3120:  XCH     A,R1            ;SWAP R2:R0, R3:R1
3111
        XCH     A,R0
3112
        XCH     A,R1
3113
        XCH     A,R3
3114
        XCH     A,R2
3115
        XCH     A,R3
3116
        RET
3117
        ;
3118
V4:     JB      F0,SD0          ;ERROR IF NO LPAR FOR DIM
3119
        LCALL   F_VAR           ;GET SCALAR VARIABLE
3120
        CLR     C
3121
        RET
3122
        ;
3123
$EJECT
3124
        ;
3125
SDI:    ACALL   PAREN_INT       ;EVALUATE PAREN EXPRESSION
3126
        CJNE    R3,#0,SD0       ;ERROR IF NOT ZERO
3127
        POP     R0B0            ;SET UP R2:R0
3128
        POP     R2B0
3129
        ACALL   D_CHK           ;DO DIM
3130
        ACALL   C_TST           ;CHECK FOR COMMA
3131
        JNC     SDIMX           ;LOOP IF COMMA
3132
        RET                     ;RETURN IF NO COMMA
3133
        ;
3134
D_CHK:  INC     R1              ;BUMP FOR TABLE LOOKUP
3135
        MOV     A,R1
3136
        JZ      SD0             ;ERROR IF 0FFFFH
3137
        MOV     R4,A            ;SAVE FOR LATER
3138
        MOV     DPTR,#MT_ALL    ;GET MATRIX ALLOCATION
3139
        ACALL   VARB            ;DO THE CALCULATION
3140
        MOV     R7,DPH          ;SAVE MATRIX ALLOCATION
3141
        MOV     R6,DPL
3142
        MOV     DPTR,#ST_ALL    ;SEE IF TOO MUCH MEMORY TAKEN
3143
        CALL    FUL1            ;ST_ALL SHOULD BE > R3:R1
3144
        MOV     DPTR,#MT_ALL    ;SAVE THE NEW MATRIX POINTER
3145
        CALL    S31DP
3146
        MOV     DPL,R0          ;GET VARIABLE ADDRESS
3147
        MOV     DPH,R2
3148
        MOV     A,R4            ;DIMENSION SIZE
3149
        MOVX    @DPTR,A         ;SAVE IT
3150
        CALL    DECDP2          ;SAVE TARGET ADDRESS
3151
        ;
3152
R76S:   MOV     A,R7
3153
        MOVX    @DPTR,A
3154
        INC     DPTR
3155
        MOV     A,R6            ;ELEMENT SIZE
3156
        MOVX    @DPTR,A
3157
        RET                     ;R2:R0 STILL HAS SYMBOL TABLE ADDRESS
3158
        ;
3159
$EJECT
3160
        ;***************************************************************
3161
        ;
3162
        ; The statement action routine - INPUT
3163
        ;
3164
        ;***************************************************************
3165
        ;
3166
SINPUT: ACALL   CPS             ;PRINT STRING IF THERE
3167
        ;
3168
        ACALL   C_TST           ;CHECK FOR A COMMA
3169
        JNC     IN2A            ;NO CRLF
3170
        ACALL   SP0             ;DO A CRLF
3171
        ;
3172
IN2:    MOV     R5,#'?'         ;OUTPUT A ?
3173
        CALL    TEROT
3174
        ;
3175
IN2A:   SETB    INP_B           ;DOING INPUT
3176
        CALL    INLINE          ;INPUT THE LINE
3177
        CLR     INP_B
3178
        MOV     TEMP5,#HIGH IBUF
3179
        MOV     TEMP4,#LOW IBUF
3180
        ;
3181
IN3:    ACALL   S_C             ;SEE IF A STRING
3182
        JC      IN3A            ;IF CARRY IS SET, NO STRING
3183
        ACALL   X3120           ;FLIP THE ADDRESSES
3184
        MOV     R3,TEMP5
3185
        MOV     R1,TEMP4
3186
        ACALL   SSOOP
3187
        ACALL   C_TST           ;SEE IF MORE TO DO
3188
        JNC     IN2
3189
        RET
3190
        ;
3191
IN3A:   CALL    DTEMP           ;GET THE USER LOCATION
3192
        CALL    GET_NUM         ;GET THE USER SUPPLIED NUMBER
3193
        JNZ     IN5             ;ERROR IF NOT ZERO
3194
        CALL    TEMPD           ;SAVE THE DATA POINTER
3195
        ACALL   VAR_ER          ;GET THE VARIABLE
3196
        ACALL   XPOP            ;SAVE THE VARIABLE
3197
        CALL    DTEMP           ;GET DPTR BACK FROM VAR_ER
3198
        ACALL   C_TST           ;SEE IF MORE TO DO
3199
        JC      IN6             ;EXIT IF NO COMMA
3200
        MOVX    A,@DPTR         ;GET INPUT TERMINATOR
3201
        CJNE    A,#',',IN5      ;IF NOT A COMMA DO A CR AND TRY AGAIN
3202
        INC     DPTR            ;BUMP PAST COMMA AND READ NEXT VALUE
3203
        CALL    TEMPD
3204
        SJMP    IN3
3205
        ;
3206
$EJECT
3207
        ;
3208
IN5:    MOV     DPTR,#IAN       ;PRINT INPUT A NUMBER
3209
        CALL    CRP             ;DO A CR, THEN, PRINT FROM ROM
3210
        LJMP    CC1             ;TRY IT AGAIN
3211
        ;
3212
IN6:    MOVX    A,@DPTR
3213
        CJNE    A,#CR,EIGP
3214
        RET
3215
        ;
3216
EIGP:   MOV     DPTR,#EIG
3217
        CALL    CRP             ;PRINT THE MESSAGE AND EXIT
3218
        AJMP    SP0             ;EXIT WITH A CRLF
3219
        ;
3220
        ;***************************************************************
3221
        ;
3222
SOT:    ; On timer interrupt
3223
        ;
3224
        ;***************************************************************
3225
        ;
3226
        ACALL   TWO             ;GET THE NUMBERS
3227
        MOV     SP_H,R3
3228
        MOV     SP_L,R1
3229
        MOV     DPTR,#TIV       ;SAVE THE NUMBER
3230
        SETB    OTS
3231
        AJMP    R76S            ;EXIT
3232
        ;
3233
        ;
3234
        ;***************************************************************
3235
        ;
3236
SCALL:  ; Call a user rountine
3237
        ;
3238
        ;***************************************************************
3239
        ;
3240
        ACALL   INTERR          ;CONVERT INTEGER
3241
        CJNE    R2,#0,S_C_1     ;SEE IF TRAP
3242
        MOV     A,R0
3243
        JB      ACC.7,S_C_1
3244
        ADD     A,R0
3245
        MOV     DPTR,#4100H
3246
        MOV     DPL,A
3247
        ;
3248
S_C_1:  ACALL   AC1             ;JUMP TO USER PROGRAM
3249
        ANL     PSW,#11100111B  ;BACK TO BANK 0
3250
        RET                     ;EXIT
3251
        ;
3252
$EJECT
3253
        ;**************************************************************
3254
        ;
3255
THREE:  ; Save value for timer function
3256
        ;
3257
        ;**************************************************************
3258
        ;
3259
        ACALL   ONE             ;GET THE FIRST INTEGER
3260
        CALL    CBIAS           ;BIAS FOR TIMER LOAD
3261
        MOV     T_HH,R3
3262
        MOV     T_LL,R1
3263
        MOV     R7,#','         ;WASTE A COMMA
3264
        ACALL   EATC            ;FALL THRU TO TWO
3265
        ;
3266
        ;**************************************************************
3267
        ;
3268
TWO:    ; Get two values seperated by a comma off the stack
3269
        ;
3270
        ;**************************************************************
3271
        ;
3272
        ACALL   EXPRB
3273
        MOV     R7,#','         ;WASTE THE COMMA
3274
        ACALL   WE
3275
        JMP     TWOL            ;EXIT
3276
        ;
3277
        ;*************************************************************
3278
        ;
3279
ONE:    ; Evaluate an expression and get an integer
3280
        ;
3281
        ;*************************************************************
3282
        ;
3283
        ACALL   EXPRB           ;EVALUATE EXPERSSION
3284
        ;
3285
IFIXL:  CALL    IFIX            ;INTEGERS IN R3:R1
3286
        MOV     A,R1
3287
        RET
3288
        ;
3289
        ;
3290
        ;*************************************************************
3291
        ;
3292
I_PI:   ; Increment text pointer then get an integer
3293
        ;
3294
        ;*************************************************************
3295
        ;
3296
        ACALL   GCI1            ;BUMP TEXT, THEN GET INTEGER
3297
        ;
3298
PAREN_INT:; Get an integer in parens ( )
3299
        ;
3300
        ACALL   P_E
3301
        SJMP    IFIXL
3302
        ;
3303
$EJECT
3304
        ;
3305
DP_B:   MOV     DPH,BOFAH
3306
        MOV     DPL,BOFAL
3307
        RET
3308
        ;
3309
DP_T:   MOV     DPH,TXAH
3310
        MOV     DPL,TXAL
3311
        RET
3312
        ;
3313
CPS:    ACALL   GC              ;GET THE CHARACTER
3314
        CJNE    A,#'"',NOPASS   ;EXIT IF NO STRING
3315
        ACALL   DP_T            ;GET TEXT POINTER
3316
        INC     DPTR            ;BUMP PAST "
3317
        MOV     R4,#'"'
3318
        CALL    PN0             ;DO THE PRINT
3319
        INC     DPTR            ;GO PAST QUOTE
3320
        CLR     C               ;PASSED TEST
3321
        ;
3322
T_DP:   MOV     TXAH,DPH        ;TEXT POINTER GETS DPTR
3323
        MOV     TXAL,DPL
3324
        RET
3325
        ;
3326
        ;*************************************************************
3327
        ;
3328
S_C:    ; Check for a string
3329
        ;
3330
        ;*************************************************************
3331
        ;
3332
        ACALL   GC              ;GET THE CHARACTER
3333
        CJNE    A,#'$',NOPASS   ;SET CARRY IF NOT A STRING
3334
        AJMP    IST_CAL         ;CLEAR CARRY, CALCULATE OFFSET
3335
        ;
3336
        ;
3337
        ;
3338
        ;**************************************************************
3339
        ;
3340
C_TST:  ACALL   GC              ;GET A CHARACTER
3341
        CJNE    A,#',',NOPASS   ;SEE IF A COMMA
3342
        ;
3343
$EJECT
3344
        ;***************************************************************
3345
        ;
3346
        ;GC AND GCI - GET A CHARACTER FROM TEXT (NO BLANKS)
3347
        ;             PUT CHARACTER IN THE ACC
3348
        ;
3349
        ;***************************************************************
3350
        ;
3351
IGC:    ACALL   GCI1            ;BUMP POINTER, THEN GET CHARACTER
3352
        ;
3353
GC:     SETB    RS0             ;USE BANK 1
3354
        MOV     P2,R2           ;SET UP PORT 2
3355
        MOVX    A,@R0           ;GET EXTERNAL BYTE
3356
        CLR     RS0             ;BACK TO BANK 0
3357
        RET                     ;EXIT
3358
        ;
3359
GCI:    ACALL   GC
3360
        ;
3361
        ; This routine bumps txa by one and always clears the carry
3362
        ;
3363
GCI1:   SETB    RS0             ;BANK 1
3364
        INC     R0              ;BUMP TXA
3365
        CJNE    R0,#0,GCI11
3366
        INC     R2
3367
GCI11:  CLR     RS0
3368
        RET                     ;EXIT
3369
        ;
3370
$EJECT
3371
        ;**************************************************************
3372
        ;
3373
        ; Check delimiters
3374
        ;
3375
        ;**************************************************************
3376
        ;
3377
DELTST: ACALL   GC              ;GET A CHARACTER
3378
DELTST1:CJNE    A,#CR,DT1       ;SEE IF A CR
3379
        CLR     A
3380
        RET
3381
        ;
3382
DT1:    CJNE    A,#':',NOPASS   ;SET CARRY IF NO MATCH
3383
        ;
3384
L_RET:  RET
3385
        ;
3386
        ;
3387
        ;***************************************************************
3388
        ;
3389
        ; FINDC - Find the character in R7, update TXA
3390
        ;
3391
        ;***************************************************************
3392
        ;
3393
FINDCR: MOV     R7,#CR          ;KILL A STATEMENT LINE
3394
        ;
3395
FINDC:  ACALL   DELTST
3396
        JNC     L_RET
3397
        ;
3398
        CJNE    A,R7B0,FNDCL2   ;MATCH?
3399
        RET
3400
        ;
3401
FNDCL2: ACALL   GCI1
3402
        SJMP    FINDC           ;LOOP
3403
        ;
3404
FNDCL3: ACALL   GCI1
3405
        ;
3406
WCR:    ACALL   DELTST          ;WASTE UNTIL A "REAL" CR
3407
        JNZ     FNDCL3
3408
        RET
3409
        ;
3410
$EJECT
3411
        ;***************************************************************
3412
        ;
3413
        ; VAR_ER - Check for a variable, exit if error
3414
        ;
3415
        ;***************************************************************
3416
        ;
3417
VAR_ER: ACALL   VAR
3418
        SJMP    INTERR1
3419
        ;
3420
        ;
3421
        ;***************************************************************
3422
        ;
3423
        ; S_D0 - The Statement Action Routine DO
3424
        ;
3425
        ;***************************************************************
3426
        ;
3427
S_DO:   ACALL   CSC             ;FINISH UP THE LINE
3428
        MOV     R4,#DTYPE       ;TYPE FOR STACK
3429
        ACALL   SGS1            ;SAVE ON STACK
3430
        AJMP    ILOOP           ;EXIT
3431
        ;
3432
$EJECT
3433
        ;***************************************************************
3434
        ;
3435
        ; CLN_UP - Clean up the end of a statement, see if at end of
3436
        ;          file, eat character and line count after CR
3437
        ;
3438
        ;***************************************************************
3439
        ;
3440
C_2:    CJNE    A,#':',C_1      ;SEE IF A TERMINATOR
3441
        AJMP    GCI1            ;BUMP POINTER AND EXIT, IF SO
3442
        ;
3443
C_1:    CJNE    A,#T_ELSE,EP5
3444
        ACALL   WCR             ;WASTE UNTIL A CR
3445
        ;
3446
CLN_UP: ACALL   GC              ;GET THE CHARACTER
3447
        CJNE    A,#CR,C_2       ;SEE IF A CR
3448
        ACALL   IGC             ;GET THE NEXT CHARACTER
3449
        CJNE    A,#EOF,B_TXA    ;SEE IF TERMINATOR
3450
        ;
3451
NOPASS: SETB    C
3452
        RET
3453
        ;
3454
B_TXA:  XCH     A,TXAL          ;BUMP TXA BY THREE
3455
        ADD     A,#3
3456
        XCH     A,TXAL
3457
        JBC     CY,B_TXA1
3458
        RET
3459
B_TXA1: INC     TXAH
3460
        RET
3461
        ;
3462
$EJECT
3463
        ;***************************************************************
3464
        ;
3465
        ;         Get an INTEGER from the text
3466
        ;         sets CARRY if not found
3467
        ;         returns the INTGER value in DPTR and R2:R0
3468
        ;         returns the terminator in ACC
3469
        ;
3470
        ;***************************************************************
3471
        ;
3472
INTERR: ACALL   INTGER          ;GET THE INTEGER
3473
INTERR1:JC      EP5             ;ERROR IF NOT FOUND
3474
        RET                     ;EXIT IF FOUND
3475
        ;
3476
INTGER: ACALL   DP_T
3477
        CALL    FP_BASE9        ;CONVERT THE INTEGER
3478
        ACALL   T_DP
3479
        MOV     DPH,R2          ;PUT THE RETURNED VALUE IN THE DPTR
3480
        MOV     DPL,R0
3481
        ;
3482
ITRET:  RET                     ;EXIT
3483
        ;
3484
        ;
3485
WE:     ACALL   EATC            ;WASTE THE CHARACTER
3486
        ;
3487
        ; Fall thru to evaluate the expression
3488
        ;
3489
$EJECT
3490
        ;***************************************************************
3491
        ;
3492
        ; EXPRB - Evaluate an expression
3493
        ;
3494
        ;***************************************************************
3495
        ;
3496
EXPRB:  MOV     R2,#LOW OPBOL   ;BASE PRECEDENCE
3497
        ;
3498
EP1:    PUSH    R2B0            ;SAVE OPERATOR PRECEDENCE
3499
        CLR     ARGF            ;RESET STACK DESIGNATOR
3500
        ;
3501
EP2:    MOV     A,SP            ;GET THE STACK POINTER
3502
        ADD     A,#12           ;NEED AT LEAST 12 BYTES
3503
        JNC     EP21
3504
        LJMP    E1XX2
3505
EP21:   MOV     A,ASTKA         ;GET THE ARG STACK
3506
        SUBB    A,#LOW TM_TOP+12;NEED 12 BYTES ALSO
3507
        JNC     EP22
3508
        LJMP    E4YY
3509
EP22:   JB      ARGF,EP4        ;MUST BE AN OPERATOR, IF SET
3510
        ACALL   VAR             ;IS THE VALUE A VARIABLE?
3511
        JNC     EP3             ;PUT VARIABLE ON STACK
3512
        ;
3513
        ACALL   CONST           ;IS THE VALUE A NUMERIC CONSTANT?
3514
        JNC     EP4             ;IF SO, CONTINUE, IF NOT, SEE WHAT
3515
        CALL    GC              ;GET THE CHARACTER
3516
        CJNE    A,#T_LPAR,EP4   ;SEE IF A LEFT PAREN
3517
        MOV     A,#(LOW OPBOL+1)
3518
        SJMP    XLPAR           ;PROCESS THE LEFT PAREN
3519
        ;
3520
EP3:    ACALL   PUSHAS          ;SAVE VAR ON STACK
3521
        ;
3522
EP4:    ACALL   GC              ;GET THE OPERATOR
3523
        ;
3524
        CJNE    A,#T_LPAR,EP41  ;IS IT AN OPERATOR
3525
EP41:   JNC     XOP             ;PROCESS OPERATOR
3526
        CJNE    A,#T_UOP,EP42   ;IS IT A UNARY OPERATOR
3527
EP42:   JNC     XBILT           ;PROCESS UNARY (BUILT IN) OPERATOR
3528
        POP     R2B0            ;GET BACK PREVIOUS OPERATOR PRECEDENCE
3529
        JB      ARGF,ITRET      ;OK IF ARG FLAG IS SET
3530
        ;
3531
EP5:    CLR     C               ;NO RECOVERY
3532
        LJMP    E1XX1
3533
        ;
3534
        ; Process the operator
3535
        ;
3536
XOP:    ANL     A,#1FH          ;STRIP OFF THE TOKE BITS
3537
        JB      ARGF,XOP1       ;IF ARG FLAG IS SET, PROCESS
3538
        CJNE    A,#T_SUB-T_LPAR,XOP3
3539
        MOV     A,#T_NEG-T_LPAR
3540
        ;
3541
$EJECT
3542
XOP1:   ADD     A,#LOW OPBOL+1  ;BIAS THE TABLE
3543
        MOV     R2,A
3544
        MOV     DPTR,#00H
3545
        MOVC    A,@A+DPTR       ;GET THE CURRENT PRECEDENCE
3546
        MOV     R4,A
3547
        POP     ACC             ;GET THE PREVIOUS PRECEDENCE
3548
        MOV     R5,A            ;SAVE THE PREVIOUS PRECEDENCE
3549
        MOVC    A,@A+DPTR       ;GET IT
3550
        CJNE    A,R4B0,XOP11    ;SEE WHICH HAS HIGHER PRECEDENCE
3551
        CJNE    A,#12,ITRET     ;SEE IF ANEG
3552
        SETB    C
3553
XOP11:  JNC     ITRET           ;PROCESS NON-INCREASING PRECEDENCE
3554
        ;
3555
        ; Save increasing precedence
3556
        ;
3557
        PUSH    R5B0            ;SAVE OLD PRECEDENCE ADDRESS
3558
        PUSH    R2B0            ;SAVE NEW PRECEDENCE ADDRESS
3559
        ACALL   GCI1            ;EAT THE OPERATOR
3560
        ACALL   EP1             ;EVALUATE REMAINING EXPRESSION
3561
XOP12:  POP     ACC
3562
        ;
3563
        ; R2 has the action address, now setup and perform operation
3564
        ;
3565
XOP2:   MOV     DPTR,#OPTAB
3566
        ADD     A,#LOW (NOT OPBOL)
3567
        CALL    ISTA1           ;SET UP TO RETURN TO EP2
3568
        AJMP    EP2             ;JUMP TO EVALUATE EXPRESSION
3569
        ;
3570
        ; Built-in operator processing
3571
        ;
3572
XBILT:  ACALL   GCI1            ;EAT THE TOKEN
3573
        ADD     A,#LOW (50H+LOW UOPBOL)
3574
        JB      ARGF,EP5        ;XBILT MUST COME AFTER AN OPERATOR
3575
        CJNE    A,#STP,XBILT1
3576
XBILT1: JNC     XOP2
3577
        ;
3578
XLPAR:  PUSH    ACC             ;PUT ADDRESS ON THE STACK
3579
        ACALL   P_E
3580
        SJMP    XOP12           ;PERFORM OPERATION
3581
        ;
3582
XOP3:   CJNE    A,#T_ADD-T_LPAR,EP5
3583
        ACALL   GCI1
3584
        AJMP    EP2             ;WASTE + SIGN
3585
        ;
3586
$EJECT
3587
XPOP:   ACALL   X3120           ;FLIP ARGS THEN POP
3588
        ;
3589
        ;***************************************************************
3590
        ;
3591
        ; POPAS - Pop arg stack and copy variable to R3:R1
3592
        ;
3593
        ;***************************************************************
3594
        ;
3595
POPAS:  LCALL   INC_ASTKA
3596
        JMP     VARCOP          ;COPY THE VARIABLE
3597
        ;
3598
AXTAL:  MOV     R2,#HIGH CXTAL
3599
        MOV     R0,#LOW CXTAL
3600
        ;
3601
        ; fall thru
3602
        ;
3603
        ;***************************************************************
3604
        ;
3605
PUSHAS: ; Push the Value addressed by R2:R0 onto the arg stack
3606
        ;
3607
        ;***************************************************************
3608
        ;
3609
        CALL    DEC_ASTKA
3610
        SETB    ARGF            ;SAYS THAT SOMTHING IS ON THE STACK
3611
        LJMP    VARCOP
3612
        ;
3613
        ;
3614
        ;***************************************************************
3615
        ;
3616
ST_A:   ; Store at expression
3617
        ;
3618
        ;***************************************************************
3619
        ;
3620
        ACALL   ONE             ;GET THE EXPRESSION
3621
        SJMP    POPAS           ;SAVE IT
3622
        ;
3623
        ;
3624
        ;***************************************************************
3625
        ;
3626
LD_A:   ; Load at expression
3627
        ;
3628
        ;***************************************************************
3629
        ;
3630
        ACALL   ONE             ;GET THE EXPRESSION
3631
        ACALL   X3120           ;FLIP ARGS
3632
        SJMP    PUSHAS
3633
        ;
3634
$EJECT
3635
        ;***************************************************************
3636
        ;
3637
CONST:  ; Get a constant fron the text
3638
        ;
3639
        ;***************************************************************
3640
        ;
3641
        CALL    GC              ;FIRST SEE IF LITERAL
3642
        CJNE    A,#T_ASC,C0C    ;SEE IF ASCII TOKEN
3643
        CALL    IGC             ;GET THE CHARACTER AFTER TOKEN
3644
        CJNE    A,#'$',CN0      ;SEE IF A STRING
3645
        ;
3646
CNX:    CALL    CSY             ;CALCULATE IT
3647
        JMP     AXBYTE1         ;SAVE IT ON THE STACK
3648
        ;
3649
CN0:    CALL    TWO_R2          ;PUT IT ON THE STACK
3650
        CALL    GCI1            ;BUMP THE POINTER
3651
        JMP     ERPAR           ;WASTE THE RIGHT PAREN
3652
        ;
3653
        ;
3654
C0C:    CALL    DP_T            ;GET THE TEXT POINTER
3655
        CALL    GET_NUM         ;GET THE NUMBER
3656
        CJNE    A,#0FFH,C1C     ;SEE IF NO NUMBER
3657
        SETB    C
3658
C2C:    RET
3659
        ;
3660
C1C:    JNZ     FPTST
3661
        CLR     C
3662
        SETB    ARGF
3663
        ;
3664
C3C:    JMP     T_DP
3665
        ;
3666
FPTST:  ANL     A,#00001011B    ;CHECK FOR ERROR
3667
        JZ      C2C             ;EXIT IF ZERO
3668
        ;
3669
        ; Handle the error condition
3670
        ;
3671
        MOV     DPTR,#E2X       ;DIVIDE BY ZERO
3672
        JNB     ACC.0,FPTST1    ;UNDERFLOW
3673
        MOV     DPTR,#E7X
3674
FPTST1: JNB     ACC.1,FPTS      ;OVERFLOW
3675
        MOV     DPTR,#E11X
3676
        ;
3677
FPTS:   JMP     ERROR
3678
        ;
3679
$EJECT
3680
        ;***************************************************************
3681
        ;
3682
        ; The Command action routine - LIST
3683
        ;
3684
        ;***************************************************************
3685
        ;
3686
CLIST:  CALL    NUMC            ;SEE IF TO LINE PORT
3687
        ACALL   FSTK            ;PUT 0FFFFH ON THE STACK
3688
        CALL    INTGER          ;SEE IF USER SUPPLIES LN
3689
        CLR     A               ;LN = 0 TO START
3690
        MOV     R3,A
3691
        MOV     R1,A
3692
        JC      CL1             ;START FROM ZERO
3693
        ;
3694
        CALL    TEMPD           ;SAVE THE START ADDTESS
3695
        CALL    GCI             ;GET THE CHARACTER AFTER LIST
3696
        CJNE    A,#T_SUB,CLIST1 ;CHECK FOR TERMINATION ADDRESS '-'
3697
        ACALL   INC_ASTKA       ;WASTE 0FFFFH
3698
        LCALL   INTERR          ;GET TERMINATION ADDRESS
3699
        ACALL   TWO_EY          ;PUT TERMINATION ON THE ARG STACK
3700
CLIST1: MOV     R3,TEMP5        ;GET THE START ADDTESS
3701
        MOV     R1,TEMP4
3702
        ;
3703
CL1:    CALL    GETLIN          ;GET THE LINE NO IN R3:R1
3704
        JZ      CL3             ;RET IF AT END
3705
        ;
3706
CL2:    ACALL   C3C             ;SAVE THE ADDRESS
3707
        INC     DPTR            ;POINT TO LINE NUMBER
3708
        ACALL   PMTOP1          ;PUT LINE NUMBER ON THE STACK
3709
        ACALL   CMPLK           ;COMPARE LN TO END ADDRESS
3710
        JC      CL3             ;EXIT IF GREATER
3711
        CALL    BCK             ;CHECK FOR A CONTROL C
3712
        ACALL   DEC_ASTKA       ;SAVE THE COMPARE ADDRESS
3713
        CALL    DP_T            ;RESTORE ADDRESS
3714
        ACALL   UPPL            ;UN-PROCESS THE LINE
3715
        ACALL   C3C             ;SAVE THE CR ADDRESS
3716
        ACALL   CL6             ;PRINT IT
3717
        INC     DPTR            ;BUMP POINTER TO NEXT LINE
3718
        MOVX    A,@DPTR         ;GET LIN LENGTH
3719
        DJNZ    ACC,CL2         ;LOOP
3720
        ACALL   INC_ASTKA       ;WASTE THE COMPARE BYTE
3721
        ;
3722
CL3:    AJMP    CMND1           ;BACK TO COMMAND PROCESSOR
3723
        ;
3724
CL6:    MOV     DPTR,#IBUF      ;PRINT IBUF
3725
        CALL    PRNTCR          ;PRINT IT
3726
        CALL    DP_T
3727
        ;
3728
CL7:    JMP     CRLF
3729
        ;
3730
UPPL0:  LCALL   X31DP
3731
$EJECT
3732
        ;***************************************************************
3733
        ;
3734
        ;UPPL - UN PREPROCESS A LINE ADDRESSED BY DPTR INTO IBUF
3735
        ;       RETURN SOURCE ADDRESS OF CR IN DPTR ON RETURN
3736
        ;
3737
        ;***************************************************************
3738
        ;
3739
UPPL:   MOV     R3,#HIGH IBUF   ;POINT R3 AT HIGH IBUF
3740
        MOV     R1,#LOW IBUF    ;POINT R1 AT IBUF
3741
        INC     DPTR            ;SKIP OVER LINE LENGTH
3742
        ACALL   C3C             ;SAVE THE DPTR (DP_T)
3743
        CALL    L20DPI          ;PUT LINE NUMBER IN R2:R0
3744
        CALL    FP_BASE8        ;CONVERT R2:R0 TO INTEGER
3745
        CALL    DP_T
3746
        INC     DPTR            ;BUMP DPTR PAST THE LINE NUMBER
3747
        ;
3748
UPP0:   CJNE    R1,#LOW IBUF+6,UPP01
3749
UPP01:  JC      UPP91           ;PUT SPACES IN TEXT
3750
        INC     DPTR            ;BUMP PAST LN HIGH
3751
        MOVX    A,@DPTR         ;GET USER TEXT
3752
        MOV     R6,A            ;SAVE A IN R6 FOR TOKE COMPARE
3753
        JB      ACC.7,UPP1      ;IF TOKEN, PROCESS
3754
        CJNE    A,#20H,UPP02    ;TRAP THE USER TOKENS
3755
UPP02:  JNC     UPP03
3756
        CJNE    A,#CR,UPP1      ;DO IT IF NOT A CR
3757
UPP03:  CJNE    A,#'"',UPP9     ;SEE IF STRING
3758
        ACALL   UPP7            ;SAVE IT
3759
UPP04:  ACALL   UPP8            ;GET THE NEXT CHARACTER AND SAVE IT
3760
        CJNE    A,#'"',UPP04    ;LOOP ON QUOTES
3761
        SJMP    UPP0
3762
        ;
3763
UPP9:   CJNE    A,#':',UPP1A    ;PUT A SPACE IN DELIMITER
3764
        ACALL   UPP7A
3765
        MOV     A,R6
3766
        ACALL   UPP7
3767
UPP91:  ACALL   UPP7A
3768
        SJMP    UPP0
3769
        ;
3770
UPP1A:  ACALL   UPP81           ;SAVE THE CHARACTER, UPDATE POINTER
3771
        SJMP    UPP0            ;EXIT IF A CR, ELSE LOOP
3772
        ;
3773
UPP1:   ACALL   C3C             ;SAVE THE TEXT POINTER
3774
        MOV     C,XBIT
3775
        MOV     F0,C            ;SAVE XBIT IN F0
3776
UPP11:  MOV     DPTR,#TOKTAB    ;POINT AT TOKEN TABLE
3777
        JNB     F0,UPP2
3778
        LCALL   2078H           ;SET UP DPTR FOR LOOKUP
3779
        ;
3780
UPP2:   CLR     A               ;ZERO A FOR LOOKUP
3781
        MOVC    A,@A+DPTR       ;GET TOKEN
3782
        INC     DPTR            ;ADVANCE THE TOKEN POINTER
3783
        CJNE    A,#0FFH,UP_2    ;SEE IF DONE
3784
        JBC     F0,UPP11        ;NOW DO NORMAL TABLE
3785
        AJMP    CMND1           ;EXIT IF NOT FOUND
3786
        ;
3787
UP_2:   CJNE    A,R6B0,UPP2     ;LOOP UNTIL THE SAME
3788
        ;
3789
UP_3:   CJNE    A,#T_UOP,UP_4
3790
UP_4:   JNC     UPP3
3791
        ACALL   UPP7A           ;PRINT THE SPACE IF OK
3792
        ;
3793
UPP3:   CLR     A               ;DO LOOKUP
3794
        MOVC    A,@A+DPTR
3795
        JB      ACC.7,UPP4      ;EXIT IF DONE, ELSE SAVE
3796
        JZ      UPP4            ;DONE IF ZERO
3797
        ACALL   UPP7            ;SAVE THE CHARACTER
3798
        INC     DPTR
3799
        SJMP    UPP3            ;LOOP
3800
        ;
3801
UPP4:   CALL    DP_T            ;GET IT BACK
3802
        MOV     A,R6            ;SEE IF A REM TOKEN
3803
        XRL     A,#T_REM
3804
        JNZ     UPP42
3805
UPP41:  ACALL   UPP8
3806
        SJMP    UPP41
3807
UPP42:  JNC     UPP0            ;START OVER AGAIN IF NO TOKEN
3808
        ACALL   UPP7A           ;PRINT THE SPACE IF OK
3809
        SJMP    UPP0            ;DONE
3810
        ;
3811
UPP7A:  MOV     A,#' '          ;OUTPUT A SPACE
3812
        ;
3813
UPP7:   AJMP    PPL91           ;SAVE A
3814
        ;
3815
UPP8:   INC     DPTR
3816
        MOVX    A,@DPTR
3817
UPP81:  CJNE    A,#CR,UPP7
3818
        AJMP    PPL71
3819
        ;
3820
$EJECT
3821
        ;**************************************************************
3822
        ;
3823
        ; This table contains all of the floating point constants
3824
        ;
3825
        ; The constants in ROM are stored "backwards" from the way
3826
        ; basic normally treats floating point numbers. Instead of
3827
        ; loading from the exponent and decrementing the pointer,
3828
        ; ROM constants pointers load from the most significant
3829
        ; digits and increment the pointers. This is done to 1) make
3830
        ; arg stack loading faster and 2) compensate for the fact that
3831
        ; no decrement data pointer instruction exsist.
3832
        ;
3833
        ; The numbers are stored as follows:
3834
        ;
3835
        ; BYTE X+5    = MOST SIGNIFICANT DIGITS IN BCD
3836
        ; BYTE X+4    = NEXT MOST SIGNIFICANT DIGITS IN BCD
3837
        ; BYTE X+3    = NEXT LEAST SIGNIFICANT DIGITS IN BCD
3838
        ; BYTE X+2    = LEAST SIGNIFICANT DIGITS IN BCD
3839
        ; BYTE X+1    = SIGN OF THE ABOVE MANTISSA 0 = +, 1 = -
3840
        ; BYTE X      = EXPONENT IN TWO'S COMPLEMENT BINARY
3841
        ;               ZERO EXPONENT = THE NUMBER ZERO
3842
        ;
3843
        ;**************************************************************
3844
        ;
3845
ATTAB:  DB      128-2           ; ARCTAN LOOKUP
3846
        DB      00H
3847
        DB      57H
3848
        DB      22H
3849
        DB      66H
3850
        DB      28H
3851
        ;
3852
        DB      128-1
3853
        DB      01H
3854
        DB      37H
3855
        DB      57H
3856
        DB      16H
3857
        DB      16H
3858
        ;
3859
        DB      128-1
3860
        DB      00H
3861
        DB      14H
3862
        DB      96H
3863
        DB      90H
3864
        DB      42H
3865
        ;
3866
        DB      128-1
3867
        DB      01H
3868
        DB      40H
3869
        DB      96H
3870
        DB      28H
3871
        DB      75H
3872
        ;
3873
        DB      128
3874
        DB      00H
3875
        DB      64H
3876
        DB      62H
3877
        DB      65H
3878
        DB      10H
3879
        ;
3880
        DB      128
3881
        DB      01H
3882
        DB      99H
3883
        DB      88H
3884
        DB      20H
3885
        DB      14H
3886
        ;
3887
        DB      128
3888
        DB      00H
3889
        DB      51H
3890
        DB      35H
3891
        DB      99H
3892
        DB      19H
3893
        ;
3894
        DB      128
3895
        DB      01H
3896
        DB      45H
3897
        DB      31H
3898
        DB      33H
3899
        DB      33H
3900
        ;
3901
        DB      129
3902
        DB      00H
3903
        DB      00H
3904
        DB      00H
3905
        DB      00H
3906
        DB      10H
3907
        ;
3908
        DB      0FFH            ;END OF TABLE
3909
        ;
3910
NTWO:   DB      129
3911
        DB      0
3912
        DB      0
3913
        DB      0
3914
        DB      0
3915
        DB      20H
3916
        ;
3917
TTIME:  DB      128-4           ; CLOCK CALCULATION
3918
        DB      00H
3919
        DB      00H
3920
        DB      00H
3921
        DB      04H
3922
        DB      13H
3923
        ;
3924
$EJECT
3925
        ;***************************************************************
3926
        ;
3927
        ; COSINE - Add pi/2 to stack, then fall thru to SIN
3928
        ;
3929
        ;***************************************************************
3930
        ;
3931
ACOS:   ACALL   POTWO           ;PUT PI/2 ON THE STACK
3932
        ACALL   AADD            ;TOS = TOS+PI/2
3933
        ;
3934
        ;***************************************************************
3935
        ;
3936
        ; SINE - use taylor series to calculate sin function
3937
        ;
3938
        ;***************************************************************
3939
        ;
3940
ASIN:   ACALL   PIPI            ;PUT PI ON THE STACK
3941
        ACALL   RV              ;REDUCE THE VALUE
3942
        MOV     A,MT2           ;CALCULATE THE SIGN
3943
        ANL     A,#01H          ;SAVE LSB
3944
        XRL     MT1,A           ;SAVE SIGN IN MT1
3945
        ACALL   CSTAKA          ;NOW CONVERT TO ONE QUADRANT
3946
        ACALL   POTWO
3947
        ACALL   CMPLK           ;DO COMPARE
3948
        JC      ASIN1
3949
        ACALL   PIPI
3950
        ACALL   ASUB
3951
ASIN1:  ACALL   AABS
3952
        MOV     DPTR,#SINTAB    ;SET UP LOOKUP TABLE
3953
        ACALL   POLYC           ;CALCULATE THE POLY
3954
        ACALL   STRIP
3955
        AJMP    SIN0
3956
        ;
3957
        ; Put PI/2 on the stack
3958
        ;
3959
POTWO:  ACALL   PIPI            ;PUT PI ON THE STACK, NOW DIVIDE
3960
        ;
3961
DBTWO:  MOV     DPTR,#NTWO
3962
        ACALL   PUSHC
3963
        ;MOV    A,#2            ;BY TWO
3964
        ;ACALL  TWO_R2
3965
        AJMP    ADIV
3966
        ;
3967
$EJECT
3968
        ;*************************************************************
3969
        ;
3970
POLYC:  ; Expand a power series to calculate a polynomial
3971
        ;
3972
        ;*************************************************************
3973
        ;
3974
        ACALL   CSTAKA2         ;COPY THE STACK
3975
        ACALL   AMUL            ;SQUARE THE STACK
3976
        ACALL   POP_T1          ;SAVE X*X
3977
        ACALL   PUSHC           ;PUT CONSTANT ON STACK
3978
        ;
3979
POLY1:  ACALL   PUSH_T1         ;PUT COMPUTED VALUE ON STACK
3980
        ACALL   AMUL            ;MULTIPLY CONSTANT AND COMPUTED VALUE
3981
        ACALL   PUSHC           ;PUT NEXT CONSTANT ON STACK
3982
        ACALL   AADD            ;ADD IT TO THE OLD VALUE
3983
        CLR     A               ;CHECK TO SEE IF DONE
3984
        MOVC    A,@A+DPTR
3985
        CJNE    A,#0FFH,POLY1   ;LOOP UNTIL DONE
3986
        ;
3987
AMUL:   LCALL   FP_BASE3
3988
        AJMP    FPTST
3989
        ;
3990
        ;*************************************************************
3991
        ;
3992
RV:     ; Reduce a value for Trig and A**X functions
3993
        ;
3994
        ; value = (value/x - INT(value/x)) * x
3995
        ;
3996
        ;*************************************************************
3997
        ;
3998
        ACALL   C2_T2           ;COPY TOS TO T2
3999
        ACALL   ADIV            ;TOS = TOS/TEMP2
4000
        ACALL   AABS            ;MAKE THE TOS A POSITIVE NUMBER
4001
        MOV     MT1,A           ;SAVE THE SIGN
4002
        ACALL   CSTAKA2         ;COPY THE STACK TWICE
4003
        ACALL   IFIX            ;PUT THE NUMBER IN R3:R1
4004
        PUSH    R3B0            ;SAVE R3
4005
        MOV     MT2,R1          ;SAVE THE LS BYTE IN MT2
4006
        ACALL   AINT            ;MAKE THE TOS AN INTEGER
4007
        ACALL   ASUB            ;TOS = TOS/T2 - INT(TOS/T2)
4008
        ACALL   P_T2            ;TOS = T2
4009
        ACALL   AMUL            ;TOS = T2*(TOS/T2 - INT(TOS/T2)
4010
        POP     R3B0            ;RESTORE R3
4011
        RET                     ;EXIT
4012
        ;
4013
$EJECT
4014
        ;**************************************************************
4015
        ;
4016
        ; TAN
4017
        ;
4018
        ;**************************************************************
4019
        ;
4020
ATAN:   ACALL   CSTAKA          ;DUPLACATE STACK
4021
        ACALL   ASIN            ;TOS = SIN(X)
4022
        ACALL   SWAP_ASTKA      ;TOS = X
4023
        ACALL   ACOS            ;TOS = COS(X)
4024
        AJMP    ADIV            ;TOS = SIN(X)/COS(X)
4025
        ;
4026
STRIP:  ACALL   SETREG          ;SETUP R0
4027
        MOV     R3,#1           ;LOOP COUNT
4028
        AJMP    AI11            ;WASTE THE LSB
4029
        ;
4030
        ;************************************************************
4031
        ;
4032
        ; ARC TAN
4033
        ;
4034
        ;************************************************************
4035
        ;
4036
AATAN:  ACALL   AABS
4037
        MOV     MT1,A           ;SAVE THE SIGN
4038
        ACALL   SETREG          ;GET THE EXPONENT
4039
        ADD     A,#7FH          ;BIAS THE EXPONENT
4040
        MOV     UBIT,C          ;SAVE CARRY STATUS
4041
        JNC     AATAN1          ;SEE IF > 1
4042
        ACALL   RECIP           ;IF > 1, TAKE RECIP
4043
AATAN1: MOV     DPTR,#ATTAB     ;SET UP TO CALCULATE THE POLY
4044
        ACALL   POLYC           ;CALCULATE THE POLY
4045
        JNB     UBIT,SIN0       ;JUMP IF NOT SET
4046
        ACALL   ANEG            ;MAKE X POLY NEGATIVE
4047
        ACALL   POTWO           ;SUBTRACT PI/2
4048
        ACALL   AADD
4049
        ;
4050
SIN0:   MOV     A,MT1           ;GET THE SIGN
4051
        JZ      SRT
4052
        AJMP    ANEG
4053
        ;
4054
$EJECT
4055
        ;*************************************************************
4056
        ;
4057
        ; FCOMP - COMPARE 0FFFFH TO TOS
4058
        ;
4059
        ;*************************************************************
4060
        ;
4061
FCMP:   ACALL   CSTAKA          ;COPY THE STACK
4062
        ACALL   FSTK            ;MAKE THE TOS = 0FFFFH
4063
        ACALL   SWAP_ASTKA      ;NOW COMPARE IS 0FFFFH - X
4064
        ;
4065
CMPLK:  JMP     FP_BASE2        ;DO THE COMPARE
4066
        ;
4067
        ;*************************************************************
4068
        ;
4069
DEC_ASTKA:      ;Push ARG STACK and check for underflow
4070
        ;
4071
        ;*************************************************************
4072
        ;
4073
        MOV     A,#-FPSIZ
4074
        ADD     A,ASTKA
4075
        CJNE    A,#LOW TM_TOP+6,DEC_ASTKA1
4076
DEC_ASTKA1:
4077
        JC      E4YY
4078
        MOV     ASTKA,A
4079
        MOV     R1,A
4080
        MOV     R3,#ASTKAH
4081
        ;
4082
SRT:    RET
4083
        ;
4084
E4YY:   MOV     DPTR,#EXA
4085
        AJMP    FPTS            ;ARG STACK ERROR
4086
        ;
4087
        ;
4088
AXTAL3: ACALL   PUSHC           ;PUSH CONSTANT, THEN MULTIPLY
4089
        ACALL   AMUL
4090
        ;
4091
        ; Fall thru to IFIX
4092
        ;
4093
$EJECT
4094
        ;***************************************************************
4095
        ;
4096
IFIX:   ; Convert a floating point number to an integer, put in R3:R1
4097
        ;
4098
        ;***************************************************************
4099
        ;
4100
        CLR     A               ;RESET THE START
4101
        MOV     R3,A
4102
        MOV     R1,A
4103
        MOV     R0,ASTKA        ;GET THE ARG STACK
4104
        MOV     P2,#ASTKAH
4105
        MOVX    A,@R0           ;READ EXPONENT
4106
        CLR     C
4107
        SUBB    A,#81H          ;BASE EXPONENT
4108
        MOV     R4,A            ;SAVE IT
4109
        DEC     R0              ;POINT AT SIGN
4110
        MOVX    A,@R0           ;GET THE SIGN
4111
        JNZ     SQ_ERR          ;ERROR IF NEGATIVE
4112
        JC      INC_ASTKA       ;EXIT IF EXPONENT IS < 81H
4113
        INC     R4              ;ADJUST LOOP COUNTER
4114
        MOV     A,R0            ;BUMP THE POINTER REGISTER
4115
        SUBB    A,#FPSIZ-1
4116
        MOV     R0,A
4117
        ;
4118
I2:     INC     R0              ;POINT AT DIGIT
4119
        MOVX    A,@R0           ;GET DIGIT
4120
        SWAP    A               ;FLIP
4121
        CALL    FP_BASE10       ;ACCUMULATE
4122
        JC      SQ_ERR
4123
        DJNZ    R4,I21
4124
        SJMP    INC_ASTKA
4125
I21:    MOVX    A,@R0           ;GET DIGIT
4126
        CALL    FP_BASE10
4127
        JC      SQ_ERR
4128
        DJNZ    R4,I2
4129
        ;
4130
$EJECT
4131
        ;************************************************************
4132
        ;
4133
INC_ASTKA:      ; Pop the ARG STACK and check for overflow
4134
        ;
4135
        ;************************************************************
4136
        ;
4137
        MOV     A,#FPSIZ        ;NUMBER TO POP
4138
        SJMP    SETREG1
4139
        ;
4140
SETREG: CLR     A               ;DON'T POP ANYTHING
4141
SETREG1:MOV     R0,ASTKA
4142
        MOV     R2,#ASTKAH
4143
        MOV     P2,R2
4144
        ADD     A,R0
4145
        JC      E4YY
4146
        MOV     ASTKA,A
4147
        MOVX    A,@R0
4148
A_D:    RET
4149
        ;
4150
        ;************************************************************
4151
        ;
4152
        ; EBIAS - Bias a number for E to the X calculations
4153
        ;
4154
        ;************************************************************
4155
        ;
4156
EBIAS:  ACALL   PUSH_ONE
4157
        ACALL   RV
4158
        CJNE    R3,#00H,SQ_ERR  ;ERROR IF R3 <> 0
4159
        ACALL   C2_T2           ;TEMP 2 GETS FRACTIONS
4160
        ACALL   INC_ASTKA
4161
        ACALL   POP_T1
4162
        ACALL   PUSH_ONE
4163
        ;
4164
AELP:   MOV     A,MT2
4165
        JNZ     AEL1
4166
        ;
4167
        MOV     A,MT1
4168
        JZ      A_D
4169
        MOV     DPTR,#FPT2-1
4170
        MOVX    @DPTR,A         ;MAKE THE FRACTIONS NEGATIVE
4171
        ;
4172
RECIP:  ACALL   PUSH_ONE
4173
        ACALL   SWAP_ASTKA
4174
        AJMP    ADIV
4175
        ;
4176
AEL1:   DEC     MT2
4177
        ACALL   PUSH_T1
4178
        ACALL   AMUL
4179
        SJMP    AELP
4180
        ;
4181
SQ_ERR: LJMP    E3XX            ;LINK TO BAD ARG
4182
        ;
4183
$EJECT
4184
        ;************************************************************
4185
        ;
4186
        ; SQUARE ROOT
4187
        ;
4188
        ;************************************************************
4189
        ;
4190
ASQR:   ACALL   AABS            ;GET THE SIGN
4191
        JNZ     SQ_ERR          ;ERROR IF NEGATIVE
4192
        ACALL   C2_T2           ;COPY VARIABLE TO T2
4193
        ACALL   POP_T1          ;SAVE IT IN T1
4194
        MOV     R0,#LOW FPT1
4195
        MOVX    A,@R0           ;GET EXPONENT
4196
        JZ      SQR41           ;EXIT IF ZERO
4197
        ADD     A,#128          ;BIAS THE EXPONENT
4198
        JNC     SQR1            ;SEE IF < 80H
4199
        RR      A
4200
        ANL     A,#127
4201
        SJMP    SQR2
4202
        ;
4203
SQR1:   CPL     A               ;FLIP BITS
4204
        INC     A
4205
        RR      A
4206
        ANL     A,#127          ;STRIP MSB
4207
        CPL     A
4208
        INC     A
4209
        ;
4210
SQR2:   ADD     A,#128          ;BIAS EXPONENT
4211
        MOVX    @R0,A           ;SAVE IT
4212
        ;
4213
        ; NEWGUESS = ( X/OLDGUESS + OLDGUESS) / 2
4214
        ;
4215
SQR4:   ACALL   P_T2            ;TOS = X
4216
        ACALL   PUSH_T1         ;PUT NUMBER ON STACK
4217
        ACALL   ADIV            ;TOS = X/GUESS
4218
        ACALL   PUSH_T1         ;PUT ON AGAIN
4219
        ACALL   AADD            ;TOS = X/GUESS + GUESS
4220
        ACALL   DBTWO           ;TOS = ( X/GUESS + GUESS ) / 2
4221
        ACALL   TEMP_COMP       ;SEE IF DONE
4222
        JNB     F0,SQR4
4223
        ;
4224
SQR41:  AJMP    PUSH_T1         ;PUT THE ANSWER ON THE STACK
4225
        ;
4226
$EJECT
4227
        ;*************************************************************
4228
        ;
4229
        ; NATURAL LOG
4230
        ;
4231
        ;*************************************************************
4232
        ;
4233
ALN:    ACALL   AABS            ;MAKE SURE THAT NUM IS POSITIVE
4234
        JNZ     SQ_ERR          ;ERROR IF NOT
4235
        MOV     MT2,A           ;CLEAR FOR LOOP
4236
        INC     R0              ;POINT AT EXPONENT
4237
        MOVX    A,@R0           ;READ THE EXPONENT
4238
        JZ      SQ_ERR          ;ERROR IF EXPONENT IS ZERO
4239
        CJNE    A,#81H,ALN1     ;SEE IF NUM >= 1
4240
ALN1:   MOV     UBIT,C          ;SAVE CARRY STATUS
4241
        JC      ALNL            ;TAKE RECIP IF >= 1
4242
        ACALL   RECIP
4243
        ;
4244
        ; Loop to reduce
4245
        ;
4246
ALNL:   ACALL   CSTAKA          ;COPY THE STACK FOR COMPARE
4247
        ACALL   PUSH_ONE        ;COMPARE NUM TO ONE
4248
        ACALL   CMPLK
4249
        JNC     ALNO            ;EXIT IF DONE
4250
        ACALL   SETREG          ;GET THE EXPONENT
4251
        ADD     A,#85H          ;SEE HOW BIG IT IS
4252
        JNC     ALN11           ;BUMP BY EXP(11) IF TOO SMALL
4253
        ACALL   PLNEXP          ;PUT EXP(1) ON STACK
4254
        MOV     A,#1            ;BUMP COUNT
4255
        ;
4256
ALNE:   ADD     A,MT2
4257
        JC      SQ_ERR
4258
        MOV     MT2,A
4259
        ACALL   AMUL            ;BIAS THE NUMBER
4260
        SJMP    ALNL
4261
        ;
4262
ALN11:  MOV     DPTR,#EXP11     ;PUT EXP(11) ON STACK
4263
        ACALL   PUSHC
4264
        MOV     A,#11
4265
        SJMP    ALNE
4266
        ;
4267
$EJECT
4268
ALNO:   ACALL   C2_T2           ;PUT NUM IN TEMP 2
4269
        ACALL   PUSH_ONE        ;TOS = 1
4270
        ACALL   ASUB            ;TOS = X - 1
4271
        ACALL   P_T2            ;TOS = X
4272
        ACALL   PUSH_ONE        ;TOS = 1
4273
        ACALL   AADD            ;TOS = X + 1
4274
        ACALL   ADIV            ;TOS = (X-1)/(X+1)
4275
        MOV     DPTR,#LNTAB     ;LOG TABLE
4276
        ACALL   POLYC
4277
        INC     DPTR            ;POINT AT LN(10)
4278
        ACALL   PUSHC
4279
        ACALL   AMUL
4280
        MOV     A,MT2           ;GET THE COUNT
4281
        ACALL   TWO_R2          ;PUT IT ON THE STACK
4282
        ACALL   ASUB            ;INT - POLY
4283
        ACALL   STRIP
4284
        JNB     UBIT,AABS
4285
        ;
4286
LN_D:   RET
4287
        ;
4288
        ;*************************************************************
4289
        ;
4290
TEMP_COMP:      ; Compare FPTEMP1 to TOS, FPTEMP1 gets TOS
4291
        ;
4292
        ;*************************************************************
4293
        ;
4294
        ACALL   PUSH_T1         ;SAVE THE TEMP
4295
        ACALL   SWAP_ASTKA      ;TRADE WITH THE NEXT NUMBER
4296
        ACALL   CSTAKA          ;COPY THE STACK
4297
        ACALL   POP_T1          ;SAVE THE NEW NUMBER
4298
        JMP     FP_BASE2        ;DO THE COMPARE
4299
        ;
4300
$EJECT
4301
AETOX:  ACALL   PLNEXP          ;EXP(1) ON TOS
4302
        ACALL   SWAP_ASTKA      ;X ON TOS
4303
        ;
4304
AEXP:   ;EXPONENTIATION
4305
        ;
4306
        ACALL   EBIAS           ;T1=BASE,T2=FRACTIONS,TOS=INT MULTIPLIED
4307
        MOV     DPTR,#FPT2      ;POINT AT FRACTIONS
4308
        MOVX    A,@DPTR         ;READ THE EXP OF THE FRACTIONS
4309
        JZ      LN_D            ;EXIT IF ZERO
4310
        ACALL   P_T2            ;TOS = FRACTIONS
4311
        ACALL   PUSH_T1         ;TOS = BASE
4312
        ACALL   SETREG          ;SEE IF BASE IS ZERO
4313
        JZ      AEXP1
4314
        ACALL   ALN             ;TOS = LN(BASE)
4315
AEXP1:  ACALL   AMUL            ;TOS = FRACTIONS * LN(BASE)
4316
        ACALL   PLNEXP          ;TOS = EXP(1)
4317
        ACALL   SWAP_ASTKA      ;TOS = FRACTIONS * LN(BASE)
4318
        ACALL   EBIAS           ;T2 = FRACTIONS, TOS = INT MULTIPLIED
4319
        MOV     MT2,#00H        ;NOW CALCULATE E**X
4320
        ACALL   PUSH_ONE
4321
        ACALL   CSTAKA
4322
        ACALL   POP_T1          ;T1 = 1
4323
        ;
4324
AEXL:   ACALL   P_T2            ;TOS = FRACTIONS
4325
        ACALL   AMUL            ;TOS = FRACTIONS * ACCUMLATION
4326
        INC     MT2             ;DO THE DEMONIATOR
4327
        MOV     A,MT2
4328
        ACALL   TWO_R2
4329
        ACALL   ADIV
4330
        ACALL   CSTAKA          ;SAVE THE ITERATION
4331
        ACALL   PUSH_T1         ;NOW ACCUMLATE
4332
        ACALL   AADD            ;ADD ACCUMLATION
4333
        ACALL   TEMP_COMP
4334
        JNB     F0,AEXL         ;LOOP UNTIL DONE
4335
        ;
4336
        ACALL   INC_ASTKA
4337
        ACALL   PUSH_T1
4338
        ACALL   AMUL            ;LAST INT MULTIPLIED
4339
        ;
4340
MU1:    AJMP    AMUL            ;FIRST INT MULTIPLIED
4341
        ;
4342
$EJECT
4343
        ;***************************************************************
4344
        ;
4345
        ; integer operator - INT
4346
        ;
4347
        ;***************************************************************
4348
        ;
4349
AINT:   ACALL   SETREG          ;SET UP THE REGISTERS, CLEAR CARRY
4350
        SUBB    A,#129          ;SUBTRACT EXPONENT BIAS
4351
        JNC     AI1             ;JUMP IF ACC > 81H
4352
        ;
4353
        ; Force the number to be a zero
4354
        ;
4355
        ACALL   INC_ASTKA       ;BUMP THE STACK
4356
        ;
4357
P_Z:    MOV     DPTR,#ZRO       ;PUT ZERO ON THE STACK
4358
        AJMP    PUSHC
4359
        ;
4360
AI1:    SUBB    A,#7
4361
        JNC     AI3
4362
        CPL     A
4363
        INC     A
4364
        MOV     R3,A
4365
AI11:   DEC     R0              ;POINT AT SIGN
4366
        ;
4367
AI2:    DEC     R0              ;NOW AT LSB'S
4368
        MOVX    A,@R0           ;READ BYTE
4369
        ANL     A,#0F0H         ;STRIP NIBBLE
4370
        MOVX    @R0,A           ;WRITE BYTE
4371
        DJNZ    R3,AI21
4372
        RET
4373
AI21:   CLR     A
4374
        MOVX    @R0,A           ;CLEAR THE LOCATION
4375
        DJNZ    R3,AI2
4376
        ;
4377
AI3:    RET                     ;EXIT
4378
        ;
4379
$EJECT
4380
        ;***************************************************************
4381
        ;
4382
AABS:   ; Absolute value - Make sign of number positive
4383
        ;                  return sign in ACC
4384
        ;
4385
        ;***************************************************************
4386
        ;
4387
        ACALL   ANEG            ;CHECK TO SEE IF + OR -
4388
        JNZ     ALPAR           ;EXIT IF NON ZERO, BECAUSE THE NUM IS
4389
        MOVX    @R0,A           ;MAKE A POSITIVE SIGN
4390
        RET
4391
        ;
4392
        ;***************************************************************
4393
        ;
4394
ASGN:   ; Returns the sign of the number 1 = +, -1 = -
4395
        ;
4396
        ;***************************************************************
4397
        ;
4398
        ACALL   INC_ASTKA       ;POP STACK, GET EXPONENT
4399
        JZ      P_Z             ;EXIT IF ZERO
4400
        DEC     R0              ;BUMP TO SIGN
4401
        MOVX    A,@R0           ;GET THE SIGN
4402
        MOV     R7,A            ;SAVE THE SIGN
4403
        ACALL   PUSH_ONE        ;PUT A ONE ON THE STACK
4404
        MOV     A,R7            ;GET THE SIGN
4405
        JZ      ALPAR           ;EXIT IF ZERO
4406
        ;
4407
        ; Fall thru to ANEG
4408
        ;
4409
        ;***************************************************************
4410
        ;
4411
ANEG:   ; Flip the sign of the number on the tos
4412
        ;
4413
        ;***************************************************************
4414
        ;
4415
        ACALL   SETREG
4416
        DEC     R0              ;POINT AT THE SIGN OF THE NUMBER
4417
        JZ      ALPAR           ;EXIT IF ZERO
4418
        MOVX    A,@R0
4419
        XRL     A,#01H          ;FLIP THE SIGN
4420
        MOVX    @R0,A
4421
        XRL     A,#01H          ;RESTORE THE SIGN
4422
        ;
4423
ALPAR:  RET
4424
        ;
4425
$EJECT
4426
        ;***************************************************************
4427
        ;
4428
ACBYTE: ; Read the ROM
4429
        ;
4430
        ;***************************************************************
4431
        ;
4432
        ACALL   IFIX            ;GET EXPRESSION
4433
        CALL    X31DP           ;PUT R3:R1 INTO THE DP
4434
        CLR     A
4435
        MOVC    A,@A+DPTR
4436
        AJMP    TWO_R2
4437
        ;
4438
        ;***************************************************************
4439
        ;
4440
ADBYTE: ; Read internal memory
4441
        ;
4442
        ;***************************************************************
4443
        ;
4444
        ACALL   IFIX            ;GET THE EXPRESSION
4445
        CALL    R3CK            ;MAKE SURE R3 = 0
4446
        MOV     A,@R1
4447
        AJMP    TWO_R2
4448
        ;
4449
        ;***************************************************************
4450
        ;
4451
AXBYTE: ; Read external memory
4452
        ;
4453
        ;***************************************************************
4454
        ;
4455
        ACALL   IFIX            ;GET THE EXPRESSION
4456
AXBYTE1:MOV     P2,R3
4457
        MOVX    A,@R1
4458
        AJMP    TWO_R2
4459
        ;
4460
$EJECT
4461
        ;***************************************************************
4462
        ;
4463
        ; The relational operators - EQUAL                        (=)
4464
        ;                            GREATER THAN                 (>)
4465
        ;                            LESS THAN                    (<)
4466
        ;                            GREATER THAN OR EQUAL        (>=)
4467
        ;                            LESS THAN OR EQUAL           (<=)
4468
        ;                            NOT EQUAL                    (<>)
4469
        ;
4470
        ;***************************************************************
4471
        ;
4472
AGT:    ACALL   CMPLK
4473
        ORL     C,F0            ;SEE IF EITHER IS A ONE
4474
AGT1:   JC      P_Z
4475
        ;
4476
FSTK:   MOV     DPTR,#FS
4477
        AJMP    PUSHC
4478
        ;
4479
FS:     DB      85H
4480
        DB      00H
4481
        DB      00H
4482
        DB      50H
4483
        DB      53H
4484
        DB      65H
4485
        ;
4486
ALT:    ACALL   CMPLK
4487
ALT1:   CPL     C
4488
        SJMP    AGT1
4489
        ;
4490
AEQ:    ACALL   CMPLK
4491
AEQ1:   MOV     C,F0
4492
        SJMP    ALT1
4493
        ;
4494
ANE:    ACALL   CMPLK
4495
        CPL     F0
4496
        SJMP    AEQ1
4497
        ;
4498
AGE:    ACALL   CMPLK
4499
        SJMP    AGT1
4500
        ;
4501
ALE:    ACALL   CMPLK
4502
        ORL     C,F0
4503
        SJMP    ALT1
4504
        ;
4505
$EJECT
4506
        ;***************************************************************
4507
        ;
4508
ARND:   ; Generate a random number
4509
        ;
4510
        ;***************************************************************
4511
        ;
4512
        MOV     DPTR,#RCELL     ;GET THE BINARY SEED
4513
        CALL    L31DPI
4514
        MOV     A,R1
4515
        CLR     C
4516
        RRC     A
4517
        MOV     R0,A
4518
        MOV     A,#6
4519
        RRC     A
4520
        ADD     A,R1
4521
        XCH     A,R0
4522
        ADDC    A,R3
4523
        MOV     R2,A
4524
        DEC     DPL             ;SAVE THE NEW SEED
4525
        ACALL   S20DP
4526
        ACALL   TWO_EY
4527
        ACALL   FSTK
4528
        ;
4529
ADIV:   LCALL   FP_BASE4
4530
        AJMP    FPTST
4531
        ;
4532
$EJECT
4533
        ;***************************************************************
4534
        ;
4535
SONERR: ; ON ERROR Statement
4536
        ;
4537
        ;***************************************************************
4538
        ;
4539
        LCALL   INTERR          ;GET THE LINE NUMBER
4540
        SETB    ON_ERR
4541
        MOV     DPTR,#ERRNUM    ;POINT AT THR ERROR LOCATION
4542
        SJMP    S20DP
4543
        ;
4544
        ;
4545
        ;**************************************************************
4546
        ;
4547
SONEXT: ; ON EXT1 Statement
4548
        ;
4549
        ;**************************************************************
4550
        ;
4551
        LCALL   INTERR
4552
        SETB    INTBIT
4553
        ORL     IE,#10000100B   ;ENABLE INTERRUPTS
4554
        MOV     DPTR,#INTLOC
4555
        ;
4556
S20DP:  MOV     A,R2            ;SAVE R2:R0 @DPTR
4557
        MOVX    @DPTR,A
4558
        INC     DPTR
4559
        MOV     A,R0
4560
        MOVX    @DPTR,A
4561
        RET
4562
        ;
4563
$EJECT
4564
        ;***************************************************************
4565
        ;
4566
        ; CASTAK - Copy and push another top of arg stack
4567
        ;
4568
        ;***************************************************************
4569
        ;
4570
CSTAKA2:ACALL   CSTAKA          ;COPY STACK TWICE
4571
        ;
4572
CSTAKA: ACALL   SETREG          ;SET UP R2:R0
4573
        SJMP    PUSH_T12
4574
        ;
4575
PLNEXP: MOV     DPTR,#EXP1
4576
        ;
4577
        ;***************************************************************
4578
        ;
4579
        ; PUSHC - Push constant on to the arg stack
4580
        ;
4581
        ;***************************************************************
4582
        ;
4583
PUSHC:  ACALL   DEC_ASTKA
4584
        MOV     P2,R3
4585
        MOV     R3,#FPSIZ       ;LOOP COUNTER
4586
        ;
4587
PCL:    CLR     A               ;SET UP A
4588
        MOVC    A,@A+DPTR       ;LOAD IT
4589
        MOVX    @R1,A           ;SAVE IT
4590
        INC     DPTR            ;BUMP POINTERS
4591
        DEC     R1
4592
        DJNZ    R3,PCL          ;LOOP
4593
        ;
4594
        SETB    ARGF
4595
        RET                     ;EXIT
4596
        ;
4597
PUSH_ONE:;
4598
        ;
4599
        MOV     DPTR,#FPONE
4600
        AJMP    PUSHC
4601
        ;
4602
$EJECT
4603
        ;
4604
POP_T1:
4605
        ;
4606
        MOV     R3,#HIGH FPT1
4607
        MOV     R1,#LOW FPT1
4608
        JMP     POPAS
4609
        ;
4610
PUSH_T1:
4611
        ;
4612
        MOV     R0,#LOW FPT1
4613
PUSH_T11:
4614
        MOV     R2,#HIGH FPT1
4615
PUSH_T12:
4616
        LJMP    PUSHAS
4617
        ;
4618
P_T2:   MOV     R0,#LOW FPT2
4619
        SJMP    PUSH_T11                ;JUMP TO PUSHAS
4620
        ;
4621
        ;****************************************************************
4622
        ;
4623
SWAP_ASTKA:     ; SWAP TOS<>TOS-1
4624
        ;
4625
        ;****************************************************************
4626
        ;
4627
        ACALL   SETREG          ;SET UP R2:R0 AND P2
4628
        MOV     A,#FPSIZ        ;PUT TOS+1 IN R1
4629
        MOV     R2,A
4630
        ADD     A,R0
4631
        MOV     R1,A
4632
        ;
4633
S_L:    MOVX    A,@R0
4634
        MOV     R3,A
4635
        MOVX    A,@R1
4636
        MOVX    @R0,A
4637
        MOV     A,R3
4638
        MOVX    @R1,A
4639
        DEC     R1
4640
        DEC     R0
4641
        DJNZ    R2,S_L
4642
        RET
4643
        ;
4644
$EJECT
4645
        ;
4646
C2_T2:  ACALL   SETREG          ;SET UP R2:R0
4647
        MOV     R3,#HIGH FPT2
4648
        MOV     R1,#LOW FPT2    ;TEMP VALUE
4649
        ;
4650
        ; Fall thru
4651
        ;
4652
        ;***************************************************************
4653
        ;
4654
        ; VARCOP - Copy a variable from R2:R0 to R3:R1
4655
        ;
4656
        ;***************************************************************
4657
        ;
4658
VARCOP: MOV     R4,#FPSIZ       ;LOAD THE LOOP COUNTER
4659
        ;
4660
V_C:    MOV     P2,R2           ;SET UP THE PORTS
4661
        MOVX    A,@R0           ;READ THE VALUE
4662
        MOV     P2,R3           ;PORT TIME AGAIN
4663
        MOVX    @R1,A           ;SAVE IT
4664
        ACALL   DEC3210         ;BUMP POINTERS
4665
        DJNZ    R4,V_C          ;LOOP
4666
        RET                     ;EXIT
4667
        ;
4668
PIPI:   MOV     DPTR,#PIE
4669
        AJMP    PUSHC
4670
        ;
4671
$EJECT
4672
        ;***************************************************************
4673
        ;
4674
        ; The logical operators ANL, ORL, XRL, NOT
4675
        ;
4676
        ;***************************************************************
4677
        ;
4678
AANL:   ACALL   TWOL            ;GET THE EXPRESSIONS
4679
        MOV     A,R3            ;DO THE AND
4680
        ANL     A,R7
4681
        MOV     R2,A
4682
        MOV     A,R1
4683
        ANL     A,R6
4684
        SJMP    TWO_EX
4685
        ;
4686
AORL:   ACALL   TWOL            ;SAME THING FOR OR
4687
        MOV     A,R3
4688
        ORL     A,R7
4689
        MOV     R2,A
4690
        MOV     A,R1
4691
        ORL     A,R6
4692
        SJMP    TWO_EX
4693
        ;
4694
ANOT:   ACALL   FSTK            ;PUT 0FFFFH ON THE STACK
4695
        ;
4696
AXRL:   ACALL   TWOL
4697
        MOV     A,R3
4698
        XRL     A,R7
4699
        MOV     R2,A
4700
        MOV     A,R1
4701
        XRL     A,R6
4702
        SJMP    TWO_EX
4703
        ;
4704
TWOL:   ACALL   IFIX
4705
        MOV     R7,R3B0
4706
        MOV     R6,R1B0
4707
        AJMP    IFIX
4708
        ;
4709
$EJECT
4710
        ;*************************************************************
4711
        ;
4712
AGET:   ; READ THE BREAK BYTE AND PUT IT ON THE ARG STACK
4713
        ;
4714
        ;*************************************************************
4715
        ;
4716
        MOV     DPTR,#GTB       ;GET THE BREAK BYTE
4717
        MOVX    A,@DPTR
4718
        JBC     GTRD,TWO_R2
4719
        CLR     A
4720
        ;
4721
TWO_R2: MOV     R2,#00H         ;ACC GOES TO STACK
4722
        ;
4723
        ;
4724
TWO_EX: MOV     R0,A            ;R2:ACC GOES TO STACK
4725
        ;
4726
        ;
4727
TWO_EY: SETB    ARGF            ;R2:R0 GETS PUT ON THE STACK
4728
        JMP     FP_BASE12       ;DO IT
4729
        ;
4730
$EJECT
4731
        ;*************************************************************
4732
        ;
4733
        ; Put directs onto the stack
4734
        ;
4735
        ;**************************************************************
4736
        ;
4737
A_IE:   MOV     A,IE            ;IE
4738
        SJMP    TWO_R2
4739
        ;
4740
A_IP:   MOV     A,IP            ;IP
4741
        SJMP    TWO_R2
4742
        ;
4743
ATIM0:  MOV     R2,TH0          ;TIMER 0
4744
        MOV     R0,TL0
4745
        SJMP    TWO_EY
4746
        ;
4747
ATIM1:  MOV     R2,TH1          ;TIMER 1
4748
        MOV     R0,TL1
4749
        SJMP    TWO_EY
4750
        ;
4751
ATIM2:  MOV     R2,TH2
4752
        MOV     R0,TL2
4753
;       DB      0AAH            ;MOV R2 DIRECT OP CODE
4754
;       DB      0CDH            ;T2 HIGH
4755
;       DB      0A8H            ;MOV R0 DIRECT OP CODE
4756
;       DB      0CCH            ;T2 LOW
4757
        SJMP    TWO_EY          ;TIMER 2
4758
        ;
4759
AT2CON: MOV     A,T2CON
4760
;       DB      0E5H            ;MOV A,DIRECT OPCODE
4761
;       DB      0C8H            ;T2CON LOCATION
4762
        SJMP    TWO_R2
4763
        ;
4764
ATCON:  MOV     A,TCON          ;TCON
4765
        SJMP    TWO_R2
4766
        ;
4767
ATMOD:  MOV     A,TMOD          ;TMOD
4768
        SJMP    TWO_R2
4769
        ;
4770
ARCAP2: MOV     R2,RCAPH2
4771
        MOV     R0,RCAPL2
4772
;       DB      0AAH            ;MOV R2, DIRECT OP CODE
4773
;       DB      0CBH            ;RCAP2H LOCATION
4774
;       DB      0A8H            ;MOV R0, DIRECT OP CODE
4775
;       DB      0CAH            ;R2CAPL LOCATION
4776
        SJMP    TWO_EY
4777
        ;
4778
AP1:    MOV     A,P1            ;GET P1
4779
        SJMP    TWO_R2          ;PUT IT ON THE STACK
4780
        ;
4781
APCON:  MOV     A,PCON
4782
;       DB      0E5H            ;MOV A, DIRECT OP CODE
4783
;       DB      87H             ;ADDRESS OF PCON
4784
        SJMP    TWO_R2          ;PUT PCON ON THE STACK
4785
        ;
4786
$EJECT
4787
        ;***************************************************************
4788
        ;
4789
        ;THIS IS THE LINE EDITOR
4790
        ;
4791
        ;TAKE THE PROCESSED LINE IN IBUF AND INSERT IT INTO THE
4792
        ;BASIC TEXT FILE.
4793
        ;
4794
        ;***************************************************************
4795
        ;
4796
LINE0:  LJMP    NOGO            ;CAN'T EDIT A ROM
4797
        ;
4798
LINE:   MOV     A,BOFAH
4799
        CJNE    A,#HIGH PSTART,LINE0
4800
        CALL    G4              ;GET END ADDRESS FOR EDITING
4801
        MOV     R4,DPL
4802
        MOV     R5,DPH
4803
        MOV     R3,TEMP5        ;GET HIGH ORDER IBLN
4804
        MOV     R1,TEMP4        ;LOW ORDER IBLN
4805
        ;
4806
        CALL    GETLIN          ;FIND THE LINE
4807
        JNZ     INSR            ;INSERT IF NOT ZERO, ELSE APPEND
4808
        ;
4809
        ;APPEND THE LINE AT THE END
4810
        ;
4811
        MOV     A,TEMP3         ;PUT IBCNT IN THE ACC
4812
        CJNE    A,#4H,LINE1     ;SEE IF NO ENTRY
4813
        RET                     ;RET IF NO ENTRY
4814
        ;
4815
LINE1:  ACALL   FULL            ;SEE IF ENOUGH SPACE LEFT
4816
        MOV     R2,R5B0         ;PUT END ADDRESS A INTO TRANSFER
4817
        MOV     R0,R4B0         ;REGISTERS
4818
        ACALL   IMOV            ;DO THE BLOCK MOVE
4819
        ;
4820
UE:     MOV     A,#EOF          ;SAVE EOF CHARACTER
4821
        AJMP    TBR
4822
        ;
4823
        ;INSERT A LINE INTO THE FILE
4824
        ;
4825
INSR:   MOV     R7,A            ;SAVE IT IN R7
4826
        CALL    TEMPD           ;SAVE INSERATION ADDRESS
4827
        MOV     A,TEMP3         ;PUT THE COUNT LENGTH IN THE ACC
4828
        JC      LTX             ;JUMP IF NEW LINE # NOT = OLD LINE #
4829
        CJNE    A,#04H,INSR1    ;SEE IF NULL
4830
        CLR     A
4831
        ;
4832
INSR1:  SUBB    A,R7            ;SUBTRACT LINE COUNT FROM ACC
4833
        JZ      LIN1            ;LINE LENGTHS EQUAL
4834
        JC      GTX             ;SMALLER LINE
4835
        ;
4836
$EJECT
4837
        ;
4838
        ;EXPAND FOR A NEW LINE OR A LARGER LINE
4839
        ;
4840
LTX:    MOV     R7,A            ;SAVE A IN R7
4841
        MOV     A,TEMP3         ;GET THE COUNT IN THE ACC
4842
        CJNE    A,#04H,LTX1     ;DO NO INSERTATION IF NULL LINE
4843
        RET                     ;EXIT IF IT IS
4844
        ;
4845
LTX1:   MOV     A,R7            ;GET THE COUNT BACK - DELTA IN A
4846
        ACALL   FULL            ;SEE IF ENOUGH MEMORY NEW EOFA IN R3:R1
4847
        CALL    DTEMP           ;GET INSERATION ADDRESS
4848
        ACALL   NMOV            ;R7:R6 GETS (EOFA)-DPTR
4849
        CALL    X3120
4850
        MOV     R1,R4B0         ;EOFA LOW
4851
        MOV     R3,R5B0         ;EOFA HIGH
4852
        INC     R6              ;INCREMENT BYTE COUNT
4853
        CJNE    R6,#00,LTX2     ;NEED TO BUMP HIGH BYTE?
4854
        INC     R7
4855
        ;
4856
LTX2:   ACALL   RMOV            ;GO DO THE INSERTION
4857
        SJMP    LIN1            ;INSERT THE CURRENT LINE
4858
        ;
4859
GTX:    CPL     A               ;FLIP ACC
4860
        INC     A               ;TWOS COMPLEMENT
4861
        CALL    ADDPTR          ;DO THE ADDITION
4862
        ACALL   NMOV            ;R7:R6 GETS (EOFA)-DPTR
4863
        MOV     R1,DPL          ;SET UP THE REGISTERS
4864
        MOV     R3,DPH
4865
        MOV     R2,TEMP5        ;PUT INSERTATION ADDRESS IN THE RIGHT REG
4866
        MOV     R0,TEMP4
4867
        JZ      GTX1            ;IF ACC WAS ZERO FROM NMOV, JUMP
4868
        ACALL   LMOV            ;IF NO ZERO DO A LMOV
4869
        ;
4870
GTX1:   ACALL   UE              ;SAVE NEW END ADDRESS
4871
        ;
4872
LIN1:   MOV     R2,TEMP5        ;GET THE INSERTATION ADDRESS
4873
        MOV     R0,TEMP4
4874
        MOV     A,TEMP3         ;PUT THE COUNT LENGTH IN ACC
4875
        CJNE    A,#04H,IMOV     ;SEE IF NULL
4876
        RET                     ;EXIT IF NULL
4877
$EJECT
4878
        ;***************************************************************
4879
        ;
4880
        ;INSERT A LINE AT ADDRESS R2:R0
4881
        ;
4882
        ;***************************************************************
4883
        ;
4884
IMOV:   CLR     A               ;TO SET UP
4885
        MOV     R1,#LOW IBCNT   ;INITIALIZE THE REGISTERS
4886
        MOV     R3,A
4887
        MOV     R6,TEMP3        ;PUT THE BYTE COUNT IN R6 FOR LMOV
4888
        MOV     R7,A            ;PUT A 0 IN R7 FOR LMOV
4889
        ;
4890
        ;***************************************************************
4891
        ;
4892
        ;COPY A BLOCK FROM THE BEGINNING
4893
        ;
4894
        ;R2:R0 IS THE DESTINATION ADDRESS
4895
        ;R3:R1 IS THE SOURCE ADDRESS
4896
        ;R7:R6 IS THE COUNT REGISTER
4897
        ;
4898
        ;***************************************************************
4899
        ;
4900
LMOV:   ACALL   TBYTE           ;TRANSFER THE BYTE
4901
        ACALL   INC3210         ;BUMP THE POINTER
4902
        ACALL   DEC76           ;BUMP R7:R6
4903
        JNZ     LMOV            ;LOOP
4904
        RET                     ;GO BACK TO CALLING ROUTINE
4905
        ;
4906
INC3210:INC     R0
4907
        CJNE    R0,#00H,INC3211
4908
        INC     R2
4909
        ;
4910
INC3211:INC     R1
4911
        CJNE    R1,#00H,INC3212
4912
        INC     R3
4913
INC3212:RET
4914
        ;
4915
$EJECT
4916
        ;***************************************************************
4917
        ;
4918
        ;COPY A BLOCK STARTING AT THE END
4919
        ;
4920
        ;R2:R0 IS THE DESTINATION ADDRESS
4921
        ;R3:R1 IS THE SOURCE ADDRESS
4922
        ;R6:R7 IS THE COUNT REGISTER
4923
        ;
4924
        ;***************************************************************
4925
        ;
4926
RMOV:   ACALL   TBYTE           ;TRANSFER THE BYTE
4927
        ACALL   DEC3210         ;DEC THE LOCATIONS
4928
        ACALL   DEC76           ;BUMP THE COUNTER
4929
        JNZ     RMOV            ;LOOP
4930
        ;
4931
DEC_R:  NOP                     ;CREATE EQUAL TIMING
4932
        RET                     ;EXIT
4933
        ;
4934
DEC3210:DEC     R0              ;BUMP THE POINTER
4935
        CJNE    R0,#0FFH,DEC3212;SEE IF OVERFLOWED
4936
DEC3211:DEC     R2              ;BUMP THE HIGH BYTE
4937
DEC3212:DEC     R1              ;BUMP THE POINTER
4938
        CJNE    R1,#0FFH,DEC_R  ;SEE IF OVERFLOWED
4939
        DEC     R3              ;CHANGE THE HIGH BYTE
4940
        RET                     ;EXIT
4941
        ;
4942
        ;***************************************************************
4943
        ;
4944
        ;TBYTE - TRANSFER A BYTE
4945
        ;
4946
        ;***************************************************************
4947
        ;
4948
TBYTE:  MOV     P2,R3           ;OUTPUT SOURCE REGISTER TO PORT
4949
        MOVX    A,@R1           ;PUT BYTE IN ACC
4950
        ;
4951
TBR:    MOV     P2,R2           ;OUTPUT DESTINATION TO PORT
4952
        MOVX    @R0,A           ;SAVE THE BYTE
4953
        RET                     ;EXIT
4954
        ;
4955
$EJECT
4956
        ;***************************************************************
4957
        ;
4958
        ;NMOV - R7:R6 = END ADDRESS - DPTR
4959
        ;
4960
        ;ACC GETS CLOBBERED
4961
        ;
4962
        ;***************************************************************
4963
        ;
4964
NMOV:   MOV     A,R4            ;THE LOW BYTE OF EOFA
4965
        CLR     C               ;CLEAR THE CARRY FOR SUBB
4966
        SUBB    A,DPL           ;SUBTRACT DATA POINTER LOW
4967
        MOV     R6,A            ;PUT RESULT IN R6
4968
        MOV     A,R5            ;HIGH BYTE OF EOFA
4969
        SUBB    A,DPH           ;SUBTRACT DATA POINTER HIGH
4970
        MOV     R7,A            ;PUT RESULT IN R7
4971
        ORL     A,R6            ;SEE IF ZERO
4972
NMOV1:  RET                     ;EXIT
4973
        ;
4974
        ;***************************************************************
4975
        ;
4976
        ;CHECK FOR A FILE OVERFLOW
4977
        ;LEAVES THE NEW END ADDRESS IN R3:R1
4978
        ;A HAS THE INCREASE IN SIZE
4979
        ;
4980
        ;***************************************************************
4981
        ;
4982
FULL:   ADD     A,R4            ;ADD A TO END ADDRESS
4983
        MOV     R1,A            ;SAVE IT
4984
        CLR     A
4985
        ADDC    A,R5            ;ADD THE CARRY
4986
        MOV     R3,A
4987
        MOV     DPTR,#VARTOP    ;POINT AT VARTOP
4988
        ;
4989
FUL1:   CALL    DCMPX           ;COMPARE THE TWO
4990
        JC      NMOV1           ;OUT OF ROOM
4991
        ;
4992
TB:     MOV     DPTR,#E5X       ;OUT OF MEMORY
4993
        AJMP    FPTS
4994
        ;
4995
$EJECT
4996
        ;***************************************************************
4997
        ;
4998
        ; PP - Preprocesses the line in IBUF back into IBUF
4999
        ;      sets F0 if no line number
5000
        ;      leaves the correct length of processed line in IBCNT
5001
        ;      puts the line number in IBLN
5002
        ;      wastes the text address TXAL and TXAH
5003
        ;
5004
        ;***************************************************************
5005
        ;
5006
PP:     ACALL   T_BUF           ;TXA GETS IBUF
5007
        CALL    INTGER          ;SEE IF A NUMBER PRESENT
5008
        CALL    TEMPD           ;SAVE THE INTEGER IN TEMP5:TEMP4
5009
        MOV     F0,C            ;SAVE INTEGER IF PRESENT
5010
        MOV     DPTR,#IBLN      ;SAVE THE LINE NUMBER, EVEN IF NONE
5011
        ACALL   S20DP
5012
        MOV     R0,TXAL         ;TEXT POINTER
5013
        MOV     R1,#LOW IBUF    ;STORE POINTER
5014
        ;
5015
        ; Now process the line back into IBUF
5016
        ;
5017
PPL:    CLR     ARGF            ;FIRST PASS DESIGNATOR
5018
        MOV     DPTR,#TOKTAB    ;POINT DPTR AT LOOK UP TABLE
5019
        ;
5020
PPL1:   MOV     R5B0,R0         ;SAVE THE READ POINTER
5021
        CLR     A               ;ZERO A FOR LOOKUP
5022
        MOVC    A,@A+DPTR       ;GET THE TOKEN
5023
        MOV     R7,A            ;SAVE TOKEN IN CASE OF MATCH
5024
        ;
5025
PPL2:   MOVX    A,@R0           ;GET THE USER CHARACTER
5026
        MOV     R3,A            ;SAVE FOR REM
5027
        CJNE    A,#'a',PPL21
5028
PPL21:  JC      PPX             ;CONVERT LOWER TO UPPER CASE
5029
        CJNE    A,#('z'+1),PPL22
5030
PPL22:  JNC     PPX
5031
        CLR     ACC.5
5032
        ;
5033
PPX:    MOV     R2,A
5034
        MOVX    @R0,A           ;SAVE UPPER CASE
5035
        INC     DPTR            ;BUMP THE LOOKUP POINTER
5036
        CLR     A
5037
        MOVC    A,@A+DPTR
5038
        CJNE    A,R2B0,PPL3     ;LEAVE IF NOT THE SAME
5039
        INC     R0              ;BUMP THE USER POINTER
5040
        SJMP    PPL2            ;CONTINUE TO LOOP
5041
        ;
5042
PPL3:   JB      ACC.7,PPL6      ;JUMP IF FOUND MATCH
5043
        JZ      PPL6            ;USER MATCH
5044
        ;
5045
        ;
5046
        ; Scan to the next TOKTAB entry
5047
        ;
5048
PPL4:   INC     DPTR            ;ADVANCE THE POINTER
5049
        CLR     A               ;ZERO A FOR LOOKUP
5050
        MOVC    A,@A+DPTR       ;LOAD A WITH TABLE
5051
        JB      ACC.7,PPL41     ;KEEP SCANNING IF NOT A RESERVED WORD
5052
        JNZ     PPL4
5053
        INC     DPTR
5054
        ;
5055
        ; See if at the end of TOKTAB
5056
        ;
5057
PPL41:  MOV     R0,R5B0         ;RESTORE THE POINTER
5058
        CJNE    A,#0FFH,PPL1    ;SEE IF END OF TABLE
5059
        ;
5060
        ; Character not in TOKTAB, so see what it is
5061
        ;
5062
        CJNE    R2,#' ',PPLX    ;SEE IF A SPACE
5063
        INC     R0              ;BUMP USER POINTER
5064
        SJMP    PPL             ;TRY AGAIN
5065
        ;
5066
PPLX:   JNB     XBIT,PPLY       ;EXTERNAL TRAP
5067
        JB      ARGF,PPLY
5068
        SETB    ARGF            ;SAYS THAT THE USER HAS TABLE
5069
        LCALL   2078H           ;SET UP POINTER
5070
        AJMP    PPL1
5071
        ;
5072
PPLY:   ACALL   PPL7            ;SAVE CHARACTER, EXIT IF A CR
5073
        CJNE    A,#'"',PPL      ;SEE IF QUOTED STRING, START AGAIN IF NOT
5074
        ;
5075
        ; Just copy a quoted string
5076
        ;
5077
PPLY1:  ACALL   PPL7            ;SAVE THE CHARACTER, TEST FOR CR
5078
        CJNE    A,#'"',PPLY1    ;IS THERE AN ENDQUOTE, IF NOT LOOP
5079
        SJMP    PPL             ;DO IT AGAIN IF ENDQUOTE
5080
        ;
5081
PPL6:   MOV     A,R7            ;GET THE TOKEN
5082
        ACALL   PPL91           ;SAVE THE TOKEN
5083
        CJNE    A,#T_REM,PPL    ;SEE IF A REM TOKEN
5084
        MOV     A,R3
5085
        ACALL   PPL71           ;WASTE THE REM STATEMENT
5086
PPL61:  ACALL   PPL7            ;LOOP UNTIL A CR
5087
        SJMP    PPL61
5088
        ;
5089
PPL7:   MOVX    A,@R0           ;GET THE CHARACTER
5090
PPL71:  CJNE    A,#CR,PPL9      ;FINISH IF A CR
5091
        POP     R0B0            ;WASTE THE CALLING STACK
5092
        POP     R0B0
5093
        MOVX    @R1,A           ;SAVE CR IN MEMORY
5094
        INC     R1              ;SAVE A TERMINATOR
5095
        MOV     A,#EOF
5096
        MOVX    @R1,A
5097
        MOV     A,R1            ;SUBTRACT FOR LENGTH
5098
        SUBB    A,#4
5099
        MOV     TEMP3,A         ;SAVE LENGTH
5100
        MOV     R1,#LOW IBCNT   ;POINT AT BUFFER COUNT
5101
        ;
5102
PPL9:   INC     R0
5103
PPL91:  MOVX    @R1,A           ;SAVE THE CHARACTER
5104
        INC     R1              ;BUMP THE POINTERS
5105
        RET                     ;EXIT TO CALLING ROUTINE
5106
        ;
5107
        ;
5108
        ;***************************************************************
5109
        ;
5110
        ;DEC76 - DECREMENT THE REGISTER PAIR R7:R6
5111
        ;
5112
        ;ACC = ZERO IF R7:R6 = ZERO ; ELSE ACC DOES NOT
5113
        ;
5114
        ;***************************************************************
5115
        ;
5116
DEC76:  DEC     R6              ;BUMP R6
5117
        CJNE    R6,#0FFH,DEC77  ;SEE IF RAPPED AROUND
5118
        DEC     R7
5119
DEC77:  MOV     A,R7            ;SEE IF ZERO
5120
        ORL     A,R6
5121
        RET                     ;EXIT
5122
        ;
5123
        ;***************************************************************
5124
        ;
5125
        ; MTOP - Get or Put the top of assigned memory
5126
        ;
5127
        ;***************************************************************
5128
        ;
5129
PMTOP:  MOV     DPTR,#MEMTOP
5130
PMTOP1: CALL    L20DPI
5131
        AJMP    TWO_EY          ;PUT R2:R0 ON THE STACK
5132
        ;
5133
$EJECT
5134
        ;*************************************************************
5135
        ;
5136
        ; AXTAL - Crystal value calculations
5137
        ;
5138
        ;*************************************************************
5139
        ;
5140
AXTAL0: MOV     DPTR,#XTALV     ;CRYSTAL VALUE
5141
        ACALL   PUSHC
5142
        ;
5143
AXTAL1: ACALL   CSTAKA2         ;COPY CRYSTAL VALUE TWICE
5144
        ACALL   CSTAKA
5145
        MOV     DPTR,#PTIME     ;PROM TIMER
5146
        ACALL   AXTAL2
5147
        MOV     DPTR,#PROGS
5148
        ACALL   S31L
5149
        MOV     DPTR,#IPTIME    ;IPROM TIMER
5150
        ACALL   AXTAL2
5151
        MOV     DPTR,#IPROGS
5152
        ACALL   S31L
5153
        MOV     DPTR,#TTIME     ;CLOCK CALCULATION
5154
        ACALL   AXTAL3
5155
        MOV     A,R1
5156
        CPL     A
5157
        INC     A
5158
        MOV     SAVE_T,A
5159
        MOV     R3,#HIGH CXTAL
5160
        MOV     R1,#LOW CXTAL
5161
        JMP     POPAS
5162
        ;
5163
AXTAL2: ACALL   AXTAL3
5164
        ;
5165
CBIAS:  ;Bias the crystal calculations
5166
        ;
5167
        MOV     A,R1            ;GET THE LOW COUNT
5168
        CPL     A               ;FLIP IT FOR TIMER LOAD
5169
        ADD     A,#15           ;BIAS FOR CALL AND LOAD TIMES
5170
        MOV     R1,A            ;RESTORE IT
5171
        MOV     A,R3            ;GET THE HIGH COUNT
5172
        CPL     A               ;FLIP IT
5173
        ADDC    A,#00H          ;ADD THE CARRY
5174
        MOV     R3,A            ;RESTORE IT
5175
        RET
5176
        ;
5177
$EJECT
5178
;$INCLUDE(:F2:BAS52.PWM)
5179
;BEGINNING
5180
        ;**************************************************************
5181
        ;
5182
STONE:  ; Toggle the I/O port
5183
        ;
5184
        ;**************************************************************
5185
        ;
5186
        CALL    THREE           ;GET THE NUMBERS
5187
        ACALL   CBIAS           ;BIAS R3:R1 FOR COUNT LOOP
5188
        ;
5189
STONE1: CLR     T_BIT           ;TOGGLE THE BIT
5190
        CLR     TR1             ;STOP THE TIMER
5191
        MOV     TH1,R3          ;LOAD THE TIMER
5192
        MOV     TL1,R1
5193
        CLR     TF1             ;CLEAR THE OVERFLOW FLAG
5194
        SETB    TR1             ;TURN IT ON
5195
        ACALL   DEC76
5196
        JNB     TF1,$           ;WAIT
5197
        ACALL   ALPAR
5198
        SETB    T_BIT           ;BACK TO A ONE
5199
        CALL    TIMER_LOAD1     ;LOAD THE HIGH VALUE
5200
        JNB     TF1,$           ;WAIT
5201
        JNZ     STONE1          ;LOOP
5202
        RET
5203
        ;
5204
 
5205
;END
5206
;$INCLUDE(:F2:BAS52.PWM)
5207
$EJECT
5208
        ;LNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLN
5209
        ;
5210
LNTAB:  ; Natural log lookup table
5211
        ;
5212
        ;LNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLN
5213
        ;
5214
        DB      80H
5215
        DB      00H
5216
        DB      71H
5217
        DB      37H
5218
        DB      13H
5219
        DB      19H
5220
        ;
5221
        DB      7FH
5222
        DB      00H
5223
        DB      76H
5224
        DB      64H
5225
        DB      37H
5226
        DB      94H
5227
        ;
5228
        DB      80H
5229
        DB      00H
5230
        DB      07H
5231
        DB      22H
5232
        DB      75H
5233
        DB      17H
5234
        ;
5235
        DB      80H
5236
        DB      00H
5237
        DB      52H
5238
        DB      35H
5239
        DB      93H
5240
        DB      28H
5241
        ;
5242
        DB      80H
5243
        DB      00H
5244
        DB      71H
5245
        DB      91H
5246
        DB      85H
5247
        DB      86H
5248
        ;
5249
        DB      0FFH
5250
        ;
5251
        DB      81H
5252
        DB      00H
5253
        DB      51H
5254
        DB      58H
5255
        DB      02H
5256
        DB      23H
5257
        ;
5258
$EJECT
5259
        ;SINSINSINSINSINSINSINSINSINSINSINSINSINSINSINSINSIN
5260
        ;
5261
SINTAB: ; Sin lookup table
5262
        ;
5263
        ;SINSINSINSINSINSINSINSINSINSINSINSINSINSINSINSINSIN
5264
        ;
5265
        DB      128-9
5266
        DB      00H
5267
        DB      44H
5268
        DB      90H
5269
        DB      05H
5270
        DB      16H
5271
        ;
5272
        DB      128-7
5273
        DB      01H
5274
        DB      08H
5275
        DB      21H
5276
        DB      05H
5277
        DB      25H
5278
        ;
5279
        DB      128-5
5280
        DB      00H
5281
        DB      19H
5282
        DB      73H
5283
        DB      55H
5284
        DB      27H
5285
        ;
5286
$EJECT
5287
        ;
5288
        DB      128-3
5289
        DB      01H
5290
        DB      70H
5291
        DB      12H
5292
        DB      84H
5293
        DB      19H
5294
        ;
5295
        DB      128-2
5296
        DB      00H
5297
        DB      33H
5298
        DB      33H
5299
        DB      33H
5300
        DB      83H
5301
        ;
5302
        DB      128
5303
        DB      01H
5304
        DB      67H
5305
        DB      66H
5306
        DB      66H
5307
        DB      16H
5308
        ;
5309
FPONE:  DB      128+1
5310
        DB      00H
5311
        DB      00H
5312
        DB      00H
5313
        DB      00H
5314
        DB      10H
5315
        ;
5316
        DB      0FFH            ;END OF TABLE
5317
        ;
5318
$EJECT
5319
        ;
5320
SBAUD:  CALL    AXTAL           ;PUT CRYSTAL ON THE STACK
5321
        CALL    EXPRB           ;PUT THE NUMBER AFTER BAUD ON STACK
5322
        MOV     A,#12
5323
        ACALL   TWO_R2          ;TOS = 12
5324
        ACALL   AMUL            ;TOS = 12*BAUD
5325
        ACALL   ADIV            ;TOS = XTAL/(12*BAUD)
5326
        ACALL   IFIX
5327
        ACALL   CBIAS
5328
        MOV     DPTR,#SPV
5329
        ;
5330
S31L:   JMP     S31DP
5331
        ;
5332
AFREE:  CALL    PMTOP           ;PUT MTOP ON STACK
5333
        CALL    G4              ;GET END ADDRESS
5334
        MOV     R0,DPL
5335
        MOV     R2,DPH
5336
        ACALL   TWO_EY
5337
        ;
5338
ASUB:   LCALL   FP_BASE1        ;DO FP SUB
5339
        AJMP    FPTST
5340
        ;
5341
ALEN:   CALL    CCAL            ;CALCULATE THE LEN OF THE SELECTED PROGRAM
5342
        MOV     R2,R7B0         ;SAVE THE HIGH BYTE
5343
        MOV     A,R6            ;SAVE THE LOW BYTE
5344
        AJMP    TWO_EX          ;PUT IT ON THE STACK
5345
        ;
5346
ATIME:  MOV     C,EA            ;SAVE INTERRUTS
5347
        CLR     EA
5348
        PUSH    MILLIV          ;SAVE MILLI VALUE
5349
        MOV     R2,TVH          ;GET THE TIMER
5350
        MOV     A,TVL
5351
        MOV     EA,C            ;SAVE INTERRUPTS
5352
        ACALL   TWO_EX          ;PUT TIMER ON THE STACK
5353
        POP     ACC             ;GET MILLI
5354
        ACALL   TWO_R2          ;PUT MILLI ON STACK
5355
        MOV     A,#200
5356
        ACALL   TWO_R2          ;DIVIDE MILLI BY 200
5357
        ACALL   ADIV
5358
        ;
5359
AADD:   LCALL   FP_BASE         ;DO FP ADDITION
5360
        AJMP    FPTST           ;CHECK FOR ERRORS
5361
        ;
5362
$EJECT
5363
        ;**************************************************************
5364
        ;
5365
        ; Here are some error messages that were moved
5366
        ;
5367
        ;**************************************************************
5368
        ;
5369
        ;
5370
E1X:    DB      'BAD SYNTAX"'
5371
E2X:    DB      128+10
5372
        DB      'DIVIDE BY ZERO"'
5373
        ;
5374
E6X:    DB      'ARRAY SIZE"'
5375
        ;
5376
$EJECT
5377
        ;**************************************************************
5378
        ;
5379
T_BUF:  ; TXA gets IBUF
5380
        ;
5381
        ;**************************************************************
5382
        ;
5383
        MOV     TXAH,#HIGH IBUF
5384
        MOV     TXAL,#LOW IBUF
5385
        RET
5386
        ;
5387
        ;
5388
        ;***************************************************************
5389
        ;
5390
CXFER:  ; Transfer a program from rom to ram
5391
        ;
5392
        ;***************************************************************
5393
        ;
5394
        CALL    CCAL            ;GET EVERYTHING SET UP
5395
        MOV     R2,#HIGH PSTART
5396
        MOV     R0,#LOW PSTART
5397
        ACALL   LMOV            ;DO THE TRANSFER
5398
        CALL    RCLEAR          ;CLEAR THE MEMORY
5399
        ;
5400
        ; Fall thru to CRAM
5401
        ;
5402
        ;***************************************************************
5403
        ;
5404
CRAM:   ; The command action routine - RAM - Run out of ram
5405
        ;
5406
        ;***************************************************************
5407
        ;
5408
        CLR     CONB            ;CAN'T CONTINUE IF MODE CHANGE
5409
        MOV     BOFAH,#HIGH PSTART
5410
        MOV     BOFAL,#LOW PSTART
5411
        ;
5412
        ; Fall thru to Command Processor
5413
        ;
5414
$EJECT
5415
        ;***************************************************************
5416
        ;
5417
CMND1:  ; The entry point for the command processor
5418
        ;
5419
        ;***************************************************************
5420
        ;
5421
        LCALL   SPRINT1         ;WASTE AT AND HEX
5422
        CLR     XBIT            ;TO RESET IF NEEDED
5423
        CLR     A
5424
        MOV     DPTR,#2002H     ;CHECK FOR EXTERNAL TRAP PACKAGE
5425
        MOVC    A,@A+DPTR
5426
        CJNE    A,#5AH,CMND11
5427
        LCALL   2048H           ;IF PRESENT JUMP TO LOCATION 200BH
5428
CMND11: MOV     DPTR,#RDYS      ;PRINT THE READY MESSAGE
5429
        CALL    CRP             ;DO A CR, THEN, PRINT FROM THE ROM
5430
        ;
5431
CMNDR:  SETB    DIRF            ;SET THE DIRECT INPUT BIT
5432
        MOV     SP,SPSAV        ;LOAD THE STACK
5433
        ACALL   CL7             ;DO A CRLF
5434
        ;
5435
CMNX:   CLR     GTRD            ;CLEAR BREAK
5436
        MOV     DPTR,#5EH       ;DO RUN TRAP
5437
        MOVX    A,@DPTR
5438
        XRL     A,#52
5439
        JNZ     CMNX1
5440
        LJMP    CRUN
5441
CMNX1:  MOV     R5,#'>'         ;OUTPUT A PROMPT
5442
        LCALL   TEROT
5443
        CALL    INLINE          ;INPUT A LINE INTO IBUF
5444
        CALL    PP              ;PRE-PROCESS THE LINE
5445
        JB      F0,CMND3        ;NO LINE NUMBER
5446
        CALL    LINE            ;PROCESS THE LINE
5447
        LCALL   LCLR
5448
        JB      LINEB,CMNX      ;DON'T CLEAR MEMORY IF NO NEED
5449
        SETB    LINEB
5450
        LCALL   RCLEAR          ;CLEAR THE MEMORY
5451
        SJMP    CMNX            ;LOOP BACK
5452
        ;
5453
CMND3:  CALL    T_BUF           ;SET UP THE TEXT POINTER
5454
        CALL    DELTST          ;GET THE CHARACTER
5455
        JZ      CMNDR           ;IF CR, EXIT
5456
        MOV     DPTR,#CMNDD     ;POINT AT THE COMMAND LOOKUP
5457
        CJNE    A,#T_CMND,CMND31;PROCESS STATEMENT IF NOT A COMMAND
5458
CMND31: JC      CMND5
5459
        CALL    GCI1            ;BUMP TXA
5460
        ANL     A,#0FH          ;STRIP MSB'S FOR LOOKUP
5461
        LCALL   ISTA1           ;PROCESS COMMAND
5462
        SJMP    CMNDR
5463
        ;
5464
CMND5:  LJMP    ILOOP           ;CHECK FOR A POSSIBLE BREAK
5465
        ;
5466
        ;
5467
        ;
5468
        ;CONSTANTS
5469
        ;
5470
XTALV:  DB      128+8           ; DEFAULT CRYSTAL VALUE
5471
        DB      00H
5472
        DB      00H
5473
        DB      92H
5474
        DB      05H
5475
        DB      11H
5476
        ;
5477
EXP11:  DB      85H
5478
        DB      00H
5479
        DB      42H
5480
        DB      41H
5481
        DB      87H
5482
        DB      59H
5483
        ;
5484
EXP1:   DB      128+1           ; EXP(1)
5485
        DB      00H
5486
        DB      18H
5487
        DB      28H
5488
        DB      18H
5489
        DB      27H
5490
        ;
5491
IPTIME: DB      128-4           ;FPROG TIMING
5492
        DB      00H
5493
        DB      00H
5494
        DB      00H
5495
        DB      75H
5496
        DB      83H
5497
        ;
5498
PIE:    DB      128+1           ;PI
5499
        DB      00H
5500
        DB      26H
5501
        DB      59H
5502
        DB      41H
5503
        DB      31H             ; 3.1415926
5504
        ;
5505
$EJECT
5506
        ;***************************************************************
5507
        ;
5508
        ; The error messages, some have been moved
5509
        ;
5510
        ;***************************************************************
5511
        ;
5512
E7X:    DB      128+30
5513
        DB      'ARITH. UNDERFLOW"'
5514
        ;
5515
E5X:    DB      'MEMORY ALLOCATION"'
5516
        ;
5517
E3X:    DB      128+40
5518
        DB      'BAD ARGUMENT"'
5519
        ;
5520
EXI:    DB      'I-STACK"'
5521
        ;
5522
$EJECT
5523
        ;***************************************************************
5524
        ;
5525
        ; The command action routine - CONTINUE
5526
        ;
5527
        ;***************************************************************
5528
        ;
5529
CCONT:  MOV     DPTR,#E15X
5530
        JNB     CONB,ERROR      ;ERROR IF CONTINUE IS NOT SET
5531
        ;
5532
CC1:    ;used for input statement entry
5533
        ;
5534
        MOV     TXAH,INTXAH     ;RESTORE TXA
5535
        MOV     TXAL,INTXAL
5536
        JMP     CILOOP          ;EXECUTE
5537
        ;
5538
DTEMP:  MOV     DPH,TEMP5       ;RESTORE DPTR
5539
        MOV     DPL,TEMP4
5540
        RET
5541
        ;
5542
TEMPD:  MOV     TEMP5,DPH
5543
        MOV     TEMP4,DPL
5544
        RET
5545
        ;
5546
$EJECT
5547
        ;**************************************************************
5548
        ;
5549
I_DL:   ; IDLE
5550
        ;
5551
        ;**************************************************************
5552
        ;
5553
        JB      DIRF,E1XX       ;SYNTAX ERROR IN DIRECT INPUT
5554
        CLR     DACK            ;ACK IDLE
5555
        ;
5556
U_ID1:  ORL     PCON,#01H
5557
;       DB      01000011B       ;ORL DIRECT OP CODE
5558
;       DB      87H             ;PCON ADDRESS
5559
;       DB      01H             ;SET IDLE BIT
5560
        JB      INTPEN,I_RET    ;EXIT IF EXTERNAL INTERRUPT
5561
        JBC     U_IDL,I_RET     ;EXIT IF USER WANTS TO
5562
        JNB     OTS,U_ID1       ;LOOP IF TIMER NOT ENABLED
5563
        LCALL   T_CMP           ;CHECK THE TIMER
5564
        JC      U_ID1           ;LOOP IF TIME NOT BIG ENOUGH
5565
        ;
5566
I_RET:  SETB    DACK            ;RESTORE EXECUTION
5567
        RET                     ;EXIT IF IT IS
5568
        ;
5569
        ;
5570
        ;
5571
ER0:    INC     DPTR            ;BUMP TO TEXT
5572
        JB      DIRF,ERROR0     ;CAN'T GET OUT OF DIRECT MODE
5573
        JNB     ON_ERR,ERROR0   ;IF ON ERROR ISN'T SET, GO BACK
5574
        MOV     DPTR,#ERRLOC    ;SAVE THE ERROR CODE
5575
        CALL    RC2             ;SAVE ERROR AND SET UP THE STACKS
5576
        INC     DPTR            ;POINT AT ERRNUM
5577
        JMP     ERL4            ;LOAD ERR NUM AND EXIT
5578
        ;
5579
$EJECT
5580
        ;
5581
        ; Syntax error
5582
        ;
5583
E1XX:   MOV     C,DIRF          ;SEE IF IN DIRECT MODE
5584
E1XX1:  MOV     DPTR,#E1X       ;ERROR MESSAGE
5585
        SJMP    ERROR1          ;TRAP ON SET DIRF
5586
        ;
5587
E1XX2:  MOV     DPTR,#EXI       ;STACK ERROR
5588
        ;
5589
        ; Falls through
5590
        ;
5591
        ;***************************************************************
5592
        ;
5593
        ;ERROR PROCESSOR - PRINT OUT THE ERROR TYPE, CHECK TO SEE IF IN
5594
        ;                  RUN OR COMMAND MODE, FIND AND PRINT OUT THE
5595
        ;                  LINE NUMBER IF IN RUN MODE
5596
        ;
5597
        ;***************************************************************
5598
        ;
5599
ERROR:  CLR     C               ;RESET STACK
5600
ERROR1: MOV     SP,SPSAV        ;RESET THE STACK
5601
        LCALL   SPRINT1         ;CLEAR LINE AND AT MODE
5602
        CLR     A               ;SET UP TO GET ERROR CODE
5603
        MOVC    A,@A+DPTR
5604
        JBC     ACC.7,ER0       ;PROCESS ERROR
5605
        ;
5606
ERROR0: ACALL   TEMPD           ;SAVE THE DATA POINTER
5607
        JC      ERROR01         ;NO RESET IF CARRY IS SET
5608
        LCALL   RC1             ;RESET THE STACKS
5609
ERROR01:CALL    CRLF2           ;DO TWO CARRIAGE RET - LINE FEED
5610
        MOV     DPTR,#ERS       ;OUTPUT ERROR MESSAGE
5611
        CALL    ROM_P
5612
        CALL    DTEMP           ;GET THE ERROR MESSAGE BACK
5613
        ;
5614
ERRS:   CALL    ROM_P           ;PRINT ERROR TYPE
5615
        JNB     DIRF,ER1        ;DO NOT PRINT IN LINE IF DIRF=1
5616
        ;
5617
SERR1:  CLR     STOPBIT         ;PRINT STOP THEN EXIT, FOR LIST
5618
        JMP     CMND1
5619
        ;
5620
ER1:    MOV     DPTR,#INS       ;OUTPUT IN LINE
5621
        CALL    ROM_P
5622
        ;
5623
        ;NOW, FIND THE LINE NUMBER
5624
        ;
5625
        ;
5626
$EJECT
5627
        ;
5628
        ;
5629
        CALL    DP_B            ;GET THE FIRST ADDRESS OF THE PROGRAM
5630
        CLR     A               ;FOR INITIALIZATION
5631
        ;
5632
ER2:    ACALL   TEMPD           ;SAVE THE DPTR
5633
        CALL    ADDPTR          ;ADD ACC TO DPTR
5634
        ACALL   ER4             ;R3:R1 = TXA-DPTR
5635
        JC      ER3             ;EXIT IF DPTR>TXA
5636
        JZ      ER3             ;EXIT IF DPTR=TXA
5637
        MOVX    A,@DPTR         ;GET LENGTH
5638
        CJNE    A,#EOF,ER2      ;SEE IF AT THE END
5639
        ;
5640
ER3:    ACALL   DTEMP           ;PUT THE LINE IN THE DPTR
5641
        ACALL   ER4             ;R3:R1 = TXA - BEGINNING OF LINE
5642
        MOV     A,R1            ;GET LENGTH
5643
        ADD     A,#10           ;ADD 10 TO LENGTH, DPTR STILL HAS ADR
5644
        MOV     MT1,A           ;SAVE THE COUNT
5645
        INC     DPTR            ;POINT AT LINE NUMBER HIGH BYTE
5646
        CALL    PMTOP1          ;LOAD R2:R0, PUT IT ON THE STACK
5647
        ACALL   FP_BASE7        ;OUTPUT IT
5648
        JB      STOPBIT,SERR1   ;EXIT IF STOP BIT SET
5649
        CALL    CRLF2           ;DO SOME CRLF'S
5650
        CALL    DTEMP
5651
        CALL    UPPL            ;UNPROCESS THE LINE
5652
        CALL    CL6             ;PRINT IT
5653
ER31:   MOV     R5,#'-'         ;OUTPUT DASHES, THEN AN X
5654
        ACALL   T_L             ;PRINT AN X IF ERROR CHARACTER FOUND
5655
        DJNZ    MT1,ER31        ;LOOP UNTIL DONE
5656
        MOV     R5,#'X'
5657
        ACALL   T_L
5658
        AJMP    SERR1
5659
        ;
5660
ER4:    MOV     R3,TXAH         ;GET TEXT POINTER AND PERFORM SUBTRACTION
5661
        MOV     R1,TXAL
5662
        JMP     DUBSUB
5663
        ;
5664
$EJECT
5665
        ;**************************************************************
5666
        ;
5667
        ; Interrupt driven timer
5668
        ;
5669
        ;**************************************************************
5670
        ;
5671
I_DR:   MOV     TH0,SAVE_T      ;LOAD THE TIMER
5672
        XCH     A,MILLIV        ;SAVE A, GET MILLI COUNTER
5673
        INC     A               ;BUMP COUNTER
5674
        CJNE    A,#200,TR       ;CHECK OUT TIMER VALUE
5675
        CLR     A               ;FORCE ACC TO BE ZERO
5676
        INC     TVL             ;INCREMENT LOW TIMER
5677
        CJNE    A,TVL,TR        ;CHECK LOW VALUE
5678
        INC     TVH             ;BUMP TIMER HIGH
5679
        ;
5680
TR:     XCH     A,MILLIV
5681
        POP     PSW
5682
        RETI
5683
        ;
5684
$EJECT
5685
;$INCLUDE(:F2:BAS52.CLK)
5686
;BEGINNING
5687
        ;**************************************************************
5688
        ;
5689
        ; The statement action routine - CLOCK
5690
        ;
5691
        ;**************************************************************
5692
        ;
5693
SCLOCK: ACALL   OTST            ;GET CHARACTER AFTER CLOCK TOKEN
5694
        CLR     ET0
5695
        CLR     C_BIT
5696
        JNC     SC_R            ;EXIT IF A ZERO
5697
        ANL     TMOD,#0F0H      ;SET UP THE MODE
5698
        SETB    C_BIT           ;USER INTERRUPTS
5699
        ORL     IE,#82H         ;ENABLE ET0 AND EA
5700
        SETB    TR0             ;TURN ON THE TIMER
5701
        ;
5702
SC_R:   RET
5703
        ;
5704
 
5705
;END
5706
;$INCLUDE(:F2:BAS52.CLK)
5707
        ;***************************************************************
5708
        ;
5709
SUI:    ; Statement USER IN action routine
5710
        ;
5711
        ;***************************************************************
5712
        ;
5713
        ACALL   OTST
5714
        MOV     CIUB,C          ;SET OR CLEAR CIUB
5715
        RET
5716
        ;
5717
        ;***************************************************************
5718
        ;
5719
SUO:    ; Statement USER OUT action routine
5720
        ;
5721
        ;***************************************************************
5722
        ;
5723
        ACALL   OTST
5724
        MOV     COUB,C
5725
        RET
5726
        ;
5727
OTST:   ; Check for a one
5728
        ;
5729
        LCALL   GCI             ;GET THE CHARACTER, CLEARS CARRY
5730
        SUBB    A,#'1'          ;SEE IF A ONE
5731
        CPL     C               ;SETS CARRY IF ONE, CLEARS IT IF ZERO
5732
OTST1:  RET
5733
        ;
5734
$EJECT
5735
        ;**************************************************************
5736
        ;
5737
        ; IBLK - EXECUTE USER SUPPLIED TOKEN
5738
        ;
5739
        ;**************************************************************
5740
        ;
5741
IBLK:   JB      PSW.4,OTST1     ;EXIT IF REGISTER BANK <> 0
5742
        JB      PSW.3,OTST1
5743
        JBC     ACC.7,IBLK1     ;SEE IF BIT SEVEN IS SET
5744
        MOV     DPTR,#USENT     ;USER ENTRY LOCATION
5745
        LJMP    ISTA1
5746
        ;
5747
IBLK1:  JB      ACC.0,FP_BASE6  ;FLOATING POINT INPUT
5748
        JZ      T_L             ;DO OUTPUT ON 80H
5749
        MOV     DPTR,#FP_BASE-2
5750
        JMP     @A+DPTR
5751
        ;
5752
        ;
5753
        ;**************************************************************
5754
        ;
5755
        ; GET_NUM - GET A NUMBER, EITHER HEX OR FLOAT
5756
        ;
5757
        ;**************************************************************
5758
        ;
5759
GET_NUM:ACALL   FP_BASE5        ;SCAN FOR HEX
5760
        JNC     FP_BASE6        ;DO FP INPUT
5761
        ;
5762
        ACALL   FP_BASE9        ;ASCII STRING TO R2:R0
5763
        JNZ     H_RET
5764
        PUSH    DPH             ;SAVE THE DATA_POINTER
5765
        PUSH    DPL
5766
        ACALL   FP_BASE12       ;PUT R2:R0 ON THE STACK
5767
        POP     DPL             ;RESTORE THE DATA_POINTER
5768
        POP     DPH
5769
        CLR     A               ;NO ERRORS
5770
        RET                     ;EXIT
5771
        ;
5772
$EJECT
5773 7 jesus
 
5774
        ; START OF BAUD RATE MODIFICATIONS BY DANIEL WALLNER
5775
TIB1:MOV        ACC,TL2
5776
        JB      ACC.3,TIB1
5777
        CALL    DEC3211
5778
TIB2:   MOV     ACC,TL2
5779
        JNB     ACC.3,TIB2
5780
        JNB     RXD,TIB1                ;16x12 CLOCKS, LOOP UNTIL DONE
5781
        JB      RXD,$           ;WAIT FOR STOP CHARACTER TO END
5782
        RET
5783
 
5784 6 jesus
        ;**************************************************************
5785
        ;
5786
        ; WB - THE EGO MESSAGE
5787
        ;
5788
        ;**************************************************************
5789
        ;
5790 7 jesus
WB:
5791
;       DB      'W'+80H,'R'+80H
5792
;       DB      'I'+80H,'T'+80H,'T','E'+80H,'N'+80H
5793
;       DB      ' ','B'+80H,'Y'+80H,' '
5794
;       DB      'J'+80H,'O'+80H,'H'+80H,'N'+80H,' '+80H
5795
;       DB      'K','A'+80H,'T'+80H,'A'+80H,'U'+80H
5796
;       DB      'S','K'+80H,'Y'+80H
5797
 
5798
        ; END OF BAUD RATE MODIFICATIONS BY DANIEL WALLNER
5799
 
5800 6 jesus
        DB      ', I','N'+80H,'T'+80H,'E'+80H,'L'+80H
5801
        DB      ' '+80H,'C'+80H,'O'+80H,'R'+80H,'P'+80H
5802
        DB      '. 1','9'+80H,'85'
5803
H_RET:  RET
5804
        ;
5805
$EJECT
5806
        ORG     1990H
5807
        ;
5808
OUTPUT:
5809
T_L:    LJMP    TEROT
5810
        ;
5811
        ORG     1F78H
5812
        ;
5813
CKS_I:  JB      CKS_B,CS_I
5814
        LJMP    401BH
5815
        ;
5816
CS_I:   LJMP    2088H
5817
        ;
5818
E14X:   DB      'NO DATA"'
5819
        ;
5820
E11X:   DB      128+20
5821
        DB      'ARITH. OVERFLOW"'
5822
        ;
5823
E16X:   DB      'PROGRAMMING"'
5824
        ;
5825
E15X:   DB      'CAN'
5826
        DB      27H
5827
        DB      'T CONTINUE"'
5828
        ;
5829
E10X:   DB      'INVALID LINE NUMBER"'
5830
        ;
5831
NOROM:  DB      'PROM MODE"'
5832
        ;
5833
S_N:    DB      '*MCS-51(tm) BASIC V1.1*"'
5834
        ;
5835
        ORG     1FF8H
5836
        ;
5837
ERS:    DB      'ERROR: "'
5838
        ;
5839
$EJECT
5840
 
5841
 
5842
;************************************************************
5843
;
5844
; This is a complete BCD floating point package for the 8051 micro-
5845
; controller. It provides 8 digits of accuracy with exponents that
5846
; range from +127 to -127. The mantissa is in packed BCD, while the
5847
; exponent is expressed in pseudo-twos complement. A ZERO exponent
5848
; is used to express the number ZERO. An exponent value of 80H or
5849
; greater than means the exponent is positive, i.e. 80H = E 0,
5850
; 81H = E+1, 82H = E+2 and so on. If the exponent is 7FH or less,
5851
; the exponent is negative, 7FH = E-1, 7EH = E-2, and so on.
5852
; ALL NUMBERS ARE ASSUMED TO BE NORMALIZED and all results are
5853
; normalized after calculation. A normalized mantissa is >=.10 and
5854
; <=.99999999.
5855
;
5856
; The numbers in memory assumed to be stored as follows:
5857
;
5858
; EXPONENT OF ARGUMENT 2   =   VALUE OF ARG_STACK+FP_NUMBER_SIZE
5859
; SIGN OF ARGUMENT 2       =   VALUE OF ARG_STACK+FP_NUMBER_SIZE-1
5860
; DIGIT 78 OF ARGUMENT 2   =   VALUE OF ARG_STACK+FP_NUMBER_SIZE-2
5861
; DIGIT 56 OF ARGUMENT 2   =   VALUE OF ARG_STACK+FP_NUMBER_SIZE-3
5862
; DIGIT 34 OF ARGUMENT 2   =   VALUE OF ARG_STACK+FP_NUMBER_SIZE-4
5863
; DIGIT 12 OF ARGUMENT 2   =   VALUE OF ARG_STACK+FP_NUMBER_SIZE-5
5864
;
5865
; EXPONENT OF ARGUMENT 1   =   VALUE OF ARG_STACK
5866
; SIGN OF ARGUMENT 1       =   VALUE OF ARG_STACK-1
5867
; DIGIT 78 OF ARGUMENT 1   =   VALUE OF ARG_STACK-2
5868
; DIGIT 56 OF ARGUMENT 1   =   VALUE OF ARG_STACK-3
5869
; DIGIT 34 OF ARGUMENT 1   =   VALUE OF ARG_STACK-4
5870
; DIGIT 12 OF ARGUMENT 1   =   VALUE OF ARG_STACK-5
5871
;
5872
; The operations are performed thusly:
5873
;
5874
; ARG_STACK+FP_NUMBER_SIZE = ARG_STACK+FP_NUMBER_SIZE # ARG_STACK
5875
;
5876
; Which is ARGUMENT 2 = ARGUMENT 2 # ARGUMENT 1
5877
;
5878
; Where # can be ADD, SUBTRACT, MULTIPLY OR DIVIDE.
5879
;
5880
; Note that the stack gets popped after an operation.
5881
;
5882
; The FP_COMP instruction POPS the ARG_STACK TWICE and returns status.
5883
;
5884
;**********************************************************************
5885
;
5886
$EJECT
5887
;**********************************************************************
5888
;
5889
; STATUS ON RETURN - After performing an operation (+, -, *, /)
5890
;                    the accumulator contains the following status
5891
;
5892
; ACCUMULATOR - BIT 0 - FLOATING POINT UNDERFLOW OCCURED
5893
;
5894
;             - BIT 1 - FLOATING POINT OVERFLOW OCCURED
5895
;
5896
;             - BIT 2 - RESULT WAS ZER0
5897
;
5898
;             - BIT 3 - DIVIDE BY ZERO ATTEMPTED
5899
;
5900
;             - BIT 4 - NOT USED, 0 RETURNED
5901
;
5902
;             - BIT 5 - NOT USED, 0 RETURNED
5903
;
5904
;             - BIT 6 - NOT USED, 0 RETURNED
5905
;
5906
;             - BIT 7 - NOT USED, 0 RETURNED
5907
;
5908
; NOTE: When underflow occures, a ZERO result is returned.
5909
;       When overflow or divide by zero occures, a result of
5910
;       .99999999 E+127 is returned and it is up to the user
5911
;       to handle these conditions as needed in the program.
5912
;
5913
; NOTE: The Compare instruction returns F0 = 0 if ARG 1 = ARG 2
5914
;       and returns a CARRY FLAG = 1 if ARG 1 is > ARG 2
5915
;
5916
;***********************************************************************
5917
;
5918
$EJECT
5919
;***********************************************************************
5920
;
5921
; The following values MUST be provided by the user
5922
;
5923
;***********************************************************************
5924
;
5925
ARG_STACK       EQU     9       ;ARGUMENT STACK POINTER
5926
ARG_STACK_PAGE  EQU     1
5927
;OUTPUT          EQU     1990H   ;CALL LOCATION TO OUTPUT A CHARACTER
5928
CONVERT         EQU     58H     ;LOCATION TO CONVERT NUMBERS
5929
INTGRC          BIT     25      ;BIT SET IF INTGER ERROR
5930
;
5931
;***********************************************************************
5932
;
5933
; The following equates are used internally
5934
;
5935
;***********************************************************************
5936
;
5937
FP_NUMBER_SIZE  EQU     6
5938
UNDERFLOW       EQU     0
5939
OVERFLOW        EQU     1
5940
ZERO            EQU     2
5941
ZERO_DIVIDE     EQU     3
5942
;
5943
;***********************************************************************
5944
$EJECT
5945
        ;**************************************************************
5946
        ;
5947
        ; The following internal locations are used by the math pack
5948
        ; ordering is important and the FP_DIGITS must be bit
5949
        ; addressable
5950
        ;
5951
        ;***************************************************************
5952
        ;
5953
FP_STATUS       EQU     28H             ;NOT USED
5954
FP_TEMP         EQU     FP_STATUS+1     ;NOT USED
5955
FP_CARRY        EQU     FP_STATUS+2     ;USED FOR BITS
5956
ADD_IN          BIT     35              ;DCMPXZ IN BASIC BACKAGE
5957
XSIGN           BIT     FP_CARRY.0
5958
FOUND_RADIX     BIT     FP_CARRY.1
5959
FIRST_RADIX     BIT     FP_CARRY.2
5960
DONE_LOAD       BIT     FP_CARRY.3
5961
FP_DIG12        EQU     FP_CARRY+1
5962
FP_DIG34        EQU     FP_CARRY+2
5963
FP_DIG56        EQU     FP_CARRY+3
5964
FP_DIG78        EQU     FP_CARRY+4
5965
FP_SIGN         EQU     FP_CARRY+5
5966
MSIGN           BIT     FP_SIGN.0
5967
FP_EXP          EQU     FP_CARRY+6
5968
FP_NIB1         EQU     FP_DIG12
5969
FP_NIB2         EQU     FP_NIB1+1
5970
FP_NIB3         EQU     FP_NIB1+2
5971
FP_NIB4         EQU     FP_NIB1+3
5972
FP_NIB5         EQU     FP_NIB1+4
5973
FP_NIB6         EQU     FP_NIB1+5
5974
FP_NIB7         EQU     FP_NIB1+6
5975
FP_NIB8         EQU     FP_NIB1+7
5976
FP_ACCX         EQU     FP_NIB1+8
5977
FP_ACCC         EQU     FP_NIB1+9
5978
FP_ACC1         EQU     FP_NIB1+10
5979
FP_ACC2         EQU     FP_NIB1+11
5980
FP_ACC3         EQU     FP_NIB1+12
5981
FP_ACC4         EQU     FP_NIB1+13
5982
FP_ACC5         EQU     FP_NIB1+14
5983
FP_ACC6         EQU     FP_NIB1+15
5984
FP_ACC7         EQU     FP_NIB1+16
5985
FP_ACC8         EQU     FP_NIB1+17
5986
FP_ACCS         EQU     FP_NIB1+18
5987
        ;
5988
$EJECT
5989
        ORG     1993H
5990
        ;
5991
        ;**************************************************************
5992
        ;
5993
        ; The floating point entry points and jump table
5994
        ;
5995
        ;**************************************************************
5996
        ;
5997
FP_BASE:        AJMP    FLOATING_ADD
5998
FP_BASE1:       AJMP    FLOATING_SUB
5999
FP_BASE2:       AJMP    FLOATING_COMP
6000
FP_BASE3:       AJMP    FLOATING_MUL
6001
FP_BASE4:       AJMP    FLOATING_DIV
6002
FP_BASE5:       AJMP    HEXSCAN
6003
FP_BASE6:       AJMP    FLOATING_POINT_INPUT
6004
FP_BASE7:       AJMP    FLOATING_POINT_OUTPUT
6005
FP_BASE8:       AJMP    CONVERT_BINARY_TO_ASCII_STRING
6006
FP_BASE9:       AJMP    CONVERT_ASCII_STRING_TO_BINARY
6007
FP_BASE10:      AJMP    MULNUM10
6008
FP_BASE11:      AJMP    HEXOUT
6009
FP_BASE12:      AJMP    PUSHR2R0
6010
        ;
6011
$EJECT
6012
        ;
6013
FLOATING_SUB:
6014
        ;
6015
        MOV     P2,#ARG_STACK_PAGE
6016
        MOV     R0,ARG_STACK
6017
        DEC     R0              ;POINT TO SIGN
6018
        MOVX    A,@R0           ;READ SIGN
6019
        CPL     ACC.0
6020
        MOVX    @R0,A
6021
        ;
6022
        ;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
6023
        ;
6024
FLOATING_ADD:
6025
        ;
6026
        ;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
6027
        ;
6028
        ;
6029
        ACALL   MDES1           ;R7=TOS EXP, R6=TOS-1 EXP, R4=TOS SIGN
6030
                                ;R3=TOS-1 SIGN, OPERATION IS R1 # R0
6031
        ;
6032
        MOV     A,R7            ;GET TOS EXPONENT
6033
        JZ      POP_AND_EXIT    ;IF TOS=0 THEN POP AND EXIT
6034
        CJNE    R6,#0,LOAD1     ;CLEAR CARRY EXIT IF ZERO
6035
        ;
6036
        ;**************************************************************
6037
        ;
6038
SWAP_AND_EXIT:  ; Swap external args and return
6039
        ;
6040
        ;**************************************************************
6041
        ;
6042
        ACALL   LOAD_POINTERS
6043
        MOV     R7,#FP_NUMBER_SIZE
6044
        ;
6045
SE1:    MOVX    A,@R0           ;SWAP THE ARGUMENTS
6046
        MOVX    @R1,A
6047
        DEC     R0
6048
        DEC     R1
6049
        DJNZ    R7,SE1
6050
        ;
6051
POP_AND_EXIT:
6052
        ;
6053
        MOV     A,ARG_STACK     ;POP THE STACK
6054
        ADD     A,#FP_NUMBER_SIZE
6055
        MOV     ARG_STACK,A
6056
        CLR     A
6057
        RET
6058
        ;
6059
        ;
6060
LOAD1:  SUBB    A,R6            ;A = ARG 1 EXP - ARG 2 EXP
6061
        MOV     FP_EXP,R7       ;SAVE EXPONENT AND SIGN
6062
        MOV     FP_SIGN,R4
6063
        JNC     LOAD2           ;ARG1 EXPONENT IS LARGER OR SAME
6064
        MOV     FP_EXP,R6
6065
        MOV     FP_SIGN,R3
6066
        CPL     A
6067
        INC     A               ;COMPENSATE FOR EXP DELTA
6068
        XCH     A,R0            ;FORCE R0 TO POINT AT THE LARGEST
6069
        XCH     A,R1            ;EXPONENT
6070
        XCH     A,R0
6071
        ;
6072
LOAD2:  MOV     R7,A            ;SAVE THE EXPONENT DELTA IN R7
6073
        CLR     ADD_IN
6074
        CJNE    R5,#0,LOAD21
6075
        SETB    ADD_IN
6076
        ;
6077
$EJECT
6078
        ; Load the R1 mantissa
6079
        ;
6080
LOAD21: ACALL   LOADR1_MANTISSA ;LOAD THE SMALLEST NUMBER
6081
        ;
6082
        ; Now align the number to the delta exponent
6083
        ; R4 points to the string of the last digits lost
6084
        ;
6085
        CJNE    R7,#DIGIT+DIGIT+3,LOAD22
6086
LOAD22: JC      LOAD23
6087
        MOV     R7,#DIGIT+DIGIT+2
6088
        ;
6089
LOAD23: MOV     FP_CARRY,#00    ;CLEAR THE CARRY
6090
        ACALL   RIGHT           ;SHIFT THE NUMBER
6091
        ;
6092
        ; Set up for addition and subtraction
6093
        ;
6094
        MOV     R7,#DIGIT       ;LOOP COUNT
6095
        MOV     R1,#FP_DIG78
6096
        MOV     A,#9EH
6097
        CLR     C
6098
        SUBB    A,R4
6099
        DA      A
6100
        XCH     A,R4
6101
        JNZ     LOAD24
6102
        MOV     R4,A
6103
LOAD24: CJNE    A,#50H,LOAD25   ;TEST FOR SUBTRACTION
6104
LOAD25: JNB     ADD_IN,SUBLP    ;DO SUBTRACTION IF NO ADD_IN
6105
        CPL     C               ;FLIP CARRY FOR ADDITION
6106
        ACALL   ADDLP           ;DO ADDITION
6107
        ;
6108
        JNC     ADD_R
6109
        INC     FP_CARRY
6110
        MOV     R7,#1
6111
        ACALL   RIGHT
6112
        ACALL   INC_FP_EXP      ;SHIFT AND BUMP EXPONENT
6113
        ;
6114
ADD_R:  AJMP    STORE_ALIGN_TEST_AND_EXIT
6115
        ;
6116
ADDLP:  MOVX    A,@R0
6117
        ADDC    A,@R1
6118
        DA      A
6119
        MOV     @R1,A
6120
        DEC     R0
6121
        DEC     R1
6122
        DJNZ    R7,ADDLP        ;LOOP UNTIL DONE
6123
        RET
6124
        ;
6125
$EJECT
6126
        ;
6127
SUBLP:  MOVX    A,@R0           ;NOW DO SUBTRACTION
6128
        MOV     R6,A
6129
        CLR     A
6130
        ADDC    A,#99H
6131
        SUBB    A,@R1
6132
        ADD     A,R6
6133
        DA      A
6134
        MOV     @R1,A
6135
        DEC     R0
6136
        DEC     R1
6137
        DJNZ    R7,SUBLP
6138
        JC      FSUB6
6139
        ;
6140
$EJECT
6141
        ;
6142
        ; Need to complement the result and sign because the floating
6143
        ; point accumulator mantissa was larger than the external
6144
        ; memory and their signs were equal.
6145
        ;
6146
        CPL     FP_SIGN.0
6147
        MOV     R1,#FP_DIG78
6148
        MOV     R7,#DIGIT       ;LOOP COUNT
6149
        ;
6150
FSUB5:  MOV     A,#9AH
6151
        SUBB    A,@R1
6152
        ADD     A,#0
6153
        DA      A
6154
        MOV     @R1,A
6155
        DEC     R1
6156
        CPL     C
6157
        DJNZ    R7,FSUB5        ;LOOP
6158
        ;
6159
        ; Now see how many zeros their are
6160
        ;
6161
FSUB6:  MOV     R0,#FP_DIG12
6162
        MOV     R7,#0
6163
        ;
6164
FSUB7:  MOV     A,@R0
6165
        JNZ     FSUB8
6166
        INC     R7
6167
        INC     R7
6168
        INC     R0
6169
        CJNE    R0,#FP_SIGN,FSUB7
6170
        AJMP    ZERO_AND_EXIT
6171
        ;
6172
FSUB8:  CJNE    A,#10H,FSUB81
6173
FSUB81: JNC     FSUB9
6174
        INC     R7
6175
        ;
6176
        ; Now R7 has the number of leading zeros in the FP ACC
6177
        ;
6178
FSUB9:  MOV     A,FP_EXP        ;GET THE OLD EXPONENT
6179
        CLR     C
6180
        SUBB    A,R7            ;SUBTRACT FROM THE NUMBER OF ZEROS
6181
        JZ      FSUB10
6182
        JC      FSUB10
6183
        ;
6184
        MOV     FP_EXP,A        ;SAVE THE NEW EXPONENT
6185
        ;
6186
        ACALL   LEFT1           ;SHIFT THE FP ACC
6187
        MOV     FP_CARRY,#0
6188
        AJMP    STORE_ALIGN_TEST_AND_EXIT
6189
        ;
6190
FSUB10: AJMP    UNDERFLOW_AND_EXIT
6191
        ;
6192
$EJECT
6193
        ;***************************************************************
6194
        ;
6195
FLOATING_COMP:  ; Compare two floating point numbers
6196
                ; used for relational operations and is faster
6197
                ; than subtraction. ON RETURN, The carry is set
6198
                ; if ARG1 is > ARG2, else carry is not set
6199
                ; if ARG1 = ARG2, F0 gets set
6200
        ;
6201
        ;***************************************************************
6202
        ;
6203
        ACALL   MDES1           ;SET UP THE REGISTERS
6204
        MOV     A,ARG_STACK
6205
        ADD     A,#FP_NUMBER_SIZE+FP_NUMBER_SIZE
6206
        MOV     ARG_STACK,A     ;POP THE STACK TWICE, CLEAR THE CARRY
6207
        MOV     A,R6            ;CHECK OUT EXPONENTS
6208
        CLR     F0
6209
        SUBB    A,R7
6210
        JZ      EXPONENTS_EQUAL
6211
        JC      ARG1_EXP_IS_LARGER
6212
        ;
6213
        ; Now the ARG2 EXPONENT is > ARG1 EXPONENT
6214
        ;
6215
SIGNS_DIFFERENT:
6216
        ;
6217
        MOV     A,R3            ;SEE IF SIGN OF ARG2 IS POSITIVE
6218
        SJMP    ARG1_EXP_IS_LARGER1
6219
        ;
6220
ARG1_EXP_IS_LARGER:
6221
        ;
6222
        MOV     A,R4            ;GET THE SIGN OF ARG1 EXPONENT
6223
ARG1_EXP_IS_LARGER1:
6224
        JZ      ARG1_EXP_IS_LARGER2
6225
        CPL     C
6226
ARG1_EXP_IS_LARGER2:
6227
        RET
6228
        ;
6229
EXPONENTS_EQUAL:
6230
        ;
6231
        ; First, test the sign, then the mantissa
6232
        ;
6233
        CJNE    R5,#0,SIGNS_DIFFERENT
6234
        ;
6235
BOTH_PLUS:
6236
        ;
6237
        MOV     R7,#DIGIT       ;POINT AT MS DIGIT
6238
        DEC     R0
6239
        DEC     R0
6240
        DEC     R0
6241
        DEC     R1
6242
        DEC     R1
6243
        DEC     R1
6244
        ;
6245
        ; Now do the compare
6246
        ;
6247
CLOOP:  MOVX    A,@R0
6248
        MOV     R6,A
6249
        MOVX    A,@R1
6250
        SUBB    A,R6
6251
        JNZ     ARG1_EXP_IS_LARGER
6252
        INC     R0
6253
        INC     R1
6254
        DJNZ    R7,CLOOP
6255
        ;
6256
        ; If here, the numbers are the same, the carry is cleared
6257
        ;
6258
        SETB    F0
6259
        RET                     ;EXIT WITH EQUAL
6260
        ;
6261
$EJECT
6262
;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
6263
;
6264
FLOATING_MUL:   ; Floating point multiply
6265
;
6266
;MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
6267
;
6268
        ACALL   MUL_DIV_EXP_AND_SIGN
6269
        ;
6270
        ; check for zero exponents
6271
        ;
6272
        CJNE    R6,#00,FMUL1    ;ARG 2 EXP ZERO?
6273
FMUL0:  AJMP    ZERO_AND_EXIT
6274
        ;
6275
        ; calculate the exponent
6276
        ;
6277
FMUL1:  MOV     FP_SIGN,R5      ;SAVE THE SIGN, IN CASE OF FAILURE
6278
        ;
6279
        MOV     A,R7
6280
        JZ      FMUL0
6281
        ADD     A,R6            ;ADD THE EXPONENTS
6282
        JB      ACC.7,FMUL_OVER
6283
        JBC     CY,FMUL2        ;SEE IF CARRY IS SET
6284
        ;
6285
        AJMP    UNDERFLOW_AND_EXIT
6286
        ;
6287
FMUL_OVER:
6288
        ;
6289
        JNC     FMUL2           ;OK IF SET
6290
        ;
6291
FOV:    AJMP    OVERFLOW_AND_EXIT
6292
        ;
6293
FMUL2:  SUBB    A,#129          ;SUBTRACT THE EXPONENT BIAS
6294
        MOV     R6,A            ;SAVE IT FOR LATER
6295
        ;
6296
        ; Unpack and load R0
6297
        ;
6298
        ACALL   UNPACK_R0
6299
        ;
6300
        ; Now set up for loop multiply
6301
        ;
6302
        MOV     R3,#DIGIT
6303
        MOV     R4,R1B0
6304
        ;
6305
$EJECT
6306
        ;
6307
        ; Now, do the multiply and accumulate the product
6308
        ;
6309
FMUL3:  MOV     R1B0,R4
6310
        MOVX    A,@R1
6311
        MOV     R2,A
6312
        ACALL   MUL_NIBBLE
6313
        ;
6314
        MOV     A,R2
6315
        SWAP    A
6316
        ACALL   MUL_NIBBLE
6317
        DEC     R4
6318
        DJNZ    R3,FMUL3
6319
        ;
6320
        ; Now, pack and restore the sign
6321
        ;
6322
        MOV     FP_EXP,R6
6323
        MOV     FP_SIGN,R5
6324
        AJMP    PACK            ;FINISH IT OFF
6325
        ;
6326
$EJECT
6327
        ;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
6328
        ;
6329
FLOATING_DIV:
6330
        ;
6331
        ;DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
6332
        ;
6333
        ACALL   MDES1
6334
        ;
6335
        ; Check the exponents
6336
        ;
6337
        MOV     FP_SIGN,R5      ;SAVE THE SIGN
6338
        CJNE    R7,#0,DIV0      ;CLEARS THE CARRY
6339
        ACALL   OVERFLOW_AND_EXIT
6340
        CLR     A
6341
        SETB    ACC.ZERO_DIVIDE
6342
        RET
6343
        ;
6344
DIV0:   MOV     A,R6            ;GET EXPONENT
6345
        JZ      FMUL0           ;EXIT IF ZERO
6346
        SUBB    A,R7            ;DELTA EXPONENT
6347
        JB      ACC.7,D_UNDER
6348
        JNC     DIV3
6349
        AJMP    UNDERFLOW_AND_EXIT
6350
        ;
6351
D_UNDER:JNC     FOV
6352
        ;
6353
DIV3:   ADD     A,#129          ;CORRECTLY BIAS THE EXPONENT
6354
        MOV     FP_EXP,A        ;SAVE THE EXPONENT
6355
        ACALL   LOADR1_MANTISSA ;LOAD THE DIVIDED
6356
        ;
6357
        MOV     R2,#FP_ACCC     ;SAVE LOCATION
6358
        MOV     R3,R0B0         ;SAVE POINTER IN R3
6359
        MOV     FP_CARRY,#0     ;ZERO CARRY BYTE
6360
        ;
6361
DIV4:   MOV     R5,#0FFH        ;LOOP COUNT
6362
        SETB    C
6363
        ;
6364
DIV5:   MOV     R0B0,R3         ;RESTORE THE EXTERNAL POINTER
6365
        MOV     R1,#FP_DIG78    ;SET UP INTERNAL POINTER
6366
        MOV     R7,#DIGIT       ;LOOP COUNT
6367
        JNC     DIV7            ;EXIT IF NO CARRY
6368
        ;
6369
DIV6:   MOVX    A,@R0           ;DO ACCUMLATION
6370
        MOV     R6,A
6371
        CLR     A
6372
        ADDC    A,#99H
6373
        SUBB    A,R6
6374
        ADD     A,@R1
6375
        DA      A
6376
        MOV     @R1,A
6377
        DEC     R0
6378
        DEC     R1
6379
        DJNZ    R7,DIV6         ;LOOP
6380
        ;
6381
        INC     R5              ;SUBTRACT COUNTER
6382
        JC      DIV5            ;KEEP LOOPING IF CARRY
6383
        MOV     A,@R1           ;GET CARRY
6384
        SUBB    A,#1            ;CARRY IS CLEARED
6385
        MOV     @R1,A           ;SAVE CARRY DIGIT
6386
        CPL     C
6387
        SJMP    DIV5            ;LOOP
6388
        ;
6389
        ; Restore the result if carry was found
6390
        ;
6391
DIV7:   ACALL   ADDLP           ;ADD NUMBER BACK
6392
        MOV     @R1,#0          ;CLEAR CARRY
6393
        MOV     R0B0,R2         ;GET SAVE COUNTER
6394
        MOV     @R0,5           ;SAVE COUNT BYTE
6395
        ;
6396
        INC     R2              ;ADJUST SAVE COUNTER
6397
        MOV     R7,#1           ;BUMP DIVIDEND
6398
        ACALL   LEFT
6399
        CJNE    R2,#FP_ACC8+2,DIV4
6400
        ;
6401
        DJNZ    FP_EXP,DIV8
6402
        AJMP    UNDERFLOW_AND_EXIT
6403
        ;
6404
DIV8:   MOV     FP_CARRY,#0
6405
        ;
6406
$EJECT
6407
        ;***************************************************************
6408
        ;
6409
PACK:   ; Pack the mantissa
6410
        ;
6411
        ;***************************************************************
6412
        ;
6413
        ; First, set up the pointers
6414
        ;
6415
        MOV     R0,#FP_ACCC
6416
        MOV     A,@R0           ;GET FP_ACCC
6417
        MOV     R6,A            ;SAVE FOR ZERO COUNT
6418
        JZ      PACK0           ;JUMP OVER IF ZERO
6419
        ACALL   INC_FP_EXP      ;BUMP THE EXPONENT
6420
        DEC     R0
6421
        ;
6422
PACK0:  INC     R0              ;POINT AT FP_ACC1
6423
        ;
6424
PACK1:  MOV     A,#8            ;ADJUST NIBBLE POINTER
6425
        MOV     R1,A
6426
        ADD     A,R0
6427
        MOV     R0,A
6428
        CJNE    @R0,#5,PACK11   ;SEE IF ADJUSTING NEEDED
6429
PACK11: JC      PACK31
6430
        ;
6431
PACK2:  SETB    C
6432
        CLR     A
6433
        DEC     R0
6434
        ADDC    A,@R0
6435
        DA      A
6436
        XCHD    A,@R0           ;SAVE THE VALUE
6437
        JNB     ACC.4,PACK3
6438
        DJNZ    R1,PACK2
6439
        ;
6440
        DEC     R0
6441
        MOV     @R0,#1
6442
        ACALL   INC_FP_EXP
6443
        SJMP    PACK4
6444
        ;
6445
PACK3:  DEC     R1
6446
PACK31: MOV     A,R1
6447
        CLR     C
6448
        XCH     A,R0
6449
        SUBB    A,R0
6450
        MOV     R0,A
6451
        ;
6452
PACK4:  MOV     R1,#FP_DIG12
6453
        ;
6454
        ; Now, pack
6455
        ;
6456
PLOOP:  MOV     A,@R0
6457
        SWAP    A               ;FLIP THE DIGITS
6458
        INC     R0
6459
        XCHD    A,@R0
6460
        ORL     6,A             ;ACCUMULATE THE OR'ED DIGITS
6461
        MOV     @R1,A
6462
        INC     R0
6463
        INC     R1
6464
        CJNE    R1,#FP_SIGN,PLOOP
6465
        MOV     A,R6
6466
        JNZ     STORE_ALIGN_TEST_AND_EXIT
6467
        MOV     FP_EXP,#0       ;ZERO EXPONENT
6468
        ;
6469
        ;**************************************************************
6470
        ;
6471
STORE_ALIGN_TEST_AND_EXIT:      ;Save the number align carry and exit
6472
        ;
6473
        ;**************************************************************
6474
        ;
6475
        ACALL   LOAD_POINTERS
6476
        MOV     ARG_STACK,R1    ;SET UP THE NEW STACK
6477
        MOV     R0,#FP_EXP
6478
        ;
6479
        ; Now load the numbers
6480
        ;
6481
STORE2: MOV     A,@R0
6482
        MOVX    @R1,A           ;SAVE THE NUMBER
6483
        DEC     R0
6484
        DEC     R1
6485
        CJNE    R0,#FP_CARRY,STORE2
6486
        ;
6487
        CLR     A               ;NO ERRORS
6488
        ;
6489
PRET:   RET                     ;EXIT
6490
        ;
6491
$EJECT
6492
INC_FP_EXP:
6493
        ;
6494
        INC     FP_EXP
6495
        MOV     A,FP_EXP
6496
        JNZ     PRET            ;EXIT IF NOT ZERO
6497
        POP     ACC             ;WASTE THE CALLING STACK
6498
        POP     ACC
6499
        AJMP    OVERFLOW_AND_EXIT
6500
        ;
6501
;***********************************************************************
6502
;
6503
UNPACK_R0:      ; Unpack BCD digits and load into nibble locations
6504
;
6505
;***********************************************************************
6506
        ;
6507
        PUSH    R1B0
6508
        MOV     R1,#FP_NIB8
6509
        ;
6510
ULOOP:  MOVX    A,@R0
6511
        ANL     A,#0FH
6512
        MOV     @R1,A           ;SAVE THE NIBBLE
6513
        MOVX    A,@R0
6514
        SWAP    A
6515
        ANL     A,#0FH
6516
        DEC     R1
6517
        MOV     @R1,A           ;SAVE THE NIBBLE AGAIN
6518
        DEC     R0
6519
        DEC     R1
6520
        CJNE    R1,#FP_NIB1-1,ULOOP
6521
        ;
6522
        POP     R1B0
6523
        ;
6524
LOAD7:  RET
6525
        ;
6526
$EJECT
6527
        ;**************************************************************
6528
        ;
6529
OVERFLOW_AND_EXIT:      ;LOAD 99999999 E+127,  SET OV BIT, AND EXIT
6530
        ;
6531
        ;**************************************************************
6532
        ;
6533
        MOV     R0,#FP_DIG78
6534
        MOV     A,#99H
6535
        ;
6536
OVE1:   MOV     @R0,A
6537
        DEC     R0
6538
        CJNE    R0,#FP_CARRY,OVE1
6539
        ;
6540
        MOV     FP_EXP,#0FFH
6541
        ACALL   STORE_ALIGN_TEST_AND_EXIT
6542
        ;
6543
        SETB    ACC.OVERFLOW
6544
        RET
6545
        ;
6546
$EJECT
6547
        ;**************************************************************
6548
        ;
6549
UNDERFLOW_AND_EXIT:     ;LOAD 0, SET UF BIT, AND EXIT
6550
        ;
6551
        ;**************************************************************
6552
        ;
6553
        ACALL   ZERO_AND_EXIT
6554
        CLR     A
6555
        SETB    ACC.UNDERFLOW
6556
        RET
6557
        ;
6558
        ;**************************************************************
6559
        ;
6560
ZERO_AND_EXIT:          ;LOAD 0, SET ZERO BIT, AND EXIT
6561
        ;
6562
        ;**************************************************************
6563
        ;
6564
        ACALL   FP_CLEAR
6565
        ACALL   STORE_ALIGN_TEST_AND_EXIT
6566
        SETB    ACC.ZERO
6567
        RET                     ;EXIT
6568
        ;
6569
        ;**************************************************************
6570
        ;
6571
FP_CLEAR:
6572
        ;
6573
        ; Clear internal storage
6574
        ;
6575
        ;**************************************************************
6576
        ;
6577
        CLR     A
6578
        MOV     R0,#FP_ACC8+1
6579
        ;
6580
FPC1:   MOV     @R0,A
6581
        DEC     R0
6582
        CJNE    R0,#FP_TEMP,FPC1
6583
        RET
6584
        ;
6585
$EJECT
6586
        ;**************************************************************
6587
        ;
6588
RIGHT:  ; Shift ACCUMULATOR RIGHT the number of nibbles in R7
6589
        ; Save the shifted values in R4 if SAVE_ROUND is set
6590
        ;
6591
        ;**************************************************************
6592
        ;
6593
        MOV     R4,#0           ;IN CASE OF NO SHIFT
6594
        ;
6595
RIGHT1: CLR     C
6596
RIGHT2: MOV     A,R7            ;GET THE DIGITS TO SHIFT
6597
        JZ      RIGHTL1         ;EXIT IF ZERO
6598
        SUBB    A,#2            ;TWO TO DO?
6599
        JNC     RIGHT5          ;SHIFT TWO NIBBLES
6600
        ;
6601
        ; Swap one nibble then exit
6602
        ;
6603
RIGHT3: PUSH    R0B0            ;SAVE POINTER REGISTER
6604
        PUSH    R1B0
6605
        ;
6606
        MOV     R1,#FP_DIG78    ;LOAD THE POINTERS
6607
        MOV     R0,#FP_DIG56
6608
        MOV     A,R4            ;GET THE OVERFLOW REGISTER
6609
        XCHD    A,@R1           ;GET DIGIT 8
6610
        SWAP    A               ;FLIP FOR LOAD
6611
        MOV     R4,A
6612
        ;
6613
RIGHTL: MOV     A,@R1           ;GET THE LOW ORDER BYTE
6614
        XCHD    A,@R0           ;SWAP NIBBLES
6615
        SWAP    A               ;FLIP FOR STORE
6616
        MOV     @R1,A           ;SAVE THE DIGITS
6617
        DEC     R0              ;BUMP THE POINTERS
6618
        DEC     R1
6619
        CJNE    R1,#FP_DIG12-1,RIGHTL   ;LOOP
6620
        ;
6621
        MOV     A,@R1           ;ACC = CH8
6622
        SWAP    A               ;ACC = 8CH
6623
        ANL     A,#0FH          ;ACC = 0CH
6624
        MOV     @R1,A           ;CARRY DONE
6625
        POP     R1B0            ;EXIT
6626
        POP     R0B0            ;RESTORE REGISTER
6627
RIGHTL1:RET
6628
        ;
6629
RIGHT5: MOV     R7,A            ;SAVE THE NEW SHIFT NUMBER
6630
        CLR     A
6631
        XCH     A,FP_CARRY      ;SWAP THE NIBBLES
6632
        XCH     A,FP_DIG12
6633
        XCH     A,FP_DIG34
6634
        XCH     A,FP_DIG56
6635
        XCH     A,FP_DIG78
6636
        MOV     R4,A            ;SAVE THE LAST DIGIT SHIFTED
6637
        SJMP    RIGHT2
6638
        ;
6639
$EJECT
6640
        ;***************************************************************
6641
        ;
6642
LEFT:   ; Shift ACCUMULATOR LEFT the number of nibbles in R7
6643
        ;
6644
        ;***************************************************************
6645
        ;
6646
        MOV     R4,#00H         ;CLEAR FOR SOME ENTRYS
6647
        ;
6648
LEFT1:  CLR     C
6649
LEFT2:  MOV     A,R7            ;GET SHIFT VALUE
6650
        JZ      LEFTL1          ;EXIT IF ZERO
6651
        SUBB    A,#2            ;SEE HOW MANY BYTES TO SHIFT
6652
        JNC     LEFT5
6653
        ;
6654
LEFT3:  PUSH    R0B0            ;SAVE POINTER
6655
        PUSH    R1B0
6656
        MOV     R0,#FP_CARRY
6657
        MOV     R1,#FP_DIG12
6658
        ;
6659
        MOV     A,@R0           ;ACC=CHCL
6660
        SWAP    A               ;ACC = CLCH
6661
        MOV     @R0,A           ;ACC = CLCH, @R0 = CLCH
6662
        ;
6663
LEFTL:  MOV     A,@R1           ;DIG 12
6664
        SWAP    A               ;DIG 21
6665
        XCHD    A,@R0
6666
        MOV     @R1,A           ;SAVE IT
6667
        INC     R0              ;BUMP POINTERS
6668
        INC     R1
6669
        CJNE    R0,#FP_DIG78,LEFTL
6670
        ;
6671
        MOV     A,R4
6672
        SWAP    A
6673
        XCHD    A,@R0
6674
        ANL     A,#0F0H
6675
        MOV     R4,A
6676
        ;
6677
        POP     R1B0
6678
        POP     R0B0            ;RESTORE
6679
LEFTL1: RET                     ;DONE
6680
        ;
6681
LEFT5:  MOV     R7,A            ;RESTORE COUNT
6682
        CLR     A
6683
        XCH     A,R4            ;GET THE RESTORATION BYTE
6684
        XCH     A,FP_DIG78      ;DO THE SWAP
6685
        XCH     A,FP_DIG56
6686
        XCH     A,FP_DIG34
6687
        XCH     A,FP_DIG12
6688
        XCH     A,FP_CARRY
6689
        SJMP    LEFT2
6690
        ;
6691
$EJECT
6692
MUL_NIBBLE:
6693
        ;
6694
        ; Multiply the nibble in R7 by the FP_NIB locations
6695
        ; accumulate the product in FP_ACC
6696
        ;
6697
        ; Set up the pointers for multiplication
6698
        ;
6699
        ANL     A,#0FH          ;STRIP OFF MS NIBBLE
6700
        MOV     R7,A
6701
        MOV     R0,#FP_ACC8
6702
        MOV     R1,#FP_NIB8
6703
        CLR     A
6704
        MOV     FP_ACCX,A
6705
        ;
6706
MNLOOP: DEC     R0              ;BUMP POINTER TO PROPAGATE CARRY
6707
        ADD     A,@R0           ;ATTEMPT TO FORCE CARRY
6708
        DA      A               ;BCD ADJUST
6709
        JNB     ACC.4,MNL0      ;DON'T ADJUST IF NO NEED
6710
        DEC     R0              ;PROPAGATE CARRY TO THE NEXT DIGIT
6711
        INC     @R0             ;DO THE ADJUSTING
6712
        INC     R0              ;RESTORE R0
6713
        ;
6714
MNL0:   XCHD    A,@R0           ;RESTORE INITIAL NUMBER
6715
        MOV     B,R7            ;GET THE NUBBLE TO MULTIPLY
6716
        MOV     A,@R1           ;GET THE OTHER NIBBLE
6717
        MUL     AB              ;DO THE MULTIPLY
6718
        MOV     B,#10           ;NOW BCD ADJUST
6719
        DIV     AB
6720
        XCH     A,B             ;GET THE REMAINDER
6721
        ADD     A,@R0           ;PROPAGATE THE PARTIAL PRODUCTS
6722
        DA      A               ;BCD ADJUST
6723
        JNB     ACC.4,MNL1      ;PROPAGATE PARTIAL PRODUCT CARRY
6724
        INC     B
6725
        ;
6726
MNL1:   INC     R0
6727
        XCHD    A,@R0           ;SAVE THE NEW PRODUCT
6728
        DEC     R0
6729
        MOV     A,B             ;GET BACK THE QUOTIENT
6730
        DEC     R1
6731
        CJNE    R1,#FP_NIB1-1,MNLOOP
6732
        ;
6733
        ADD     A,FP_ACCX       ;GET THE OVERFLOW
6734
        DA      A               ;ADJUST
6735
        MOV     @R0,A           ;SAVE IT
6736
        RET                     ;EXIT
6737
        ;
6738
$EJECT
6739
        ;***************************************************************
6740
        ;
6741
LOAD_POINTERS:  ; Load the ARG_STACK into R0 and bump R1
6742
        ;
6743
        ;***************************************************************
6744
        ;
6745
        MOV     P2,#ARG_STACK_PAGE
6746
        MOV     R0,ARG_STACK
6747
        MOV     A,#FP_NUMBER_SIZE
6748
        ADD     A,R0
6749
        MOV     R1,A
6750
        RET
6751
        ;
6752
        ;***************************************************************
6753
        ;
6754
MUL_DIV_EXP_AND_SIGN:
6755
        ;
6756
        ; Load the sign into R7, R6. R5 gets the sign for
6757
        ; multiply and divide.
6758
        ;
6759
        ;***************************************************************
6760
        ;
6761
        ACALL   FP_CLEAR        ;CLEAR INTERNAL MEMORY
6762
        ;
6763
MDES1:  ACALL   LOAD_POINTERS   ;LOAD REGISTERS
6764
        MOVX    A,@R0           ;ARG 1 EXP
6765
        MOV     R7,A            ;SAVED IN R7
6766
        MOVX    A,@R1           ;ARG 2 EXP
6767
        MOV     R6,A            ;SAVED IN R6
6768
        DEC     R0              ;BUMP POINTERS TO SIGN
6769
        DEC     R1
6770
        MOVX    A,@R0           ;GET THE SIGN
6771
        MOV     R4,A            ;SIGN OF ARG1
6772
        MOVX    A,@R1           ;GET SIGN OF NEXT ARG
6773
        MOV     R3,A            ;SIGN OF ARG2
6774
        XRL     A,R4            ;ACC GETS THE NEW SIGN
6775
        MOV     R5,A            ;R5 GETS THE NEW SIGN
6776
        ;
6777
        ; Bump the pointers to point at the LS digit
6778
        ;
6779
        DEC     R0
6780
        DEC     R1
6781
        ;
6782
        RET
6783
        ;
6784
$EJECT
6785
        ;***************************************************************
6786
        ;
6787
LOADR1_MANTISSA:
6788
        ;
6789
        ; Load the mantissa of R0 into FP_Digits
6790
        ;
6791
        ;***************************************************************
6792
        ;
6793
        PUSH    R0B0            ;SAVE REGISTER 1
6794
        MOV     R0,#FP_DIG78    ;SET UP THE POINTER
6795
        ;
6796
LOADR1: MOVX    A,@R1
6797
        MOV     @R0,A
6798
        DEC     R1
6799
        DEC     R0
6800
        CJNE    R0,#FP_CARRY,LOADR1
6801
        ;
6802
        POP     R0B0
6803
        RET
6804
        ;
6805
$EJECT
6806
        ;***************************************************************
6807
        ;
6808
HEXSCAN:        ; Scan a string to determine if it is a hex number
6809
                ; set carry if hex, else carry = 0
6810
        ;
6811
        ;***************************************************************
6812
        ;
6813
        ACALL   GET_DPTR_CHARACTER
6814
        PUSH    DPH
6815
        PUSH    DPL             ;SAVE THE POINTER
6816
        ;
6817
HEXSC1: MOVX    A,@DPTR         ;GET THE CHARACTER
6818
        ACALL   DIGIT_CHECK     ;SEE IF A DIGIT
6819
        JC      HS1             ;CONTINUE IF A DIGIT
6820
        ACALL   HEX_CHECK       ;SEE IF HEX
6821
        JC      HS1
6822
        ;
6823
        CLR     ACC.5           ;NO LOWER CASE
6824
        CJNE    A,#'H',HEXDON
6825
        SETB    C
6826
        SJMP    HEXDO1          ;NUMBER IS VALID HEX, MAYBE
6827
        ;
6828
HEXDON: CLR     C
6829
        ;
6830
HEXDO1: POP     DPL             ;RESTORE POINTER
6831
        POP     DPH
6832
        RET
6833
        ;
6834
HS1:    INC     DPTR            ;BUMP TO NEXT CHARACTER
6835
        SJMP    HEXSC1          ;LOOP
6836
        ;
6837
HEX_CHECK:      ;CHECK FOR A VALID ASCII HEX, SET CARRY IF FOUND
6838
        ;
6839
        CLR     ACC.5           ;WASTE LOWER CASE
6840
        CJNE    A,#'F'+1,HEX_CHECK1     ;SEE IF F OR LESS
6841
HEX_CHECK1:
6842
        JC      HC1
6843
        RET
6844
        ;
6845
HC1:    CJNE    A,#'A',HC11     ;SEE IF A OR GREATER
6846
HC11:   CPL     C
6847
        RET
6848
        ;
6849
$EJECT
6850
        ;
6851
PUSHR2R0:
6852
        ;
6853
        MOV     R3,#HIGH CONVERT;CONVERSION LOCATION
6854
        MOV     R1,#LOW CONVERT
6855
        ACALL   CONVERT_BINARY_TO_ASCII_STRING
6856
        MOV     A,#0DH          ;A CR TO TERMINATE
6857
        MOVX    @R1,A           ;SAVE THE CR
6858
        MOV     DPTR,#CONVERT
6859
        ;
6860
        ; Falls thru to FLOATING INPUT
6861
        ;
6862
$EJECT
6863
        ;***************************************************************
6864
        ;
6865
FLOATING_POINT_INPUT:   ; Input a floating point number pointed to by
6866
                        ; the DPTR
6867
        ;
6868
        ;***************************************************************
6869
        ;
6870
        ACALL   FP_CLEAR        ;CLEAR EVERYTHING
6871
        ACALL   GET_DPTR_CHARACTER
6872
        ACALL   PLUS_MINUS_TEST
6873
        MOV     MSIGN,C         ;SAVE THE MANTISSA SIGN
6874
        ;
6875
        ; Now, set up for input loop
6876
        ;
6877
        MOV     R0,#FP_ACCC
6878
        MOV     R6,#7FH         ;BASE EXPONENT
6879
        SETB    F0              ;SET INITIAL FLAG
6880
        ;
6881
INLOOP: ACALL   GET_DIGIT_CHECK
6882
        JNC     GTEST           ;IF NOT A CHARACTER, WHAT IS IT?
6883
        ANL     A,#0FH          ;STRIP ASCII
6884
        ACALL   STDIG           ;STORE THE DIGITS
6885
        ;
6886
INLPIK: INC     DPTR            ;BUMP POINTER FOR LOOP
6887
        SJMP    INLOOP          ;LOOP FOR INPUT
6888
        ;
6889
GTEST:  CJNE    A,#'.',GT1      ;SEE IF A RADIX
6890
        JB      FOUND_RADIX,INERR
6891
        SETB    FOUND_RADIX
6892
        CJNE    R0,#FP_ACCC,INLPIK
6893
        SETB    FIRST_RADIX     ;SET IF FIRST RADIX
6894
        SJMP    INLPIK          ;GET ADDITIONAL DIGITS
6895
        ;
6896
GT1:    JB      F0,INERR        ;ERROR IF NOT CLEARED
6897
        CJNE    A,#'e',GT11     ;CHECK FOR LOWER CASE
6898
        SJMP    GT12
6899
GT11:   CJNE    A,#'E',FINISH_UP
6900
GT12:   ACALL   INC_AND_GET_DPTR_CHARACTER
6901
        ACALL   PLUS_MINUS_TEST
6902
        MOV     XSIGN,C         ;SAVE SIGN STATUS
6903
        ACALL   GET_DIGIT_CHECK
6904
        JNC     INERR
6905
        ;
6906
        ANL     A,#0FH          ;STRIP ASCII BIAS OFF THE CHARACTER
6907
        MOV     R5,A            ;SAVE THE CHARACTER IN R5
6908
        ;
6909
GT2:    INC     DPTR
6910
        ACALL   GET_DIGIT_CHECK
6911
        JNC     FINISH1
6912
        ANL     A,#0FH          ;STRIP OFF BIAS
6913
        XCH     A,R5            ;GET THE LAST DIGIT
6914
        MOV     B,#10           ;MULTIPLY BY TEN
6915
        MUL     AB
6916
        ADD     A,R5            ;ADD TO ORIGINAL VALUE
6917
        MOV     R5,A            ;SAVE IN R5
6918
        JNC     GT2             ;LOOP IF NO CARRY
6919
        MOV     R5,#0FFH        ;FORCE AN ERROR
6920
        ;
6921
FINISH1:MOV     A,R5            ;GET THE SIGN
6922
        JNB     XSIGN,POSNUM    ;SEE IF EXPONENT IS POS OR NEG
6923
        CLR     C
6924
        SUBB    A,R6
6925
        CPL     A
6926
        INC     A
6927
        JC      FINISH2
6928
        MOV     A,#01H
6929
        RET
6930
        ;
6931
POSNUM: ADD     A,R6            ;ADD TO EXPONENT
6932
        JNC     FINISH2
6933
        ;
6934
POSNM1: MOV     A,#02H
6935
        RET
6936
        ;
6937
FINISH2:XCH     A,R6            ;SAVE THE EXPONENT
6938
        ;
6939
FINISH_UP:
6940
        ;
6941
        MOV     FP_EXP,R6       ;SAVE EXPONENT
6942
        CJNE    R0,#FP_ACCC,FINISH_UP1
6943
        ACALL   FP_CLEAR        ;CLEAR THE MEMORY IF 0
6944
FINISH_UP1:
6945
        MOV     A,ARG_STACK     ;GET THE ARG STACK
6946
        CLR     C
6947
        SUBB    A,#FP_NUMBER_SIZE+FP_NUMBER_SIZE
6948
        MOV     ARG_STACK,A     ;ADJUST FOR STORE
6949
        AJMP    PACK
6950
        ;
6951
STDIG:  CLR     F0              ;CLEAR INITIAL DESIGNATOR
6952
        JNZ     STDIG1          ;CONTINUE IF NOT ZERO
6953
        CJNE    R0,#FP_ACCC,STDIG1
6954
        JNB     FIRST_RADIX,RET_X
6955
        ;
6956
DECX:   DJNZ    R6,RET_X
6957
        ;
6958
INERR:  MOV     A,#0FFH
6959
        ;
6960
RET_X:  RET
6961
        ;
6962
STDIG1: JB      DONE_LOAD,FRTEST
6963
        CLR     FIRST_RADIX
6964
        ;
6965
FRTEST: JB      FIRST_RADIX,DECX
6966
        ;
6967
FDTEST: JB      FOUND_RADIX,FDT1
6968
        INC     R6
6969
        ;
6970
FDT1:   JB      DONE_LOAD,RET_X
6971
        CJNE    R0,#FP_ACC8+1,FDT2
6972
        SETB    DONE_LOAD
6973
        ;
6974
FDT2:   MOV     @R0,A           ;SAVE THE STRIPPED ACCUMULATOR
6975
        INC     R0              ;BUMP THE POINTER
6976
        RET                     ;EXIT
6977
        ;
6978
$EJECT
6979
        ;***************************************************************
6980
        ;
6981
        ; I/O utilities
6982
        ;
6983
        ;***************************************************************
6984
        ;
6985
INC_AND_GET_DPTR_CHARACTER:
6986
        ;
6987
        INC     DPTR
6988
        ;
6989
GET_DPTR_CHARACTER:
6990
        ;
6991
        MOVX    A,@DPTR         ;GET THE CHARACTER
6992
        CJNE    A,#' ',PMT1     ;SEE IF A SPACE
6993
        ;
6994
        ; Kill spaces
6995
        ;
6996
        SJMP    INC_AND_GET_DPTR_CHARACTER
6997
        ;
6998
PLUS_MINUS_TEST:
6999
        ;
7000
        CJNE    A,#0E3H,PMT11   ;SEE IF A PLUS, PLUS TOKEN FROM BASIC
7001
        SJMP    PMT3
7002
PMT11:  CJNE    A,#'+',PMT12
7003
        SJMP    PMT3
7004
PMT12:  CJNE    A,#0E5H,PMT13   ;SEE IF MINUS, MINUS TOKEN FROM BASIC
7005
        SJMP    PMT2
7006
PMT13:  CJNE    A,#'-',PMT1
7007
        ;
7008
PMT2:   SETB    C
7009
        ;
7010
PMT3:   INC     DPTR
7011
        ;
7012
PMT1:   RET
7013
        ;
7014
$EJECT
7015
        ;***************************************************************
7016
        ;
7017
FLOATING_POINT_OUTPUT:  ; Output the number, format is in location 23
7018
        ;
7019
        ; IF FORMAT = 00 - FREE FLOATING
7020
        ;           = FX - EXPONENTIAL (X IS THE NUMBER OF SIG DIGITS)
7021
        ;           = NX - N = NUM BEFORE RADIX, X = NUM AFTER RADIX
7022
        ;                  N + X = 8 MAX
7023
        ;
7024
        ;***************************************************************
7025
        ;
7026
        ACALL   MDES1           ;GET THE NUMBER TO OUTPUT, R0 IS POINTER
7027
        ACALL   POP_AND_EXIT    ;OUTPUT POPS THE STACK
7028
        MOV     A,R7
7029
        MOV     R6,A            ;PUT THE EXPONENT IN R6
7030
        ACALL   UNPACK_R0       ;UNPACK THE NUMBER
7031
        MOV     R0,#FP_NIB1     ;POINT AT THE NUMBER
7032
        MOV     A,FORMAT        ;GET THE FORMAT
7033
        MOV     R3,A            ;SAVE IN CASE OF EXP FORMAT
7034
        JZ      FREE            ;FREE FLOATING?
7035
        CJNE    A,#0F0H,FPO1    ;SEE IF EXPONENTIAL
7036
FPO1:   JNC     EXPOUT
7037
        ;
7038
        ; If here, must be integer USING format
7039
        ;
7040
        MOV     A,R6            ;GET THE EXPONENT
7041
        JNZ     FPO2
7042
        MOV     R6,#80H
7043
FPO2:   MOV     A,R3            ;GET THE FORMAT
7044
        SWAP    A               ;SPLIT INTEGER AND FRACTION
7045
        ANL     A,#0FH
7046
        MOV     R2,A            ;SAVE INTEGER
7047
        ACALL   NUM_LT          ;GET THE NUMBER OF INTEGERS
7048
        XCH     A,R2            ;FLIP FOR SUBB
7049
        CLR     C
7050
        SUBB    A,R2
7051
        MOV     R7,A
7052
        JNC     FPO3
7053
        MOV     R5,#'?'         ;OUTPUT A QUESTION MARK
7054
        ACALL   SOUT1           ;NUMBER IS TOO LARGE FOR FORMAT
7055
        AJMP    FREE
7056
FPO3:   CJNE    R2,#00,USING0   ;SEE IF ZERO
7057
        DEC     R7
7058
        ACALL   SS7
7059
        ACALL   ZOUT            ;OUTPUT A ZERO
7060
        SJMP    USING1
7061
        ;
7062
USING0: ACALL   SS7             ;OUTPUT SPACES, IF NEED TO
7063
        MOV     A,R2            ;OUTPUT DIGITS
7064
        MOV     R7,A
7065
        ACALL   OUTR0
7066
        ;
7067
USING1: MOV     A,R3
7068
        ANL     A,#0FH          ;GET THE NUMBER RIGHT OF DP
7069
        MOV     R2,A            ;SAVE IT
7070
        JZ      PMT1            ;EXIT IF ZERO
7071
        ACALL   ROUT            ;OUTPUT DP
7072
        ACALL   NUM_RT
7073
        CJNE    A,2,USINGX      ;COMPARE A TO R2
7074
        ;
7075
USINGY: MOV     A,R2
7076
        AJMP    Z7R7
7077
        ;
7078
USINGX: JNC     USINGY
7079
        ;
7080
USING2: XCH     A,R2
7081
        CLR     C
7082
        SUBB    A,R2
7083
        XCH     A,R2
7084
        ACALL   Z7R7            ;OUTPUT ZEROS IF NEED TO
7085
        MOV     A,R2
7086
        MOV     R7,A
7087
        AJMP    OUTR0
7088
        ;
7089
        ; First, force exponential output, if need to
7090
        ;
7091
FREE:   MOV     A,R6            ;GET THE EXPONENT
7092
        JNZ     FREE1           ;IF ZERO, PRINT IT
7093
        ACALL   SOUT
7094
        AJMP    ZOUT
7095
        ;
7096
FREE1:  MOV     R3,#0F0H        ;IN CASE EXP NEEDED
7097
        MOV     A,#80H-DIGIT-DIGIT-1
7098
        ADD     A,R6
7099
        JC      EXPOUT
7100
        SUBB    A,#0F7H
7101
        JC      EXPOUT
7102
        ;
7103
        ; Now, just print the number
7104
        ;
7105
        ACALL   SINOUT          ;PRINT THE SIGN OF THE NUMBER
7106
        ACALL   NUM_LT          ;GET THE NUMBER LEFT OF DP
7107
        CJNE    A,#8,FREE4
7108
        AJMP    OUTR0
7109
        ;
7110
FREE4:  ACALL   OUTR0
7111
        ACALL   ZTEST           ;TEST FOR TRAILING ZEROS
7112
        JZ      U_RET           ;DONE IF ALL TRAILING ZEROS
7113
        ACALL   ROUT            ;OUTPUT RADIX
7114
        ;
7115
FREE2:  MOV     R7,#1           ;OUTPUT ONE DIGIT
7116
        ACALL   OUTR0
7117
        JNZ     U_RET
7118
        ACALL   ZTEST
7119
        JZ      U_RET
7120
        SJMP    FREE2           ;LOOP
7121
        ;
7122
EXPOUT: ACALL   SINOUT          ;PRINT THE SIGN
7123
        MOV     R7,#1           ;OUTPUT ONE CHARACTER
7124
        ACALL   OUTR0
7125
        ACALL   ROUT            ;OUTPUT RADIX
7126
        MOV     A,R3            ;GET FORMAT
7127
        ANL     A,#0FH          ;STRIP INDICATOR
7128
        JZ      EXPOTX
7129
        ;
7130
        MOV     R7,A            ;OUTPUT THE NUMBER OF DIGITS
7131
        DEC     R7              ;ADJUST BECAUSE ONE CHAR ALREADY OUT
7132
        ACALL   OUTR0
7133
        SJMP    EXPOT4
7134
        ;
7135
EXPOTX: ACALL   FREE2           ;OUTPUT UNTIL TRAILING ZEROS
7136
        ;
7137
EXPOT4: ACALL   SOUT            ;OUTPUT A SPACE
7138
        MOV     R5,#'E'
7139
        ACALL   SOUT1           ;OUTPUT AN E
7140
        MOV     A,R6            ;GET THE EXPONENT
7141
        JZ      XOUT0           ;EXIT IF ZERO
7142
        DEC     A               ;ADJUST FOR THE DIGIT ALREADY OUTPUT
7143
        CJNE    A,#80H,XOUT2    ;SEE WHAT IT IS
7144
        ;
7145
XOUT0:  ACALL   SOUT
7146
        CLR     A
7147
        SJMP    XOUT4
7148
        ;
7149
XOUT2:  JC      XOUT3           ;NEGATIVE EXPONENT
7150
        MOV     R5,#'+'         ;OUTPUT A PLUS SIGN
7151
        ACALL   SOUT1
7152
        SJMP    XOUT4
7153
        ;
7154
XOUT3:  ACALL   MOUT
7155
        CPL     A               ;FLIP BITS
7156
        INC     A               ;BUMP
7157
        ;
7158
XOUT4:  CLR     ACC.7
7159
        MOV     R0,A
7160
        MOV     R2,#0
7161
        MOV     R1,#LOW CONVERT ;CONVERSION LOCATION
7162
        MOV     R3,#HIGH CONVERT
7163
        ACALL   CONVERT_BINARY_TO_ASCII_STRING
7164
        MOV     R0,#LOW CONVERT ;NOW, OUTPUT EXPONENT
7165
        ;
7166
EXPOT5: MOVX    A,@R0           ;GET THE CHARACTER
7167
        MOV     R5,A            ;OUTPUT IT
7168
        ACALL   SOUT1
7169
        INC     R0              ;BUMP THE POINTER
7170
        MOV     A,R0            ;GET THE POINTER
7171
        CJNE    A,R1B0,EXPOT5   ;LOOP
7172
        ;
7173
U_RET:  RET                     ;EXIT
7174
        ;
7175
OUTR0:  ; Output the characters pointed to by R0, also bias ascii
7176
        ;
7177
        MOV     A,R7            ;GET THE COUNTER
7178
        JZ      OUTR            ;EXIT IF DONE
7179
        MOV     A,@R0           ;GET THE NUMBER
7180
        ORL     A,#30H          ;ASCII BIAS
7181
        INC     R0              ;BUMP POINTER AND COUNTER
7182
        DEC     R7
7183
        MOV     R5,A            ;PUT CHARACTER IN OUTPUT REGISTER
7184
        ACALL   SOUT1           ;OUTPUT THE CHARACTER
7185
        CLR     A               ;JUST FOR TEST
7186
        CJNE    R0,#FP_NIB8+1,OUTR0
7187
        MOV     A,#55H          ;KNOW WHERE EXIT OCCURED
7188
        ;
7189
OUTR:   RET
7190
        ;
7191
ZTEST:  MOV     R1,R0B0         ;GET POINTER REGISTER
7192
        ;
7193
ZT0:    MOV     A,@R1           ;GET THE VALUE
7194
        JNZ     ZT1
7195
        INC     R1              ;BUMP POINTER
7196
        CJNE    R1,#FP_NIB8+1,ZT0
7197
        ;
7198
ZT1:    RET
7199
        ;
7200
NUM_LT: MOV     A,R6            ;GET EXPONENT
7201
        CLR     C               ;GET READY FOR SUBB
7202
        SUBB    A,#80H          ;SUB EXPONENT BIAS
7203
        JNC     NL1             ;OK IF NO CARRY
7204
        CLR     A               ;NO DIGITS LEFT
7205
        ;
7206
NL1:    MOV     R7,A            ;SAVE THE COUNT
7207
        RET
7208
        ;
7209
NUM_RT: CLR     C               ;SUBB AGAIN
7210
        MOV     A,#80H          ;EXPONENT BIAS
7211
        SUBB    A,R6            ;GET THE BIASED EXPONENT
7212
        JNC     NR1
7213
        CLR     A
7214
        ;
7215
NR1:    RET                     ;EXIT
7216
        ;
7217
SPACE7: MOV     A,R7            ;GET THE NUMBER OF SPACES
7218
        JZ      NR1             ;EXIT IF ZERO
7219
        ACALL   SOUT            ;OUTPUT A SPACE
7220
        DEC     R7              ;BUMP COUNTER
7221
        SJMP    SPACE7          ;LOOP
7222
        ;
7223
Z7R7:   MOV     R7,A
7224
        ;
7225
ZERO7:  MOV     A,R7            ;GET COUNTER
7226
        JZ      NR1             ;EXIT IF ZERO
7227
        ACALL   ZOUT            ;OUTPUT A ZERO
7228
        DEC     R7              ;BUMP COUNTER
7229
        SJMP    ZERO7           ;LOOP
7230
        ;
7231
SS7:    ACALL   SPACE7
7232
        ;
7233
SINOUT: MOV     A,R4            ;GET THE SIGN
7234
        JZ      SOUT            ;OUTPUT A SPACE IF ZERO
7235
        ;
7236
MOUT:   MOV     R5,#'-'
7237
        SJMP    SOUT1           ;OUTPUT A MINUS IF NOT
7238
        ;
7239
ROUT:   MOV     R5,#'.'         ;OUTPUT A RADIX
7240
        SJMP    SOUT1
7241
        ;
7242
ZOUT:   MOV     R5,#'0'         ;OUTPUT A ZERO
7243
        SJMP    SOUT1
7244
        ;
7245
SOUT:   MOV     R5,#' '         ;OUTPUT A SPACE
7246
        ;
7247
SOUT1:  AJMP    OUTPUT
7248
        ;
7249
$EJECT
7250
        ;***************************************************************
7251
        ;
7252
CONVERT_ASCII_STRING_TO_BINARY:
7253
        ;
7254
        ;DPTR POINTS TO ASCII STRING
7255
        ;PUT THE BINARY NUMBER IN R2:R0, ERROR IF >64K
7256
        ;
7257
        ;***************************************************************
7258
        ;
7259
CASB:   ACALL   HEXSCAN         ;SEE IF HEX NUMBER
7260
        MOV     ADD_IN,C        ;IF ADD_IN IS SET, THE NUMBER IS HEX
7261
        ACALL   GET_DIGIT_CHECK
7262
        CPL     C               ;FLIP FOR EXIT
7263
        JC      RCASB
7264
        MOV     R3,#00H         ;ZERO R3:R1 FOR LOOP
7265
        MOV     R1,#00H
7266
        SJMP    CASB5
7267
        ;
7268
CASB2:  INC     DPTR
7269
        MOV     R0B0,R1         ;SAVE THE PRESENT CONVERTED VALUE
7270
        MOV     R2B0,R3         ;IN R2:R0
7271
        ACALL   GET_DIGIT_CHECK
7272
        JC      CASB5
7273
        JNB     ADD_IN,RCASB    ;CONVERSION COMPLETE
7274
        ACALL   HEX_CHECK       ;SEE IF HEX NUMBER
7275
        JC      CASB4           ;PROCEED IF GOOD
7276
        INC     DPTR            ;BUMP PAST H
7277
        SJMP    RCASB
7278
        ;
7279
CASB4:  ADD     A,#9            ;ADJUST HEX ASCII BIAS
7280
        ;
7281
CASB5:  MOV     B,#10
7282
        JNB     ADD_IN,CASB6
7283
        MOV     B,#16           ;HEX MODE
7284
        ;
7285
CASB6:  ACALL   MULNUM          ;ACCUMULATE THE DIGITS
7286
        JNC     CASB2           ;LOOP IF NO CARRY
7287
        ;
7288
RCASB:  CLR     A               ;RESET ACC
7289
        MOV     ACC.OVERFLOW,C  ;IF OVERFLOW, SAY SO
7290
        RET                     ;EXIT
7291
        ;
7292
$EJECT
7293
        ;
7294
MULNUM10:MOV    B,#10
7295
        ;
7296
        ;***************************************************************
7297
        ;
7298
MULNUM: ; Take the next digit in the acc (masked to 0FH)
7299
        ; accumulate in R3:R1
7300
        ;
7301
        ;***************************************************************
7302
        ;
7303
        PUSH    ACC             ;SAVE ACC
7304
        PUSH    B               ;SAVE MULTIPLIER
7305
        MOV     A,R1            ;PUT LOW ORDER BITS IN ACC
7306
        MUL     AB              ;DO THE MULTIPLY
7307
        MOV     R1,A            ;PUT THE RESULT BACK
7308
        MOV     A,R3            ;GET THE HIGH ORDER BYTE
7309
        MOV     R3,B            ;SAVE THE OVERFLOW
7310
        POP     B               ;GET THE MULTIPLIER
7311
        MUL     AB              ;DO IT
7312
        MOV     C,OV            ;SAVE OVERFLOW IN F0
7313
        MOV     F0,C
7314
        ADD     A,R3            ;ADD OVERFLOW TO HIGH RESULT
7315
        MOV     R3,A            ;PUT IT BACK
7316
        POP     ACC             ;GET THE ORIGINAL ACC BACK
7317
        ORL     C,F0            ;OR CARRY AND OVERFLOW
7318
        JC      MULX            ;NO GOOD IF THE CARRY IS SET
7319
        ;
7320
MUL11:  ANL     A,#0FH          ;MASK OFF HIGH ORDER BITS
7321
        ADD     A,R1            ;NOW ADD THE ACC
7322
        MOV     R1,A            ;PUT IT BACK
7323
        CLR     A               ;PROPAGATE THE CARRY
7324
        ADDC    A,R3
7325
        MOV     R3,A            ;PUT IT BACK
7326
        ;
7327
MULX:   RET                     ;EXIT WITH OR WITHOUT CARRY
7328
        ;
7329
        ;***************************************************************
7330
        ;
7331
CONVERT_BINARY_TO_ASCII_STRING:
7332
        ;
7333
        ;R3:R1 contains the address of the string
7334
        ;R2:R0 contains the value to convert
7335
        ;DPTR, R7, R6, and ACC gets clobbered
7336
        ;
7337
        ;***************************************************************
7338
        ;
7339
        CLR     A               ;NO LEADING ZEROS
7340
        MOV     DPTR,#10000     ;SUBTRACT 10000
7341
        ACALL   RSUB            ;DO THE SUBTRACTION
7342
        MOV     DPTR,#1000      ;NOW 1000
7343
        ACALL   RSUB
7344
        MOV     DPTR,#100       ;NOW 100
7345
        ACALL   RSUB
7346
        MOV     DPTR,#10        ;NOW 10
7347
        ACALL   RSUB
7348
        MOV     DPTR,#1         ;NOW 1
7349
        ACALL   RSUB
7350
        JZ      RSUB2           ;JUMP OVER RET
7351
        ;
7352
RSUB_R: RET
7353
        ;
7354
RSUB:   MOV     R6,#-1          ;SET UP THE COUNTER
7355
        ;
7356
RSUB1:  INC     R6              ;BUMP THE COUNTER
7357
        XCH     A,R2            ;DO A FAST COMPARE
7358
        CJNE    A,DPH,RSUB11
7359
RSUB11: XCH     A,R2
7360
        JC      FAST_DONE
7361
        XCH     A,R0            ;GET LOW BYTE
7362
        SUBB    A,DPL           ;SUBTRACT, CARRY IS CLEARED
7363
        XCH     A,R0            ;PUT IT BACK
7364
        XCH     A,R2            ;GET THE HIGH BYTE
7365
        SUBB    A,DPH           ;ADD THE HIGH BYTE
7366
        XCH     A,R2            ;PUT IT BACK
7367
        JNC     RSUB1           ;LOOP UNTIL CARRY
7368
        ;
7369
        XCH     A,R0
7370
        ADD     A,DPL           ;RESTORE R2:R0
7371
        XCH     A,R0
7372
        XCH     A,R2
7373
        ADDC    A,DPH
7374
        XCH     A,R2
7375
        ;
7376
FAST_DONE:
7377
        ;
7378
        ORL     A,R6            ;OR THE COUNT VALUE
7379
        JZ      RSUB_R          ;RETURN IF ZERO
7380
        ;
7381
RSUB2:  MOV     A,#'0'          ;GET THE ASCII BIAS
7382
        ADD     A,R6            ;ADD THE COUNT
7383
        ;
7384
RSUB4:  MOV     P2,R3           ;SET UP P2
7385
        MOVX    @R1,A           ;PLACE THE VALUE IN MEMORY
7386
        INC     R1
7387
        CJNE    R1,#00H,RSUB3   ;SEE IF RAPPED AROUND
7388
        INC     R3              ;BUMP HIGH BYTE
7389
        ;
7390
RSUB3:  RET                     ;EXIT
7391
        ;
7392
$EJECT
7393
        ;***************************************************************
7394
        ;
7395
HEXOUT: ; Output the hex number in R3:R1, supress leading zeros, if set
7396
        ;
7397
        ;***************************************************************
7398
        ;
7399
        ACALL   SOUT            ;OUTPUT A SPACE
7400
        MOV     C,ZSURP         ;GET ZERO SUPPRESSION BIT
7401
        MOV     ADD_IN,C
7402
        MOV     A,R3            ;GET HIGH NIBBLE AND PRINT IT
7403
        ACALL   HOUTHI
7404
        MOV     A,R3
7405
        ACALL   HOUTLO
7406
        ;
7407
HEX2X:  CLR     ADD_IN          ;DON'T SUPPRESS ZEROS
7408
        MOV     A,R1            ;GET LOW NIBBLE AND PRINT IT
7409
        ACALL   HOUTHI
7410
        MOV     A,R1
7411
        ACALL   HOUTLO
7412
        MOV     R5,#'H'         ;OUTPUT H TO INDICATE HEX MODE
7413
        ;
7414
SOUT_1: AJMP    SOUT1
7415
        ;
7416
HOUT1:  CLR     ADD_IN          ;PRINTED SOMETHING, SO CLEAR ADD_IN
7417
        ADD     A,#90H          ;CONVERT TO ASCII
7418
        DA      A
7419
        ADDC    A,#40H
7420
        DA      A               ;GOT IT HERE
7421
        MOV     R5,A            ;OUTPUT THE BYTE
7422
        SJMP    SOUT_1
7423
        ;
7424
HOUTHI: SWAP    A               ;SWAP TO OUTPUT HIGH NIBBLE
7425
        ;
7426
HOUTLO: ANL     A,#0FH          ;STRIP
7427
        JNZ     HOUT1           ;PRINT IF NOT ZERO
7428
        JNB     ADD_IN,HOUT1    ;OUTPUT A ZERO IF NOT SUPRESSED
7429
        RET
7430
        ;
7431
$EJECT
7432
        ORG     1FEBH           ;FOR LINK COMPATABILITY
7433
        ;
7434
        ;
7435
GET_DIGIT_CHECK:        ; Get a character, then check for digit
7436
        ;
7437
        ACALL   GET_DPTR_CHARACTER
7438
        ;
7439
DIGIT_CHECK:    ;CHECK FOR A VALID ASCII DIGIT, SET CARRY IF FOUND
7440
        ;
7441
        CJNE    A,#'9'+1,DC10   ;SEE IF ASCII 9 OR LESS
7442
DC10:   JC      DC1
7443
        RET
7444
        ;
7445
DC1:    CJNE    A,#'0',DC11     ;SEE IF ASCII 0 OR GREATER
7446
DC11:   CPL     C
7447
        RET
7448
        ;
7449
        ;***************************************************************
7450
        ;
7451
        XSEG    ;External Ram
7452
        ;
7453
        ;***************************************************************
7454
        ;
7455
        DS      4
7456
IBCNT:  DS      1               ;LENGTH OF A LINE
7457
IBLN:   DS      2               ;THE LINE NUMBER
7458
IBUF:   DS      LINLEN          ;THE INPUT BUFFER
7459
CONVT:  DS      15              ;CONVERSION LOCATION FOR FPIN
7460
        ;
7461
        ORG     100H
7462
        ;
7463
GTB:    DS      1               ;GET LOCATION
7464
ERRLOC: DS      1               ;ERROR TYPE
7465
ERRNUM: DS      2               ;WHERE TO GO ON AN ERROR
7466
VARTOP: DS      2               ;TOP OF VARIABLE STORAGE
7467
ST_ALL: DS      2               ;STORAGE ALLOCATION
7468
MT_ALL: DS      2               ;MATRIX ALLOCATION
7469
MEMTOP: DS      2               ;TOP OF MEMORY
7470
RCELL:  DS      2               ;RANDOM NUMBER CELL
7471
        DS      FPSIZ-1
7472
CXTAL:  DS      1               ;CRYSTAL
7473
        DS      FPSIZ-1
7474
FPT1:   DS      1               ;FLOATINP POINT TEMP 1
7475
        DS      FPSIZ-1
7476
FPT2:   DS      1               ;FLOATING POINT TEMP 2
7477
INTLOC: DS      2               ;LOCATION TO GO TO ON INTERRUPT
7478
STR_AL: DS      2               ;STRING ALLOCATION
7479
SPV:    DS      2               ;SERIAL PORT BAUD RATE
7480
TIV:    DS      2               ;TIMER INTERRUPT NUM AND LOC
7481
PROGS:  DS      2               ;PROGRAM A PROM TIME OUT
7482
IPROGS: DS      2               ;INTELLIGENT PROM PROGRAMMER TIMEOUT
7483
TM_TOP: DS      1
7484
 
7485
        END
7486
 
7487
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.