-
Notifications
You must be signed in to change notification settings - Fork 1
/
main64.asm
521 lines (439 loc) · 11.6 KB
/
main64.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
// D71/D81 writer. Main module C64 version version 1.1
// ----------------------------------------
//
// This C64 software is intended to transfer a D71/D81 file
// from the 1541 Ultimate II back to disk.
//
// Inspired by http://csdb.dk/release/?id=120666 written by Jasmin68k
//
// This version was written by Ernoman.
// WdW added in May 2017:
// - kickassembler source format
// - path selector
// - sanity checks, some error handing
// - restoration of disk write commands
// - d71 writer
// -optimise : skip empty sectors
BasicUpstart2(MAIN)
.import source "kernal.asm"
.import source "diskwrite64.asm"
.import source "print.asm"
.import source "keyinput.asm"
.import source "ultio.asm"
.import source "reu.asm"
.pc = * "Main"
MAIN:
jsr DISPLAY_WELCOME
jsr DISPLAY_ULTIDOS
// todo: check for REU
// ask for d71 or d81
jsr ENTER_DISK_TYPE
lda INPUT_BUFFER
sec
sbc #$30
sta disk_type
lda disk_type
beq error_occurred // zero entered
cmp #3
bcs error_occurred // equal or higher than 3.
// ask for image path and select it
jsr ENTER_PATH
jsr DISPLAY_STATUS // get and print status
jsr STATUS_OK
beq !continue+
jmp error_occurred // abort
!continue:
jsr DISPLAY_CURRENT_PATH // display current path
// ask for file name and open it
jsr ENTER_FILE_NAME // name of d81 file to open
jsr ULT_OPEN_FILE_READ // attempt to open the file on sd card
jsr DISPLAY_STATUS // get and print status
jsr STATUS_OK // check status. 0=ok
beq !continue+
jmp error_occurred // abort
!continue:
// ask for destination device id
lda #0 // reset device id
sta device
jsr ENTER_DEVICE // get destination id
ldx #0 // reset input buffer offset
ldy INPUT_LEN // how many digits entered?
beq error_occurred // nothing entered
cpy #1
beq device_single_digit // single digit entered
cpy #2
beq device_double_digit // double digit entered
jmp error_occurred // too many digits
device_double_digit:
lda #10 // should only be 10 or 11 so force this
sta device
inx // go to next digit
device_single_digit:
lda INPUT_BUFFER,x
sec
sbc #$30 // convert to real number
clc
adc device // add to what is already there
sta device
// sanity check for device id
lda device
cmp #7
bcc error_occurred // less or equal to 7
cmp #11
bcc device_entered // less or equal to 11, but higher than 7
jmp error_occurred // above 11
device_entered:
jsr DISPLAY_OK
jmp TRANSFER_DISK
error_occurred:
jmp ERROR
TRANSFER_DISK:
!skip:
// Have the ultimate place the file in the REU
// Note; reading the file using the read function seems to miss
// every first byte on each transfer. Doing this via the REU seems to
// work fine.
jsr ULT_FILE_READ_REU
jsr STATUS_OK
beq setup_reu
jmp ERROR
setup_reu:
// Setup the REU transfer initial state
jsr REU_SETUP_TRANSFER
setup_write:
// set zero page pointer to sector buffer in ram
lda #<sector_buffer
sta buffer
lda #>sector_buffer
sta buffer+1
// reset command string characters
// also used for printing progress
jsr ZERO_SECTOR
jsr ZERO_TRACK
// start at track 1, sector 0
lda #1
sta current_track
lda #0
sta current_sector
// do D71 or D81 write
lda disk_type
cmp #2
beq do_d81
// ----------------
// do D71
jsr SET_1571_MODE // make sure drive is in 1571 mode.
jsr OPEN_BUFFER_CHANNEL
next_sector_read_d71:
jsr DISPLAY_PROGRESS
jsr DISPLAY_PROGRESS_HOME
// get data from reu to memory buffer
jsr REU_TRANSFER_SECTOR
jsr CHECK_BUFFER_EMPTY
bcc !skip+ // bit clear means buffer is empty
jsr WRITE_SECTOR
!skip:
jsr NEXT_SECTOR
inc current_sector
ldx current_track
lda sectors_1571,x // all sectors for this track done?
cmp current_sector
beq next_track_d71
jmp next_sector_read_d71
next_track_d71:
// start at sector 0 in next track
lda #0
sta current_sector
jsr ZERO_SECTOR
// go to next track
jsr NEXT_TRACK
inc current_track
lda current_track
cmp #71 // all done?
beq !finish+
jmp next_sector_read_d71
// ----------------
// do D81
do_d81:
jsr OPEN_BUFFER_CHANNEL
next_sector_read_d81:
jsr DISPLAY_PROGRESS
jsr DISPLAY_PROGRESS_HOME
// get data from reu to memory buffer
jsr REU_TRANSFER_SECTOR
jsr WRITE_SECTOR
jsr CHECK_BUFFER_EMPTY
bcc !skip+ // clear bit means buffer is empty
jsr WRITE_SECTOR
!skip:
inc current_sector
lda current_sector
cmp #40
beq next_track_d81
jsr NEXT_SECTOR // advance text, and cmd string
jmp next_sector_read_d81 // get ready for next sector
next_track_d81:
// start at sector 0 in next track
lda #0
sta current_sector
jsr ZERO_SECTOR
// go to next track
jsr NEXT_TRACK
inc current_track
lda current_track
cmp #81 // done?
beq !finish+
jmp next_sector_read_d81
// ---------
!finish:
jsr DISPLAY_DONE
jmp CLOSE_APP
ERROR:
jsr DISPLAY_FAIL
CLOSE_APP:
jsr CLOSE_BUFFER_CHANNEL
jsr CLOSE_COMMAND_CHANNEL
jsr ULT_CLOSE_FILE
rts
// -----
// ---- Helper functions
// Display a nice welcome message
DISPLAY_WELCOME:
lda #>str_welcome
ldx #<str_welcome
jsr PRINT
rts
// Ask for the file name
ENTER_FILE_NAME:
lda #>str_enter_file_name
ldx #<str_enter_file_name
jsr PRINT
jsr GET_TEXT
jsr NEW_LINE
rts
// Ask for the disk type
ENTER_DISK_TYPE:
lda #>str_enter_disk_type
ldx #<str_enter_disk_type
jsr PRINT
jsr GET_DECIMAL
jsr NEW_LINE
rts
// Ask for the device number
ENTER_DEVICE:
lda #>str_enter_device
ldx #<str_enter_device
jsr PRINT
jsr GET_DECIMAL
jsr NEW_LINE
rts
// Display ultimate dos version
DISPLAY_ULTIDOS:
jsr ULT_GET_DOS
jsr DISPLAY_DATA
jsr NEW_LINE
rts
// Display the path the ultimate is looking at
DISPLAY_CURRENT_PATH:
lda #>str_current_path
ldx #<str_current_path
jsr PRINT
jsr ULT_GET_PATH
jsr DISPLAY_DATA
jsr NEW_LINE
rts
// Ask and set the dos path.
ENTER_PATH:
lda #>str_enter_path
ldx #<str_enter_path
jsr PRINT
jsr GET_TEXT
jsr NEW_LINE
jsr ULT_SET_PATH
rts
// Set cursor at a new line
NEW_LINE:
lda #$0d
jsr CHROUT
rts
// Display the current track and sector
DISPLAY_PROGRESS:
lda #>str_track
ldx #<str_track
jsr PRINT
ldx #$00
!next:
lda write_track,x // found in diskwrite.asm
jsr CHROUT
inx
cpx #$03
beq print_sector
jmp !next-
print_sector:
lda #>str_sector
ldx #<str_sector
jsr PRINT
ldx #$00
!next:
lda write_sector,x // found in diskwrite.asm
jsr CHROUT
inx
cpx #$02
beq !end+
jmp !next-
!end:
rts
// Set the cursor home after track and sector were displayed
DISPLAY_PROGRESS_HOME:
ldx #18
lda #$9d
!next:
jsr CHROUT
dex
bne !next-
rts
// Display done message
DISPLAY_DONE:
lda #>str_done
ldx #<str_done
jsr PRINT
rts
// Display fail message
DISPLAY_FAIL:
lda #>str_fail
ldx #<str_fail
jsr PRINT
rts
// Display OK message
DISPLAY_OK:
lda #>str_ok
ldx #<str_ok
jsr PRINT
rts
// Display Data read from the ultimate
DISPLAY_DATA:
jsr ULT_READ_DATA
bcc !end+ // no more
beq !end+ // 0 character?
jsr CHROUT
jmp DISPLAY_DATA
!end:
rts
// Display Status read from the ultimate
DISPLAY_STATUS:
ldy #$01
jsr read_status
jsr NEW_LINE
rts
// Get Status from the ultimate
GET_STATUS:
ldy #$00
read_status:
lda #$00
sta status
sta status+1
lda #$00
sta status_ptr
!next:
// read next status byte
jsr ULT_READ_STATUS
bcc !end+ // no more
beq !end+ // 0 character?
store_code:
ldx status_ptr
cpx #$02
bcs check_print // no store when x >= 2
pha
sta status,x
lda #$30
sec
sbc status,x // subract '0'
sta status,x // store
inx // x++
stx status_ptr
pla
check_print:
cpy #$01
beq !print+ // print when y = 1
jmp !next-
!end:
rts
!print:
jsr CHROUT
jmp !next-
// Checks if the status code is OK.
// Just as CMP the zero flag holds the result.
STATUS_OK:
lda status
beq !next+
rts
!next:
lda status+1
rts
// checks if buffer is empty.
// carry bit is cleared if buffer is empty, set when not.
CHECK_BUFFER_EMPTY:
ldy #0
!loop:
lda (buffer),y
bne !done+
iny
bne !loop-
clc
rts
!done:
sec
rts
// ----- Data
.encoding "petscii_mixed"
str_welcome:
.byte $93 // clear
.byte $0e // lowercase set (lower-> upper, upper->lower)
.text "D71/D81 writer V1.1, by Ernoman and WdW"
.byte $0d, 0
str_current_path:
.text "Current path is: "
.byte 0
str_enter_disk_type:
.text "Select (1) D71 or (2) D81: "
.byte 0
str_enter_path:
.text "Enter path to file: "
.byte 0
str_enter_file_name:
.text "Enter file name: "
.byte 0
str_enter_device:
.text "Destination device (8-11): "
.byte 0
str_fail:
.text "Fail!"
.byte $0d, 0
str_ok:
.text "OK"
.byte $0d, 0
str_track:
.text "Track "
.byte 0
str_sector:
.text "sector "
.byte 0
str_done:
.byte $0d,$0d
.text "Done!"
.byte 0
// status read from the ultimate
status:
.byte 0, 0
status_ptr:
.byte 0
// indexes for write loop
current_track:
.byte 0
current_sector:
.byte 0
// the device id the user entered
device:
.byte $09
// diskdrive type the user entered
disk_type:
.byte 0