Der komplette TINY-MP-BASIC-Interpreter des ROMs des U883
AS V1.42 Beta [Bld 157] - Source File U883_MME_BAS.asm - Page 1 - 8/16/2021 14:5:33
1/ 0 : ; reass: Volker Pohlers 02.2007/07.2021
2/ 0 :
3/ 0 :
4/ 0 : ;AS-Funktionen
5/ 0 : hi function x,(x>>8)&255
6/ 0 : lo function x, x&255
7/ 0 :
8/ 0 :
9/ 0 : cpu z8601
10/ 0 : include stddefz8.inc
(1) 1/ 0 : save
(1) 55/ 0 : ALL restore ; wieder erlauben
(1) 56/ 0 :
(1) 57/ 0 :
11/ 0 : page 0
12/ 0 :
13/ 0 : org 0
14/ 0 : assume RP:0C0h ; keine Optimierung durch AS!
15/ 0 :
16/ 0 : =4H reg_04 equ 4 ; Hi TRAP
17/ 0 : =5H reg_05 equ 5 ; Lo TRAP
18/ 0 : =6H reg_06 equ 6 ; Hi Adr. Basic-Programm
19/ 0 : =7H reg_07 equ 7 ; Lo Adr. Basic-Programm
20/ 0 : =8H reg_08 equ 8 ; Hi Adr. ext. Prozedurliste
21/ 0 : =9H reg_09 equ 9 ; Lo Adr. ext. Prozedurliste
22/ 0 : =0AH reg_0A equ 0Ah
23/ 0 : =0BH reg_0B equ 0Bh
24/ 0 : =0CH reg_0C equ 0Ch
25/ 0 : =0EH reg_0E equ 0Eh ; Bit0..Bit3: Verschachtelungstiefe f. GOSUB
26/ 0 : ; Bit5 = 1: return without gosub
27/ 0 : ; Bit6
28/ 0 : ; Bit7
29/ 0 :
30/ 0 : =0FH reg_0F equ 0Fh ; aktueller State
31/ 0 : ; Bit 0 01: 1=ELSE
32/ 0 : ; Bit 1 02: END
33/ 0 : ; Bit 2 04: CONT
34/ 0 : ; Bit 3 08: STOP, STEP
35/ 0 : ; Bit 4 10: <
36/ 0 : ; Bit 5 20: >
37/ 0 : ; Bit 6 40: =
38/ 0 : ; Bit 7 80:
39/ 0 : =7FH reg_7F equ 7Fh
40/ 0 :
41/ 0 : ;reg_20h..reg53h Variablen A..Z (Doppelregister, 16 Bit)
42/ 0 : ;ab 54h frei nutzbar, z.B. f. Stack
43/ 0 :
44/ 0 : ; ext. Routinen
45/ 0 : ;saddrh equ 0E000h ; startadr RAM s. init10
46/ 0 : ;saddr equ 812h ; startadr ROM s. init10
47/ 0 : =815H getch equ 815h
48/ 0 : =818H putch equ 818h
49/ 0 :
50/ 0 :
51/ 0 : ; Register
52/ 0 : =0FEH gpr equ 0FEh ; General purpose register bzw. Stackpointer, Highteil
53/ 0 :
54/ 0 : ;-----------------------------------------------------------------------------
55/ 0 : ;
56/ 0 : ;-----------------------------------------------------------------------------
57/ 0 :
58/ 0 : 08 00 irq0: dw 800h
59/ 2 : 08 03 irq1: dw 803h
60/ 4 : 08 06 irq2: dw 806h
61/ 6 : 08 09 irq3: dw 809h
62/ 8 : 08 0C irq4: dw 80Ch
63/ A : 08 0F irq5: dw 80Fh
64/ C :
65/ C : ;-----------------------------------------------------------------------------
66/ C : ; Bootstrap MODULE
67/ C : ; s. Kieser/Bankel Seite 228-229
68/ C : ;-----------------------------------------------------------------------------
69/ C :
70/ C : ; public init
71/ C : 31 00 init: srp #0 ; Registerprointer auf 00-Gruppe
72/ E : 3C 0F ld R3, #0Fh ; Test, ob P32 und P35 gebrückt sind
73/ 10 : FF nop
74/ 11 : 76 E3 04 tm R3, #4
75/ 14 : 3C FF ld R3, #0FFh
76/ 16 : EB 05 jr NZ, init10
77/ 18 : 76 E3 04 tm R3, #4
78/ 1B : EB 20 jr NZ, test ; wenn gebrückt, dann weiter im Test-Programm
79/ 1D : ;
80/ 1D : E6 F8 B6 init10: ld p01m, #10110110b ; Festlegung für erweitertes Zeitverhalten
81/ 20 : E6 F7 08 ld p3m, #00001000b ; Programmierung Port 3
82/ 23 : 4C 08 ld R4, #8 ; Test, ob sich auf Adresse 0812h RAM befindet
83/ 25 : 5C 12 ld R5, #12h
84/ 27 : C2 64 ldc R6, @RR4
85/ 29 : 60 E6 com R6
86/ 2B : D2 64 ldc @RR4, R6
87/ 2D : C2 74 ldc R7, @RR4
88/ 2F : 60 E6 com R6
89/ 31 : D2 64 ldc @RR4, R6
90/ 33 : B2 67 xor R6, R7
91/ 35 : 31 F0 srp #0F0h
92/ 37 : ED E0 00 jp NZ, 0E000h ; wenn RAM lokalisiert ist, Sprung nach 0E000h
93/ 3A : 8D 08 12 jp 812h ; sonst nach Adresse 0812h springen
94/ 3D :
95/ 3D :
96/ 3D : ;-----------------------------------------------------------------------------
97/ 3D : ; Testhilfe zur Ausgabe von alternierenden
98/ 3D : ; Impulsen am Port P1 und P0 mit
99/ 3D : ; Triggerimpuls an Leitung P35
100/ 3D : ;-----------------------------------------------------------------------------
101/ 3D :
102/ 3D : E6 F8 04 test: ld p01m, #4 ; Port P1 und P0 auf Ausgabe
103/ 40 : E6 F1 C0 ld tmr, #0C0h ; internen Takt ausgeben
104/ 43 : 0C FF ld R0, #0FFh
105/ 45 : 1C FF ld R1, #0FFh
106/ 47 : CF rcf
107/ 48 : 56 E3 DF test10: and R3, #0DFh ; Triggerimpuls an Leitung P35
108/ 4B : 46 E3 20 or R3, #20h
109/ 4E : 10 E1 test20: rlc R1
110/ 50 : 10 E0 rlc R0
111/ 52 : 76 E3 04 tm R3, #4 ; Abfrage für tristate
112/ 55 : 6B 04 jr Z, tristate
113/ 57 : 7B F5 jr C, test20
114/ 59 : 8B ED jr test10
115/ 5B : E6 F8 7F tristate: ld p01m, #7Fh ; Ports 0-1 mode
116/ 5E : 8B FE halt: jr halt ; Warteschleife
117/ 60 :
118/ 60 : ;-----------------------------------------------------------------------------
119/ 60 : ; dma MODULE
120/ 60 : ; s. Kieser/Bankel Seite 235
121/ 60 :
122/ 60 : ; Serviceroutine für BUSREQ,
123/ 60 : ; mit BUSREQ an P32 und
124/ 60 : ; BUSACK ans P35, beide L-aktiv
125/ 60 : ;-----------------------------------------------------------------------------
126/ 60 :
127/ 60 : busreq: ; Festlegung der Kodierung für Tristate für Port 0 und P1
128/ 60 : 46 7F 18 or reg_7F, #18h ; P01M muß in Register %7F verfügbar sein, da P01M nicht lesbar
129/ 63 : E4 7F F8 ld p01m, reg_7F ; Ports 0-1 mode
130/ 66 : 56 03 DF and p3, #0DFh ; Ausgabe von BUSACK
131/ 69 : 76 03 04 busreq10: tm p3, #4 ; Port 3
132/ 6C : 6B FB jr Z, busreq10 ; Ende abwarten
133/ 6E : 56 7F F7 and reg_7F, #0F7h ; Festlegung der Kodierung für AD0..AD7 an Port 0 und Port 1
134/ 71 : 46 03 20 or p3, #20h ; BUSACK zurücknehmen
135/ 74 : E4 7F F8 ld p01m, reg_7F ; wieder auf Bus gehen
136/ 77 : FF nop ; Ausführung (wegen Pipeline) abwarten
137/ 78 : BF iret
138/ 79 :
139/ 79 : ; Beginn TINY-MP-BASIC
140/ 79 : ; Variablen A..Z liegen in Register 20h..53h
141/ 79 : ; Registernutzung RP = 10h
142/ 79 : ; RR0 Pointer aktuelles Zeichen in BASIC-Programm
143/ 79 : ; RR2 Y, Rückgabewert
144/ 79 : ; RR4 X, Eingabewert
145/ 79 : ; R6 aktuelles Zeichen
146/ 79 :
147/ 79 :
148/ 79 : ; Arithmetik: Parameter1 X R4+R5, Rückgabewert Y R2+R3
149/ 79 :
150/ 79 : ;-----------------------------------------------------------------------------
151/ 79 : ; Y := X
152/ 79 : ;-----------------------------------------------------------------------------
153/ 79 :
154/ 79 : 28 E4 p_let: ld R2, R4 ; Y := X
155/ 7B : 38 E5 ld R3, R5
156/ 7D : AF ret
157/ 7E :
158/ 7E : ;-----------------------------------------------------------------------------
159/ 7E : ; Y := Y + X
160/ 7E : ;-----------------------------------------------------------------------------
161/ 7E :
162/ 7E : 02 35 p_plus: add R3, R5 ; Y := Y + X
163/ 80 : 12 24 adc R2, R4
164/ 82 : 4B 16 jr OV, p_abs3
165/ 84 : AF ret
166/ 85 :
167/ 85 : ;-----------------------------------------------------------------------------
168/ 85 : ; Y := Y - X
169/ 85 : ;-----------------------------------------------------------------------------
170/ 85 :
171/ 85 : 22 35 p_minus: sub R3, R5 ; Y := Y - X
172/ 87 : 32 24 sbc R2, R4
173/ 89 : 4B 0F jr OV, p_abs3
174/ 8B : AF ret
175/ 8C :
176/ 8C : ;-----------------------------------------------------------------------------
177/ 8C : ; interne Prozedur ABS
178/ 8C : ; ABS[parameter] absoluter Betrag
179/ 8C : ;-----------------------------------------------------------------------------
180/ 8C : ; Y := ABS (X)
181/ 8C : 76 E4 80 p_abs: tm R4, #80h ; X Test Vorzeichen Bit 7
182/ 8F : 6B E8 jr Z, p_let ; Y := X
183/ 91 : ; sonst negieren
184/ 91 : B0 E2 p_abs1: clr R2 ; Y := 0
185/ 93 : B0 E3 clr R3
186/ 95 : 8B EE jr p_minus ; Y := Y - X
187/ 97 : 46 0F 80 p_abs2: or reg_0F, #80h ; Bit7
188/ 9A : 46 0E 80 p_abs3: or reg_0E, #80h ; Bit7
189/ 9D : AF ret
190/ 9E :
191/ 9E :
192/ 9E : ;-----------------------------------------------------------------------------
193/ 9E : ; UP zu DIV/MULT
194/ 9E : ;-----------------------------------------------------------------------------
195/ 9E :
196/ 9E : ; ? Vorzeichen behandeln
197/ 9E : 88 E2 sign: ld R8, R2
198/ A0 : B2 84 xor R8, R4
199/ A2 : 9C 02 ld R9, #2
200/ A4 : ;
201/ A4 : 68 E2 sign1: ld R6, R2
202/ A6 : 78 E3 ld R7, R3
203/ A8 : D6 00 8C call p_abs ; ABS[parameter] absoluter Betrag
204/ AB : 48 E6 ld R4, R6
205/ AD : 58 E7 ld R5, R7
206/ AF : 9A F3 djnz R9, sign1
207/ B1 : 68 E2 ld R6, R2
208/ B3 : 78 E3 ld R7, R3
209/ B5 : B0 E2 clr R2
210/ B7 : B0 E3 clr R3
211/ B9 : AF ret
212/ BA :
213/ BA : ;-----------------------------------------------------------------------------
214/ BA : ; Y := Y * X
215/ BA : ;-----------------------------------------------------------------------------
216/ BA :
217/ BA : D6 00 9E p_mult: call sign
218/ BD : BC 0F ld R11, #0Fh
219/ BF : D0 E6 p_mult1: sra R6
220/ C1 : C0 E7 rrc R7
221/ C3 : FB 06 jr NC, p_mult2
222/ C5 : 02 35 add R3, R5
223/ C7 : 12 24 adc R2, R4
224/ C9 : 4B CC jr OV, p_abs2
225/ CB : 10 E5 p_mult2: rlc R5
226/ CD : 10 E4 rlc R4
227/ CF : CB 04 jr NOV, p_mult3
228/ D1 : 42 67 or R6, R7
229/ D3 : EB C2 jr NZ, p_abs2
230/ D5 : BA E8 p_mult3: djnz R11, p_mult1
231/ D7 : 48 E2 p_mult4: ld R4, R2
232/ D9 : 58 E3 ld R5, R3
233/ DB : 10 E8 rlc R8
234/ DD : 7B B2 jr C, p_abs1
235/ DF : AF ret
236/ E0 :
237/ E0 : ;-----------------------------------------------------------------------------
238/ E0 : ; Y := Y / X
239/ E0 : ;-----------------------------------------------------------------------------
240/ E0 :
241/ E0 : D6 00 9E p_div: call sign
242/ E3 : 9C 10 ld R9, #10h
243/ E5 : CF rcf
244/ E6 : B0 EA clr R10 ; RR10 = Divisionstrest = 0
245/ E8 : B0 EB clr R11
246/ EA : 10 E7 p_div1: rlc R7
247/ EC : 10 E6 rlc R6
248/ EE : 10 EB rlc R11
249/ F0 : 10 EA rlc R10
250/ F2 : 7B 0A jr C, p_div2
251/ F4 : A2 4A cp R4, R10
252/ F6 : BB 0B jr UGT, p_div3
253/ F8 : 7B 04 jr C, p_div2
254/ FA : A2 5B cp R5, R11
255/ FC : BB 05 jr UGT, p_div3
256/ FE : 22 B5 p_div2: sub R11, R5
257/ 100 : 32 A4 sbc R10, R4
258/ 102 : DF scf
259/ 103 : 9A E5 p_div3: djnz R9, p_div1
260/ 105 : 98 E4 ld R9, R4
261/ 107 : 42 95 or R9, R5
262/ 109 : 6B 0A jr Z, p_div5
263/ 10B : 10 E7 rlc R7
264/ 10D : 10 E6 rlc R6
265/ 10F : ;
266/ 10F : 28 E6 p_div4: ld R2, R6
267/ 111 : 38 E7 ld R3, R7
268/ 113 : 8B C2 jr p_mult4
269/ 115 : ;
270/ 115 : D6 01 0F p_div5: call p_div4
271/ 118 : 46 0E 40 or reg_0E, #40h ; Bit6
272/ 11B : 46 0F 80 p_div6: or reg_0F, #80h ; Bit7
273/ 11E : AF ret
274/ 11F :
275/ 11F : ;-----------------------------------------------------------------------------
276/ 11F : ; $-Operator
277/ 11F : ; Y := Y MOD X
278/ 11F : ;-----------------------------------------------------------------------------
279/ 11F :
280/ 11F : D6 00 E0 p_mod: call p_div
281/ 122 : 88 E2 ld R8, R2
282/ 124 : 28 EA ld R2, R10 ; Divisonsrest
283/ 126 : 38 EB ld R3, R11
284/ 128 : 8B AD jr p_mult4
285/ 12A :
286/ 12A : ;-----------------------------------------------------------------------------
287/ 12A : ; $-Operator
288/ 12A : ; Y := Y OR X
289/ 12A : ;-----------------------------------------------------------------------------
290/ 12A :
291/ 12A : 42 24 p_or: or R2, R4
292/ 12C : 42 35 or R3, R5
293/ 12E : AF ret
294/ 12F :
295/ 12F : ;-----------------------------------------------------------------------------
296/ 12F : ; $-Operator
297/ 12F : ; Y := Y AND X
298/ 12F : ;-----------------------------------------------------------------------------
299/ 12F :
300/ 12F : 52 24 p_and: and R2, R4
301/ 131 : 52 35 and R3, R5
302/ 133 : AF ret
303/ 134 :
304/ 134 : ;-----------------------------------------------------------------------------
305/ 134 : ; $-Operator
306/ 134 : ; Y := Y XOR X
307/ 134 : ;-----------------------------------------------------------------------------
308/ 134 :
309/ 134 : B2 24 p_xor: xor R2, R4
310/ 136 : B2 35 xor R3, R5
311/ 138 : AF ret
312/ 139 :
313/ 139 : ;-----------------------------------------------------------------------------
314/ 139 : ; interne Prozedur NOT
315/ 139 : ;-----------------------------------------------------------------------------
316/ 139 : ; Y := NOT X
317/ 139 : ; NOT[parameter] bitweise logische Negation
318/ 139 :
319/ 139 : D6 00 79 p_not: call p_let ; Y := X
320/ 13C : 60 E2 com R2 ; Y := NOT X
321/ 13E : 60 E3 com R3
322/ 140 : AF ret
323/ 141 :
324/ 141 : ;-----------------------------------------------------------------------------
325/ 141 : ; Vergleich RR2 und RR4 auf <,=,>: out: reg_0F
326/ 141 : ;-----------------------------------------------------------------------------
327/ 141 :
328/ 141 : 56 0F 8F relcmp: and reg_0F, #8Fh ; Bit 4..6 = 0
329/ 144 : A2 24 cp R2, R4
330/ 146 : 6B 0A jr Z, relcmp3
331/ 148 : 7C 20 ld R7, #20h
332/ 14A : AB 02 jr GT, relcmp2 ; > Bitmaske 20h
333/ 14C : 7C 10 relcmp1: ld R7, #10h ; < Bitmaske 10h
334/ 14E : 44 E7 0F relcmp2: or reg_0F, R7
335/ 151 : AF ret
336/ 152 : ;
337/ 152 : 7C 40 relcmp3: ld R7, #40h
338/ 154 : A2 35 cp R3, R5
339/ 156 : 6B F6 jr Z, relcmp2 ; = Bitmaske 40h
340/ 158 : 7C 20 ld R7, #20h
341/ 15A : BB F2 jr UGT, relcmp2
342/ 15C : 8B EE jr relcmp1
343/ 15E :
344/ 15E : ;-----------------------------------------------------------------------------
345/ 15E : ; UP zu c_PRINTHEX
346/ 15E : ; Konvertierung nach hexadezimal
347/ 15E : ;-----------------------------------------------------------------------------
348/ 15E :
349/ 15E : 88 E3 tohex: ld R8, R3 ; Byte->Nibble
350/ 160 : 78 E3 ld R7, R3 ; R2/R3 in R5..R8 kopieren
351/ 162 : 68 E2 ld R6, R2 ;
352/ 164 : 58 E2 ld R5, R2 ;
353/ 166 : F0 E5 swap R5 ; Hi Nibble in untere Tetrade
354/ 168 : F0 E7 swap R7 ; Hi Nibble in untere Tetrade
355/ 16A : 4C 25 ld R4, #'%'
356/ 16C : ;
357/ 16C : AC 04 ld R10, #4 ; 4 Stellen
358/ 16E : BC 15 tohex1: ld R11, #15h ; Buffer
359/ 170 : 57 EB 0F tohex2: and @R11, #0Fh
360/ 173 : 07 EB 30 add @R11, #30h ; '0'
361/ 176 : A7 EB 3A cp @R11, #3Ah ; '9'+1
362/ 179 : 7B 03 jr C, tohex3 ; wenn größer '9', dann + 7
363/ 17B : 07 EB 07 add @R11, #7 ; ergibt 'A'..'F'
364/ 17E : BE tohex3: inc R11 ; nächste Ausgabepos
365/ 17F : AA EF djnz R10, tohex2 ; nächste Stelle
366/ 181 : AF ret
367/ 182 :
368/ 182 : ;-----------------------------------------------------------------------------
369/ 182 : ; UP zu c_PRINT
370/ 182 : ; Konvertierung nach dezimal
371/ 182 : ;-----------------------------------------------------------------------------
372/ 182 :
373/ 182 : 48 E2 todez: ld R4, R2
374/ 184 : 58 E3 ld R5, R3
375/ 186 : D6 00 8C call p_abs ; absoluter Betrag
376/ 189 : 10 E4 rlc R4
377/ 18B : 4C 20 ld R4, #' ' ; bei pos. Zahl Leerzeichen
378/ 18D : FB 02 jr NC, todez1
379/ 18F : 4C 2D ld R4, #'-' ; bei neg. Zahl '-'
380/ 191 : BC 06 todez1: ld R11, #6 ; 6 Stellen
381/ 193 : AC 15 ld R10, #15h ; Buffer
382/ 195 : B1 EA todez2: clr @R10 ; leeren
383/ 197 : AE inc R10
384/ 198 : BA FB djnz R11, todez2
385/ 19A : ;hex-> bcd
386/ 19A : BC 0F ld R11, #0Fh
387/ 19C : D0 E2 todez3: sra R2
388/ 19E : C0 E3 rrc R3
389/ 1A0 : FB 0C jr NC, todez4
390/ 1A2 : 02 7A add R7, R10
391/ 1A4 : 40 E7 da R7
392/ 1A6 : 12 69 adc R6, R9
393/ 1A8 : 40 E6 da R6
394/ 1AA : 12 58 adc R5, R8
395/ 1AC : 40 E5 da R5
396/ 1AE : 02 AA todez4: add R10, R10
397/ 1B0 : 40 EA da R10
398/ 1B2 : 12 99 adc R9, R9
399/ 1B4 : 40 E9 da R9
400/ 1B6 : 12 88 adc R8, R8
401/ 1B8 : 40 E8 da R8
402/ 1BA : BA E0 djnz R11, todez3
403/ 1BC : 88 E7 ld R8, R7
404/ 1BE : 98 E7 ld R9, R7
405/ 1C0 : 78 E6 ld R7, R6
406/ 1C2 : F0 E6 swap R6
407/ 1C4 : F0 E8 swap R8
408/ 1C6 : ;bcd->ascii
409/ 1C6 : AC 05 ld R10, #5 ; 5 Stellen
410/ 1C8 : 8B A4 jr tohex1 ; nach ASCII wandeln
411/ 1CA :
412/ 1CA : ;-----------------------------------------------------------------------------
413/ 1CA : ; Ziffer in Result einschieben (i.e. * 16 + stelle)
414/ 1CA : ; UP zu number
415/ 1CA : ;-----------------------------------------------------------------------------
416/ 1CA :
417/ 1CA : F1 ED rotate: swap @R13 ; Ziffer in oberes Nibble
418/ 1CC : EC 04 ld R14, #4 ; alles 4 Stellen nach links
419/ 1CE : 11 ED rotate1: rlc @R13 ; d.h. * 16
420/ 1D0 : 10 E5 rlc R5
421/ 1D2 : 10 E4 rlc R4
422/ 1D4 : 10 E3 rlc R3
423/ 1D6 : EA F6 djnz R14, rotate1
424/ 1D8 : AF ret
425/ 1D9 :
426/ 1D9 : ;-----------------------------------------------------------------------------
427/ 1D9 : ; Konvertierung ASCII->Zahl (hex, o. dez signed)
428/ 1D9 : ; in: String in Konvertierungspuffer ab 16h (R6 ff) ..
429/ 1D9 : ; ret: RR4 = Wert
430/ 1D9 : ;-----------------------------------------------------------------------------
431/ 1D9 :
432/ 1D9 : DC 16 number: ld R13, #16h ; Konvertierungspuffer
433/ 1DB : B0 E4 clr R4 ; Startwert 0
434/ 1DD : B0 E5 clr R5
435/ 1DF : A6 E6 25 cp R6, #'%' ; Präfix Hexzahl
436/ 1E2 : EB 27 jr NZ, number5
437/ 1E4 :
438/ 1E4 : ; Hex-Zahl
439/ 1E4 : CC 05 ld R12, #5 ; max. 5 Stellen
440/ 1E6 : DE number1: inc R13
441/ 1E7 : 27 ED 30 sub @R13, #'0'
442/ 1EA : 7B 19 jr C, number4
443/ 1EC : A7 ED 0A cp @R13, #0Ah ; 9+1
444/ 1EF : 7B 0D jr C, number2
445/ 1F1 : 27 ED 11 sub @R13, #11h ; A..F -> 0..5
446/ 1F4 : 7B 0F jr C, number4
447/ 1F6 : 07 ED 0A add @R13, #0Ah ; +10
448/ 1F9 : A7 ED 10 cp @R13, #10h
449/ 1FC : FB 07 jr NC, number4
450/ 1FE : D6 01 CA number2: call rotate ; * 16 + Stelle
451/ 201 : CA E3 djnz R12, number1
452/ 203 : CF number3: rcf
453/ 204 : AF ret
454/ 205 : ;
455/ 205 : A6 EC 05 number4: cp R12, #5
456/ 208 : 6B F9 jr Z, number3
457/ 20A : AF ret
458/ 20B :
459/ 20B : ; Dezimalzahl
460/ 20B : CC 06 number5: ld R12, #6 ; max. 6 Stellen
461/ 20D : B0 E2 clr R2
462/ 20F : B0 E3 clr R3
463/ 211 : A6 E6 2D cp R6, #'-' ; Vorzeichen
464/ 214 : EB 02 jr NZ, number7
465/ 216 : 2E inc R2
466/ 217 : DE number6: inc R13
467/ 218 : 27 ED 30 number7: sub @R13, #'0'
468/ 21B : 7B 0C jr C, number9 ; wenn keine Ziffer mehr
469/ 21D : A7 ED 0A cp @R13, #0Ah ; 9+1
470/ 220 : FB 07 jr NC, number9 ; wenn keine Ziffer mehr
471/ 222 : D6 01 CA call rotate ; sonst zu BCD konvertieren
472/ 225 : CA F0 djnz R12, number6
473/ 227 : CF number8: rcf
474/ 228 : AF ret
475/ 229 :
476/ 229 : ; BCD R3R4R5 -> hex RR4
477/ 229 : A6 EC 06 number9: cp R12, #6
478/ 22C : 6B F9 jr Z, number8
479/ 22E : A6 E3 04 cp R3, #4
480/ 231 : FB F4 jr NC, number8
481/ 233 : B0 E6 clr R6
482/ 235 : B0 E7 clr R7
483/ 237 : BC 13 ld R11, #13h
484/ 239 : 8C 27 ld R8, #27h ; 2710h = 10000
485/ 23B : 9C 10 ld R9, #10h
486/ 23D : D6 02 71 call number11
487/ 240 : BE inc R11
488/ 241 : 8C 03 ld R8, #3 ; 3E8h = 1000
489/ 243 : 9C E8 ld R9, #0E8h
490/ 245 : D6 02 6F call number10
491/ 248 : 8C 00 ld R8, #0 ; 064h = 100
492/ 24A : 9C 64 ld R9, #64h
493/ 24C : D6 02 6F call number10
494/ 24F : BE inc R11
495/ 250 : 9C 0A ld R9, #0Ah ; 10
496/ 252 : D6 02 6F call number10
497/ 255 : 9C 01 ld R9, #1 ; 1
498/ 257 : D6 02 6F call number10
499/ 25A : 48 E6 ld R4, R6
500/ 25C : 58 E7 ld R5, R7
501/ 25E : 10 E6 rlc R6
502/ 260 : 7B C5 jr C, number8
503/ 262 : C0 E2 rrc R2
504/ 264 : FB 18 jr NC, number13
505/ 266 : D6 00 91 call p_abs1
506/ 269 : 48 E2 ld R4, R2
507/ 26B : 58 E3 ld R5, R3
508/ 26D : 8B 0F jr number13
509/ 26F :
510/ 26F : ;
511/ 26F : F1 EB number10: swap @R11
512/ 271 : E3 AB number11: ld R10, @R11 ; Stelle n
513/ 273 : 56 EA 0F and R10, #0Fh
514/ 276 : 6B 06 jr Z, number13
515/ 278 : 02 79 number12: add R7, R9 ; RR8 = Stelligkeit
516/ 27A : 12 68 adc R6, R8
517/ 27C : AA FA djnz R10, number12 ; n mal Addieren
518/ 27E : DF number13: scf
519/ 27F : AF ret
520/ 280 :
521/ 280 : ;-----------------------------------------------------------------------------
522/ 280 : ; bei Prozeduraufruf PROC [Y1,Y2,Y3,..,Ym] = prozedurname [X1,X2,X3,..,Xn] gilt:
523/ 280 : ; SP returnadr.
524/ 280 : ; SP+2 .. SP+2n-2 n-1 Parameter, wenn n>1
525/ 280 : ; letzter Parameter aus Liste ist in RR4
526/ 280 : ; SP+2n (intern f. interpreter)
527/ 280 : ; SP+2n+2 .. SP+2m+2n Platz für m-1 Ergebnisvariable, wenn m>1
528/ 280 : ; letzter Parameter aus Liste ist in RR2 zu übergeben
529/ 280 : ;-----------------------------------------------------------------------------
530/ 280 :
531/ 280 : ;-----------------------------------------------------------------------------
532/ 280 : ; Ret.Adr. und ersten Parameter vom Stack nach R6/R7 holen
533/ 280 : ;-----------------------------------------------------------------------------
534/ 280 :
535/ 280 : 50 E8 para1: pop R8 ; RR8 Rückkehradresse dieser Routine
536/ 282 : 50 E9 pop R9
537/ 284 : 50 E2 pop R2 ; RR2 Rückkehradresse zum Interpreter
538/ 286 : 50 E3 pop R3
539/ 288 : 50 E6 pop R6 ; RR6 Adresse von X1
540/ 28A : 50 E7 pop R7
541/ 28C : 30 E8 jp @RR8 ; RET
542/ 28E :
543/ 28E : ;-----------------------------------------------------------------------------
544/ 28E : ; interne Prozedur
545/ 28E : ; SETRR [register,wert] Doppelregister setzen
546/ 28E : ;-----------------------------------------------------------------------------
547/ 28E :
548/ 28E : D6 02 80 p_setrr: call para1 ; Parameter register nach R6/R7
549/ 291 : F3 74 ld @R7, R4 ; register (hi) := wert
550/ 293 : 7E inc R7
551/ 294 : 8B 03 jr p_setr1
552/ 296 :
553/ 296 : ;-----------------------------------------------------------------------------
554/ 296 : ; interne Prozedur
555/ 296 : ; SETR [register,wert] Register setzen
556/ 296 : ;-----------------------------------------------------------------------------
557/ 296 :
558/ 296 : D6 02 80 p_setr: call para1 ; Parameter register nach R6/R7
559/ 299 : F3 75 p_setr1: ld @R7, R5 ; register (lo) := wert
560/ 29B : 30 E2 jp @RR2 ; zurück zum Interpreter
561/ 29D :
562/ 29D : ;-----------------------------------------------------------------------------
563/ 29D : ; interne Prozedur
564/ 29D : ; SETEW [adresse,wert] externes Wort setzen
565/ 29D : ;-----------------------------------------------------------------------------
566/ 29D :
567/ 29D : D6 02 80 p_setew: call para1 ; Parameter adresse nach R6/R7
568/ 2A0 : 92 46 lde @RR6, R4
569/ 2A2 : A0 E6 incw RR6
570/ 2A4 : 8B 03 jr p_seteb1
571/ 2A6 :
572/ 2A6 : ;-----------------------------------------------------------------------------
573/ 2A6 : ; interne Prozedur
574/ 2A6 : ; SETEB [adresse,wert] externes Byte setzen
575/ 2A6 : ;-----------------------------------------------------------------------------
576/ 2A6 :
577/ 2A6 : D6 02 80 p_seteb: call para1 ; Parameter adresse nach R6/R7
578/ 2A9 : 92 56 p_seteb1: lde @RR6, R5
579/ 2AB : 30 E2 jp @RR2
580/ 2AD :
581/ 2AD : ;-----------------------------------------------------------------------------
582/ 2AD : ; interne Prozedur
583/ 2AD : ; GETRR [register] liefert Inhalt des Doppelregisters
584/ 2AD : ;-----------------------------------------------------------------------------
585/ 2AD :
586/ 2AD : E3 25 p_getrr: ld R2, @R5
587/ 2AF : 5E inc R5
588/ 2B0 : 0D db 0Dh ; JP FALSE mit nächstem Befehl
589/ 2B1 :
590/ 2B1 : ;-----------------------------------------------------------------------------
591/ 2B1 : ; interne Prozedur
592/ 2B1 : ; GETR [register] liefert Inhalt des Registers
593/ 2B1 : ;-----------------------------------------------------------------------------
594/ 2B1 :
595/ 2B1 : B0 E2 p_getr: clr R2 ; Hi = 0
596/ 2B3 : E3 35 ld R3, @R5
597/ 2B5 : AF ret
598/ 2B6 :
599/ 2B6 : ;-----------------------------------------------------------------------------
600/ 2B6 : ; interne Prozedur
601/ 2B6 : ; GETEW [register] holt Wortwert aus externem Speicher
602/ 2B6 : ;-----------------------------------------------------------------------------
603/ 2B6 :
604/ 2B6 : 82 24 p_getew: lde R2, @RR4
605/ 2B8 : A0 E4 incw RR4
606/ 2BA : 0D db 0Dh ; JP FALSE mit nächstem Befehl
607/ 2BB :
608/ 2BB : ;-----------------------------------------------------------------------------
609/ 2BB : ; interne Prozedur
610/ 2BB : ; GETEB [register] holt Bytewert aus externem Speicher
611/ 2BB : ;-----------------------------------------------------------------------------
612/ 2BB :
613/ 2BB : B0 E2 p_geteb: clr R2
614/ 2BD : 82 34 lde R3, @RR4
615/ 2BF : AF ret
616/ 2C0 :
617/ 2C0 : ;-----------------------------------------------------------------------------
618/ 2C0 : ; angezeigtes Zeichen löschen
619/ 2C0 : ;-----------------------------------------------------------------------------
620/ 2C0 : ; UP zu p_input6
621/ 2C0 :
622/ 2C0 : D6 02 C8 delc: call delc1 ; ein Zeichen zurück
623/ 2C3 : 5C 20 ld R5, #' ' ; mit Leerzeichen überschreiben
624/ 2C5 : D6 08 18 call putch ; PUT_CHAR
625/ 2C8 : 5C 08 delc1: ld R5, #8 ; BS
626/ 2CA : 8D 08 18 jp putch ; PUT_CHAR
627/ 2CD :
628/ 2CD : ;-----------------------------------------------------------------------------
629/ 2CD : ; interne Prozedur
630/ 2CD : ; ; RL[x] x links rotieren
631/ 2CD : ;-----------------------------------------------------------------------------
632/ 2CD :
633/ 2CD : CF p_rl: rcf ; Cy = 0
634/ 2CE : 10 E5 rlc R5
635/ 2D0 : 10 E4 rlc R4
636/ 2D2 : 16 E5 00 adc R5, #0
637/ 2D5 : 8D 00 79 p_rl1: jp p_let ; Y := X
638/ 2D8 :
639/ 2D8 : ;-----------------------------------------------------------------------------
640/ 2D8 : ; interne Prozedur
641/ 2D8 : ; RR[x] x rechts rotieren
642/ 2D8 : ;-----------------------------------------------------------------------------
643/ 2D8 :
644/ 2D8 : CF p_rr: rcf ; Cy = 0
645/ 2D9 : C0 E4 rrc R4
646/ 2DB : C0 E5 rrc R5
647/ 2DD : FB F6 jr NC, p_rl1
648/ 2DF : 46 E4 80 or R4, #80h ; Vorzeichen löschen
649/ 2E2 : 8B F1 jr p_rl1
650/ 2E4 :
651/ 2E4 : ;-----------------------------------------------------------------------------
652/ 2E4 : ; interne Prozedur
653/ 2E4 : ; INPUT Zahleneingabe vom Terminal
654/ 2E4 : ;-----------------------------------------------------------------------------
655/ 2E4 :
656/ 2E4 : 5C 3F p_input: ld R5, #'?'
657/ 2E6 : D6 08 18 call putch ; PUT_CHAR
658/ 2E9 : FC 15 p_input1: ld R15, #15h ; Konvertierungspuffer
659/ 2EB : FE p_input2: inc R15
660/ 2EC : A6 EF 1F cp R15, #1Fh
661/ 2EF : 6B 20 jr Z, p_input4
662/ 2F1 : D6 08 15 p_input3: call getch ; GET_CHAR
663/ 2F4 : F3 F3 ld @R15, R3
664/ 2F6 : A6 E3 0D cp R3, #0Dh ; CR
665/ 2F9 : 6B 16 jr Z, p_input4
666/ 2FB : A6 E3 08 cp R3, #8 ; BS
667/ 2FE : EB 19 jr NZ, p_input5
668/ 300 : 5C 20 ld R5, #' '
669/ 302 : D6 08 18 call putch ; PUT_CHAR
670/ 305 : 00 EF dec R15
671/ 307 : A6 EF 15 cp R15, #15h
672/ 30A : 6B DF jr Z, p_input2
673/ 30C : D6 02 C8 call delc1
674/ 30F : 8B E0 jr p_input3
675/ 311 : D6 01 D9 p_input4: call number
676/ 314 : FB CE jr NC, p_input ; INPUT Zahleneingabe vom Terminal
677/ 316 : 8D 00 79 jp p_let ; Y := X
678/ 319 : 3E p_input5: inc R3
679/ 31A : DB CF jr PL, p_input2
680/ 31C : A6 EF 16 p_input6: cp R15, #16h
681/ 31F : 6B C8 jr Z, p_input1
682/ 321 : D6 02 C0 call delc ; angezeigtes Zeichen löschen
683/ 324 : 00 EF dec R15
684/ 326 : 8B F4 jr p_input6
685/ 328 :
686/ 328 : ;-----------------------------------------------------------------------------
687/ 328 : ; Liste der internen Prozeduren
688/ 328 : ;-----------------------------------------------------------------------------
689/ 328 :
690/ 328 : 03 4E 4F 54 tab_prc: db 3,"NOT"
691/ 32C : 01 39 dw p_not ; NOT[parameter] bitweise logische Negation
692/ 32E : 03 41 42 53 db 3,"ABS"
693/ 332 : 00 8C dw p_abs ; ABS[parameter] absoluter Betrag
694/ 334 : 05 53 45 54 52 52 db 5,"SETRR"
695/ 33A : 02 8E dw p_setrr ; SETRR [register,wert] Doppelregister setzen
696/ 33C : 04 53 45 54 52 db 4,"SETR"
697/ 341 : 02 96 dw p_setr ; SETR [register,wert] Register setzen
698/ 343 : 05 53 45 54 45 57 db 5,"SETEW"
699/ 349 : 02 9D dw p_setew ; SETEW [adresse,wert] externes Wort setzen
700/ 34B : 05 53 45 54 45 42 db 5,"SETEB"
701/ 351 : 02 A6 dw p_seteb ; SETEB [adresse,wert] externes Byte setzen
702/ 353 : 05 47 45 54 52 52 db 5,"GETRR"
703/ 359 : 02 AD dw p_getrr ; GETRR [register] liefert Inhalt des Doppelregisters
704/ 35B : 04 47 45 54 52 db 4,"GETR"
705/ 360 : 02 B1 dw p_getr ; GETR [register] liefert Inhalt des Registers
706/ 362 : 05 47 45 54 45 57 db 5,"GETEW"
707/ 368 : 02 B6 dw p_getew ; GETEW [register] holt Wortwert aus externem Speicher
708/ 36A : 05 47 45 54 45 42 db 5,"GETEB"
709/ 370 : 02 BB dw p_geteb ; GETEB [register] holt Bytewert aus externem Speicher
710/ 372 : 02 52 4C db 2,"RL"
711/ 375 : 02 CD dw p_rl ; RL[x] x links rotieren
712/ 377 : 02 52 52 db 2,"RR"
713/ 37A : 02 D8 dw p_rr ; RR[x] x rechts rotieren
714/ 37C : 05 49 4E 50 55 54 db 5,"INPUT"
715/ 382 : 02 E4 dw p_input ; INPUT Zahleneingabe vom Terminal
716/ 384 : 03 47 54 43 db 3,"GTC"
717/ 388 : 08 15 dw getch ; Get Char extern !
718/ 38A : 03 50 54 43 db 3,"PTC"
719/ 38E : 08 18 dw putch ; Put Char extern !
720/ 390 : FF db 0FFh ; Listenende
721/ 391 :
722/ 391 : ;-----------------------------------------------------------------------------
723/ 391 : ;nächstes Zeichen aus Programmtext holen
724/ 391 : ;in: R7 Vergleichszeichen ret: Z=1 Zeichen gefunden
725/ 391 : ;-----------------------------------------------------------------------------
726/ 391 : FC 16 next_char: ld R15, #16h ; R15 vorbelegen für buffer ?
727/ 393 : C2 60 ldc R6, @RR0 ; nächstes Zeichen aus Basic-Programmcode
728/ 395 : A0 E0 incw RR0 ; Pointer weiterstellen
729/ 397 : A2 67 cp R6, R7 ; Vergleich mit R7
730/ 399 : AF ret
731/ 39A :
732/ 39A : ;-----------------------------------------------------------------------------
733/ 39A : ; Operator in Operator-Tabelle suchen
734/ 39A : ; ret: R7 = op, RR8 = proc.addr.
735/ 39A : ;-----------------------------------------------------------------------------
736/ 39A : AC 03 oper: ld R10, #HI(tab_op)
737/ 39C : BC C1 ld R11, #LO(tab_op)
738/ 39E : DC 03 ld R13, #3 ; 4 arithm. Operatoren
739/ 3A0 : D6 03 AF call oper1 ; suche
740/ 3A3 : 6B 1B jr Z, oper3 ; Operator nicht gefunden
741/ 3A5 : A6 E6 24 cp R6, #'$' ; Präfix logischer Operator
742/ 3A8 : EB 16 jr NZ, oper3 ; Präfix stimmt nicht
743/ 3AA : D6 03 91 call next_char
744/ 3AD : DC 03 ld R13, #3 ; 4 logische Operatoren
745/ 3AF :
746/ 3AF : oper1: ; tab_op durchsuchen
747/ 3AF : D6 03 B6 call oper2
748/ 3B2 : 6B 0C jr Z, oper3 ; wenn Operator gefunden
749/ 3B4 : DA F9 djnz R13, oper1
750/ 3B6 : ;
751/ 3B6 : CC 17 oper2: ld R12, #17h ; 3 Byte nach 17h kopieren
752/ 3B8 : C3 CA ldci @R12, @RR10 ; R7 := Op
753/ 3BA : C3 CA ldci @R12, @RR10 ; RR8 := Fkt.Adresse
754/ 3BC : C3 CA ldci @R12, @RR10
755/ 3BE : A2 67 cp R6, R7 ; Operator mit Suchwert vergleichen
756/ 3C0 : AF oper3: ret
757/ 3C1 :
758/ 3C1 : ;-----------------------------------------------------------------------------
759/ 3C1 : ; Tabelle Arithmetik-/Logik-Operatoren, s. oper
760/ 3C1 : ;-----------------------------------------------------------------------------
761/ 3C1 :
762/ 3C1 : tab_op:
763/ 3C1 : 2B db '+'
764/ 3C2 : 00 7E dw p_plus ; Y := Y + X
765/ 3C4 : 2D db '-'
766/ 3C5 : 00 85 dw p_minus ; Y := Y - X
767/ 3C7 : 2A db '*'
768/ 3C8 : 00 BA dw p_mult ; Y := Y * X
769/ 3CA : 2F db '/'
770/ 3CB : 00 E0 dw p_div ; Y := Y / X
771/ 3CD : ; $-Operatoren (mit vorausgehendem '$')
772/ 3CD : 41 db 'A'
773/ 3CE : 01 2F dw p_and ; Y := Y AND X
774/ 3D0 : 4F db 'O'
775/ 3D1 : 01 2A dw p_or ; Y := Y OR X
776/ 3D3 : 58 db 'X'
777/ 3D4 : 01 34 dw p_xor ; Y := Y XOR X
778/ 3D6 : 4D db 'M'
779/ 3D7 : 01 1F dw p_mod ; Y := Y MOD X
780/ 3D9 :
781/ 3D9 :
782/ 3D9 : ;-----------------------------------------------------------------------------
783/ 3D9 : ; Zeichenklassentests
784/ 3D9 : ;-----------------------------------------------------------------------------
785/ 3D9 :
786/ 3D9 : ;in: @R15 out: cy=1 bei Buchstaben A..Z
787/ 3D9 : A7 EF 41 is_letter: cp @R15, #41h ; 'A'
788/ 3DC : 7B 12 jr C, is_notf
789/ 3DE : A7 EF 5B cp @R15, #5Bh ; 'Z'+1
790/ 3E1 : AF ret
791/ 3E2 :
792/ 3E2 : ;in: @R15 out: cy=1 bei Buchstaben A..Z oder Zahl 0..9
793/ 3E2 : D6 03 D9 is_char: call is_letter
794/ 3E5 : 7B 08 jr C, is_digit_ret
795/ 3E7 :
796/ 3E7 : ;in: @R15 out: cy=1 bei Zahl 0..9
797/ 3E7 : A7 EF 30 is_digit: cp @R15, #30h ; '0'
798/ 3EA : 7B 04 jr C, is_notf
799/ 3EC : A7 EF 3A cp @R15, #3Ah ; '9'+1
800/ 3EF : AF is_digit_ret: ret
801/ 3F0 :
802/ 3F0 : ;
803/ 3F0 : CF is_notf: rcf ; Cy=0
804/ 3F1 : AF ret
805/ 3F2 :
806/ 3F2 : ;in: @R15 out: cy=1 bei Zahl 0..F
807/ 3F2 : D6 03 E7 is_hexdigit: call is_digit
808/ 3F5 : 7B F8 jr C, is_digit_ret
809/ 3F7 : A7 EF 41 cp @R15, #41h ; 'A'
810/ 3FA : 7B F4 jr C, is_notf
811/ 3FC : A7 EF 47 cp @R15, #47h ; 'F'+1
812/ 3FF : AF ret
813/ 400 :
814/ 400 : ;-----------------------------------------------------------------------------
815/ 400 : ; Prozedurnamen in Proc-Tabelle suchen
816/ 400 : ; ret: Cy=gefunden, RR8=Proc-Adresse
817/ 400 : ;-----------------------------------------------------------------------------
818/ 400 : ; Aubau Tabelle: je 1 Byte Namenslänge
819/ 400 : ; Procedurenamen
820/ 400 : ; 2 Byte Adresse
821/ 400 : ; Ende mit Namenslänge = FFh
822/ 400 : ;-----------------------------------------------------------------------------
823/ 400 :
824/ 400 : ; zu func1
825/ 400 : find_name: ; Suche in interner Tabelle
826/ 400 : 2C 03 ld R2, #HI(tab_prc)
827/ 402 : 3C 28 ld R3, #LO(tab_prc)
828/ 404 : D6 04 12 call find_name1
829/ 407 : 7B 15 jr C, find_name4 ; Ende wenn gefunden
830/ 409 : ; Suche in externer Tabelle
831/ 409 : B0 E2 clr R2
832/ 40B : 44 08 E2 or R2, reg_08 ; HI ext. Proc-Table
833/ 40E : 6B 0D jr Z, find_name3 ; wenn 0 (= nicht vorhanden)
834/ 410 : 38 09 ld R3, reg_09 ; LO ext. Proc-Table
835/ 412 : ;
836/ 412 : 48 E0 find_name1: ld R4, R0 ; akt. Position Basicprogramm
837/ 414 : 58 E1 ld R5, R1 ; d.h. Procedur-Name
838/ 416 : C2 82 find_name2: ldc R8, @RR2 ; Länge Procedurname
839/ 418 : A6 E8 FF cp R8, #0FFh ; tap_prc-Ende ?
840/ 41B : EB 02 jr NZ, comp_name
841/ 41D : CF find_name3: rcf
842/ 41E : AF find_name4: ret
843/ 41F :
844/ 41F : ; Namensvergleich
845/ 41F : A0 E2 comp_name: incw RR2 ; auf nächstes Zeichen Procedur-Name
846/ 421 : C2 72 ldc R7, @RR2 ; Zeichen nach R7 f. Vergleich
847/ 423 : D6 03 91 call next_char ; gesuchte Procedur nächstes Zeichen
848/ 426 : EB 14 jr NZ, comp_name2 ; passt nicht -> nächsten Prozedurnamen vergleichen
849/ 428 : 8A F5 djnz R8, comp_name ; weiter bis alle Zeichen verglichen
850/ 42A : ; Procedur-Name in Tabelle gefunden
851/ 42A : C2 60 ldc R6, @RR0 ; Zeichen an akt. Position Basicprogramm
852/ 42C : D6 03 E2 call is_char ; ist der gesuchte Name länger?
853/ 42F : 7B 0A jr C, comp_name1 ; dann weitersuchen
854/ 431 : A0 E2 incw RR2
855/ 433 : C2 82 ldc R8, @RR2 ; sonst Proceduradresse nach RR8
856/ 435 : A0 E2 incw RR2
857/ 437 : C2 92 ldc R9, @RR2
858/ 439 : DF scf ; Cy=gefunden
859/ 43A : AF ret
860/ 43B : ; nächsten Prozedurnamen vergleichen
861/ 43B : 8E comp_name1: inc R8 ; Restlänge v. Namen + 1
862/ 43C : 8E comp_name2: inc R8 ; + 2 Byte Adresse
863/ 43D : 8E inc R8
864/ 43E : 02 38 add R3, R8 ; zu Pos in Proc-Table addieren
865/ 440 : 16 E2 00 adc R2, #0
866/ 443 : 08 E4 ld R0, R4 ; akt. Position Basicprogramm
867/ 445 : 18 E5 ld R1, R5 ; rücksetzen
868/ 447 : 8B CD jr find_name2 ; weitersuchen
869/ 449 :
870/ 449 : ;-----------------------------------------------------------------------------
871/ 449 : ; Prozedur/Fkt.namen suchen, Eingabeparameter ablegen, Prozedur ausführen
872/ 449 : ;-----------------------------------------------------------------------------
873/ 449 :
874/ 449 : 80 E0 func: decw RR0
875/ 44B :
876/ 44B : ; zu c_PROC3
877/ 44B : D6 04 00 func1: call find_name ; Prozedurnamen suchen
878/ 44E : C2 A0 ldc R10, @RR0 ; Zeichen an akt. Position Basicprogramm
879/ 450 : A6 EA 5B cp R10, #'[' ; folgen Eingabeparameter?
880/ 453 : EB 1A jr NZ, func3 ; nein
881/ 455 : A0 E0 incw RR0
882/ 457 : ; Eingabeparameter evaluieren und auf Stack ablegen
883/ 457 : 70 E8 func2: push R8 ; Proc-Adr. sichern
884/ 459 : 70 E9 push R9
885/ 45B : D6 04 C7 call expr ; Eingabeparameter evaluieren -> RR2
886/ 45E : 50 E9 pop R9 ; Proc-Adr. restaurieren
887/ 460 : 50 E8 pop R8
888/ 462 : 7C 5D ld R7, #']'
889/ 464 : D6 03 91 call next_char
890/ 467 : 6B 06 jr Z, func3 ; wenn Ende Parameterliste
891/ 469 : 70 E3 push R3 ; sonst Wert auf Stack
892/ 46B : 70 E2 push R2
893/ 46D : 8B E8 jr func2 ; und nächsten Parameter
894/ 46F : ; X1..Xn-1 liegen auf Stack, Xn in RR2
895/ 46F : 48 E2 func3: ld R4, R2 ; Y = X setzen
896/ 471 : 58 E3 ld R5, R3
897/ 473 : D4 E8 call @RR8 ; Procedur starten
898/ 475 : 31 10 srp #10h ; zur Sicherheit f. ext. Proceduren
899/ 477 : DF scf ; Cy=Erfolg
900/ 478 : AF ret
901/ 479 :
902/ 479 : ;-----------------------------------------------------------------------------
903/ 479 : ; Ausdruck
904/ 479 : ; Variable, Prozedur[..], Hex-Zahl, Dez-Zahl
905/ 479 : ;-----------------------------------------------------------------------------
906/ 479 :
907/ 479 : D6 03 D9 factor: call is_letter
908/ 47C : FB 17 jr NC, factor1 ; wenn kein Buchstabe A..Z
909/ 47E : C2 70 ldc R7, @RR0
910/ 480 : FE inc R15
911/ 481 : D6 03 E2 call is_char ; folgt Buchstabe oder Zahl?
912/ 484 : 7B C3 jr C, func ; ja, dann Prozedurname
913/ 486 : ; sonst einzelne Variable A..Z
914/ 486 : 26 E6 41 sub R6, #41h ; 'A'
915/ 489 : 90 E6 rl R6 ; *2
916/ 48B : 06 E6 20 add R6, #20h ; Register 20h..53h
917/ 48E : E3 26 ld R2, @R6 ; Wert nach R2/R3 (Y)
918/ 490 : 6E inc R6
919/ 491 : E3 36 ld R3, @R6
920/ 493 : DF scf
921/ 494 : AF ret
922/ 495 :
923/ 495 : A7 EF 3B factor1: cp @R15, #';' ; Statement-Ende
924/ 498 : 6B 19 jr Z, factor3
925/ 49A : A7 EF 0D cp @R15, #0Dh ; CR, Zeilenende
926/ 49D : 6B 14 jr Z, factor3
927/ 49F : FE inc R15
928/ 4A0 : C3 F0 factor2: ldci @R15, @RR0 ; Ablegen in Konvertierungspuffer
929/ 4A2 : 00 EF dec R15
930/ 4A4 : D6 03 F2 call is_hexdigit
931/ 4A7 : FE inc R15
932/ 4A8 : 7B F6 jr C, factor2 ; solange (Hex-)Ziffer 0..F
933/ 4AA : 80 E0 decw RR0
934/ 4AC : D6 01 D9 call number ; Zahl konvertieren
935/ 4AF : 28 E4 ld R2, R4
936/ 4B1 : 38 E5 ld R3, R5
937/ 4B3 : AF factor3: ret
938/ 4B4 :
939/ 4B4 : ;-----------------------------------------------------------------------------
940/ 4B4 : ; geklammerter Ausdruck
941/ 4B4 : ;-----------------------------------------------------------------------------
942/ 4B4 :
943/ 4B4 : 7C 28 term: ld R7, #'(' ; linke Klammer
944/ 4B6 : D6 03 91 call next_char
945/ 4B9 : EB BE jr NZ, factor ; wenn keine Klammer
946/ 4BB : D6 04 C7 call expr ; Ausdruck berechnen
947/ 4BE : FB 06 jr NC, term1
948/ 4C0 : 7C 29 ld R7, #')' ; rechte Klammer
949/ 4C2 : D6 03 91 call next_char
950/ 4C5 : EF ccf
951/ 4C6 : AF term1: ret
952/ 4C7 :
953/ 4C7 : ;-----------------------------------------------------------------------------
954/ 4C7 : ; Ausdruck berechnen von links nach rechts (Kettenrechnen)
955/ 4C7 : ; Rückgabe Wert in RR2
956/ 4C7 : ;-----------------------------------------------------------------------------
957/ 4C7 :
958/ 4C7 : D6 04 B4 expr: call term ; linker Wert
959/ 4CA : FB 09 jr NC, expr2
960/ 4CC : D6 03 91 expr1: call next_char
961/ 4CF : D6 03 9A call oper ; Operator
962/ 4D2 : 6B 04 jr Z, expr3 ; wenn Operator gefunden
963/ 4D4 : DF scf ; sonst Fehler
964/ 4D5 : 80 E0 expr2: decw RR0
965/ 4D7 : AF ret
966/ 4D8 : ;
967/ 4D8 : 70 E8 expr3: push R8 ; RR8 = Op-Fkt.Adresse
968/ 4DA : 70 E9 push R9
969/ 4DC : 70 E2 push R2 ; aktueller linker Wert (Y)
970/ 4DE : 70 E3 push R3
971/ 4E0 : D6 04 B4 call term ; rechter Wert
972/ 4E3 : 48 E2 ld R4, R2 ; nach RR4 (X)
973/ 4E5 : 58 E3 ld R5, R3
974/ 4E7 : 50 E3 pop R3 ; Y restaurieren
975/ 4E9 : 50 E2 pop R2
976/ 4EB : 50 E9 pop R9 ; Adr. restaurieren
977/ 4ED : 50 E8 pop R8
978/ 4EF : D4 E8 call @RR8 ; berechnen
979/ 4F1 : ;
980/ 4F1 : 8B D9 jr expr1 ; weitere Operationen
981/ 4F3 :
982/ 4F3 : ;-----------------------------------------------------------------------------
983/ 4F3 : ; holt Speicheradresse zu Variable A..Z
984/ 4F3 : ; out RR8 = Adr. in Registerspeicher (20h..53h)
985/ 4F3 : ;-----------------------------------------------------------------------------
986/ 4F3 :
987/ 4F3 : D6 03 91 get_var: call next_char
988/ 4F6 : 26 E6 41 sub R6, #'A'
989/ 4F9 : 02 66 add R6, R6
990/ 4FB : 8C 20 ld R8, #20h ; Register 20h..53h
991/ 4FD : 02 86 add R8, R6
992/ 4FF : AF ret
993/ 500 :
994/ 500 : ;-----------------------------------------------------------------------------
995/ 500 : ; Zeilennummer ermitteln
996/ 500 : ; ret: RR4 = zeilennummer, RR0 = Zeilenanfang; Cy=1 Programmanfang
997/ 500 : ;-----------------------------------------------------------------------------
998/ 500 :
999/ 500 : ; UP zu GOTO
1000/ 500 : linum: ;auf Zeilenanfang
1001/ 500 : C2 40 ldc R4, @RR0
1002/ 502 : 80 E0 decw RR0 ; aktuelle Zeile rückwärts
1003/ 504 : 76 E4 80 tm R4, #80h ; Bit7 gesetzt?
1004/ 507 : 6B F7 jr Z, linum ; rückwärts bis Zeilenanfang
1005/ 509 : A0 E0 incw RR0
1006/ 50B : ;Programmanfang erreicht?
1007/ 50B : 56 E4 7F and R4, #7Fh ; strip hi bit
1008/ 50E : A4 06 E0 cp R0, reg_06 ; Vergleich Adr. mit Programmanfang
1009/ 511 : EB 06 jr NZ, linum1 ;
1010/ 513 : A4 07 E1 cp R1, reg_07
1011/ 516 : DF scf
1012/ 517 : 6B 0F jr Z, linum2 ; Programmanfang erreicht
1013/ 519 : ;
1014/ 519 : linum1: ;steht vor gesetztem hi-bit ein CR? dann Zeilenanfang gefunden
1015/ 519 : 80 E0 decw RR0
1016/ 51B : C2 50 ldc R5, @RR0
1017/ 51D : A0 E0 incw RR0
1018/ 51F : A6 E5 0D cp R5, #0Dh ; CR, Suche Zeilenende
1019/ 522 : 6B 04 jr Z, linum2 ; ja, Zeilenanfang gefunden
1020/ 524 : 80 E0 decw RR0
1021/ 526 : 8B D8 jr linum ; sonst weitersuchen
1022/ 528 : ;
1023/ 528 : A0 E0 linum2: incw RR0
1024/ 52A : C2 50 ldc R5, @RR0 ; RR4=Zeilennummer
1025/ 52C : 80 E0 decw RR0
1026/ 52E : AF ret
1027/ 52F :
1028/ 52F : ;-----------------------------------------------------------------------------
1029/ 52F : ; Ausgabe "text"
1030/ 52F : ;-----------------------------------------------------------------------------
1031/ 52F :
1032/ 52F : 7C 22 prnstr: ld R7, #'"'
1033/ 531 : D6 03 91 call next_char
1034/ 534 : EB 0C jr NZ, prnstr2 ; kein Quote -> Abbruch
1035/ 536 : D6 03 91 prnstr1: call next_char ; nächstes Zeichen
1036/ 539 : 6B 09 jr Z, prnstr3 ; Ende beim abschließenden Quote
1037/ 53B : 58 E6 ld R5, R6 ; nach R5
1038/ 53D : D6 08 18 call putch ; mit PUT_CHAR ausgeben
1039/ 540 : 8B F4 jr prnstr1
1040/ 542 : ;
1041/ 542 : 80 E0 prnstr2: decw RR0 ; Pointer zurückstellen
1042/ 544 : AF prnstr3: ret
1043/ 545 :
1044/ 545 :
1045/ 545 : ;-----------------------------------------------------------------------------
1046/ 545 : ; logischer Ausdruck
1047/ 545 : ; expr. relop expr., ret NZ wenn true, Z wenn false
1048/ 545 : ;-----------------------------------------------------------------------------
1049/ 545 :
1050/ 545 : D6 04 C7 relop: call expr ; linker wert
1051/ 548 : B0 EA clr R10
1052/ 54A : 9C 02 ld R9, #2 ; max 2 Zeichen
1053/ 54C : 8C 10 relop1: ld R8, #10h
1054/ 54E : C2 60 ldc R6, @RR0
1055/ 550 : A6 E6 3C cp R6, #'<'
1056/ 553 : 6B 0E jr Z, relop2 ; < R8=10
1057/ 555 : 90 E8 rl R8
1058/ 557 : A6 E6 3E cp R6, #'>'
1059/ 55A : 6B 07 jr Z, relop2 ; > R8=20
1060/ 55C : 90 E8 rl R8
1061/ 55E : A6 E6 3D cp R6, #'='
1062/ 561 : EB 06 jr NZ, relop3 ; = R8=40
1063/ 563 : 42 A8 relop2: or R10, R8 ; <= R8=50, >= R8=60
1064/ 565 : A0 E0 incw RR0
1065/ 567 : 9A E3 djnz R9, relop1
1066/ 569 : ;
1067/ 569 : 70 EA relop3: push R10
1068/ 56B : 70 E2 push R2
1069/ 56D : 70 E3 push R3
1070/ 56F : D6 04 C7 call expr ; rechter Wert
1071/ 572 : 48 E2 ld R4, R2 ; RR4 = rechter Wert
1072/ 574 : 58 E3 ld R5, R3
1073/ 576 : 50 E3 pop R3 ; RR2 = linker Wert
1074/ 578 : 50 E2 pop R2
1075/ 57A : D6 01 41 call relcmp ; Vergleich
1076/ 57D : 50 E8 pop R8
1077/ 57F : 54 0F E8 and R8, reg_0F ; Mit relop verknüpfen
1078/ 582 : AF ret ; Z=1 => relop false
1079/ 583 :
1080/ 583 : ;-----------------------------------------------------------------------------
1081/ 583 : ; REM kommentar
1082/ 583 : ;-----------------------------------------------------------------------------
1083/ 583 :
1084/ 583 : 7C 3B c_REM: ld R7, #';'
1085/ 585 : D6 03 91 c_REM1: call next_char
1086/ 588 : 6B 06 jr Z, c_REM2 ; überlesen bis ;
1087/ 58A : A6 E6 0D cp R6, #0Dh ; CR
1088/ 58D : DF scf
1089/ 58E : EB F5 jr NZ, c_REM1 ; oder Zeilenende
1090/ 590 : 80 E0 c_REM2: decw RR0
1091/ 592 : AF c_REM3: ret
1092/ 593 :
1093/ 593 :
1094/ 593 : ;-----------------------------------------------------------------------------
1095/ 593 : ; Goto, If, Else: Rest bis Zeilenende übergehen
1096/ 593 : ;-----------------------------------------------------------------------------
1097/ 593 :
1098/ 593 : D6 05 83 skip: call c_REM ; Rest übergehen
1099/ 596 : 7B FA jr C, c_REM3 ; Ende bei CR
1100/ 598 : A0 E0 incw RR0 ; sonst auch nächste Anw.
1101/ 59A : 8B F7 jr skip ; übergehen
1102/ 59C :
1103/ 59C : ;-----------------------------------------------------------------------------
1104/ 59C : ; LET variable=ausdruck
1105/ 59C : ;-----------------------------------------------------------------------------
1106/ 59C :
1107/ 59C : D6 04 F3 c_LET: call get_var ; @RR8 = Variablenadr.
1108/ 59F : 70 E8 push R8
1109/ 5A1 : A0 E0 incw RR0
1110/ 5A3 : D6 04 C7 call expr ; RR2 = ausdruck
1111/ 5A6 : 50 E8 pop R8
1112/ 5A8 : F3 82 c_LET1: ld @R8, R2 ; Wert abspeichern
1113/ 5AA : 8E inc R8
1114/ 5AB : F3 83 ld @R8, R3
1115/ 5AD : AF ret
1116/ 5AE :
1117/ 5AE :
1118/ 5AE : ;-----------------------------------------------------------------------------
1119/ 5AE : ; TRAP
1120/ 5AE : ; TRAP bedingung TO ausdruck
1121/ 5AE : ;-----------------------------------------------------------------------------
1122/ 5AE : ; Trap setzen
1123/ 5AE : ; der Rest der Anweisung wird hier übergangen
1124/ 5AE :
1125/ 5AE : 09 04 c_TRAP: ld reg_04, R0 ; RR0 = akt. Pos. in Programm
1126/ 5B0 : 19 05 ld reg_05, R1
1127/ 5B2 : 8B CF c_TRAP1: jr c_REM
1128/ 5B4 :
1129/ 5B4 : ;-----------------------------------------------------------------------------
1130/ 5B4 : ; PROC [variablenliste] = prozedurname [parameterliste]
1131/ 5B4 : ; PROC [Y1,Y2,Y3,..,Ym] = prozedurname [X1,X2,X3,..,Xn]
1132/ 5B4 : ;-----------------------------------------------------------------------------
1133/ 5B4 : ; bei Prozeduraufruf gilt:
1134/ 5B4 : ; Stack SP+2m+2n Ym-1 je 2 Byte Werte
1135/ 5B4 : ; .. Ym-2
1136/ 5B4 : ; .. ..
1137/ 5B4 : ; SP+2n+4 Y2
1138/ 5B4 : ; SP+2n+2 Y1
1139/ 5B4 : ; SP+2n (intern f. interpreter)
1140/ 5B4 : ; SP+2n-2 X1
1141/ 5B4 : ; .. ..
1142/ 5B4 : ; SP+4 Xn-2
1143/ 5B4 : ; SP+2 Xn-1
1144/ 5B4 : ; SP returnadr. zum interpreter
1145/ 5B4 : ; die rechten Parameter Ym, Xn werden in Registern abgelegt
1146/ 5B4 : ; out RR2 = Ym, in RR4 Xm
1147/ 5B4 : ;-----------------------------------------------------------------------------
1148/ 5B4 :
1149/ 5B4 : 70 04 c_PROC: push reg_04 ; aktuelle TRAP sichern
1150/ 5B6 : 70 05 push reg_05
1151/ 5B8 : 09 04 ld reg_04, R0 ; aktuelle Programmposition sichern
1152/ 5BA : 19 05 ld reg_05, R1
1153/ 5BC : ;Ausgabeparameter auf Stack initialisieren
1154/ 5BC : C2 60 ldc R6, @RR0 ; nächstes Zeichen testen
1155/ 5BE : A6 E6 5B cp R6, #'[' ; folgen Ausgabeparameter Y?
1156/ 5C1 : EB 15 jr NZ, c_PROC3 ; nein
1157/ 5C3 : A0 E0 incw RR0
1158/ 5C5 : B0 E8 clr R8 ; 0
1159/ 5C7 : 7C 5D ld R7, #']'
1160/ 5C9 : A0 E0 c_PROC1: incw RR0
1161/ 5CB : D6 03 91 call next_char
1162/ 5CE : 6B 06 jr Z, c_PROC2
1163/ 5D0 : 70 E8 push R8 ; Stackspeicher f. Ausgabeparameter
1164/ 5D2 : 70 E8 push R8 ; belegen (mit Wert 0)
1165/ 5D4 : 8B F3 jr c_PROC1
1166/ 5D6 : A0 E0 c_PROC2: incw RR0
1167/ 5D8 : ;Prozedurnamen suchen, Eingabeparameter evaluieren und ablegen, Prozedur ausführen
1168/ 5D8 : D6 04 4B c_PROC3: call func1
1169/ 5DB : ;Ausgabeparameter von Stack in Variablen schreiben
1170/ 5DB : 08 04 ld R0, reg_04 ; Programmposition auf Anfang setzen
1171/ 5DD : 18 05 ld R1, reg_05
1172/ 5DF : 7C 5B ld R7, #'['
1173/ 5E1 : D6 03 91 call next_char
1174/ 5E4 : EB 18 jr NZ, c_PROC6 ; wenn keine Ausgabeparameter
1175/ 5E6 : 7C 5D ld R7, #']'
1176/ 5E8 : D6 04 F3 c_PROC4: call get_var ; get Variable
1177/ 5EB : D6 03 91 call next_char
1178/ 5EE : 6B 0B jr Z, c_PROC5 ; Ende bei ]
1179/ 5F0 : 50 EA pop R10 ; Parameter
1180/ 5F2 : F3 8A ld @R8, R10 ; in Variable schreiben (Hi)
1181/ 5F4 : 50 EA pop R10
1182/ 5F6 : 8E inc R8
1183/ 5F7 : F3 8A ld @R8, R10 ; Lo
1184/ 5F9 : 8B ED jr c_PROC4 ; nächsten Parameter
1185/ 5FB : D6 05 A8 c_PROC5: call c_LET1
1186/ 5FE : 50 05 c_PROC6: pop reg_05 ; TRAP wiederherstellen
1187/ 600 : 50 04 pop reg_04
1188/ 602 : 8B AE jr c_TRAP1
1189/ 604 :
1190/ 604 : ;-----------------------------------------------------------------------------
1191/ 604 : ; GOTO ausdruck
1192/ 604 : ;-----------------------------------------------------------------------------
1193/ 604 : ; suche passende zeile oder nächstgrößere; bei Programmende -> Ende
1194/ 604 :
1195/ 604 : D6 04 C7 c_GOTO: call expr ; RR2 = ausdruck
1196/ 607 : D6 05 00 call linum ; RR4 = aktuelle Zeilennummer
1197/ 60A : D6 01 41 call relcmp ; vergleichen
1198/ 60D : 76 0F 50 tm reg_0F, #50h ; <=
1199/ 610 : EB 1F jr NZ, c_GOTO3 ; wenn ausdruck <= akt. Zeile
1200/ 612 :
1201/ 612 : c_GOTO1: ; Suche vorwärts
1202/ 612 : D6 05 93 call skip ; Rest bis Zeilenende übergehen
1203/ 615 : A0 E0 incw RR0
1204/ 617 : C2 40 ldc R4, @RR0 ; RR4 = nächste Zeilennummer
1205/ 619 : A0 E0 incw RR0
1206/ 61B : C2 50 ldc R5, @RR0
1207/ 61D : 80 E0 decw RR0
1208/ 61F : 90 E4 rl R4 ; Bit7 nach Cy und Bit0
1209/ 621 : CF rcf ; Cy=0
1210/ 622 : C0 E4 rrc R4 ; Bit7=0, Cy=orig. Bit7
1211/ 624 : FB 08 jr NC, c_GOTO2 ; Programmende erreicht?
1212/ 626 : D6 01 41 call relcmp
1213/ 629 : 76 0F 50 tm reg_0F, #50h ; <=
1214/ 62C : 6B E4 jr Z, c_GOTO1 ; weiter, solange ausdruck <= akt. Zeile
1215/ 62E : c_GOTO2: ; Programmende erreicht
1216/ 62E : 80 E0 decw RR0
1217/ 630 : AF ret
1218/ 631 :
1219/ 631 : D6 05 00 c_GOTO3: call linum ; RR4 = aktuelle Zeilennummer
1220/ 634 : FB 07 jr NC, c_GOTO4 ; solange
1221/ 636 :
1222/ 636 : ; Wenn Zeile gefunden
1223/ 636 : A0 FE incw gpr ; Stackpointer
1224/ 638 : A0 FE incw gpr ; Stackpointer
1225/ 63A : 8D 07 3E jp run2 ; Zeile abarbeiten
1226/ 63D :
1227/ 63D : c_GOTO4: ; suche Rückwärts
1228/ 63D : D6 01 41 call relcmp
1229/ 640 : 76 0F 60 tm reg_0F, #60h ; >=
1230/ 643 : EB E9 jr NZ, c_GOTO2
1231/ 645 : 80 E0 decw RR0 ; ein Zeichen zurück
1232/ 647 : 8B E8 jr c_GOTO3 ; weitersuchen
1233/ 649 :
1234/ 649 : ;-----------------------------------------------------------------------------
1235/ 649 : ; IF bedingung THEN anweisungen
1236/ 649 : ;-----------------------------------------------------------------------------
1237/ 649 :
1238/ 649 : 56 0F FE c_IF: and reg_0F, #0FEh ; Bit0 = 0
1239/ 64C : D6 05 45 call relop ; bedingung auswerten
1240/ 64F : EB 05 jr NZ, c_IF1 ; Bedinung erfüllt
1241/ 651 : ; -> nächste Anweisung abarbeiten (nach ;)
1242/ 651 : 20 0F inc reg_0F ; Bit0 = 1 ( -> ELSE)
1243/ 653 : 8D 05 93 jp skip ; Rest bis Zeilenende übergehen
1244/ 656 : AF c_IF1: ret
1245/ 657 :
1246/ 657 : ;-----------------------------------------------------------------------------
1247/ 657 : ; ELSE anweisungen
1248/ 657 : ;-----------------------------------------------------------------------------
1249/ 657 :
1250/ 657 : 76 0F 01 c_ELSE: tm reg_0F, #1 ; ELSE aktiv?
1251/ 65A : 6D 05 93 jp Z, skip ; nein, Rest bis Zeilenende übergehen
1252/ 65D : 56 0F FE and reg_0F, #0FEh ; Bit0 = 0 (kein ELSE aktiv)
1253/ 660 : AF ret
1254/ 661 :
1255/ 661 : ;-----------------------------------------------------------------------------
1256/ 661 : ; RETURN
1257/ 661 : ;-----------------------------------------------------------------------------
1258/ 661 :
1259/ 661 : A6 0E 00 c_RETURN: cp reg_0E, #0 ; Verschachtelungstiefe 0?
1260/ 664 : EB 06 jr NZ, c_RETURN2 ; nein
1261/ 666 : 46 0E 20 or reg_0E, #20h ; Bit5 = 1
1262/ 669 : 8D 01 1B c_RETURN1: jp p_div6 ; reg_0F Bit7=1
1263/ 66C : ;
1264/ 66C : 00 0E c_RETURN2: dec reg_0E ; Verschachtelungstiefe verringern
1265/ 66E : 50 E6 pop R6 ; Return-Adr.
1266/ 670 : 50 E7 pop R7
1267/ 672 : 50 E0 pop R0 ; RR0= Pos. nach GOSUB
1268/ 674 : 50 E1 pop R1
1269/ 676 : 56 0F FE and reg_0F, #0FEh ; Bit0 = 0 (kein ELSE aktiv)
1270/ 679 : 30 E6 jp @RR6 ; return
1271/ 67B :
1272/ 67B : ;-----------------------------------------------------------------------------
1273/ 67B : ; GOSUB ausdruck
1274/ 67B : ;-----------------------------------------------------------------------------
1275/ 67B :
1276/ 67B : 88 E0 c_GOSUB: ld R8, R0 ; aktuelle Position
1277/ 67D : 98 E1 ld R9, R1 ; sichern
1278/ 67F : D6 05 83 call c_REM ; RR0=Kommandoende
1279/ 682 : 50 EA pop R10 ; Return-Adresse vom Stack
1280/ 684 : 50 EB pop R11
1281/ 686 : 70 E1 push R1 ; Pos. nach GOSUB
1282/ 688 : 70 E0 push R0 ; auf Stack
1283/ 68A : 70 EB push R11 ; Return-Adresse restaurieren
1284/ 68C : 70 EA push R10
1285/ 68E : 08 E8 ld R0, R8 ; orig. Position
1286/ 690 : 18 E9 ld R1, R9 ; rückschreiben
1287/ 692 : 20 0E c_GOSUB1: inc reg_0E ; Verschachtelungstiefe erhöhen
1288/ 694 : 76 0E 10 tm reg_0E, #10h ; > 15 ?
1289/ 697 : 6D 06 04 jp Z, c_GOTO ; nein, UP aufrufen
1290/ 69A : ; max Verschachtelungstiefe erreicht
1291/ 69A : D6 05 83 call c_REM ; bis Kommandoende überlesen
1292/ 69D : 8B CA jr c_RETURN1 ; und Verschachtelungstiefe verringern
1293/ 69F :
1294/ 69F : ;-----------------------------------------------------------------------------
1295/ 69F : ; WAIT ausdruck
1296/ 69F : ; Schleifendauer 1 ms bei 8 MHz Taktfrequenz
1297/ 69F : ;-----------------------------------------------------------------------------
1298/ 69F :
1299/ 69F : D6 04 C7 c_WAIT: call expr ; RR2 = ausdruck
1300/ 6A2 : 68 E2 ld R6, R2
1301/ 6A4 : 42 63 or R6, R3 ; = 0?
1302/ 6A6 : 6B 10 jr Z, c_WAIT3 ; dann kein Wait
1303/ 6A8 : 40 E6 c_WAIT1: da R6
1304/ 6AA : 6C 00 ld R6, #0
1305/ 6AC : 7C B4 ld R7, #0B4h
1306/ 6AE : 80 E6 c_WAIT2: decw RR6
1307/ 6B0 : ED 06 AE jp NZ, c_WAIT2
1308/ 6B3 : 80 E2 decw RR2
1309/ 6B5 : ED 06 A8 jp NZ, c_WAIT1
1310/ 6B8 : AF c_WAIT3: ret
1311/ 6B9 :
1312/ 6B9 : ;-----------------------------------------------------------------------------
1313/ 6B9 : ; CALL ausdruck
1314/ 6B9 : ;-----------------------------------------------------------------------------
1315/ 6B9 :
1316/ 6B9 : D6 04 C7 c_CALL: call expr ; RR2 = ausdruck
1317/ 6BC : D4 E2 call @RR2 ; UP aufrufen (berechnete Adr.)
1318/ 6BE : 31 10 srp #10h ; RP auf Standard
1319/ 6C0 : AF ret
1320/ 6C1 :
1321/ 6C1 : ;-----------------------------------------------------------------------------
1322/ 6C1 : ; STOP
1323/ 6C1 : ;-----------------------------------------------------------------------------
1324/ 6C1 :
1325/ 6C1 : 46 0F 08 c_STOP: or reg_0F, #8 ; Bit3 = 1
1326/ 6C4 : AF ret
1327/ 6C5 :
1328/ 6C5 : ;-----------------------------------------------------------------------------
1329/ 6C5 : ; END
1330/ 6C5 : ;-----------------------------------------------------------------------------
1331/ 6C5 :
1332/ 6C5 : 46 0F 02 c_END: or reg_0F, #2 ; Bit1 = 1
1333/ 6C8 : AF ret
1334/ 6C9 :
1335/ 6C9 : ;-----------------------------------------------------------------------------
1336/ 6C9 : ; CLRTRP
1337/ 6C9 : ;-----------------------------------------------------------------------------
1338/ 6C9 :
1339/ 6C9 : B0 04 c_CLRTRAP: clr reg_04 ; Trap auf 0 setzen
1340/ 6CB : B0 05 clr reg_05
1341/ 6CD : AF ret
1342/ 6CE :
1343/ 6CE : ;-----------------------------------------------------------------------------
1344/ 6CE : ; PRINTHEX "text" ausdruck
1345/ 6CE : ;-----------------------------------------------------------------------------
1346/ 6CE :
1347/ 6CE : D6 05 2F c_PRINTHEX: call prnstr ; Ausgabe text
1348/ 6D1 : D6 04 C7 call expr ; Ausdruck berechnen
1349/ 6D4 : FB 22 jr NC, c_PRINT3 ; bei Fehler o. ohne Ausdruck
1350/ 6D6 : D6 01 5E call tohex ; Konvertierung nach Hex-String
1351/ 6D9 : ; In Buffer ab #14h
1352/ 6D9 : AC 05 ld R10, #5 ; 5 Stellen
1353/ 6DB : 8B 0D jr c_PRINT1
1354/ 6DD :
1355/ 6DD : ;-----------------------------------------------------------------------------
1356/ 6DD : ; PRINT "text" ausdruck
1357/ 6DD : ;-----------------------------------------------------------------------------
1358/ 6DD :
1359/ 6DD : D6 05 2F c_PRINT: call prnstr ; Ausgabe text
1360/ 6E0 : D6 04 C7 call expr ; Ausdruck berechnen
1361/ 6E3 : FB 13 jr NC, c_PRINT3 ; bei Fehler o. ohne Ausdruck keine Ausgabe
1362/ 6E5 : ; Ausdruck anzeigen
1363/ 6E5 : D6 01 82 call todez ; Konvertierung nach dezimal
1364/ 6E8 : AC 06 ld R10, #6 ; 6 Stellen
1365/ 6EA : BC 14 c_PRINT1: ld R11, #14h ; Konvertierungspuffer
1366/ 6EC : 70 E5 c_PRINT2: push R5
1367/ 6EE : E3 5B ld R5, @R11
1368/ 6F0 : BE inc R11
1369/ 6F1 : D6 08 18 call putch ; Stelle ausgeben
1370/ 6F4 : 50 E5 pop R5
1371/ 6F6 : AA F4 djnz R10, c_PRINT2
1372/ 6F8 : ; Am Ende Zeilenende ausgeben, falls kein Komma
1373/ 6F8 : C2 60 c_PRINT3: ldc R6, @RR0
1374/ 6FA : A6 E6 2C cp R6, #',' ; folgt Komma?
1375/ 6FD : EB 11 jr NZ, c_PRINT5 ; nein -> CR
1376/ 6FF : A0 E0 incw RR0
1377/ 701 : C2 60 ldc R6, @RR0
1378/ 703 : A6 E6 3B cp R6, #';' ; folgt Kdo-Ende?
1379/ 706 : 6B 07 jr Z, c_PRINT4 ; ja -> kein CR ausgeben
1380/ 708 : A6 E6 0D cp R6, #0Dh ; oder folgt Zeilenende CR?
1381/ 70B : 6B 02 jr Z, c_PRINT4 ; dann ebenfalls kein CR ausgeben
1382/ 70D : 80 E0 decw RR0
1383/ 70F : AF c_PRINT4: ret
1384/ 710 : 5C 0D c_PRINT5: ld R5, #0Dh ; CR
1385/ 712 : 8D 08 18 jp putch ; ausgeben (Zeilenende)
1386/ 715 :
1387/ 715 : ;-----------------------------------------------------------------------------
1388/ 715 : ; INPUT "text" variable
1389/ 715 : ;-----------------------------------------------------------------------------
1390/ 715 :
1391/ 715 : D6 05 2F c_INPUT: call prnstr ; Ausgabe text
1392/ 718 : D6 02 E9 call p_input1 ; Abfrage Wert
1393/ 71B : D6 04 F3 call get_var ; Variablenadresse
1394/ 71E : 8D 05 A8 jp c_LET1 ; und Wert zuweisen
1395/ 721 :
1396/ 721 : ;-----------------------------------------------------------------------------
1397/ 721 : ; Einsprung aus BM200 (CONT)
1398/ 721 : ;-----------------------------------------------------------------------------
1399/ 721 :
1400/ 721 : E6 0F 04 cont: ld reg_0F, #4
1401/ 724 : 8B 10 jr run1
1402/ 726 :
1403/ 726 : ;-----------------------------------------------------------------------------
1404/ 726 : ; Einsprung aus BM200 (STEP)
1405/ 726 : ;-----------------------------------------------------------------------------
1406/ 726 :
1407/ 726 : E6 0F 08 step: ld reg_0F, #8
1408/ 729 : 8B 0B jr run1
1409/ 72B :
1410/ 72B : ;-----------------------------------------------------------------------------
1411/ 72B : ; RUN
1412/ 72B : ; in 6,7 = Startadr. Basic-Programm
1413/ 72B : ; 8,9 = Adr. Prozedurtabelle (oder 0)
1414/ 72B : ; srp #10h; call $7fd
1415/ 72B : ;-----------------------------------------------------------------------------
1416/ 72B :
1417/ 72B : ; Programmstart
1418/ 72B : B0 0F run: clr reg_0F
1419/ 72D : B0 0E clr reg_0E
1420/ 72F : 08 06 ld R0, reg_06 ; RR0 = Startadr. Basic-Programm
1421/ 731 : 18 07 ld R1, reg_07
1422/ 733 : D6 06 C9 call c_CLRTRAP ; clear trap
1423/ 736 : ;
1424/ 736 : 31 10 run1: srp #10h ; Standard setzen
1425/ 738 : 50 0A pop reg_0A ; Return-Adresse f. END
1426/ 73A : 50 0B pop reg_0B
1427/ 73C : 8B 0A jr run3
1428/ 73E :
1429/ 73E : ; nächste Zeile abarbeiten
1430/ 73E : 76 0F 0A run2: tm reg_0F, #0Ah
1431/ 741 : EB 0A jr NZ, run4 ; END
1432/ 743 : 66 0F 84 tcm reg_0F, #84h ;-7Ch
1433/ 746 : 6B 05 jr Z, run4 ; END
1434/ 748 :
1435/ 748 : C2 60 run3: ldc R6, @RR0 ; R6=Hi(Zeilennummer)+$80
1436/ 74A : 6E inc R6
1437/ 74B : 6A 02 djnz R6, run5
1438/ 74D : ;END
1439/ 74D : 30 0A run4: jp @reg_0A ; END bei Zeilenummer > 7Fxxh (32512)
1440/ 74F :
1441/ 74F : ;
1442/ 74F : A4 E0 06 run5: cp reg_06, R0
1443/ 752 : EB 05 jr NZ, run6
1444/ 754 : A4 E1 07 cp reg_07, R1
1445/ 757 : 6B 2C jr Z, run8
1446/ 759 : ; Test auf TRAP
1447/ 759 : 68 04 run6: ld R6, reg_04 ; TRAP
1448/ 75B : 44 05 E6 or R6, reg_05
1449/ 75E : 6B 25 jr Z, run8 ; =0? kein TRAP
1450/ 760 : ; TRAP
1451/ 760 : 70 E1 push R1 ; akt. Pogrammpos. sichern
1452/ 762 : 70 E0 push R0
1453/ 764 : 08 04 ld R0, reg_04 ; auf TRAP-Adr. setzen
1454/ 766 : 18 05 ld R1, reg_05
1455/ 768 : D6 05 45 call relop ; logischen Ausdruck auswerten
1456/ 76B : 6B 14 jr Z, run7 ; wenn nicht erfüllt
1457/ 76D : ; wenn erfüllt
1458/ 76D : D6 06 C9 call c_CLRTRAP ; TRAP zurücksetzen
1459/ 770 : 50 E6 pop R6 ; aktuelle Return-Adr
1460/ 772 : 50 E7 pop R7
1461/ 774 : 80 E6 decw RR6 ; vermindern
1462/ 776 : 70 E7 push R7
1463/ 778 : 70 E6 push R6
1464/ 77A : A0 E0 incw RR0 ; akt. Pogrammpos. (TRAP) erhöhen
1465/ 77C : D6 06 92 call c_GOSUB1 ; TRAP ausführen
1466/ 77F : 8B 38 jr run14
1467/ 781 :
1468/ 781 : ; Zeile abarbeiten
1469/ 781 : 50 E0 run7: pop R0
1470/ 783 : 50 E1 pop R1
1471/ 785 : A0 E0 run8: incw RR0 ; Zeilennummer übergehen
1472/ 787 : A0 E0 incw RR0
1473/ 789 : C2 30 run9: ldc R3, @RR0 ; erstes Zeichen (Kommando)
1474/ 78B : A0 E0 incw RR0
1475/ 78D : A6 E3 3E cp R3, #'>' ; ELSE?
1476/ 790 : 6B 03 jr Z, run10 ; dann ELSE-Flag beibehalten
1477/ 792 : 56 0F FE and reg_0F, #0FEh ; sonst ELSE-Flag rücksetzen (Bit0)
1478/ 795 : 6C 07 run10: ld R6, #HI(tab_kdo) ; Liste der Kommandos
1479/ 797 : 7C C8 ld R7, #LO(tab_kdo)
1480/ 799 : B0 E2 clr R2 ; R2=0
1481/ 79B : C2 86 run11: ldc R8, @RR6
1482/ 79D : A2 83 cp R8, R3 ; Kommando in Liste suchen
1483/ 79F : 6B 05 jr Z, run12 ; wenn gefunden
1484/ 7A1 : A0 E6 incw RR6
1485/ 7A3 : 2E inc R2
1486/ 7A4 : 8B F5 jr run11
1487/ 7A6 :
1488/ 7A6 : 02 22 run12: add R2, R2
1489/ 7A8 : 6C 07 ld R6, #HI(tab_kdo2) ; Adressliste der Kommandos
1490/ 7AA : 7C D9 ld R7, #LO(tab_kdo2)
1491/ 7AC : 02 72 add R7, R2
1492/ 7AE : 16 E6 00 adc R6, #0
1493/ 7B1 : 2C 0C ld R2, #0Ch
1494/ 7B3 : C3 26 ldci @R2, @RR6 ; Adresse nach reg_0ch
1495/ 7B5 : C3 26 ldci @R2, @RR6
1496/ 7B7 : D4 0C run13: call @reg_0C ; Kommando aufrufen
1497/ 7B9 : ;
1498/ 7B9 : 7C 0D run14: ld R7, #0Dh ; CR Zeilenende?
1499/ 7BB : D6 03 91 call next_char
1500/ 7BE : 6D 07 3E jp Z, run2 ; dann nächste Zeile
1501/ 7C1 : A6 E6 3B cp R6, #';' ; Kommandoende?
1502/ 7C4 : 6B C3 jr Z, run9 ; dann nächstes Kommando in Zeile
1503/ 7C6 : ;
1504/ 7C6 : 8B EF jr run13 ; sonst Wiederholung aktuelles Kdo
1505/ 7C8 :
1506/ 7C8 : ;-----------------------------------------------------------------------------
1507/ 7C8 : ; Tabelle der BASIC-Kommandos
1508/ 7C8 : ;-----------------------------------------------------------------------------
1509/ 7C8 :
1510/ 7C8 : 4C tab_kdo: db 'L' ; LET
1511/ 7C9 : 4F db 'O' ; PROC
1512/ 7CA : 47 db 'G' ; GOTO
1513/ 7CB : 46 db 'F' ; IF..THEN F..;
1514/ 7CC : 3E db '>' ; ELSE >;
1515/ 7CD : 52 db 'R' ; RETURN
1516/ 7CE : 53 db 'S' ; GOSUB
1517/ 7CF : 57 db 'W' ; WAIT
1518/ 7D0 : 4D db 'M' ; REM
1519/ 7D1 : 43 db 'C' ; CALL
1520/ 7D2 : 54 db 'T' ; STOP
1521/ 7D3 : 45 db 'E' ; END
1522/ 7D4 : 21 db '!' ; TRAP..TO !..,
1523/ 7D5 : 2F db '/' ; CLRTRAP
1524/ 7D6 : 50 db 'P' ; PRINT
1525/ 7D7 : 48 db 'H' ; PRINTHEX
1526/ 7D8 : 49 db 'I' ; INPUT
1527/ 7D9 :
1528/ 7D9 : 05 9C tab_kdo2: dw c_LET
1529/ 7DB : 05 B4 dw c_PROC
1530/ 7DD : 06 04 dw c_GOTO
1531/ 7DF : 06 49 dw c_IF
1532/ 7E1 : 06 57 dw c_ELSE
1533/ 7E3 : 06 61 dw c_RETURN
1534/ 7E5 : 06 7B dw c_GOSUB
1535/ 7E7 : 06 9F dw c_WAIT
1536/ 7E9 : 05 83 dw c_REM
1537/ 7EB : 06 B9 dw c_CALL
1538/ 7ED : 06 C1 dw c_STOP
1539/ 7EF : 06 C5 dw c_END
1540/ 7F1 : 05 AE dw c_TRAP
1541/ 7F3 : 06 C9 dw c_CLRTRAP
1542/ 7F5 : 06 DD dw c_PRINT
1543/ 7F7 : 06 CE dw c_PRINTHEX
1544/ 7F9 : 07 15 dw c_INPUT
1545/ 7FB :
1546/ 7FB : ;-----------------------------------------------------------------------------
1547/ 7FB : ;
1548/ 7FB : ;-----------------------------------------------------------------------------
1549/ 7FB :
1550/ 7FB : FF db 0FFh
1551/ 7FC : FF db 0FFh
1552/ 7FD :
1553/ 7FD : ; Eintrittspunkt BASIC-Interpreter
1554/ 7FD : ;RUN
1555/ 7FD : 8D 07 2B jp run
1556/ 800 :
1557/ 800 : ; end of 'ROM'
1558/ 800 :
1559/ 800 : end