SprinterFirmware/DOS/dos_fm.asm
2024-05-27 11:03:22 +03:00

1024 lines
13 KiB
NASM

;[BEGIN]
;//MODULE: DOS_FM
;//CREATE: 19-05-1998 AUTHOR: Denis Parinov
;//UPDATE: 24-10-1999 DNS Restore module
;//R01 : 16-11-1999 DNS ERROR READING FAT CHAIN
NAM EQU 0
EXT EQU 8
ATR EQU 11
TIM1 EQU 22
TIM2 EQU 23
DAT1 EQU 24
DAT2 EQU 25
CLU1 EQU 26
CLU2 EQU 27
LEN1 EQU 28
LEN2 EQU 29
LEN3 EQU 30
LEN4 EQU 31
POS1 EQU 32
POS2 EQU 33
POS3 EQU 34
POS4 EQU 35
DIRCLU1 EQU 36
DIRCLU2 EQU 37
HND1 EQU 38
HND2 EQU 39
FDRV EQU 40
AMODE EQU 41
FTASK EQU 42
FMCOUNT EQU 10
FMS DB 0x00
;ACCESS MODE:
; 00 - READ/WRITE
; 01 - READ
; 02 - WRITE
;File Manipulator (FM)
FM_BUF
DB ". " ;+00 NAME
DB " " ;+08 EXT
FM_BUF_ATTR ; Attribute
DB 10h
FM_BUF_RES ; Reserved
DS 10,0
FM_BUF_TIME ; Time
DW 0h
FM_BUF_DATE ; Date
DW 0h
FM_BUF_ST_CL ; Start cluster
DW 0h
FM_BUF_FSL ; FileSize low word
DW 0h
FM_BUF_FSH ; FileSize hi word
DW 0h
FM_BUF_FPL ; File position low word
DW 0h
FM_BUF_FPH ; File position hi word
DW 0h
FM_BUF_DIR_CL ; Directory cluster
DW 0h
FM_BUF_HNDL ; Handle number
DW 0h
FM_BUF_DC ; DRIVE OR CURRENT
DB 0h
FM_BUF_AM ; ACCESS MODE
DB 0h
FM_BUF_TASK ; TASK
DB 0h
FM_BUF_REM
DS 17,0x00
END_FM
;End of FM
FM_SIZE EQU END_FM-FM_BUF
; TODO: Rewritten sub
SET_FM
CP 0xb
JP NC,ABS_FM
PUSH DE
PUSH HL
PUSH BC
EX AF,AF'
LD A,0x1
CALL BANK
EX AF,AF'
LD C,A
LD A,(FMS)
CP C
JR Z,SET_FM3
LD A,C
PUSH AF
CALL SET_FM_SUB
POP AF
LD HL,0xe000
LD DE,0x3d
OR A
JR Z,SET_FM2
SET_FM1
ADD HL,DE
CP (HL)
JR Z,SET_FM2
DJNZ SET_FM1
POP BC
POP HL
POP DE
EX AF,AF'
OUT (PAGE3),A
ABS_FM
LD A,0x5
SCF
RET
SET_FM2
LD DE,FMS
LD BC,0x3d
LDIR
SET_FM3
EX AF,AF'
OUT (PAGE3),A
POP BC
POP HL
POP DE
RET
; TODO: New sub
SET_FM_SUB
PUSH DE
LD A,(FMS)
INC A
JR Z,SFS_L3
DEC A
LD B,A
LD HL,0xe000
LD DE,0x3d
OR B
JR Z,SFS_L2
SFS_L1
ADD HL,DE
DJNZ SFS_L1
SFS_L2
EX DE,HL
LD HL,FMS
LD BC,0x3d
LDIR
SFS_L3
POP DE
RET
RES_FM
CP 0xb
JR NC,ABS_FM
EX AF,AF'
LD A,0x1
CALL BANK
EX AF,AF'
PUSH HL
PUSH BC
LD HL,0xe000
LD DE,0x3d
LD B,A
RES_FM1
ADD HL,DE
DJNZ RES_FM1
LD A,0xff
LD (FMS),A
LD DE,FMS
EX DE,HL
PUSH HL
PUSH DE
INC HL
XOR A
LD (HL),A
LD BC,0x3c
LDIR
POP DE
POP HL
LD BC,0x3d
LDIR
EX AF,AF'
OUT (PAGE3),A
POP BC
POP HL
RET
; TODO: New sub, called from OPENAT
GET_FM
PUSH HL
PUSH DE
LD A,0x1
CALL BANK
EX AF,AF'
CALL SET_FM_SUB
LD B,0xa
LD C,0x0
LD HL,0xe000
LD DE,0x3d
GET_FM1
ADD HL,DE
INC C
LD A,(HL)
INC A
JR Z,GET_FM2
DJNZ GET_FM1
SCF
JP GET_FM3
GET_FM2
LD A,C
LD DE,FMS
LD BC,0x3d
LDIR
LD (FMS),A
LD C,A
GET_FM3
POP DE
POP HL
EX AF,AF'
OUT (PAGE3),A
RET
; HL:IX - OFFSET POINTER
; A - FILE MANIPULATOR
MOVE_FP
CALL SET_FM
RET C
INC B
DEC B
JR Z,MOVE_FA
DEC B
JR Z,MOVE_FB
DEC B
JR Z,MOVE_FC
JP NOPS
;from Start File
MOVE_FA
LD BC,0
LD E,C
LD D,C
JR MOVE_F1
;from End File
MOVE_FC
LD BC,(FM_BUF_FSL)
LD DE,(FM_BUF_FSH)
JR MOVE_F1
;from Current Position
MOVE_FB
LD BC,(FM_BUF_FPL)
LD DE,(FM_BUF_FPH)
MOVE_F1
ADD IX,BC
ADC HL,DE
LD (FM_BUF_FPL),IX
LD (FM_BUF_FPH),HL
XOR A
RET
;FP COMPARE
; CY - FILE POINTER > SIZE
; NC - FILE POINTER < SIZE
MOVE_CP
LD HL,(FM_BUF_FSL)
LD DE,(FM_BUF_FPL)
AND A
SBC HL,DE
LD HL,(FM_BUF_FSH)
LD DE,(FM_BUF_FPH)
SBC HL,DE
RET
;--------------------
ECL2:
POP BC
POP DE
AND A
RET
BLOKRD0:
POP BC
POP DE
SCF
RET
; -------------------------------------
; READ FILE SECTORS
; HL:DE - File pos in sectors
; B - Count of sectors
BLOK_RD:
PUSH BC
LD (READMEM),IX
LD A,(S_P_C) ;SECTORS PER CLUSTER
CALL DIV32
PUSH HL
LD HL,(FM_BUF_ST_CL)
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,(S_P_C)
SUB E
LD C,A
CP B
JR C,BLOKRD3 ;SIZE > RESIDUE CLUSTER
LD C,B ;SIZE < CLUSTER
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,(DRIVE)
LD B,C
LD C,5
RST #18
JR C,BLOKRD0
POP BC
LD HL,(READMEM)
LD DE,(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,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
JR C,ECL1 ;R01?
EX DE,HL
PUSH HL
PUSH BC
CALL NSECTOR
LD DE,(READMEM)
LD A,(DRIVE)
LD B,C
LD C,5
RST #18
JP C,BLOKRD0
POP BC
LD HL,(READMEM)
LD DE,(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 FILE SECTORS
; HL:DE - File pointer in sectors
; B - Count of sectors
BLOK_WR:
PUSH BC
LD (READMEM),IX
LD A,(S_P_C) ;SECTORS PER CLUSTER
CALL DIV32
PUSH HL
LD HL,(FM_BUF_ST_CL)
LD A,H
OR L
JR NZ,BLOKWR2
PUSH BC
CALL G_CLUST
JR C,BLOKWRC
LD (FM_BUF_ST_CL),HL
LD DE,(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,(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,(DRIVE)
LD B,C
LD C,6
RST #18
JP C,BLOKWR0
POP BC
LD HL,(READMEM)
LD DE,(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,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,(DRIVE)
LD B,C
LD C,6
RST #18
JP C,BLOKWR0
POP BC
LD HL,(READMEM)
LD DE,(B_P_S)
BLOKWR8
ADD HL,DE
DEC C
JR NZ,BLOKWR8
LD (READMEM),HL
POP DE
JR BLOKWR6
BLOKWRA
POP BC
LD A,10
SCF
RET
TSTSIZE
XOR A
LD (READCOD),A
LD HL,(FM_BUF_FPL) ;FP LOW
ADD HL,DE
EXX
LD E,A
LD D,A
LD HL,(FM_BUF_FPH)
ADC HL,DE
EXX ;HL':HL - NEW FP
LD BC,(FM_BUF_FSL)
AND A
SBC HL,BC
EXX
LD BC,(FM_BUF_FSH) ;SIZE HIGH
SBC HL,BC
EXX
RET C ;OK READ ALL
EX DE,HL
SBC HL,DE ;VERY BIG
EX DE,HL
LD A,0xFF
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,(FM_BUF_DC)
CALL OPENDSK
JP C,RPERR1
LD HL, FM_BUF_FPL
LD C,(HL)
INC HL
LD A,(HL)
INC HL
LD E,A
AND 0x01
LD B,A
LD D,(HL)
INC HL
LD L,(HL)
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)
LD HL,(READMEM)
AND A
SBC HL,DE
LD C,H
LD B,0
ADD HL,DE
LD (R_POINT),HL
SRL C
LD HL,(SECTORL)
ADD HL,BC
EX DE,HL
LD HL,(SECTORH)
LD C,B
ADC HL,BC
ROV2
POP BC
LD A,B
AND #01
LD B,A
OR C
JR Z,ROV6
PUSH BC
LD IX,BUFFER+#C000
LD B,1
IN A,(PAGE3)
PUSH AF
IN A,(PAGE0)
OUT (PAGE3),A
CALL BLOK_RD
POP BC
LD C,PAGE3
OUT (C),B
JP C,RPERR1
LD HL,BUFFER
LD DE,(R_POINT)
POP BC
LDIR
LD (R_POINT),DE
ROV6
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_FB
POP DE
NOREAD
LD A,(READCOD)
OR A
RET
ROV1
PUSH BC
PUSH HL
PUSH DE
LD IX,BUFFER+#C000
LD B,1
IN A,(PAGE3)
PUSH AF
IN A,(PAGE0)
OUT (PAGE3),A
CALL BLOK_RD
POP BC
LD C,PAGE3
OUT (C),B
POP HL
JR 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,8
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,(FM_BUF_AM)
LD C,A
AND 0x01
JR NZ,RD_ONLY
LD A,C
SET 7,A
LD (FM_BUF_AM),A
LD A,(FM_BUF_ATTR)
SET 5,A
LD (FM_BUF_ATTR),A
LD A,(FM_BUF_DC)
CALL OPENDSK
JR C,PWERR1
LD HL,FM_BUF_FPL
LD C,(HL)
INC HL
LD A,(HL)
INC HL
LD E,A
AND #01
LD B,A
LD D,(HL)
INC HL
LD L,(HL)
LD H,0x0000
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
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
POP HL
ADD HL,BC
EX DE,HL
POP HL
LD C,B
ADC HL,BC
WOV2
POP BC
LD A,B
AND 0x01
LD B,A
OR C
JR Z,WOV6
PUSH HL
PUSH DE
PUSH BC
LD IX,BUFFER+#C000
LD B,1
IN A,(PAGE3)
PUSH AF
IN A,(PAGE0)
OUT (PAGE3),A
CALL BLOK_RD
POP BC
LD C,PAGE3
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,(PAGE3)
PUSH AF
IN A,(PAGE0)
OUT (PAGE3),A
CALL BLOK_WR
POP BC
LD C,PAGE3
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_FB
CALL MOVE_CP
POP DE
RET NC
LD HL,(FM_BUF_FPL)
LD BC,(FM_BUF_FPH)
LD (FM_BUF_FSL),HL
LD (FM_BUF_FSH),BC
AND A
RET
WOV1
PUSH BC
PUSH HL
PUSH DE
LD IX,BUFFER+#C000
LD B,1
WOV_PG EQU $ + 1
IN A,(PAGE3)
PUSH AF
IN A,(PAGE0)
OUT (PAGE3),A
CALL BLOK_RD
POP BC
LD C,PAGE3
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,(PAGE3)
PUSH AF
IN A,(PAGE0)
OUT (PAGE3),A
CALL BLOK_WR
POP BC
LD C,PAGE3
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
LD DE,0x0000
DEC HL
DEC HL
LD A,(S_P_C)
LD B,A
DEC A
LD A,B
LD B,E
JR Z,ADD_DE2
RRCA
ADD_DE1
ADD HL,HL
RL E
RL D
RRCA
JP NC,ADD_DE1 ; TODO: JR?
ADD_DE2
EX DE,HL
DB 0xDD ; TODO: fix to undocumented
LD L,E
DB 0xDD
LD H,D
LD DE,(DAT_FRM)
ADD IX,DE
LD E,B
LD D,B
ADC HL,DE
AND A
RET
; HL:DE / BC => DE:IX HL-OSTATOK
DIV32
LD B,A
DEC A
JP NZ,DIV001
LD C,A
JR DIV003
DIV001
AND E
LD C,A
LD A,B
RRCA
DIV002
SRL H
RR L
RR D
RR E
RRCA
JR NC,DIV002
DIV003
EX DE,HL
LD B,H
LD H,0x0
LD A,C
LD C,L
LD L,A
RET
READCOD
DB 0x00
READMEM
DW 0x0000
SECTORH
DW 0
SECTORL
DW 0
R_POINT
DW 0
S_POINT
DW 0
;//MODULE: DOS_FM
;[END]