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

Subversion Repositories cpu8080

[/] [cpu8080/] [tags/] [update/] [project/] [tinybasic.asm] - Blame information for rev 9

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

Line No. Rev Author Line
1 9 samiam9512
;**************************************************************
2
;*
3
;*                TINY BASIC FOR INTEL 8080
4
;*                      VERSION 1.0
5
;*                    BY LI-CHEN WANG
6
;*                     10 JUNE, 1976
7
;*                       @COPYLEFT
8
;*                  ALL WRONGS RESERVED
9
;*
10
;**************************************************************
11
;*
12
;*  ;*** ZERO PAGE SUBROUTINES ***
13
;*
14
;*  THE 8080 INSTRUCTION SET LETS YOU HAVE 8 ROUTINES IN LOW
15
;*  MEMORY THAT MAY BE CALLED BY RST N, N BEING 0 THROUGH 7.
16
;*  THIS IS A ONE BYTE INSTRUCTION AND HAS THE SAME POWER AS
17
;*  THE THREE BYTE INSTRUCTION CALL LLHH.  TINY BASIC WILL
18
;*  USE RST 0 AS START AND RST 1 THROUGH RST 7 FOR
19
;*  THE SEVEN MOST FREQUENTLY USED SUBROUTINES.
20
;*  TWO OTHER SUBROUTINES (CRLF AND TSTNUM) ARE ALSO IN THIS
21
;*  SECTION.  THEY CAN BE REACHED ONLY BY 3-BYTE CALLS.
22
;*  IN ORDER TO CONFIGURE THE SYSTEM FOR USE WITH CPM I HAVE
23
;*  MOVED SOME OF THE ROUTINES AROUND.  START WILL NOW BE AT
24
;*  LOCATION 100H AND THIS SECTION WILL END AT LOCATION 3FH
25
;*  WITH A JUMP TO 108H.
26
;*
27
;       ORG  8H
28
;       XTHL           ;*** TSTC OR RST 1 ***
29
;       RST  5         ;IGNORE BLANKS AND
30
;       CMP  M         ;TEST CHARACTER
31
;       JMP  TC1       ;REST OF THIS IS AT TC1
32
;*
33
;CRLF   MVI  A,0DH     ;*** CRLF ***
34
;*
35
;       PUSH PSW       ;*** OUTC OR RST 2 ***
36
;       LDA  OCSW      ;PRINT CHARACTER ONLY
37
;       ORA  A         ;IFF OCSW SWITCH IS ON
38
;       JMP  OC2       ;REST OF THIS IS AT OC2
39
;*
40
;       CALL EXPR2     ;*** EXPR OR RST 3 ***
41
;       PUSH H         ;EVALUATE AN EXPRESION
42
;       JMP  EXPR1     ;REST OF IT IS AT EXPR1
43
;       DB   'W'
44
;*
45
;       MOV  A,H       ;*** COMP OR RST 4 ***
46
;       CMP  D         ;COMPARE HL WITH DE
47
;       RNZ            ;RETURN CORRECT C AND
48
;       MOV  A,L       ;Z FLAGS
49
;       CMP  E         ;BUT OLD A IS LOST
50
;       RET
51
;       DB   'AN'
52
;*
53
;SS1    LDAX D         ;*** IGNBLK/RST 5 ***
54
;       CPI  40Q       ;IGNORE BLANKS
55
;       RNZ            ;IN TEXT (WHERE DE->)
56
;       INX  D         ;AND RETURN THE FIRST
57
;       JMP  SS1       ;NON-BLANK CHAR. IN A
58
;*
59
;       POP  PSW       ;*** FINISH/RST 6 ***
60
;       CALL FIN       ;CHECK END OF COMMAND
61
;       JMP  QWHAT     ;PRINT "WHAT?" IFF WRONG
62
;       DB   'G'
63
;*
64
;       RST  5         ;*** TSTV OR RST 7 ***
65
;       SUI  100Q      ;TEST VARIABLES
66
;       RC             ;C:NOT A VARIABLE
67
;       JMP  TSTV1     ;JUMP AROUND RESERVED AREA
68
       ORG  100H      ;OF CPM.
69
START  JMP  NINIT      ;GO TO INITIALIZATION ROUTINE.   JIF
70
TSTV1  JNZ  TV1       ;NOT "@" ARRAY
71
       INX  D         ;IT IS THE "@" ARRAY
72
       CALL PARN      ;@ SHOULD BE FOLLOWED
73
       DAD  H         ;BY (EXPR) AS ITS INDEX
74
       JC   QHOW      ;IS INDEX TOO BIG?
75
       PUSH D         ;WILL IT OVERWRITE
76
       XCHG           ;TEXT?
77
       CALL SIZE      ;FIND SIZE OF FREE
78
       RST  4         ;AND CHECK THAT
79
       JC   ASORRY    ;IFF SO, SAY "SORRY"
80
SS1A   LXI  H,VARBGN  ;IFF NOT, GET ADDRESS
81
       CALL SUBDE     ;OF @(EXPR) AND PUT IT
82
       POP  D         ;IN HL
83
       RET            ;C FLAG IS CLEARED
84
TV1    CPI  33Q       ;NOT @, IS IT A TO Z?
85
       CMC            ;IFF NOT RETURN C FLAG
86
       RC
87
       INX  D         ;IFF A THROUGH Z
88
TV1A   LXI  H,VARBGN  ;COMPUTE ADDRESS OF
89
       RLC            ;THAT VARIABLE
90
       ADD  L         ;AND RETURN IT IN HL
91
       MOV  L,A       ;WITH C FLAG CLEARED
92
       MVI  A,0
93
       ADC  H
94
       MOV  H,A
95
       RET
96
;*
97
;*                 TSTC   XCH  HL,(SP)   ;*** TSTC OR RST 1 ***
98
;*                        IGNBLK         THIS IS AT LOC. 8
99
;*                        CMP  M         AND THEN JMP HERE
100
TC1    INX  H         ;COMPARE THE BYTE THAT
101
       JZ   TC2       ;FOLLOWS THE RST INST.
102
       PUSH B         ;WITH THE TEXT (DE->)
103
       MOV  C,M       ;IFF NOT =, ADD THE 2ND
104
       MVI  B,0       ;BYTE THAT FOLLOWS THE
105
       DAD  B         ;RST TO THE OLD PC
106
       POP  B         ;I.E., DO A RELATIVE
107
       DCX  D         ;JUMP IFF NOT =
108
TC2    INX  D         ;IFF =, SKIP THOSE BYTES
109
       INX  H         ;AND CONTINUE
110
       XTHL
111
       RET
112
;*
113
TSTNUM LXI  H,0       ;*** TSTNUM ***
114
       MOV  B,H       ;TEST IFF THE TEXT IS
115
       RST  5         ;A NUMBER
116
TN1    CPI  60Q       ;IFF NOT, RETURN 0 IN
117
       RC             ;B AND HL
118
       CPI  72Q       ;IFF NUMBERS, CONVERT
119
       RNC            ;TO BINARY IN HL AND
120
       MVI  A,360Q    ;SET A TO # OF DIGITS
121
       ANA  H         ;IFF H>255, THERE IS NO
122
       JNZ  QHOW      ;ROOM FOR NEXT DIGIT
123
       INR  B         ;B COUNTS # OF DIGITS
124
       PUSH B
125
       MOV  B,H       ;HL=10;*HL+(NEW DIGIT)
126
       MOV  C,L
127
       DAD  H         ;WHERE 10;* IS DONE BY
128
       DAD  H         ;SHIFT AND ADD
129
       DAD  B
130
       DAD  H
131
       LDAX D         ;AND (DIGIT) IS FROM
132
       INX  D         ;STRIPPING THE ASCII
133
       ANI  17Q       ;CODE
134
       ADD  L
135
       MOV  L,A
136
       MVI  A,0
137
       ADC  H
138
       MOV  H,A
139
       POP  B
140
       LDAX D         ;DO THIS DIGIT AFTER
141
       JP   TN1       ;DIGIT. S SAYS OVERFLOW
142
QHOW   PUSH D         ;*** ERROR: "HOW?" ***
143
AHOW   LXI  D,HOW
144
       JMP  ERROR
145
HOW    DB   'HOW?',0DH
146
OK     DB   'OK',0DH
147
WHAT   DB   'WHAT?',0DH
148
SORRY  DB   'SORRY',0DH
149
;*
150
;**************************************************************
151
;*
152
;* *** MAIN ***
153
;*
154
;* THIS IS THE MAIN LOOP THAT COLLECTS THE TINY BASIC PROGRAM
155
;* AND STORES IT IN THE MEMORY.
156
;*
157
;* AT START, IT PRINTS OUT "(CR)OK(CR)", AND INITIALIZES THE
158
;* STACK AND SOME OTHER INTERNAL VARIABLES.  THEN IT PROMPTS
159
;* ">" AND READS A LINE.  IFF THE LINE STARTS WITH A NON-ZERO
160
;* NUMBER, THIS NUMBER IS THE LINE NUMBER.  THE LINE NUMBER
161
;* (IN 16 BIT BINARY) AND THE REST OF THE LINE (INCLUDING CR)
162
;* IS STORED IN THE MEMORY.  IFF A LINE WITH THE SAME LINE
163
;* NUMBER IS ALREDY THERE, IT IS REPLACED BY THE NEW ONE.  IF
164
;* THE REST OF THE LINE CONSISTS OF A 0DHONLY, IT IS NOT STORED
165
;* AND ANY EXISTING LINE WITH THE SAME LINE NUMBER IS DELETED.
166
;*
167
;* AFTER A LINE ISs INSERTED, REPLACED, OR DELETED, THE PROGRAM
168
;* LOOPS BACK AND ASK FOR ANOTHER LINE.  THIS LOOP WILL BE
169
;* TERMINATED WHEN IT READS A LINE WITH ZERO OR NO LINE
170
;* NUMBER; AND CONTROL IS TRANSFERED TO "DIRCT".
171
;*
172
;* TINY BASIC PROGRAM SAVE AREA STARTS AT THE MEMORY LOCATION
173
;* LABELED "TXTBGN" AND ENDED AT "TXTEND".  WE ALWAYS FILL THIS
174
;* AREA STARTING AT "TXTBGN", THE UNFILLED PORTION IS POINTED
175
;* BY THE CONTENT OF A MEMORY LOCATION LABELED "TXTUNF".
176
;*
177
;* THE MEMORY LOCATION "CURRNT" POINTS TO THE LINE NUMBER
178
;* THAT IS CURRENTLY BEING INTERPRETED.  WHILE WE ARE IN
179
;* THIS LOOP OR WHILE WE ARE INTERPRETING A DIRECT COMMAND
180
;* (SEE NEXT SECTION), "CURRNT" SHOULD POINT TO A 0.
181
;*
182
RSTART LXI  SP,STACK  ;SET STACK POINTER
183
ST1    CALL CRLF      ;AND JUMP TO HERE
184
       LXI  D,OK      ;DE->STRING
185
       SUB  A         ;A=0
186
       CALL PRTSTG    ;PRINT STRING UNTIL 0DH
187
       LXI  H,ST2+1   ;LITERAL 0
188
       SHLD CURRNT    ;CURRNT->LINE # = 0
189
ST2    LXI  H,0
190
       SHLD LOPVAR
191
       SHLD STKGOS
192
ST3    MVI  A,76Q     ;PROMPT '>' AND
193
       CALL GETLN     ;READ A LINE
194
       PUSH D         ;DE->END OF LINE
195
ST3A   LXI  D,BUFFER  ;DE->BEGINNING OF LINE
196
       CALL TSTNUM    ;TESt IFF IT IS A NUMBER
197
       RST  5
198
       MOV  A,H       ;HL=VALUE OF THE # OR
199
       ORA  L         ;0 IFF NO # WAS FOUND
200
       POP  B         ;BC->END OF LINE
201
       JZ   DIRECT
202
       DCX  D         ;BACKUP DE AND SAVE
203
       MOV  A,H       ;VALUE OF LINE # THERE
204
       STAX D
205
       DCX  D
206
       MOV  A,L
207
       STAX D
208
       PUSH B         ;BC,DE->BEGIN, END
209
       PUSH D
210
       MOV  A,C
211
       SUB  E
212
       PUSH PSW       ;A=# OF BYTES IN LINE
213
       CALL FNDLN     ;FIND THIS LINE IN SAVE
214
       PUSH D         ;AREA, DE->SAVE AREA
215
       JNZ  ST4       ;NZ:NOT FOUND, INSERT
216
       PUSH D         ;Z:FOUND, DELETE IT
217
       CALL FNDNXT    ;FIND NEXT LINE
218
;*                                       DE->NEXT LINE
219
       POP  B         ;BC->LINE TO BE DELETED
220
       LHLD TXTUNF    ;HL->UNFILLED SAVE AREA
221
       CALL MVUP      ;MOVE UP TO DELETE
222
       MOV  H,B       ;TXTUNF->UNFILLED AREA
223
       MOV  L,C
224
       SHLD TXTUNF    ;UPDATE
225
ST4    POP  B         ;GET READY TO INSERT
226
       LHLD TXTUNF    ;BUT FIRT CHECK IF
227
       POP  PSW       ;THE LENGTH OF NEW LINE
228
       PUSH H         ;IS 3 (LINE # AND CR)
229
       CPI  3         ;THEN DO NOT INSERT
230
       JZ   RSTART    ;MUST CLEAR THE STACK
231
       ADD  L         ;COMPUTE NEW TXTUNF
232
       MOV  L,A
233
       MVI  A,0
234
       ADC  H
235
       MOV  H,A       ;HL->NEW UNFILLED AREA
236
ST4A   LXI  D,TXTEND  ;CHECK TO SEE IF THERE
237
       RST  4         ;IS ENOUGH SPACE
238
       JNC  QSORRY    ;SORRY, NO ROOM FOR IT
239
       SHLD TXTUNF    ;OK, UPDATE TXTUNF
240
       POP  D         ;DE->OLD UNFILLED AREA
241
       CALL MVDOWN
242
       POP  D         ;DE->BEGIN, HL->END
243
       POP  H
244
       CALL MVUP      ;MOVE NEW LINE TO SAVE
245
       JMP  ST3       ;AREA
246
;*
247
;**************************************************************
248
;*
249
;* *** TABLES *** DIRECT *** & EXEC ***
250
;*
251
;* THIS SECTION OF THE CODE TESTS A STRING AGAINST A TABLE.
252
;* WHEN A MATCH IS FOUND, CONTROL IS TRANSFERED TO THE SECTION
253
;* OF CODE ACCORDING TO THE TABLE.
254
;*
255
;* AT 'EXEC', DE SHOULD POINT TO THE STRING AD HL SHOULD POINT
256
;* TO THE TABLE-1.  AT 'DIRECT', DE SHOULD POINT TO THE STRING,
257
;* HL WILL BE SET UP TO POINT TO TAB1-1, WHICH IS THE TABLE OF
258
;* ALL DIRECT AND STATEMENT COMMANDS.
259
;*
260
;* A '.' IN THE STRING WILL TERMINATE THE TEST AND THE PARTIAL
261
;* MATCH WILL BE CONSIDERED AS A MATCH.  E.G., 'P.', 'PR.',
262
;* 'PRI.', 'PRIN.', OR 'PRINT' WILL ALL MATCH 'PRINT'.
263
;*
264
;* THE TABLE CONSISTS OF ANY NUMBER OF ITEMS.  EACH ITEM
265
;* IS A STRING OF CHARACTERS WITH BIT 7 SET TO 0 AND
266
;* A JUMP ADDRESS STORED HI-LOW WITH BIT 7 OF THE HIGH
267
;* BYTE SET TO 1.
268
;*
269
;* END OF TABLE IS AN ITEM WITH A JUMP ADDRESS ONLY.  IFF THE
270
;* STRING DOES NOT MATCH ANY OF THE OTHER ITEMS, IT WILL
271
;* MATCH THIS NULL ITEM AS DEFAULT.
272
;*
273
TAB1   EQU  $         ;DIRECT COMMANDS
274
       DB   'LIST'
275
       DB   LIST SHR 8 + 128,LIST AND 0FFH
276
       DB   'RUN'
277
       DB   RUN SHR 8 + 128,RUN AND 255
278
       DB   'NEW'
279
       DB   NEW SHR 8 + 128,NEW AND 255
280
       DB   'LOAD'
281
       DB   DLOAD SHR 8 + 128,DLOAD AND 255
282
       DB   'SAVE'
283
       DB   DSAVE SHR 8 + 128,DSAVE AND 255
284
       DB   'BYE',80H,0H   ;GO BACK TO CPM
285
TAB2   EQU  $         ;DIRECT/TATEMENT
286
       DB   'NEXT'
287
       DB   NEXT SHR 8 + 128,NEXT AND 255
288
       DB   'LET'
289
       DB   LET SHR 8 + 128,LET AND 255
290
       DB   'OUT'
291
       DB   OUTCMD SHR 8 + 128,OUTCMD AND 255
292
       DB   'POKE'
293
       DB   POKE SHR 8 + 128,POKE AND 255
294
       DB   'WAIT'
295
       DB   WAITCM SHR 8 + 128,WAITCM AND 255
296
       DB   'IF'
297
       DB   IFF SHR 8 + 128,IFF AND 255
298
       DB   'GOTO'
299
       DB   GOTO SHR 8 + 128,GOTO AND 255
300
       DB   'GOSUB'
301
       DB   GOSUB SHR 8 + 128,GOSUB AND 255
302
       DB   'RETURN'
303
       DB   RETURN SHR 8 + 128,RETURN AND 255
304
       DB   'REM'
305
       DB   REM SHR 8 + 128,REM AND 255
306
       DB   'FOR'
307
       DB   FOR SHR 8 + 128,FOR AND 255
308
       DB   'INPUT'
309
       DB   INPUT SHR 8 + 128,INPUT AND 255
310
       DB   'PRINT'
311
       DB   PRINT SHR 8 + 128,PRINT AND 255
312
       DB   'STOP'
313
       DB   STOP SHR 8 + 128,STOP AND 255
314
       DB   DEFLT SHR 8 + 128,DEFLT AND 255
315
       DB   'YOU CAN ADD MORE' ;COMMANDS BUT
316
            ;REMEMBER TO MOVE DEFAULT DOWN.
317
TAB4   EQU  $         ;FUNCTIONS
318
       DB   'RND'
319
       DB   RND SHR 8 + 128,RND AND 255
320
       DB   'INP'
321
       DB   INP SHR 8 + 128,INP AND 255
322
       DB   'PEEK'
323
       DB   PEEK SHR 8 + 128,PEEK AND 255
324
       DB   'USR'
325
       DB   USR SHR 8 + 128,USR AND 255
326
       DB   'ABS'
327
       DB   ABS SHR 8 + 128,ABS AND 255
328
       DB   'SIZE'
329
       DB   SIZE SHR 8 + 128,SIZE AND 255
330
       DB   XP40 SHR 8 + 128,XP40 AND 255
331
       DB   'YOU CAN ADD MORE' ;FUNCTIONS BUT REMEMBER
332
                      ;TO MOVE XP40 DOWN
333
TAB5   EQU  $         ;"TO" IN "FOR"
334
       DB   'TO'
335
       DB   FR1 SHR 8 + 128,FR1 AND 255
336
       DB   QWHAT SHR 8 + 128,QWHAT AND 255
337
TAB6   EQU  $         ;"STEP" IN "FOR"
338
       DB   'STEP'
339
       DB   FR2 SHR 8 + 128,FR2 AND 255
340
       DB   FR3 SHR 8 + 128,FR3 AND 255
341
TAB8   EQU  $         ;RELATION OPERATORS
342
       DB   '>='
343
       DB   XP11 SHR 8 + 128,XP11 AND 255
344
       DB   '#'
345
       DB   XP12 SHR 8 + 128,XP12 AND 255
346
       DB   '>'
347
       DB   XP13 SHR 8 + 128,XP13 AND 255
348
       DB   '='
349
       DB   XP15 SHR 8 + 128,XP15 AND 255
350
       DB   '<='
351
       DB   XP14 SHR 8 + 128,XP14 AND 255
352
       DB   '<'
353
       DB   XP16 SHR 8 + 128,XP16 AND 255
354
       DB   XP17 SHR 8 + 128,XP17 AND 255
355
;*
356
DIRECT LXI  H,TAB1-1  ;*** DIRECT ***
357
;*
358
EXEC   EQU  $         ;*** EXEC ***
359
EX0    RST  5         ;IGNORE LEADING BLANKS
360
       PUSH D         ;SAVE POINTER
361
EX1    LDAX D         ;IFF FOUND '.' IN STRING
362
       INX  D         ;BEFORE ANY MISMATCH
363
       CPI  56Q       ;WE DECLARE A MATCH
364
       JZ   EX3
365
       INX  H         ;HL->TABLE
366
       CMP  M         ;IFF MATCH, TEST NEXT
367
       JZ   EX1
368
       MVI  A,177Q    ;ELSE, SEE IFF BIT 7
369
       DCX  D         ;OF TABLEIS SET, WHICH
370
       CMP  M         ;IS THE JUMP ADDR. (HI)
371
       JC   EX5       ;C:YES, MATCHED
372
EX2    INX  H         ;NC:NO, FIND JUMP ADDR.
373
       CMP  M
374
       JNC  EX2
375
       INX  H         ;BUMP TO NEXT TAB. ITEM
376
       POP  D         ;RESTORE STRING POINTER
377
       JMP  EX0       ;TEST AGAINST NEXT ITEM
378
EX3    MVI  A,177Q    ;PARTIAL MATCH, FIND
379
EX4    INX  H         ;JUMP ADDR., WHICH IS
380
       CMP  M         ;FLAGGED BY BIT 7
381
       JNC  EX4
382
EX5    MOV  A,M       ;LOAD HL WITH THE JUMP
383
       INX  H         ;ADDRESS FROM THE TABLE
384
       MOV  L,M
385
       ANI  177Q      ;MASK OFF BIT 7
386
       MOV  H,A
387
       POP  PSW       ;CLEAN UP THE GABAGE
388
       PCHL           ;AND WE GO DO IT
389
;*
390
;**************************************************************
391
;*
392
;* WHAT FOLLOWS IS THE CODE TO EXECUTE DIRECT AND STATEMENT
393
;* COMMANDS.  CONTROL IS TRANSFERED TO THESE POINTS VIA THE
394
;* COMMAND TABLE LOOKUP CODE OF 'DIRECT' AND 'EXEC' IN LAST
395
;* SECTION.  AFTER THE COMMAND IS EXECUTED, CONTROL IS
396
;* TANSFERED TO OTHER SECTIONS AS FOLLOWS:
397
;*
398
;* FOR 'LIST', 'NEW', AND 'STOP': GO BACK TO 'RSTART'
399
;* FOR 'RUN': GO EXECUTE THE FIRST STORED LINE IFF ANY; ELSE
400
;* GO BACK TO 'RSTART'.
401
;* FOR 'GOTO' AND 'GOSUB': GO EXECUTE THE TARGET LINE.
402
;* FOR 'RETURN' AND 'NEXT': GO BACK TO SAVED RETURN LINE.
403
;* FOR ALL OTHERS: IFF 'CURRNT' -> 0, GO TO 'RSTART', ELSE
404
;* GO EXECUTE NEXT COMMAND.  (THIS IS DONE IN 'FINISH'.)
405
;*
406
;**************************************************************
407
;*
408
;* *** NEW *** STOP *** RUN (& FRIENDS) *** & GOTO ***
409
;*
410
;* 'NEW(CR)' SETS 'TXTUNF' TO POINT TO 'TXTBGN'
411
;*
412
;* 'STOP(CR)' GOES BACK TO 'RSTART'
413
;*
414
;* 'RUN(CR)' FINDS THE FIRST STORED LINE, STORE ITS ADDRESS (IN
415
;* 'CURRNT'), AND START EXECUTE IT.  NOTE THAT ONLY THOSE
416
;* COMMANDS IN TAB2 ARE LEGAL FOR STORED PROGRAM.
417
;*
418
;* THERE ARE 3 MORE ENTRIES IN 'RUN':
419
;* 'RUNNXL' FINDS NEXT LINE, STORES ITS ADDR. AND EXECUTES IT.
420
;* 'RUNTSL' STORES THE ADDRESS OF THIS LINE AND EXECUTES IT.
421
;* 'RUNSML' CONTINUES THE EXECUTION ON SAME LINE.
422
;*
423
;* 'GOTO EXPR(CR)' EVALUATES THE EXPRESSION, FIND THE TARGET
424
;* LINE, AND JUMP TO 'RUNTSL' TO DO IT.
425
;* 'DLOAD' LOADS A NAMED PROGRAM FROM DISK.
426
;* 'DSAVE' SAVES A NAMED PROGRAM ON DISK.
427
;* 'FCBSET' SETS UP THE FILE CONTROL BLOCK FOR SUBSEQUENT DISK I/O.
428
;*
429
NEW    CALL ENDCHK    ;*** NEW(CR) ***
430
       LXI  H,TXTBGN
431
       SHLD TXTUNF
432
;*
433
STOP   CALL ENDCHK    ;*** STOP(CR) ***
434
       JMP RSTART
435
;*
436
RUN    CALL ENDCHK    ;*** RUN(CR) ***
437
       LXI  D,TXTBGN  ;FIRST SAVED LINE
438
;*
439
RUNNXL LXI  H,0       ;*** RUNNXL ***
440
       CALL FNDLNP    ;FIND WHATEVER LINE #
441
       JC   RSTART    ;C:PASSED TXTUNF, QUIT
442
;*
443
RUNTSL XCHG           ;*** RUNTSL ***
444
       SHLD CURRNT    ;SET 'CURRNT'->LINE #
445
       XCHG
446
       INX  D         ;BUMP PASS LINE #
447
       INX  D
448
;*
449
RUNSML CALL CHKIO     ;*** RUNSML ***
450
       LXI  H,TAB2-1  ;FIND COMMAND IN TAB2
451
       JMP  EXEC      ;AND EXECUTE IT
452
;*
453
GOTO   RST  3         ;*** GOTO EXPR ***
454
       PUSH D         ;SAVE FOR ERROR ROUTINE
455
       CALL ENDCHK    ;MUST FIND A 0DH
456
       CALL FNDLN     ;FIND THE TARGET LINE
457
       JNZ  AHOW      ;NO SUCH LINE #
458
       POP  PSW       ;CLEAR THE "PUSH DE"
459
       JMP  RUNTSL    ;GO DO IT
460
CPM    EQU  5         ;DISK PARAMETERS
461
FCB    EQU  5CH
462
SETDMA EQU  26
463
OPEN   EQU  15
464
READD  EQU  20
465
WRITED EQU  21
466
CLOSE  EQU  16
467
MAKE   EQU  22
468
DELETE EQU  19
469
;*
470
DLOAD  RST  5         ;IGNORE BLANKS
471
       PUSH H         ;SAVE H
472
       CALL FCBSET    ;SET UP FILE CONTROL BLOCK
473
       PUSH D         ;SAVE THE REST
474
       PUSH B
475
       LXI  D,FCB     ;GET FCB ADDRESS
476
       MVI  C,OPEN    ;PREPARE TO OPEN FILE
477
       CALL CPM       ;OPEN IT
478
       CPI  0FFH      ;IS IT THERE?
479
       JZ   QHOW      ;NO, SEND ERROR
480
       XRA  A         ;CLEAR A
481
       STA  FCB+32    ;START AT RECORD 0
482
       LXI  D,TXTUNF  ;GET BEGINNING
483
LOAD   PUSH D         ;SAVE DMA ADDRESS
484
       MVI  C,SETDMA  ;
485
       CALL CPM       ;SET DMA ADDRESS
486
       MVI  C,READD   ;
487
       LXI  D,FCB
488
       CALL CPM       ;READ SECTOR
489
       CPI  1         ;DONE?
490
       JC   RDMORE    ;NO, READ MORE
491
       JNZ  QHOW      ;BAD READ
492
       MVI  C,CLOSE
493
       LXI  D,FCB
494
       CALL CPM       ;CLOSE FILE
495
       POP  D         ;THROW AWAY DMA ADD.
496
       POP  B         ;GET OLD REGISTERS BACK
497
       POP  D
498
       POP  H
499
       RST  6         ;FINISH
500
RDMORE POP  D         ;GET DMA ADDRESS
501
       LXI  H,80H     ;GET 128
502
       DAD  D         ;ADD 128 TO DMA ADD.
503
       XCHG           ;PUT IT BACK IN D
504
       JMP  LOAD      ;AND READ SOME MORE
505
;*
506
DSAVE  RST  5         ;IGNORE BLANKS
507
       PUSH H         ;SAVE H
508
       CALL FCBSET    ;SETUP FCB
509
       PUSH D
510
       PUSH B         ;SAVE OTHERS
511
       LXI  D,FCB
512
       MVI  C,DELETE
513
       CALL CPM       ;ERASE FILE IF IT EXISTS
514
       LXI  D,FCB
515
       MVI  C,MAKE
516
       CALL CPM       ;MAKE A NEW ONE
517
       CPI  0FFH      ;IS THERE SPACE?
518
       JZ   QHOW      ;NO, ERROR
519
       XRA  A         ;CLEAR A
520
       STA  FCB+32    ;START AT RECORD 0
521
       LXI  D,TXTUNF  ;GET BEGINNING
522
SAVE   PUSH D         ;SAVE DMA ADDRESS
523
       MVI  C,SETDMA  ;
524
       CALL CPM       ;SET DMA ADDRESS
525
       MVI  C,WRITED
526
       LXI  D,FCB
527
       CALL CPM       ;WRITE SECTOR
528
       ORA  A         ;SET FLAGS
529
       JNZ  QHOW      ;IF NOT ZERO, ERROR
530
       POP  D         ;GET DMA ADD. BACK
531
       LDA  TXTUNF+1  ;AND MSB OF LAST ADD.
532
       CMP  D         ;IS D SMALLER?
533
       JC   SAVDON    ;YES, DONE
534
       JNZ  WRITMOR   ;DONT TEST E IF NOT EQUAL
535
       LDA  TXTUNF    ;IS E SMALLER?
536
       CMP  E
537
       JC   SAVDON    ;YES, DONE
538
WRITMOR LXI  H,80H
539
       DAD  D         ;ADD 128 TO DMA ADD.
540
       XCHG           ;GET IT BACK IN D
541
       JMP  SAVE      ;WRITE SOME MORE
542
SAVDON MVI  C,CLOSE
543
       LXI  D,FCB
544
       CALL CPM       ;CLOSE FILE
545
       POP  B         ;GET REGISTERS BACK
546
       POP  D
547
       POP  H
548
       RST  6         ;FINISH
549
;*
550
FCBSET LXI  H,FCB     ;GET FILE CONTROL BLOCK ADDRESS
551
       MVI  M,0       ;CLEAR ENTRY TYPE
552
FNCLR  INX  H         ;NEXT LOCATION
553
       MVI  M,' '     ;CLEAR TO SPACE
554
       MVI  A,FCB+8 AND 255
555
       CMP  L         ;DONE?
556
       JNZ  FNCLR     ;NO, DO IT AGAIN
557
       INX  H         ;NEXT
558
       MVI  M,'T'     ;SET FILE TYPE TO 'TBI'
559
       INX  H
560
       MVI  M,'B'
561
       INX  H
562
       MVI  M,'I'
563
EXRC   INX  H         ;CLEAR REST OF FCB
564
       MVI  M,0
565
       MVI  A,FCB+15 AND 255
566
       CMP  L         ;DONE?
567
       JNZ  EXRC      ;NO, CONTINUE
568
       LXI  H,FCB+1   ;GET FILENAME START
569
FN     LDAX D         ;GET CHARACTER
570
       CPI  0DH       ;IS IT A 'CR'
571
       RZ             ;YES, DONE
572
       CPI  '!'       ;LEGAL CHARACTER?
573
       JC   QWHAT     ;NO, SEND ERROR
574
       CPI  '['       ;AGAIN
575
       JNC  QWHAT     ;DITTO
576
       MOV  M,A        ;SAVE IT IN FCB
577
       INX  H         ;NEXT
578
       INX  D
579
       MVI  A,FCB+9 AND 255
580
       CMP  L         ;LAST?
581
       JNZ  FN        ;NO, CONTINUE
582
       RET            ;TRUNCATE AT 8 CHARACTERS
583
;*
584
;*************************************************************
585
;*
586
;* *** LIST *** & PRINT ***
587
;*
588
;* LIST HAS TWO FORMS:
589
;* 'LIST(CR)' LISTS ALL SAVED LINES
590
;* 'LIST #(CR)' START LIST AT THIS LINE #
591
;* YOU CAN STOP THE LISTING BY CONTROL C KEY
592
;*
593
;* PRINT COMMAND IS 'PRINT ....;' OR 'PRINT ....(CR)'
594
;* WHERE '....' IS A LIST OF EXPRESIONS, FORMATS, BACK-
595
;* ARROWS, AND STRINGS.  THESE ITEMS ARE SEPERATED BY COMMAS.
596
;*
597
;* A FORMAT IS A POUND SIGN FOLLOWED BY A NUMBER.  IT CONTROLSs
598
;* THE NUMBER OF SPACES THE VALUE OF A EXPRESION IS GOING TO
599
;* BE PRINTED.  IT STAYS EFFECTIVE FOR THE REST OF THE PRINT
600
;* COMMAND UNLESS CHANGED BY ANOTHER FORMAT.  IFF NO FORMAT IS
601
;* SPECIFIED, 6 POSITIONS WILL BE USED.
602
;*
603
;* A STRING IS QUOTED IN A PAIR OF SINGLE QUOTES OR A PAIR OF
604
;* DOUBLE QUOTES.
605
;*
606
;* A BACK-ARROW MEANS GENERATE A (CR) WITHOUT (LF)
607
;*
608
;* A (CRLF) IS GENERATED AFTER THE ENTIRE LIST HAS BEEN
609
;* PRINTED OR IFF THE LIST IS A NULL LIST.  HOWEVER IFF THE LIST
610
;* ENDED WITH A COMMA, NO (CRL) IS GENERATED.
611
;*
612
LIST   CALL TSTNUM    ;TEST IFF THERE IS A #
613
       CALL ENDCHK    ;IFF NO # WE GET A 0
614
       CALL FNDLN     ;FIND THIS OR NEXT LINE
615
LS1    JC   RSTART    ;C:PASSED TXTUNF
616
       CALL PRTLN     ;PRINT THE LINE
617
       CALL CHKIO     ;STOP IFF HIT CONTROL-C
618
       CALL FNDLNP    ;FIND NEXT LINE
619
       JMP  LS1       ;AND LOOP BACK
620
;*
621
PRINT  MVI  C,6       ;C = # OF SPACES
622
       RST  1         ;IFF NULL LIST & ";"
623
       DB   73Q
624
       DB   6Q
625
       CALL CRLF      ;GIVE CR-LF AND
626
       JMP  RUNSML    ;CONTINUE SAME LINE
627
PR2    RST  1         ;IFF NULL LIST (CR)
628
       DB   0DH
629
       DB   6Q
630
       CALL CRLF      ;ALSO GIVE CR-LF AND
631
       JMP  RUNNXL    ;GO TO NEXT LINE
632
PR0    RST  1         ;ELSE IS IT FORMAT?
633
       DB   '#'
634
       DB   5Q
635
       RST  3         ;YES, EVALUATE EXPR.
636
       MOV  C,L       ;AND SAVE IT IN C
637
       JMP  PR3       ;LOOK FOR MORE TO PRINT
638
PR1    CALL QTSTG     ;OR IS IT A STRING?
639
       JMP  PR8       ;IFF NOT, MUST BE EXPR.
640
PR3    RST  1         ;IFF ",", GO FIND NEXT
641
       DB   ','
642
       DB   6Q
643
       CALL FIN       ;IN THE LIST.
644
       JMP  PR0       ;LIST CONTINUES
645
PR6    CALL CRLF      ;LIST ENDS
646
       RST  6
647
PR8    RST  3         ;EVALUATE THE EXPR
648
       PUSH B
649
       CALL PRTNUM    ;PRINT THE VALUE
650
       POP  B
651
       JMP  PR3       ;MORE TO PRINT?
652
;*
653
;**************************************************************
654
;*
655
;* *** GOSUB *** & RETURN ***
656
;*
657
;* 'GOSUB EXPR;' OR 'GOSUB EXPR (CR)' IS LIKE THE 'GOTO'
658
;* COMMAND, EXCEPT THAT THE CURRENT TEXT POINTER, STACK POINTER
659
;* ETC. ARE SAVE SO THAT EXECUTION CAN BE CONTINUED AFTER THE
660
;* SUBROUTINE 'RETURN'.  IN ORDER THAT 'GOSUB' CAN BE NESTED
661
;* (AND EVEN RECURSIVE), THE SAVE AREA MUST BE STACKED.
662
;* THE STACK POINTER IS SAVED IN 'STKGOS'. THE OLD 'STKGOS' IS
663
;* SAVED IN THE STACK.  IFF WE ARE IN THE MAIN ROUTINE, 'STKGOS'
664
;* IS ZERO (THIS WAS DONE BY THE "MAIN" SECTION OF THE CODE),
665
;* BUT WE STILL SAVE IT AS A FLAG FORr NO FURTHER 'RETURN'S.
666
;*
667
;* 'RETURN(CR)' UNDOS EVERYHING THAT 'GOSUB' DID, AND THUS
668
;* RETURN THE EXCUTION TO THE COMMAND AFTER THE MOST RECENT
669
;* 'GOSUB'.  IFF 'STKGOS' IS ZERO, IT INDICATES THAT WE
670
;* NEVER HAD A 'GOSUB' AND IS THUS AN ERROR.
671
;*
672
GOSUB  CALL PUSHA     ;SAVE THE CURRENT "FOR"
673
       RST  3         ;PARAMETERS
674
       PUSH D         ;AND TEXT POINTER
675
       CALL FNDLN     ;FIND THE TARGET LINE
676
       JNZ  AHOW      ;NOT THERE. SAY "HOW?"
677
       LHLD CURRNT    ;FOUND IT, SAVE OLD
678
       PUSH H         ;'CURRNT' OLD 'STKGOS'
679
       LHLD STKGOS
680
       PUSH H
681
       LXI  H,0       ;AND LOAD NEW ONES
682
       SHLD LOPVAR
683
       DAD  SP
684
       SHLD STKGOS
685
       JMP  RUNTSL    ;THEN RUN THAT LINE
686
RETURN CALL ENDCHK    ;THERE MUST BE A 0DH
687
       LHLD STKGOS    ;OLD STACK POINTER
688
       MOV  A,H       ;0 MEANS NOT EXIST
689
       ORA  L
690
       JZ   QWHAT     ;SO, WE SAY: "WHAT?"
691
       SPHL           ;ELSE, RESTORE IT
692
       POP  H
693
       SHLD STKGOS    ;AND THE OLD 'STKGOS'
694
       POP  H
695
       SHLD CURRNT    ;AND THE OLD 'CURRNT'
696
       POP  D         ;OLD TEXT POINTER
697
       CALL POPA      ;OLD "FOR" PARAMETERS
698
       RST  6         ;AND WE ARE BACK HOME
699
;*
700
;**************************************************************
701
;*
702
;* *** FOR *** & NEXT ***
703
;*
704
;* 'FOR' HAS TWO FORMS:
705
;* 'FOR VAR=EXP1 TO EXP2 STEP EXP1' AND 'FOR VAR=EXP1 TO EXP2'
706
;* THE SECOND FORM MEANS THE SAME THING AS THE FIRST FORM WITH
707
;* EXP1=1.  (I.E., WITH A STEP OF +1.)
708
;* TBI WILL FIND THE VARIABLE VAR. AND SET ITS VALUE TO THE
709
;* CURRENT VALUE OF EXP1.  IT ALSO EVALUATES EXPR2 AND EXP1
710
;* AND SAVE ALL THESE TOGETHER WITH THE TEXT POINTERr ETC. IN
711
;* THE 'FOR' SAVE AREA, WHICH CONSISTS OF 'LOPVAR', 'LOPINC',
712
;* 'LOPLMT', 'LOPLN', AND 'LOPPT'.  IFF THERE IS ALREADY SOME-
713
;* THING IN THE SAVE AREA (THIS IS INDICATED BY A NON-ZERO
714
;* 'LOPVAR'), THEN THE OLD SAVE AREA IS SAVED IN THE STACK
715
;* BEFORE THE NEW ONE OVERWRITES IT.
716
;* TBI WILL THEN DIG IN THE STACK AND FIND OUT IFF THIS SAME
717
;* VARIABLE WAS USED IN ANOTHER CURRENTLY ACTIVE 'FOR' LOOP.
718
;* IFF THAT IS THE CASE THEN THE OLD 'FOR' LOOP IS DEACTIVATED.
719
;* (PURGED FROM THE STACK..)
720
;*
721
;* 'NEXT VAR' SERVES AS THE LOGICAL (NOT NECESSARILLY PHYSICAL)
722
;* END OF THE 'FOR' LOOP.  THE CONTROL VARIABLE VAR. IS CHECKED
723
;* WITH THE 'LOPVAR'.  IFF THEY ARE NOT THE SAME, TBI DIGS IN
724
;* THE STACK TO FIND THE RIGHTt ONE AND PURGES ALL THOSE THAT
725
;* DID NOT MATCH.  EITHER WAY, TBI THEN ADDS THE 'STEP' TO
726
;* THAT VARIABLE AND CHECK THE RESULT WITH THE LIMIT.  IFF IT
727
;* IS WITHIN THE LIMIT, CONTROL LOOPS BACK TO THE COMMAND
728
;* FOLLOWING THE 'FOR'.  IFF OUTSIDE THE LIMIT, THE SAVE ARER
729
;* IS PURGED AND EXECUTION CONTINUES.
730
;*
731
FOR    CALL PUSHA     ;SAVE THE OLD SAVE AREA
732
       CALL SETVAL    ;SET THE CONTROL VAR.
733
       DCX  H         ;HL IS ITS ADDRESS
734
       SHLD LOPVAR    ;SAVE THAT
735
       LXI  H,TAB5-1  ;USE 'EXEC' TO LOOK
736
       JMP  EXEC      ;FOR THE WORD 'TO'
737
FR1    RST  3         ;EVALUATE THE LIMIT
738
       SHLD LOPLMT    ;SAVE THAT
739
       LXI  H,TAB6-1  ;USE 'EXEC' TO LOOK
740
       JMP  EXEC      ;FOR THE WORD 'STEP'
741
FR2    RST  3         ;FOUND IT, GET STEP
742
       JMP  FR4
743
FR3    LXI  H,1Q      ;NOT FOUND, SET TO 1
744
FR4    SHLD LOPINC    ;SAVE THAT TOO
745
FR5    LHLD CURRNT    ;SAVE CURRENT LINE #
746
       SHLD LOPLN
747
       XCHG           ;AND TEXT POINTER
748
       SHLD LOPPT
749
       LXI  B,12Q     ;DIG INTO STACK TO
750
       LHLD LOPVAR    ;FIND 'LOPVAR'
751
       XCHG
752
       MOV  H,B
753
       MOV  L,B       ;HL=0 NOW
754
       DAD  SP        ;HERE IS THE STACK
755
       DB   76Q
756
FR7    DAD  B         ;EACH LEVEL IS 10 DEEP
757
       MOV  A,M       ;GET THAT OLD 'LOPVAR'
758
       INX  H
759
       ORA  M
760
       JZ   FR8       ;0 SAYS NO MORE IN IT
761
       MOV  A,M
762
       DCX  H
763
       CMP  D         ;SAME AS THIS ONE?
764
       JNZ  FR7
765
       MOV  A,M       ;THE OTHER HALF?
766
       CMP  E
767
       JNZ  FR7
768
       XCHG           ;YES, FOUND ONE
769
       LXI  H,0Q
770
       DAD  SP        ;TRY TO MOVE SP
771
       MOV  B,H
772
       MOV  C,L
773
       LXI  H,12Q
774
       DAD  D
775
       CALL MVDOWN    ;AND PURGE 10 WORDS
776
       SPHL           ;IN THE STACK
777
FR8    LHLD LOPPT     ;JOB DONE, RESTORE DE
778
       XCHG
779
       RST  6         ;AND CONTINUE
780
;*
781
NEXT   RST  7         ;GET ADDRESS OF VAR.
782
       JC   QWHAT     ;NO VARIABLE, "WHAT?"
783
       SHLD VARNXT    ;YES, SAVE IT
784
NX0    PUSH D         ;SAVE TEXT POINTER
785
       XCHG
786
       LHLD LOPVAR    ;GET VAR. IN 'FOR'
787
       MOV  A,H
788
       ORA  L         ;0 SAYS NEVER HAD ONE
789
       JZ   AWHAT     ;SO WE ASK: "WHAT?"
790
       RST  4         ;ELSE WE CHECK THEM
791
       JZ   NX3       ;OK, THEY AGREE
792
       POP  D         ;NO, LET'S SEE
793
       CALL POPA      ;PURGE CURRENT LOOP
794
       LHLD VARNXT    ;AND POP ONE LEVEL
795
       JMP  NX0       ;GO CHECK AGAIN
796
NX3    MOV  E,M       ;COME HERE WHEN AGREED
797
       INX  H
798
       MOV  D,M       ;DE=VALUE OF VAR.
799
       LHLD LOPINC
800
       PUSH H
801
       DAD  D         ;ADD ONE STEP
802
       XCHG
803
       LHLD LOPVAR    ;PUT IT BACK
804
       MOV  M,E
805
       INX  H
806
       MOV  M,D
807
       LHLD LOPLMT    ;HL->LIMIT
808
       POP  PSW       ;OLD HL
809
       ORA  A
810
       JP   NX1       ;STEP > 0
811
       XCHG
812
NX1    CALL CKHLDE    ;COMPARE WITH LIMIT
813
       POP  D         ;RESTORE TEXT POINTER
814
       JC   NX2       ;OUTSIDE LIMIT
815
       LHLD LOPLN     ;WITHIN LIMIT, GO
816
       SHLD CURRNT    ;BACK TO THE SAVED
817
       LHLD LOPPT     ;'CURRNT' AND TEXT
818
       XCHG           ;POINTER
819
       RST  6
820
NX2    CALL POPA      ;PURGE THIS LOOP
821
       RST  6
822
;*
823
;**************************************************************
824
;*
825
;* *** REM *** IFF *** INPUT *** & LET (& DEFLT) ***
826
;*
827
;* 'REM' CAN BE FOLLOWED BY ANYTHING AND IS IGNORED BY TBI.
828
;* TBI TREATS IT LIKE AN 'IF' WITH A FALSE CONDITION.
829
;*
830
;* 'IF' IS FOLLOWED BY AN EXPR. AS A CONDITION AND ONE OR MORE
831
;* COMMANDS (INCLUDING OUTHER 'IF'S) SEPERATED BY SEMI-COLONS.
832
;* NOTE THAT THE WORD 'THEN' IS NOT USED.  TBI EVALUATES THE
833
;* EXPR. IFF IT IS NON-ZERO, EXECUTION CONTINUES.  IFF THE
834
;* EXPR. IS ZERO, THE COMMANDS THAT FOLLOWS ARE IGNORED AND
835
;* EXECUTION CONTINUES AT THE NEXT LINE.
836
;*
837
;* 'IPUT' COMMAND IS LIKE THE 'PRINT' COMMAND, AND IS FOLLOWED
838
;* BY A LIST OF ITEMS.  IFF THE ITEM IS A STRING IN SINGLE OR
839
;* DOUBLE QUOTES, OR IS A BACK-ARROW, IT HAS THE SAME EFFECT AS
840
;* IN 'PRINT'.  IFF AN ITEM IS A VARIABLE, THIS VARIABLE NAME IS
841
;* PRINTED OUT FOLLOWED BY A COLON.  THEN TBI WAITS FOR AN
842
;* EXPR. TO BE TYPED IN.  THE VARIABLE ISs THEN SET TO THE
843
;* VALUE OF THIS EXPR.  IFF THE VARIABLE IS PROCEDED BY A STRING
844
;* (AGAIN IN SINGLE OR DOUBLE QUOTES), THE STRING WILL BE
845
;* PRINTED FOLLOWED BY A COLON.  TBI THEN WAITS FOR INPUT EXPR.
846
;* AND SET THE VARIABLE TO THE VALUE OF THE EXPR.
847
;*
848
;* IFF THE INPUT EXPR. IS INVALID, TBI WILL PRINT "WHAT?",
849
;* "HOW?" OR "SORRY" AND REPRINT THE PROMPT AND REDO THE INPUT.
850
;* THE EXECUTION WILL NOT TERMINATE UNLESS YOU TYPE CONTROL-C.
851
;* THIS IS HANDLED IN 'INPERR'.
852
;*
853
;* 'LET' IS FOLLOWED BY A LIST OF ITEMS SEPERATED BY COMMAS.
854
;* EACH ITEM CONSISTS OF A VARIABLE, AN EQUAL SIGN, AND AN EXPR.
855
;* TBI EVALUATES THE EXPR. AND SET THE VARIBLE TO THAT VALUE.
856
;* TB WILL ALSO HANDLE 'LET' COMMAND WITHOUT THE WORD 'LET'.
857
;* THIS IS DONE BY 'DEFLT'.
858
;*
859
REM    LXI  H,0Q      ;*** REM ***
860
       DB   76Q
861
;*
862
IFF     RST  3         ;*** IFF ***
863
       MOV  A,H       ;IS THE EXPR.=0?
864
       ORA  L
865
       JNZ  RUNSML    ;NO, CONTINUE
866
       CALL FNDSKP    ;YES, SKIP REST OF LINE
867
       JNC  RUNTSL
868
       JMP  RSTART
869
;*
870
INPERR LHLD STKINP    ;*** INPERR ***
871
       SPHL           ;RESTORE OLD SP
872
       POP  H         ;AND OLD 'CURRNT'
873
       SHLD CURRNT
874
       POP  D         ;AND OLD TEXT POINTER
875
       POP  D         ;REDO INPUT
876
;*
877
INPUT  EQU  $         ;*** INPUT ***
878
IP1    PUSH D         ;SAVE IN CASE OF ERROR
879
       CALL QTSTG     ;IS NEXT ITEM A STRING?
880
       JMP  IP2       ;NO
881
       RST  7         ;YES. BUT FOLLOWED BY A
882
       JC   IP4       ;VARIABLE?   NO.
883
       JMP  IP3       ;YES.  INPUT VARIABLE
884
IP2    PUSH D         ;SAVE FOR 'PRTSTG'
885
       RST  7         ;MUST BE VARIABLE NOW
886
       JC   QWHAT     ;"WHAT?" IT IS NOT?
887
       LDAX D         ;GET READY FOR 'RTSTG'
888
       MOV  C,A
889
       SUB  A
890
       STAX D
891
       POP  D
892
       CALL PRTSTG    ;PRINT STRING AS PROMPT
893
       MOV  A,C       ;RESTORE TEXT
894
       DCX  D
895
       STAX D
896
IP3    PUSH D         ;SAVE IN CASE OF ERROR
897
       XCHG
898
       LHLD CURRNT    ;ALSO SAVE 'CURRNT'
899
       PUSH H
900
       LXI  H,IP1     ;A NEGATIVE NUMBER
901
       SHLD CURRNT    ;AS A FLAG
902
       LXI  H,0Q      ;SAVE SP TOO
903
       DAD  SP
904
       SHLD STKINP
905
       PUSH D         ;OLD HL
906
       MVI  A,72Q     ;PRINT THIS TOO
907
       CALL GETLN     ;AND GET A LINE
908
IP3A   LXI  D,BUFFER  ;POINTS TO BUFFER
909
       RST  3         ;EVALUATE INPUT
910
       NOP            ;CAN BE 'CALL ENDCHK'
911
       NOP
912
       NOP
913
       POP  D         ;OK, GET OLD HL
914
       XCHG
915
       MOV  M,E       ;SAVE VALUE IN VAR.
916
       INX  H
917
       MOV  M,D
918
       POP  H         ;GET OLD 'CURRNT'
919
       SHLD CURRNT
920
       POP  D         ;AND OLD TEXT POINTER
921
IP4    POP  PSW       ;PURGE JUNK IN STACK
922
       RST  1         ;IS NEXT CH. ','?
923
       DB   ','
924
       DB   3Q
925
       JMP  IP1       ;YES, MORE ITEMS.
926
IP5    RST  6
927
;*
928
DEFLT  LDAX D         ;*** DEFLT ***
929
       CPI  0DH       ;EMPTY LINE IS OK
930
       JZ   LT1       ;ELSE IT IS 'LET'
931
;*
932
LET    CALL SETVAL    ;*** LET ***
933
       RST  1         ;SET VALUE TO VAR.
934
       DB   ','
935
       DB   3Q
936
       JMP  LET       ;ITEM BY ITEM
937
LT1    RST  6         ;UNTIL FINISH
938
;*
939
;**************************************************************
940
;*
941
;* *** EXPR ***
942
;*
943
;* 'EXPR' EVALUATES ARITHMETICAL OR LOGICAL EXPRESSIONS.
944
;* ::=
945
;*          
946
;* WHERE  IS ONE OF THE OPERATORSs IN TAB8 AND THE
947
;* RESULT OF THESE OPERATIONS IS 1 IFF TRUE AND 0 IFF FALSE.
948
;* ::=(+ OR -)(+ OR -)(....)
949
;* WHERE () ARE OPTIONAL AND (....) ARE OPTIONAL REPEATS.
950
;* ::=(<* OR />)(....)
951
;* ::=
952
;*           
953
;*           ()
954
;*  IS RECURSIVE SO THAT VARIABLE '@' CAN HAVE AN 
955
;* AS INDEX, FNCTIONS CAN HAVE AN  AS ARGUMENTS, AND
956
;*  CAN BE AN  IN PARANTHESE.
957
;*
958
;*                 EXPR   CALL EXPR2     THIS IS AT LOC. 18
959
;*                        PUSH HL        SAVE  VALUE
960
EXPR1  LXI  H,TAB8-1  ;LOOKUP REL.OP.
961
       JMP  EXEC      ;GO DO IT
962
XP11   CALL XP18      ;REL.OP.">="
963
       RC             ;NO, RETURN HL=0
964
       MOV  L,A       ;YES, RETURN HL=1
965
       RET
966
XP12   CALL XP18      ;REL.OP."#"
967
       RZ             ;FALSE, RETURN HL=0
968
       MOV  L,A       ;TRUE, RETURN HL=1
969
       RET
970
XP13   CALL XP18      ;REL.OP.">"
971
       RZ             ;FALSE
972
       RC             ;ALSO FALSE, HL=0
973
       MOV  L,A       ;TRUE, HL=1
974
       RET
975
XP14   CALL XP18      ;REL.OP."<="
976
       MOV  L,A       ;SET HL=1
977
       RZ             ;REL. TRUE, RETURN
978
       RC
979
       MOV  L,H       ;ELSE SET HL=0
980
       RET
981
XP15   CALL XP18      ;REL.OP."="
982
       RNZ            ;FALSE, RETRUN HL=0
983
       MOV  L,A       ;ELSE SET HL=1
984
       RET
985
XP16   CALL XP18      ;REL.OP."<"
986
       RNC            ;FALSE, RETURN HL=0
987
       MOV  L,A       ;ELSE SET HL=1
988
       RET
989
XP17   POP  H         ;NOT REL.OP.
990
       RET            ;RETURN HL=
991
XP18   MOV  A,C       ;SUBROUTINE FOR ALL
992
       POP  H         ;REL.OP.'S
993
       POP  B
994
       PUSH H         ;REVERSE TOP OF STACK
995
       PUSH B
996
       MOV  C,A
997
       CALL EXPR2     ;GET 2ND 
998
       XCHG           ;VALUE IN DE NOW
999
       XTHL           ;1ST  IN HL
1000
       CALL CKHLDE    ;COMPARE 1ST WITH 2ND
1001
       POP  D         ;RESTORE TEXT POINTER
1002
       LXI  H,0Q      ;SET HL=0, A=1
1003
       MVI  A,1
1004
       RET
1005
;*
1006
EXPR2  RST  1         ;NEGATIVE SIGN?
1007
       DB   '-'
1008
       DB   6Q
1009
       LXI  H,0Q      ;YES, FAKE '0-'
1010
       JMP  XP26      ;TREAT LIKE SUBTRACT
1011
XP21   RST  1         ;POSITIVE SIGN?  IGNORE
1012
       DB   '+'
1013
       DB   0Q
1014
XP22   CALL EXPR3     ;1ST 
1015
XP23   RST  1         ;ADD?
1016
       DB   '+'
1017
       DB   25Q
1018
       PUSH H         ;YES, SAVE VALUE
1019
       CALL EXPR3     ;GET 2ND
1020
XP24   XCHG           ;2ND IN DE
1021
       XTHL           ;1ST IN HL
1022
       MOV  A,H       ;COMPARE SIGN
1023
       XRA  D
1024
       MOV  A,D
1025
       DAD  D
1026
       POP  D         ;RESTORE TEXT POINTER
1027
       JM   XP23      ;1ST 2ND SIGN DIFFER
1028
       XRA  H         ;1ST 2ND SIGN EQUAL
1029
       JP   XP23      ;SO ISp RESULT
1030
       JMP  QHOW      ;ELSE WE HAVE OVERFLOW
1031
XP25   RST  1         ;SUBTRACT?
1032
       DB   '-'
1033
       DB   203Q
1034
XP26   PUSH H         ;YES, SAVE 1ST 
1035
       CALL EXPR3     ;GET 2ND 
1036
       CALL CHGSGN    ;NEGATE
1037
       JMP  XP24      ;AND ADD THEM
1038
;*
1039
EXPR3  CALL EXPR4     ;GET 1ST 
1040
XP31   RST  1         ;MULTIPLY?
1041
       DB   '*'
1042
       DB   54Q
1043
       PUSH H         ;YES, SAVE 1ST
1044
       CALL EXPR4     ;AND GET 2ND 
1045
       MVI  B,0Q      ;CLEAR B FOR SIGN
1046
       CALL CHKSGN    ;CHECK SIGN
1047
       XCHG           ;2ND IN DE NOW
1048
       XTHL           ;1ST IN HL
1049
       CALL CHKSGN    ;CHECK SIGN OF 1ST
1050
       MOV  A,H       ;IS HL > 255 ?
1051
       ORA  A
1052
       JZ   XP32      ;NO
1053
       MOV  A,D       ;YES, HOW ABOUT DE
1054
       ORA  D
1055
       XCHG           ;PUT SMALLER IN HL
1056
       JNZ  AHOW      ;ALSO >, WILL OVERFLOW
1057
XP32   MOV  A,L       ;THIS IS DUMB
1058
       LXI  H,0Q      ;CLEAR RESULT
1059
       ORA  A         ;ADD AND COUNT
1060
       JZ   XP35
1061
XP33   DAD  D
1062
       JC   AHOW      ;OVERFLOW
1063
       DCR  A
1064
       JNZ  XP33
1065
       JMP  XP35      ;FINISHED
1066
XP34   RST  1         ;DIVIDE?
1067
       DB   '/'
1068
       DB   104Q
1069
       PUSH H         ;YES, SAVE 1ST 
1070
       CALL EXPR4     ;AND GET 2ND ONE
1071
       MVI  B,0Q      ;CLEAR B FOR SIGN
1072
       CALL CHKSGN    ;CHECK SIGN OF 2ND
1073
       XCHG           ;PUT 2ND IN DE
1074
       XTHL           ;GET 1ST IN HL
1075
       CALL CHKSGN    ;CHECK SIGN OF 1ST
1076
       MOV  A,D       ;DIVIDE BY 0?
1077
       ORA  E
1078
       JZ   AHOW      ;SAY "HOW?"
1079
       PUSH B         ;ELSE SAVE SIGN
1080
       CALL DIVIDE    ;USE SUBROUTINE
1081
       MOV  H,B       ;RESULT IN HL NOW
1082
       MOV  L,C
1083
       POP  B         ;GET SIGN BACK
1084
XP35   POP  D         ;AND TEXT POINTER
1085
       MOV  A,H       ;HL MUST BE +
1086
       ORA  A
1087
       JM   QHOW      ;ELSE IT IS OVERFLOW
1088
       MOV  A,B
1089
       ORA  A
1090
       CM   CHGSGN    ;CHANGE SIGN IFF NEEDED
1091
       JMP  XP31      ;LOOK OR MORE TERMS
1092
;*
1093
EXPR4  LXI  H,TAB4-1  ;FIND FUNCTION IN TAB4
1094
       JMP  EXEC      ;AND GO DO IT
1095
XP40   RST  7         ;NO, NOT A FUNCTION
1096
       JC   XP41      ;NOR A VARIABLE
1097
       MOV  A,M       ;VARIABLE
1098
       INX  H
1099
       MOV  H,M       ;VALUE IN HL
1100
       MOV  L,A
1101
       RET
1102
XP41   CALL TSTNUM    ;OR IS IT A NUMBER
1103
       MOV  A,B       ;# OF DIGIT
1104
       ORA  A
1105
       RNZ            ;OK
1106
PARN   RST  1         ;NO DIGIT, MUST BE
1107
       DB   '('
1108
       DB   5Q
1109
       RST  3         ;"(EXPR)"
1110
       RST  1
1111
       DB   ')'
1112
       DB   1Q
1113
XP42   RET
1114
XP43   JMP  QWHAT     ;ELSE SAY: "WHAT?"
1115
;*
1116
RND    CALL PARN      ;*** RND(EXPR) ***
1117
       MOV  A,H       ;EXPR MUST BE +
1118
       ORA  A
1119
       JM   QHOW
1120
       ORA  L         ;AND NON-ZERO
1121
       JZ   QHOW
1122
       PUSH D         ;SAVE BOTH
1123
       PUSH H
1124
       LHLD RANPNT    ;GET MEMORY AS RANDOM
1125
       LXI  D,LSTROM  ;NUMBER
1126
       RST  4
1127
       JC   RA1       ;WRAP AROUND IFF LAST
1128
       LXI  H,START
1129
RA1    MOV  E,M
1130
       INX  H
1131
       MOV  D,M
1132
       SHLD RANPNT
1133
       POP  H
1134
       XCHG
1135
       PUSH B
1136
       CALL DIVIDE    ;RND(N)=MOD(M,N)+1
1137
       POP  B
1138
       POP  D
1139
       INX  H
1140
       RET
1141
;*
1142
ABS    CALL PARN      ;*** ABS(EXPR) ***
1143
       CALL CHKSGN    ;CHECK SIGN
1144
       MOV  A,H       ;NOTE THAT -32768
1145
       ORA  H         ;CANNOT CHANGE SIGN
1146
       JM   QHOW      ;SO SAY: "HOW?"
1147
       RET
1148
SIZE   LHLD TXTUNF    ;*** SIZE ***
1149
       PUSH D         ;GET THE NUMBER OF FREE
1150
       XCHG           ;BYTES BETWEEN 'TXTUNF'
1151
SIZEA  LXI  H,VARBGN  ;AND 'VARBGN'
1152
       CALL SUBDE
1153
       POP  D
1154
       RET
1155
;*
1156
;*********************************************************
1157
;*
1158
;*   *** OUT *** INP *** WAIT *** POKE *** PEEK *** & USR
1159
;*
1160
;*  OUT I,J(,K,L)
1161
;*
1162
;*  OUTPUTS EXPRESSION 'J' TO PORT 'I', AND MAY BE REPEATED
1163
;*  AS IN DATA 'L' TO PORT 'K' AS MANY TIMES AS NEEDED
1164
;*  THIS COMMAND MODIFIES ;*  THIS COMMAND MODIFIES
1165
;*  THIS COMMAND MODIFY'S A SMALL SECTION OF CODE LOCATED
1166
;*  JUST ABOVE ADDRESS 2K
1167
;*
1168
;*  INP (I)
1169
;*
1170
;*  THIS FUNCTION RETURNS DATA READ FROM INPUT PORT 'I' AS
1171
;*  IT'S VALUE.
1172
;*  IT ALSO MODIFIES CODE JUST ABOVE 2K.
1173
;*
1174
;*  WAIT I,J,K
1175
;*
1176
;*  THIS COMMAND READS THE STATUS OF PORT 'I', EXCLUSIVE OR'S
1177
;*  THE RESULT WITH 'K' IF THERE IS ONE, OR IF NOT WITH 0,
1178
;*  AND'S WITH 'J' AND RETURNS WHEN THE RESULT IS NONZERO.
1179
;*  ITS MODIFIED CODE IS ALSO ABOVE 2K.
1180
;*
1181
;*  POKE I,J(,K,L)
1182
;*
1183
;*  THIS COMMAND WORKS LIKE OUT EXCEPT THAT IT PUTS DATA 'J'
1184
;*  INTO MEMORY LOCATION 'I'.
1185
;*
1186
;*  PEEK (I)
1187
;*
1188
;*  THIS FUNCTION WORKS LIKE INP EXCEPT IT GETS IT'S VALUE
1189
;*  FROM MEMORY LOCATION 'I'.
1190
;*
1191
;*  USR (I(,J))
1192
;*
1193
;*  USR CALLS A MACHINE LANGUAGE SUBROUTINE AT LOCATION 'I'
1194
;*  IF THE OPTIONAL PARAMETER 'J' IS USED ITS VALUE IS PASSED
1195
;*  IN H&L.  THE VALUE OF THE FUNCTION SHOULD BE RETURNED IN H&L.
1196
;*
1197
;************************************************************
1198
;*
1199
OUTCMD RST  3
1200
       MOV  A,L
1201
       STA  OUTIO + 1
1202
       RST  1
1203
       DB   ','
1204
       DB   2FH
1205
       RST  3
1206
       MOV  A,L
1207
       CALL OUTIO
1208
       RST  1
1209
       DB   ','
1210
       DB   03H
1211
       JMP  OUTCMD
1212
       RST  6
1213
WAITCM RST  3
1214
       MOV  A,L
1215
       STA  WAITIO + 1
1216
       RST  1
1217
       DB   ','
1218
       DB   1BH
1219
       RST  3
1220
       PUSH H
1221
       RST  1
1222
       DB   ','
1223
       DB   7H
1224
       RST  3
1225
       MOV  A,L
1226
       POP  H
1227
       MOV  H,A
1228
       JMP  $ + 2
1229
       MVI  H,0
1230
       JMP  WAITIO
1231
INP    CALL PARN
1232
       MOV  A,L
1233
       STA  INPIO + 1
1234
       MVI  H,0
1235
       JMP  INPIO
1236
       JMP  QWHAT
1237
POKE   RST  3
1238
       PUSH H
1239
       RST  1
1240
       DB   ','
1241
       DB   12H
1242
       RST  3
1243
       MOV  A,L
1244
       POP  H
1245
       MOV  M,A
1246
       RST  1
1247
       DB   ',',03H
1248
       JMP  POKE
1249
       RST 6
1250
PEEK   CALL PARN
1251
       MOV  L,M
1252
       MVI  H,0
1253
       RET
1254
       JMP  QWHAT
1255
USR    PUSH B
1256
       RST  1
1257
       DB   '(',28D    ;QWHAT
1258
       RST  3          ;EXPR
1259
       RST  1
1260
       DB   ')',7      ;PASPARM
1261
       PUSH D
1262
       LXI  D,USRET
1263
       PUSH D
1264
       PUSH H
1265
       RET             ;CALL USR ROUTINE
1266
PASPRM RST  1
1267
       DB   ',',14D
1268
       PUSH H
1269
       RST  3
1270
       RST  1
1271
       DB   ')',9
1272
       POP  B
1273
       PUSH D
1274
       LXI  D,USRET
1275
       PUSH D
1276
       PUSH B
1277
       RET             ;CALL USR ROUTINE
1278
USRET  POP  D
1279
       POP  B
1280
       RET
1281
       JMP  QWHAT
1282
;*
1283
;**************************************************************
1284
;*
1285
;* *** DIVIDE *** SUBDE *** CHKSGN *** CHGSGN *** & CKHLDE ***
1286
;*
1287
;* 'DIVIDE' DIVIDES HL BY DE, RESULT IN BC, REMAINDER IN HL
1288
;*
1289
;* 'SUBDE' SUBTRACTS DE FROM HL
1290
;*
1291
;* 'CHKSGN' CHECKS SIGN OF HL.  IFF +, NO CHANGE.  IFF -, CHANGE
1292
;* SIGN AND FLIP SIGN OF B.
1293
;*
1294
;* 'CHGSGN' CHNGES SIGN OF HL AND B UNCONDITIONALLY.
1295
;*
1296
;* 'CKHLE' CHECKS SIGN OF HL AND DE.  IFF DIFFERENT, HL AND DE
1297
;* ARE INTERCHANGED.  IFF SAME SIGN, NOT INTERCHANGED.  EITHER
1298
;* CASE, HL DE ARE THEN COMPARED TO SET THE FLAGS.
1299
;*
1300
DIVIDE PUSH H         ;*** DIVIDE ***
1301
       MOV  L,H       ;DIVIDE H BY DE
1302
       MVI  H,0
1303
       CALL DV1
1304
       MOV  B,C       ;SAVE RESULT IN B
1305
       MOV  A,L       ;(REMAINDER+L)/DE
1306
       POP  H
1307
       MOV  H,A
1308
DV1    MVI  C,377Q    ;RESULT IN C
1309
DV2    INR  C         ;DUMB ROUTINE
1310
       CALL SUBDE     ;DIVIDE BY SUBTRACT
1311
       JNC  DV2       ;AND COUNT
1312
       DAD  D
1313
       RET
1314
;*
1315
SUBDE  MOV  A,L       ;*** SUBDE ***
1316
       SUB  E         ;SUBTRACT DE FROM
1317
       MOV  L,A       ;HL
1318
       MOV  A,H
1319
       SBB  D
1320
       MOV  H,A
1321
       RET
1322
;*
1323
CHKSGN MOV  A,H       ;*** CHKSGN ***
1324
       ORA  A         ;CHECK SIGN OF HL
1325
       RP             ;IFF -, CHANGE SIGN
1326
;*
1327
CHGSGN MOV  A,H       ;*** CHGSGN ***
1328
       CMA            ;CHANGE SIGN OF HL
1329
       MOV  H,A
1330
       MOV  A,L
1331
       CMA
1332
       MOV  L,A
1333
       INX  H
1334
       MOV  A,B       ;AND ALSO FLIP B
1335
       XRI  200Q
1336
       MOV  B,A
1337
       RET
1338
;*
1339
CKHLDE MOV  A,H
1340
       XRA  D         ;SAME SIGN?
1341
       JP   CK1       ;YES, COMPARE
1342
       XCHG           ;NO, XCH AND COMP
1343
CK1    RST  4
1344
       RET
1345
;*
1346
;**************************************************************
1347
;*
1348
;* *** SETVAL *** FIN *** ENDCHK *** & ERROR (& FRIENDS) ***
1349
;*
1350
;* "SETVAL" EXPECTS A VARIABLE, FOLLOWED BY AN EQUAL SIGN AND
1351
;* THEN AN EXPR.  IT EVALUATES THE EXPR. AND SET THE VARIABLE
1352
;* TO THAT VALUE.
1353
;*
1354
;* "FIN" CHECKS THE END OF A COMMAND.  IFF IT ENDED WITH ";",
1355
;* EXECUTION CONTINUES.  IFF IT ENDED WITH A CR, IT FINDS THE
1356
;* NEXT LINE AND CONTINUE FROM THERE.
1357
;*
1358
;* "ENDCHK" CHECKS IFF A COMMAND IS ENDED WITH CR.  THIS IS
1359
;* REQUIRED IN CERTAIN COMMANDS. (GOTO, RETURN, AND STOP ETC.)
1360
;*
1361
;* "ERROR" PRINTS THE STRING POINTED BY DE (AND ENDS WITH CR).
1362
;* IT THEN PRINTS THE LINE POINTED BY 'CURRNT' WITH A "?"
1363
;* INSERTED AT WHERE THE OLD TEXT POINTER (SHOULD BE ON TOP
1364
;* O THE STACK) POINTS TO.  EXECUTION OF TB IS STOPPED
1365
;* AND TBI IS RESTARTED.  HOWEVER, IFF 'CURRNT' -> ZERO
1366
;* (INDICATING A DIRECT COMMAND), THE DIRECT COMMAND IS NOT
1367
;*  PRINTED.  AND IFF 'CURRNT' -> NEGATIVE # (INDICATING 'INPUT'
1368
;* COMMAND, THE INPUT LINE IS NOT PRINTED AND EXECUTION IS
1369
;* NOT TERMINATED BUT CONTINUED AT 'INPERR'.
1370
;*
1371
;* RELATED TO 'ERROR' ARE THE FOLLOWING:
1372
;* 'QWHAT' SAVES TEXT POINTER IN STACK AND GET MESSAGE "WHAT?"
1373
;* 'AWHAT' JUST GET MESSAGE "WHAT?" AND JUMP TO 'ERROR'.
1374
;* 'QSORRY' AND 'ASORRY' DO SAME KIND OF THING.
1375
;* 'QHOW' AND 'AHOW' IN THE ZERO PAGE SECTION ALSO DO THIS
1376
;*
1377
SETVAL RST  7         ;*** SETVAL ***
1378
       JC   QWHAT     ;"WHAT?" NO VARIABLE
1379
       PUSH H         ;SAVE ADDRESS OF VAR.
1380
       RST  1         ;PASS "=" SIGN
1381
       DB   '='
1382
       DB   10Q
1383
       RST  3         ;EVALUATE EXPR.
1384
       MOV  B,H       ;VALUE IN BC NOW
1385
       MOV  C,L
1386
       POP  H         ;GET ADDRESS
1387
       MOV  M,C       ;SAVE VALUE
1388
       INX  H
1389
       MOV  M,B
1390
       RET
1391
SV1    JMP  QWHAT     ;NO "=" SIGN
1392
;*
1393
FIN    RST  1         ;*** FIN ***
1394
       DB   73Q
1395
       DB   4Q
1396
       POP  PSW       ;";", PURGE RET ADDR.
1397
       JMP  RUNSML    ;CONTINUE SAME LINE
1398
FI1    RST  1         ;NOT ";", IS IT CR?
1399
       DB   0DH
1400
       DB   4Q
1401
       POP  PSW       ;YES, PURGE RET ADDR.
1402
       JMP  RUNNXL    ;RUN NEXT LINE
1403
FI2    RET            ;ELSE RETURN TO CALLER
1404
;*
1405
ENDCHK RST  5         ;*** ENDCHK ***
1406
       CPI  0DH       ;END WITH CR?
1407
       RZ             ;OK, ELSE SAY: "WHAT?"
1408
;*
1409
QWHAT  PUSH D         ;*** QWHAT ***
1410
AWHAT  LXI  D,WHAT    ;*** AWHAT ***
1411
ERROR  SUB  A         ;*** ERROR ***
1412
       CALL PRTSTG    ;PRINT 'WHAT?', 'HOW?'
1413
       POP  D         ;OR 'SORRY'
1414
       LDAX D         ;SAVE THE CHARACTER
1415
       PUSH PSW       ;AT WHERE OLD DE ->
1416
       SUB  A         ;AND PUT A 0 THERE
1417
       STAX D
1418
       LHLD CURRNT    ;GET CURRENT LINE #
1419
       PUSH H
1420
       MOV  A,M       ;CHECK THE VALUE
1421
       INX  H
1422
       ORA  M
1423
       POP  D
1424
       JZ   RSTART    ;IFF ZERO, JUST RERSTART
1425
       MOV  A,M       ;IFF NEGATIVE,
1426
       ORA  A
1427
       JM   INPERR    ;REDO INPUT
1428
       CALL PRTLN     ;ELSE PRINT THE LINE
1429
       DCX  D         ;UPTO WHERE THE 0 IS
1430
       POP  PSW       ;RESTORE THE CHARACTER
1431
       STAX D
1432
       MVI  A,77Q     ;PRINTt A "?"
1433
       RST  2
1434
       SUB  A         ;AND THE REST OF THE
1435
       CALL PRTSTG    ;LINE
1436
       JMP  RSTART
1437
QSORRY PUSH D         ;*** QSORRY ***
1438
ASORRY LXI  D,SORRY   ;*** ASORRY ***
1439
       JMP  ERROR
1440
;*
1441
;**************************************************************
1442
;*
1443
;* *** GETLN *** FNDLN (& FRIENDS) ***
1444
;*
1445
;* 'GETLN' READS A INPUT LINE INTO 'BUFFER'.  IT FIRST PROMPT
1446
;* THE CHARACTER IN A (GIVEN BY THE CALLER), THEN IT FILLS THE
1447
;* THE BUFFER AND ECHOS.  IT IGNORES LF'S AND NULLS, BUT STILL
1448
;* ECHOS THEM BACK.  RUB-OUT IS USED TO CAUSE IT TO DELETE
1449
;* THE LAST CHARATER (IFF THERE IS ONE), AND ALT-MOD IS USED TO
1450
;* CAUSE IT TO DELETE THE WHOLE LINE AND START IT ALL OVER.
1451
;* 0DHSIGNALS THE END OF A LINE, AND CAUE 'GETLN' TO RETURN.
1452
;*
1453
;* 'FNDLN' FINDS A LINE WITH A GIVEN LINE # (IN HL) IN THE
1454
;* TEXT SAVE AREA.  DE IS USED AS THE TEXT POINTER.  IFF THE
1455
;* LINE IS FOUND, DE WILL POINT TO THE BEGINNING OF THAT LINE
1456
;* (I.E., THE LOW BYTE OF THE LINE #), AND FLAGS ARE NC & Z.
1457
;* IFF THAT LINE IS NOT THERE AND A LINE WITH A HIGHER LINE #
1458
;* IS FOUND, DE POINTS TO THERE AND FLAGS ARE NC & NZ.  IFF
1459
;* WE REACHED THE END OF TEXT SAVE ARE AND CANNOT FIND THE
1460
;* LINE, FLAGS ARE C & NZ.
1461
;* 'FNDLN' WILL INITIALIZE DE TO THE BEGINNING OF THE TEXT SAVE
1462
;* AREA TO START THE SEARCH.  SOME OTHER ENTRIES OF THIS
1463
;* ROUTINE WILL NOT INITIALIZE DE AND DO THE SEARCH.
1464
;* 'FNDLNP' WILL START WITH DE AND SEARCH FOR THE LINE #.
1465
;* 'FNDNXT' WILL BUMP DE BY 2, FIND A 0DHAND THEN START SEARCH.
1466
;* 'FNDSKP' USE DE TO FIND A CR, AND THEN STRART SEARCH.
1467
;*
1468
GETLN  RST  2         ;*** GETLN ***
1469
       LXI  D,BUFFER  ;PROMPT AND INIT
1470
GL1    CALL CHKIO     ;CHECK KEYBOARD
1471
       JZ   GL1       ;NO INPUT, WAIT
1472
       CPI  177Q      ;DELETE LST CHARACTER?
1473
       JZ   GL3       ;YES
1474
       CPI  12Q       ;IGNORE LF
1475
       JZ   GL1
1476
       ORA  A         ;IGNORE NULL
1477
       JZ   GL1
1478
       CPI  134Q      ;DELETE THE WHOLE LINE?
1479
       JZ   GL4       ;YES
1480
       STAX D         ;ELSE, SAVE INPUT
1481
       INX  D         ;AND BUMP POINTER
1482
       CPI  15Q       ;WAS IT CR?
1483
       JNZ  GL2       ;NO
1484
       MVI  A,12Q     ;YES, GET LINE FEED
1485
       RST  2         ;CALL OUTC AND LINE FEED
1486
       RET            ;WE'VE GOT A LINE
1487
GL2    MOV  A,E       ;MORE FREE ROOM?
1488
       CPI  BUFEND AND 0FFH
1489
       JNZ  GL1       ;YES, GET NEXT INPUT
1490
GL3    MOV  A,E       ;DELETE LAST CHARACTER
1491
       CPI  BUFFER AND 0FFH    ;BUT DO WE HAVE ANY?
1492
       JZ   GL4       ;NO, REDO WHOLE LINE
1493
       DCX  D         ;YES, BACKUP POINTER
1494
       MVI  A,'_'     ;AND ECHO A BACK-SPACE
1495
       RST  2
1496
       JMP  GL1       ;GO GET NEXT INPUT
1497
GL4    CALL CRLF      ;REDO ENTIRE LINE
1498
       MVI  A,136Q    ;CR, LF AND UP-ARROW
1499
       JMP  GETLN
1500
;*
1501
FNDLN  MOV  A,H       ;*** FNDLN ***
1502
       ORA  A         ;CHECK SIGN OF HL
1503
       JM   QHOW      ;IT CANNT BE -
1504
       LXI  D,TXTBGN  ;INIT. TEXT POINTER
1505
;*
1506
FNDLNP EQU  $         ;*** FNDLNP ***
1507
FL1    PUSH H         ;SAVE LINE #
1508
       LHLD TXTUNF    ;CHECK IFF WE PASSED END
1509
       DCX  H
1510
       RST  4
1511
       POP  H         ;GET LINE # BACK
1512
       RC             ;C,NZ PASSED END
1513
       LDAX D         ;WE DID NOT, GET BYTE 1
1514
       SUB  L         ;IS THIS THE LINE?
1515
       MOV  B,A       ;COMPARE LOW ORDER
1516
       INX  D
1517
       LDAX D         ;GET BYTE 2
1518
       SBB  H         ;COMPARE HIGH ORDER
1519
       JC   FL2       ;NO, NOT THERE YET
1520
       DCX  D         ;ELSE WE EITHER FOUND
1521
       ORA  B         ;IT, OR IT IS NOT THERE
1522
       RET            ;NC,Z:FOUND; NC,NZ:NO
1523
;*
1524
FNDNXT EQU  $         ;*** FNDNXT ***
1525
       INX  D         ;FIND NEXT LINE
1526
FL2    INX  D         ;JUST PASSED BYTE 1 & 2
1527
;*
1528
FNDSKP LDAX D         ;*** FNDSKP ***
1529
       CPI  0DH       ;TRY TO FIND 0DH
1530
       JNZ  FL2       ;KEEP LOOKING
1531
       INX  D         ;FOUND CR, SKIP OVER
1532
       JMP  FL1       ;CHECK IFF END OF TEXT
1533
;*
1534
;*************************************************************
1535
;*
1536
;* *** PRTSTG *** QTSTG *** PRTNUM *** & PRTLN ***
1537
;*
1538
;* 'PRTSTG' PRINTS A STRING POINTED BY DE.  IT STOPS PRINTING
1539
;* AND RETURNS TO CALÌER WHEN EITHER A 0DHIS PRINTED OR WHEN
1540
;* THE NEXT BYTE IS THE SAME AS WHAT WAS IN A (GIVEN BY THE
1541
;* CALLER).  OLD A IS STORED IN B, OLD B IS LOST.
1542
;*
1543
;* 'QTSTG' LOOKS FOR A BACK-ARROW, SINGLE QUOTE, OR DOUBLE
1544
;* QUOTE.  IFF NONE OF THESE, RETURN TO CALLER.  IFF BACK-ARROW,
1545
;* OUTPUT A 0DHWITHOUT A LF.  IFF SINGLE OR DOUBLE QUOTE, PRINT
1546
;* THE STRING IN THE QUOTE AND DEMANDS A MATCHING UNQUOTE.
1547
;* AFTER THE PRINTING THE NEXT 3 BYTES OF THE CALLER IS SKIPPED
1548
;* OVER (USUALLY A JUMP INSTRUCTION).
1549
;*
1550
;* 'PRTNUM' PRINTS THE NUMBER IN HL.  LEADING BLANKS ARE ADDED
1551
;* IFF NEEDED TO PAD THE NUMBER OF SPACES TO THE NUMBER IN C.
1552
;* HOWEVER, IFF THE NUMBER OF DIGITS IS LARGER THAN THE # IN
1553
;* C, ALL DIGITS ARE PRINTED ANYWAY.  NEGATIVE SIGN IS ALSO
1554
;* PRINTED AND COUNTED IN, POSITIVE SIGN IS NOT.
1555
;*
1556
;* 'PRTLN' PRINSrA SAVED TEXT LINE WITH LINE # AND ALL.
1557
;*
1558
PRTSTG MOV  B,A       ;*** PRTSTG ***
1559
PS1    LDAX D         ;GET A CHARACTERr
1560
       INX  D         ;BUMP POINTER
1561
       CMP  B         ;SAME AS OLD A?
1562
       RZ             ;YES, RETURN
1563
       RST  2         ;ELSE PRINT IT
1564
       CPI  0DH       ;WAS IT A CR?
1565
       JNZ  PS1       ;NO, NEXT
1566
       RET            ;YES, RETURN
1567
;*
1568
QTSTG  RST  1         ;*** QTSTG ***
1569
       DB   '"'
1570
       DB   17Q
1571
       MVI  A,42Q     ;IT IS A "
1572
QT1    CALL PRTSTG    ;PRINT UNTIL ANOTHER
1573
       CPI  0DH       ;WAS LAST ONE A CR?
1574
       POP  H         ;RETURN ADDRESS
1575
       JZ   RUNNXL    ;WAS CR, RUN NEXT LINE
1576
QT2    INX  H         ;SKIP 3 BYTES ON RETURN
1577
       INX  H
1578
       INX  H
1579
       PCHL           ;RETURN
1580
QT3    RST  1         ;IS IT A ' ?
1581
       DB   47Q
1582
       DB   5Q
1583
       MVI  A,47Q     ;YES, DO SAME
1584
       JMP  QT1       ;AS IN "
1585
QT4    RST  1         ;IS IT BACK-ARROW?
1586
       DB   137Q
1587
       DB   10Q
1588
       MVI  A,215Q    ;YES, 0DHWITHOUT LF!!
1589
       RST  2         ;DO IT TWICE TO GIVE
1590
       RST  2         ;TTY ENOUGH TIME
1591
       POP  H         ;RETURN ADDRESS
1592
       JMP  QT2
1593
QT5    RET            ;NONE OF ABOVE
1594
;*
1595
PRTNUM PUSH D         ;*** PRTNUM ***
1596
       LXI  D,12Q     ;DECIMAL
1597
       PUSH D         ;SAVE AS A FLAG
1598
       MOV  B,D       ;B=SIGN
1599
       DCR  C         ;C=SPACES
1600
       CALL CHKSGN    ;CHECK SIGN
1601
       JP   PN1       ;NO SIGN
1602
       MVI  B,55Q     ;B=SIGN
1603
       DCR  C         ;'-' TAKES SPACE
1604
PN1    PUSH B         ;SAVE SIGN & SPACE
1605
PN2    CALL DIVIDE    ;DEVIDE HL BY 10
1606
       MOV  A,B       ;RESULT 0?
1607
       ORA  C
1608
       JZ   PN3       ;YES, WE GOT ALL
1609
       XTHL           ;NO, SAVE REMAINDER
1610
       DCR  L         ;AND COUNT SPACE
1611
       PUSH H         ;HL IS OLD BC
1612
       MOV  H,B       ;MOVE RESULT TO BC
1613
       MOV  L,C
1614
       JMP  PN2       ;AND DIVIDE BY 10
1615
PN3    POP  B         ;WE GOT ALL DIGITS IN
1616
PN4    DCR  C         ;THE STACK
1617
       MOV  A,C       ;LOOK AT SPACE COUNT
1618
       ORA  A
1619
       JM   PN5       ;NO LEADING BLANKS
1620
       MVI  A,40Q     ;LEADING BLANKS
1621
       RST  2
1622
       JMP  PN4       ;MORE?
1623
PN5    MOV  A,B       ;PRINT SIGN
1624
       RST  2         ;MAYBE - OR NULL
1625
       MOV  E,L       ;LAST REMAINDER IN E
1626
PN6    MOV  A,E       ;CHECK DIGIT IN E
1627
       CPI  12Q       ;10 IS FLAG FOR NO MORE
1628
       POP  D
1629
       RZ             ;IFF SO, RETURN
1630
       ADI  60Q         ;ELSE CONVERT TO ASCII
1631
       RST  2         ;AND PRINT THE DIGIT
1632
       JMP  PN6       ;GO BACK FOR MORE
1633
;*
1634
PRTLN  LDAX D         ;*** PRTLN ***
1635
       MOV  L,A       ;LOW ORDER LINE #
1636
       INX  D
1637
       LDAX D         ;HIGH ORDER
1638
       MOV  H,A
1639
       INX  D
1640
       MVI  C,4Q      ;PRINT 4 DIGIT LINE #
1641
       CALL PRTNUM
1642
       MVI  A,40Q     ;FOLLOWED BY A BLANK
1643
       RST  2
1644
       SUB  A         ;AND THEN THE TEXT
1645
       CALL PRTSTG
1646
       RET
1647
;*
1648
;**************************************************************
1649
;*
1650
;* *** MVUP *** MVDOWN *** POPA *** & PUSHA ***
1651
;*
1652
;* 'MVUP' MOVES A BLOCK UP FROM HERE DE-> TO WHERE BC-> UNTIL
1653
;* DE = HL
1654
;*
1655
;* 'MVDOWN' MOVES A BLOCK DOWN FROM WHERE DE-> TO WHERE HL->
1656
;* UNTIL DE = BC
1657
;*
1658
;* 'POPA' RESTORES THE 'FOR' LOOP VARIABLE SAVE AREA FROM THE
1659
;* STACK
1660
;*
1661
;* 'PUSHA' STACKS THE 'FOR' LOOP VARIABLE SAVE AREA INTO THE
1662
;* STACK
1663
;*
1664
MVUP   RST  4         ;*** MVUP ***
1665
       RZ             ;DE = HL, RETURN
1666
       LDAX D         ;GET ONE BYTE
1667
       STAX B         ;MOVE IT
1668
       INX  D         ;INCREASE BOTH POINTERS
1669
       INX  B
1670
       JMP  MVUP      ;UNTIL DONE
1671
;*
1672
MVDOWN MOV  A,B       ;*** MVDOWN ***
1673
       SUB  D         ;TEST IFF DE = BC
1674
       JNZ  MD1       ;NO, GO MOVE
1675
       MOV  A,C       ;MAYBE, OTHER BYTE?
1676
       SUB  E
1677
       RZ             ;YES, RETURN
1678
MD1    DCX  D         ;ELSE MOVE A BYTE
1679
       DCX  H         ;BUT FIRST DECREASE
1680
       LDAX D         ;BOTH POINTERS AND
1681
       MOV  M,A       ;THEN DO IT
1682
       JMP  MVDOWN    ;LOOP BACK
1683
;*
1684
POPA   POP  B         ;BC = RETURN ADDR.
1685
       POP  H         ;RESTORE LOPVAR, BUT
1686
       SHLD LOPVAR    ;=0 MEANS NO MORE
1687
       MOV  A,H
1688
       ORA  L
1689
       JZ   PP1       ;YEP, GO RETURN
1690
       POP  H         ;NOP, RESTORE OTHERS
1691
       SHLD LOPINC
1692
       POP  H
1693
       SHLD LOPLMT
1694
       POP  H
1695
       SHLD LOPLN
1696
       POP  H
1697
       SHLD LOPPT
1698
PP1    PUSH B         ;BC = RETURN ADDR.
1699
       RET
1700
;*
1701
PUSHA  LXI  H,STKLMT  ;*** PUSHA ***
1702
       CALL CHGSGN
1703
       POP  B         ;BC=RETURN ADDRESS
1704
       DAD  SP        ;IS STACK NEAR THE TOP?
1705
       JNC  QSORRY    ;YES, SORRY FOR THAT.
1706
       LHLD LOPVAR    ;ELSE SAVE LOOP VAR.S
1707
       MOV  A,H       ;BUT IFF LOPVAR IS 0
1708
       ORA  L         ;THAT WILL BE ALL
1709
       JZ   PU1
1710
       LHLD LOPPT     ;ELSE, MORE TO SAVE
1711
       PUSH H
1712
       LHLD LOPLN
1713
       PUSH H
1714
       LHLD LOPLMT
1715
       PUSH H
1716
       LHLD LOPINC
1717
       PUSH H
1718
       LHLD LOPVAR
1719
PU1    PUSH H
1720
       PUSH B         ;BC = RETURN ADDR.
1721
       RET
1722
;*
1723
;**************************************************************
1724
;*
1725
;* *** OUTC *** & CHKIO ****!
1726
;* THESE ARE THE ONLY I/O ROUTINES IN TBI.
1727
;* 'OUTC' IS CONTROLLED BY A SOFTWARE SWITCH 'OCSW'.  IFF OCSW=0
1728
;* 'OUTC' WILL JUST RETURN TO THE CALLER.  IFF OCSW IS NOT 0,
1729
;* IT WILL OUTPUT THE BYTE IN A.  IFF THAT IS A CR, A LF IS ALSO
1730
;* SEND OUT.  ONLY THE FLAGS MAY BE CHANGED AT RETURN, ALL REG.
1731
;* ARE RESTORED.
1732
;*
1733
;* 'CHKIO' CHECKS THE INPUT.  IFF NO INPUT, IT WILL RETURN TO
1734
;* THE CALLER WITH THE Z FLAG SET.  IFF THERE IS INPUT, Z FLAG
1735
;* IS CLEARED AND THE INPUT BYTE IS IN A.  HOWERER, IFF THE
1736
;* INPUT IS A CONTROL-O, THE 'OCSW' SWITCH IS COMPLIMENTED, AND
1737
;* Z FLAG IS RETURNED.  IFF A CONTROL-C IS READ, 'CHKIO' WILL
1738
;* RESTART TBI AND DO NOT RETURN TO THE CALLER.
1739
;*
1740
;*                 OUTC   PUSH AF        THIS IS AT LOC. 10
1741
;*                        LD   A,OCSW    CHECK SOFTWARE SWITCH
1742
;*                        IOR  A
1743
OC2    JNZ  OC3       ;IT IS ON
1744
       POP  PSW       ;IT IS OFF
1745
       RET            ;RESTORE AF AND RETURN
1746
OC3    POP  A         ;GET OLD A BACK
1747
       PUSH B         ;SAVE B ON STACK
1748
       PUSH D         ;AND D
1749
       PUSH H         ;AND H TOO
1750
       STA  OUTCAR    ;SAVE CHARACTER
1751
       MOV  E,A       ;PUT CHAR. IN E FOR CPM
1752
       MVI  C,2       ;GET CONOUT COMMAND
1753
       CALL CPM       ;CALL CPM AND DO IT
1754
       LDA  OUTCAR    ;GET CHAR. BACK
1755
       CPI  0DH       ;WAS IT A 'CR'?
1756
       JNZ  DONE      ;NO, DONE
1757
       MVI  E,0AH     ;GET LINEFEED
1758
       MVI  C,2       ;AND CONOUT AGAIN
1759
       CALL CPM       ;CALL CPM
1760
DONE   LDA  OUTCAR    ;GET CHARACTER BACK
1761
IDONE  POP  H         ;GET H BACK
1762
       POP  D         ;AND D
1763
       POP  B         ;AND B TOO
1764
       RET            ;DONE AT LAST
1765
CHKIO  PUSH B         ;SAVE B ON STACK
1766
       PUSH D         ;AND D
1767
       PUSH H         ;THEN H
1768
       MVI  C,11      ;GET CONSTAT WORD
1769
       CALL CPM       ;CALL THE BDOS
1770
       ORA  A         ;SET FLAGS
1771
       JNZ  CI1       ;IF READY GET CHARACTER
1772
       JMP  IDONE     ;RESTORE AND RETURN
1773
CI1    MVI  C,1       ;GET CONIN WORD
1774
       CALL CPM       ;CALL THE BDOS
1775
       CPI  0FH       ;IS IT CONTROL-O?
1776
       JNZ  CI2       ;NO, MORE CHECKING
1777
       LDA  OCSW      ;CONTROL-O  FLIP OCSW
1778
       CMA            ;ON TO OFF, OFF TO ON
1779
       STA  OCSW      ;AND PUT IT BACK
1780
       JMP  CHKIO     ;AND GET ANOTHER CHARACTER
1781
CI2    CPI  3         ;IS IT CONTROL-C?
1782
       JNZ  IDONE     ;RETURN AND RESTORE IF NOT
1783
       JMP  RSTART    ;YES, RESTART TBI
1784
LSTROM EQU  $         ;ALL ABOVE CAN BE ROM
1785
OUTIO  OUT  0FFH
1786
       RET
1787
WAITIO IN   0FFH
1788
       XRA  H
1789
       ANA  L
1790
       JZ   WAITIO
1791
       RST  6
1792
INPIO  IN   0FFH
1793
       MOV  L,A
1794
       RET
1795
OUTCAR DB   0         ;OUTPUT CHAR. STORAGE
1796
OCSW   DB   0FFH      ;SWITCH FOR OUTPUT
1797
CURRNT DW   0         ;POINTS TO CURRENT LINE
1798
STKGOS DW   0         ;SAVES SP IN 'GOSUB'
1799
VARNXT DW   0         ;TEMPORARY STORAGE
1800
STKINP DW   0         ;SAVES SP IN 'INPUT'
1801
LOPVAR DW   0         ;'FOR' LOOP SAVE AREA
1802
LOPINC DW   0         ;INCREMENT
1803
LOPLMT DW   0         ;LIMIT
1804
LOPLN  DW   0         ;LINE NUMBER
1805
LOPPT  DW   0         ;TEXT POINTER
1806
RANPNT DW   START     ;RANDOM NUMBER POINTER
1807
TXTUNF DW   TXTBGN    ;->UNFILLED TEXT AREA
1808
TXTBGN DS   1         ;TEXT SAVE AREA BEGINS
1809
MSG1   DB   7FH,7FH,7FH,'SHERRY BROTHERS TINY BASIC VER. 3.1',0DH
1810
INIT   MVI  A,0FFH
1811
       STA  OCSW      ;TURN ON OUTPUT SWITCH
1812
       MVI  A,0CH     ;GET FORM FEED
1813
       RST  2         ;SEND TO CRT
1814
PATLOP SUB  A         ;CLEAR ACCUMULATOR
1815
       LXI  D,MSG1    ;GET INIT MESSAGE
1816
       CALL PRTSTG    ;SEND IT
1817
LSTRAM LDA  7         ;GET FBASE FOR TOP
1818
       STA  RSTART+2
1819
       DCR  A         ;DECREMENT FOR OTHER POINTERS
1820
       STA  SS1A+2    ;AND FIX THEM TOO
1821
       STA  TV1A+2
1822
       STA  ST3A+2
1823
       STA  ST4A+2
1824
       STA  IP3A+2
1825
       STA  SIZEA+2
1826
       STA  GETLN+3
1827
       STA  PUSHA+2
1828
       LXI  H,ST1     ;GET NEW START JUMP
1829
       SHLD START+1   ;AND FIX IT
1830
       JMP  ST1
1831
;       RESTART TABLE
1832
        ORG     0A50H
1833
RSTBL:
1834
       XTHL           ;*** TSTC OR RST 1 ***
1835
       RST  5         ;IGNORE BLANKS AND
1836
       CMP  M         ;TEST CHARACTER
1837
       JMP  TC1       ;REST OF THIS IS AT TC1
1838
;*
1839
CRLF:   EQU     0EH     ;EXECUTE TIME LOCATION OF THIS INSTRUCTION.
1840
        MVI  A,0DH     ;*** CRLF ***
1841
;*
1842
       PUSH PSW       ;*** OUTC OR RST 2 ***
1843
       LDA  OCSW      ;PRINT CHARACTER ONLY
1844
       ORA  A         ;IFF OCSW SWITCH IS ON
1845
       JMP  OC2       ;REST OF THIS IS AT OC2
1846
;*
1847
       CALL EXPR2     ;*** EXPR OR RST 3 ***
1848
       PUSH H         ;EVALUATE AN EXPRESION
1849
       JMP  EXPR1     ;REST OF IT IS AT EXPR1
1850
       DB   'W'
1851
;*
1852
       MOV  A,H       ;*** COMP OR RST 4 ***
1853
       CMP  D         ;COMPARE HL WITH DE
1854
       RNZ            ;RETURN CORRECT C AND
1855
       MOV  A,L       ;Z FLAGS
1856
       CMP  E         ;BUT OLD A IS LOST
1857
       RET
1858
       DB   'AN'
1859
;*
1860
SS1:    EQU     28H     ;EXECUTE TIME LOCATION OF THIS INSTRUCTION.
1861
        LDAX D         ;*** IGNBLK/RST 5 ***
1862
       CPI  40Q       ;IGNORE BLANKS
1863
       RNZ            ;IN TEXT (WHERE DE->)
1864
       INX  D         ;AND RETURN THE FIRST
1865
       JMP  SS1       ;NON-BLANK CHAR. IN A
1866
;*
1867
       POP  PSW       ;*** FINISH/RST 6 ***
1868
       CALL FIN       ;CHECK END OF COMMAND
1869
       JMP  QWHAT     ;PRINT "WHAT?" IFF WRONG
1870
       DB   'G'
1871
;*
1872
       RST  5         ;*** TSTV OR RST 7 ***
1873
       SUI  100Q      ;TEST VARIABLES
1874
       RC             ;C:NOT A VARIABLE
1875
       JMP  TSTV1     ;JUMP AROUND RESERVED AREA
1876
; ROUTINE TO COPY RESTART TABLE INTO LOW MEMORY
1877
RST1:   EQU     8       ;LOCATION FIRST REATART ROUTINE
1878
 
1879
EOT:    EQU     40H     ;LAST LOC TO BE FILLED
1880
 
1881
        ORG     0AA0H
1882
NINIT:  LXI     H,RST1          ;POINT TO BEGINNING OF MODEL TABLE
1883
        LXI     D,RSTBL
1884
NXT:    LDAX    D
1885
        MOV     M,A
1886
        INX     H
1887
        INX     D
1888
        MVI     A,EOT
1889
        CMP     L
1890
        JNZ     NXT
1891
        LXI     H,INIT
1892
        SHLD    START+1
1893
        JMP     START
1894
       ORG  0F00H
1895
TXTEND EQU  $         ;TEXT SAVE AREA ENDS
1896
VARBGN DS   2*27      ;VARIABLE @(0)
1897
       DS   1         ;EXTRA BYTE FOR BUFFER
1898
BUFFER DS   80        ;INPUT BUFFER
1899
BUFEND EQU  $         ;BUFFER ENDS
1900
       DS   40        ;EXTRA BYTES FOR STACK
1901
STKLMT EQU  $         ;TOP LIMIT FOR STACK
1902
       ORG  2000H
1903
STACK  EQU  $         ;STACK STARTS HERE
1904
       END

powered by: WebSVN 2.1.0

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