-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbas.asm
4714 lines (4705 loc) · 163 KB
/
bas.asm
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
* Color BASIC 1.3
* Copied from the PDF version of Color BASIC Unravelled.
* Fixed up to assemble in Mamou
* Fixed up later to assemble in lwasm
*
* Revision History
*
* 04/04/2009 r21 Color BASIC 1.3 (match ROM)
* 04/03/2009 r18 Color BASIC 1.2 (match ROM)
* 08/17/2021 Started Squanchy BASIC
*
*# $Id: $
*
ORG BASIC_START
ifdef EXTBASIC
include extbas.asm
endif
*POLCAT FDB KEYIN GET A KEYSTROKE
*CHROUT FDB PUTCHR OUTPUT A CHARACTER
*CSRDON FDB CASON TURN ON CASSETTE MOTOR, START READING
*BLKIN FDB GETBLK READ A BLOCK FROM CASSETTE
*BLKOUT FDB SNDBLK WRITE A BLOCK TO CASSETTE
*JOYIN FDB GETJOY READ JOYSTICKS
*WRTLDR FDB WRLDR TURN ON MOTOR AND WRITE $55’S TO CASSETTE
*
LA00E LDS #LINBUF+LBUFMX+1 SET STACK TO TOP OF LINE INPUT BUFFER
LDA #$37 *
STA PIA1+3 * ENABLE 63.5 MICROSECOND INTERRUPT
LDA RSTFLG GET WARM START FLAG
CMPA #$55 IS IT A WARM START?
BNE BACDST NO - D0 A COLD START
LDX RSTVEC WARM START VECTOR
LDA ,X GET FIRST BYTE OF WARM START ADDR
CMPA #$12 IS IT NOP?
BNE BACDST NO - DO A COLD START
JMP ,X YES, G0 THERE
RESVEC LEAY <LA00E,PCR POINT Y TO WARM START CHECK CODE
*LA02A LDX #PIA1 POINT X TO PIA1
LA02A LDX #PIA0+4 POINT X TO PIA0
CLR -3,X CLEAR PIA0 CONTROL REGISTER A
CLR -1,X CLEAR PIA0 CONTROL REGISTER B
CLR -4,X SET PIA0 SIDE A TO INPUT
LDD #$FF34 *
STA -2,X * SET PIA0 SIDE B TO OUTPUT
STB -3,X * ENABLE PIA0 PERIPHERAL REGISTERS, DISABLE
STB -1,X * MPU INTERRUPTS, SET CA2, CA1 TO OUTPUTS
LDX #PIA1 POINT X TO PIA1
CLR 1,X CLEAR CONTROL REGISTER A ON PIA1
CLR 3,X CLEAR CONTROL REGISTER B ON PIA1
DECA A REG NOW HAS $FE
STA ,X BITS 1-7 ARE OUTPUTS, BIT 0 IS INPUT ON PIA1
LDA #$F8 =
STA 2,X = BITS 0-2 ARE INPUTS, BITS 3-7 ARE OUTPUTS
STB 1,X * ENABLE PERIPHERAL REGISTERS, DISABLE PIA1
STB 3,X * INTERRUPTS AND SET CA2, CB2 AS OUTPUTS
CLR 2,X SET 6847 MODE TO ALPHA-NUMERIC
LDB #$02 *
STB ,X * MAKE RS232 OUTPUT MARKING
LDU #SAMREG SAM CONTROL REGISTER ADDR
LDB #13 13 SAM CONTROL REGISTER BITS - Don't Clear the last three, leave in all RAM mode. Don't touch RAM mode.
LA056 STA ,U++ ZERO OUT SAM CONTROL REGISTER BIT
DECB * DECREMENT COUNTER AND
BNE LA056 * BRANCH IF NOT DONE
STA SAMREG+9 SET DISPLAY PAGE AT $400
LA05E TFR B,DP SET DIRECT PAGE TO ZERO
* No longer need RAM Size check - this requires 64k RAM
* LDB #$04 USE AS A MASK TO CHECK RAMSZ INPUT
* CLR -2,X
* BITB 2,X
* BEQ LA06E
* beq LA072
* STA -5,U ($FFE0-5 = $FFDB) Set SAM R1
* STA -11,U ($FFE0-11 = $FFCF) Set SAM F4
* BRA LA072
*LA06E NOP
* NOP
*LA070 STA -3,U ($FFE0-3 = $FFDD) PROGRAM SAM FOR 16K OR 64K RAMS
LA072 JMP ,Y GO DO A WARM OR COLD START
* COLD START ENTRY
BACDST LDX #VIDRAM+1 POINT X TO CLEAR 1ST 1K OF RAM
LA077 CLR ,--X MOVE POINTER DOWN TWO-CLEAR BYTE
LEAX 1,X ADVANCE POINTER ONE
BNE LA077 KEEP GOING IF NOT AT BOTTOM OF PAGE 0
JSR >LA928 CLEAR SCREEN
CLR ,X+ CLEAR 1ST BYTE OF BASIC PROGRAM
STX TXTTAB BEGINNING OF BASIC PROGRAM
* remove this part of BASIC that probes for the end of RAM
*LA084 LDA 2,X LOOK FOR END OF MEMORY
* COMA * COMPLEMENT IT AND PUT IT BACK
* STA 2,X * INTO SYSTEM MEMORY
* CMPA 2,X IS IT RAM?
* BNE LA093 BRANCH IF NOT (ROM, BAD RAM OR NO RAM)
* LEAX 1,X MOVE POINTER UP ONE
* COM 1,X RE-COMPLEMENT TO RESTORE BYTE
* BRA LA084 KEEP LOOKING FOR END OF RAM
LA084 ldx #BASIC_START-2 Set end of RAM
LA093 STX TOPRAM SAVE ABSOLUTE TOP OF RAM
STX MEMSIZ SAVE TOP OF STRING SPACE
STX STRTAB SAVE START OF STRING VARIABLES
LEAX -200,X CLEAR 200 - DEFAULT STRING SPACE TO 200 BYTES
STX FRETOP SAVE START OF STRING SPACE
TFR X,S PUT STACK THERE
LDX #LA10D POINT X TO ROM SOURCE DATA
LDU #CMPMID POINT U TO RAM DESTINATION
LDB #28 MOVE 28 BYTES
JSR >LA59A MOVE 28 BYTES FROM ROM TO RAM
LDU #IRQVEC POINT U TO NEXT RAM DESTINATION
LDB #30 MOVE 30 MORE BYTES
JSR >LA59A MOVE 30 BYTES FROM ROM TO RAM
LDX -12,X POINT X TO SYNTAX ERROR ADDRESS
LA0B6 STX 3,U * SET EXBAS COMMAND INTERPRETATION
STX 8,U * HANDLERS TO SYNTAX ERROR
* no need to preset ram vectors anymore
* LDX #RVEC0 POINT X TO START OF RAM VECTORS
* LDD #$394B SET UP TO SAVE 75 RTS’
*LA0C0 STA ,X+ FILL THE RAM VECTORS WITH RTS’
* DECB * DECREMENT COUNTER AND
* BNE LA0C0 * BRANCH IF NOT DONE
lda #$39 RTS opcode
STA LINHDR-1 PUT RTS IN LINHDR-1
JSR >LAD19 G0 DO A ‘NEW’
ifdef EXTBASIC
* LDX #$4558 ASCII ‘EX’ (FIRST TWO LETTERS OF ‘EXTENDED’)
*LA0CE CMPX EXBAS SEE IF EXTENDED ROM IS THERE
* LBEQ EXBAS+2 IF IT IS, BRANCH TO IT FIXME
lbra L8002
endif
ifdef COLBASIC
ANDCC #$AF ENABLE IRQ, FIRQ
LDX #LA147-1 POINT X TO COLOR BASIC COPYRIGHT MESSAGE
JSR >LB99C PRINT ‘COLOR BASIC’
endif
* copy rom to ram program to ram
SBASRS ldx #rstpgm point x to rom source data
ldu #RSTRAM point u to ram destination
ldb #7 move 7 bytes
jsr >LA59A move 7 bytes from rom to ram
* place 64k RAM aware reset program vector
* LDX #BAWMST WARM START ADDRESS
LDX #RSTRAM Small ROM to RAM program
STX RSTVEC SAVE IT
LA0E2 LDA #$55 WARM START FLAG
STA RSTFLG SAVE IT
BRA LA0F3 GO TO BASIC’S MAIN LOOP
*BAWMST NOP NOP REQ’D FOR WARM START
* This no longer needs a NOP
BAWMST
CLR DEVNUM SET DEVICE NUMBER TO SCREEN
JSR >LAD33 DO PART OF A NEW
ANDCC #$AF ENABLE IRQ,FIRQ
JSR >LA928 CLEAR SCREEN
LA0F3 JMP >LAC73 GO TO MAIN LOOP OF BASIC
* These bytes are moved to addresses RSTRAM
rstpgm nop
clr $ffdf
ifdef EXTBASIC
ifdef DISKBASIC
jmp DKWMST
else
jmp XBWMST
endif
else
jmp BAWMST
endif
*
* FIRQ SERVICE ROUTINE
BFRQSV TST PIA1+3 CARTRIDGE INTERRUPT?
BMI LA0FC YES
RTI
LA0FC JSR >LA7D1 DELAY FOR A WHILE
JSR >LA7D1 KEEP DELAYING
LA102 LEAY <LA108,PCR Y = ROM-PAK START UP VECTOR
JMP >LA02A GO DO INITIALIZATION
LA108 CLR RSTFLG CLEAR WARM START FLAG
JMP >$C000 JUMP TO EXTERNAL ROM PACK
*
* THESE BYTES ARE MOVED TO ADDRESSES $8F - $AA THE DIRECT PAGE
LA10D FCB 18 MID BAND PARTITION OF 1200/2400 HERTZ PERIOD
FCB 24 UPPER LIMIT OF 1200 HERTZ PERIOD
FCB 10 UPPER LIMIT OF 2400 HERTZ PERIOD
FDB 128 NUMBER OF 55’S TO CASSETTE LEADER
FCB 11 CURSOR BLINK DELAY
FDB 88 CONSTANT FOR 600 BAUD VER 1.2 & UP
FDB 1 PRINTER CARRIAGE RETURN DELAY
FCB 16 TAB FIELD WIDTH
FCB 112 LAST TAB ZONE
FCB 132 PRINTER WIDTH
FCB 0 LINE PRINTER POSITION
FDB LB44A ARGUMENT OF EXEC COMMAND - SET TO ‘FC’ ERROR
* LINE INPUT ROUTINE (GETNCH)
INC CHARAD+1 INCREMENT LS BYTE OF INPUT POINTER
BNE LA123 BRANCH IF NOT ZERO (NO CARRY)
INC CHARAD INCREMENT MS BYTE OF INPUT POINTER
LA123 LDA >0000 LOAD A WITH CONTENTS OF INPUT POINTER (CHARAD)
JMP >BROMHK JUMP BACK INTO THE BASIC ROM
*
* THESE BYTES ARE MOVED TO ADDRESSES $10C-$129 (IRQVEC-)
JMP >BIRQSV IRQ SERVICE
JMP >BFRQSV FIRQ SERVICE
JMP >LB44A USR ADDRESS FOR 8K BASIC (INITIALIZED TO ‘FC’ ERROR)
FCB $80 *RANDOM SEED
FDB $4FC7 *RANDON SEED OF MANTISSA
FDB $5259 *.811635157
FCB $FF UPPER CASE/LOWER CASE FLAG (STARTS SET TO UPPER)
FDB DEBDEL KEYBOARD DEBOUNCE DELAY
JMP >LB277 DISPATCH FOR EXPONENTIATION (INITIALIZED TO SYNTAX ERROR)
* BASIC COMMAND INTERPRETATION TABLE ROM IMAGE
LA13D FCB 53 53 BASIC COMMANDS
LA13E FDB LAA66 POINTS TO RESERVED WORDS
LA140 FDB LAB67 POINTS TO JUMP TABLE FOR COMMANDS
LA142 FCB 20 20 BASIC SECONDARY COMMANDS
LA143 FDB LAB1A POINTS TO SECONDARY FUNCTION RESERVED WORDS
LA145 FDB LAA29 POINTS TO SECONDARY FUNCTION JUMP TABLE
* COPYRIGHT MESSAGES
*LA147 FCC 'COLOR BASIC '
* FCB '1'
* FCC '.'
* FCB '3'
ifdef COLBASIC
ifdef COCO3
LA147 fcc 'SUPER SQUANCHY BASIC'
else
LA147 fcc 'SQUANCHY BASIC'
endif
LA156 FCB CR
*LA157 FCC '(C) 1982 TANDY'
LA165 FCB $00
endif
*LA166 FCC 'MICROSOFT'
*LA16F FCB CR,$00
LA171 BSR LA176 GET A CHARACTER FROM CONSOLE IN
ANDA #$7F MASK OFF BIT 7
RTS
* CONSOLE IN
LA176
* JSR >RVEC4 HOOK INTO RAM
ifdef EXTBASIC
ifdef DISKBASIC
jsr DVEC4
else
jsr XVEC4
endif
endif
CLR CINBFL RESET CONSOLE IN BUFFER FLAG = FULL
LA17B TST DEVNUM CHECK DEVICE NUMBER
BEQ LA1B1 G0 DO CURSOR AND GET A KEY IF SCREEN MODE
TST CINCTR TEST CHARACTER COUNTER
BNE LA186 NOT EMPTY - READ IN SOME CASSETTE DATA
COM CINBFL SET TO $FF: CONSOLE IN BUFFER EMPTY
LA185 RTS
*
LA186 PSHS U,Y,X,B SAVE REGISTERS
LDX CINPTR PICK UP BUFFER POINTER
LDA ,X+ GET NEXT CHAR
PSHS A SAVE CHAR ON STACK
STX CINPTR SAVE NEW BUFFER POINTER
LA190 DEC CINCTR DECR CHAR COUNT
BNE LA197 RETURN IF BUFFER NOT EMPTY
JSR >LA635 GO READ TAPE
LA197 PULS A,B,X,Y,U,PC RESTORE REGISTERS
*
LA199 DEC BLKCNT CURSOR BLINK DELAY
BNE LA1AB NOT TIME FOR NEW COLOR
LDB #11 *
STB BLKCNT *RESET DELAY COUNTER
LDX CURPOS GET CURSOR POSITION
LDA ,X GET CURRENT CURSOR CHAR
ADDA #$10 BUMP TO NEXT COLOR
ORA #$8F MAKE SURE IT’S A SOLID GRAPHICS BLOCK
STA ,X STORE TO SCREEN
LA1AB LDX #DEBDEL CURSOR BLINK DELAY
LA1AE JMP >LA7D3 DELAY WHILE X DECREMENTS TO ZERO
* BLINK CURSOR WHILE WAITING FOR A KEYSTROKE
LA1B1 PSHS X,B SAVE REGISTERS
LA1B3 BSR LA199 GO DO CURSOR
BSR KEYIN GO CHECK KEYBOARD
BEQ LA1B3 LOOP IF NO KEY DOWN
LDB #$60 BLANK
STB [CURPOS] BLANK CURRENT CURSOR CHAR ON SCREEN
LA1BF PULS B,X,PC
*
* THIS ROUTINE GETS A KEYSTROKE FROM THE KEYBOARD IF A KEY
* IS DOWN. IT RETURNS ZERO TRUE IF THERE WAS NO KEY DOWN.
*
LA1C1 CLR PIA0+2 CLEAR COLUMN STROBE
LDA PIA0 READ KEY ROWS
COMA COMPLEMENT ROW DATA
ASLA SHIFT OFF JOYSTICK DATA
BEQ LA244 RETURN IF NO KEYS OR FIRE BUTTONS DOWN
KEYIN PSHS U,X,B SAVE REGISTERS
LDU #PIA0 POINT U TO PIA0
LDX #KEYBUF POINT X TO KEYBOARD MEMORY BUFFER
CLRA * CLEAR CARRY FLAG, SET COLUMN COUNTER (ACCA)
DECA * TO $FF
PSHS X,A SAVE COLUMN CTR & 2 BLANK (X REG) ON STACK
STA 2,U INITIALIZE COLUMN STROBE TO $FF
LA1D9 ROL 2,U * ROTATE COLUMN STROBE DATA LEFT 1 BIT, CARRY
BCC LA220 * INTO BIT 0 - BRANCH IF 8 SHIFTS DONE
INC 0,S INCREMENT COLUMN COUNTER
BSR LA23A READ KEYBOARD ROW DATA
STA 1,S TEMP STORE KEY DATA
EORA ,X SET ANY BIT WHERE A KEY HAS MOVED
ANDA ,X ACCA=0 IF NO NEW KEY DOWN, <70 IF KEY WAS RELEASED
LDB 1,S GET NEW KEY DATA
STB ,X+ STORE IT IN KEY MEMORY
TSTA WAS A NEW KEY DOWN?
BEQ LA1D9 NO-CHECK ANOTHER COLUMN
LDB 2,U * GET COLUMN STROBE DATA AND
STB 2,S * TEMP STORE IT ON THE STACK
* THIS ROUTINE CONVERTS THE KEY DEPRESSION INTO A NUMBER
* FROM 0-50 IN ACCB CORRESPONDING TO THE KEY THAT WAS DOWN
LDB #$F8 TO MAKE SURE ACCB=0 AFTER FIRST ADDB #8
LA1F4 ADDB #$08 ADD 8 FOR EACH ROW OF KEYBOARD
LSRA ACCA HAS THE ROW NUMBER OF THIS KEY - ADD 8 FOR EACH ROW
BCC LA1F4 GO ON UNTIL A ZERO APPEARS IN THE CARRY FLAG
ADDB 0,S ADD IN THE COLUMN NUMBER
* NOW CONVERT THE VALUE IN ACCB INTO ASCII
BEQ LA245 THE ‘AT SIGN’ KEY WAS DOWN
CMPB #26 WAS IT A LETTER?
BHI LA247 NO
ORB #$40 YES, CONVERT TO UPPER CASE ASCII
BSR LA22E CHECK FOR THE SHIFT KEY
ORA CASFLG * ‘OR’ IN THE CASE FLAG & BRANCH IF IN UPPER
BNE LA20C * CASE MODE OR SHIFT KEY DOWN
ORB #$20 CONVERT TO LOWER CASE
LA20C STB 0,S TEMP STORE ASCII VALUE
LDX DEBVAL GET KEYBOARD DEBOUNCE
BSR LA1AE
LDB #$FF SET COLUMN STROBE TO ALL ONES (NO
BSR LA238 STROBE) AND READ KEYBOARD
INCA = INCR ROW DATA, ACCA NOW 0 IF NO JOYSTICK
BNE LA220 = BUTTON DOWN. BRANCH IF JOYSTICK BUTTON DOWN
LA21A LDB 2,S GET COLUMN STROBE DATA
BSR LA238 READ A KEY
CMPA 1,S IS IT THE SAME KEY AS BEFORE DEBOUNCE?
LA220 PULS A,X REMOVE TEMP SLOTS FROM THE STACK AND RECOVER
* THE ASCII VALUE OF THE KEY
BNE LA22B NOT THE SAME KEY OR JOYSTICK BUTTON
CMPA #$12 IS SHIFT ZERO DOWN?
BNE LA22C NO
COM CASFLG YES, TOGGLE UPPER CASE/LOWER CASE FLAG
LA22B CLRA SET ZERO FLAG TO INDICATE NO NEW KEY DOWN
LA22C PULS B,X,U,PC RESTORE REGISTERS
* TEST FOR THE SHIFT KEY
LA22E LDA #$7F COLUMN STROBE
STA 2,U STORE TO PlA
LDA ,U READ KEY DATA
COMA *
ANDA #$40 * SET BIT 6 IF SHIFT KEY DOWN
RTS RETURN
* READ THE KEYBOARD
LA238 STB 2,U SAVE NEW COLUMN STROBE VALUE
LA23A LDA ,U READ PIA0, PORT A TO SEE IF KEY IS DOWN
* A BIT WILL BE ZERO IF ONE IS
ORA #$80 MASK OFF THE JOYSTICK COMPARATOR INPUT
TST $02,U ARE WE STROBING COLUMN 7?
BMI LA244 NO
ORA #$C0 YES, FORCE ROW 6 TO BE HIGH - THIS WILL CAUSE
* THE SHIFT KEY TO BE IGNORED
LA244 RTS RETURN
LA245 LDB #51 CODE FOR ‘AT SIGN’
LA247 LDX #CONTAB-$36 POINT X TO CONTROL CODE TABLE
CMPB #33 KEY NUMBER <33?
BLO LA264 YES (ARROW KEYS, SPACE BAR, ZERO)
LDX #CONTAB-$54 POINT X TO MIDDLE OF CONTROL TABLE
CMPB #48 KEY NUMBER >48?
BHS LA264 YES (ENTER,CLEAR,BREAK,AT SIGN)
BSR LA22E CHECK SHIFT KEY (ACCA WILL CONTAIN STATUS)
CMPB #43 IS KEY A NUMBER, COLON OR SEMICOLON?
BLS LA25D YES
EORA #$40 TOGGLE BIT 6 OF ACCA WHICH CONTAINS THE SHIFT DATA
* ONLY FOR SLASH,HYPHEN,PERIOD,COMMA
LA25D TSTA SHIFT KEY DOWN?
BNE LA20C YES
ADDB #$10 NO, ADD IN ASCII OFFSET CORRECTION
BRA LA20C GO CHECK FOR DEBOUNCE
LA264 ASLB MULT ACCB BY 2 - THERE ARE 2 ENTRIES IN CONTROL
* TABLE FOR EACH KEY - ONE SHIFTED, ONE NOT
BSR LA22E CHECK SHIFT KEY
BEQ LA26A NOT DOWN
INCB ADD ONE TO GET THE SHIFTED VALUE
LA26A LDB B,X GET ASCII CODE FROM CONTROL TABLE
BRA LA20C GO CHECK DEBOUNCE
*
*
* CONTROL TABLE UNSHIFTED, SHIFTED VALUES
CONTAB FCB $5E,$5F UP ARROW
FCB $0A,$5B DOWN ARROW
FCB $08,$15 RIGHT ARROW
FCB $09,$5D LEFT ARROW
FCB $20,$20 SPACE BAR
FCB $30,$12 ZERO
FCB $0D,$0D ENTER
FCB $0C,$5C CLEAR
FCB $03,$03 BREAK
FCB $40,$13 AT SIGN
* CONSOLE OUT
PUTCHR
* JSR >RVEC3 HOOK INTO RAM
ifdef EXTBASIC
ifdef DISKBASIC
jsr DVEC3
else
jsr XVEC3
endif
endif
PSHS B SAVE ACCB
LDB DEVNUM GET DEVICE NUMBER
INCB SET FLAGS
PULS B RESTORE ACCB
BMI LA2BF SEND TO LINE PRINTER
BNE LA30A SEND TO SCREEN
* SEND TO CASSETTE
PSHS X,B,A RESTORE REGISTERS
LDB FILSTA GET FILE STATUS
DECB INPUT FILE?
BEQ LA2A6 YES
LDB CINCTR TEMP CHAR CTR
INCB IS THE BUFFER FULL
BNE LA29E NO
BSR LA2A8 YES, WRITE DATA BLOCK TO TAPE
LA29E LDX CINPTR GET BUFFER POINTER
STA ,X+ PUT CHAR IN CASSETTE BUFFER
STX CINPTR STORE NEW BUFFER POINTER
INC CINCTR INCR BYTE COUNT
LA2A6 PULS A,B,X,PC
* WRITE A BLOCK OF DATA TO TAPE
LA2A8 LDB #1 DATA BLOCK TYPE - NOT A HEADER BLOCK
LA2AA STB BLKTYP BLOCK NUMBER
LDX #CASBUF CASSETTE BUFFER
STX CBUFAD STARTING ADDRESS
LDB CINCTR GET NUMBER OF BYTES
STB BLKLEN BYTE COUNT
PSHS U,Y,A SAVE REGISTERS
JSR >LA7E5 WRITE A BLOCK ON TAPE
PULS A,Y,U RESTORE REGISTERS
JMP >LA650 RESET BUFFER POINTERS
* SOFTWARE UART TO L1NE PRINTER
LA2BF PSHS X,B,A,CC SAVE REGISTERS AND INTERRUPT STATUS
ORCC #$50 DISABLE IRQ,FIRQ
LA2C3 LDB PIA1+2 GET RS 232 STATUS
LSRB SHIFT RS 232 STATUS BIT INTO CARRY
BCS LA2C3 LOOP UNTIL READY
BSR LA2FB SET OUTPUT TO MARKING
CLRB *
BSR LA2FD * TRANSMIT ONE START BIT
LDB #8 SEND 8 BITS
LA2D0 PSHS B SAVE BIT COUNTER
CLRB CLEAR DA IMAGE I ZEROES TO DA WHEN SENDING RS 232 DATA
LSRA ROTATE NEXT BIT OF OUTPUT CHARACTER TO CARRY FLAG
ROLB * ROTATE CARRY FLAG INTO BIT ONE
ASLB * AND ALL OTHER BITS SET TO ZERO
BSR LA2FD TRANSMIT DATA BYTE
PULS B GET BIT COUNTER
DECB SENT ALL 8 BITS?
BNE LA2D0 NO
BSR LA2FB SEND STOP BIT (ACCB:0)
PULS CC,A RESTORE OUTPUT CHARACTER & INTERRUPT STATUS
CMPA #CR IS IT CARRIAGE RETURN?
BEQ LA2ED YES
INC LPTPOS INCREMENT CHARACTER COUNTER
LDB LPTPOS CHECK FOR END OF LINE PRINTER LINE
CMPB LPTWID AT END OF LINE PRINTER LINE?
BLO LA2F3 NO
LA2ED CLR LPTPOS RESET CHARACTER COUNTER
BSR LA305 *
BSR LA305 * DELAY FOR CARRIAGE RETURN
LA2F3 LDB PIA1+2 WAIT FOR HANDSHAKE
LSRB CHECK FOR R5232 STATUS?
BCS LA2F3 NOT YET READY
PULS B,X,PC RESTORE REGISTERS
LA2FB LDB #2 SET RS232 OUTPUT HIGH (MARKING)
LA2FD STB DA STORE TO THE D/A CONVERTER REGISTER
BSR LA302 GO WAIT A WHILE
LA302 LDX LPTBTD GET BAUD RATE
FCB SKP2 SKIP NEXT TWO BYTES
LA305 LDX LPTLND PRINTER CARRIAGE RETURN DELAY
JMP >LA7D3 DELAY ON DECREMENTING X
* PUT A CHARACTER ON THE SCREEN
LA30A PSHS X,B,A SAVE REGISTERS
LDX CURPOS POINT X TO CURRENT CHARACTER POSITION
CMPA #BS IS IT BACKSPACE?
BNE LA31D NO
CMPX #VIDRAM AT TOP OF SCREEN?
BEQ LA35D YES - DO NOT ALLOW BACKSPACE
LDA #$60 BLANK
STA ,-X PUT IN PREVIOUS POSITION
BRA LA344 SAVE NEW CURPOS
LA31D CMPA #CR ENTER KEY?
BNE LA32F BRANCH IF NOT
LDX CURPOS GET CURRENT CHAR POSITION
LA323 LDA #$60 BLANK
STA ,X+ PUT IT ON SCREEN
TFR X,D *
BITB #$1F * TEST FOR BEGINNING OF NEW LINE
BNE LA323 PUT OUT BLANKS TILL NEW LINE
BRA LA344 CHECK FOR SCROLLING
LA32F CMPA #SPACE *
BCS LA35D * BRANCH IF CONTROL CHARACTER
TSTA SET FLAGS
BMI LA342 IT IS GRAPHIC CHARACTER
CMPA #$40 *
BCS LA340 * BRANCH IF NUMBER OR SPECIAL CHARACTER
CMPA #$60 UPPER/LOWER CASE?
BCS LA342 BRANCH IF UPPER CASE ALPHA
ANDA #$DF CLEAR BIT 5, FORCE ASCII LOWER CASE TO BE UPPER CASE
LA340 EORA #$40 INVERT BIT 6, CHANGE UPPER CASE TO LOWER & VICE VERSA
LA342 STA ,X+ STORE CHARACTER TO SCREEN
LA344 STX CURPOS SAVE CURRENT CHAR POSITION
CMPX #VIDRAM+511 END OF SCREEN BUFFER?
BLS LA35D RETURN IF NO NEED TO SCROLL
LDX #VIDRAM TOP OF SCREEN
* SCROLL THE SCREEN
LA34E LDD 32,X GET TWO BYTES
STD ,X++ MOVE THEM UP ONE ROW
CMPX #VIDRAM+$1E0 AT THE LAST LINE?
BCS LA34E NO
LDB #$60 BLANK
JSR >LA92D BLANK LAST LINE
LA35D PULS A,B,X,PC RESTORE REGISTERS
* SET UP TAB FIELD WIDTH, TAB ZONE, CURRENT POSITION
* AND LINE WIDTH ACCORDING TO THE DEVICE SELECTED
LA35F
* JSR >RVEC2 HOOK INTO RAM
ifdef DISKBASIC
jsr DVEC2
endif
PSHS X,B,A SAVE REGISTERS
CLR PRTDEV RESET PRINT DEVICE NUMBER
LDA DEVNUM GET DEVICE NUMBER
BEQ LA373 BRANCH IF SCREEN
INCA CHECK FOR CASSETTE
BEQ LA384 BRANCH IF CASSETTE
* END UP HERE IF PRINTER
LDX LPTCFW TAB FIELD WIDTH AND TAB ZONE
LDD LPTWID PRINTER WIDTH AND POSITION
BRA LA37C SET PRINT PARAMETERS
* SCREEN DISPLAY VALUES
LA373 LDB CURPOS+1 GET CURSOR LOC LS BYTE
ANDB #$1F KEEP ONLY COLUMN POSITION
LDX #$1010 TAB FIELD WIDTH AND LAST TAB ZONE
LDA #32 DISPLAY SCREEN LINE WIDTH
LA37C STX DEVCFW SAVE TAB FIELD WIDTH AND ZONE
STB DEVPOS SAVE PRINT POSITION
STA DEVWID SAVE PRINT WIDTH
PULS A,B,X,PC RESTORE REGISTERS
LA384 COM PRTDEV SET TO $FF FOR CASSETTE
LDX #$0100 * TAB FIELD WIDTH = 1; ALL OTHER
CLRA * PARAMETERS = 0
CLRB *
BRA LA37C SET PRINT PARAMETERS
* THIS IS THE ROUTINE THAT GETS AN INPUT LINE FOR BASIC
* EXIT WITH BREAK KEY: CARRY = 1
* EXIT WITH ENTER KEY: CARRY = 0
LA38D JSR >LA928 CLEAR SCREEN
LA390
* JSR >RVEC12 HOOK INTO RAM
ifdef DISKBASIC
jsr DVEC12
endif
CLR IKEYIM RESET BREAK CHECK KEY TEMP KEY STORAGE
LDX #LINBUF+1 INPUT LINE BUFFER
LDB #1 ACCB CHAR COUNTER: SET TO 1 TO ALLOW A
* BACKSPACE AS FIRST CHARACTER
LA39A JSR >LA171 GO GET A CHARACTER FROM CONSOLE IN
TST CINBFL GET CONSOLE IN BUFFER FLAG
BNE LA3CC BRANCH IF NO MORE CHARACTERS IN INPUT FILE
TST DEVNUM CHECK DEVICE NUMBER
BNE LA3C8 BRANCH IF NOT SCREEN
CMPA #FORMF FORM FEED
BEQ LA38D YES - CLEAR SCREEN
CMPA #BS BACKSPACE
BNE LA3B4 NO
DECB YES - DECREMENT CHAR COUNTER
BEQ LA390 BRANCH IF BACK AT START OF LINE AGAIN
LEAX -1,X DECREMENT BUFFER POINTER
BRA LA3E8 ECHO CHAR TO SCREEN
LA3B4 CMPA #$15 SHIFT RIGHT ARROW?
BNE LA3C2 NO
* YES, RESET BUFFER TO BEGINNING AND ERASE CURRENT LINE
LA3B8 DECB DEC CHAR CTR
BEQ LA390 GO BACK TO START IF CHAR CTR = 0
LDA #BS BACKSPACE?
JSR >PUTCHR SEND TO CONSOLE OUT (SCREEN)
BRA LA3B8 KEEP GOING
LA3C2 CMPA #3 BREAK KEY?
ORCC #1 SET CARRY FLAG
LA3C6 BEQ LA3CD BRANCH IF BREAK KEY DOWN
LA3C8 CMPA #CR ENTER KEY?
BNE LA3D9 NO
LA3CC CLRA CLEAR CARRY FLAG IF ENTER KEY - END LINE ENTRY
LA3CD PSHS CC SAVE CARRY FLAG
JSR >LB958 SEND CR TO SCREEN
CLR ,X MAKE LAST BYTE IN INPUT BUFFER = 0
LDX #LINBUF RESET INPUT BUFFER POINTER
PULS CC,PC RESTORE CARRY FLAG
* INSERT A CHARACTER INTO THE BASIC LINE INPUT BUFFER
LA3D9 CMPA #$20 IS IT CONTROL CHAR?
BLO LA39A BRANCH IF CONTROL CHARACTER
CMPA #'z+1 *
BCC LA39A * IGNORE IF > LOWER CASE Z
CMPB #LBUFMX HAVE 250 OR MORE CHARACTERS BEEN ENTERED?
BCC LA39A YES, IGNORE ANY MORE
STA ,X+ PUT IT IN INPUT BUFFER
INCB INCREMENT CHARACTER COUNTER
LA3E8 JSR >PUTCHR ECHO IT TO SCREEN
BRA LA39A GO SET SOME MORE
* INPUT DEVICE NUMBER CHECK
LA3ED
* JSR >RVEC5 HOOK INTO RAM
ifdef DISKBASIC
jsr DVEC5
endif
LDA DEVNUM DEVICE NUMBER
BEQ LA415 RETURN IF SCREEN
INCA *
BNE LA403 * BRANCH IF NOT CASSETTE (BAD FILE MODE)
LDA FILSTA GET FILE STATUS
BNE LA400 FILE IS OPEN
LA3FB LDB #22*2 ‘FILE NOT OPEN’ ERROR
JMP >LAC46 JUMP TO ERROR SERVICING ROUTINE
LA400 DECA *
BEQ LA415 * FILE IS IN INPUT MODE, RETURN
LA403 JMP >LA616 ‘BAD FILE MODE’ ERROR
* PRINT DEVICE NUMBER CHECK
LA406
* JSR >RVEC6 HOOK INTO RAM
ifdef DISKBASIC
jsr DVEC6
endif
LDA DEVNUM GET DEVICE NUMBER
INCA *
BNE LA415 * RETURN IF NOT TAPE
LDA FILSTA GET FILE STATUS
BEQ LA3FB ‘FILE NOT OPEN’ ERROR
DECA *
BEQ LA403 * ‘BAD FILE MODE’ - FILE IN INPUT MODE
LA415 RTS
* CLOSE
CLOSE BEQ LA426 BRANCH IF NO NAME SPECIFIED
JSR >LA5A5 CHECK DEVICE NUMBER
LA41B BSR LA42D GO CLOSE A FILE
JSR GETCCH GET CURRENT BASIC CHARACTER
BEQ LA44B RETURN IF NO MORE FILES
JSR >LA5A2 CHECK SYNTAX AND DEVICE NUMBER
BRA LA41B KEEP CLOSING FILES
* CLOSE ALL FILES HANDLER
LA426
* JSR >RVEC7 HOOK INTO RAM
ifdef DISKBASIC
jsr DVEC7
endif
LA429 LDA #-1 CASSETTE DEVICE NUMBER
STA DEVNUM SET DEVICE NUMBER
* CLOSE FILE HANDLER
LA42D
* JSR >RVEC8 HOOK INTO RAM
ifdef EXTBASIC
ifdef DISKBASIC
jsr DVEC8
else
jsr XVEC8
endif
endif
LDA DEVNUM GET DEVICE NUMBER
CLR DEVNUM SET TO SCREEN
INCA *
BNE LA44B * BRANCH IF WAS NOT CASSETTE
LDA FILSTA GET FILE STATUS
CMPA #2 IS IT OUTPUT MODE
BNE LA449 NO
LDA CINCTR GET CHARACTER BUFFER CTR
BEQ LA444 WRITE END OF PROG BLOCK IF BUFFER EMPTY
JSR >LA2A8 WRITE A BLOCK TO TAPE
LA444 LDB #$FF END OF FILE TYPE BLOCK NUMBER
JSR >LA2AA WRITE END OF FILE TYPE BLOCK
LA449 CLR FILSTA CASSETTE FILE STATUS CLOSED
LA44B RTS
* CSAVE
CSAVE JSR >LA578 GO SCAN OFF NAME
JSR GETCCH GET CURRENT CHARACTER IN THE BASIC LINE
BEQ LA469 BRANCH IF NONE
JSR >LB26D SYNTAX ERROR IF NOT COMMA
LDB #'A IS THIS AN ASCII SAVE?
JSR >LB26F SYNTAX ERROR IF NOT ‘A’
BNE LA44B RETURN IF NOT END OF LINE
CLRA FILE TYPE = 0
JSR >LA65C WRITE OUT HEADER BLOCK
LDA #-1 CASSETTE CODE
STA DEVNUM SET DEVICE NUMBER TO CASSETTE
CLRA CLEAR CARRY - FORCE LIST TO BEGIN AT PROGRAM START
JMP >LIST GO DO A ‘LIST’ TO CASSETTE
* NON-ASCII CSAVE
LA469 CLRA FILE TYPE = 0
LDX ZERO ZERO OUT ASCII FLAG AND FILE MODE
JSR >LA65F WRITE HEADER BLOCK
CLR FILSTA CLOSE FILES
INC BLKTYP INCREMENT BLOCK NUMBER
JSR >WRLDR WRITE 55’S TO CASSETTE
LDX TXTTAB ADDRESS OF PROGRAM START
LA478 STX CBUFAD STORE CURRENT BLOCK START ADDR
LDA #255 255 BYTE BLOCKS
STA BLKLEN BLOCK SIZE
LDD VARTAB END OF PROGRAM
SUBD CBUFAD CURRENT BLOCK STARTING ADDR
BEQ LA491 BRANCH IF IT CAME OUT EXACT
CMPD #255 MORE THAN 255 BYTES LEFT?
BHS LA48C YES
STB BLKLEN USE ACTUAL BLOCK SIZE IF LESS THAN 255
LA48C JSR >SNDBLK WRITE BLOCK TO CASSETTE
BRA LA478 DO ANOTHER BLOCK
LA491 NEG BLKTYP MAKE BLOCK NUMBER NEGATIVE (EOF BLOCK)
CLR BLKLEN ZERO BLOCK SIZE
JMP >LA7E7 WRITE A BLOCK, TURN OFF MOTOR
* CLOAD
CLOAD CLR FILSTA CLOSE FILES
CMPA #'M IS IT CLOADM?
BEQ LA4FE BRANCH IF SO
LEAS 2,S GET RID OF THE RETURN
JSR >LA5C5 GO GET FILE NAME
JSR >LA648 SEARCH FOR FILE
TST CASBUF+10 GET FILE MODE (NON-ZERO=DATA OR ASCII)
BEQ LA4C8 ZERO = CRUNCHED BASIC OR MACHINE LANG
LDA CASBUF+9 GET ASCII FLAG
BEQ LA4CD ‘BAD FILE NODE’ 0 = CRUNCHED OR MACH LANG
JSR >LAD19 DO A ‘NEW’
LDA #-1 TAPE DEVICE NUMBER
STA DEVNUM SET DEVICE NUMBER TO TAPE
INC FILSTA FILE TYPE = INPUT
JSR >LA635 GO LOAD ASCII RECORD
JMP >LAC7C GO LOAD AND CRUNCH INPUT
* COME HERE FROM BASIC’S DIRECT LOOP IF CONSOLE
* IN BUFFER EMPTY
LA4BF
* JSR >RVEC13 HOOK INTO RAM
ifdef DISKBASIC
jsr DVEC13
endif
JSR >LA42D CLOSE ACTIVE FILE
JMP >LAC73 GO TO BASIC’S DIRECT LOOP
* CLOAD A CRUNCHED BASIC
LA4C8 LDA CASBUF+8 FILE TYPE
BEQ LA4D0 ZERO IS CSAVE TYPE
LA4CD JMP >LA616 ‘BAD FILE MODE’ IF NOT BASIC FILE
LA4D0 JSR >LAD19 DO A ‘NEW’
JSR >CASON TURN ON TAPE, START READING
LDX TXTTAB GET START OF PROGRAM ADDRESS
LA4D8 STX CBUFAD STORE IT IN LOAD BUFFER
LDD CBUFAD GET START ADDRESS TO D REG
INCA ADD 256 TO LOAD ADDRESS
JSR >LAC37 SEE IF ROOM BELOW STACK FOR ONE BLOCK
JSR >GETBLK READ A BLOCK
BNE LA4F8 GOT AN ERROR DURING READ
LDA BLKTYP BLOCK NUMBER
BEQ LA4F8 I/O ERROR IF HEADER BLOCK TYPE
BPL LA4D8 REAR MORE IF BLOCK NUMBER POSITIVE
STX VARTAB SET END OF PROGRAM ADDRESS
BSR LA53B TURN OFF TAPE DECK
LDX #LABED-1 POINT TO ‘OK’ MESSAGE
JSR >LB99C PRINT ‘OK’ TO CONSOLE OUT
JMP >LACE9 RESET INPUT POINTER, CLEAR VARIABLES AND
* RETURN TO MAIN LOOP OF BASIC
LA4F8 JSR >LAD19 DO A ‘NEW’
LA4FB JMP >LA619 ‘I/O ERROR’
* CLOADM
LA4FE JSR GETNCH GET NEXT CHARACTER IN BASIC LINE
BSR LA578 GO SCAN OFF NAME
JSR >LA648 SEARCH FOR FILE
LA505 LDX ZERO STORE ZERO TO X REG, DEFAULT OFFSET VALUE
JSR GETCCH CHECK FOR AN OFFSET
BEQ LA511 BRANCH IF NO OFFSET
JSR >LB26D SYNTAX CHECK FOR COMMA
JSR >LB73D EVALUATE OFFSET; RETURN VALUE IN X
LA511 LDA CASBUF+8 CHECK FILE MODE
CMPA #2 IS IT MACHINE LANGUAGE?
BNE LA4CD ‘BAD FILE MODE’ ERROR IF NOT
LDD CASBUF+11 GET TRANSFER ADDR FROM TAPE
LEAU D,X ADD OFFSET
STU EXECJP STORE TRANSFER ADDR IN EXEC ARGUMENT
TST CASBUF+10 CHECK FILE MODE
BNE LA4CD ‘BAD FILE MODE’ ERROR
LDD CASBUF+13 GET LOAD ADDR FROM TAPE
LEAX D,X ADD OFFSET
STX CBUFAD STORE IN BUFFER START ADDRESS POINTER
JSR >CASON START UP TAPE
LA52E JSR >GETBLK READ A BLOCK
BNE LA4FB BRANCH IF I/O ERROR
STX CBUFAD STORE NEW START ADDR (ONE BLOCK HIGHER)
TST BLKTYP CHECK BLOCK NUMBER
BEQ LA4FB BRANCH IF I/O ERROR (HEADER BLOCK)
BPL LA52E GO READ SOME MORE
LA53B JMP >LA7E9 GO TURN OFF TAPE DECK
* EXEC
EXEC BEQ LA545 BRANCH IF NO ARGUMENT
JSR >LB73D EVALUATE ARGUMENT - ARGUMENT RETURNED IN X
STX EXECJP STORE X TO EXEC JUMP ADDRESS
LA545 JMP [EXECJP] GO DO IT
* BREAK CHECK
LA549
* JSR >RVEC11 HOOK INTO RAM
ifdef DISKBASIC
jsr DVEC11
endif
LDA DEVNUM GET DEVICE NUMBER
INCA CHECK FOR TAPE
BEQ LA5A1 RETURN IF TAPE
JMP >LADEB GO DO BREAK KEY CHECK
* THIS ROUTINE EVALUATES AN ARGUMENT
* AND MAKES SURE IT IS WITHIN LIMITS OF VIDEO DISPLAY RAM
LA554 JSR >LB3E4 EVALUATE EXPRESSION AND RETURN VALUE IN ACCD
SUBD #511 ONLY 512 VIDEO DISPLAY LOCATIONS
LBHI LB44A BRANCH IF > 511 TO ‘ILLEGAL FUNCTION CALL’
ADDD #VIDRAM+511 ADD BACK IN OFFSET + START OF VIDEO RAM
STD CURPOS PUT THE CURSOR THERE
RTS
* INKEY$
INKEY LDA IKEYIM WAS A KEY DOWN IN THE BREAK CHECK?
BNE LA56B YES
JSR >KEYIN GO GET A KEY
LA56B CLR IKEYIM CLEAR INKEY RAM IMAGE
STA FPA0+3 STORE THE KEY IN FPA0
LBNE LB68F CONVERT FPA0+3 TO A STRING
STA STRDES SET LENGTH OF STRING = 0 IF NO KEY DOWN
JMP >LB69B PUT A NULL STRING ONTO THE STRING STACK
* STRIP A FILENAME OFF OF THE BASIC INPUT LINE
LA578 LDX #CFNBUF POINT TO FILE NAME BUFFER
CLR ,X+ CLEAR THE FIRST BYTE - IT WILL CONTAIN THE COUNT
* OF THE NUMBER OF CHARACTERS IN THE NAME
LDA #SPACE SPACE
LA57F STA ,X+ BLANK FILL 8 CHARS
CMPX #CASBUF DONE?
BNE LA57F NO
JSR GETCCH GET CURRENT INPUT CHAR
BEQ LA5A1 RETURN IF NO NAME
JSR >LB156 GET THE FILE NAME - EVALUATE EXPRESSION
JSR >LB654 POINT X TO START OF NAME (TOP STRING ON STRING STACK)
LDU #CFNBUF CASSETTE FILE NAME BUFFER
STB ,U+ STORE THE NUMBER OF BYTES IN THE NAME
BEQ LA5A1 NULL NAME (BLANK NAME)
FCB SKP2 SKIP THE NEXT TWO BYTES
LA598 LDB #8 MOVE 8 BYTES
* MOVE ACCB BYTES FROM (X) TO (U)
LA59A LDA ,X+ GET BYTE FROM X
STA ,U+ STORE IT AT U
DECB MOVED ALL BYTES?
BNE LA59A NO
LA5A1 RTS
* GET DEVICE NUMBER FROM BASIC LINE - CHECK VALIDITY
LA5A2 JSR >LB26D CHECK FOR COMMA, SYNTAX ERROR IF NONE
LA5A5 CMPA #'# IS NEXT CHARACTER A NUMBER?
BNE LA5AB NO
JSR GETNCH GET NEXT BASIC INPUT CHARACTER
LA5AB JSR >LB141 EVALUATE EXPRESSION
LA5AE JSR >INTCNV CONVERT FPA0 TO INTEGER, RETURN VALUE IN ACCD
ROLB MSB OF ACCB TO CARRY
ADCA #0 ADD MSB OF ACCB TO ACCA
BNE LA61F ‘DEVICE # ERROR’ IF ACCA<FF80 OR >007F
RORB RESTORE ACCB
STB DEVNUM STORE B IN DEVICE NUMBER
* JSR >RVEC1 HOOK INTO RAM
ifdef DISKBASIC
jsr DVEC1
endif
BEQ LA5C4 BRANCH IF DEVICE NUMBER SET TO SCREEN
BPL LA61F ‘DEVICE NUMBER’ ERROR IF POSITIVE DEVICE NUMBER
CMPB #-2 LOWEST LEGAL DEVICE NUMBER
BLT LA61F ‘DEVICE NUMBER ERROR’
LA5C4 RTS
** THIS ROUTINE WILL SCAN OFF THE FILE NAME FROM A BASIC LINE
** AND RETURN A SYNTAX ERROR IF THERE ARE ANY CHARACTERS
** FOLLOWING THE END OF THE NAME
LA5C5 BSR LA578 SCAN OFF NAME
LA5C7 JSR GETCCH GET CURRENT INPUT CHAR FROM BASIC LINE
LA5C9 BEQ LA5C4 RETURN IF END OF LINE
JMP >LB277 SYNTAX ERROR IF ANY MORE CHARACTERS
* EOF
EOF
* JSR >RVEC14 HOOK INTO RAM
ifdef DISKBASIC
jsr DVEC14
endif
LDA DEVNUM GET DEVICE NUMBER
PSHS A SAVE IT
BSR LA5AE CHECK DEVICE NUMBER
JSR >LA3ED CHECK FOR PROPER FILE AND MODE
LA5DA CLRB NOT EOF FLAG = 0
LDA DEVNUM TEST DEVICE NUMBER
BEQ LA5E4 BRANCH IF NOT SET TO DISPLAY
TST CINCTR ANY CHARACTERS LEFT TO SEND?
BNE LA5E4 YES
COMB NO - EOF: SET FLAG = -1 ($FF)
LA5E4 PULS A GET DEVICE NUMBER BACK AGAIN
STA DEVNUM RESTORE IT
LA5E8 SEX CONVERT ACCB TO 2 DIGIT SIGNED INTEGER
JMP >GIVABF CONVERT ACCD TO FLOATING POINT
* SKIPF
SKIPF BSR LA5C5 SCAN OFF THE BASIC FILE NAME
BSR LA648 LOOK FOR THAT FILE ON TAPE
JSR >LA6D1 READ THE FILE
BNE LA619 ‘I/O ERROR’
RTS
* OPEN
OPEN
* JSR >RVEC0 HOOK INTO RAM
ifdef DISKBASIC
jsr DVEC0
endif
JSR >LB156 GET FILE STATUS (INPUT,OUTPUT)
JSR >LB6A4 GET FIRST BYTE OF STATUS STRING TO ACCB
PSHS B SAVE IT ON STACK
BSR LA5A2 CHECK FOR SYNTAX AND GET DEVICE NUMBER
LA603 JSR >LB26D SYNTAX CHECK FOR COMMA, SYNTAX ERROR IF NOT
BSR LA5C5 GET FILE NAME
LDA DEVNUM GET DEVICE NUMBER
CLR DEVNUM SET DEVICE NUMBER TO SCREEN
PULS B GET STATUS AGAIN
CMPB #'I IS IT INPUT MODE?
BEQ LA624 YES
CMPB #'O IS IT OUTPUT MODE?
BEQ LA658 YES
* IF IT ISN’T INPUT OR OUTPUT, BAD FILE MODE
LA616 LDB #21*2 ERROR # 21 ‘BAD FILE MODE’
FCB SKP2 SKIP TWO BYTES
LA619 LDB #20*2 ERROR # 20 ‘I/O ERROR
FCB SKP2 SKIP TWO BYTES
LA61C LDB #18*2 ERROR # 18 ‘FILE ALREADY OPEN’
FCB SKP2 SKIP TWO BYTES
LA61F LDB #19*2 ERROR # 19 ‘DEVICE NUMBER ERROR’
JMP >LAC46 JUMP TO ERROR HANDLER
*
LA624 INCA DEVICE NUMBER SET TO TAPE?
BMI LA616 ‘BAD FILE MODE’ IF DEVNUM = NEG BUT NOT CASSETTE
BNE LA657 RETURN IF DEVNUM WAS SET TO SCREEN OR DISK
* SET TO TAPE
BSR LA648 GET HEADER BLOCK
LDA CASBUF+9 GET ASCII FLAG
ANDA CASBUF+10 ‘AND’ IT WITH FILE MODE
BEQ LA616 ‘BAD FILE MODE’ - CRUNCHED FlLE OR MACH LANG
INC FILSTA OPEN FILE FOR INPUT
LA635 JSR >LA701 START TAPE, READ A BLOCK
BNE LA619 ‘I/O ERROR’
TST BLKTYP CHECK BLOCK NUMBER
BEQ LA619 ‘I/O ERROR’ IF HEADER BLOCK
BMI LA657 BRANCH IF THIS IS THE LAST BLOCK
LDA BLKLEN CHAR COUNT
BEQ LA635 READ ANOTHER BLOCK IF NULL BLOCK
LA644 STA CINCTR STORE IN TEMP CHARACTER COUNTER
BRA LA652 RESET BUFFER POINTER
* SEARCH FOR FILE NAME IN CNMBUF
LA648 TST FILSTA IS THE FILE OPEN?
BNE LA61C YES- ‘FILE ALREADY OPEN’
BSR LA681 SEARCH FOR CORRECT FILE NAME
BNE LA619 ‘I/O ERROR’
LA650 CLR CINCTR CLEAR CHARACTER COUNTER
LA652 LDX #CASBUF CASSETTE INPUT BUFFER ADDRESS
STX CINPTR RESET IT
LA657 RTS
* WRITE OUT THE HEADER BLOCK
** CASBUF FILE NAME
** CASBUF+8 FILE TYPE
** CASBUF+9 ASCII FLAG
** CASBUF+10 FILE MODE
** CASBUF+11,12 TRANSFER ADDRESS
** CASBUF+13,14 START ADDRESS
* ENTER HERE FOR DATA FILES W/DEVICE NUMBER IN ACCA
LA658 INCA CHECK FOR CASSETTE DEVICE NUMBER
BNE LA657 RETURN IF DEVICE NUMBER WASN’T TAPE
INCA MAKE FILE TYPE = 1
* ENTER HERE FOR ASCII FILES
LA65C LDX #$FFFF SET ASCII FLAG AND MODE = $FF
LA65F TST FILSTA IS FILE OPEN?
BNE LA61C YES- ‘FILE ALREADY OPEN’
LDU #CASBUF CASSETTE INPUT BUFFER
STU CBUFAD STORE IN STARTING ADDRESS
STA 8,U FILE TYPE IN CASBUF+8
STX 9,U ASCII FLAG & MODE IN CASBUF+9, CASBUF+10
* CASBUF +8 +9 +10
* TYPE ASCII MODE
* BASIC CRUNCHED 00 00 00
* BASIC ASCII 00 FF FF
* DATA 01 FF FF
* MACHINE LANGUAGE 02 00 00
* MACHINE BLK LOAD 02 00 FF
LDX #CFNBUF+1 POINT X TO FILE NAME BUFFER
JSR >LA598 MOVE 8 BYTES FROM (X) TO (U)
CLR BLKTYP ZERO BLOCK NUMBER
LDA #15 15 BYTES IN THE HEADER BLOCK
STA BLKLEN CHAR COUNT
JSR >LA7E5 GO WRITE ONE BLOCK
LDA #2 OUTPUT FILE
STA FILSTA STORE IN FILE MODE
BRA LA650 RESET POINTERS
* SEARCH FOR CORRECT CASSETTE FILE NAME
LA681 LDX #CASBUF CASSETTE BUFFER