;[BEGIN] ;//MODULE: DOS_FM ;//CREATE: 19-05-1998 AUTHOR: Denis Parinov ;//UPDATE: 24-10-1999 DNS Restore module ;--------------------------------------------------------------- ;Rev Date Name Description ;--------------------------------------------------------------- ;R01 16-11-1999 DNS ERROR READING FAT CHAIN ;--------------------------------------------------------------- ;FMS DB FMCOUNT ;ACCESS MODE: ; 00 - READ/WRITE ; 01 - READ ; 02 - WRITE ;FM_BUF: ;File Manipulator (FM) ; BYTE '. ' ;+00 NAME ; BYTE ' ' ;+08 EXT ; BYTE #10 ;+11 ATTRIBUT ; BYTE 0 ;+12 RESERVED; !TODO следующий кластер для чтения ; BYTE 0 ;+13 RESERVED; !TODO следующий кластер для записи ; BLOCK 8,0 ;+14 RESERVED ; WORD #0000 ;+22 TIME ; WORD #0000 ;+24 DATE ; WORD #0000 ;+26 START CLUSTER ; DWORD #0000 ;+28 SIZE FILE ; DWORD #0000 ;+32 FILE POSITION (FP) ; WORD #0000 ;+36 DIRECTORY CLUSTER ; WORD #0000 ;+38 HANDLE NUMBER ; BYTE #00 ;+40 DRIVE OR CURRENT ; BYTE #00 ;+41 ACCESS MODE ; BYTE #00 ;+42 TASK ; BYTE #00 ;+43 EMPTY /* ;!TEST FM_BUF: _sFM .Size EQU _sFM BLOCK (FMCOUNT-1)*FM_BUF.Size, 0 */ MACRO _mFM_FIND CP FMCOUNT+1 JR NC,ABS_FM PUSH DE LD IY,FM_BUF LD DE,FM_BUF.Size AND A JR Z,.endLoop .loop: ADD IY,DE DEC A JR NZ,.loop .endLoop: POP DE ; A=0 OR (IY) ;+00 NAME ENDM SET_FM: _mFM_FIND LD A,0 ;!FIXIT номер ошибки RET NZ ABS_FM LD A,DSS_Error.sys.INVALID_HANDLE SCF RET RES_FM: _mFM_FIND LD A,5 EXX SCF RET Z XOR A LD (IY+0),A RET GET_FM: LD B,FMCOUNT LD C,#FF LD IY,FM_BUF-FM_BUF.Size LD DE,FM_BUF.Size .loop: ADD IY,DE INC C LD A,(IY+0) OR A RET Z DJNZ .loop LD A,DSS_Error.sys.NO_HANDLES SCF RET ; HL:IX - OFFSET POINTER ; A - FILE MANIPULATOR MOVE_FP CALL SET_FM RET C INC B DEC B JR Z,.F_start DEC B JR Z,.F_current DEC B JR Z,.B_end LD A,DSS_Error.sys.INVALID_FUNCTION SCF RET ;from Start File .F_start: ; B=0 LD C,B LD D,B LD E,B JR MOVE_F1 ;from End File .B_end: LD C,(IY+28) LD B,(IY+29) LD E,(IY+30) LD D,(IY+31) JR MOVE_F1 ;from Current Position .F_current: LD C,(IY+32) LD B,(IY+33) LD E,(IY+34) LD D,(IY+35) MOVE_F1 ADD IX,BC ADC HL,DE LD D,XH LD E,XL LD (IY+32),E LD (IY+33),D LD (IY+34),L LD (IY+35),H XOR A RET ;FP COMPARE ; CY - FILE POINTER > SIZE ; NC - FILE POINTER < SIZE MOVE_CP LD L,(IY+28) LD H,(IY+29) LD E,(IY+32) LD D,(IY+33) AND A SBC HL,DE LD L,(IY+30) LD H,(IY+31) LD E,(IY+34) LD D,(IY+35) SBC HL,DE RET ;-------------------- ECL2 POP BC POP DE AND A RET BLOKRD0 POP BC POP DE SCF RET ;READ SECTORS OF FILE ;HL:DE - FP (in sectors) ; B - Amount sectors BLOK_RD PUSH BC LD (READMEM),IX LD A,(BootSector.S_P_C) ;SECTORS PER CLUSTER LD C,A LD B,0 CALL DIV32 LD B,XH LD C,XL PUSH HL ;RESIDUE LD L,(IY+26) ;START CLUSTER LD H,(IY+27) LD A,H OR L JR NZ,BLOKRD2 JR ECL2 ;R01 JR BLOKRD0 BLOKRD1 PUSH BC CALL R_F_FAT POP BC JR C,ECL2 ;R01 EX DE,HL DEC BC BLOKRD2 LD A,B OR C JR NZ,BLOKRD1 POP DE POP BC LD A,(BootSector.S_P_C) SUB E LD C,A ;\ CP B ; \ JR C,BLOKRD3 ;SIZE > RESIDUE CLUSTER ; \ LD C,B ;SIZE < CLUSTER ;->-|--> ; !TODO разобраться BLOKRD3 LD A,B ; / SUB C ; / LD B,A ;/ PUSH HL PUSH BC PUSH DE CALL NSECTOR POP DE ADD IX,DE JR NC,BLOKRD4 INC HL BLOKRD4 LD DE,(READMEM) LD A,(FatBuffer.DRIVE) LD B,C LD C,5 RST #18 JP C,BLOKRD0 POP BC LD HL,(READMEM) LD DE,(BootSector.B_P_S) BLOKRD5 ADD HL,DE DEC C JR NZ,BLOKRD5 LD (READMEM),HL POP DE LD A,B OR A RET Z BLOKRD6 LD HL,BootSector.S_P_C LD A,B SUB (HL) LD B,A LD C,(HL) JR NC,BLOKRD7 LD B,0 ADD A,(HL) ;0 AND CF LD C,A OR A ;CLEAR CF RET Z BLOKRD7 EX DE,HL PUSH BC CALL R_F_FAT POP BC JP C,ECL1 ;R01? EX DE,HL PUSH HL PUSH BC CALL NSECTOR LD DE,(READMEM) LD A,(FatBuffer.DRIVE) LD B,C LD C,5 RST #18 JP C,BLOKRD0 POP BC LD HL,(READMEM) LD DE,(BootSector.B_P_S) BLOKRD8 ADD HL,DE DEC C JR NZ,BLOKRD8 LD (READMEM),HL POP DE JR BLOKRD6 ECL1 AND A RET ;-------------------- BLOKWRC POP BC BLOKWR0 POP BC POP DE SCF RET ;WRITE SECTORS OF FILE ;HL:DE - FP (in sectors) ; B - Amount sectors BLOK_WR PUSH BC LD (READMEM),IX LD A,(BootSector.S_P_C) ;SECTORS PER CLUSTER LD C,A LD B,0 CALL DIV32 LD B,XH LD C,XL PUSH HL ;RESIDUE LD L,(IY+26) ;START CLUSTER LD H,(IY+27) LD A,H OR L JR NZ,BLOKWR2 PUSH BC CALL G_CLUST JR C,BLOKWRC LD (IY+26),L LD (IY+27),H LD DE,(FatBuffer.ENDCLUS) CALL W_T_FAT PUSH HL CALL WR_FAT POP HL POP BC JR BLOKWR2 BLOKWR1 PUSH BC CALL R_F_FAT JR NC,BLOKWRB PUSH HL CALL INC_FAT POP HL JR C,BLOKWRC CALL R_F_FAT BLOKWRB POP BC EX DE,HL DEC BC BLOKWR2 LD A,B OR C JR NZ,BLOKWR1 POP DE POP BC LD A,(BootSector.S_P_C) SUB E LD C,A CP B JR C,BLOKWR3 ;SIZE > RESIDUE CLUSTER LD C,B ;SIZE < CLUSTER BLOKWR3 LD A,B SUB C LD B,A PUSH HL PUSH BC PUSH DE CALL NSECTOR POP DE ADD IX,DE JR NC,BLOKWR4 INC HL BLOKWR4 LD DE,(READMEM) LD A,(FatBuffer.DRIVE) LD B,C LD C,6 RST #18 JP C,BLOKWR0 POP BC LD HL,(READMEM) LD DE,(BootSector.B_P_S) BLOKWR5 ADD HL,DE DEC C JR NZ,BLOKWR5 LD (READMEM),HL POP DE LD A,B OR A RET Z BLOKWR6 LD HL,BootSector.S_P_C LD A,B SUB (HL) LD B,A LD C,(HL) JR NC,BLOKWR7 LD B,0 ADD A,(HL) ;0 AND CF LD C,A OR A ;CLEAR CF RET Z BLOKWR7 EX DE,HL PUSH BC CALL R_F_FAT JR NC,BLOKWR9 PUSH HL CALL INC_FAT POP HL JR C,BLOKWRA CALL R_F_FAT BLOKWR9 POP BC EX DE,HL PUSH HL PUSH BC CALL NSECTOR LD DE,(READMEM) LD A,(FatBuffer.DRIVE) LD B,C LD C,6 RST #18 JP C,BLOKWR0 POP BC LD HL,(READMEM) LD DE,(BootSector.B_P_S) BLOKWR8 ADD HL,DE DEC C JR NZ,BLOKWR8 LD (READMEM),HL POP DE JR BLOKWR6 BLOKWRA POP BC LD A,DSS_Error.sys.DISK_FULL SCF RET TSTSIZE XOR A LD (READCOD),A LD L,(IY+32) ;FP LOW LD H,(IY+33) ADD HL,DE EXX LD DE,0 LD L,(IY+34) ;FP HIGH LD H,(IY+35) ADC HL,DE EXX ;HL':HL - NEW FP LD C,(IY+28) LD B,(IY+29) ;SIZE LOW AND A SBC HL,BC EXX LD C,(IY+30) ;SIZE HIGH LD B,(IY+31) SBC HL,BC EXX RET C ;OK READ ALL EX DE,HL SBC HL,DE ;VERY BIG EX DE,HL LD A,#FF LD (READCOD),A RET ; HL - ADDRESS ; DE - SIZE ; A - FM READ LD (R_POINT),HL LD (S_POINT),HL CALL SET_FM RET C CALL TSTSIZE LD A,D OR E JP Z,NOREAD PUSH DE LD A,(IY+_sFM.DRIVE) CALL OPENDSK JP C,RPERR1 LD C,(IY+_sFM.F_POSITION) LD E,(IY+_sFM.F_POSITION+1) LD A,E AND #01 LD B,A LD D,(IY+_sFM.F_POSITION+2) LD L,(IY+_sFM.F_POSITION+3) LD H,0 OR A RR L RR D RR E ;HL:DE FP (in sectors) ; BC FP residue (in bytes) LD A,B OR C JP NZ,ROV1 ROV4 POP BC PUSH BC SRL B JR Z,ROV2 LD (SECTORH),HL LD (SECTORL),DE LD IX,(R_POINT) CALL BLOK_RD JP C,RPERR1 LD DE,(R_POINT) READMEM+1: LD HL,0 // LD HL,(READMEM) AND A SBC HL,DE LD C,H LD B,0 ADD HL,DE LD (R_POINT),HL SRL C SECTORL+1: LD HL,0 // LD HL,(SECTORL) ADD HL,BC EX DE,HL SECTORH+1: LD HL,0 // LD HL,(SECTORH) LD C,B ADC HL,BC ROV2 POP BC LD A,B AND #01 LD B,A OR C JP Z,ROV6 PUSH BC LD IX,BUFFER+#C000 LD B,1 IN A,(SLOT3) PUSH AF IN A,(SLOT0) OUT (SLOT3),A CALL BLOK_RD POP BC LD C,SLOT3 OUT (C),B JP C,RPERR1 LD HL,BUFFER LD DE,(R_POINT) POP BC LDIR LD (R_POINT),DE ROV6: S_POINT+1: LD HL,0 // LD HL,(S_POINT) LD DE,(R_POINT) EX DE,HL AND A SBC HL,DE PUSH HL EX DE,HL LD XH,D LD XL,E LD HL,0 CALL MOVE_FP.F_current POP DE NOREAD: READCOD+1: LD A,0 // LD A,(READCOD) OR A RET ROV1 PUSH BC PUSH HL PUSH DE LD IX,BUFFER+#C000 LD B,1 IN A,(SLOT3) PUSH AF IN A,(SLOT0) OUT (SLOT3),A CALL BLOK_RD POP BC LD C,SLOT3 OUT (C),B POP HL JP C,RPERR3 LD BC,1 ADD HL,BC EX DE,HL POP HL LD C,B ADC HL,BC EXX POP DE LD HL,512 AND A SBC HL,DE LD B,H LD C,L POP HL AND A SBC HL,BC JR NC,ROV3 ADD HL,BC LD B,H LD C,L LD HL,0 ROV3 PUSH HL LD HL,BUFFER ADD HL,DE LD DE,(R_POINT) LDIR LD (R_POINT),DE EXX JP ROV4 RPERR3 POP HL RPERR2 POP HL RPERR1 POP BC SCF RET PWERR3 POP HL PWERR2 POP HL PWERR1 POP BC SCF RET RD_ONLY POP DE LD A,DSS_Error.sys.READONLY SCF RET ; HL - ADDRESS ; DE - SIZE ; A - FM WRITE LD (R_POINT),HL LD (S_POINT),HL PUSH DE CALL SET_FM JP C,PWERR1 LD A,(IY+_sFM.ACCESS_MODE) AND #01 JR NZ,RD_ONLY SET 7,(IY+_sFM.ACCESS_MODE) SET 5,(IY+_sFM.ATTRIBUT) LD A,(IY+_sFM.DRIVE) CALL OPENDSK JP C,PWERR1 LD C,(IY+32) LD A,(IY+33) LD E,A AND #01 LD B,A LD D,(IY+34) LD L,(IY+35) LD H,0 OR A RR L RR D RR E ;HL:DE FP (in sectors) ; BC FP residue (in bytes) LD A,B OR C JP NZ,WOV1 WOV4 POP BC PUSH BC SRL B JR Z,WOV2 PUSH HL PUSH DE PUSH BC R_POINT+2: LD IX,0 // LD IX,(R_POINT) CALL BLOK_WR POP BC JP C,PWERR3 LD C,B LD HL,(R_POINT) LD DE,#0200 WOV5 ADD HL,DE DJNZ WOV5 LD (R_POINT),HL LD B,0 POP HL ADD HL,BC EX DE,HL POP HL LD C,B ADC HL,BC WOV2 POP BC LD A,B AND #01 LD B,A OR C JP Z,WOV6 PUSH HL PUSH DE PUSH BC LD IX,BUFFER+#C000 LD B,1 IN A,(SLOT3) PUSH AF IN A,(SLOT0) OUT (SLOT3),A CALL BLOK_RD POP BC LD C,SLOT3 OUT (C),B LD DE,BUFFER LD HL,(R_POINT) POP BC JP C,PWERR2 LDIR LD (R_POINT),HL POP DE POP HL LD IX,BUFFER+#C000 LD B,1 IN A,(SLOT3) PUSH AF IN A,(SLOT0) OUT (SLOT3),A CALL BLOK_WR POP BC LD C,SLOT3 OUT (C),B RET C WOV6 LD DE,(S_POINT) LD HL,(R_POINT) AND A SBC HL,DE PUSH HL EX DE,HL LD XH,D LD XL,E LD HL,0 CALL MOVE_FP.F_current CALL MOVE_CP POP DE RET NC LD L,(IY+32) LD H,(IY+33) LD C,(IY+34) LD B,(IY+35) LD (IY+28),L LD (IY+29),H LD (IY+30),C LD (IY+31),B AND A RET WOV1 PUSH BC PUSH HL PUSH DE LD IX,BUFFER+#C000 LD B,1 IN A,(SLOT3) PUSH AF IN A,(SLOT0) OUT (SLOT3),A CALL BLOK_RD POP BC LD C,SLOT3 OUT (C),B POP DE POP HL EXX POP DE JP C,PWERR1 LD HL,512 AND A SBC HL,DE LD B,H LD C,L POP HL AND A SBC HL,BC JR NC,WOV3 ADD HL,BC LD B,H LD C,L LD HL,0 WOV3 PUSH HL LD HL,BUFFER ADD HL,DE LD DE,(R_POINT) EX DE,HL LDIR LD (R_POINT),HL EXX PUSH HL PUSH DE LD IX,BUFFER+#C000 LD B,1 IN A,(SLOT3) PUSH AF IN A,(SLOT0) OUT (SLOT3),A CALL BLOK_WR POP BC LD C,SLOT3 OUT (C),B POP HL JP C,PWERR2 LD BC,1 ADD HL,BC EX DE,HL POP HL LD C,B ADC HL,BC JP WOV4 ; HL - CLUSTER ; HL:IX - SECTOR NSECTOR DEC HL DEC HL EX DE,HL LD A,(BootSector.S_P_C) LD B,A LD HL,0 LD IX,0 ADD_DE1 ADD IX,DE JR NC,ADD_DE2 INC HL ADD_DE2 DJNZ ADD_DE1 LD DE,(FatBuffer.DAT_FRM) ADD IX,DE LD DE,#0000 ADC HL,DE RET ; HL:DE / BC => DE:IX HL-OSTATOK DIV32 LD XH,D LD XL,E EX DE,HL LD HL,0 LD A,#20 DIV001 ADD IX,IX EX DE,HL ADC HL,HL EX DE,HL ADC HL,HL SBC HL,BC JR NC,DIV002 ADD HL,BC DEC A JR NZ,DIV001 RET DIV002 INC IX DEC A JR NZ,DIV001 RET //READCOD DB #00 //READMEM DW #0000 //SECTORH DW 0 //SECTORL DW 0 //R_POINT DW 0 //S_POINT DW 0 ;//MODULE: DOS_FM ;[END]