-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathmmfs100.asm
8470 lines (7676 loc) · 136 KB
/
mmfs100.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
\** MMFS ROM by Martin Mather
\** Compiled using BeebAsm V1.04
\** August 2011
\** Includes code from Acorn's DFS 2.26, and DFS 2.24 (Master)
\** MAIN CODE **\
\\ Include *DONBOOT and code to load the default drives on startup
\\ (costs 45 bytes)
_DONBOOT_=NOT(_MM32_)
\\ Enable support for large (>512 disk) MMB files
\\ (costs 128 bytes)
_LARGEMMB_=NOT(_MM32_)
\\ Include *DBASE and code to load the default base on startup
\\ (costs 95 bytes)
_DBASE_=NOT(_MM32_)
;; At the moment, we either include or exclude all the optional commands
;; Normal Commands
_INCLUDE_CMD_ACCESS_=_COMMANDS_
_INCLUDE_CMD_BACKUP_=_COMMANDS_
_INCLUDE_CMD_COMPACT_=_COMMANDS_
_INCLUDE_CMD_COPY_=_COMMANDS_
_INCLUDE_CMD_DELETE_=_COMMANDS_
_INCLUDE_CMD_DESTROY_=_COMMANDS_
_INCLUDE_CMD_ENABLE_=_COMMANDS_
_INCLUDE_CMD_FORM_VERIFY_=_COMMANDS_
_INCLUDE_CMD_FREE_MAP_=_COMMANDS_
_INCLUDE_CMD_RENAME_=_COMMANDS_
_INCLUDE_CMD_TITLE_=_COMMANDS_
_INCLUDE_CMD_WIPE_=_COMMANDS_
;; DUTILS Commands
_INCLUDE_CMD_DBASE_=_COMMANDS_ AND _DBASE_
_INCLUDE_CMD_DCAT_=_COMMANDS_
_INCLUDE_CMD_DDRIVE_=_COMMANDS_
_INCLUDE_CMD_DFREE_=_COMMANDS_
_INCLUDE_CMD_DONBOOT_=_COMMANDS_ AND _DONBOOT_
_INCLUDE_CMD_DOP_=_COMMANDS_
_INCLUDE_CMD_DRECAT_=_COMMANDS_
_INCLUDE_CMD_DABOUT_=_COMMANDS_
;; Additional MMFS2 DUTILs commands
_MM32_DRENAME=NOT(_BP12K_)
\ MA/MP constants must be even numbers
IF _MASTER_
CPU 1 ; 65C12
MA=&C000-&0E00 ; Offset to Master hidden static workspace
ELIF _BP12K_
; Memory at &Axxx in the 12K private RAM has the (to us) undesirable
; property that code running there accesses the display RAM, whether
; that's main or shadow RAM. We therefore can't have any code which
; needs to access user memory there. To use as much of it as possible up
; harmlessly, we situate our workspace in that range.
MA=&A200-&0E00
UTILSBUF=(&BF-&B6)+HI(MA+&0E00)
MAEND=(UTILSBUF+1)<<8
ELIF _SWRAM_
MA=&B600-&0E00
UTILSBUF=&BF ; Utilities buffer page
ELSE
MA=0
ENDIF
MP=HI(MA)
INCLUDE "VERSION.asm"
INCLUDE "SYSVARS.asm" ; OS constants
DirectoryParam=&CC
CurrentDrv=&CD
CurrentCat=MA+&1082
IF _MM32_
TubeNoTransferIf0=MA+&10AE
MMC_STATE=MA+&10AF
ELSE
TubeNoTransferIf0=MA+&109E
MMC_STATE=MA+&109F ; Bit 6 set if card initialised
ENDIF
FSMessagesOnIfZero=MA+&10C6
CMDEnabledIf1=MA+&10C7
DEFAULT_DIR=MA+&10C9
DEFAULT_DRIVE=MA+&10CA
LIB_DIR=MA+&10CB
LIB_DRIVE=MA+&10CC
PAGE=MA+&10CF
RAMBufferSize=MA+&10D0 ; HIMEM-PAGE
ForceReset=MA+&10D3
TubePresentIf0=MA+&10D6
CardSort=MA+&10DE
IF _LARGEMMB_
DiskTableIndex=MA+&10D4
MACRO DO_ASLA_X4
IF _SWRAM_
JSR A_rolx4 ; actually 4x ASL A
ELSE
ASL A
ASL A
ASL A
ASL A
ENDIF
ENDMACRO
MACRO MASK_DISKNO
AND #&1F
ENDMACRO
ELSE
MACRO MASK_DISKNO
AND #&01
ENDMACRO
ENDIF
buf%=MA+&E00
cat%=MA+&E00
FilesX8=MA+&F05
\\ TODO: CardSort should be protected by VID...
IF _MM32_
VID=MA+&10E0 ; VID
VID2=VID ; 14 bytes
MMC_CIDCRC=VID2+&E ; 2 bytes
CHECK_CRC7=VID2+&10 ; 1 byte
ELSE
IF _LARGEMMB_
VID=MA+&10DF ; VID
CHUNK_BASE=VID+&E ; 1 byte
NUM_CHUNKS=VID+&F ; 1 byte
CHECK_CRC7=VID+&10 ; 1 byte
ELSE
VID=MA+&10E0 ; VID
CHECK_CRC7=VID+&E ; 1 byte
ENDIF
DRIVE_INDEX0=VID ; 4 bytes
DRIVE_INDEX4=VID+4 ; 4 bytes
MMC_SECTOR=VID+8 ; 3 bytes
MMC_SECTOR_VALID=VID+&B ; 1 bytes
MMC_CIDCRC=VID+&C ; 2 bytes
ENDIF
IF _MM32_
OWCtlBlock = MA+&10B0 ; 16 bytes
ENDIF
IF _DFS_EMUL
filesysno%=&04 ; Filing System Number
filehndl%=&10 ; First File Handle - 1
ELSE
filesysno%=&74 ; Filing System Number
filehndl%=&70 ; First File Handle - 1
ENDIF
tubeid%=&0A ; See Tube Application Note No.004 Page 7
; &0A is unallocated so shouldn't clash
MACRO BP12K_NEST
IF _BP12K_
JSR PageIn12K
JSR nested
JMP PageOut12K
.nested
ENDIF
ENDMACRO
IF _SWRAM_ AND NOT(_BP12K_)
guard_value=&B5FE
;; Add a special marker that ZMMFS uses to identify an already installed SWMMFS
org &B5FE
EQUB MAGIC0
EQUB MAGIC1
ELSE
guard_value=&C000
ENDIF
ORG &8000
GUARD guard_value
\\ ROM Header
.langentry
BRK
BRK
BRK
.serventry
JMP MMFS_SERVICECALLS
.romtype
EQUB &82
.copywoffset
EQUB LO(copyright-1)
.binversion
EQUB &7B
.title
BUILD_NAME
.version
BUILD_VERSION
.copyright
BUILD_COPYRIGHT
.header_end
.Go_FSCV
JMP (FSCV)
\ Illuminate Caps Lock & Shift Lock
.SetLEDS
IF _ELECTRON_
LDA &282
EOR #&80
STA &282
STA &FE07
ELSE
LDX #&6
STX &FE40
INX
STX &FE40
ENDIF
RTS
\ Reset LEDs
.ResetLEDS
JSR RememberAXY
LDA #&76
JMP OSBYTE
.errDISK
JSR ReportErrorCB ; Disk Error
BRK
EQUS "Disc "
BCC ErrCONTINUE
.errBAD
JSR ReportErrorCB ; Bad Error
BRK
EQUS "Bad "
BCC ErrCONTINUE
\\ **** Report Error ****
\\ A string terminated with 0 causes JMP &100
\\ Check if writing channel buffer
.ReportErrorCB
LDA MA+&10DD ; Error while writing
BNE brk100_notbuf ; channel buffer?
JSR ClearEXECSPOOLFileHandle
.brk100_notbuf
LDA #&FF
STA CurrentCat
STA MA+&10DD ; Not writing buffer
.ReportError
LDX #&02
LDA #&00 ; "BRK"
STA &0100
.ErrCONTINUE
\STA &B3 ; Save A???
JSR ResetLEDS
.ReportError2
PLA ; Word &AE = Calling address + 1
STA &AE
PLA
STA &AF
\LDA &B3 ; Restore A???
LDY #&00
JSR inc_word_AE_and_load
STA &0101 ; Error number
DEX
.errstr_loop
INX
JSR inc_word_AE_and_load
STA &0100,X
BMI prtstr_return2 ; Bit 7 set, return
BNE errstr_loop
JSR TUBE_RELEASE
JMP &0100
\* print Nibble and fall into print string
.PrintNibble_PrintString
JSR PrintNibble
\ **** Print String ****
\ String terminated if bit 7 set
\ Exit: AXY preserved, C=0
.PrintString
STA &B3 ; Print String (bit 7 terminates)
PLA ; A,X,Y preserved
STA &AE
PLA
STA &AF
LDA &B3
PHA ; Save A & Y
TYA
PHA
LDY #&00
.prtstr_loop
JSR inc_word_AE_and_load
BMI prtstr_return1 ; If end
JSR PrintChrA
\\ PrintChrA uses RememberAXY, so the final instruction is PLA
\\ which means it's safe to BPL
BPL prtstr_loop ; always
.prtstr_return1
PLA ; Restore A & Y
TAY
PLA
.prtstr_return2
CLC
JMP (&00AE) ; Return to caller
\ As above sub, but can be spooled
.PrintStringSPL
{
STA &B3 ; Save A
PLA ; Pull calling address
STA &AE
PLA
STA &AF
LDA &B3 ; Save A & Y
PHA
TYA
PHA
LDY #&00
.pstr_loop
JSR inc_word_AE_and_load
BMI prtstr_return1
JSR OSASCI
JMP pstr_loop
}
IF _MM32_
\ Print space, on exit A=&20
.PrintSpace
LDA #' '
BNE PrintChrA
ENDIF
.PrintNibFullStop
JSR PrintNibble
.PrintFullStop
LDA #&2E
.PrintChrA
JSR RememberAXY ; Print character
PHA
LDA #&EC
JSR osbyte_X0YFF
TXA ; X = chr destination
PHA
ORA #&10
JSR osbyte03_Aoutstream ; Disable spooled output
PLA
TAX
PLA
JSR OSASCI ; Output chr
JMP osbyte03_Xoutstream ; Restore previous setting
IF _ROMS_
\ Currently only used in *ROMS so save 3bytes
\ Print BCD/Hex : A=number
.PrintBCD
JSR BinaryToBCD
ENDIF
.PrintHex
PHA
JSR A_rorx4
JSR PrintNibble
PLA
.PrintNibble
JSR NibToASC
BNE PrintChrA ; always
\ As above but allows it to be spooled
.PrintBCDSPL
JSR BinaryToBCD
.PrintHexSPL
PHA
JSR A_rorx4
JSR PrintNibbleSPL
PLA
.PrintNibbleSPL
JSR NibToASC
JMP OSASCI
\\ Print spaces, exit C=0 A preserved
.Print2SpacesSPL
JSR PrintSpaceSPL ; Print 2 spaces
.PrintSpaceSPL
PHA ; Print space
LDA #&20
JSR OSASCI
PLA
CLC
RTS
\ Convert low nibble to ASCII
.NibToASC
{
AND #&0F
CMP #&0A
BCC nibasc
ADC #&06
.nibasc
ADC #&30
RTS
}
.CopyVarsB0BA
{
JSR CopyWordB0BA
DEX
DEX ;restore X to entry value
JSR cpybyte1 ;copy word (b0)+y to 1072+x
.cpybyte1
LDA (&B0),Y
STA MA+&1072,X
INX
INY
RTS
}
.CopyWordB0BA
{
JSR cpybyte2 ;Note: to BC,X in 0.90
.cpybyte2
LDA (&B0),Y
STA &BA,X
INX
INY
RTS
}
.read_fspTextPointer
JSR Set_CurDirDrv_ToDefaults ; **Read filename to &1000
JMP rdafsp_entry ; **1st pad &1000-&103F with spaces
.read_fspBA_reset
JSR Set_CurDirDrv_ToDefaults ; Reset cur dir & drive
.read_fspBA
LDA &BA ; **Also creates copy at &C5
STA TextPointer
LDA &BB
STA TextPointer+1
LDY #&00
JSR GSINIT_A
.rdafsp_entry
LDX #&20 ; Get drive & dir (X="space")
JSR GSREAD_A ; get C
BCS errBadName ; IF end of string
STA MA+&1000
CMP #&2E ; C="."?
BNE rdafsp_notdot ; ignore leading ...'s
.rdafsp_setdrv
STX DirectoryParam ; Save directory (X)
BEQ rdafsp_entry ; always
.rdafsp_notdot
CMP #&3A ; C=":"? (Drive number follows)
BNE rdafsp_notcolon
JSR Param_DriveNo_BadDrive ; Get drive no.
JSR GSREAD_A
BCS errBadName ; IF end of string
CMP #&2E ; C="."?
BEQ rdafsp_entry ; err if not eg ":0."
.errBadName
JSR errBAD
EQUB &CC
EQUS "name",0
.rdafsp_notcolon
{
TAX ; X=last Chr
JSR GSREAD_A ; get C
BCS Rdafsp_padall ; IF end of string
CMP #&2E ; C="."?
BEQ rdafsp_setdrv
LDX #&01 ; Read rest of filename
.rdafsp_rdfnloop
STA MA+&1000,X
INX
JSR GSREAD_A
BCS rdafsp_padX ; IF end of string
CPX #&07
BNE rdafsp_rdfnloop
BEQ errBadName
}
.GSREAD_A
{
JSR GSREAD ; GSREAD ctrl chars cause error
PHP ; C set if end of string reached
AND #&7F
CMP #&0D ; Return?
BEQ dogsrd_exit
CMP #&20 ; Control character? (I.e. <&20)
BCC errBadName
CMP #&7F ; Backspace?
BEQ errBadName
.dogsrd_exit
PLP
RTS
}
.SetTextPointerYX
STX TextPointer
STY TextPointer+1
LDY #&00
RTS
.GSINIT_A
CLC
JMP GSINIT
.Rdafsp_padall
LDX #&01 ; Pad all with spaces
.rdafsp_padX
{
LDA #&20 ; Pad with spaces
.rdafsp_padloop
STA MA+&1000,X
INX
CPX #&40 ; Why &40? : Wildcards buffer!
BNE rdafsp_padloop
LDX #&06 ; Copy from &1000 to &C5
.rdafsp_cpyfnloop
LDA MA+&1000,X ; 7 byte filename
STA &C5,X
DEX
BPL rdafsp_cpyfnloop
RTS
}
.prt_filename_Yoffset
{
JSR RememberAXY
LDA MA+&0E0F,Y
PHP
AND #&7F ; directory
BNE prt_filename_prtchr
JSR Print2SpacesSPL ; if no dir. print " "
BEQ prt_filename_nodir ; always?
.prt_filename_prtchr
JSR PrintChrA ; print dir
JSR PrintFullStop ; print "."
.prt_filename_nodir
LDX #&06 ; print filename
.prt_filename_loop
LDA MA+&0E08,Y
AND #&7F
JSR PrintChrA
INY
DEX
BPL prt_filename_loop
JSR Print2SpacesSPL ; print " "
LDA #&20 ; " "
PLP
BPL prt_filename_notlocked
LDA #&4C ; "L"
.prt_filename_notlocked
JSR PrintChrA ; print "L" or " "
LDY #&01
}
.prt_Yspaces
JSR PrintSpaceSPL
DEY
BNE prt_Yspaces
RTS
.A_rorx6and3
LSR A
LSR A
.A_rorx4and3
LSR A
LSR A
.A_rorx2and3
LSR A
LSR A
AND #&03
RTS
.A_rorx5
LSR A
.A_rorx4
LSR A
.A_rorx3
LSR A
LSR A
LSR A
RTS
.A_rolx5
ASL A
.A_rolx4
ASL A
ASL A
ASL A
ASL A
.getcat_exit
RTS
.parameter_afsp_Param_SyntaxErrorIfNull_getcatentry_fspTxtP
JSR parameter_afsp
.Param_SyntaxErrorIfNull_getcatentry_fspTxtP
JSR Param_SyntaxErrorIfNull
.getcatentry_fspTxtP
JSR read_fspTextPointer
BMI getcatentry ;always
.getcatentry_fspBA
JSR read_fspBA_reset
.getcatentry
JSR get_cat_firstentry80
BCS getcat_exit
.err_FILENOTFOUND
JSR ReportError
EQUB &D6
EQUS "Not found",0 ; Not Found error
\ *EX (<dir>)
.fscv9_starEX
JSR SetTextPointerYX
.CMD_EX
{
JSR Set_CurDirDrv_ToDefaults
JSR GSINIT_A
BEQ cmd_ex_nullstr ; If null string
JSR ReadDirDrvParameters2 ; Get dir
.cmd_ex_nullstr
LDA #&2A ; "*"
STA MA+&1000
JSR Rdafsp_padall
JSR parameter_afsp
JSR getcatentry
JMP cmd_info_loop
}
\ *INFO <afsp>
.fscv10_starINFO
JSR SetTextPointerYX
LDA #info_cmd_index - cmdtable1-1 ; BF needs to point to the INFO command
STA &BF ; Param_SyntaxErrorIfNull to work
.CMD_INFO
JSR parameter_afsp_Param_SyntaxErrorIfNull_getcatentry_fspTxtP
.cmd_info_loop
JSR prt_InfoLine_Yoffset
JSR get_cat_nextentry
BCS cmd_info_loop
RTS
.get_cat_firstentry81
JSR CheckCurDrvCat ; Get cat entry
LDA #&00
BEQ getcatentry2 ; always
.get_cat_firstentry80fname
LDX #&06 ; copy filename from &C5 to &1058
.getcatloop1
LDA &C5,X
STA MA+&1058,X
DEX
BPL getcatloop1
LDA #&20
STA MA+&105F
LDA #&58
BNE getcatentry1 ; always
.get_cat_nextentry
LDX #&00 ; Entry: wrd &B6 -> first entry
BEQ getcatloop2 ; always
.get_cat_firstentry80
LDA #&00 ; now first byte @ &1000+X
.getcatentry1
PHA ; Set up & return first
JSR CheckCurDrvCat ; catalogue entry matching
PLA ; string at &1000+A
.getcatentry2
TAX
LDA #&00 ; word &B6 = &E00 = PTR
STA &B6
.getcatloop2
LDY #&00
LDA #MP+&0E ; string at &1000+A
STA &B7
LDA &B6
CMP FilesX8
BCS matfn_exitC0 ; If >FilesX8 Exit with C=0
ADC #&08
STA &B6 ; word &B6 += 8
JSR MatchFilename
BCC getcatloop2 ; not a match, try next file
LDA DirectoryParam
LDY #&07
JSR MatchChr
BNE getcatloop2 ; If directory doesn't match
LDY &B6
SEC ; Return, Y=offset-8, C=1
.Y_sub8
DEY
DEY
DEY
DEY
DEY
DEY
DEY
DEY
RTS
.MatchFilename
{
JSR RememberAXY ; Match filename at &1000+X
.matfn_loop1
LDA MA+&1000,X ; with that at (&B6)
CMP MA+&10CE
BNE matfn_nomatch ; e.g. If="*"
INX
.matfn_loop2
JSR MatchFilename
BCS matfn_exit ; If match then exit with C=1
INY
CPY #&07
BCC matfn_loop2 ; If Y<7
.matfn_loop3
LDA MA+&1000,X ; Check next char is a space!
CMP #&20
BNE matfn_exitC0 ; If exit with c=0 (no match)
RTS ; exit with C=1
.matfn_nomatch
CPY #&07
BCS matfn_loop3 ; If Y>=7
JSR MatchChr
BNE matfn_exitC0
INX
INY
BNE matfn_loop1 ; next chr
}
.matfn_exitC0
CLC ; exit with C=0
.matfn_exit
RTS
.MatchChr
{
CMP MA+&10CE
BEQ matchr_exit ; eg. If "*"
CMP MA+&10CD
BEQ matchr_exit ; eg. If "#"
JSR IsAlphaChar
EOR (&B6),Y
BCS matchr_notalpha ; IF not alpah char
AND #&5F
.matchr_notalpha
AND #&7F
.matchr_exit
RTS ; If n=1 then matched
}
.UcaseA2
{
PHP
JSR IsAlphaChar
BCS ucasea
AND #&5F ; A=Ucase(A)
.ucasea
AND #&7F ; Ignore bit 7
PLP
RTS
}
.DeleteCatEntry_YFileOffset
{
JSR CheckFileNotLockedOrOpenY ; Delete catalogue entry
.delcatloop
LDA MA+&0E10,Y
STA MA+&0E08,Y
LDA MA+&0F10,Y
STA MA+&0F08,Y
INY
CPY FilesX8
BCC delcatloop
TYA
SBC #&08
STA FilesX8
CLC
}
.print_infoline_exit
RTS
.IsAlphaChar
{
PHA
AND #&5F ; Uppercase
CMP #&41
BCC isalpha1 ; If <"A"
CMP #&5B
BCC isalpha2 ; If <="Z"
.isalpha1
SEC
.isalpha2
PLA
RTS
}
.prt_InfoMsg_Yoffset
BIT FSMessagesOnIfZero ; Print message
BMI print_infoline_exit
.prt_InfoLine_Yoffset
JSR RememberAXY ; Print info
JSR prt_filename_Yoffset
TYA ; Save offset
PHA
LDA #&60 ; word &B0=1060
STA &B0
LDA #MP+&10
STA &B1
JSR ReadFileAttribsToB0_Yoffset ; create no. str
LDY #&02
JSR PrintSpaceSPL ; print " "
JSR PrintHex3Byte ; Load address
JSR PrintHex3Byte ; Exec address
JSR PrintHex3Byte ; Length
PLA
TAY
LDA MA+&0F0E,Y ; First sector high bits
AND #&03
JSR PrintNibble
LDA MA+&0F0F,Y ; First sector low byte
JSR PrintHex
\ Print New Line
.PrintNewLine
PHA
LDA #&0D
JSR PrintChrA
PLA
RTS
.PrintHex3Byte
{
LDX #&03 ; eg print "123456 "
.printhex3byte_loop
LDA MA+&1062,Y
JSR PrintHex
DEY
DEX
BNE printhex3byte_loop
JSR Y_add7
JMP PrintSpaceSPL
}
.ReadFileAttribsToB0_Yoffset
{
JSR RememberAXY ; Decode file attribs
TYA
PHA ; bytes 2-11
TAX ; X=cat offset
LDY #&12 ; Y=(B0) offset
LDA #&00 ; Clear pwsp+2 to pwsp+&11
.readfileattribs_clearloop
DEY
STA (&B0),Y
CPY #&02
BNE readfileattribs_clearloop
.readfileattribs_copyloop
JSR readfileattribs_copy2bytes ; copy low bytes of
INY ; load/exec/length
INY
CPY #&0E
BNE readfileattribs_copyloop
PLA
TAX
LDA MA+&0E0F,X
BPL readfileattribs_notlocked ; If not locked
LDA #&08
STA (&B0),Y ; pwsp+&E=8
.readfileattribs_notlocked
LDA MA+&0F0E,X ; mixed byte
LDY #&04 ; load address high bytes
JSR readfileattribs_addrHiBytes
LDY #&0C ; file length high bytes
LSR A
LSR A
PHA
AND #&03
STA (&B0),Y
PLA
LDY #&08 ; exec address high bytes
.readfileattribs_addrHiBytes
LSR A
LSR A ; /4
PHA
AND #&03
CMP #&03 ; done slightly diff. to 8271
BNE readfileattribs_nothost
LDA #&FF
STA (&B0),Y
INY
.readfileattribs_nothost
STA (&B0),Y
.readfileattribs_exits
PLA
RTS
.readfileattribs_copy2bytes
JSR readfileattribs_copy1byte
.readfileattribs_copy1byte
LDA MA+&0F08,X
STA (&B0),Y
INX
INY
RTS
}
.inc_word_AE_and_load
{
INC &AE
BNE inc_word_AE_exit
INC &AF
.inc_word_AE_exit
LDA (&AE),Y
RTS
}
\\ Save AXY and restore after
\\ calling subroutine exited
.RememberAXY
PHA
TXA
PHA
TYA
PHA
LDA #HI(rAXY_restore-1) ; Return to rAXY_restore
PHA
LDA #LO(rAXY_restore-1)
PHA
.rAXY_loop_init
{
LDY #&05
.rAXY_loop
TSX
LDA &0107,X
PHA
DEY
BNE rAXY_loop
LDY #&0A
.rAXY_loop2
LDA &0109,X
STA &010B,X
DEX
DEY
BNE rAXY_loop2
PLA
PLA
}
.rAXY_restore
PLA
TAY
PLA
TAX
PLA
RTS
.RememberXYonly
PHA
TXA
PHA
TYA
PHA
JSR rAXY_loop_init
.axyret1
TSX
STA &0103,X
JMP rAXY_restore
IF NOT(_MM32_)
IF _LARGEMMB_
\ ** Convert 12 bit binary in word &B8/9 to
\ ** 4 digit BCD in word &B5/6 (decno%)
decno%=&B5
\Used by GetDisk
.DecNo_BIN2BCD
{
SED ; Switch to decimal mode
LDA #0 ; Ensure the result is clear
STA decno%+0
STA decno%+1
; STA decno%+2
LDX #16 ; The number of source bits