-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsjload.s
724 lines (678 loc) · 12.2 KB
/
sjload.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
.feature labels_without_colons
.include "defs64.inc"
feature_colors = 2
; SJLOAD - C64 floppy speeder and disk utility
; based on VDOS by Edward Carroll 1986
; modified for Jiffy compatibility by 1570 in 2008
; todo
; move core routines above $e000 instead of $cb00
; much cleanup
; xa65 assembler format
; Usage:
; LOAD"!*PROGRAM",8,1 - autostart VDOS, fastload PROGRAM
; LOAD"!",8 RUN - save autostarting VDOS to (new) disk
; VERIFY - send commands, read floppy status
; VERIFY"$" - display directory
; VDOS uses memory at CB00 and therefore limits length
; of programs loaded to basic start to about 195 blocks.
.word $031a
.org $031a
; BASIC header SYS 2169 ($0879)
; In case this gets loaded to BASIC start (,8)
; Will overwrite IOPEN, ICLOSE, ICHKIN, ICHKOUT,
; ICLRCH, IBASIN vectors otherwise
firstbyte:
.byt $0b,$08,$d8
.byt $07,$9e,$32
.byt $31,$36,$39
.byt $00,$00,$00
; IBASOUT/CHROUT vector ($0326)
.word autostart
; ISTOP ($0328)
.word $f6ed
; IGETIN ($032A)
.word $f13e
; ICLALL ($032C)
.word $f32f
; USRCMD ($032E)
.word $fe66
; ILOAD ($0330)
iload: .word $f4a5
; ISAVE ($0332)
.word $f5ed
; $DD00 bits
; 0..1 VIC bank
; 2 RS-232 TXD Ausgang, User PA 2
; 3..5 IEC OUT. 0=High/Inactive, 1=Low/Active.
; 3 ATN OUT
; 4 CLOCK OUT
; 5 DATA OUT
; 6..7 IEC IN. 0=Low/Active, 1=High/Inactive.
; 6 CLOCK IN
; 7 DATA IN
autostart:
jsr $fd15 ; restore kernal vectors
sei
lda #$30
sta $01
l33c ldy #$00
l33e lda da80code,y
l341 sta $da80,y
iny
bne l33e
inc l33e+2
inc l341+2
lda l341+2
cmp #$e0
bne l33c
lda #$00
sta $0800 ; remove garbage in $0800 confusing RUN
l359 jsr ldace ; install helpers, display message
jsr $a533 ; rechain basic lines
lda $22
clc
adc #$02
sta $2d
lda $23
adc #$00
sta $2e
jsr $a660 ; clear screen
ldy $b7 ; number of characters in filename
dey
bne autoload ; b.i. more than 1 character in filename
l374 jmp ($a002) ; basic warm start
autoload:
dey
sty $b7 ; number of characters in filename
lda $bb
clc
adc #$02
sta $bb ; advance filename pointer by two chars ("!*")
bcc l385
l383 inc $bc
l385 lda #$01
sta $b9 ; current sa
lda #$a4
pha
lda #$7f
pha
jmp $e16f ; load (will jump through iload)
; Code called by BASIC stub.
; Just copies everything to standard location and saves.
; Located at $0879.
l392 lda #$61
sta $b9 ; Secondary address ($61 = SAVE)
lda #$01
ldx #<filename
ldy #>filename
jsr $ffbd ; Set Filename
ldy #$00
l3a1 lda $0801,y
sta firstbyte+$0000,y
lda $0901,y
sta firstbyte+$0100,y
lda $0a01,y
sta firstbyte+$0200,y
lda $0b01,y
sta firstbyte+$0300,y
lda $0c01,y
sta firstbyte+$0400,y
iny
bne l3a1
l3c2 jsr $f3d5 ; Send Secondary Address
lda #<firstbyte
sta $c1
lda #>firstbyte
sta $c2 ; Set start address
lda #<$07ff ; TODO use proper end address
sta $ae
lda #>$07ff
sta $af ; Set end address
jsr $f60b ; Save (without printing "SAVING")
lda #$01
sta $b7 ; Number of characters in filename
jmp autostart
filename:
da80code = * + 1
.byt $21
.org $da80
lda80 jsr lda89 ; swap cb00.. and db00..
jsr ldaf2 ; move helper to 02e1
jmp lcd6a ; display message, install load vector, exit
; swap cb00.. and db00..
lda89 php
pha
stx ldafe
sty ldaff
lda #$db
sta ldaa7
sta ldaae
lda #$cb
sta ldaab
sta ldab2
ldx #$05
ldy #$00
ldaa5
ldaa7 = * + 2
lda $db00,y
pha
ldaab = * + 2
lda $cb00,y
ldaae = * + 2
sta $db00,y
pla
ldab2 = * + 2
sta $cb00,y
iny
bne ldaa5
ldab6 inc ldaa7
inc ldaae
inc ldaab
inc ldab2
dex
bne ldaa5
ldac5 ldx ldafe
ldy ldaff
pla
plp
ldace = * + 1
rts
; this code portion is relocatable and called both at $dace and $02e1
.org $02e1
clc
.byt $24 ; bit $xx
; iload vector
vload: sec
sei
pha
lda $01
sta $92
lda #$30
sta $01
bcc vlnm
jmp ldaec ; swap cb00/db00, load/verify
vlnm: jmp lda80 ; install helper, display message
l2f6 jsr lda89 ; swap cb00.. and db00..
lda $92
sta $01
cli
rts
.org $daec
ldaec jsr lda89 ; swap cb00.. and db00..
jmp lcc05 ; load/verify
; move helper to 02e1
ldaf2 ldy #$1e
ldaf4 lda ldace,y
sta $02e1,y
dey
bpl ldaf4
ldafd rts
ldafe .byt $00
ldaff .byt $00
; db00
.org $cb00
lcb00 rts
lcb01 ora $fd,x
listDir:
bit $c5
bvc listDir
lda #$60
sta $b9 ; current sa
jsr $f3d5 ; Send Secondary Address
lcd96 lda $ba ; device number
jsr $ffb4 ; Command Serial Bus TALK
lda $b9 ; current sa
jsr $ff96 ; Send SA After Talk
; jsr lcd96 (was doubled in VDOS?)
jsr ldgc
jsr ldgc
lcb13 lda #$0d
jsr $e10c ; Output character
lda #$0a
jsr $e10c ; Output character
lda #$20
jsr $e10c ; Output character
jsr ldgc
jsr ldgc
jsr ldgc
tax
jsr ldgc
jsr $bdcd ; output number in FAC
lda #$20
jsr $e10c ; Output character
lcb2c jsr ldgc
beq lcb13
lcb31 ldy $d3
cpy #$19
bne lcb42
lcb37 cmp #$20
beq lcb42
lcb3b pha
lda #$3a ; ":"
jsr $ffd2 ; chrout
pla
lcb42 jsr $ffd2 ; chrout
jmp lcb2c
; get serial byte (with error handling)
ldgc: jsr $ffa5
bit $90
bvs lcb68
lcb4f bit $91
bpl readError
lcb53 bit $c5
bvs lcb63
lcb57 bit $c5
bvc lcb57
lcb5b bit $c5
bvs lcb5b
lcb5f bit $c5
bvc lcb5f
lcb63 tay
rts
; read error channel
readError:
jsr $aad7 ; output cr/lf
lcb68 jsr $ffab ; untalk
jsr $f642 ; in save (send LISTEN?)
lcb6e jsr $aad7 ; output cr/lf
jsr $ab3f ; output format character
lda $ba ; device number
jsr $ffb4 ; talk
lda #$6f
jsr $ff96 ; send sa after talk
lcb7e jsr $ffa5 ; handhake serial byte in
jsr $ffd2 ; chrout
cmp #$0d
bne lcb7e
lcb88 jsr $ffab ; untalk
lda #$00
sta $c6 ; number of chars in keyboard buffer
vExit: ldx #$fb
txs
lda #>$a473
ldy #<$a473 ; Restart BASIC ($a474)
jmp returnOut
; send drive command
sendCmd:
lda #$6f
pha
lda $ba ; device number
jsr $ffb1 ; Command Serial Bus LISTEN
pla
jsr $ff93 ; Send SA After Listen
ldy #$00
lcd4d lda ($bb),y
jsr $ffa8 ; handshake serial byte out
iny
cpy $b7 ; number of characters in filename
bcc lcd4d
jsr $ffae ; unlisten
jmp vExit
; load/verify
lcc05 lda #$37
sta $01
cli
pla
load sta $93 ; load/verify flag
lda #$00
sta $90 ; iec status
lda $ba ; device number
bne cdn
jmp $f713
cdn cmp #$03
bne lload
bcs lload
jmp $f4af
; actual LOAD routine
lload ldx $ba ; device number
cpx #$01 ; device 1 (default)? Override with 8.
bne vnstd
ldx #$08
stx $ba ; device number
vnstd: lda $93 ; load/verify
beq lnv ; b.i. load
lda $b7 ; number of characters in filename
bne vsc
jmp readError
vsc: ldy #$00
lda ($bb),y ; file name
cmp #$24
bne sendCmd
jmp listDir
lnv: ldx $b7 ; length of filename
bne lfnok
lda #>$f712
ldy #<$f712
jmp returnOut ; illegal device number ($f713)
lfnok ldx $b9 ; secondary address
jsr $f5af ; searching for filename
sei
lda $d011
and #$ef
sta $d011 ; disable screen
ld1 lda $d011 ; wait for next screen
bpl ld1
ld2 lda $d011
bmi ld2
lda #$60 ; sa for load
sta $b9 ; secondary address
jsr $f3d5 ; open file/open secondary address
sei ; $f3d5 does cli
lda $ba ; device number
jsr ltalk ; talk
lda $b9 ; secondary address
jsr lsendsa ; send sa
jsr lgiecin ; iecin (get load address lo)
sta $ae ; load address lo
lda $90 ; iec status
lsr
lsr
bcc liecok
lda #>$f703
ldy #<$f703
jmp returnOut ; file not found ($f704)
liecok jsr lgiecin ; iecin (get load address hi)
sta $af ; load address hi
inc $b9 ; secondary address 61 = JD load
jsr luntalk ; untalk
lda $ba ; device number
jsr ltalk ; talk
lda $b9 ; secondary address
jsr lsendsa ; send sa
dec $b9 ; secondary address
cpx #$00 ; original secondary address
bne lloadabs2 ; branch if load absolute
lda $c3 ; basic start lo
sta $ae ; load address lo
lda $c4 ; basic start hi
sta $af ; load address hi
lloadabs2 jsr $f5d2 ; loading message
ldy #$00
ldx #$00
ljlw: dex
bne ljlw
lda $d020
sta $0110
lloadinnerloop:
lda $0110
sta $d020
lda #$03
sta $dd00 ; IEC lines inactive/high
lwch1 bit $dd00
bvc lwch1 ; wait until 1541 sets clock inactive/high
bmi lprocessdrivesignal ; branch if data inactive/high (some signal to process)
ltransferblock:
bit $dd00
bpl ltransferblock ; wait until 1541 sets data inactive/high
ltransferbyte:
.if feature_colors=2
nop
inc $d020 ; 6
.else
nop ; timing critical section
nop ; 2
nop
nop
.endif
lda #$03
ldx #$23
stx $dd00 ; data=active,clock=inactive,ATN=inactive
bit $dd00
bvc lloadinnerloop ; branch if 1541 sets clock active (needs to load next block)
nop
sta $dd00 ; set data inactive
lda $dd00 ; read bits 1/0
nop
lsr
lsr
eor $dd00 ; read bits 3/2
bit $00 ; burn cycles
lsr
lsr
eor $dd00 ; read bits 5/4
bit $00 ; burn cycles
lsr
lsr
eor $dd00 ; read bits 7/6
eor #$03
sta ($ae),y ; store byte
inc $ae ; load address lo
bne ltransferbyte
inc $af ; load address hi
jmp ltransferbyte
lprocessdrivesignal:
ldx #$64
lwok1 bit $dd00
bvc lend2 ; 1541 sets clock active/low: everything ok
dex
bne lwok1 ; wait for ok signal or timeout
lda #$42 ; end, error
.byt $2c
lend2 lda #$40 ; end, okay
jsr $fe1c ; set iec status ($90)
jsr luntalk ; UNTALK
jsr $f642 ; In Save (close file)
bcc lend3
lda #>$f703
ldy #<$f703
jmp returnOut ; file not found ($f704)
lend3 lda #>$f5a8
ldy #<$f5a8
jmp returnOut ; ok ($f509)
; TALK
ltalk ora #$40
lsendb sta $95 ; byte to send
jsr $ee97 ; Set Data inactive
cmp #$3f
bne lca1
jsr $ee85 ; Set Clock inactive
lca1 lda $dd00
ora #$08
sta $dd00 ; Set ATN active
; send IEC byte
lwiecs jsr $ee8e ; Set Clock active
jsr $ee97 ; Set Data inactive
jsr $eeb3 ; Delay 1 ms
jsr $eea9 ; Data => Carry, Clock => M
bcc lcont1 ; branch if data active
lda #>$edac
ldy #<$edac
jmp returnOut ; device not found ($edad)
lcont1 jsr $ee85 ; Set Clock inactive
lcont4 jsr $eea9 ; Data => Carry, Clock => M
bcc lcont4 ; Wait until data inactive
jsr $ee8e ; Set Clock active
txa
pha ; save X
ldx #$08 ; 8 bits to send
lsendbits nop
nop
nop
bit $dd00
bmi lcont5
pla
tax ; restore X
lda #>$edaf
ldy #<$edaf
jmp returnOut ; timeout ($edb0)
lcont5 jsr $ee97 ; Set Data inactive
ror $95 ; byte to send
bcs lci1
jsr $eea0 ; Set Data active
lci1 jsr $ee85 ; Set Clock inactive
lda $dd00
and #$df
ora #$10
; send two bits
sta $dd00
and #$08
beq ltwobitssent
lda $95 ; byte to send
ror
ror
cpx #$02
bne ltwobitssent
ldx #$1e
lwack1 bit $dd00
bpl lwack2
dex
bne lwack1
beq lcont6
lwack2 bit $dd00
bpl lwack2
; when we are here JD is present in floppy
lcont6 ldx #$02
ltwobitssent:
dex ; other dex is above
bne lsendbits ; branch if still bits to send
ldx #$56
lcont7: dex
beq ltbtimeout
lda $dd00
bmi lcont7 ; wait until data active
ltbok: pla
tax ; restore X
rts
ltbtimeout:
pla
tax ; restore X
lda #>$edaf
ldy #<$edaf
jmp returnOut ; Write timeout ($edb0)
; SEND SECONDARY ADDRESS
lsendsa sta $95 ; byte to send
jsr lwiecs ; send IEC byte
lda #$23 ; Data active, ATN/clock inactive
sta $dd00
lwca1 bit $dd00
bvs lwca1 ; Wait until clock active
rts
; UNTALK
luntalk lda $dd00
ora #$08
sta $dd00 ; Set ATN active
jsr $ee8e ; Set Clock active
lda #$5f ; UNTALK command
jsr lsendb ; send byte
jsr $edbe ; Clear ATN
txa
ldx #$0a
ll2 dex
bne ll2
tax
jsr $ee85 ; Set Clock inactive
jmp $ee97 ; Set Data inactive
; IECIN (jumped to from EE13)
lgiecin:
ll3 lda $dd00
cmp #$40
bcc ll3
.if feature_colors=1
inc $d020
.else
nop
nop
nop
.endif
nop
nop
nop
nop
nop
lda #$03
nop
nop
sta $dd00
nop
nop
nop
.if feature_colors=1
dec $d020
.else
nop
nop
nop
.endif
ora $dd00
lsr
lsr
nop
ora $dd00
lsr
lsr
eor #$03
eor $dd00
lsr
lsr
eor #$03
nop
eor $dd00
pha
lda #$23
bit $dd00
sta $dd00
bvc lend1
bpl lerr1
pla
lda #$42
jmp $edb2
lerr1 lda #$40 ; Too few bytes
jsr $fe1c ; In Control OS Messages
lend1 pla
clc
rts
; return to vector in a/y+1
returnOut:
pha
tya
pha
lcd27 sei
lda $d011
ora #$10
sta $d011 ; enable screen
lda #$30
sta $01
jsr ldaf2 ; move helper to 02e1
jmp l2f6 ; swap cb00/db00, cli, exit
; display message, install load vector, exit
lcd6a pla
lda #$37
sta $01
sta $92
; lda #$00
; sta $d021
; lda #$06
; sta $d020
; lda #<lcdac
; ldy #>lcdac
; jsr $ab1e ; output string
; print string
ldx #0
@l1:lda lcdac,X
beq @l2
jsr $ffd2
inx
bne @l1
@l2:
; inject keys
ldx #keys9-keys
@l3:lda keys-1,X
sta KEYD-1,x
inc NDX
dex
bne @l3
lda #<vload
ldy #>vload
sta iload
sty iload+1
jmp lcd27 ; install 02xx helper, swap cb00/db00, exit
; Message
lcdac .byt $93 ; ,$11,$9e
.byt "sjload 0.96+ - 2022-12-18",13
.byt 13,"load",'"',":*",'"',13,$13
.byt $00
; Keystrokes
keys:
.byt 13,"run",13
keys9:
.byt $08