-
Notifications
You must be signed in to change notification settings - Fork 1
/
c64-spsc.s
2915 lines (2792 loc) · 39.9 KB
/
c64-spsc.s
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
; SpeedScript 3.1
; copied by hand out of the pdf at archive.org
;
.PSC02
.org $0801
; memory map
TEXENDVAL = $7F00
INSCOLOR = 14
TOPFGCOLOR = 1
; allow some dasm things
.feature missing_char_term
.feature labels_without_colons
.code
; sys2061
.word BASICEND ; end of basic
.word 10 ; line number
.byte $9E ; SYS token
.ASSERT BEGIN<10000, error, "SYS number would be too high"
.byte $30 + (BEGIN .MOD 10000)/1000
.byte $30 + (BEGIN .MOD 1000)/100
.byte $30 + (BEGIN .MOD 100)/10
.byte $30 + (BEGIN .MOD 10)
; now I can put stuff here
.byte 0
BASICEND: .byte 0,0
; some macros
.macro copy16 src, dst, dst2
lda src
sta dst
.ifnblank dst2
sta dst2
.endif
lda src+1
sta dst+1
.ifnblank dst2
sta dst2+1
.endif
.endmacro
.macro add16 left,right
clc
lda left
adc right
sta left
lda left+1
adc right+1
sta left+1
.endmacro
;Compares two 16-bit values, and sets the C and Z flags the
;same as a LDA and CMP;instruction would for 8-bit addresses.
.macro COMP16 left,right
sec
lda left
sbc right
sta temp
lda left+1
sbc right+1
ora temp
.endmacro
; Compares two 16-bit values but only affects the C flag.
.macro COMPC16 left,right
SEC
LDA left
SBC right
LDA left+1
SBC right+1
.endmacro
; sub16 left,right : left - right -> left
; sub16 left,right,dst : left - right -> dst
.macro sub16 left,right,dst
sec
lda left
sbc right
.ifnblank dst
sta dst
.else
sta left
.endif
lda left+1
sbc right+1
.ifnblank dst
sta dst+1
.else
sta left+1
.endif
.endmacro
; Subtract an 8-bit value from a 16-bit one
.macro sub8 left,right,dst,dst2
sec
lda left
sbc right
.ifnblank dst
sta dst
.ifnblank dst2
sta dst2
.endif
.else
sta left
.endif
lda left+1
sbc #0
.ifnblank dst
sta dst+1
.ifnblank dst2
sta dst2+1
.endif
.else
sta left+1
.endif
.endmacro
.macro PrintMessage message
LDA #<message
LDY #>message
JSR PRMSG
.endmacro
.macro TopPrintMessage message
jsr topclr
PrintMessage message
.endmacro
.macro BASIC_ON
ldy #55
sty map
.endmacro
.macro BASIC_OFF
ldy #54
sty map
.endmacro
.macro display_number
BASIC_ON
jsr $BDCD ;BASIC number display
BASIC_OFF
.endmacro
.macro B_UNLESS_SHIFT_CTRL addr
LDA 653
CMP #5
BNE addr
.endmacro
;Named constants not used in source.
;May be useful for future ports.
SCRMEM = $0400
COLMEM = $D800
COLUMNS = 40
ROWS = 25
space = 32
PETSCII_CLR = 147
;Locations used by high-speed memory
;move routines:
froml = $26
fromh = $27
destl = $9E
desth = $9F
llen = $B4
hlen = $B5
;curr: Position of cursor within text
;memory. scr: used by the refresh
;routine.
curr = $39
scr = $C3
;tex: An alternate location used in tan-
;dem with curr. COLR is used by RE-
;FRESH. temp is used throughout as a
;reusable scratchpad pointer. INDIR is
;also a reusable indirect pointer.
;UNDERCURS stores the value of the
;character highlighted by the cursor.
tex = $FB
COLR = $14
temp = $3B
indir = $FD
UNDERCURS = $02
;WINDCOLR: Color of command line
;window supported by refresh. MAP
;is the 6510's built-in I/O port, used for
;mapping in and out ROMs from the
;address space. RETCHAR is the screen-
;code value of the return mark (a left-
;pointing arrow).
windcolr = $0C
map = $01
retchar = 31
;Kernal Routines
;(refer to the Commodore 64 Programmer's Reference ;Guide):
chrout = $FFD2
stop = $FFE1
setlfs = $FFBA
setnam = $FFBD
clall = $FFE7
open = $FFC0
chrin = $FFCF
chkin = $FFC6
chkout = $FFC9
getin = $FFE4
clrchn = $FFCC
close = $FFC3
load = $FFD5
save = $FFD8
ioinit = $FF84
;Called only when run from BASIC. It is
;assumed that the author's initials (that
;conveniently work out in hex) are not
;normally present in memory. If they
;are, we know that SpeedScript has been
;run before, so we avoid the ERASE
;routine to preserve the text in memory.
BEGIN JSR INIT
LDA #$CB
CMP firstrun
STA firstrun
BEQ SKIPERAS
JSR erase
SKIPERAS JSR INIT2
JMP main
;UMOVE is a high-speed memory move
;routine. It gets its speed from self-
;modifying code (the $0000's at
;MOVLOOP are replaced by actual ad-
;dresses when UMOVE is called). Some
;assemblers may assemble this as a
;zero-page mode, so you may want to
;change the $0000's to $FFFF's. UMOVE
;is used to move an overlapping range
;of memory upward, so it is used to de-
;lete. Set froml/fromh to point to
;the source area of memory,
;destl/desth to point to the destina-
;tion, and llen/hlen to hold the
;length of the area being moved.
umove LDA froml
STA MOVLOOP+1
LDA fromh
STA MOVLOOP+2
LDA destl
STA MOVLOOP+4
LDA desth
STA MOVLOOP+5
LDX hlen
BEQ SKIPMOV
MOV1 LDA #0
MOV2 STA endpos
LDY #0
MOVLOOP LDA $0000,Y
STA $0000,Y
INY
CPY endpos
BNE MOVLOOP
INC MOVLOOP+2
INC MOVLOOP+5
CPX #0
BEQ OUT
DEX
BNE MOV1
SKIPMOV LDA llen
BNE MOV2
OUT RTS
;DMOVE uses the same variables as UMOVE, but is used to move an
;overlapping block of memory down ward, so it is used to insert. If the block
;of memory to be moved does not overlap the destination area, then either
;routine can be used.
dmove LDA hlen
TAX
ORA llen
BNE NOTNULL
RTS
NOTNULL CLC
TXA
ADC fromh
STA DMOVLOOP+2
LDA froml
STA DMOVLOOP+1
CLC
TXA
ADC desth
STA DMOVLOOP+5
LDA destl
STA DMOVLOOP+4
INX
LDY llen
BNE DMOVLOOP
BEQ SKIPDMOV
DMOV1 LDY #255
DMOVLOOP LDA $0000,Y
STA $0000,Y
DEY
CPY #255
BNE DMOVLOOP
SKIPDMOV DEC DMOVLOOP+2
DEC DMOVLOOP+5
DEX
BNE DMOV1
RTS
;refresh copies a screenful of text
;from the area of memory pointed to by
;toplin. It works like a printer routine,
;fitting a line of text between the screen
;margins, wrapping words, and restarts
;at the left margin after printing a car-
;riage return. SpeedScript constantly calls
;this routine while the cursor is blink-
;ing, so it has to be very fast. To elimi-
;nate flicker, it also clears out the end of
;each line instead of first clearing the
;screen. It stores the length of the first
;screen line for the sake of the check
;routine (which scrolls up by adding
;that length to toplin), the last text
;location referenced (so check can see
;if the cursor has moved off the visible
;screen).
refresh LDA #COLUMNS
STA scr
STA COLR
LDA #>SCRMEM
STA scr+1
LDA #>COLMEM
STA COLR+1
LDA toplin
STA tex
LDA toplin+1
STA tex+1
LDX #1
LDA INSMODE
STA windcolr
LDA scrcol
STA 53280 ; VIC BORDER
PPAGE LDY #0
PLINE LDA TEXCOLR
STA (COLR),Y
LDA (tex),Y
STA lbuff,Y
INY
AND #127
CMP #retchar
BEQ BREAK
CPY #COLUMNS
BNE PLINE
DEY
SLOOP LDA (tex),Y
AND #127
NXCUR CMP #32
BEQ SBRK
DEY
BNE SLOOP
LDY #39
SBRK INY
BREAK STY temp
DEY
COPY LDA lbuff,Y
STA (scr),Y
DEY
BPL COPY
LDY temp
CLC
TYA
ADC tex
STA tex
LDA tex+1
ADC #0
STA tex+1
CPX #1
BNE CLRLN
STY LENTABLE
CLRLN CPY #COLUMNS
BEQ CLEARED
LDA #32
STA (scr),Y
INY
JMP CLRLN
CLEARED CLC
LDA scr
ADC #COLUMNS
STA scr
STA COLR
BCC incnot
INC scr+1
INC COLR+1
incnot INX
CPX #ROWS
BEQ pdone
JMP PPAGE
pdone LDA tex
STA BOTSCR
LDA tex+1
STA BOTSCR+1
RTS
; comment from left column of page 99
erase LDA texstart
STA tex
STA toplin
STA lastline
STA curr
LDA texstart+1
STA tex+1
STA toplin+1
STA lastline+1
STA curr+1
SEC
LDA texend+1
SBC texstart+1
TAX
LDA #32
CLRLOOP LDY #255
DEC tex+1
STA (tex),Y
INY
INC tex+1
CLR2 STA (tex),Y
INY
BNE CLR2
INC tex+1
DEX
BNE CLR2
STA (tex),Y
RTS
; PRMSG is used anytime we need to
; print something at the top of the screen
; (the command line). Pass it the address
; of the message to be printed by storing
; the low byte of the address in the accu
; mulator, and the high byte in the
; register. The message in memory must
; end with a zero byte. The routine does
; not add a carriage return.
PRMSG STA temp
STY temp+1
LDY #0
PRLOOP LDA (temp),Y
BEQ PREXIT
JSR chrout
INY
BNE PRLOOP
PREXIT RTS
getakey JSR getin
BEQ getakey
RTS
;The initialization routine sets up the
;memory map, clears out certain flags,
;and enables the raster interrupt
INIT LDA #147
JSR chrout
lda #54
sta map
LDA #0
STA INSMODE
STA texstart
STA texend
STA texbuf
STA bufend
STA huntlen
STA replen
LDA #>END ;
CLC
ADC #1
STA texstart+1
LDA #$CF
STA texend+1
LDA #$D0
STA texbuf+1
LDA #$FF
STA bufend+1
STA fpos+1
JMP ioinit
INIT2 JSR killbuff
; moved forward to match binary
INIT3 LDA #128
STA 650 ;TODO
STA $9D ;TODO
JSR highlight
LDA #<mynmi
sta $0318
LDA #>mynmi
sta $0319
copy16 texstart,curr
JSR sysmsg
PrintMessage MSG2
INC msgflg
RTS
;The NOPS are here because I replaced
;a three-byte JSR check with RTS.
;I did not want the size of the code
;or the location of any routines to change.
;JSR check was originally inserted to fix
;a bug, but caused a bug itself.
;NOP
;NOP
.BYTE $B1,$0B ; to match a known binary
;sysmsg displays "SpeedScript" and the version.
sysmsg JSR topclr
PrintMessage MSG1
LDA #0
STA msgflg
RTS
; This routine traps the RESTORE key. It reproduces
; some of the ROM code so that RS-232 is still supported
; (although SpeedScript does not directly support
; RS-232 output).
mynmi PHA
TXA
PHA
TYA
PHA
LDA #$7F
STA $DD0D
LDY $DD0D
BPL NOTRS
JMP $FE72
;If RESTORE is pressed, we have to fix the
;cursor in case it was lit.
NOTRS LDA blinkflag
BEQ NOTCURSOR
LDA UNDERCURS
LDY #0
STA (curr),Y
NOTCURSOR LDA #2
STA windcolr
JSR clrchn
JSR topclr
PrintMessage xitmsg
JSR YORN
BNE REBOOT
JSR delite
SEI
LDA #$7F
JMP $FE66
REBOOT JSR delite
LDX #$FA
TXS
JSR INIT2
JMP main
;
;topclr keeps the command line clean.
;It is called before most messages.
;It's like a one-line clear-screen.
topclr LDX #COLUMNS-1
LDA #32 ;space
toploop STA SCRMEM,X
DEX
BPL toploop
LDA #19 ;HOME
JMP chrout
;Converts PETSCII to screen codes.
astoin PHA
AND #128
LSR
STA temp
PLA
AND #63
ORA temp
RTS
;The MAIN loop blinks the cursor,
;checks for keystrokes, converts
;them from ASCII to screen codes,
;puts them in text at the CURRent position, and increments
;the CURRent position and lastline. It also checks for special
;cases like the back-arrow and the return key and passes control
;characters to the CONTROL routine. SHIFTed spaces are turned into
;unSHIFTed ones. The INSMODE flag is checked to see if we should
;insert a space before a character.
main LDY #0
STY blinkflag
LDA (curr),Y
STA UNDERCURS
main2 LDY #0
LDA (curr),Y
EOR #$80
STA (curr),Y
LDA blinkflag
EOR #1
STA blinkflag
JSR refresh
WAIT JSR getin
BNE KEYPRESS
LDA 162 ;TODO: label
AND #16
BEQ WAIT
LDA #0
STA 162
JMP main2
KEYPRESS TAX
LDY #0
LDA UNDERCURS
STA (curr),Y
STY blinkflag
CPX #95
BNE NOTBKS
JSR left
LDA #32
LDY #0
STA (curr),Y
JMP main
NOTBKS LDA msgflg
BEQ nomsg
TXA
PHA
jsr sysmsg
PLA
TAX
nomsg TXA
CMP #13
BNE notcr
ldx #retchar+64
notcr txa
AND #127
CMP #32
BCC CONTROL
CPX #160
BNE NESHIFT
LDX #space
NESHIFT TXA
PHA
LDY #0
LDA (curr),Y
CMP #retchar
BEQ DOINS
LDA INSMODE
BEQ NOTINST
DOINS JSR inschar
NOTINST PLA
JSR astoin
PUTCHR LDY #0
STA (curr),Y
JSR refresh
SEC
LDA curr
SBC lastline
STA temp
LDA curr+1
SBC lastline+1
ORA temp
BCC INKURR
LDA curr
ADC #0
STA lastline
LDA curr+1
ADC #0
STA lastline+1
INKURR INC curr
BNE NOINC2
INC curr+1
NOINC2 JSR check
JMP main
;CONTROl looks up a keyboard command in the list
;of control codes at CTBL. The first byte of
;CTBL is the actual number of commands. Once the
;position is found, this position is doubled as
;an index to the two-byte address table at VECT.
;The address of MAIN-1 is put on the stack,
;simulating the return address; then the address
;of the command routine taken from VECT is pushed.
;We then perform an RTS. RTS pulls the bytes off
;the stack as if they were put there by a JSR.
;This powerful technique is used to simulate
;ON+GOTO in machine language.
CONTROL TXA
LDX CTBL
SRCH CMP CTBL,X
BEQ FOUND
DEX
BNE SRCH
JMP main
FOUND DEX
TXA
ASL
TAX
LDA #>(main-1)
PHA
LDA #<(main-1)
PHA
LDA VECT+1,X
PHA
LDA VECT,X
PHA
RTS
CTBL .BYTE 39
.BYTE 29,157,137,133,2,12,138,134,20,148
.BYTE 4,19,9,147,135,139,5,136,140
.BYTE 22,145,17,159,18,24,26,16
.BYTE 28,30,6,1,11,8,31,3,131
.BYTE 10,141,7
VECT .WORD right-1,left-1,wleft-1,wright-1,BORDER-1,LETTERS-1
.WORD sleft-1,sright-1,DELCHAR-1,inschar-1,DELETE-1
.WORD HOME-1,instgl-1,CLEAR-1,paright-1,parleft-1
.WORD ERAS-1,TLOAD-1,TSAVE-1,verify-1
.WORD sleft-1,sright-1,catalog-1,insbuffer-1,switch-1
.WORD endtex-1,print-1,FORMAT-1,dcmnd-1
.WORD DELIN-1,alpha-1,killbuff-1,HUNT-1,FREEMEM-1,tab-1
.WORD lottaspaces-1,repstart-1,endpar-1,SANDR-1
;The CHECK routine first prevents the cursor from
;disappearing past the beginning or end-of-text memory,
;and prevents us from cursoring past the end-of-text pointer.
;It also checks to see if the cursor has left the visible
;screen, scrolling with REFRESH to make the cursor visible.
check JSR check2
COMPC16 curr,toplin
BCS OK1
COMP16 toplin,texstart
BEQ OK1
LDA curr
STA toplin
LDA curr+1
STA toplin+1
JSR refresh
OK1 SEC
LDA BOTSCR
SBC curr
STA tex
LDA BOTSCR+1
SBC curr+1
STA tex+1
ORA tex
BEQ EQA
BCS OK2
EQA CLC
LDA toplin
ADC LENTABLE
STA toplin
LDA toplin+1
ADC #0
STA toplin+1
REF JSR refresh
JMP OK1
OK2 RTS
check2 SEC
lda lastline
SBC texend
STA temp
lda lastline+1
SBC texend+1
ORA temp
BCC CK3
LDA texend
STA lastline
LDA texend+1
STA lastline+1
CK3 SEC
LDA curr
SBC texstart
STA temp
LDA curr+1
SBC texstart+1
ORA temp
BCS INRANGE
LDA texstart
STA curr
LDA texstart+1
STA curr+1
RTS
INRANGE SEC
LDA curr
SBC lastline
STA temp
LDA curr+1
SBC lastline+1
ORA temp
BCS OUTRANGE
RTS
OUTRANGE
lda lastline
STA curr
lda lastline+1
STA curr+1
RTS
; move cursor right.
right INC curr
BNE NOINCR
INC curr+1
NOINCR JMP check
; Cursor left.
left LDA curr
BNE NODEC
DEC curr+1
NODEC DEC curr
JMP check
; Word left. We look backward for a space.
wleft
copy16 curr,tex
DEC tex+1
LDY #$FF
STRIP LDA (tex),Y
CMP #space
BEQ STRLOOP
CMP #retchar
BNE WLOOP
STRLOOP DEY
BNE STRIP
WLOOP LDA (tex),Y
CMP #space
BEQ wrout
CMP #retchar
BEQ wrout
DEY
BNE WLOOP
RTS
wrout
SEC
TYA
ADC tex
STA curr
LDA tex+1
ADC #0
STA curr+1
JMP check
;Word right. We scan forward
;for a space. OIDS is not a meaningful label.
wright LDY #0
RLOOP LDA (curr),Y
CMP #space
BEQ ROUT
CMP #retchar
BEQ ROUT
INY
BNE RLOOP
RTS
ROUT INY
BNE OIDS
INC curr+1
LDA curr+1
CMP lastline+1
BCC OIDS
BNE lastword
OIDS LDA (curr),Y
CMP #space
BEQ ROUT
CMP #retchar
BEQ ROUT
; add Y to curr to move the cursor
; check prevents illegal cursor movement.
; LASTWORD is called if the end
; of the word cannot be found within 255 characters.
adycurr CLC
TYA
ADC curr
STA curr
LDA curr+1
ADC #0
STA curr+1
wrtn JMP check
lastword
copy16 lastline,curr
jmp check
;endtex is tricky, (p103)
endtex LDA #0
STA toplin
lda lastline+1
SEC
SBC #4
CMP texstart+1
BCS SAFE
LDA texstart+1
SAFE STA toplin+1
JSR refresh
JMP lastword
.MACRO INC15 loc
INC loc
LDA loc
and #15
sta loc
.ENDMACRO
;The raster interrupt automatically places
;SCRCOL into 53281 when appropriate. The AND
;keeps SCRCOL within a legal range (I know that's
;not really necessary)
BORDER INC15 scrcol
RTS
scrcol .BYTE 12 ; gray
;TEXCOLR (text color) is used in the refresh routine
;and stored into color memory. Both SCRCOL and TEXCOLR
;are stored within the SpeedScript code so that after
;they're changed, you can resave SpeedScript and it
;will come up with your color choice in the future.
LETTERS INC15 TEXCOLR
JMP refresh
TEXCOLR .BYTE 11 ;dark gray
;Sentence left. We look backward for ending punctuation
;or a return mark, then go forward until we run out of spaces.
.MACRO B_IF_PUNCT loc
CMP #'.
BEQ loc
CMP #'!
BEQ loc
CMP #'?
BEQ loc
.ENDMACRO
sleft
copy16 curr,tex
DEC tex+1
LDY #$FF
PMANY LDA (tex),Y
B_IF_PUNCT PSRCH
CMP #retchar
BNE psloop
PSRCH DEY
BNE PMANY
RTS
psloop LDA (tex),Y
B_IF_PUNCT PUNCT
CMP #retchar
BEQ PUNCT
DEY
BNE psloop
DEC tex+1
LDA tex+1
CMP texstart
BCS psloop
JMP firstword
PUNCT STY temp
DEC temp
SKIPSPC INY
BEQ REPEAT
LDA (tex),y
CMP #space
BEQ SKIPSPC
dey
jmp wrout
REPEAT ldy temp
jmp psloop
firstword copy16 texstart,curr
jmp check
; Sentence right. We look for ending punctuation,
; then skip forward until we run out of spaces.
sright LDY #0
srlp LDA (curr),Y
B_IF_PUNCT punct2
CMP #retchar
BEQ punct2
INY
BNE srlp
inc curr+1
lda curr+1
cmp lastline+1
beq srlp
bcc srlp
srexit jmp lastword
punct2 iny
bne nofixcurr
inc curr+1
lda curr+1
cmp lastline+1
bcc nofixcurr
beq nofixcurr
jmp lastword
nofixcurr lda (curr),y