-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsoftrom.asm
1449 lines (1271 loc) · 27.6 KB
/
softrom.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
; **********************************************
; ************* SoftROM EEPROM tool ************
; **********************************************
;
; Assemble with "The Bit Shift Assembler"
; freely available from https://github.com/Edilbert/BSA
;
; Copyright (c) 2014 Nils Eilers <[email protected]>
; This work is free. You can redistribute it and/or modify it under the
; terms of the Do What The Fuck You Want to Public License, Version 2,
; as published by Sam Hocevar. See the COPYING file for more details.
; ************
; * Keycodes *
; ************
TAB = 9 ; Tab
CR = 13 ; Carriage Return
HOME = 19 ; Home
DEL = 20 ; Delete
CLR = 147 ; Clear
CDOWN = 17 ; Cursor Down
CRIGHT = 29 ; Cursor Right
CUP = 145 ; Cursor Up
CLEFT = 157 ; Cursor Left
; ****************
; * Screen codes *
; ****************
C8296 = 0
#if C8296
HOR_BAR = 102 ; -
VER_BAR = 97 ; |
UL = 104 ; upper left
UR = 106 ; upper right
LL = 98 ; lower left
LR = 100 ; lower right
TL = 101 ; T left
TR = 103 ; T right
TU = 105 ; T upper
TB = 99 ; T bottom
#else
HOR_BAR = 64 ; -
VER_BAR = 93 ; |
UL = 112 ; upper left
UR = 110 ; upper right
LL = 109 ; lower left
LR = 125 ; lower right
TL = 107 ; T left
TR = 115 ; T right
#endif
ROWS = 25
; ****************************
; * Some Zero Page Variables *
; ****************************
BP = $5e ; Buffer Pointer
STRPTR = $60 ; String Pointer
SP = $62 ; SCREEN Pointer
TP = $64 ; Temporary Pointer
SelPtr = $66 ; Selection pointer
; ************************
; * CBM Kernal Variables *
; ************************
STATUS = $96 ; Status byte
STKEY = $9b ; Stop key pressed?
BLNSW = $a7 ; Blink switch
BLNCT = $a8 ; Blink count
BLNON = $aa ; Blink On
EAL = $c9 ; used for LOAD, SAVE and TIM
FNLEN = $d1 ; Filename length
SA = $d3 ; Secondary address
FA = $d4 ; First sddress
FNADR = $da ; Filename address
DOS_Filename = $0342
; *************
; * Constants *
; *************
Screen = $8000
EntriesPerPage = 20
; *****************************************
; * Put the buffer after the program code *
; *****************************************
Buffer = [EOP & $ff00] + $100
PosDiskName = 8
PosDiskID = 26
; ***************************************************
; * The CBM 8000 Kernal has no jump table for these *
; ***************************************************
READY = $b403 ; $b3ff ; $b406 omitting prompt
TALK = $f0d2
LISTEN = $f0d5
SECOND = $f143
TKSA = $f193
CIOUT = $f19e
UNTLK = $f1ae
UNLSN = $f1b9
ACPTR = $f1c0
BSOUT = $ffd2
CHROUT = $ffd2
GETIN = $ffe4
Kernal_STOP = $f343
; ***************
; * Print Macro *
; ***************
MACRO MAC_Print(lab)
LDY #<lab
LDA #>lab
LDX #?lab
JSR PrintText
ENDMAC
MACRO MAC_Plot(Row,Col,Char)
LDA #Char
LDX #Row
LDY #Col
JSR PlotAt
ENDMAC
MACRO MAC_PutString(Row,Col,Text)
LDX #Row
LDY #Col
JSR GotoXY
LDX #<Text
LDY #>Text
JSR PutString
ENDMAC
; ***************************************************
; The directory is loaded into RAM beyond the program
; SOD = Start of directory
; EOD = End of directory
; ***************************************************
; **********************************
; * BASIC header for program start *
; **********************************
START = $0401
* = START ; *** BASIC *** CBM / PET series
.LOAD START ; LOAD address
.STORE START,EOP-START,"softrom.prg"
Link .WORD EndLink
; **********
Linenumber
; **********
.WORD 2015
; **********
SysCommand
; **********
.BYTE $9e ; SYS token
StartML .BYTE "(1065)"
.BYTE ':',$8f ; REM token
.BYTE " SOFTROM EEPROM TOOL 0.2"
LineEnd .BYTE 0
EndLink .WORD 0
JMP Main
NUMBER .BYTE "00000 "
UnitText .PET 'unit:',0
DriveText .PET 'drive:',0
HelpText .BYTE "<H> = HELP",0
ProgramText .BYTE " SOFTROM EEPROM TOOL (C) NILS EILERS & BS ",0
Msg_READY .BYTE "READY.",0
Cols .BYTE 80
Count .BYTE 0
CursorRow .BYTE 0
CursorCol .BYTE 0
Entries .BYTE 0
FirstLine .BYTE 0
LastLine .BYTE 20
HelpScreen .BYTE 0
Pages .BYTE 2
ScreenLo .FILL 25 (0)
ScreenHi .FILL 25 (0)
EntryLo .FILL 40 (0)
EntryHi .FILL 40 (0)
Page .BYTE 0
Offset .BYTE 0
Unit .BYTE 8
Drive .BYTE '0'
LV0 .BYTE 0
LV1 .BYTE 0
Reverse .BYTE 0
Select .BYTE 2
FirstFile .BYTE 0 ; First file on display
SOD .WORD 0 ; Start Of Directory
EOD .WORD 0 ; End Of Directory
TargetLo .BYTE $00
TargetHi .BYTE $90
SelectionLo .BYTE 0
SelectionHi .BYTE 0
SelFilename .BYTE 16
DiskStatus = $8000 + 201
HelpLen = 30
HelpLines = 7
HelpWin .BYTE "UP/DN MOVE SELECTION BAR ",0
.BYTE "+ / - CHANGE UNIT OR DRIVE #",0
.BYTE "HOME RESET THE SCREEN ",0
.BYTE "RETURN FLASH EEPROM FROM FILE",0
.BYTE "STOP QUIT THE PROGRAM ",0
.BYTE "H SHOW THIS HELP WINDOW ",0
.BYTE "ESC CLOSE HELP WINDOW ",0
; ********
ShowHelp
; ********
LDA #0
STA Offset
LDX #53
STX Count
LDX #8
LDY #24
JSR HorLine
LDX #16
LDY #24
JSR HorLine
LDX #16
STX Count
LDX #8
LDY #23
JSR VerLine
LDX #8
LDY #53
JSR VerLine
MAC_Plot( 8,23,UL)
MAC_Plot( 8,53,UR)
MAC_Plot(16,23,LL)
MAC_Plot(16,53,LR)
LDA #HelpLines
STA Count
LDX #9
LDY #24
JSR GotoXY
LDX #<HelpWin
LDY #>HelpWin
ShHe10 JSR PutString
LDX CursorRow
INX
LDY #24
JSR GotoXY
CLC
LDA STRPTR
ADC #HelpLen
TAX
LDA STRPTR+1
ADC #0
TAY
DEC Count
BNE ShHe10
LDA #$ff
STA HelpScreen
RTS
; ****
STOP
; ****
LDA STKEY
CMP #$ef
RTS
; **********
Error_Beep
; **********
LDA #7
JMP BSOUT
; *********
PrintText
; *********
STY SP
STA SP+1
LDY #0
PrTe_10 LDA (SP),Y
JSR BSOUT
INY
DEX
BNE PrTe_10
RTS
; ********************
Flush_Keyboard_Queue
; ********************
JSR GETIN
BNE Flush_Keyboard_Queue
RTS
; ***********
FormatByte
; ***********
; Convert binary number in (A) to
; three decimal digits in (Y),(X) and (A)
LDY #'0' ; 100
LDX #'0'-1 ; 10
SEC
asts_01 INX
SBC #10
BCS asts_01
ADC #$3a
CPX #$3a
BCC asts_rt ; X < 10
PHA
TXA
SBC #10 ; X -= 10
TAX
PLA
INY ; Y = 1
asts_rt RTS
; **************
FormatInteger
; **************
LDY #$2f ; X = low byte
SEC ; A = high byte
FORINT_01 INY
STX LV0
STA LV1
TXA
SBC #<10000
TAX
LDA LV1
SBC #>10000
BCS FORINT_01
STY NUMBER
LDX LV0
LDA LV1
LDY #$2f
SEC
FORINT_02 INY
STX LV0
STA LV1
TXA
SBC #<1000
TAX
LDA LV1
SBC #>1000
BCS FORINT_02
STY NUMBER+1
LDX LV0
LDA LV1
LDY #$2f
SEC
FORINT_03 INY
STX LV0
STA LV1
TXA
SBC #100
TAX
LDA LV1
SBC #0
BCS FORINT_03
STY NUMBER+2
LDA LV0
LDY #$2f
SEC
FORINT_04 INY
SBC #10
BCS FORINT_04
STY NUMBER+3
ADC #$3a
STA NUMBER+4
LDX #0
LDA #' '
FORINT_05 LDY NUMBER,X
CPY #'0'
BNE FORINT_06
STA NUMBER,X
INX
CPX #4
BCC FORINT_05
FORINT_06 RTS
; ********
ShowUnit
; ********
LDX #0
LDY Select
BNE ShUn10
LDX #$80
ShUn10 STX Reverse
LDX #2
LDY #6
JSR GotoXY
LDA Unit
JSR FormatByte
CPX #'0'
BEQ ShUn20
PHA
TXA
JSR PutCharR
PLA
ShUn20 JSR PutCharR
LDA #' '
JMP PutChar
; *********
ShowDrive
; *********
LDX #0
LDY Select
DEY
BNE ShDr10
LDX #$80
ShDr10 STX Reverse
LDA Drive
LDX #2
LDY #15
JMP PlotAtR
; ************
ShowDiskName
; ************
LDX #2
LDY #18
JSR GotoXY
LDA #' '
STA Buffer + PosDiskName + 16 ; delete quote
LDA #0
STA Buffer + PosDiskName + 20 ; mark string end
LDX #<[Buffer + PosDiskName]
LDY #>[Buffer + PosDiskName]
JMP PutString
; **************
FormatFilename
; **************
LDA BP
STA STRPTR
LDA BP+1
STA STRPTR+1
LDY #2
LDA (BP),Y ; Blocks low
TAX
INY
LDA (BP),Y ; Blocks high
JSR FormatInteger
LDY #0
FoFi10 LDA NUMBER+2,Y
STA (BP),Y
INY
CPY #4
BCC FoFi10
LDA (BP),Y
CMP #' '
BNE FoFi99
FoFi20 INC STRPTR
LDA (STRPTR),Y
CMP #' '
BEQ FoFi20
CMP #$22
BEQ FoFi20
STA (BP),Y
FoFi40 INY
CPY #$20
BCS FoFi99
FoFi50 LDA (STRPTR),Y
STA (BP),Y
BNE FoFi40
INC Entries
FoFi99 RTS
; *************
FormatEntries
; *************
LDA #0
STA Entries
LDA #$20 ; 1st. file
STA BP
LDA #>Buffer
STA BP+1
FoEn10 LDY #4 ; after link and #
LDA (BP),Y
CMP #' ' ; for filename must be blank
BNE FoEn99
JSR FormatFilename
JSR GetLoadAddress
LDX Entries
DEX
JSR ShowEntry
CLC
LDA BP
ADC #$20
STA BP
BCC FoEn20
INC BP+1
FoEn20 LDA EOD ; check for End Of Directory
CMP BP
LDA EOD+1
SBC BP+1
BCS FoEn10
FoEn99 RTS
; *******
PET2SCR
; *******
CMP #$41
BCC P2C99
CMP #$5b
BCS P2C10
AND #$1f ; a - z
RTS
P2C10 CMP #$c1
BCC P2C99
CMP #$ca
BCS P2C99
AND #$7f ; A - Z
P2C99 RTS
; *********
ShowEntry
; *********
; Input: (X) = entry # (unchanged)
; (BP) = buffer pointer
; Used: (A),(Y)
CPX LastLine
BCS ShEn99
LDY #0 ; no reverse
TXA ; entry # in (X)
CLC
ADC #2
CMP Select
BNE ShEn10
LDA EntryLo,X
STA SelectionLo
LDA EntryHi,X
STA SelectionHi
LDA BP
STA SelPtr
LDA BP+1
STA SelPtr+1
LDY #$80 ; selected
ShEn10 STY Reverse
LDA EntryLo,X
STA SP
LDA EntryHi,X
STA SP+1
LDY #0
ShEn20 LDA (BP),Y
BEQ ShEn99
CMP #$22 ; hide quote
BNE ShEn30
LDA #' '
ShEn30 JSR PET2SCR
ORA Reverse
STA (SP),Y
INY
CPY #32
BCC ShEn20
ShEn99 RTS
; ***********
ShowEntries
; ***********
LDA SOD
STA BP
LDA SOD+1
STA BP+1
LDX #0
ShoE10 JSR ShowEntry
CLC
LDA BP
ADC #$20
STA BP
BCC ShoE20
INC BP+1
ShoE20 INX
CPX LastLine
BCS ShoE99
TXA
ADC FirstLine ; Carry is clear
CMP Entries
BCC ShoE10
ShoE99 RTS
; ***********
RightSelect
; ***********
LDA Select
BEQ IncSelect ; Unit -> Drive
CMP #2
BCC RiSe99 ; Drive
CLC
ADC #18
CMP Entries
BCS RiSe99
ADC #2
STA Select
RiSe99 RTS
; **********
LeftSelect
; **********
LDA Select
CMP #1
BEQ DecSelect ; Unit <- Drive
CMP #23
BCC LeSe99
SBC #20
STA Select
LeSe99 RTS
; *********
IncSelect
; *********
; Increment selection
; 0 : unit
; 1 : drive
; > 1 : filename
LDX Select
BEQ InSe40 ; Unit
DEX
BEQ InSe40 ; Drive
CPX LastLine
BCC InSe20
CLC ; Scroll display
LDA FirstLine
ADC LastLine
CMP Entries
BCS InSe30 ; At end alreay
INC FirstLine
LDA SOD ; Advance SOD
ADC #$20
STA SOD
BCC InSe10
INC SOD+1
InSe10 RTS
InSe20 CPX Entries
BCC InSe40 ; in range
InSe30 LDX #1
STX Select ; wrap around
InSe40 INC Select
InSe99 RTS
; *********
DecSelect
; *********
; Decrement selection
; 0 : unit
; 1 : drive
; > 1 : filename
LDX Select
CPX #2 ; First file
BNE DeSe20
LDA FirstLine ; Scroll display
BEQ DeSe20
DEC FirstLine
SEC
LDA SOD
SBC #$20
STA SOD
BCS DeSe10
DEC SOD+1
DeSe10 RTS
DeSe20 DEC Select
BPL DeSe99
LDX Entries
CPX LastLine
BCC DeSe30
LDX LastLine
DeSe30 INX
STX Select ; wrap around
DeSe99 RTS
; *************
ShowSelection
; *************
JSR ShowUnit
JSR ShowDrive
JMP ShowEntries
; ********
IncValue
; ********
LDX Select
BNE InVa10
LDA Unit
CMP #11
BCS InVa99
INC Unit
BNE InVa20
InVa10 DEX
BNE InVa99
LDA Drive
CMP #'9'
BCS InVa99
INC Drive
InVa20 JSR Reload
InVa99 RTS
; ********
DecValue
; ********
LDX Select
BNE DeVa10
LDA Unit
CMP #9
BCC DeVa99
DEC Unit
BNE DeVa20
DeVa10 DEX
BNE DeVa99
LDA Drive
CMP #'1'
BCC DeVa99
DEC Drive
DeVa20 JSR Reload
DeVa99 RTS
; **********
HomeSelect
; **********
LDA #0
STA Select
STA FirstLine
LDA #$20
STA SOD
LDA #>Buffer
STA SOD+1
RTS
; ********
MainLoop
; ********
JSR GETIN
BEQ MainLoop
BIT HelpScreen
BPL MaLo02
PHA
JSR Repaint
PLA
MaLo02 CMP #3 ; STOP key
BEQ MaLo99
CMP #TAB
BEQ MaLo85
CMP #CDOWN
BEQ MaLo85
MaLo05 CMP #CUP
BNE MaLo10
JSR DecSelect
JMP MaLo90
MaLo10 CMP #CRIGHT
BNE MaLo15
JSR RightSelect
JMP MaLo90
MaLo15 CMP #CLEFT
BNE MaLo20
JSR LeftSelect
JMP MaLo90
MaLo20 CMP #'+'
BNE MaLo25
JSR IncValue
JMP MaLo90
MaLo25 CMP #'-'
BNE MaLo30
JSR DecValue
JMP MaLo90
MaLo30 CMP #HOME
BNE MaLo35
JSR HomeSelect
JMP MaLo90
MaLo35 CMP #'H'
BNE MaLo40
JSR ShowHelp
JMP MainLoop
MaLo40 CMP #13
BNE MaLo45
JMP Flash
MaLo45 JMP MainLoop
MaLo85 JSR IncSelect
MaLo90 JSR ShowSelection
JMP MainLoop
MaLo99 RTS
; *******
Repaint
; *******
LDA #0
STA HelpScreen
JSR PaintMask
JSR ShowUnit
JSR ShowDrive
JSR ShowDiskName
LDA Entries
BEQ Repa10
LDA #2
STA Select
JSR ShowEntries
JSR ShowUnit
Repa10 RTS
; ******
Reload
; ******
LDA #0
STA Entries
JSR LoadDirectory
JSR FormatEntries
JSR Repaint
RTS
; ****
Init
; ****
LDA #8
STA Unit
LDA #'0'
STA Drive
LDA #0
STA CursorRow
STA CursorCol
STA Entries
STA Offset
STA Reverse
STA Select
STA FirstLine
RTS
; ****
Main
; ****
JSR Detect_BASIC_version
JSR Detect_Screen_Width
JSR SetupScreen
JSR Repaint
JSR SetupEntries
JSR Init
JSR Reload
JSR MainLoop
JSR Flush_Keyboard_Queue
LDA #<Msg_READY
LDY #>Msg_READY
JMP READY
; ********************
Detect_BASIC_version
; ********************
; TODO: detect BASIC version and patch vectors
RTS
; *******************
Detect_Screen_Width
; *******************
; TODO: detect Screen Width
LDA #80
STA Cols
LDA #2
STA Pages
LDA #40
STA LastLine
RTS
; ***********
SetupScreen
; ***********
LDA #CLR
JSR CHROUT ; clear screen
LDA #130
JSR CHROUT ; legacy character set
LDA #<Screen
LDX #>Screen
LDY #0
SeSe10 STA ScreenLo,Y
TXA
STA ScreenHi,Y
CLC
LDA ScreenLo,Y
ADC Cols
BCC SeSe20
INX
SeSe20 INY
CPY #ROWS
BCC SeSe10
RTS
; ************
SetupEntries
; ************
LDY #0
SeEn10 LDA ScreenLo+4,Y
LDX ScreenHi+4,Y
ORA #1
STA EntryLo,Y
PHA
TXA
STA EntryHi,Y
PLA
CLC
ADC #40
STA EntryLo+EntriesPerPage,Y
BCC SeEn20
INX
SeEn20 TXA
STA EntryHi+EntriesPerPage,Y
INY
CPY #EntriesPerPage
BCC SeEn10
RTS
; ********
HorLine
; ********
; Draw a horizontal line
; (X) = Row
; (Y) = Start column
; Count = Last column + 1
CLC
LDA ScreenLo,X
ADC Offset
STA SP
LDA ScreenHi,X
ADC #0