home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
SIMTEL
/
CPMUG
/
CPMUG019.ARK
/
TSAVE.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
10KB
|
299 lines
; TSAVE - SAVE CP/M DISK FILE ONTO CASSETTE TAPE
;
; L.E. HUGHES 8080SDC 77/06/12
ORG 100H
BDOS EQU 0005H ;BDOS ENTRY POINT
OPENF EQU 15 ;"OPEN FILE" FUNCTION CODE
READF EQU 20 ;"READ FILE" FUNCTION CODE
TYPEF EQU 2 ;"TYPE CONSOLE" FUNCTION CODE
FCB EQU 5CH ;FILE CONTROL BLOCK ADDRESS
DBUF EQU 80H ;DISK BUFFER ADDRESS
CASC EQU 6EH ;CASSETTE TAPE CONTROL/STATUS PORT
CASD EQU 6FH ;CASSETTE TAPE DATA PORT
CR EQU 0DH ;ASCII CARRIAGE RETURN
LF EQU 0AH ;ASCII LINE FEED
SOH EQU 01H ;ASCII START OF HEADER
STX EQU 02H ;ASCII START OF TEXT
ETX EQU 03H ;ASCII END OF TEXT
; FILE CONTROL BLOCK DEFINITIONS
FCBDN EQU FCB+0 ;DISK NAME
FCBFN EQU FCB+1 ;FILE NAME
FCBFT EQU FCB+9 ;FILE TYPE
FCBRL EQU FCB+12 ;CURRENT REEL NUMBER
FCBRC EQU FCB+15 ;CURRENT RECORD COUNT (0 TO 128)
FCBCR EQU FCB+32 ;CURRENT NEXT-RECORD
FNAME EQU FCBFN
; MAIN PROGRAM
TSAVE: LXI H,0
DAD SP
SHLD OLDSP
LXI SP,STACK+64
LXI D,FCB ;OPEN DISK FILE
MVI C,OPENF
CALL BDOS
CPI 255 ;JUMP IF OK
JNZ TSAV1
LXI H,MSG1 ;ELSE PRINT 'FILE NOT FOUND'
CALL WAS
RET ;AND RETURN TO CP/M
TSAV1: XRA A ;SET 'NEXT-RECORD' PTR TO 0
STA FCBCR
STA PRN ;INITIALIZE PRN TO 0
TSAV2: LXI H,TBUF ;POINT TO TBUF
LXI D,0 ;SET TBUF SIZE TO 0
TSAV5: CALL DISKR ;READ NEXT SECTOR ON DISK INTO DBUF
CPI 1 ;JUMP IF END-OF-FILE ON DISK
JZ TSAV4
PUSH D
LXI D,DBUF ;COPY DBUF TO TBUF
MVI C,128 ;DBUF LENGTH
TSAV3: LDAX D ;FETCH NEXT BYTE FROM DBUF
INX D
MOV M,A ;STORE IT IN TBUF
INX H
DCR C
JNZ TSAV3 ;COPY ENTIRE DBUF
POP D
MOV A,E ;ADD 128 TO TBUF SIZE
ADI 128
MOV E,A
JNC $+4
INR D
MOV A,D ;LOOP UNTIL 8 SECTORS READ
CPI 4
JNZ TSAV5
MVI A,0 ;WRITE TBUF TO TAPE UNIT 0
LXI H,TBUF
CALL CTWR
JMP TSAV2 ;LOOP THRU ENTIRE DISK FILE
TSAV4: MVI A,0 ;WRITE SHORT PR TO TAPE (EOF)
LXI H,TBUF
CALL CTWR
LXI H,MSG2 ;PRINT 'DONE' AND RETURN TO CP/M
CALL WAS
LHLD OLDSP
SPHL
RET
; DISKR - READ NEXT DISK SECTOR
DISKR: PUSH H
PUSH D
PUSH B
LXI D,FCB
MVI C,READF
CALL BDOS
POP B
POP D
POP H
RET
; WAS - WRITE ASCII STRING (TO CONSOLE)
;
; ENTRY CONDITIONS
; HL - POINTS TO STRING TO WRITE
WAS: MOV A,M ;FETCH NEXT CHAR
INX H
ORA A ;RETURN IF END-OF-STRING
RZ
CALL WAC ;ELSE PRINT CHAR AND LOOP
JMP WAS
; WAC - WRITE ASCII CHARACTER (TO CONSOLE)
WAC: PUSH H
PUSH D
PUSH B
MVI C,TYPEF
MOV E,A
CALL BDOS
POP B
POP D
POP H
RET
; CTWR - WRITE PHYSICAL RECORD TO CASSETTE TAPE
;
; FOR TARBELL INTERFACE WITH LASALLE RELAY BOARD
;
; PHYSICAL RECORD FORMAT
;
; BYTE SIZE FIELD CONTENTS
; 00 01 SOH (ASCII START-OF-HEADER)
; 01 08 FILENAME, LEFT JUSTIFIED, BLANK FILLED
; 09 03 FILETYPE, LEFT JUSTIFIED, BLANK FILLED
; 12 01 PHYSICAL RECORD NUMBER, 1 BYTE INTEGER
; 13 02 PHYSICAL RECORD SIZE, BYTES, 2 BYTE INTEGER
; 15 01 STX (ASCII START-OF-TEXT)
; 16 XX DATA BYTES
; 16+XX 01 ETX (ASCII END-OF-TEXT)
; 17+XX 02 CYCLIC REDUNDANCY CHECK, 2 BYTE INTEGER
;
; ENTRY CONDITIONS
; HL - POINTS TO BLOCK TO BE WRITTEN TO TAPE
; DE - NUMBER OF BYTES TO WRITE (PHYSICAL RECORD SIZE)
; A - CASSETTE UNIT NUMBER (CURRENTLY 0 OR 1)
; PRN - PHYSICAL RECORD NUMBER. SHOULD BE INITIALIZED BY
; USER TO ZERO. INCREMENTED BY 1 BY CTWR.
; FNAME - 11 BYTE BUFFER CONTAINING FILENAME/FILETYPE
CTWR: PUSH PSW
PUSH H ;SAVE BUFFER POINTER
PUSH D ;SAVE PHYS REC SIZE
ADD A ;SHIFT UNIT NUMBER INTO POSITION
CALL CTON ;TURN ON MOTOR
MVI A,3CH ;WRITE START BYTE
CALL CTOUT
MVI A,0E6H ;WRITE SYNC BYTE
CALL CTOUT
MVI A,SOH ;WRITE SOH
CALL CTOUT
LXI H,0 ;CLEAR CRC
SHLD CRC
LXI H,FNAME ;WRITE FILENAME/FILETYPE
LXI D,11
CALL CTWS
LDA PRN ;WRITE PHYSICAL RECORD NUMBER
CALL CTOUT
INR A ;INCREMENT PRN
STA PRN
POP D ;RESTORE PHYS REC SIZE
MOV A,D ;WRITE PHYS REC SIZE
CALL CTOUT
MOV A,E
CALL CTOUT
MVI A,STX ;WRITE STX
CALL CTOUT
POP H ;RESTORE BUFFER POINTER
PUSH D ;SAVE PHYS REC SIZE
CALL CTWS ;WRITE DATA BYTES
MVI A,ETX ;WRITE ETX
CALL CTOUT
LHLD CRC ;WRITE CRC
MOV A,H
CALL CTOUT
MOV A,L
CALL CTOUT
XRA A ;SEND A NULL
CALL CTOUT
POP D ;RESTORE PHYS REC SIZE
POP PSW
JMP CTOFF ;IDLE MOTOR AND RETURN
; CTWS - WRITE STRING TO CASSETTE TAPE
;
; ENTRY CONDITIONS
; HL - FWA OF STRING
; DE - SIZE OF STRING
CTWS: MOV A,D ;RETURN IF COUNT = 0
ORA E
RZ
MOV A,M ;WRITE NEXT BYTE
INX H
CALL CTOUT
DCX D ;DECREMENT COUNT
JMP CTWS ;AND LOOP
; CTOUT - WRITE BYTE TO CASSETTE TAPE
;
; ENTRY CONDITIONS
; A - 8 BIT BYTE TO WRITE
; B - RUNNING CHECKSUM (INIT BY USER TO ZERO)
CTOUT: PUSH PSW
IN CASC ;AWAIT TBE (INVERTED)
ANI 20H
JNZ $-4
POP PSW
OUT CASD ;WRITE BYTE
CMA ;DISPLAY ON LIGHTS, THEN FALL THRU TO CTCRC
OUT 0FFH
CMA
; CTCRC - UPDATE CRC
;
; ENTRY CONDITIONS
; A - NEW DATA BYTE
; CRC - 2 BYTE BUFFER CONTAINING CRC
; CRCP - 2 BYTE CRC POLYNOMIAL CONSTANT
CTCRC: PUSH PSW ;SAVE REGS
PUSH B
PUSH D
PUSH H
MOV B,A ;SAVE DATA BYTE
MVI C,8 ;LOOP COUNT
CTCR1: ANI 80H ;MASK OFF MSB OF DATA BYTE
LHLD CRC ;FETCH CRC INTO HL
XRA H ;XOR MSB OF DATA BYTE INTO CRC
MOV H,A
DAD H ;LEFT SHIFT CRC 1 BIT
JNC CTCR2 ;JUMP IF NO CARRY
MOV A,H ;HL = HL XOR CRCP
XRI CRCP SHR 8
MOV H,A
MOV A,L
XRI CRCP AND 0FFH
MOV L,A
CTCR2: SHLD CRC ;REPLACE CRC
DCR C ;DECREMENT LOOP COUNT
JZ CTCR3 ;EXIT WHEN ENTIRE BYTE PROCESSED
MOV A,B ;SHIFT DATA BYTE LEFT 1 BIT
ADD A
MOV B,A
JMP CTCR1 ;LOOP
CTCR3: POP H ;RESTORE REGS AND RETURN
POP D
POP B
POP PSW
RET
; CTON - TURN ON CASSETTE TAPE MOTOR
;
; ENTRY CONDITIONS
; A - UNIT NO. (SHL 1) AND OPTIONAL HUNT MODE BIT
CTON: ORI 1 ;TURN ON MOTOR CONTROL BIT
OUT CASC
IN CASC ;WAIT UNTIL NON-BUSY
ANI 1
JZ $-4
RET
; CTOFF - IDLE CASSETTE TAPE MOTOR
CTOFF: PUSH PSW ;SAVE A AND FLAGS
XRA A ;CLEAR INTERFACE
OUT CASC
IN CASC ;WAIT UNTIL NON-BUSY
ANI 1
JZ $-4
POP PSW
RET
; DATA AREA
MSG1: DB 'FILE NOT FOUND',CR,LF,0
MSG2: DB 'DONE',CR,LF,0
PRN: DS 1
TBUF: DS 1024
CRC: DS 2 ;CYCLIC REDUNDANCY CHECK
CRCP: EQU 8005H ;CRC POLYNOMIAL (CRC-16)
OLDSP: DS 2
STACK: DS 64
END TSAVE