;[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 */ ; на выходе без ошибок IY указывает на файловый манипулятор MACRO _mFM_FIND CP FMCOUNT JR NC,ABS_FM PUSH DE LD IY,CORE_BUFFERS.FM_BUF LD DE,CORE_BUFFERS.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,DSS_Error.sys.NO_ERROR RET NZ ABS_FM LD A,DSS_Error.sys.INVALID_HANDLE SCF RET RES_FM: _mFM_FIND LD A,DSS_Error.sys.INVALID_HANDLE ;EXX SCF RET Z XOR A LD (IY+0),A RET ; GET_FM: LD B,FMCOUNT LD C,#FF LD IY,CORE_BUFFERS.FM_BUF - CORE_BUFFERS.FM_BUF.Size LD DE,CORE_BUFFERS.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 /* ;!TEST CHECK LOCKING 10/11/2023 GET_FM: LD IY,0 LD (.freeHandle),IY ; LD B,FMCOUNT LD C,#FF LD IY,CORE_BUFFERS.FM_BUF - CORE_BUFFERS.FM_BUF.Size LD DE,CORE_BUFFERS.FM_BUF.Size .loop: ADD IY,DE INC C ; CHECK LOCKING ; .cont: 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 JP .DO ;from End File .B_end: LD C,(IY+_sFM.F_SIZE) LD B,(IY+_sFM.F_SIZE+1) LD E,(IY+_sFM.F_SIZE+2) LD D,(IY+_sFM.F_SIZE+3) JP .DO ;from Current Position .F_current: LD C,(IY+_sFM.F_POSITION) LD B,(IY+_sFM.F_POSITION+1) LD E,(IY+_sFM.F_POSITION+2) LD D,(IY+_sFM.F_POSITION+3) .DO: ADD IX,BC ADC HL,DE LD D,XH LD E,XL LD (IY+_sFM.F_POSITION),E LD (IY+_sFM.F_POSITION+1),D LD (IY+_sFM.F_POSITION+2),L LD (IY+_sFM.F_POSITION+3),H XOR A RET ;FP COMPARE ; CY - FILE POINTER > SIZE ; NC - FILE POINTER < SIZE MOVE_CP: LD L,(IY+_sFM.F_SIZE) LD H,(IY+_sFM.F_SIZE+1) LD E,(IY+_sFM.F_POSITION) LD D,(IY+_sFM.F_POSITION+1) AND A SBC HL,DE LD L,(IY+_sFM.F_SIZE+2) LD H,(IY+_sFM.F_SIZE+3) LD E,(IY+_sFM.F_POSITION+2) LD D,(IY+_sFM.F_POSITION+3) SBC HL,DE RET ;-------------------- ECL2: ;[x] SAVE CLUSTER AFTER READ ;!TEST POP BC ; 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 (READ.MEM),IX LD A,(CORE_BUFFERS.BootSector.S_P_C) ;SECTORS PER CLUSTER LD C,A LD B,0 ;!FIXIT ;HL:DE / BC => DE:IX HL-OSTATOK CALL DIV_for_SPC ;!FIXIT далее заточка на то, что в DE всегда 0 - раздел не больше 2Gb LD B,XH LD C,XL PUSH HL ;RESIDUE LD L,(IY+_sFM.ST_CLUSTER) ;START CLUSTER LD H,(IY+_sFM.ST_CLUSTER+1) LD A,H OR L ;[x] SAVE CLUSTER AFTER READ ;!TEST ;JR NZ,BLOKRD2 PUSH BC JR NZ,.saveClustersOffset ; JP ECL2 ;R01 JR BLOKRD0 .saveClustersOffset: ;[x] SAVE CLUSTER AFTER READ ;!TEST LD E,(IY+_sFM.KnownCluster_L) LD D,(IY+_sFM.KnownCluster_H) LD A,D OR E JR Z,BLOKRD2 PUSH DE PUSH HL PUSH BC LD E,(IY+_sFM.KnownOffset_L) LD D,(IY+_sFM.KnownOffset_H) LD A,D OR E JR Z,.noOptimization_1 POP HL AND A SBC HL,DE JR C,.noOptimization_2 LD C,L LD B,H POP HL POP DE EX DE,HL JP BLOKRD2 .noOptimization_1: POP BC .noOptimization_2: POP HL POP DE JP BLOKRD2 ; 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 ;[x] SAVE CLUSTER AFTER READ ;!TEST LD (IY+_sFM.KnownCluster_L),L LD (IY+_sFM.KnownCluster_H),H POP BC LD (IY+_sFM.KnownOffset_L),C LD (IY+_sFM.KnownOffset_H),B ; POP DE POP BC LD A,(CORE_BUFFERS.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,(READ.MEM) LD A,(FatBuffer.DRIVE) LD B,C LD C,Dss.DRV.Read RST ToDSS.DRV JP C,BLOKRD0 POP BC LD HL,(READ.MEM) LD DE,(CORE_BUFFERS.BootSector.B_P_S) BLOKRD5 ADD HL,DE DEC C JR NZ,BLOKRD5 LD (READ.MEM),HL POP DE LD A,B OR A RET Z BLOKRD6 LD HL,CORE_BUFFERS.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,(READ.MEM) LD A,(FatBuffer.DRIVE) LD B,C LD C,Dss.DRV.Read RST ToDSS.DRV JP C,BLOKRD0 POP BC LD HL,(READ.MEM) LD DE,(CORE_BUFFERS.BootSector.B_P_S) BLOKRD8 ADD HL,DE DEC C JR NZ,BLOKRD8 LD (READ.MEM),HL POP DE JR BLOKRD6 ECL1 AND A RET ;-------------------- BLOKWRC: POP BC ;[x] SAVE CLUSTER AFTER WRITE ;!TEST POP BC ; BLOK_WR.ErrorWrite: POP BC POP DE LD A,DSS_Error.sys.WRITE_ERROR SCF RET ;WRITE SECTORS OF FILE ;HL:DE - FP (in sectors), IX - data in RAM ; B - Amount sectors BLOK_WR: PUSH BC LD (READ.MEM),IX LD A,(CORE_BUFFERS.BootSector.S_P_C) ;SECTORS PER CLUSTER LD C,A LD B,0 ;HL:DE / BC => DE:IX HL-OSTATOK CALL DIV_for_SPC LD B,XH LD C,XL PUSH HL ;RESIDUE LD L,(IY+_sFM.ST_CLUSTER) ;START CLUSTER LD H,(IY+_sFM.ST_CLUSTER+1) LD A,H OR L ;[x] SAVE CLUSTER AFTER WRITE ;!TEST ;JR NZ,BLOKWR2 PUSH BC JR NZ,.saveClustersOffset ; PUSH BC CALL G_CLUST JR C,BLOKWRC LD (IY+_sFM.ST_CLUSTER),L LD (IY+_sFM.ST_CLUSTER+1),H LD DE,(FatBuffer.ENDCLUS) CALL W_T_FAT PUSH HL CALL WR_FAT POP HL POP BC JP .WR2 .saveClustersOffset: ;[x] SAVE CLUSTER AFTER WRITE ;!TEST LD E,(IY+_sFM.KnownCluster_L) LD D,(IY+_sFM.KnownCluster_H) LD A,D OR E JR Z,.WR2 ; PUSH DE PUSH HL PUSH BC LD E,(IY+_sFM.KnownOffset_L) LD D,(IY+_sFM.KnownOffset_H) LD A,D OR E JR Z,.noOptimization_1 ; POP HL AND A SBC HL,DE JR C,.noOptimization_2 ; LD C,L LD B,H POP HL POP DE ; EX DE,HL JP .WR2 .noOptimization_1: POP BC .noOptimization_2: POP HL POP DE JP .WR2 ; .loop: PUSH BC CALL R_F_FAT JR NC,.WRB PUSH HL CALL INC_FAT POP HL JR C,BLOKWRC CALL R_F_FAT .WRB: POP BC EX DE,HL DEC BC .WR2: LD A,B OR C JR NZ,.loop ;[x] SAVE CLUSTER AFTER WRITE ;!TEST LD (IY+_sFM.KnownCluster_L),L LD (IY+_sFM.KnownCluster_H),H POP BC LD (IY+_sFM.KnownOffset_L),C LD (IY+_sFM.KnownOffset_H),B ; POP DE POP BC LD A,(CORE_BUFFERS.BootSector.S_P_C) SUB E LD C,A CP B JR C,.WR3 ;SIZE > RESIDUE CLUSTER LD C,B ;SIZE < CLUSTER .WR3: LD A,B SUB C LD B,A PUSH HL PUSH BC PUSH DE CALL NSECTOR POP DE ADD IX,DE JR NC,.WR4 INC HL ; DOUBLE 1 .WR4: LD DE,(READ.MEM) LD A,(FatBuffer.DRIVE) LD B,C LD C,Dss.DRV.Write RST ToDSS.DRV JP C,.ErrorWrite POP BC LD HL,(READ.MEM) LD DE,(CORE_BUFFERS.BootSector.B_P_S) .loop2: ADD HL,DE DEC C JR NZ,.loop2 LD (READ.MEM),HL POP DE ; LD A,B OR A RET Z .WR6: LD HL,CORE_BUFFERS.BootSector.S_P_C LD A,B SUB (HL) LD B,A LD C,(HL) JR NC,.WR7 LD B,0 ADD A,(HL) ;0 AND CF LD C,A OR A ;CLEAR CF RET Z .WR7: EX DE,HL PUSH BC CALL R_F_FAT JR NC,.WR9 PUSH HL CALL INC_FAT POP HL JR C,.ErrorFull CALL R_F_FAT .WR9: POP BC EX DE,HL PUSH HL PUSH BC CALL NSECTOR ; DOUBLE 1 LD DE,(READ.MEM) LD A,(FatBuffer.DRIVE) LD B,C LD C,Dss.DRV.Write RST ToDSS.DRV JP C,.ErrorWrite POP BC LD HL,(READ.MEM) LD DE,(CORE_BUFFERS.BootSector.B_P_S) .loop3: ADD HL,DE DEC C JR NZ,.loop3 LD (READ.MEM),HL POP DE ; JR .WR6 .ErrorFull: POP BC LD A,DSS_Error.sys.DISK_FULL SCF RET TSTSIZE: XOR A LD (READ.COD),A LD L,(IY+_sFM.F_POSITION) ;FP LOW LD H,(IY+_sFM.F_POSITION+1) ADD HL,DE EXX LD DE,0 LD L,(IY+_sFM.F_POSITION+2) ;FP HIGH LD H,(IY+_sFM.F_POSITION+3) ADC HL,DE EXX ;HL':HL - NEW FP LD C,(IY+_sFM.F_SIZE) LD B,(IY+_sFM.F_SIZE+1) ;SIZE LOW AND A SBC HL,BC EXX LD C,(IY+_sFM.F_SIZE+2) ;SIZE HIGH LD B,(IY+_sFM.F_SIZE+3) SBC HL,BC EXX RET C ;OK READ ALL EX DE,HL SBC HL,DE ;VERY BIG EX DE,HL LD A,#FF LD (READ.COD),A RET ; HL - ADDRESS ; DE - SIZE ; A - FM ;READ_FN: ; _mSavePath 1 ; HL - ADDRESS ; DE - SIZE ; A - FM READ: LD (.R_POINT),HL LD (.S_POINT),HL CALL SET_FM RET C CALL TSTSIZE ;!FIXIT можно перенести в начало процедуры LD A,D OR E JP Z,.NOREAD ; PUSH DE LD A,(IY+_sFM.DRIVE) CALL OPENDSK JP C,.ERR_1 ;Расчёт смещения в секторах ; 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 LD H,0 LD L,(IY+_sFM.F_POSITION+3) LD D,(IY+_sFM.F_POSITION+2) LD E,(IY+_sFM.F_POSITION+1) LD A,E AND #01 LD B,A LD C,(IY+_sFM.F_POSITION) ;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 .R_POINT+2: LD IX,0 CALL BLOK_RD JP C,.ERR_1 LD DE,(.R_POINT) .MEM+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,CORE_BUFFERS.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,.ERR_1 LD HL,CORE_BUFFERS.BUFFER LD DE,(.R_POINT) POP BC LDIR LD (.R_POINT),DE .ROV6: LD HL,(.R_POINT) .S_POINT+1: LD DE,0 ;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: .COD+1: LD A,0 OR A RET .ROV1: PUSH BC PUSH HL PUSH DE LD IX,CORE_BUFFERS.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,.ERR_3 LD BC,1 ADD HL,BC EX DE,HL POP HL LD C,B ADC HL,BC EXX POP DE LD HL,512 ;!HARDCODE 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 ;!TODO можно тут упростить дальнейшую ветку? .ROV3: PUSH HL LD HL,CORE_BUFFERS.BUFFER ADD HL,DE LD DE,(.R_POINT) LDIR LD (.R_POINT),DE EXX JP .ROV4 .ERR_3: POP HL .ERR_2: POP HL .ERR_1: 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 JR C,PWERR1 LD A,(IY+_sFM.ACCESS_MODE) AND FAT_ATTR.READ_ONLY JR NZ,RD_ONLY SET 7,(IY+_sFM.ACCESS_MODE) SET 5,(IY+_sFM.ATTRIBUT) LD A,(IY+_sFM.DRIVE) CALL OPENDSK JR C,PWERR1 ; LD C,(IY+_sFM.F_POSITION) LD A,(IY+_sFM.F_POSITION+1) LD E,A 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,.WOV1 .WOV4: POP BC PUSH BC SRL B JR Z,.WOV2 PUSH HL PUSH DE PUSH BC .R_POINT+2: LD IX,0 CALL BLOK_WR POP BC JR C,PWERR3 LD C,B LD HL,(.R_POINT) LD DE,#0200 ;!HARDCODE .WOV5: ADD HL,DE DJNZ .WOV5 ; B=0 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 JR Z,.WOV6 PUSH HL PUSH DE PUSH BC LD IX,CORE_BUFFERS.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,CORE_BUFFERS.BUFFER LD HL,(.R_POINT) POP BC JP C,PWERR2 LDIR LD (.R_POINT),HL POP DE POP HL LD IX,CORE_BUFFERS.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 HL,(.R_POINT) .S_POINT+1: LD DE,0 ; CF=0 ;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+_sFM.F_POSITION+0) LD H,(IY+_sFM.F_POSITION+1) LD C,(IY+_sFM.F_POSITION+2) LD B,(IY+_sFM.F_POSITION+3) LD (IY+_sFM.F_SIZE+0),L LD (IY+_sFM.F_SIZE+1),H LD (IY+_sFM.F_SIZE+2),C LD (IY+_sFM.F_SIZE+3),B AND A RET ; .WOV1: PUSH BC PUSH HL PUSH DE LD IX,CORE_BUFFERS.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 ;!HARDCODE 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,CORE_BUFFERS.BUFFER ADD HL,DE LD DE,(.R_POINT) EX DE,HL LDIR LD (.R_POINT),HL EXX PUSH HL PUSH DE LD IX,CORE_BUFFERS.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 ////////////// OLD //////////////// ; HL - CLUSTER ; HL:IX - SECTOR ; NSECTOR: DEC HL ; DEC HL ; EX DE,HL ; LD A,(CORE_BUFFERS.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) ;first data sector ; ADD IX,DE ; LD DE,#0000 ; ADC HL,DE ; RET ////////////// NEW ////////////////// ; in: HL - CLUSTER ; out: HL:IX - SECTOR NSECTOR: DEC HL DEC HL LD DE,0 LD A,(CORE_BUFFERS.BootSector.S_P_C) XOR 1 JR Z,.skip ; RRA .loop: ADD HL,HL RL E ; RL D RRA JP NC,.loop ; .skip: EX DE,HL LD XL,E LD XH,D LD DE,(FatBuffer.DAT_FRM) ;first data sector XOR A ADD IX,DE LD D,A LD E,A ADC HL,DE RET ///////////////////////////////////// ; HL:DE / C => DE:IX HL-OSTATOK (DE:BC.HL). Легко переделать под HL:DE / A => HL:DE.A DIV_for_SPC: LD A,C DEC A JR Z,.exit ; AND E LD B,A ; остаток LD A,C RRCA ; .loop: SRL H : RR L RR D : RR E RRCA JP NC,.loop LD A,B ; .exit: LD XH,D LD XL,E EX DE,HL LD H,0 LD L,A RET ; DIV32: LD A,#FF ; LD B,E ; .loop: SRL C ; JR C,.exitLoop ; SRL H : RR L : RR D : RR E : SLA A ; JP .loop ; .exitLoop: ; CPL ; AND B ; LD XH,D ; LD XL,E ; EX DE,HL ; LD H,0 ; LD L,A ; RET /* DEFINE NEW_DIV 1 DIV32: LD XH,D LD XL,E IFN NEW_DIV 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 ELSE div32_16: ;HLIX/BC -> HLIX remainder DE ;174+4*div32_16_sub8 ;min: 2186cc ;max: 2794cc ;avg: 2466cc ;61 bytes ex de,hl ; 4 ; Negate BC to allow add instead of sbc xor a ; 4 ; Need to set HL to 0 anyways, so save 2cc and a byte ld h,a ; 4 ld l,a ; 4 sub c ; 4 ld c,a ; 4 sbc a,a ; 4 sub b ; 4 ld b,a ; 4 ld a,d ; 4 call div32_16_sub8 ; 17 rla ; 4 ld d,a ; 4 ld a,e ; 4 call div32_16_sub8 ; 17 rla ; 4 ld e,a ; 4 ld a,ixh ; 8 call div32_16_sub8 ; 17 rla ; 4 ld ixh,a ; 8 ld a,ixl ; 8 call div32_16_sub8 ; 17 rla ; 4 ld ixl,a ; 8 ;ex de,hl ; 4 ret ; 10 div32_16_sub8: ;119+8*div32_16_sub ;min: 503cc ;max: 655cc ;avg: 573cc call 1F 1: ;17+2(17+2(div32_16_sub))) call 1F 1: ;17+2(div32_16_sub) call div32_16_sub div32_16_sub: ;48+{8,0+{0,19}} ;min: 48cc ;max: 67cc ;avg: 56.75cc rla ; 4 adc hl,hl ; 15 jr c,1F ;12/7 add hl,bc ; 11 ret c ;11/5 sbc hl,bc ; 15 ret ; 10 1: add hl,bc ; 11 scf ; 4 ret ; 10 ENDIF */ ;