OpenCores
URL https://opencores.org/ocsvn/System09/System09/trunk

Subversion Repositories System09

[/] [System09/] [trunk/] [src/] [xrecv/] [XSEND.ASM] - Rev 174

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.