home *** CD-ROM | disk | FTP | other *** search
- processor 6502
-
- include "jmptab.inc"
-
- #if target & pet4001
- include "include/petram34.lib"
- include "include/petrom4.lib"
- #endif
- #if target & pet3001
- include "include/petram34.lib"
- include "include/petrom3.lib"
- #endif
- #if target & (c64 | c128 | vic20)
- include "include/cbmrom.lib"
- #endif
-
- seg code
- org prutils
-
- cmd_dread = 1 ; command for reading a disk
- cmd_dwrite = 2 ; command for writing a disk
-
- entry:
- lda #0 ; send ack
- jsr send_switch
-
- loop:
- ; copy a disk protocol:
- ; C= PC or Amiga
- ; ack (00) ->
- ; <- function: 0=quit, 1=read disk, 2=write disk
- ; <- device #
- ; <status (0=ok)> ->
- ;
- ; read disk:
- ; <floppy status (0=ok)><chksum>datablock (256 bytes) ->
- ; <- ok (80) or again (81) or stop (82)
- ; send same or next block, accordingly
- ; last block will be notified with the error code 66
- ; (illegal track or sector)
- ;
- ; write disk:
- ; <- <flag><chksum>datablock (256 bytes)
- ; ok (80) or again (81) or stop (82 followed by error code) ->
- ; last block will be notified with a non-zero flag.
-
- jsr receive_switch ; get function
- tay
- bne noexit$ ; check if it was an exit command
- jmpxit$:
- jmp exit ; reinstall server and exit.
- noexit$:
- cmp #cmd_dread ; is it a legal command?
- beq init
- cmp #cmd_dwrite
- bne jmpxit$
-
- init: pha
- jsr receive ; receive device number
- sta fa
- lda #15
- sta sa ; error channel number
- sta la
- lda #0
- sta fnlen ; use zero file name
- jsr open
- lda status ; check if it succeeded
- beq ok
- abort_init:
- pla
- abortst:
- jsr send_switch ; send a non-zero number
- abort: jsr clrchn
- lda #2
- jsr close ; close the files
- lda #15
- jsr close
- jmp loop
-
- ok: lda #2
- sta sa ; use channel 2 for buffer
- sta la
- lda #filenend-filename
- sta fnlen ; use the file name "#"
- lda #<filename
- sta fnadr
- lda #>filename
- sta fnadr + 1
- jsr open
- lda status
- bne abort_init
- jsr send_switch ; send status code 0 (ok)
-
- pla
- cmp #cmd_dwrite ; branch according to the function specified
- beq write
-
- lda #"1" ; select read operation
- jsr seek1 ; reset the track and sector pointers
- ; loop to send blocks from the disk
- nextblock$:
- jsr advance ; command to get next sector, error code is in A
- bne abortst ; break in case of error
-
- ldx #2
- jsr chkin
- ldx #0
- stx checksum ; clear checksum
-
- read$: ; read 256 bytes from the disk
- jsr stop ; test stop key
- bne noabort$
- lda #2 ; send error code 2 (user break)
- bne abortst
- noabort$:
- jsr chrin
- sta filebuf,x
- clc ; add into checksum
- adc checksum
- sta checksum
- inx ; x ranges from 00 to FF
- bne read$
-
- txa
- jsr send_switch ; send the status code (0)
- jsr clrchn ; restore normal file I/O assignments
- ; now go send the buffer
- sameblock$:
- lda checksum
- jsr send_switch ; send checksum
- ldx #0
- send$: lda filebuf,x
- jsr send
- inx
- bne send$
- ; wait for go on, repeat, or abort.
- jsr receive_switch
- cmp #$80
- beq nextblock$
- cmp #$81
- beq sameblock$
- abortj: jmp abort ; $82 (or other values) abort
-
- write: lda #"1" ; first select read operation and
- jsr seek1 ; try to read track 1, sector 0
- jsr advance ; (the error is ignored, this is only a kludge
- ; to make the b-p command work)
- lda #"2" ; select write operation
- jsr seek1 ; reset the track and sector pointers
- ; loop to receive blocks for the disk
-
- nextblock$:
- jsr receive_switch
- tax ; copy the return code to X
- bne abortj ; nonzero return value indicates end of transmission
- sameblock$:
- jsr receive_switch
- pha ; store checksum
- stx checksum ; clear checksum
-
- receive$: ; receive 256 bytes for the disk
- jsr receive
- sta filebuf,x
- clc ; add to checksum
- adc checksum
- sta checksum
- inx ; x ranges from 00 to FF
- bne receive$
-
- pla
- cmp checksum ; compare the checksums
- beq received$
- lda #$81
- jsr send_switch ; request the block again in case of error
- jmp sameblock$ ; get the block again
-
- received$: ; send the data to the drive
- ldx #15
- jsr chkout ; first issue the B-P command
- ldx #bpend-bp-1
- sendbp$:
- lda bp,x
- jsr chrout
- dex
- bpl sendbp$
- ldx #2
- jsr chkout ; then set the output channel
- ldx #0
- send$: lda filebuf,x ; send the data to the floppy
- jsr chrout
- inx
- bne send$
- jsr clrchn
-
- jsr stop ; test stop key
- beq error$ ; abort the transfer when necessary
- jsr advance ; try to write the sector
- bne error$ ; abort the transfer in case of error
- lda #$80
- jsr send_switch ; acknowledge the data block to the remote end
- jmp nextblock$ ; get the next data block
- stopped$:
- lda #0
- error$: pha
- lda #$82
- jsr send_switch ; tell the remote end to abort the transfer
- pla
- jmp abortst ; and return the error code
-
- seek1: sta _cmd ; select operation ("1"=read, "2"=write)
- lda #"0" ; reset the track and sector numbers
- ldx #2
- 0$: sta track,x
- sta sector,x
- dex
- bpl 0$
- rts
-
- advance: ; go to next sector (or track),
- ldx #2 ; return error code in A, use Z as error flag
- incsect$: ; increment the sector number
- lda #"9"
- inc sector,x
- cmp sector,x
- bcs advanced$
- lda #"0"
- sta sector,x
- dex
- bpl incsect$
- bcc adv_track$ ; branch always (sector number overflow)
-
- advanced$: ; try to read or write the sector
- ldx #15
- jsr chkout
- ldy #0
- send$: lda string,y ; send the command
- jsr chrout
- iny
- cpy #_strend-string
- bcc send$
- jsr clrchn
-
- jsr geterror ; get the error code from the drive
- beq return$ ; no error
-
- cmp #66 ; was it an illegal track or sector?
- bne return$ ; no, some other error => return
-
- lda #"0" ; check the sector number (should be nonzero)
- ldx #2
- check_sector$:
- cmp sector,x
- bne sector_ok$
- dex
- bpl check_sector$
- bmi return66$ ; branch always
-
- sector_ok$:
- ldx #2
- zero_sector$: ; reset the sector number
- sta sector,x
- dex
- bpl zero_sector$
-
- adv_track$: ; increase the track number
- ldx #2
- inctrack$:
- lda #"9"
- inc track,x
- cmp track,x
- bcs advanced$
- lda #"0"
- sta track,x
- dex
- bpl inctrack$
- ; fall through in case of track number overflow
-
- return66$:
- lda #66 ; return with error code 66 (end of copy)
- return$:
- rts
-
- geterror: ; read the disk error channel
- ldx #15
- jsr chkin ; select the error channel
- jsr chrin ; read the first digit
- and #$0f
- tax ; and store it
- jsr chrin ; read the second digit
- clc
- and #$0f
- 0$: dex ; combine the digits to one number
- bmi 1$
- adc #10
- bne 0$ ; branch always
- 1$: pha
- 2$: jsr chrin
- lda status
- beq 2$
- jsr clrchn ; clear the channel
- pla
- rts ; return (error code in accumulator)
-
- filename: .byte "#"
- filenend:
- string: .byte "U"
- _cmd: .byte "1:2 0 "
- track: .byte "000 "
- sector: .byte "000"
- _strend:
- bp: .byte "0 2:P-B" ; string stored backwards
- bpend:
- endcode = .
-
- seg.u bss
- org endcode
-
- checksum:
- ds.b 1 ; save block length
- filebuf:
- ds.b 256 ; checksum followed by 255 bytes of file data
-
- endbss = .
-