;[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 ;!HARDCODE номер ошибки 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 ;!FIXIT заменить вызов HLDE/BC на HLDE/C 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,Dss.DRV.Read RST ToDSS.DRV 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 ToDSS.DRV 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,Dss.DRV.Write RST ToDSS.DRV 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,Dss.DRV.Write RST ToDSS.DRV 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) ;!TEST CHNDISK OPENDSK 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) ;!TEST CHNDISK OPENDSK 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]