-
Notifications
You must be signed in to change notification settings - Fork 5
/
BASIC1.1.disasm
13905 lines (11997 loc) · 456 KB
/
BASIC1.1.disasm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;;***Main.asm
;#dialect=RASM
;Current progress:
;(Mostly) fully reverse engineered as far as **TK
;'Unassembled'[1] Amstrad CPC6128 BASIC 1.1 Source Code
;[1] 'Unassembled' meaning that this code can be modified and reassembled.
;(As far as I can tell) all links etc have been converted to labels etc in
;such a way that the code can be assembled at a different target address
;and still function correctly (excepting code which must run at a specific
;address).
;Based on the riginal commented disassembly at:
; http://cpctech.cpc-live.com/docs/basic.asm
;There are two versions of this file: a single monolithic version and
;one which has been broken out into separate 'includes'. The latter may
;prove better for modification, assembly and re-use. The former for
;exploration and reverse engineering.
;For more details see: https://github.com/Bread80/Amstrad-CPC-BASIC-Source
;and http://Bread80.com
;;***Initialisation.asm
;;=======
;;BASIC 1.1
c000
;ROM header
defb $80 ;; foreground rom
defb $01 ;mark
defb $02 ;version
defb $00 ;modification
defw $c040 ;; name table
;On entry
;DE = first byte of available memory
;HL=last byte of memory not used by BASIC
;BC=last byte of memory not used by firmware
c006 3100c0 ld sp,$c000 ;##LIT##
c009 cdcbbc call $bccb ; firmware function: kl rom walk
c00c cd3ff5 call $f53f
c00f da0000 jp c,$0000 ;; reboot if not enough memory
c012 af xor a
c013 3200ac ld ($ac00),a
c016 2133c0 ld hl,$c033 ; startup message "BASIC 1.1"
c019 cd7dc3 call $c37d
c01c cdaade call $deaa
c01f cd37cb call $cb37
c022 cdbbbd call $bdbb ; maths function - initialise random number generator?
c025 cddec0 call $c0de
c028 cd45c1 call $c145
c02b 11f000 ld de,$00f0 ; DE = 240
c02e cde9f7 call $f7e9 ; symbol after 240
c031 1825 jr $c058
;;= version string message
c033 defb " BASIC 1.1",10,10,0
;;=rsx name table
c040 defb "BASI","C"+$80 ;; |BASIC
c045 defb 0 ;end of rsx name table
;;***ProgramEntry.asm
;;<< PROGRAM ENTRY ROUTINES
;;< REPL loop, EDIT, AUTO, NEW, CLEAR (INPUT)
;;========================================================================
;; command EDIT
;EDIT <line number>
;Edit the given line number
c046 cd48cf call $cf48
c049 c0 ret nz
c04a 3100c0 ld sp,$c000 ;##LIT##
c04d cd5ce8 call $e85c
c050 cd54e2 call $e254 ;convert line to string (detokenise)
c053 cd01cb call $cb01 ; edit
c056 385f jr c,$c0b7 ; (+$5f)
;;========================================
;;REPL Read Eval Print Loop
;;REPL = Read, Evaluate, Print, Loop
;;This is the command line!
c058 3100c0 ld sp,$c000 ;##LIT##
c05b cd66c1 call $c166
c05e cdb5de call $deb5
c061 dcb6bc call c,$bcb6 ; firmware function: sound hold
c064 cdd0c4 call $c4d0 ; ON BREAK CONT
c067 cdd0c3 call $c3d0
c06a 3a2cae ld a,($ae2c) ; program protection flag
;; do a new
c06d b7 or a
c06e c445c1 call nz,$c145
c071 3a90ad ld a,($ad90) ;; error number
c074 d602 sub $02
c076 2009 jr nz,$c081 ; (+$09)
c078 3290ad ld ($ad90),a
c07b cdaacb call $cbaa
c07e eb ex de,hl
c07f 38c9 jr c,$c04a ; (-$37)
;;=display ready message
c081 21d7c0 ld hl,$c0d7 ; "Ready" message
c084 cd8bc3 call $c38b ;; display 0 terminated string
;;-----------------------------------------------------------------
;;=REPL input loop
c087 cdaade call $deaa
c08a 3a01ac ld a,($ac01) ; AUTO active?
c08d b7 or a
c08e 281f jr z,$c0af ; (+$1f)
;;next AUTO line number
c090 cd0dc1 call $c10d
c093 30c3 jr nc,$c058 ; (-$3d)
c095 cd4dde call $de4d ; skip space, lf or tab
c098 cdcfee call $eecf
c09b 300a jr nc,$c0a7
c09d cd4dde call $de4d ; skip space, lf or tab
c0a0 b7 or a
c0a1 37 scf
c0a2 cc64e8 call z,$e864
c0a5 30e3 jr nc,$c08a ; (-$1d)
;;=REPL no line number
c0a7 d4dec0 call nc,$c0de
c0aa 218aac ld hl,$ac8a
c0ad 1808 jr $c0b7 ; (+$08)
;;-----------------------------------------------------------------
;;=REPL get input
c0af cdf9ca call $caf9 ; edit
c0b2 30fb jr nc,$c0af ; (-$05)
c0b4 cd98c3 call $c398 ;; new text line
;;=REPL execute or insert in program
c0b7 cd4dde call $de4d ; skip space, lf or tab
c0ba b7 or a
c0bb 28ca jr z,$c087 ; (-$36) empty buffer - loop
c0bd cdcfee call $eecf
c0c0 300b jr nc,$c0cd ; (+$0b) no line number so execute
c0c2 cd4dfb call $fb4d
c0c5 cda5e7 call $e7a5
c0c8 cd8fc1 call $c18f
c0cb 18ba jr $c087 ; (-$46)
;;+-----------------------------------------------------------------
;;REPL tokenise and execute
c0cd cda4df call $dfa4
c0d0 cdd3c4 call $c4d3 ; ON BREAK STOP
c0d3 2b dec hl
c0d4 c360de jp $de60
;;========================================================================
;; ready message
c0d7 defb "Ready",10,0
;;========================================================================
;; cancel AUTO mode
c0de af xor a
c0df 1805 jr $c0e6 ; (+$05)
;;+------------------
;; set AUTO mode
c0e1 2202ac ld ($ac02),hl ;current auto mode
c0e4 3eff ld a,$ff ;auto mode active
;;=set auto mode
;A=ff=active, A=0=inactive
c0e6 3201ac ld ($ac01),a ;current auto mode
c0e9 c9 ret
;;==================================================================
;; command AUTO
;AUTO [<line number>],[<increment>]
;Generate line numbers. Values default to 10
c0ea 110a00 ld de,$000a ; default line number is 10
c0ed 2802 jr z,$c0f1 ;no parameters
c0ef fe2c cp $2c ; ',' no first parameter
c0f1 c448cf call nz,$cf48 ;read initial line number, if given
c0f4 d5 push de
c0f5 110a00 ld de,$000a ; default increment is 10
c0f8 cd41de call $de41
c0fb dc48cf call c,$cf48 ; read increment if given
c0fe cd37de call $de37
c101 eb ex de,hl
c102 2204ac ld ($ac04),hl ;AUTO increment step
c105 e1 pop hl
c106 cde1c0 call $c0e1 ;store line number to create or edit
c109 c1 pop bc
c10a c387c0 jp $c087
;;=-----------------------------------------------------------------
;;next AUTO line number
c10d 2a02ac ld hl,($ac02)
c110 eb ex de,hl
c111 d5 push de
c112 cd38e2 call $e238
c115 cddec0 call $c0de
c118 cd01cb call $cb01 ; edit
c11b d1 pop de
c11c d0 ret nc
;;========================================================================
c11d e5 push hl
c11e 2a04ac ld hl,($ac04) ;AUTO increment step
c121 19 add hl,de
c122 d4e1c0 call nc,$c0e1
c125 e1 pop hl
c126 37 scf
c127 c9 ret
;;========================================================================
;; command NEW
;NEW
;Completely clears the current contents of memory
c128 c0 ret nz
c129 cd45c1 call $c145
c12c c358c0 jp $c058
;;=============================================================================
;; command CLEAR, CLEAR INPUT
;CLEAR
;Clear all variables and files
c12f fea3 cp $a3 ; token for "INPUT"
c131 280c jr z,$c13f ; CLEAR INPUT
c133 e5 push hl
c134 cd78c1 call $c178
c137 cd5fc1 call $c15f
c13a cd8fc1 call $c18f
c13d e1 pop hl
c13e c9 ret
;;========================================================================
;; CLEAR INPUT
;CLEAR INPUT ??
c13f cd2cde call $de2c ; get next token skipping space
c142 c33dbd jp $bd3d ; firmware function: km flush
;;========================================================================
;; reset basic
;; clear all memory and reset
c145 2a62ae ld hl,($ae62) ;input buffer/start of BASIC memory
c148 eb ex de,hl
c149 2a5eae ld hl,($ae5e) ; HIMEM
c14c cde4ff call $ffe4 ; BC = HL-DE
c14f 62 ld h,d
c150 6b ld l,e
c151 13 inc de
c152 af xor a
c153 77 ld (hl),a
c154 edb0 ldir
c156 322cae ld ($ae2c),a
c159 cdead5 call $d5ea
c15c cd6fc1 call $c16f
;;=close streams and reset angle mode, string stack and fn params
c15f cd00d3 call $d300 ; close input and output streams
;;=reset angle mode, string stack and fn params
c162 af xor a
c163 cd97bd call $bd97 ; maths: set angle mode
;;=reset string stack and fn params
c166 cdccfb call $fbcc ; string catenation
c169 cd20da call $da20
c16c c3a1c1 jp $c1a1
;;-------------------------------------------------------------------
;;=clear program and variables etc
c16f cdc5de call $dec5 ;; TROFF
c172 cddec0 call $c0de
c175 cd89c1 call $c189
;;=reset variable data
c178 c5 push bc
c179 e5 push hl
c17a cd8cf6 call $f68c
c17d cdead5 call $d5ea
c180 cd38d6 call $d638
c183 cd4dea call $ea4d
c186 e1 pop hl
c187 c1 pop bc
c188 c9 ret
;;-----------------------------------------------------------------
;;=reset zone and clear program
c189 cd99f2 call $f299
c18c cd61e7 call $e761 ;; ?
;;-----------------------------------------------------------------
;;=reset exec data
;Appears to be a 'light' reset after running and before editing etc.
c18f cdaccc call $ccac
c192 cd7ecc call $cc7e
c195 cda3c9 call $c9a3
c198 cd4ff6 call $f64f
c19b cd0ed6 call $d60e
c19e c3d4dc jp $dcd4
;;***Streams.asm
;;<< (TEXT) STREAM MANAGEMENT
;;=========================================
;;select txt stream zero
c1a1 af xor a
c1a2 cdb3c1 call $c1b3
c1a5 af xor a
;;=select txt stream
c1a6 e5 push hl
c1a7 f5 push af
c1a8 fe08 cp $08
c1aa dcb4bb call c,$bbb4 ; firmware function: txt str select
c1ad f1 pop af
c1ae 2106ac ld hl,$ac06
c1b1 1804 jr $c1b7 ; (+$04)
;;==========================================
;;swap input streams
c1b3 e5 push hl
c1b4 2107ac ld hl,$ac07
;;=swap stream number atHL
c1b7 d5 push de
c1b8 5f ld e,a
c1b9 7e ld a,(hl)
c1ba 73 ld (hl),e
c1bb d1 pop de
c1bc e1 pop hl
c1bd c9 ret
;;-----------------------------------------------------------------
;;=get output stream
c1be 3a06ac ld a,($ac06)
c1c1 fe08 cp $08
c1c3 c9 ret
;;-----------------------------------------------------------------
;;=get input stream
;returns Carry clear if stream is on screen, Carry set if not on screen (i.e. a file)
c1c4 3a07ac ld a,($ac07)
c1c7 fe09 cp $09
c1c9 c9 ret
;;-----------------------------------------------------------------
;;=eval and select txt stream
c1ca cdfbc1 call $c1fb
c1cd 18d7 jr $c1a6 ; (-$29)
;;=exec following on evalled stream and swap back
c1cf cdfbc1 call $c1fb
c1d2 1818 jr $c1ec ; (+$18)
;;=swap both streams, exec TOS and swap back
c1d4 cdfbc1 call $c1fb
c1d7 cdb3c1 call $c1b3
c1da c1 pop bc
c1db f5 push af
c1dc cdc4c1 call $c1c4
c1df cdedc1 call $c1ed
c1e2 f1 pop af
c1e3 18ce jr $c1b3 ; (-$32)
;;===============================================
;;=exec TOS on evalled stream and swap back
c1e5 cdfbc1 call $c1fb
c1e8 fe08 cp $08
c1ea 3031 jr nc,$c21d ; (+$31)
;;=exec TOS on stream and swap back
c1ec c1 pop bc
;;=exec BC on stream and swap back
c1ed cda6c1 call $c1a6
c1f0 f5 push af
c1f1 7e ld a,(hl)
c1f2 fe2c cp $2c ; ','
c1f4 cdfcff call $fffc ; JP (BC)
c1f7 f1 pop af
c1f8 c3a6c1 jp $c1a6
;;======================================
;;=eval and validate stream number if present
c1fb 7e ld a,(hl)
c1fc fe23 cp $23 ; #
c1fe 3e00 ld a,$00
c200 c0 ret nz
c201 cd0dc2 call $c20d
c204 f5 push af
c205 cd41de call $de41
c208 d437de call nc,$de37
c20b f1 pop af
c20c c9 ret
;;====================================
;;=eval and validate stream number
c20d cd25de call $de25
c210 defb $23 ;Inline token to test "#"
c211 3e0a ld a,$0a
;;=check byte value in range.
;; if not give "Improper Argument" error message
;; In: A = max value
;; Out: A = value if in range
c213 c5 push bc
c214 d5 push de
c215 47 ld b,a
c216 cdb8ce call $ceb8 ; get number and check it's less than 255
c219 b8 cp b ; compare to value we want
c21a d1 pop de
c21b c1 pop bc
c21c d8 ret c ;; return if less than value
;; greater than value
;;=raise Improper Argument error
c21d c34dcb jp $cb4d ; Error: Improper Argument
;;***Screen.asm
;;<< SCREEN HANDLING FUNCTIONS
;;========================================================================
;; check number is less than 2
c220 3e02 ld a,$02
c222 18ef jr $c213 ; check value is in range
;;========================================================================
;; command PEN
;PEN [#<stream expression>,]<masked ink>
;Sets the ink to use for the foreground of the given window.
c224 cde5c1 call $c1e5
c227 0190bb ld bc,$bb90 ; firmware function: txt set pen
c22a c43fc2 call nz,$c23f
c22d cd41de call $de41
c230 d0 ret nc
c231 cd20c2 call $c220 ; check number is less than 2
c234 019fbb ld bc,$bb9f ; firmware function: txt set back
c237 1809 jr $c242
;;========================================================================
;; command PAPER
;PAPER [#<stream expression>,]<masked ink>
;Sets the ink to use for the background of the given window.
c239 cde5c1 call $c1e5
c23c 0196bb ld bc,$bb96 ; firmware function: txt set paper
c23f cd71c2 call $c271 ; check parameter is less than 16
c242 e5 push hl
c243 cdfcff call $fffc ; JP (BC)
c246 e1 pop hl
c247 c9 ret
;;=========================================================================
;; command BORDER
;BORDER <colour>[,colour]
;Set the border colour. If two values are supplied border will flash between them
c248 cd62c2 call $c262 ; one or two numbers each less than 32
;; B,C = numbers which are the inks
c24b e5 push hl
c24c cd38bc call $bc38 ; firmware function: scr set border
c24f e1 pop hl
c250 c9 ret
;;=========================================================================
;; command INK
;INK <ink number>,<colour>[,<colour>]
;Specifies the colour for an ink. If two colours are given the ink flashes between the two.
c251 cd71c2 call $c271 ; check parameter is less than 16
c254 f5 push af
c255 cd15de call $de15 ; check for comma
c258 cd62c2 call $c262 ; one or two numbers each less than 32
;; B,C = numbers which are the inks
c25b f1 pop af
c25c e5 push hl
c25d cd32bc call $bc32 ; firmware function: scr set ink
c260 e1 pop hl
c261 c9 ret
;;=========================================================================
;; eval one or two numbers less than 32
;; used to get ink values
;;
;; first number in B, second number in C
c262 cd6ac2 call $c26a
c265 41 ld b,c
c266 cd41de call $de41
c269 d0 ret nc
c26a 3e20 ld a,$20
c26c cd13c2 call $c213 ; check value is in range
c26f 4f ld c,a
c270 c9 ret
;;========================================================================
;; check value is less than 16
c271 3e10 ld a,$10
c273 189e jr $c213 ; check value is in range
;;========================================================================
;; command MODE
;MODE <integer expression>
;Changes screen mode
c275 3e03 ld a,$03
c277 cd13c2 call $c213 ; check value is in range
;; A = mode
c27a e5 push hl
c27b cd0ebc call $bc0e ; firmware function: scr set mode
c27e e1 pop hl
c27f c9 ret
;;=============================================================================
;; command CLS
;CLS [#<stream expression>]
;Clear the screen window for a stream
;Stream expression must be 0..7. If no value is given stream #0 is cleared.
c280 cde5c1 call $c1e5
c283 e5 push hl
c284 cd6cbb call $bb6c ; firmware function: txt clear window
c287 e1 pop hl
c288 c9 ret
;;=eval stream param, and exec TOS, and swap back
c289 cd0dc2 call $c20d
c28c fe08 cp $08
c28e 308d jr nc,$c21d ; (-$73)
;;=exec TOS on stream and swap back
c290 f5 push af
c291 cd1dde call $de1d ; check for close bracket
c294 f1 pop af
c295 c3ecc1 jp $c1ec
;;========================================================================
;; function COPYCHR$
c298 cd89c2 call $c289
c29b cd60bb call $bb60 ; firmware function: txt rd char
c29e c378fa jp $fa78
;;========================================================================
;; function VPOS
;VPOS(#<stream expression>)
;Returns the vertical position of the given stream
c2a1 cd89c2 call $c289
c2a4 e5 push hl
c2a5 cdc7c2 call $c2c7 ; get y cursor position
c2a8 180a jr $c2b4 ; (+$0a)
;;========================================================================
;; function POS
;POS(#<stream expression>)
;Established the position of the specified stream.
;1. Screen streams #0..#7: Returns the current x coordinate. 1 is the left column
;2. Printer stream #8: Returns the current position across the printer, counting
;all character codes greater than &1F. 1 is the left column
;3. Cassette output stream #9: Returns the number of printing characters since the last
;carriage return, where printing characters are those > &1F. 1 is the leftmost column.
c2aa cd0dc2 call $c20d
c2ad cd90c2 call $c290
c2b0 e5 push hl
c2b1 cdb9c2 call $c2b9
c2b4 cd32ff call $ff32
c2b7 e1 pop hl
c2b8 c9 ret
;;========================================================================
;;=get xpos of output stream
;stream can be stream, file or printer
c2b9 cdbec1 call $c1be
c2bc 3a08ac ld a,($ac08)
c2bf c8 ret z
c2c0 3a0aac ld a,($ac0a)
c2c3 d0 ret nc
c2c4 c3ecc3 jp $c3ec
;;========================================================================
;; get Y cursor position
c2c7 cd78bb call $bb78 ; firmware function: txt get cursor
c2ca cd87bb call $bb87 ; firmware function: txt validate
c2cd 7d ld a,l
c2ce c9 ret
;;========================================================================
;;=pos is xpos in D in range
c2cf cdbec1 call $c1be
c2d2 280d jr z,$c2e1 ; (+$0d)
c2d4 d0 ret nc
c2d5 d5 push de
c2d6 e5 push hl
c2d7 cd69bb call $bb69 ; firmware function: txt get window
c2da 7a ld a,d
c2db 94 sub h
c2dc 3c inc a
c2dd e1 pop hl
c2de d1 pop de
c2df 37 scf
c2e0 c9 ret
;;=poss get screen width
c2e1 3a09ac ld a,($ac09)
c2e4 feff cp $ff
c2e6 c9 ret
;;=poss validate xpos in D
c2e7 e5 push hl
c2e8 67 ld h,a
c2e9 cdcfc2 call $c2cf
c2ec 3f ccf
c2ed 380e jr c,$c2fd ; (+$0e)
c2ef 6f ld l,a
c2f0 cdb9c2 call $c2b9
c2f3 3d dec a
c2f4 37 scf
c2f5 2806 jr z,$c2fd ; (+$06)
c2f7 84 add a,h
c2f8 3f ccf
c2f9 3002 jr nc,$c2fd ; (+$02)
c2fb 3d dec a
c2fc bd cp l
c2fd e1 pop hl
c2fe c9 ret
;;========================================================================
;; command LOCATE
;LOCATE [#<stream expression>,]<x coordinate>,<y coordinate>
;Positions the text cursor in the specified stream, default 0.
;Valid coordinates are 0..255. (1,1) is the top-left or the window.
c2ff cde5c1 call $c1e5
c302 cd51c3 call $c351
c305 e5 push hl
c306 eb ex de,hl
c307 24 inc h
c308 2c inc l
c309 cd75bb call $bb75 ; firmware function: txt set cursor
c30c e1 pop hl
c30d c9 ret
;;========================================================================
;; command WINDOW, WINDOW SWAP
;WINDOW [#<stream expression>,]<left>,<right>,<top>,<bottom>
;Defines a text window. Values can be 1..255
;WINDOW SWAP <stream expression>,<stream expression>
;Swaps two text windows
c30e fee7 cp $e7
c310 2816 jr z,$c328 ; (+$16)
c312 cde5c1 call $c1e5
c315 cd51c3 call $c351
c318 d5 push de
c319 cd15de call $de15 ; check for comma
c31c cd51c3 call $c351
c31f e3 ex (sp),hl
c320 7a ld a,d
c321 55 ld d,l
c322 6f ld l,a
c323 cd66bb call $bb66 ; firmware function: txt win enable
c326 e1 pop hl
c327 c9 ret
;;========================================================================
;;=window swap
c328 cd2cde call $de2c ; get next token skipping space
c32b cd3ec3 call $c33e ; get number less than 8
c32e 4f ld c,a
c32f cd41de call $de41
c332 3e00 ld a,$00
c334 dc3ec3 call c,$c33e ; get number less than 8
c337 47 ld b,a
c338 e5 push hl
c339 cdb7bb call $bbb7 ; firmware function: txt swap streams
c33c e1 pop hl
c33d c9 ret
;;=eval number less than 8
c33e 3e08 ld a,$08
c340 c313c2 jp $c213 ; check value is in range
;;========================================================================
;; command TAG
;TAG [#<stream expression>]
;Enables text at graphics on the given stream
;Text is printed with the top left pixel at the graphics cursor position.
;Control characters have to effect and print as symbols
c343 cde5c1 call $c1e5
c346 3eff ld a,$ff
c348 1804 jr $c34e ; (+$04)
;;========================================================================
;; command TAGOFF
;TAGOFF [#<stream expression>]
;Cancels TAG for the given stream
c34a cde5c1 call $c1e5
c34d af xor a
c34e c363bb jp $bb63 ; firmware function: txt set graphic
;;-------------------------------------------------------------------------
;;=eval two params minus 1 to D E
c351 cd58c3 call $c358
c354 53 ld d,e
c355 cd15de call $de15 ; check for comma
;;--------------------------------------------------------------------------
;;=eval param minus 1 to E
c358 d5 push de
c359 cdc3ce call $cec3
c35c d1 pop de
c35d 5f ld e,a
c35e 1d dec e
c35f c9 ret
;;========================================================================
;; command CURSOR
c360 cde5c1 call $c1e5
c363 280a jr z,$c36f ; (+$0a)
c365 cd20c2 call $c220 ; check number is less than 2
c368 b7 or a
c369 cc84bb call z,$bb84 ; firmware function: txt cur off
c36c c481bb call nz,$bb81 ; firmware function: txt cur on
c36f cd41de call $de41
c372 d0 ret nc
c373 cd20c2 call $c220 ; check number is less than 2
c376 b7 or a
c377 ca7ebb jp z,$bb7e ; firmware function: txt cur disable
c37a c37bbb jp $bb7b ; firmware function: txt cur enable
;;***StreamIO.asm
;;<< STREAM I/O
;;< Low level I/O via streams, WIDTH and EOF
;;=====================================================
;; init streams and display ASCIIZ string
c37d e5 push hl
c37e 210184 ld hl,$8401
c381 2208ac ld ($ac08),hl
c384 cd69c4 call $c469
c387 cda1c1 call $c1a1
c38a e1 pop hl
;;+----------------------------------------------------
;;output ASCIIZ string
c38b f5 push af
c38c e5 push hl
c38d 7e ld a,(hl) ; get character
c38e 23 inc hl
c38f b7 or a
c390 c4a0c3 call nz,$c3a0 ;; display text char
c393 20f8 jr nz,$c38d ; (-$08)
c395 e1 pop hl
c396 f1 pop af
c397 c9 ret
;;=======================================================
;; output new line
c398 f5 push af
c399 3e0a ld a,$0a
c39b cda0c3 call $c3a0 ;; display text char
c39e f1 pop af
c39f c9 ret
;;=======================================================
;; output char
c3a0 f5 push af
c3a1 c5 push bc
c3a2 cda8c3 call $c3a8
c3a5 c1 pop bc
c3a6 f1 pop af
c3a7 c9 ret
;;-=======================================================
;;=output char or new line
c3a8 fe0a cp $0a
c3aa 200c jr nz,$c3b8 ; (+$0c)
c3ac cdbec1 call $c1be
c3af caf5c3 jp z,$c3f5
c3b2 d231c4 jp nc,$c431 ; write cr, lf to file
c3b5 c3e2c3 jp $c3e2
;;-------------------------------------------------------------------
;;=output raw char
;A=char
c3b8 f5 push af
c3b9 c5 push bc
c3ba 4f ld c,a
c3bb cdc1c3 call $c3c1
c3be c1 pop bc
c3bf f1 pop af
c3c0 c9 ret
;;-------------------------------------------------------------------
;;=output raw char to current stream
;C=char
;stream could be printer, file or display
c3c1 3a06ac ld a,($ac06)
c3c4 fe08 cp $08
c3c6 cafcc3 jp z,$c3fc
c3c9 d238c4 jp nc,$c438 ; write char to file
c3cc 79 ld a,c
c3cd c3e9c3 jp $c3e9
;;========================================================================
;;=turn display on
;and move cursor to new line if not at start of line
c3d0 af xor a ; output letters using text functions
c3d1 cd63bb call $bb63 ; firmware function: txt set graphic
c3d4 af xor a ; opaque characters
c3d5 e5 push hl
c3d6 cd9fbb call $bb9f ; firmware function: txt set back
c3d9 e1 pop hl
c3da cd54bb call $bb54 ; firmware function: txt vdu enable
c3dd cdecc3 call $c3ec ; get x cursor position
c3e0 3d dec a
c3e1 c8 ret z
;;=display cr lf
c3e2 3e0d ld a,$0d ; print CR,LF
c3e4 cde9c3 call $c3e9
c3e7 3e0a ld a,$0a
;;=do txt output
c3e9 c35abb jp $bb5a ; firmware function: txt output
;;========================================================================
;; get x cursor position
c3ec c5 push bc
c3ed e5 push hl
c3ee cdc7c2 call $c2c7
c3f1 7c ld a,h
c3f2 e1 pop hl
c3f3 c1 pop bc
c3f4 c9 ret
;;========================================================================
;;=printer new line
c3f5 0e0d ld c,$0d
c3f7 cdfcc3 call $c3fc
c3fa 0e0a ld c,$0a
;;=output char to printer
c3fc e5 push hl
c3fd 2a08ac ld hl,($ac08)
c400 cd11c4 call $c411
c403 3208ac ld ($ac08),a
c406 e1 pop hl
;;=print char
c407 79 ld a,c
c408 cd2bbd call $bd2b ; firmware function: mc print char
c40b d8 ret c ;printed? (otherwise port busy)
c40c cd72c4 call $c472 ; key - abort if break
c40f 18f6 jr $c407 ; repeat until printed?
;;=process new lines for file or printer
c411 79 ld a,c
c412 ee0d xor $0d
c414 2810 jr z,$c426 ; (+$10)
c416 79 ld a,c
c417 fe20 cp $20 ; ' '
c419 7d ld a,l
c41a d8 ret c
c41b 24 inc h
c41c 2808 jr z,$c426 ; (+$08)
c41e bc cp h
c41f 2005 jr nz,$c426 ; (+$05)
c421 cd98c3 call $c398 ;; new text line
c424 3e01 ld a,$01
c426 3c inc a
c427 c0 ret nz
c428 3d dec a
c429 c9 ret
;;========================================================================
;; command WIDTH
;WIDTH <integer expression>
;Set the printer width so BASIC can insert carriage returns.
;Default 132. 255 means do not insert carriage returns
c42a cdc3ce call $cec3
c42d 3209ac ld ($ac09),a
c430 c9 ret
;;========================================================================
;; write cr,lf to file
c431 0e0d ld c,$0d ;; cr
c433 cd38c4 call $c438 ; write char to file
c436 0e0a ld c,$0a ;; lf
;;=write char to file
c438 e5 push hl
c439 2a0aac ld hl,($ac0a)
c43c 26ff ld h,$ff
c43e cd11c4 call $c411
c441 320aac ld ($ac0a),a
c444 e1 pop hl
c445 79 ld a,c
c446 cd95bc call $bc95 ; firmware function: cas out char
c449 d8 ret c
c44a 2019 jr nz,$c465 ; (+$19)
;;=raise File not open error
c44c c337cc jp $cc37
;;=================================================
;; variable EOF
;EOF
;Test for end of input file
;Returns -1 (true) or 0 (false)
;If no file is open returns true
c44f e5 push hl
c450 cd89bc call $bc89 ; firmware function: cas test eof
c453 28f7 jr z,$c44c ; (-$09)
c455 3f ccf
c456 9f sbc a,a
c457 cd2dff call $ff2d
c45a e1 pop hl
c45b c9 ret
;;==================================================
;; read byte from cassette or disc
c45c cd80bc call $bc80 ; firmware function: cas in char
c45f d8 ret c
c460 28ea jr z,$c44c ; (-$16)
c462 ee0e xor $0e
c464 c0 ret nz
;;=raise File not open error
c465 cd45cb call $cb45
c468 defb $1f ;Inline error code: File not open
;;=set file output stream line pos to 1
c469 3e01 ld a,$01
c46b 320aac ld ($ac0a),a
c46e c9 ret
;;***Keyboard.asm
;;<< LOW LEVEL KEYBOARD HANDLING
;;< including BREAK key handler
;;=======================================================================================
;;jp km read char
c46f c309bb jp $bb09 ; firmware function: km read char