From 2e997af3bed0708772c1f32919f492825f5c2c25 Mon Sep 17 00:00:00 2001 From: Tolik Trek Date: Sun, 17 May 2026 01:05:06 +1000 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=B8?= =?UTF-8?q?=D0=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 2 +- RAMDRIVE.ASM | 264 ---------------------- RAMDRV.ASM | 574 ++++++++++++++++++++++++++++++++++++++++++++++++ Shared_Includes | 2 +- 4 files changed, 576 insertions(+), 266 deletions(-) delete mode 100644 RAMDRIVE.ASM create mode 100644 RAMDRV.ASM diff --git a/.gitmodules b/.gitmodules index 7355856..bc0897b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "Shared_Includes"] branch = main path = Shared_Includes - url = https://github.com/Tolik-Trek/Shared_Includes.git + url = ../Shared_Includes.git diff --git a/RAMDRIVE.ASM b/RAMDRIVE.ASM deleted file mode 100644 index eaddfea..0000000 --- a/RAMDRIVE.ASM +++ /dev/null @@ -1,264 +0,0 @@ - - ORG #8100-512 - INCLUDE "DOS_EQU.ASM" -PAGE3 EQU #E2 -CR EQU 13 -LF EQU 10 -EN EQU 00 - - DB "EXE" ;EXE ID - DB #00 ;EXE VERSION - DW #0200 ;CODE OFFSET LOW - DW #0000 ;CODE OFFSET HIGH - DW #0000 ;END-BEG ;PRIMARY LOADER - DW #0000 ; - DW #0000 ;RESERVED - DW #0000 ; - DW #8100 ;LOAD ADDRESS - DW #8100 ;START ADDRESS - DW #BFFF ;STACK ADDRESS - DS 490 -BEG LD HL,MS0 - LD C,PCHARS - RST #10 - DI - - LD BC,#00CE ; Получение идентификатора блока, назначенного на RAM-Disk -NEXTRD LD A,B ; номер RAM-Disk-а 0..15 - PUSH BC - RST #08 - - POP BC - OR A - JR Z,FNDRD - INC B - LD A,B - CP #10 - JR NZ,NEXTRD - JP NORAMD -FNDRD PUSH BC - LD C,#C2 ; выделение блока ОЗУ - LD B,45 ; запрашиваемое число страниц ОЗУ (45 = 720 kb) - RST #08 - POP BC - JP C,NOMEM - PUSH AF - - LD C,A - LD A,B ; номер RAM-Disk-а 0..15 - соответствует RAM-Disk-ам от e: до t: - LD B,C ; идентификатор блока - LD C,#C9 ; назначить блок памяти RAM-Disk-у - RST #08 - - POP AF - LD C,PAGE3 - IN B,(C) - OUT (C),A - PUSH BC - LD HL,#C000 - LD DE,#C001 - LD BC,#3FFF - LD (HL),L - LDIR - - LD HL,BPB ;boot sector [512Bytes] - LD DE,#C000 - LD BC,BPB.Size - LDIR - - LD HL,#AA55 - LD (#C200-2),HL - LD HL,#C200 - LD (HL),#F9 - INC L - LD (HL),#FF - INC L - LD (HL),#FF - INC L - LD (HL),#00 - - LD HL,#C200+(512*5) - LD (HL),#F9 - INC L - LD (HL),#FF - INC L - LD (HL),#FF - INC L - LD (HL),#00 - - POP BC - OUT (C),B - LD HL,MS1 - LD C,PCHARS - RST #10 - LD B,#00 -EXITT LD C,#41 - RST #10 - DI - HALT - -NORAMD LD HL,MS2 - LD C,PCHARS - RST #10 - LD B,1 - JP EXITT - -NOMEM LD HL,MS3 - LD C,PCHARS - RST #10 - LD B,1 - JP EXITT - - -; -; RAMDRIVE 720 -; RAMDRIVE E:720 -; 0 1 2 3 4 5 6 7 8 9 A B C D E F -; - -;GETPARM LD A,#FF -; LD (RDRIVE),A -; LD (RSIZE),A -; LD D,XH -; LD E,XL -; EX DE,HL -; LD E,(HL) -; INC HL -; LD D,0 -; EX DE,HL -; ADD HL,DE -; LD (HL),0 -;NEXTPRM EX DE,HL -; LD DE,BUFFER -; LD C,GSWITCH -; RST #10 -; EX DE,HL ;SAVE HL IN DE -; LD HL,BUFFER -; LD A,(HL) -; INC HL -; OR A -; RET Z -; CP "/" -; JR NZ,NOSLASH -; LD A,(HL) -; INC HL -; CALL UPPER -; CALL ATOHEX -; JP C,ILLEGAL -; LD (RDRIVE),A -; LD A,(HL) -; OR A -; JR Z,NEXTPRM -; JP ILLEGAL -; -;NOSLASH CP ":" -; JP NZ,NOSIZER -; LD IX,0 -;NDIG LD C,XL -; LD B,XH -; ADD IX,IX ;X2 -; ADD IX,IX ;X4 -; ADD IX,BC ;X5 -; ADD IX,IX ;X10 -; JP C,ILLEGAL -; LD A,(HL) -; OR A -; JR Z,ENDSZ -; CALL UPPER -; CP "K" -; JR Z,ENDSZ -; CALL ATODEC -; LD C,A -; LD B,0 -; ADD IX,BC -; JR NDIG -;ENDSZ LD A,XL -; LD C,A -; LD B,XH -; SRL B -; RR C -; SRL B -; RR C -; SRL B -; RR C -; SRL B -; RR C -; AND #0F -; JR Z,L101 -; INC BC -;L101 LD A,B -; OR A -; JP NZ,ILLEGAL -; LD A,C -; LD (RSIZE),A -; JP NEXTPRM - -;NOSIZER JP ILLEGAL - -;ATODEC CP "0" -; RET C -; CP ":" -; CCF -; RET C -; SUB "0" -; RET - -;ATOHEX CP "0" -; RET C -; CP ":" -; JR NC,TRYHEX -; SUB "0" -; AND A -; RET -;TRYHEX CALL UPPER -; CP "A" -; RET C -; CP "G" -; CCF -; RET C -; SUB "A" -; RET - -;UPPER CP "a" -; RET C -; CP "z"+1 -; RET NC -; SUB #20 -; RET - -MS0 DB "RAMDRIVE DRIVER (C) 1999 PETERS Plus ltd.",CR,LF,CR,LF,EN - -MS1 DB "RAM DISK created",CR,LF,EN - -MS2 DB "No free RAM-DISK",CR,LF,EN - -MS3 DB "No free memory, for create RAM-DISK",CR,LF,EN - -MS4 DB "Illegal parametr",CR,LF,EN - -MS5 DB "Usage : RAMDRIVE [/drive 0...F] [:size]",CR,LF,EN - -; Area for boot sector [512Bytes] -BPB DB #EB,#3C,#90 ; +00 JMP - DB "DOS_X.XX" ; +03 DOS NAME -; Block Parameters BIOS - DW #0200 ; +0B BYTE PER SECTOR - DB 1 ; +0D SECTORS PER CLUSTER - DW 1 ; +0E RESERVE SECTORS - DB 2 ; 1 ; +10 AMOUNT FATS - DW 112 ; +11 FILES IN DIRECTORY - DW 1440 ; +13 ALL SECTORS ON DISK - DB #FA ; +15 ID FORMAT - DW 5 ; +16 SIZE FAT IN SECTORS - DW 9 ; +18 SECTOR PER TRACK - DW 2 ; +1A AMOUNT SIDES - DW 0,0 ; +1C HIDDEN SECTORS - DW 0,0 ; +20 ALL SECTORS BIG - DW #0080 ; +24 PHISICAL DRIVE NUMBER - DB #29 ; +26 EXTENDED RECORD SIGNATURE - DW #104B,#D765 ; +27 SERIAL VOLUME NUMBER - DB "NO NAME " ; +2B DISK LABEL - DB "FAT12" ; +36 FAT ID -.Size $-BPB -; DEFS 453,0 -; end boot sector diff --git a/RAMDRV.ASM b/RAMDRV.ASM new file mode 100644 index 0000000..ccc5450 --- /dev/null +++ b/RAMDRV.ASM @@ -0,0 +1,574 @@ +; Перед таблицей диска вывести строку о размере своб. системной памяти +; + + DEFINE App_EXE_Version 1 + INCLUDE 'shared_includes/constants/sp2000.inc' + INCLUDE 'shared_includes/constants/BIOS_equ.inc' + INCLUDE 'shared_includes/constants/DSS_EQU.inc' + INCLUDE 'shared_includes/macroses/macros.z80' + +; Версия программы +major_version equ 1 +minor_version equ 12 + + +org_addr EQU SLOT1.MEM_ADDR + #100 + CLP_Buffer +code_addr EQU ramdrv +program_start EQU ramdrv +stack_point EQU #C000 +Loader_length EQU 0 + + + + + + ; org 4100h + + ; db "EX" ; exe ID + ; db "E" ; exe тип + ; db 0 ; exe версия + ; dw 512 ; мл. смещ. кода + ; dw 0 ; ст. смещ. кода + ; dw 0 ; end-beg, первичный загрузчик + ; dw 0,0 ; резерв + ; dw 0 ; + ; dw start ; адрес загрузки кода + ; dw start ; адрес передачи управления + ; dw 0C000h ; адрес стека + ; ds 490 ; резерв + + EXE_ORG org_addr + +ramdrv: ; парсинг ком-строки + push ix + ld hl,title ; титл программы + ld c,5Ch ; вывести строку + rst 10h + ; очистить буфер клавы + ld bc,3135h + rst 10h + pop de + ld hl,help ; вывод помощи + ld a,(de) + or a + jr z,.error + inc de ; перейти на ком-строку + ld a,(de) + cp " " + jr z,$-4 + ld a,(de) ; цифра + or a + jr z,.bad_option + call dec_to_word ; char -> int + ld (.kbytes+1),hl ; размер диска в kB + jr nc,.ok_option +.bad_option: ld hl,err_value ; "Invalid value" + jr .error + ; +.ok_option: ld hl,(.kbytes+1) ; размер диска в kB + ld de,64 ; мин. размер диска в kB + sbc hl,de + jr nc,$+5 + ld (.kbytes+1),de + ; создать серийный номер диска + ld c,21h ; получить время + rst 10h + ; hl=часы/минуты, b=секунды + ld a,r ; динамич. счетчик долей секунды + cp 99+1 + jr c,.rand + ld a,99 +.rand: ld c,a ; доли секунды + ld de,07C7h + add hl,de + ld (msdos+39),hl ; sn_low + ld hl,0707h + add hl,bc + ld (msdos+41),hl ; sn_high + ; получить идентиф. блока, назначенного на RAM-диск + di + ld bc,00CEh ; с=номер функции +.loop: ld a,b ; номер RAM-диска 0..15, (от E: до T:) + push bc + rst 08h + pop bc + or a + jr z,.free ; блок не назначен + inc b + ld a,b + cp 15+1 ; номер RAM-диска + jr nz,.loop + ; выход за пределы 0..15 диапазона + ld hl,no_free_ramdisk ; "No free RAM-DISK" +.error: ld c,5Ch ; вывод строки + rst 10h + ld b,1 ; код ошибки + jp .abort ; выход в ДОС + + +.free: ld a,b + ld (.ram+1),a ; номер ram-диска +.kbytes: ld hl,0 ; размер в kB + call get_sect_fat ; расчитать число секторов на FAT + ld (msdos+22),hl ; ячейка "секторов на FAT" + ld hl,not_enough ; "No enough memory for create RAM-DISK" + jr c,.error ; слишком большой объем (> 3984 kB) + ; +.hsize: ld hl,0 ; ст.разряд +.lsize: ld bc,0 + call get_mem_pages ; выделить память + ld hl,not_enough ; "No enough memory for create RAM-DISK" + jr c,.error ; нет памяти + ld (.id+1),a ; идентиф. блока + ; создать список страниц + ld hl,list_pages ; буфер списка + ld c,0C5h + rst 08h + ; назначить блок памяти RAM-диску +.ram: ld a,0 ; номер RAM-диска 0..15 (от E: до T:) +.id: ld b,-1 ; идентиф. блока + ld c,0C9h + rst 08h + ; + in a,(0C2h) + ld (.port2+1),a ; сохр. порт Page2 + in a,(0E2h) + ld (.port3+1),a ; сохр. порт Page3 + ; вкл. начальные 2 стр. блока в #8000..#FFFF + ld hl,list_pages ; список страниц блока + ld a,(hl) + inc hl + out (0C2h),a ; 1-я стр. блока + ld a,(hl) + out (0E2h),a ; 2-я стр. блока + ; очистить Boot+FAT+RootDir + ld hl,8000h ; начало 2-й страницы + ld e,l + ld d,h + inc de + ld bc,8000h-1 ; размер области + ld (hl),l + ldir + ; перебросить BPB в 1-й сектор (boot) + ld hl,msdos ; откуда + ld de,8000h ; куда + ld bc,len_BPB + ldir + dec c + ld hl,8000h+510 + ld (hl),55h ; сигнатура + inc hl + ld (hl),0AAh ; + inc hl + ; FAT + ld (hl),0FAh ; эл. диск + inc hl + ld (hl),c ; FF + inc hl + ld (hl),c ; FF + ; +.port2: ld a,-1 + out (0C2h),a ; восст. порт Page2 +.port3: ld a,-1 + out (0E2h),a ; восст. порт Page3 + ; + call environment ; поиск переменной окружения + ; размер своб. сист. памяти + ld c,3Ch ; инфа о памяти + rst 10h + ; bc=число своб. банок + ld l,c + ld h,b + inc hl ; + банка, занимаемая самой RAMDRV + add hl,hl ;1+1=2 + add hl,hl ;2+2=4 + add hl,hl ;4+4=8 + add hl,hl ;8+8=16 + ld de,freemem ; куда + call decim + ;--------------------------- + ; весь объем диска + ld hl,(.kbytes+1) ; размер в kB + ld de,total_size ; куда + call decim ; заполнение инфо-таблицы + ; вычислить доступный размер диска + ld hl,(msdos+19) ; всех секторов на диске + ld de,(msdos+22) ; секторов на FAT + ld bc,33 ; 1+32 (Boot + RootDirSect) + and a + sbc hl,bc + and a + sbc hl,de ; hl=число дост. секторов + ; CountSect * 512 = SizeBytes + push hl + pop ix + ld b,9 + ld hl,0 +.calc: add ix,ix ; мл.разряд + adc hl,hl ; ст.разряд + djnz .calc + push ix + pop bc + ld de,1024 ; делитель + call divide + ; hl=число kB + ld de,avail_size ; буфер + call decim ; заполнение инфо-таблицы + ; узнать версию ДОС + ld c,0 + rst 10h + ld hl,013Ch ; 1.60 + and a + sbc hl,de + jr nc,.old_ver ; =< 1.60 + ; перескан. девайсы системы + ld c,8 + rst 10h + xor a + ld (mess_),a ; не выводить "Now reboot, ..." + ; вывод инфы по созданному диску + ld hl,ram_created ; info-таблица + ld c,5Ch ; вывод строки + rst 10h + jr .backcode + + ; вывод инфы по созданному диску +.old_ver: ld hl,ram_created ; info-таблица + ld c,5Ch ; вывод строки + rst 10h + ; задержка в 4 секунды + ei + ld b,4 ; 4 секунды +.wait: push bc + ld c,31h ; код клавиши без ожидания + rst 10h + pop bc + jr nz,.exit + ld a,49 ; 1/50 секунды + halt + dec a + jr nz,$-2 + djnz .wait + ; софтовый ребут + xor a + ld bc,02FDh + rst 08h + +.exit: ld hl,aborting + ld c,5Ch ; вывод строки + rst 10h +.backcode: ld b,0 ; возвр. код +.abort: ei + push bc + ; очистить буфер клавы + ld bc,3135h + rst 10h + pop bc + ; выход в ДОС + ld c,41h + rst 10h + di + halt + + + +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +; Расчитать и выделить необходимое число страниц +; +; вход: hl=ст.разряд байтов +; bc=мл.разряд +; выход: CF-ошибка выделения памяти +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +get_mem_pages: ld de,4000h ; делитель (размер страницы) + xor a + scf +.loc1: rr d + rr e + jr c,.loc2 + rr h + rr l + rr b + rr c + jr nc,.loc1 + ld a,1 + jr .loc1 + ; +.loc2: or a + jr z,.loc3 + inc bc +.loc3: xor a + cp b + scf + ret nz + ; выделить блок памяти + ld b,c ; b=число страниц + ld c,0C2h ; выделить блок памяти + rst 08h + ret + + +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +; Расчитать число секторов для FAT +; +; вход: hl=число килобайт +; выход: hl=число секторов +; CF - ошибка +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +get_sect_fat: push hl + ld bc,3984+1 ; Max kB для 31-го сектора FAT + 1 + and a + sbc hl,bc + pop ix + ccf + ret c + ; SizeKBytes * 1024 = SizeBytes + ld b,10 + ld hl,0 +.loop: add ix,ix ; мл.разряд + adc hl,hl ; ст.разряд + djnz .loop + push ix + pop bc + ld (ramdrv.hsize+1),hl + ld (ramdrv.lsize+1),bc + ; вычислить размер FAT в секторах + call get_num_sectors ; SizeBytes / 512 = Total sectors + ld (msdos+19),hl ; всех секторов на диске + ld bc,33 ; 1+32 (Boot + RootDirSect) + sbc hl,bc + add hl,hl + ld c,l + ld b,h + ld hl,0 + ;jr get_num_sectors ; / 512 = Sectors per FAT +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +; Расчитать число секторов +; вход: hl=ст.разряд байтов +; bc=мл.разряд +; выход: hl=число секторов +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +get_num_sectors:ld de,512 ; делитель (размер сектора) +divide: xor a + scf +.loc1: rr d + rr e + jr c,.loc2 + rr h + rr l + rr b + rr c + jr nc,.loc1 + ld a,1 + jr .loc1 + ; +.loc2: or a + jr z,.loc3 + inc bc +.loc3: ld l,c + ld h,b + ret + + + + +;----------------------------------------------------------- +; Конвертировать десят. число (макс. 4 цифры) в слово. +; вход: de=буфер +; выход: hl=число +; "Carry" - ошибка +;----------------------------------------------------------- +dec_to_word: ld hl,0 + ld b,4 ; макс. 4 цифры +.loop: ld a,(de) ; цифра + or a + ret z + call .isdigit + ret c ; ошибка + push bc + call .dec_digit + pop bc + inc de + djnz .loop + ld a,(de) + or a ; был один параметр ? + ret z + ld a,-1 + scf + ret + +; конверт. цифру +.dec_digit: ld c,l + ld b,h + add hl,hl ;1+1=2 + add hl,hl ;2+2=4 + add hl,bc ;4+1=5 + add hl,hl ;5+5=10 + sub "0" + ld c,a + ld b,0 + add hl,bc + ret + +; Тест на цифру +; вых: Carry - не цифра +.isdigit: cp "0" + ret c + cp "9"+1 + ccf + ret + + + +;------------------------------------------------- +; Работа с переменной окружения программы +; и отслеживание буквы диска. +;------------------------------------------------- +environment: ld bc,0146h ; получить переменную окружения + ld hl,name ; имя переменной + ld de,title ; буфер для значения переменной + rst 10h + ret c ; ошибка + or a + jr z,.not_found ; переменная не найдена + ld a,(title) + cp "Z" + ret z + inc a ; ++буква диска + jr .next_letter + ; +.not_found: ld c,2 ; получить текущий номер диска + rst 10h + ld c,1 ; смена диска + rst 10h + add a,"A" +.next_letter: ld (disk),a ; "lastdrive" + ld (disk1),a + ; + ld bc,0246h ; уст. переменную окружения + ld hl,name1 ; имя переменная=значение + rst 10h + ret + + +;------------------------------------------------- +; Перевод числа в символьный десятичный формат +; вход: hl=число +; de=буфер числа +;------------------------------------------------- +decim: ld iy,.tmp + res 7,(iy+0) + ld bc,1000 ;1.000 (макс. 9999) + call .getN16 + ld bc,100 ;100 + call .getN16 + ld bc,10 ;10 + call .getN16 + ld a,l + add a,"0" + ld (de),a + ret + ; +.tmp: db 0 + +.getN16: ld a,2Fh + or a + inc a + sbc hl,bc + jr nc,$-3 + add hl,bc + cp "0" + jr z,$+6 + set 7,(iy+0) + bit 7,(iy+0) + jr nz,$+4 + ld a," " ; вед. пробелы + ld (de),a + inc de + ret + + + + + + + + +name: db "LASTDRV",0 ; имя переменной +name1: db "LASTDRV=" +disk: db "C",0 + + + +title: db 0Dh,0Ah,"RAMdrive Version ",major_version + "0","." + db (minor_version / 10) + "0",(minor_version % 10) + "0" + db ", Copyright (c) 2005-2007 by Vasil Ivanov." + db 0Dh,0Ah,0Ah,0 + + +ram_created: db "RAM-disk " +disk1: db "C: successfully created",0Dh,0Ah + db "Free system memory: " +freemem: db "#### kB",0Dh,0Ah,0Ah + ; + db "Disk size: " +total_size: db "#### kB",0Dh,0Ah ; размер диска + db "Available space: " +avail_size: db "#### kB",0Dh,0Ah ; размер диска + db "Directory entries: 512",0Dh,0Ah ; записей в корне + db "Sector size: 512 bytes",0Dh,0Ah ; байт на сектор + db "Allocation unit: 1 sector",0Dh,0Ah,0Ah ; секторов на кластер +mess_: db "Now reboot, please wait (4 sec.) ...",0 + + + + +aborting: db " Aborting",0Dh,0Ah,0Ah + db "Press ",34,"Ctrl+Alt+Del",34," for rebooting computer..." + db 0Dh,0Ah,0Ah,0Ah,0 + +no_free_ramdisk:db "No free RAM-DISK !",0Dh,0Ah,0Ah,0 + +not_enough: db "Insufficient memory for create RAM-DISK !",0Dh,0Ah,0Ah,0 + + +; не верное значение +err_value: db "Invalid value",0Dh,0Ah,0Ah,0 + +help: db "Syntax: ramdrv.exe ##",0Dh,0Ah,0Ah + db "where: ## - disk size in kB (64 minimum).",0Dh,0Ah,0Ah,0 + + + + + + + +; MS-DOS данные +msdos: db 0EBh,3Ch,90h ; 3 байта, код перехода на загрузчик + db "RDV 1.21" ; 8 байт, OEM ID + ; BPB, 17 байт + dw 512 ;+11 ; байтов на сектор + db 1 ; 1, секторов на кластер + dw 1 ; зарезерв. секторов + db 1 ; число копий FAT-ов + dw 512 ; записей в корне + dw 34 ;+19 ; # всех секторов на диске + db 0FAh ; байт формата + dw 1 ;+22 ; # секторов на FAT + dw 1 ; секторов на сторону + dw 1 ; кол-во сторон диска + ; Extended boot-record + dw 0,0 ; скрытых секторов + dw 0,0 ; всех секторов на диске + dw 80h ; 0x00 физ. номер диска + db 29h ; сигнатура расш. boot-записи + dw 96C2h,2D3Ah ;+39..+41 ; серийный номер диска 2D3A:96C2 + db "NO NAME " ;+43 ; 11 байт, метка ram-диска + db "FAT12 " ;+54 ; 8 байт, ID файловой системы + +len_BPB equ $ - msdos + + + +; буфер списка страниц выдел. блока +list_pages: diff --git a/Shared_Includes b/Shared_Includes index 51198ce..90d8292 160000 --- a/Shared_Includes +++ b/Shared_Includes @@ -1 +1 @@ -Subproject commit 51198ce44bd19f511b63e6fafaf91b3de5470f9d +Subproject commit 90d829290d3946ab99952128f4717dde577ced04