Programming:Read/Write a file quickly byte-by-byte
From CPCWiki - THE Amstrad CPC encyclopedia!
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