; LAST UPDATE: 15.02.2023 savelij
TITLE "mounter.a80 ROM_RST83"
MOUNTER CALL P5_READ_BYTE
LD A,(NEXTBYTERST8)
ADD A,A
LD E,A
LD D,0
LD HL,TAB_MOUNTER
ADD HL,DE
LD A,(HL)
INC HL
LD H,(HL)
LD L,A
JP (HL)
TAB_MOUNTER DW OPEN_MOUNT ; монтирование образа
DW RDWR_MOUNT ; чтение/запись примонтированных образов
DW FIND_MOUNTED ; поиск монтируемых образов прописанных в IMAGE.FNT
DW GET_MOUNTED ; получение буфера описателей примонтированных образов
DW CLOSEMOUNT ; демонтирование образа
DW LOADIMAGE ; загрузка образа в рамдиск
DW REST_NAMELOAD ; получение описателя файла загруженного в рамдиск
DW CMP_DRIVE ; проверка примонтированного образа на указанной букве
DW GET_VIRT_BITS ; получение битов смонтированных дисков
DW SET_VIRTREAL ; переключение реального/виртуального дисковода
DW SET_REAL
DW SET_VIRT
; DW MOUNT_RAMDISK ; монтирование рамдиска
; DW SET_RAMDISK ; отключение/установка рамдиска
NOFUNC RET
; загрузка образа в рамдиск
LOADIMAGE LD IYL,INTERNAL
CALL OPEN_FILE
PUSH HL
LD DE,SUPPORT_EXT
CALL CP_EXT
LD (EXT_TYPE),A
LD HL,FILE_SRC
LD DE,NAME_RAMDISK
LD BC,0x20
LDIR
POP HL
CP _TAP
JR Z,LOAD_TAPE
CP _FDI
JP Z,LOAD_FDI
CP _SCL
JP Z,LOAD_SCL
LD A,RAM_DATARAMD
ILD_IMG1 PUSH AF
LD BC,WIN_P5
OUT (C),A
LD A,0x20
LD HL,CPU5
CALL READ_FILE
JR C,ILD_IMG2
POP AF
INC A
JR ILD_IMG1
LOAD_TAPE LD A,RAM_TAPE
JR ILD_IMG1
ILD_IMG2 POP AF
LD A,(EXT_TYPE)
SUB _TAP
RET Z ; если TAP то на выход
; для TRD образа генерация таблицы секторов/дорожек
EVOPORT WIN_P5,RAM_DATARAMD ; нужна страница откуда начинается загруженный образ
ILD_IMG3 LD HL,(CPU5+0x8E1) ; первый свободный трек сектор
LD A,L
LD L,H
LD H,0
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
OR L
LD L,A ; количество занятых секторов с директорией
LD DE,(CPU5+0x8E5) ; количество свободных секторов
ADD HL,DE
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL ; H=количество дорожек
LD A,H
CP 0xA0
JR NC,ELT3
ELT4 LD A,0xA0
ELT3 EX AF,AF'
EVOPORT WIN_P5,RAM_RAMDISK ; нужна страница начала рамдиска, где будет таблица описателей
LD HL,CPU5
PUSH HL
LD DE,CPU5+1
LD BC,0x3FFF
LD (HL),L
LDIR ; очистили страницу
POP DE ; адрес начала страницы
LD HL,0 ; смещение в блоках и страницах
EX AF,AF'
ELT2 EX AF,AF'
LD BC,0x1000 ; счетчик номеров секторов и их номера
LD A,L
RRCA
RRCA
LD (DE),A ; смещение в блоках дорожки в странице
INC D
LD A,H
LD (DE),A ; смещение в страницах до дорожки
INC D
ELT1 INC C
LD A,C
LD (DE),A ; номер сектора
INC D
LD A,2
LD (DE),A ; размер сектора
INC D
DJNZ ELT1 ; вносим в таблицу все номера секторов с размерами
LD D,HIGH (CPU5) ; вернули указатель в начало
INC E ; для следующей дорожки
LD BC,0x40
ADD HL,BC ; переход к следующей дорожке
EX AF,AF'
DEC A
JR NZ,ELT2 ; повторяем для всех дорожек
; общий выход из загрузки с возвратом стандартной страницы в окне проецирования 1
ELOAD_IMAGE LD HL,CPU5+0x3FFF
LD (HL),"R"
DEC H
LD (HL),"D"
DEC H
; перенос имени файла загруженного в рамдиск
LD DE,NAME_RAMDISK
LD B,8+3
.L1 LD A,(DE)
LD (HL),A
INC DE
DEC H
DJNZ .L1
XOR A
RET
ELT5 POP AF
EVOPORT WIN_P5,RAM_RAMDISK
JR ELOAD_IMAGE
; инфа для создания 9 сектора нового диска
DSKINFO DB 0 ; +0xE1 номер первого свободного сектора
DB 1 ; +0xE2 номер первого свободного трека
DB 0x16 ; +0xE3 тип дискеты
DB 0 ; +0xE4 количество файлов на дискете
SECFREE DW 2544 ; +0xE5 количество свободных секторов
DB 0x10 ; +0xE7 идентификационный код TRDOS
DW 0 ; +0xE8 2 байта 0
DUPL 9,0x20 ; +0xEA 9 байт 0x20
DB 0 ; +0xF3 1 байт 0
DB 0 ; +0xF4 количество удаленных файлов
DB "RAMDISKO" ; +0xF5 имя дискеты
DSK_END
; загрузка SCL образа
LOAD_SCL
EVOPORT WIN_P5,RAM_DATARAMD
EVOPORT WIN_P3,RAM_MOUNTER
LD A,RAM_DATARAMD
LOAD_IMAGE4 PUSH AF
LD BC,WIN_P5
OUT (C),A
LD HL,CPU5+0x1000
LD A,0x18
CALL READ_FILE
PUSH AF ; сохранили флаг окончания загрузки на случай окончания образа
LD HL,CPU5
PUSH HL ; сохранили адрес начала каталога
LD (HL),L
LD D,H
LD E,L
INC DE
LD BC,0xFFF
LDIR ; зачистка области первой дорожки для формирования каталога диска
LD HL,CPU5+0x1008 ; адрес количества файлов в SCL образе
LD A,(HL) ; взяли количество файлов как счетчик
INC HL ; перешли на первый описатель файла
EXX
LD HL,0 ; номер абсолютного сектора
LD D,L ; приращение секторов не может быть более 255 секторов
LD B,A ; сохранение количества файлов
EXX
POP DE ; вернули адрес начала каталога диска
LOAD_IMAGE3 EX AF,AF'
LD BC,0x0D
LDIR ; перенесли 13 байт тела описателя
LD A,(HL) ; забрали размер файла в секторах
LDI ; перенесли еще байт
EXX
LD E,A
PUSH HL ; сохранили текщее значение номера сектора
ADD HL,DE ; увеличили текщее значение на размер файла в секторах
EXX
EX (SP),HL
LD A,L
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
INC H
AND 0x0F
LD L,A
EX (SP),HL
POP BC ; восстановили текщий номер сектора
EX DE,HL
LD (HL),C
INC HL
LD (HL),B ; уложили после текущего описателя
INC HL
EX DE,HL
EX AF,AF'
DEC A
JR NZ,LOAD_IMAGE3 ; если файлы не кончились продолжаем
PUSH HL ; сохранили адрес начала данных
LD HL,DSKINFO
LD DE,CPU5+0x8E1
LD BC,DSK_END-DSKINFO
LDIR
EXX
LD DE,2544 ; стандартный размер дискеты
EX DE,HL
AND A
SBC HL,DE
LD (CPU5+0x8E5),HL ; количество свободных секторов
EX DE,HL
LD A,L
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
INC H
AND 0x0F
LD L,A
LD (CPU5+0x8E1),HL ; первый свободный трек и сектор
LD A,B
LD (CPU5+0x8E4),A ; количество файлов на диске
EXX
POP DE ; восстановление адреса начала данных
LD HL,CPU6 ; конец окна проецирования
AND A
SBC HL,DE ; получили количество байт для сдвига
LD B,H
LD C,L
LD HL,CPU5+0x1000 ; начало данных на рамдиске
EX DE,HL
LDIR ; сдвинули, после переноса DE=адрес куда далее грузить
LD A,D
CP HIGH (CPU6)-2
JR NC,LOAD_IMAGE7
EX DE,HL
LD A,HIGH (CPU6)-1
SUB H
SRL A
LD IXL,A
CALL READ_FILE
LD DE,0x8000
EX DE,HL
LOAD_IMAGE7 AND A
SBC HL,DE ; получили сколько байт осталось до конца окна
LD (OST_HWOST),HL
LD (KUDA_HWOST),DE
LD DE,0
EX DE,HL
SBC HL,DE
LD A,1
AND H
LD H,A
LD (NEXT4PAGE),HL
POP AF ; восстановили флаг последней загрузки
JP C,ILD_IMG2 ; если файл уже кончился, то выход
JR LOAD_IMAGE5
LOAD_IMAGE6 LD DE,CPU5
LD BC,(NEXT4PAGE)
LDIR
EX AF,AF'
JP C,ILD_IMG2
EX DE,HL
LD A,0x1F
CALL READ_FILE
JP C,ILD_IMG2
LOAD_IMAGE5 LD HL,CPU3+BUF_TEMPSEC
PUSH HL
LD A,1
CALL READ_FILE
EX AF,AF' ; спрятали флаг загрузки сектора
POP HL ; восстановили адрес куда сектор в буфер загрузили
LD DE,(KUDA_HWOST) ; куда ложит остаток в окне
LD BC,(OST_HWOST) ; сколько переносить в конец страницы
LDIR
POP AF
INC A
PUSH AF
LD BC,WIN_P5
OUT (C),A
JR LOAD_IMAGE6
; загрузка FDI
LOAD_FDI LD A,RAM_RAMDISK ; страница начала рамдиска
PUSH AF ; сохранили на стеке
EVOPORT WIN_P5,RAM_RAMDISK
EVOPORT WIN_P3,RAM_MOUNTER
LD HL,FDI_TABLE_CYL
LD DE,FDI_TABLE_CYL+1
LD BC,0x3FFF
LD (HL),0
LDIR ; очистка страницы с описателями дорожек
LD IXH,0xFF
CALL LOAD1SECFDI ; принудительная загрузка первого сектора
LD A,(CPU3+6) ; взяли количество сторон
DEC A
LD A,(CPU3+4) ; взяли количество дорожек
JR Z,LOADFDI1
ADD A,A ; если сторон 2, то умножили количество дорожек на 2
LOADFDI1 LD C,A ; количество дорожек
LD HL,(CPU3+0x0A)
LD (START_DATA),HL
LD DE,CPU5 ; адрес буфера начала описателей дорожек
LD HL,CPU3+0x0F ; адрес начала выборки описателей дорожек в FDI заголовке
LOADFDI3 BIT 1,H
CALL NZ,LOAD1SECFDI ; если вышли за пределы сектора меняем указатель и грузим следующий сектор в буфер
LD A,(HL) ; биты 8-15 смещения дорожки от начала
AND 0x3F ; взяли для 8-13 биты-смещение в блоках в странице
LD (DE),A ; уложили смещение в блоках в странице
LD A,(HL) ; взяли биты 14-15
INC HL ; следующий байт FDI заголовка
INC D ; здесь положим смещение в страницах до нужной дорожки
BIT 1,H
CALL NZ,LOAD1SECFDI ; если вышли за пределы сектора меняем указатель и грузим следующий сектор в буфер
LD B,A ; сохранили нужные 14-15 биты
LD A,(HL) ; взяли 16-23 биты смещения дорожки от начала
RL B
RLA
RL B
RLA
LD (DE),A ; укладка битов смещения номера страницы
INC D
REPT 4
INC HL
ENDM
BIT 1,H
CALL NZ,LOAD1SECFDI ; если вышли за пределы сектора меняем указатель и грузим следующий сектор в буфер
LD B,(HL) ; взяли количество секторов на дорожке
LD A,B
AND A
JP Z,LOADFDI_ERR
INC HL
INC HL
LOADFDI4 INC HL
BIT 1,H
CALL NZ,LOAD1SECFDI ; если вышли за пределы сектора меняем указатель и грузим следующий сектор в буфер
LDI ; перенос номера сектора
DEC DE
INC C
INC D
BIT 1,H
CALL NZ,LOAD1SECFDI ; если вышли за пределы сектора меняем указатель и грузим следующий сектор в буфер
LD A,(HL) ; взяли размер сектора
EX DE,HL
LD (HL),1
AND A
JR Z,LOADFDI2
LD (HL),2
DEC A
JR Z,LOADFDI2
LD (HL),4
DEC A
JR Z,LOADFDI2
LD (HL),8
LOADFDI2 EX DE,HL
INC D
REPT 5
INC HL
ENDM
DJNZ LOADFDI4 ; возвращаемся для продолжения, пока сектора дорожки не кончатся
LD D,0x40
INC E
DEC C
JR NZ,LOADFDI3 ; возвращаемся для продолжения пока не кончатся дорожки
DEC HL
BIT 1,H
CALL NZ,LOAD1SECFDI ; если вышли за пределы сектора меняем указатель и грузим следующий сектор в буфер
PUSH HL
LD A,H
AND 1
LD B,A
LD C,L
LD A,IXH
ADD A,A
ADD A,B
LD B,A
LD HL,(START_DATA)
AND A
SBC HL,BC
EX DE,HL
POP HL
LD A,D
AND A
JR Z,LOADFDI7
LOADFDI8 INC H
BIT 1,H
CALL NZ,LOAD1SECFDI ; если вышли за пределы сектора меняем указатель и грузим следующий сектор в буфер
DEC D
JR NZ,LOADFDI8
LOADFDI7 ADD HL,DE
BIT 1,H
CALL NZ,LOAD1SECFDI ; если вышли за пределы сектора меняем указатель и грузим следующий сектор в буфер
PUSH HL ; сохранили адрес на начало начала секторов
LD DE,CPU3
AND A
SBC HL,DE
LD (OSTAT_SECT),HL ; сколько байт перенести из хвоста сектора в буфере в начало страницы
LD B,H
LD C,L
LD HL,0x200
SBC HL,BC
LD (NACH_SECT),HL ; сколько байт перенести из начала сектора в буфере в конец страницы
POP HL ; восстановили сдрес начала секторов, далее загрузка всех секторов в память
LOADFDI5 POP AF
INC A
PUSH BC
LD BC,WIN_P5
OUT (C),A
POP BC
PUSH AF
BIT 1,H
CALL NZ,LOAD1SECFDI
EX AF,AF'
LD DE,CPU5
LD BC,(NACH_SECT)
LDIR
EX AF,AF'
JP C,ELT5
EX DE,HL
LD A,0x1F
CALL READ_FILE
JP C,ELT5
PUSH HL
LD HL,CPU3
PUSH HL
LD A,1
CALL READ_FILE
POP HL
POP DE
LD BC,(OSTAT_SECT)
LDIR
JR LOADFDI5
LOADFDI_ERR POP AF
EVOPORT WIN_P5,RAM_RAMDISK
CALL FORMAT_RAMDISK
LD IX,LDFDIERROR
SCF
RET
FORMAT_RAMDISK
EVOPORT WIN_P5,RAM_DATARAMD
LD HL,CPU5
LD DE,CPU5+1
LD BC,0xFFF
LD (HL),L
LDIR
LD HL,DSKINFO
LD DE,CPU5+0x8E1
LD BC,DSK_END-DSKINFO
LDIR
JP ILD_IMG3
; загрузка следующего сектора заголовка FDI
LOAD1SECFDI PUSH HL
PUSH BC
PUSH DE
PUSH AF
LD HL,CPU3
LD A,1
CALL READ_FILE
INC IXH
POP AF
POP DE
POP BC
POP HL
RES 1,H
RET
; монтирование образа
OPEN_MOUNT LD A,(RREG_A)
OPEN_MOUNT_INT LD (MOUNT_SYM),A ; номер монтирумого диска
LD IYL,INTERNAL
EVOPORT WIN_P5,RAM_MOUNTER ; включили страницу с описателями примонтированных файлов
LD A,(MOUNT_SYM) ; номер монтирумого диска
ADD A,HIGH (BUF_PATHMOUNT+CPU5)
LD D,A
LD E,0 ; DE=адрес буфера путей примонтированных файлов
LD A,(SETDVOL) ; номер текущего устройства
ADD A,HIGH (TEK_BUFPATH+CPU5)+4
LD H,A
LD L,E ; HL=адрес пути на текущем устройстве
LD BC,0x100
PUSH DE
LDIR ; перенесли путь
CALL READ_DIR ; прочитали описатель монтируемого файла
POP DE
PUSH HL
OPENMOUNT05 LD A,(DE)
INC DE
AND A
JR NZ,OPENMOUNT05
DEC DE
LD BC,0x8FF
OPENMOUNT01 LDI
LD A,(HL)
CP "!"
JR C,OPENMOUNT03
DJNZ OPENMOUNT01
LD A,"."
LD (DE),A
INC DE
JR OPENMOUNT06
OPENMOUNT03 INC HL
DJNZ OPENMOUNT03
DEC HL
LD A,"."
LD (DE),A
INC DE
OPENMOUNT06 LD B,3
OPENMOUNT02 LDI
LD A,(HL)
CP "!"
JR C,OPENMOUNT04
DJNZ OPENMOUNT02
OPENMOUNT04 XOR A
LD (DE),A
POP HL
LD A,(MOUNT_SYM) ; номер монтирумого диска
PUSH HL
LD B,A
RRCA
RRCA
LD E,A
LD A,B
LD D,HIGH (MOUNT_DRIVES)
LD IXH,D
LD IXL,E ; IX=адрес описателя примонтированного файла
LD (IX+_MOUNT_Mount_Num),B ; номер монтируемого дисковода
LD BC,0x20
LDIR
INC A
LD H,%11110111
OPENMOUNT1 RLC H
DEC A
JR NZ,OPENMOUNT1
LD A,(CPU2+VIRT_BITS)
AND H
LD L,A
LD A,H
CPL
OR L
CALL WR_VIRT_BITS
EVOPORT WIN_P5,RAM_MOUNTER ; включили страницу с описателями примонтированных файлов
POP HL
; HL=адрес описателя монтируемого файла
IOPEN_MOUNT LD DE,FILE_EXT
CALL CP_EXT
LD (IX+_MOUNT_Ext_Type),C ; тип образа по расширению
CALL ICOM_DEV
DB _KOL_VOL
LD (IX+_MOUNT_Vol_Type),A ; тип раздела
LD (IX+_MOUNT_Vol_Num),D ; номер выбранного раздела
LD L,D
LD H,0
ADD HL,HL
ADD HL,HL
ADD HL,HL
LD DE,BUF_TABLVOL ; адрес таблицы найденных разделов
ADD HL,DE
LD A,(HL)
CP _SD_SDZ
LD HL,COMSDZ
JR Z,OPENMOUNT6
CP _SD_SDG
LD HL,COMSDG
JR Z,OPENMOUNT6
LD HL,COMHDDN
OPENMOUNT6 LD (IX+_MOUNT_Adr_Mnt_Drv),L
LD (IX+_MOUNT_Adr_Mnt_Drv+1),H ; адрес драйвера монтируемого образа
LD E,(IX+_MOUNT_FileSize+1)
LD D,(IX+_MOUNT_FileSize+2)
LD L,(IX+_MOUNT_FileSize+3) ; LDE=размер файла/256
LD A,(SecPerClus)
LD H,A
OPENMOUNT3 SRL L
RR D
RR E
RRCA
JR NC,OPENMOUNT3 ; LDE=количество кластеров
; A00 секторов (256 байт) -> 500 секторов (512 байт)
; кластер=1 сектор 1280/8 байт шаг=8
; кластер=2 сектора 640/4 байт шаг=4
; кластер=4 сектора 320/2 байт шаг=2
; кластер=8 секторов 160 байт шаг=1
; кластер=16 секторов 80 байт шаг=1
; кластер=32 сектора 40 байт шаг=1
; кластер=64 сектора 20 байт шаг=1
; кластер=128 секторов 10 байт шаг=1
LD IY,1<<8+INTERNAL
LD A,H
CP 8
JR NC,OPENMOUNT5
LD IYH,8
RRCA
JR C,OPENMOUNT5
LD IYH,4
RRCA
JR C,OPENMOUNT5
LD IYH,2
OPENMOUNT5 LD A,IYH
LD (IX+_MOUNT_Cls_Step),A ; шаг кластеров
LD A,(IX+_MOUNT_Mount_Num) ; номер монтируемого дисковода
ADD A,A
ADD A,A
ADD A,HIGH (MOUNT_CLS+CPU5)
LD H,A
LD L,0
LD C,(IX+_MOUNT_FstClusHI)
LD B,(IX+_MOUNT_FstClusHI+1)
LD E,(IX+_MOUNT_FstClusLO)
LD D,(IX+_MOUNT_FstClusLO+1)
JR OPENMOUNT9
OPENMOUNT7 DEC IYH
JR NZ,OPENMOUNT8
OPENMOUNT9 LD A,(IX+_MOUNT_Cls_Step) ; шаг кластеров
LD IYH,A
LD (HL),E
INC H
LD (HL),D
INC H
LD (HL),C
INC H
LD (HL),B
DEC H
DEC H
DEC H
INC L
OPENMOUNT8 PUSH HL
CALL RDFATZP
CALL LST_CLS
POP HL
JR NC,OPENMOUNT7
RET
FILE_EXT DZ "TRD"
; чтение/запись примонтированного образа
; HL=адрес чтения/записи
; D=номер трека, E=номер сектора+1
; A=номер дисковода (BIT 7=0-чтение, =1-запись)
RDWR_MOUNT LD A,(RREG_A)
AND 3
RRCA
RRCA
LD IXL,A
LD IXH,HIGH (MOUNT_DRIVES) ; IX=описатель дисководов A-D
LD IYL,INTERNAL
EVOPORT WIN_P5,RAM_FATVARS
LD A,(SETDVOL)
ADD A,HIGH (CPU5+BUF_ALLVOL)+4
LD D,A
LD E,0
LD HL,BUF_TEKVOL
LD BC,0x100
LDIR
LD A,(IX+_MOUNT_Vol_Num)
ADD A,HIGH (CPU5+BUF_ALLVOL)+4
LD H,A
LD L,0
LD DE,BUF_TEKVOL
LD BC,0x100
LDIR
EVOPORT WIN_P5,RAM_MOUNTER
LD HL,(GO_DEV)
LD (IX+_MOUNT_Adr_Sel_Drv),L
LD (IX+_MOUNT_Adr_Sel_Drv+1),H
LD L,(IX+_MOUNT_Adr_Mnt_Drv)
LD H,(IX+_MOUNT_Adr_Mnt_Drv+1)
LD (GO_DEV),HL
LD HL,(RREG_E)
DEC L
LD E,L
LD L,H
LD H,0
LD D,H
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,DE ; HL=номер сектора в файле (256 байт)
PUSH HL
LD A,(SecPerClus)
RDWRMOUNT1 SRL H
RR L
RRCA
JR NC,RDWRMOUNT1 ; HL=номер кластера
; 0xA00 секторов (256 байт) -> 0x500 секторов (512 байт)
; кластер=1 сектор 1280/8 байт шаг=8
; кластер=2 сектора 640/4 байт шаг=4
; кластер=4 сектора 320/2 байт шаг=2
; кластер=8 секторов 160 байт шаг=1
; кластер=16 секторов 80 байт шаг=1
; кластер=32 сектора 40 байт шаг=1
; кластер=64 сектора 20 байт шаг=1
; кластер=128 секторов 10 байт шаг=1
LD A,L
EX AF,AF'
LD A,(IX+_MOUNT_Cls_Step)
DEC A
JR Z,RDWRMOUNT6
INC A
ADD HL,HL
RDWRMOUNT2 SRL H
RR L
RRCA
JR NC,RDWRMOUNT2
RDWRMOUNT6 LD A,(RREG_A) ; номер дисковода
ADD A,A
ADD A,A
ADD A,HIGH (MOUNT_CLS+CPU5)
LD H,A
LD E,(HL)
INC H
LD D,(HL)
INC H
LD C,(HL)
INC H
LD B,(HL) ; BCDE=номер кластера
; TODO: проверка номера кластера на 0 и 0xFFFFFFFF и возврат ошибки чтения/записи по надобности
LD A,(IX+_MOUNT_Cls_Step) ; шаг кластеров
DEC A
JR Z,RDWRMOUNT3 ; шаг кластеров =1
LD B,A ; маска смещения в таблице кластеров
EX AF,AF'
AND B ; A=смещение в таблице кластеров
LD B,(HL) ; восстановление номера кластера
JR Z,RDWRMOUNT3
RDWRMOUNT4 PUSH AF
CALL RDFATZP
POP AF
DEC A
JR NZ,RDWRMOUNT4
RDWRMOUNT3 CALL REALSEC ; конверсия номера кластера в номер сектора
POP HL
PUSH HL
SRL L
LD A,(SecPerClus)
DEC A
JR Z,RDWRMOUNT5
AND L
LD L,A
LD H,0
ADD HL,DE
EX DE,HL
LD HL,0
ADC HL,BC
LD B,H
LD C,L
RDWRMOUNT5 CALL LOADLST ; чтение сектора в буфер
POP BC
LD A,C
AND 1
ADD A,H
LD H,A
LD BC,CPU3
ADD HL,BC ; адрес буфера в окне 1
CALL LDIR_SEC
LD A,(RREG_A) ; чтение или запись
AND 0x80
CALL NZ,LSTSAVE
LD HL,RREG_H
INC (HL)
LD L,(IX+_MOUNT_Adr_Sel_Drv)
LD H,(IX+_MOUNT_Adr_Sel_Drv+1)
LD (GO_DEV),HL
EVOPORT WIN_P5,RAM_FATVARS
LD A,(SETDVOL)
ADD A,HIGH (CPU5+BUF_ALLVOL)+4
LD H,A
LD DE,BUF_TEKVOL
LD BC,0x100
LD L,C
LDIR
LD (NumSec2Buf + 2),HL
RET
LDIR_SEC EX DE,HL ; адрес буфера сохранили в DE
LD HL,(RREG_L) ; HL=адрес в основной памяти
CALL RESETUP_WINS ; переконфигурация окон проецирования
ADD HL,BC ; изменили адрес чтения/записи
EX DE,HL ; HL=адрес буфера, DE=адрес в основной памяти
LD A,(RREG_A-CPU5) ; чтение или запись
AND 0x80
JR Z,LDIRSEC6
EX DE,HL ; для записи меняем напраление переноса
LDIRSEC6 LD BC,0x100
LDIR
LD HL,CPU5
ADD HL,SP
LD SP,HL ; вернули адрес стека в окно 2
ATMPORT WIN_A3,0x7F ; убрали возможную зависимость в окне 3 от порта 7FFD
LD B,HIGH (WIN_A6)
OUT (C),A ; убрали возможную зависимость в окне 2 от порта 7FFD
XOR A
LD B,HIGH (WIN_P6)
OUT (C),A ; вернули страницу переменных в окно 2
RET
TXT_MOUNTER DZ "IMAGE.MNT" ; имя для поиска текстового файла с указанием к монтированию TRD
ETXT_MOUNTER
FIND_MOUNTED LD A,(KOLDVOL)
AND A
JR NZ,FINDMNTD09
LD IX,MOUNT_DRIVES
LD DE,0x40
LD B,4
FINDMNTD10 LD (IX+_MOUNT_Name),D
ADD IX,DE
DJNZ FINDMNTD10
RET
FINDMNTD09 LD A,(SETDVOL)
LD (SAVE_TEK_VOL),A ; сохранили текущее устройство
CALL SAVE_FNDVOL ; сохранили переменные текущего устройства
LD H,CMOS_BYTE_01
ROMCALL READCMOS,ROM_RST82
LD A,L
AND M_AUTOMOUNT ; определение нужно ли искать файл IMAGE.MNT
JP Z,FINDMNTD01
; ищем файл IMAGE.MNT для автомонтирования
LD IYL,INTERNAL
LD A,(KOLDVOL)
DEC A ; искать будем на последнем найденном разделе
CALL SET_VOL_MNT ; переключилсь на выбранное устройство
LD HL,(RootDIRCluster)
LD (CurrentDIRCluster),HL
LD HL,(RootDIRCluster + 2)
LD (CurrentDIRCluster + 2),HL ; выбрали корневой каталог выбранного устройства
CALL INIRTSC ; инициализировали его переменные на ROOTDIR
LD HL,TXT_MOUNTER
LD DE,BUF_256
LD BC,ETXT_MOUNTER-TXT_MOUNTER
LDIR ; перенесли имя файла для поиска
CALL ICOM_FAT
DB _FIND_NAME
JP C,FINDMNTD01 ; файл IMAGE.MNT не найден
; файл найден
CALL OPEN_FILE ; открываем файл
LD HL,FILE_SRC+0x1F
LD A,(HL)
DEC HL
OR (HL)
JP NZ,FINDMNTD01 ; файл не должен быть более 512 байт
DEC HL
LD A,(HL)
CP 2
JP NC,FINDMNTD01 ; файл не должен быть более 512 байт
LD A,1 ; читать будем 1 сектор из найденного файла
LD B,(HL)
DEC HL
LD C,(HL) ; взяли длину файла в байтах
PUSH BC ; сохранили для дальнейшего использования
LD IYL,INTERNAL
LD HL,OFFSET_BUFSYM+CPU6
PUSH HL
CALL READ_FILE ; прочитали 1 сектор из файла
EVOPORT WIN_P5,RAM_MOUNTER
POP HL
POP BC
ADD HL,BC
LD (HL),0 ; установили признак конца файла в 0
SBC HL,BC
FINDMNTD04 LD A,(HL)
AND A
JR Z,FINDMNTD01 ; выходим если файл кончился
INC HL
CP "!"
JR C,FINDMNTD04 ; если строка кончилась переносим эту строку в буфер поиска
DEC HL
PUSH HL
INC HL
CP "a" ; первый символ строки буква устройства
JR C,FINDMNTD06 ; должна быть только символ от "A"
CP 'z'+1
JR NC,FINDMNTD06 ; до "Z"
AND 0xDF ; перевели букву устройства в верхний регистр, если нужно
FINDMNTD06 SUB "E" ; FAT устройства начинаются с буквы "E"
JR C,FINDMNTD02
EXX
LD C,A ; номер устройства где искать файл
LD A,(KOLDVOL) ; количество найденных разделов
CP C
EXX
JR C,FINDMNTD02
LD A,(HL)
INC HL
CP ":" ; разделитель обязателен
JR NZ,FINDMNTD02
LD A,(HL)
INC HL
CP "/" ; разделитель обязателен
JR NZ,FINDMNTD02
FINDMNTD07 LD A,(HL)
INC HL
CP "!"
JR NC,FINDMNTD07 ; ищем конец строки
LD A,(HL) ; буква дисковода на которую монтировать
INC HL
CP "a"
JR C,FINDMNTD08
CP 'z'+1
JR NC,FINDMNTD08
AND 0xDF ; переводи в верхний регистр, если нужно
FINDMNTD08 SUB "A"
JR C,FINDMNTD02
CP 4
JR NC,FINDMNTD02
EXX
LD B,A ; номер дисковода на который монтировать
EXX
LD A,(HL)
INC HL
CP ":"
JR NZ,FINDMNTD02
LD D,H
LD E,L
EX (SP),HL
EX DE,HL
SCF
SBC HL,DE
LD B,H
LD C,L
EX DE,HL
EXX
LD A,B
EXX
ADD A,HIGH (BUF_PATHMOUNT+CPU5)
LD D,A
LD E,0 ; DE=адрес буфера текстовой строки монтируемого дисковода
DEC BC
DEC BC
LDIR ; перенесли строку
XOR A
LD (DE),A ; принудительное завершение строки монтирования
POP HL
JR FINDMNTD04
FINDMNTD02 LD A,(HL)
INC HL
AND A
JR Z,FINDMNTD01
CP " "
JR NC,FINDMNTD02
POP DE
JR FINDMNTD04
FINDMNTD01
EVOPORT WIN_P5,RAM_MOUNTER
LD BC,0x400
LD IX,MOUNT_DRIVES ; буфер описателей монтируемых файлов
FINDMNTD2 PUSH BC
CALL FINDMNTD0 ; ищем указанный файл для монтирования
JR NC,FINDMNT5
LD (IX+_MOUNT_Name),0 ; если файл не найден, то принудительно демонтируем образ
FINDMNT5 LD BC,0x40
ADD IX,BC ; следующий описатель монтируемого файла
POP BC
DJNZ FINDMNTD2
LD A,IYH
AND 0xF0 ; старшие 4 бита примонтированные файлы
LD D,A
LD A,(CPU2+VIRT_BITS)
AND 0x0F ; младшие 4 бита реальный и виртуальные приводы
OR D ; совместили для записи обратно
CALL WR_VIRT_BITS
LD A,(SAVE_TEK_VOL)
PUSH IY
LD IYL,INTERNAL
CALL SET_VOL_MNT ; восстановили текущее выбранное устройство
CALL INIRTSC ; проинитили его переменные
POP IY
JP LOAD_FNDVOL ; вернули на место описатель устройства
; поиск монтируемого файла с установкой соотвествующего бита
FINDMNTD0 CALL FINDMNTD1
EX AF,AF'
LD A,IXL
AND 0xC0
RLCA
RLCA ; номер текущего монтируемого дисковода
INC A
LD B,A
LD A,%11110111
RLCA
DJNZ $-1 ; установка маски монтируемого дисковода
LD C,A ; маска
CPL
LD B,A ; бит
LD A,IYH
AND C ; сбросили бит смонтированного дисковода
LD IYH,A
EX AF,AF'
RET C ; выход если файл не найден
LD A,IYH
OR B ; установили бит если файл найден
LD IYH,A
RET
; сохранение текущего пути
STORE_PATH PUSH AF
EVOPORT WIN_P5,RAM_MOUNTER
LD A,(SETDVOL) ; номер текущего устройства
ADD A,HIGH (TEK_BUFPATH+CPU5)+4 ; +старший байт адреса пути
LD H,A
LD DE,BUF_256
LD BC,0x100
LD L,C
LDIR
STOREPATH1 POP AF
RET
; восстановление текущего пути
RESTORE_PATH PUSH AF
EVOPORT WIN_P5,RAM_MOUNTER
LD A,(SETDVOL) ; номер текущего устройства
ADD A,HIGH (TEK_BUFPATH+CPU5)+4 ; +старший байт адреса пути
LD D,A
LD HL,BUF_256
LD BC,0x100
LD E,C
LDIR
RESTOREPATH1 POP AF
RET
; поиск монтируемого файла
FINDMNTD1 LD A,IXL
RLCA
RLCA
AND 3
ADD A,HIGH (BUF_PATHMOUNT+CPU5)
LD D,A
LD E,0 ; DE=адрес буфера строки описателя монтирумого файла
LD A,(DE) ; взяли букву устройства где файл искать
INC DE
INC DE
INC DE
AND A
SCF
RET Z
SUB "E" ; конверсия буквы в номер
PUSH DE
CALL SET_VOL_MNT ; переключились на это устройство
CALL STORE_PATH ; сохранили текущий путь
LD HL,(RootDIRCluster)
LD (CurrentDIRCluster),HL
LD HL,(RootDIRCluster + 2)
LD (CurrentDIRCluster + 2),HL ; перешли в корень устройства
CALL INIRTSC ; инициализация его переменных
EVOPORT WIN_P5,RAM_MOUNTER
POP HL
CALL FNDBUF ; распаковка текстовой строки
FINDMNTD13 PUSH HL
CALL POSTF02 ; сброс текущего номера файла в 0
CALL FINDMNTD3 ; поиск в текущей директории
POP DE
JP C,RESTORE_PATH ; восстановили текущий путь
LD BC,0x0B
ADD HL,BC
LD A,(HL)
SBC HL,BC
AND 0x10
JR Z,FINDMNTD23 ; если это файл найден, то он найден
PUSH DE
CALL ENTER_DIR ; иначе входим в директорию
CALL POSTF02 ; сброс текущего ноиера файла в 0
POP HL
LD A,(HL)
AND A
SCF
JP Z,RESTORE_PATH ; восстановили текущий путь
CALL FNDBUF ; распаковываем следующую часть строки
JR FINDMNTD13 ; продолжаем поиск
FINDMNTD23 LD A,IXL
RLCA
RLCA
LD E,IXL
LD D,IXH ; DE=куда описатель переносить
LD (IX+_MOUNT_Mount_Num),A ; номер монтируемого дисковода
PUSH HL
LD BC,0x20
LDIR
POP HL
PUSH IY
CALL IOPEN_MOUNT
POP IY
XOR A
JP RESTORE_PATH ; восстановили текущий путь
FINDMNTD4 CALL NXTLEGZ
FINDMNTD3 PUSH HL
LD DE,FB_EXT
CALL ICMP_NAME
POP HL
RET Z
LD A,(HL)
AND A
JR NZ,FINDMNTD4
SCF
RET
; получение описателя файла загруженного в рамдиск
REST_NAMELOAD LD HL,NAME_RAMDISK-CPU6
LD DE,(RREG_L)
LD BC,0x20
JP LDIR_BYTES
;STOR_NAMELOAD LD HL,(RREG_L)
; LD DE,NAME_RAMDISK-CPU6
; LD BC,0x20
; JP LDIR_BYTES
GET_MOUNTED
EVOPORT WIN_P5,RAM_MOUNTER
LD HL,MOUNT_DRIVES-CPU6
LD DE,(RREG_L)
LD BC,0x100
JP LDIR_BYTES
CMP_DRIVE
EVOPORT WIN_P5,RAM_MOUNTER
LD A,(RREG_A)
AND 3
RLCA
RLCA
LD L,A
LD H,HIGH (MOUNT_DRIVES)
LD A,(HL)
AND A ; если не примонтирован,
SCF ; то диска нет
JR Z,CMP_DRIVE1
XOR A
CMP_DRIVE1 PUSH AF
POP HL
LD (RREG_F),HL
RET
; демонтирование образа
CLOSEMOUNT
EVOPORT WIN_P5,RAM_MOUNTER
LD A,(RREG_A)
LD B,A
RRCA
RRCA
LD L,A
LD H,HIGH (MOUNT_DRIVES)
LD (HL),0
LD A,B
ADD A,HIGH (BUF_PATHMOUNT+CPU5)
LD H,A
LD L,0
LD (HL),L
INC B
LD A,%11110111
RLCA
DJNZ $-1
LD B,A
LD A,(CPU2+VIRT_BITS)
AND B
JP WR_VIRT_BITS
; распаковщик пути к файлу
; HL = адрес текстовой строки
FNDBUF LD BC,0x0802
LD DE,FB_EXT
FNDBUF4 LD A,(HL)
INC HL
CP "."
JR Z,FNDBUF2
CP "/"
JR Z,FNDBUF5
LD (DE),A
INC DE
DJNZ FNDBUF4
LD A,(HL)
AND A
RET Z
INC HL
JR FNDBUF3
FNDBUF5 LD A,C
AND A
RET Z
FNDBUF2 LD A,B
AND A
JR Z,FNDBUF3
LD A," "
LD (DE),A
INC DE
DJNZ $-2
FNDBUF3 LD B,3
DEC C
DEC HL
LD A,(HL)
CP "/"
JR Z,FNDBUF4
INC HL
JR FNDBUF4
; получение текущего состояния битов смонтированных дисководов и рамдиска
GET_VIRT_BITS LD HL,MOUNT_DRIVES
LD E,0 ; здесь будут биты смонтированных дисководов
.L2 LD A,(HL)
AND A
JR Z,.L1
SET 4,E
.L1 RR E
LD A,0x40
ADD A,L
LD L,A
JR NZ,.L2
; VIRT_BITS - в 3-0 битах биты примонтированных образов для дисков D-A
CALL GET_VIRTREAL
AND 3
INC A
LD B,A
LD A,%00001000
.L3 RLCA
DJNZ .L3
OR E
; A xxxx0000 - биты рамдиска
; E 0000xxxx - биты примонтированных образов
; копирование установок виртуал/реал для EVO-DOS
WR_VIRT_BITS PUSH BC
PUSH HL
LD H,A
LD (CPU2 + VIRT_BITS),A ; внутренняя переменная
LD (RREG_A),A ; возвращаемое значение в регистре A
AND %00001111 ; примонтированные диски
LD L,A
LD A,H
AND %11110000
RRCA
RRCA
RRCA
RRCA
OR L
LD (B_PORT_VIRT),A
EVOPORT WIN_P2,RAM_EVODOS
LD A,H
LD (CPU2 + COPY_VIRT_BITS),A ; копия переменной флагов для эмуля
LD A,VIRT_REAL_DRIVE
LD BC,CMOSD_SET_ADR
OUT (C),A
LD BC,CMOSD_RD_WR
IN L,(C)
LD A,L
AND %00000011
LD (CPU2 + VIRT_DRIVE),A ; номер виртуального диска из CMOS
LD A,L
AND %00001100
RRCA
RRCA
LD (CPU2 + REAL_DRIVE),A ; номер реального диска из CMOS
LD BC,WIN_P2
XOR A
OUT (C),A
POP HL
POP BC
RET
IF 0
; монтирование рамдиска
; MOUNT_RAMDISK CALL GET_VIRTREAL
; AND 3
; JR SET_RAMDISK.L1
; отключение/установка рамдиска
; A = >3 - отключение рамдиска
; 0..3 - номер рамдиска
; VIRT_BITS - 7-4 бит один установленный бит -> рамдиск
SET_RAMDISK LD A,(RREG_A)
CP 4
JR C,.L1
LD A,(CPU2+VIRT_BITS)
AND 0x0F
JR WR_VIRT_BITS
.L1 INC A
LD B,A
LD A,%00001000
.L2 RLCA
DJNZ .L2
LD L,A
LD A,(CPU2+VIRT_BITS)
AND 0x0F
OR L
JP WR_VIRT_BITS
ENDIF
; установка номера в реальный и виртуальный дисковод
; A = 0..3 - номер дисковода для установки
SET_VIRTREAL LD A,(RREG_A)
LD E,A
CALL GET_VIRTREAL
AND %11110000
LD D,A
LD A,E
AND 3
LD E,A
ADD A,A
ADD A,A
OR E
.L1 LD L,A
ROMCALL IWRITECMOS,ROM_RST82
JP GET_VIRT_BITS
; установка номера реального дисковода
; A = 0..3 - номер дисковода для установки
SET_REAL LD A,(RREG_A)
LD E,A
CALL GET_VIRTREAL
AND %11110011
LD D,A
LD A,E
AND 3
ADD A,A
ADD A,A
OR D
JR SET_VIRTREAL.L1
; установка номера виртуального дисковода
; A = 0..3 - номер дисковода для установки
SET_VIRT LD A,(RREG_A)
LD E,A
CALL GET_VIRTREAL
AND %11111100
LD D,A
LD A,E
AND 3
OR D
JR SET_VIRTREAL.L1
GET_VIRTREAL LD H,VIRT_REAL_DRIVE
ROMCALL READCMOS,ROM_RST82
AND 0x0F
RET