org &2000
nolist
write"copy.bin"
.kl_find_command equ &bcd4
.txt_output equ &bb5a
.bdos_set_message equ 1
.bdos_read_sector equ 4
.bdos_write_sector equ 5
.bdos_format equ 6
.bdos_move_track equ 7
.bdos_set_retry_count equ 9
.bdos_get_status equ 8
.km_read_char equ &bb09
.km_wait_char equ &bb06
.bdos_select_format equ 3
.SOURCE_DRIVE equ 0
.DEST_DRIVE equ 1
.SECTOR_ID equ 2
.TRACK equ 3
.CUR_TRACK equ 4
.CUR_SECTOR equ 5
.DATA_PTR equ 6
.PREV_SET_MESSAGE equ 7
.PREV_RETRY equ 8
.NUM_TRACKS equ 9
.copy
ld hl,disc_command
call kl_find_command
ret nc
ld hl,read_sector_command
call kl_find_command
ret nc
ld (read_sector_cmd_data),hl
ld a,c
ld (read_sector_cmd_data+2),a
ld hl,write_sector_command
call kl_find_command
ret nc
ld (write_sector_cmd_data),hl
ld a,c
ld (write_sector_cmd_data+2),a
ld hl,format_command
call kl_find_command
ret nc
ld (format_cmd_data),hl
ld a,c
ld (format_cmd_data+2),a
ld hl,select_format_command
call kl_find_command
ret nc
ld (select_format_cmd_data),hl
ld a,c
ld (select_format_cmd_data+2),a
ld hl,move_track_command
call kl_find_command
ret nc
ld (move_track_cmd_data),hl
ld a,c
ld (move_track_cmd_data+2),a
ld hl,set_retry_count_command
call kl_find_command
ret nc
ld (set_retry_count_cmd_data),hl
ld a,c
ld (set_retry_count_cmd_data+2),a
ld hl,set_message_command
call kl_find_command
ret nc
ld (set_message_cmd_data),hl
ld a,c
ld (set_message_cmd_data+2),a
ld ix,copy_data
ld hl,source_drive_txt
call print
ld hl,drive_txt
call print
call get_drive
ld (ix+source_drive),c
ld hl,dest_drive_txt
call print
ld hl,drive_txt
call print
call get_drive
ld (ix+dest_drive),c
call source_drive_msg
call crlf
ld a,(ix+source_drive)
cp (ix+dest_drive)
jr z,copy2
call dest_drive_msg
call crlf
.copy2
ld hl,ready_txt
call print
call flush_keyboard
call km_wait_char
call crlf
ld a,0
call do_set_message
ld (ix+prev_set_message),a
ld a,255
call do_set_retry_count
ld (ix+prev_retry),a
call detect_format
jr c,copy5
ld hl,not_standard_format_txt
call print
ld hl,copy_failed_txt
call print
jp exit
.copy5
ld (ix+sector_id),a
ld a,(ix+sector_id)
ld e,(ix+source_drive)
call do_select_format
ld a,(ix+source_drive)
cp (ix+dest_drive)
jr z,copy6
ld a,(ix+sector_id)
ld e,(ix+dest_drive)
call do_select_format
.copy6
xor a
ld (ix+track),a
.copy_disc
ld a,40
sub (ix+track)
cp 7
jr c,cd3
ld a,7
.cd3
ld (ix+num_tracks),a
call read_tracks
ld a,(ix+source_drive)
cp (ix+dest_drive)
jr nz,cd2
call clear
ld hl,insert_dest_txt
call print
ld hl,press_key_txt
call print
call flush_keyboard
call km_wait_char
.cd2
call write_tracks
ld a,(ix+cur_track)
ld (ix+track),a
cp 40
jr z,cd5
ld a,(ix+source_drive)
cp (ix+dest_drive)
jr nz,copy_disc
call clear
ld hl,insert_source_txt
call print
ld hl,press_key_txt
call print
call flush_keyboard
call km_wait_char
jr copy_disc
.cd5
ld hl,copy_complete_txt
call print
.exit
ld a,(ix+prev_set_message)
call do_set_message
ld a,(ix+prev_retry)
call do_set_retry_count
ret
.flush_keyboard
call km_read_char
jr nc,flush_keyboard
ret
.get_drive
call flush_keyboard
call km_wait_char
and &df
cp "A"
ld c,0
jr z,gd2
cp "B"
ld c,1
jr z,gd2
ld a,7
call txt_output
jr get_drive
.gd2
call txt_output
call crlf
ret
.clear
ld a,13
call txt_output
ld a,18
call txt_output
ld a,13
call txt_output
ret
.crlf
ld a,13
call txt_output
ld a,10
call txt_output
ret
.source_drive_msg
ld hl,insert_source_txt
ld a,(ix+source_drive)
jr insert2
.dest_drive_msg
ld hl,insert_dest_txt
ld a,(ix+dest_drive)
.insert2
push af
call print
pop af
add a,"A"
call txt_output
ret
.print
ld a,(hl)
inc hl
or a
ret z
call txt_output
jr print
.do_set_retry_count
push ix
rst 3
defw set_retry_count_cmd_data
pop ix
ret
.do_move_track
push ix
rst 3
defw move_track_cmd_data
pop ix
ret
.do_format
push ix
rst 3
defw format_cmd_data
pop ix
ret
.do_select_format
push ix
rst 3
defw select_format_cmd_data
pop ix
ret
.do_read
push ix
rst 3
defw read_sector_cmd_data
pop ix
ret
.do_write
push ix
rst 3
defw write_sector_cmd_data
pop ix
ret
.do_set_message
push ix
rst 3
defw set_message_cmd_data
pop ix
ret
.detect_format
ld e,(ix+source_drive)
ld d,(ix+cur_track)
call do_move_track
ld hl,data_buffer
ld e,(ix+source_drive)
ld d,(ix+cur_track)
ld c,&c1
call do_read
ld a,&c1
ret c
ld hl,data_buffer
ld e,(ix+source_drive)
ld d,(ix+cur_track)
ld c,&41
call do_read
ld a,&41
ret c
or a
ret
.format_track
ld hl,format_data
push hl
ld b,9
ld a,(ix+sector_id)
ld c,(ix+cur_track)
.ft2
ld (hl),c
inc hl
ld (hl),0
inc hl
ld (hl),a
inc hl
ld (hl),2
inc hl
inc a
djnz ft2
pop hl
ld e,(ix+dest_drive)
ld d,(ix+cur_track)
call do_format
ret
.write_track
ld b,9
ld a,(ix+sector_id)
.wt1 push bc
push af
ld l,(ix+data_ptr)
ld h,(ix+data_ptr+1)
ld e,(ix+dest_drive)
ld d,(ix+cur_track)
ld c,a
call do_write
ld l,(ix+data_ptr)
ld h,(ix+data_ptr+1)
ld bc,512
add hl,bc
ld (ix+data_ptr),l
ld (ix+data_ptr+1),h
pop af
pop bc
inc a
djnz wt1
ret
.write_tracks
ld a,(ix+track)
ld (ix+cur_track),a
ld hl,data_buffer
ld (ix+data_ptr),l
ld (ix+data_ptr+1),h
ld b,(ix+num_tracks)
.wts1
push bc
ld e,(ix+dest_drive)
ld d,(ix+cur_track)
call do_move_track
ld hl,format_track_txt
call print
call disp_track
call format_track
ld hl,write_track_txt
call print
call disp_track
call write_track
inc (ix+cur_track)
pop bc
djnz wts1
ret
.read_track
ld b,9
ld a,(ix+sector_id)
.rt1 push bc
push af
ld l,(ix+data_ptr)
ld h,(ix+data_ptr+1)
ld e,(ix+source_drive)
ld d,(ix+cur_track)
ld c,a
call do_read
ld l,(ix+data_ptr)
ld h,(ix+data_ptr+1)
ld bc,512
add hl,bc
ld (ix+data_ptr),l
ld (ix+data_ptr+1),h
pop af
pop bc
inc a
djnz rt1
ret
.read_tracks
ld a,(ix+track)
ld (ix+cur_track),a
ld hl,data_buffer
ld (ix+data_ptr),l
ld (ix+data_ptr+1),h
ld b,(ix+num_tracks)
.rts1
push bc
ld hl,read_track_txt
call print
call disp_track
ld e,(ix+source_drive)
ld d,(ix+cur_track)
call do_move_track
call read_track
inc (ix+cur_track)
pop bc
djnz rts1
ret
.disp_track
ld a,(ix+cur_track)
call print_decimal
ret
.print_decimal
ld e,1
ld b,100
call print_decimal_digit
ld b,10
call print_decimal_digit
dec e
ld b,1
.print_decimal_digit
ld c,0
.dd
sub b
jr c,dd2
inc c
jr dd
.dd2
add a,b
push af
ld a,e
or a
ld a,c
jr z,dd4
or a
jr z,dd5
dec e
.dd4
add a,"0"
call txt_output
.dd5
pop af
ret
.disc_command
defb "DIS","C"+&80
.read_sector_command
defb bdos_read_sector+&80
.write_sector_command
defb bdos_write_sector+&80
.format_command
defb bdos_format+&80
.select_format_command
defb bdos_select_format+&80
.move_track_command
defb bdos_move_track+&80
.set_retry_count_command
defb bdos_set_retry_count+&80
.set_message_command
defb bdos_set_message+&80
.format_cmd_data
defw 0
defb 0
.read_sector_cmd_data
defw 0
defb 0
.write_sector_cmd_data
defw 0
defb 0
.select_format_cmd_data
defw 0
defb 0
.move_track_cmd_data
defw 0
defb 0
.set_retry_count_cmd_data
defw 0
defb 0
.set_message_cmd_data
defw 0
defb 0
.source_drive_txt
defb "Source drive ",0
.dest_drive_txt
defb "Destination drive ",0
.drive_txt
defb "(A or B):",0
.not_standard_format_txt
defb "The format of the source disc is not standard.",0
.copy_failed_txt
defb 13,10,"Copy failed",13,10,0
.copy_complete_txt
defb 13,10,"Copy complete",13,10,0
.insert_source_txt
defb "Insert SOURCE disc into drive ",0
.insert_dest_txt
defb "Insert DEST disc into drive ",0
.ready_txt
defb "Press any key to start copying",0
.press_key_txt
defb " and press any key",0
.read_track_txt
defb 13,18,13,"Reading track ",0
.write_track_txt
defb 13,18,13,"Writing track ",0
.format_track_txt
defb 13,18,13,"Formating track ",0
.copy_data
defs 16
.format_data
defs 9*4
.data_buffer equ $+1