Programming:Read/Write a file quickly byte-by-byte

From CPCWiki - THE Amstrad CPC encyclopedia!
Jump to: navigation, search

Routine by ikonsgr

;;This is an example of
;;Read/Write a file Byte by Byte
;;Using firmware, BUT MUCH FASTER!
;;File must have header,named "test.bin" 
;;And don't be more than 10K.
;;Use MAXAM to assemble
;;load"Fastcopy",&4000:call &4000 to run

.CAS_OUT_OPEN EQU &BC8C
.CAS_OUT_CHAR EQU &BC95
.CAS_OUT_CLOSE EQU &BC8F
.CAS_IN_OPEN EQU &BC77
.CAS_IN_CHAR EQU &BC80
.CAS_IN_CLOSE EQU &BC7A

ORG &4000
NOLIST
write"FASTCOPY.BIN"

LD B,END_FLNAME-FLNAME
LD HL,FLNAME
LD DE,TWO_K_BUFFER
CALL CAS_IN_OPEN

DEC HL
DEC HL
PUSH HL
POP IY ;;IY=ADDR OF 2KBUF CURRENT POSITION
PUSH BC ;;BC=DATASIZE OF FILE

;;FIND ADDR FOR 128BYTES OF HEADER 
;;THIS METHOD COPIES THE ENTIRE 128Byte
;;OF HEADER,AND NOT ONLY FIRST &45 BYTES
LD HL,(&be7d)
LD BC,&e4
ADD HL,BC ;; HL = start of header    
;;COPY HEADER TO RAM BUFFER
LD BC,&8000
LD D,0
.HEAD_LOOP
LD A,128
CP D
JP Z,HEAD_EXIT
LD A,(HL)
LD (BC),A
INC HL
INC D
INC BC
JP HEAD_LOOP
.HEAD_EXIT
;;SAVE FILE SIZE TO &7002,
;;START ADDR OF READED FILE TO MEMORY &8000
POP HL 
LD (&7002),HL
DEC HL
PUSH HL
LD HL,&8080
LD (&7000),HL;;&7000=REMAINING BYTES TO READ

;;CAS_IN_CHAR READS FILE  AND 
;;FILLS THE 2K.BUFFER
.READ_2K
CALL CAS_IN_CHAR
LD (HL),A
INC HL
LD (&7000),HL
PUSH IY
POP HL
LD E,(HL)
INC HL
LD D,(HL)
LD BC,2047

;;LOOP FOR READING THE HOLE BUFFER
.READ_BYTE
;;COPY CURRENT BYTE TO RAM BUFFER
LD HL,(&7000)
LD A,(DE)
LD (HL),A
INC DE
INC HL
LD (&7000),HL
POP HL
DEC HL
LD A,H;;CHECK IF ALL DATA READED
OR L
JR Z,CLOSE_FILE

;;CHECK IF 2K.BUFFER IS FULL
LD A,B
OR C
JR Z,NEXT_2K
PUSH HL
JR READ_BYTE

.NEXT_2K
;;SET SYTEM'S ADDR OF CURRENT BYTE 
;;READED FROM FILE
LD (IY+0),E
LD (IY+1),D
;;ADDR OF DATA RECORDS TO BE READ
;;IS SET TO ZERO 
XOR A
LD (IY+21),A
LD (IY+22),A
JR READ_2K

.CLOSE_FILE
CALL CAS_IN_CLOSE

;;NOW FASTWRITE THE RAMBUFFER TO FILE

LD HL,(&7002);;READ FILE SIZE FROM &7002
;;ADD HEADER TO FILE'S DATASIZE 
LD BC,128
ADD HL,BC 
DEC HL
LD (&7002),HL

LD B,END_FWNAME-FWNAME
LD HL,FWNAME
LD DE,TWO_K_BUFFER
CALL CAS_OUT_OPEN
DEC HL
DEC HL
PUSH HL
POP IY ;;IY=ADDR.OF.CUR.POS.2KBUF 
LD HL,&8000
LD A,(HL)

;;CAS_OUT_CHAR FILLS THE 2K.BUFFER,
;;SET SYSTEM VARIABLES 
.WRITE_2K
CALL CAS_OUT_CHAR
INC HL
PUSH HL
PUSH IY
POP HL
LD E,(HL)
INC HL
LD D,(HL)
LD BC,2047
POP HL

;;LOOP FOR WRITING THE HOLE BUFFER
.WRITE_BYTE
LD A,(HL)
LD (DE),A
DEC BC
INC DE
INC HL
PUSH HL
LD HL,(&7002)
DEC HL
LD A,H;;;;CHECK IF ALL DATA WRITEN
OR L
JR Z,CLOSE_WFILE

;;CHECK IF 2K.BUFFER IS FULL
LD (&7002),HL
LD A,B
OR C
JR Z,NEXT_W2K
POP HL
JR WRITE_BYTE

.NEXT_W2K
LD (IY+0),E
LD (IY+1),D
LD A,0
LD (IY+21),A
LD A,&08
LD (IY+22),A
POP HL
JR WRITE_2K

.CLOSE_WFILE
LD HL,2048
SCF
CCF
SBC HL,BC
LD (IY+21),L
LD (IY+22),H
LD (IY+0),E
LD (IY+1),D
CALL CAS_OUT_CLOSE
RET

;;FILENAME TO READ
.FLNAME
DEFB "TEST.BIN"
.END_FLNAME

;;FILENAME TO WRITE
.FWNAME
DEFB "FILECOPY.BIN"
.END_FWNAME

.TWO_K_BUFFER DEFS 2048