URL
https://opencores.org/ocsvn/System09/System09/trunk
Subversion Repositories System09
[/] [System09/] [trunk/] [src/] [xrecv/] [XSEND.ASM] - Rev 189
Go to most recent revision | Compare with Previous | Blame | View Log
*
** Xmodem Send Utility for Flex9 (xsend.asm)
*
* WITH ACIA MAPPED AT $E000
*
* 2020-05-24 JEK Work in progress.
*
*
** FLEX9 FMS CALLS
*
SYSFCB EQU $C840
FMSCLS EQU $D403
FMS EQU $D406
*
* FLEX SYSTEM DEFINED ENTRY VECTORS
*
COLDS EQU $CD00 FLEX COLD START ADDRESS
WARMS EQU $CD03 FLEX WARM START ADDRESS
RENTER EQU $CD06 RE-ENTER FLEX PROCESSING
INCH EQU $CD09 INPUT CHARACTER (LOW LEVEL) (MAY BE REDIRECTED)
INCH2 EQU $CD0C SECONDARY INPUT CHARACTER (NOT REDIRECTED)
OUTCH EQU $CD0F OUTPUT CHARACTER (LOW LEVEL) (MAY BE REDIRECTED)
OUTCH2 EQU $CD12 SECONDARY CHAR OUTPUT (NOT REDIRECTED)
GETCHR EQU $CD15 INPUT CHARACTER ROUTINE (HONOURS TTYSET)
PUTCHR EQU $CD18 OUTPUT CHARACTER ROUTINE (HONOURS TTYSET)
INBUFF EQU $CD1B INPUT LINE BUFFER
PSTRNG EQU $CD1E PRINT STRING
CLASS EQU $CD21 CLASSIFY CHARACTER
PCRLF EQU $CD24 PRINT CR/LF SEQUENCE
NXTCH EQU $CD27 GET NEXT CHARACTER FROM INPUT BUFFER
RESTIO EQU $CD2A RESTORE I/O VECTORS ON INCH & OUCH
GETFIL EQU $CD2D GET FILE SPECIFICATION (X=FCB) (C=1 IF FORMAT ERROR)
LOAD EQU $CD30 LOAD FILE ENTRY POINT
SETEXT EQU $CD33 SET UP FILE EXTENSION
ADDBX EQU $CD36 ADD ACCB TO X INDEX REGISTER
OUTDEC EQU $CD39 OUTPUT DECIMAL NUMBER
OUTHEX EQU $CD3C OUTPUT HEXADECIMAL BYTE POINTED TO BY X
RPTERR EQU $CD3F I/O ERROR ABORT ROUTINE
GETHEX EQU $CD42 GET HEXIDECIMAL SPECIFICATION
OUTADR EQU $CD45 OUTPUT HEXADECIMAL ADDRESS POINTED TO BY X
INDEC EQU $CD48 GET DECIMAL NUMBER
DOCMD EQU $CD4B DOCMD ENTRY ADDRESS (CALL FLEX AS SUBROUTINE)
STATUS EQU $CD4E CHECK TERMINAL INPUT STATUS (Z=1 => NO CHARACTER)
*
* FMS FUNCTION CODES
*
FMSFRW EQU 0 READ OR WRITE TO FILE (Z=0 => ERROR)
FMSFOR EQU 1 OPEN FILE FOR READ (Z=0 => ERROR)
FMSFOW EQU 2 OPEN FILE FOR WRITE (Z=0 => ERROR)
FMSFOU EQU 3 OPEN FILE FOR UPDATE (1=SEQ RD, 2=RAND RD, 3=RAND WR, 4=CLOSE)
FMSFCL EQU 4 CLOSE FILE
FMSFRS EQU 5 REWIND FILE
FMSDOP EQU 6 OPEN DIRTECTORY
FMSGIR EQU 7 GET INFORMATION RECORD (READ DIRECTORY)
FMSPIR EQU 8 PUT INFORMATION RECORD (WRITE DIRECTORY)
FMSRSS EQU 9 READ SINGLE SECTOR (SET CURRENT TRACK & SECTOR IN FCB)
FMSWSS EQU 10 WRITE SINGLE SECTOR
FMSFDL EQU 11 DELETE FILE
FMSRRN EQU 12 RENAME FILE
FMSNSS EQU 15 READ OR WRITE NEXT SEQUENTIAL SECTOR
FMSOSR EQU 16 OPEN SYSTEM INFORMATION RECORD
FMSRRB EQU 17 READ RANDOM BYTE FROM SECTOR (SET RANDOM INDEX BYTE IN FCB)
FMSWRB EQU 18 WRITE RANDOM BYTE IN SECTOR (ADD 4 TO SKIP SECTOR LINK)
FMSFND EQU 20 FIND NEXT DRIVE IN READY STATE
FMSPRN EQU 21 POSITION TO RECORD N (STORE ADDRESS IN CURRENT RECORD NUMBER)
FMSBOR EQU 22 BACK UP ONE RECORD
*
* FMS ERROR CODES
*
ERRIFC EQU 1 ILLEGAL FMS FUNCTION CODE
ERRINU EQU 2 REQUESTED FILE IN USE
ERRFAE EQU 3 FILE ALREADY EXISTS (OPEN FOR WRITE EXISTING FILE)
ERRFNF EQU 4 FILE NOT FOUND (OPEN FOR READ)
ERRSDE EQU 5 SYSTEM DIRECTORY ERROR - REBOOT SYSTEM
ERRSDF EQU 6 SYSTEM DIRECTORY FULL
ERRDSF EQU 7 ALL AVAILBABLE DISK SPACE HAS BEEN USED
ERREOF EQU 8 READ PAST END OF FILE
ERRRDE EQU 9 FILE READ ERROR
ERRWRE EQU 10 FILE WRITE ERROR
ERRWRP EQU 11 FILE IS WRITE PROTRECTED
ERRFND EQU 12 FILE IS PROTECTED - FILE NOT DELETED
ERRFCB EQU 13 ILLEGAL FILE CONTROL BLOCK
ERRIDA EQU 14 ILLEGAL DISK ADDRESS
ERRIDN EQU 15 ILLEGAL DRIVE NUMBER
ERRBSY EQU 16 DRIVE NOT READY
ERRFPR EQU 17 FILE IS PROTECTED - ACCESS DENIED
ERRSFS EQU 18 SYSTEM FILE STATUS ERROR
ERRDIR EQU 19 FMS DATA INDEX RANGE ERROR
ERRFMS EQU 20 FMS INACTIVE - REBOOT SYSTEM
ERRIFS EQU 21 ILLEGAL FILE SPECIFICATION
ERRSFC EQU 22 SYSTEM FILE CLOSE ERROR
ERRSMO EQU 23 SECTOR MAP OVERFLOW
ERRNSR EQU 24 NON EXISTAND RECORD NUMBER (NO SUCH RECORD)
ERRRNM EQU 25 RECORD NUMBER MATCH ERROR (FILE DAMAGED)
ERRSYN EQU 26 COMMAND SYNTAX ERROR
ERRPRN EQU 27 COMMAND NOT ALLOWED WHILE PRINTING
ERRHWC EQU 28 WRONG HARDWARE CONFIGURATION
*
* Condition Code Flags
*
CFLAG EQU $01 CARRY FLAG
VFLAG EQU $02 OVERFLOW FLAG
ZFLAG EQU $04 ZERO FLAG
NFLAG EQU $08 NEGATIVE FLAG
IFLAG EQU $10 IRQ MASK CC
HFLAG EQU $20 HALF CARRY
FFLAG EQU $40 FIRQ MASK CC
EFLAG EQU $80 ENTIRE FLAG
*
* Serial Port
*
ACIAS EQU $E000
ACIAC1 EQU ACIAS
ACIAD1 EQU ACIAS+1
DELCON EQU 1250 Delay (Processor clock in MHz * 50)
*
* XMODEM Control characters
*
SOH EQU $01 sent for 128 byte block
STX EQU $02 sent for 1024 byte block
EOT EQU $04
ACK EQU $06
NAK EQU $15
CAN EQU $18
*
* ASCII CONTROL CHARACTERS
*
HT EQU $09
LF EQU $0A
CR EQU $0D
RETRY EQU 16
*
* Start
*
ORG $0100
START LBRA LOAD1
*
*
* RAM SPACE
*
CHKSUM FCB 0
BLKNUM FCB 0 Xmodem block number
BYTCNT FCB 0 Xmodem byte count
SNDCNT FCB 0 Send byte count
PADCNT FCB 0 Send byte count
DELCNT FCB $00,$00,$00 Xmodem Poll timer
BUFPTR FDB 0 Pointer to send buffer
TXTFLG FCB 0 Text file flag
SPTEMP FDB 0 Stack pointer store
RETRYC FCB 0 Retry count
LSTCHR FCB 0 Double CANcel
*
* SEND BUFFER
*
BUFSIZ EQU 128
BUFFER RMB BUFSIZ
*
* Program Stack
*
RMB 256
STACK EQU *
*
** MAIN ENTRY POINT
*
* Get file specification
*
LOAD1 STS SPTEMP
LDS #STACK
LDX #SYSFCB
JSR GETFIL
BCS FMSERR
*
* look for 'T' for text file
*
LOAD2 JSR NXTCH
ANDA #$5F
CMPA #'T Is it a Text File ?
BNE OPENRD No, open as binary file
STA TXTFLG
LDX #TXTMSG
JSR PSTRNG
LDX #SYSFCB
LDA #$01 If text file default to ".TXT"
JSR SETEXT
*
** OPEN FILE FOR READ
*
OPENRD LDX #SYSFCB
LDA #FMSFOR open file for read
STA 0,X
JSR FMS
BNE DSKERR
TST TXTFLG Is it a text file ?
BNE TXTFILE Yes, space compression
LDX #SYSFCB No, binary, no space compression
LDA #$FF
STA $3B,X
*
* Start from Block 1
*
TXTFILE LDA #1 Initialize block number
STA BLKNUM
LDA #RETRY Initialize retry count
STA RETRYC
LBRA RDSTRT go start transfer
*
** FINISHED LOAD
*
* Send EOT until receiver sends an ACK
*
ABORT LDA #EOT Send EOT
LBSR OUTTER
LBSR INTER Wait for ACK
BVS ABORT1 If timeout, terminate
CMPA #ACK ACK Received ?
BNE ABORT No, send another EOT
ABORT1 LDX #ENDMSG Yes, report file loaded
JSR PSTRNG
*
** CLOSE FILE
*
CLOSE LDA #FMSFCL Close file
LDX #SYSFCB
STA 0,X
JSR FMS
BEQ EXIT
*
** ERROR IN CLOSING
*
DSKERR LDA $01,X
FMSERR JSR RPTERR
JSR FMSCLS
EXIT LDS SPTEMP
JMP WARMS
*
* READ FILE INTO BUFFER
* READ UP TO 128 BYTES
*
RDSTRT DEC RETRYC decrement the retry count
BEQ ABORT terminate transmission if retry count expires
CLR BYTCNT Clear byte count
LDX #BUFFER Reset buffer pointer to start of buffer
STX BUFPTR
*
RDLOOP LDX #SYSFCB Read byte from file
JSR FMS
BNE RDERR Check for end of file
*
* TST TXTFLG Text file ?
* BEQ RDLP1 No, output binary
* CMPA #CR Yes, substitute LF for CR (Linux)
* BNE RDLP1
* LDA #LF
*
RDLP1 LDX BUFPTR store character in buffer
STA ,X+
STX BUFPTR
*
INC BYTCNT Increment send buffer byte count
LDA BYTCNT
CMPA #BUFSIZ Is send buffer full ?
BEQ SNDSOH Yes, send a 128 byte record
BRA RDLOOP No, read next byte until EOF
*
* CHECK FOR END OF FILE
* IF SO SEND BUFFER AND PAD WITH NULLS
*
RDERR LDA $01,X
CMPA #ERREOF test for End Of File Error
LBNE ABORT If not, report disk error and close
*
* Send bytes in the send buffer
*
SNDSOH LDX #BUFFER Reset buffer pointer to start of buffer
STX BUFPTR
LDA #BUFSIZ Work out how many bytes to pad out
SUBA BYTCNT
STA PADCNT
LDA BYTCNT
STA SNDCNT
LBEQ ABORT Terminate Transfer if no bytes to send
*
* SEND SOH (START OF HEADER) = $01
*
LDA #SOH Send start of header
LBSR OUTTER
*
* SEND BLOCK NUMBER
*
LDA BLKNUM Send Block number
LBSR OUTTER
*
* SEND COMPLEMENT OF BLOCK NUMBER
*
LDA BLKNUM Send complement of block number
COMA
LBSR OUTTER
*
CLR CHKSUM Clear Checksum
*
* Send Data Block
*
SNDDAT LDX BUFPTR Send data byte in buffer
LDA ,X+
STX BUFPTR
JSR OUTTER
*
ADDA CHKSUM Calculate checksum
STA CHKSUM
*
DEC SNDCNT Decrement sent byte counter
BNE SNDDAT Loop until done
*
* Send Pad Bytes
*
TST PADCNT Test if any pad characters
BEQ SNDCHK No, send checksum
SNDPAD LDA #$00 Yes, output nulls
JSR OUTTER
DEC PADCNT Decrement Pad Byte Count
BNE SNDPAD Loop until pad byte count == 0
*
* Send Checksum
*
SNDCHK LDA CHKSUM Send checksum
LBSR OUTTER
*
* wait for acknowledgement
*
SNDWAI LBSR INTER Wait for ack, Negative ack, Cancel or timeout
BVS SNDUPD If timeout, send block again
CMPA #NAK If negative acknowledge
BEQ SNDUPD send block again
CMPA #CAN If Cancel
BEQ SNDCAN Terminate transmission and close file
CMPA #ACK If Acknowledgement
BEQ SNDNXT advance block count
STA LSTCHR Update Last Character
BRA SNDWAI Loop.
*
* Acknowledge received
* increment block number,
* reset the retry count
* and loop for next block
*
SNDNXT STA LSTCHR Non CAN character
INC BLKNUM
LDA #RETRY reset the retry count
STA RETRYC
LBRA RDSTRT
*
* Look for two cancells to terminate
*
SNDCAN CMPA LSTCHR
LBEQ ABORT
STA LSTCHR
BRA SNDWAI
*
* Store characetr in LSTCHR
* And send SOH again
*
SNDUPD STA LSTCHR
LBRA SNDSOH
*
* ACIA INPUT TEST
*
INTEST LDA ACIAC1
BITA #$01
RTS
*
* RESET ACIA
*
ACIRST LDA #$03 master reset
STA ACIAC1
LDA #$11
STA ACIAC1
TST ACIAD1
RTS
*
* ACIA INPUT
* SET V FLAG IF TIME OUTADR
*
INTER LDA #16
STA DELCNT+0
CLR DELCNT+1
CLR DELCNT+2
INTER0 LDA ACIAC1
BITA #$01
BNE INTER1
BITA #$78
BEQ INTER2
BSR ACIRST
BRA INTER
*
INTER1 LDA ACIAD1
ANDCC #$FF-VFLAG
RTS
*
INTER2 DEC DELCNT+2
BNE INTER0
DEC DELCNT+1
BNE INTER0
DEC DELCNT+0
BNE INTER0
CLRA
ORCC #VFLAG
RTS
*
* ACIA OUTPUT
*
OUTTER PSHS A
*
OUTTE1 LDA ACIAC1
BITA #$02
BNE OUTTE2
BITA #$78
BEQ OUTTE1
BSR ACIRST
BRA OUTTE1
*
OUTTE2 PULS A
STA ACIAD1
RTS
*
** MESSAGES
*
ENDMSG FCC "FILE LOADED"
FCB $04
TXTMSG FCC "TEXT FILE"
FCB $04
END START
Go to most recent revision | Compare with Previous | Blame | View Log