RAM-Drive/RAMDRV.ASM
2026-05-17 01:05:10 +10:00

575 lines
12 KiB
NASM
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; <20>¥à¥¤ â ¡«¨æ¥© ¤¨áª  ¢ë¢¥á⨠áâப㠮 à §¬¥à¥ ᢮¡. á¨á⥬­®© ¯ ¬ïâ¨
;
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
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; <20> áç¨â âì ¨ ¢ë¤¥«¨âì ­¥®¡å®¤¨¬®¥ ç¨á«® áâà ­¨æ
;
; ¢å®¤: 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
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; <20> áç¨â âì ç¨á«® ᥪâ®à®¢ ¤«ï 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
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; <20> áç¨â âì ç¨á«® ᥪâ®à®¢
; ¢å®¤: 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
;-------------------------------------------------
; <20> ¡®â  á ¯¥à¥¬¥­­®© ®ªà㦥­¨ï ¯à®£à ¬¬ë
; ¨ ®âá«¥¦¨¢ ­¨¥ ¡ãª¢ë ¤¨áª .
;-------------------------------------------------
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
;-------------------------------------------------
; <20>¥à¥¢®¤ ç¨á«  ¢ ᨬ¢®«ì­ë© ¤¥áïâ¨ç­ë© ä®à¬ â
; ¢å®¤: 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: