home *** CD-ROM | disk | FTP | other *** search
-
- title 'RAMDISK - A Memory-Based Virtual Drive'
-
- ; THIS PROGRAM IS HEREBY PLACED IN THE PUBLIC DOMAIN,
- ; AND MAY BE FREELY COPIED AND DISTRIBUTED.
-
- ; program: RAMDISK
- ;
- ; created by Context Sensitive Inc.
- ; 4200 Aurora Ave. N.
- ; Seattle, WA 98103
- ; (206) 632-0301
- ;
- ; version: 1.1 October 28, 1983
- ; author: Ron Blanford
- ;
- ; The handler code for the RAM disk takes approximately 250h bytes,
- ; or just over 1/2 kbyte. In versions of CP/M-86 which include
- ; hard disk support, the hard disk initialization code is only
- ; executed once at cold boot, so this program can overlay it with the
- ; handler code to save on memory usage. To enable the overlay
- ; logic, terminate the allocation size with a 'K', for example:
- ; RAMDISK 128K
- ; Otherwise the handler code will be placed at the beginning of
- ; the TPA, reducing the available memory by a small amount.
- ;
- ; In the standard CP/M the default interrupt vector does nothing but
- ; an IRET and return to the program, effectively making all unplanned
- ; interrupts (such as arithmetic exceptions and pressing the keyboard
- ; reset button) invisible. This program causes any such interrupt
- ; to perform a warm boot, returning the user to the CP/M prompt.
-
-
- BIOS_segment equ 0040h
- BIOS_jumptable equ 2500h
-
- cseg
- org 100h
-
- mov dx,offset T_GETSEGT ;get available memory size for messages
- mov cl,50
- int 224
- mov ax,BIOS_segment
- mov es,ax
- mov ax,es:3[bx]
- mov cl,6 ;convert from pages to kbytes
- shr ax,cl
- push ax
- mov bx,offset h1_size+2
- call binasc
- pop ax
- push ax
- mov bx,offset h4_size+2
- call binasc
- pop ax
- mov bx,offset nm_size+2
- call binasc
-
- mov dx,offset company_name ;print company name message
- mov cl,9
- int 224
-
- mov bx,80h ;check command buffer
- mov cl,[bx] ; if no command tail was entered,
- or cl,cl ; display help screens
- jnz RD04
- mov dx,offset help1
- mov cl,9
- int 224
- mov cl,1
- int 224
- cmp al,ctrl_C
- jnz $+5
- jmp exit1
- mov dx,offset help3
- mov cl,9
- int 224
- mov cl,1
- int 224
- cmp al,ctrl_C
- jnz $+5
- jmp exit1
- mov dx,offset help4
- jmp exit
-
- RD04: mov dx,offset T_SELDSK ;see if drive already exists
- mov cl,50
- int 224
- or bx,bx
- jz RD05
- mov dx,offset I_exists
- jmp exit
-
- RD05: mov bx,80h ;get allocation size from command buffer
- mov cl,[bx]
- sub ch,ch
- sub ax,ax
- RD10: inc bx ;convert ascii digits to binary
- cmp byte ptr [bx],' '
- jbe RD20
- cmp byte ptr [bx],'0'
- jb RD21
- cmp byte ptr [bx],'9'
- ja RD21
- mul ten
- mov dl,byte ptr [bx]
- sub dl,'0'
- add ax,dx
- RD20: loop RD10
- RD21: or ax,ax ;make sure size specification is in range
- jnz RD30
- mov dx,offset nosize
- jmp exit
-
- RD30: mov CBOOT_overlay,1 ;if nnnK entered, then put handlers
- or byte ptr [bx],20h ; in space occupied by CBOOT code
- cmp byte ptr [bx],'k'
- jz RD35
- mov CBOOT_overlay,0
- RD35: cmp ax,512 ;max RAMDISK size is 512K
- jbe RD40
- mov ax,512
- RD40: push ax ;put allocation in 'created' message
- mov bx,offset cr_size+2
- call binasc
- pop ax
- mov cl,6
- cmp ax,256 ;if >256K, then change parameters
- jbe RD45 ; to block at 2048
- mov byte ptr BSH,4 ; rather than default 1024
- mov byte ptr BLM,15
- mov byte ptr EXM,1
- mov word ptr DRM,127
- shr ax,1
- mov cl,7
- RD45: mov word ptr DSM,ax
- dec word ptr DSM
- shl ax,cl
- mov disk_pages,ax
- RD50: mov dx,offset T_GETSEGT ;see if enough memory exists
- mov cl,50
- int 224
- mov ax,BIOS_segment
- mov es,ax
- mov dx,es:3[bx] ;number of pages available
-
- cmp CBOOT_overlay,1
- jz RD55
-
- mov ax,offset end_Kdrive ;this code puts the RAMDISK handlers
- sub ax,offset init_Kdrive ; at the beginning of the TPA
- mov cl,4 ; rather than overlaying CBOOT code.
- shr ax,cl
- inc ax
- sub dx,ax
-
- RD55: sub dx,disk_pages
- ja RD60
- mov dx,offset nomem
- jmp exit
-
- RD60: mov es:3[bx],dx ;save new TPA length
- mov di,es:.BIOS_jumptable+1
- add di,BIOS_jumptable+3
-
- cmp CBOOT_overlay,1
- jz RD65
-
- mov di,es:1[bx] ;this code puts the RAMDISK handlers
- add es:1[bx],ax ; at the beginning of the TPA
- mov ax,es ; rather than overlaying CBOOT code.
- sub di,ax
- mov cl,4
- shl di,cl
-
- RD65: mov init_addr,di
- add dx,es:1[bx]
- mov disk_seg,dx
- mov bx,BIOS_jumptable+18h ;move BIOS jumptable to local table
- mov di,offset BIOS_HOME ; after converting from relative
- mov cx,10 ; to absolute addressing
- RD70: inc bx
- mov ax,es:[bx]
- inc bx
- inc bx
- add ax,bx
- mov [di],ax
- inc di
- inc di
- loop RD70
-
- mov dx,init_addr ;move my entry points to BIOS jump table
- sub dx,2
- sub dx,offset init_Kdrive
- mov di,BIOS_jumptable+18h
- inc di
- mov ax,offset HOME
- add ax,dx
- sub ax,di
- mov es:[di],ax
- add di,3
- mov ax,offset SELDSK
- add ax,dx
- sub ax,di
- mov es:[di],ax
- add di,3
- mov ax,offset SETTRK
- add ax,dx
- sub ax,di
- mov es:[di],ax
- add di,3
- mov ax,offset SETSEC
- add ax,dx
- sub ax,di
- mov es:[di],ax
- add di,3
- mov ax,offset SETDMA
- add ax,dx
- sub ax,di
- mov es:[di],ax
- add di,3
- mov ax,offset READ
- add ax,dx
- sub ax,di
- mov es:[di],ax
- add di,3
- mov ax,offset WRITE
- add ax,dx
- sub ax,di
- mov es:[di],ax
- add di,6 ;skip list status jump
- mov ax,offset SECTRAN
- add ax,dx
- sub ax,di
- mov es:[di],ax
- add di,3
- mov ax,offset SETDMAB
- add ax,dx
- sub ax,di
- mov es:[di],ax
-
- sub ax,ax ;set up interrupt handler
- mov es,ax ; by replacing normal IRET
- mov di,es:.0 ; with JMP to my handler
- mov ax,es:.2
- mov es,ax
- mov al,0E9h ;JMP instruction
- mov es:[di],al
- inc di
- mov ax,offset inttrap
- add ax,dx
- sub ax,di
- mov es:[di],ax
-
- add dx,2 ;change local addresses to new location
- mov adj_offset,dx
- add DPH_offset,dx
- add DIRBUF_offset,dx
- add DPB_offset,dx
- add CSV_offset,dx
- add ALV_offset,dx
-
- mov di,init_addr ;move code and data into BIOS
- mov si,offset init_Kdrive
- mov cx,offset end_Kdrive
- sub cx,si
- shr cx,1
- inc cx
- cld
- rep movs ax,ax
- mov dx,offset created
- mov cl,9
- int 224
- jmpf dword ptr init_addr ;go execute disk initialization routine
- init_addr dw BIOS_jumptable+100h
- dw BIOS_segment
-
-
- ; BINASC converts an unsigned binary number to ascii representation.
- ; Input registers: ax = number to convert
- ; bx = ptr to memory location
- ; for least significant digit
- binasc:
- mov byte ptr [bx],'0'
- mov cx,10
- ba10: mov dx,0 ;convert ax to ascii
- div cx
- or ax,ax
- jnz ba15
- or dx,dx
- jz ba20
- ba15: or dl,'0'
- mov byte ptr [bx],dl ;store ascii digit in display area
- dec bx
- jmps ba10
- ba20: ret
-
- exit1: mov dx,offset abort_msg
- exit: mov cl,9
- int 224
- mov dx,0
- mov cl,0
- int 224
-
-
- eject
-
- ctrl_C equ 03h
- cr equ 0Dh
- lf equ 0Ah
- esc equ 1Bh
-
- ten dw 10
- CBOOT_overlay db 1 ;1=overlay CBOOT code, 0=use part of TPA
-
- T_SELDSK db 9 ;direct BIOS call for disk selection
- dw 10
- dw 0
- T_GETSEGT db 18 ;direct BIOS call for memory extents
- dw 0
- dw 0
-
- company_name db esc,'[1;1H',esc,'[J',cr,lf,' ',esc,'[2;3m ',esc,'[3;23m'
- db ' RAMDISK 1.1 '
- db esc,'[2m ',esc,'[m',cr,lf,' ',esc,'[2;4m ',esc,'[4;20m'
- db ' Context Sensitive Inc. Seattle, Washington (206) NEC-0301 '
- db esc,'[2m '
- db esc,'[m',cr,lf,'$'
- help1 db cr,lf,esc,'[19m'
- db cr,lf,' Thank you for choosing RAMDISK from Context Sensitive Inc.'
- db cr,lf,esc,'[20m'
- db cr,lf,' This program creates a pseudo disk drive using part of the'
- db cr,lf,' random access memory (RAM) of your computer. Your computer'
- db cr,lf,' has '
- h1_size db ' '
- db ' kbytes of memory available for program execution.'
- db cr,lf,' Most programs require less than 64 kbytes, so any remaining'
- db cr,lf,' memory would otherwise be unused.'
- db cr,lf
- db cr,lf,' The main advantage of using a RAM disk is its speed. The'
- db cr,lf,' main drawback is that it is not permanent. Each time the'
- db cr,lf,' computer is turned off or CP/M-86 rebooted using the'
- db cr,lf,' CTRL-FNC-BREAK sequence, all files stored on the RAM disk'
- db cr,lf,' are deleted and the RAM disk itself is eliminated. Therefore'
- db cr,lf,' be sure to save all modified files on a permanent disk at'
- db cr,lf,' the end of every session with the computer. In an emergency'
- db cr,lf,' press the reset button behind the rubber stopper in the key-'
- db cr,lf,' board to return to CP/M-86 without erasing the RAM disk.'
- db cr,lf
- db esc,'[25;1H',esc,'[21m Press any key to continue...',esc,'[m$'
- help3 db esc,'[7;1H',esc,'[J'
- db cr,lf,' The RAM disk created by this program is called drive K.'
- db cr,lf,' Drive K is used the same way as any other disk drive. To'
- db cr,lf,' list the directory of files, type:'
- db cr,lf,esc,'[23m DIR K:',esc,'[20m'
- db cr,lf,' (Initially drive K is empty and this command will give the'
- db cr,lf,' NO FILE message.) To copy programs and data files to'
- db cr,lf,' drive K, type:'
- db cr,lf,esc,'[23m PIP K:=filename.typ',esc,'[20m'
- db cr,lf,' To select drive K as the default drive, just type:'
- db cr,lf,esc,'[23m K:',esc,'[20m'
- db cr,lf,' in response to the CP/M-86 prompt.'
- db cr,lf
- db esc,'[25;1H',esc,'[21m Press any key to continue...',esc,'[m$'
- help4 db esc,'[7;1H',esc,'[J'
- db cr,lf,' To create the RAM disk, type:'
- db cr,lf,esc,'[23m RAMDISK nnn',esc,'[20m'
- db cr,lf,' where nnn is the number of kbytes of memory to allocate for'
- db cr,lf,' drive K. Remember, this must be less than '
- h4_size db ' '
- db ' kbytes.'
- db cr,lf,esc,'[m$'
- abort_msg db 0Bh,esc,'[m',esc,'[J$'
- nosize db cr,lf,esc,'[19m'
- db cr,lf,' A size must be specified for RAMDISK drive K'
- db cr,lf,esc,'[21m'
- db cr,lf,' for example: ''RAMDISK 128'' allocates 128K of memory'
- db esc,'[m',cr,lf,'$'
- nomem db cr,lf,esc,'[19m'
- db cr,lf,' RAMDISK drive K not created - not enough memory'
- db cr,lf,esc,'[21m'
- db cr,lf,' Your computer only has '
- nm_size db ' '
- db ' kbytes of memory available'
- db esc,'[m',cr,lf,'$'
- I_exists db cr,lf,esc,'[19m'
- db cr,lf,' RAMDISK drive K not created - it already exists'
- db cr,lf,esc,'[21m'
- db cr,lf,' CTRL-FNC-BREAK deletes all files and removes the drive'
- db esc,'[m',cr,lf,'$'
- created db cr,lf,esc,'[19m'
- db cr,lf,' RAMDISK drive K has been created ('
- cr_size db ' '
- db ' kbytes)'
- db cr,lf,esc,'[21m'
- db cr,lf,' CTRL-FNC-BREAK deletes all files and removes the drive'
- db esc,'[m',cr,lf,'$'
-
-
- title 'RAMDISK initialization and handler code'
- eject
-
- init_Kdrive:
- call adjust
- mov es,disk_seg[bx]
- mov ax,disk_pages[bx]
- init1: push ax ;format the disk area
- mov cx,8000h
- cmp ax,1000h
- ja init2
- mov cl,3
- shl ax,cl
- mov cx,ax
- init2: mov di,0
- mov ax,0E5E5h
- cld
- rep stos ax
- mov ax,es
- add ax,1000h
- mov es,ax
- pop ax
- sub ax,1000h
- ja init1
- mov dx,0
- mov cl,0
- int 224
-
- HOME: call adjust
- cmp byte ptr sek_dsk[bx],10
- jz $+7
- jmp BIOS_HOME[bx]
- ret
-
- SELDSK: call adjust
- mov byte ptr sek_dsk[bx],cl
- cmp cl,10
- jz $+7
- jmp BIOS_SELDSK[bx]
- mov bx,DPH_offset[bx]
- ret
-
- SETTRK: call adjust
- cmp byte ptr sek_dsk[bx],10
- jz $+7
- jmp BIOS_SETTRK[bx]
- mov sek_trk[bx],cx
- ret
-
- SETSEC: call adjust
- cmp byte ptr sek_dsk[bx],10
- jz $+7
- jmp BIOS_SETSEC[bx]
- mov sek_sec[bx],cl
- ret
-
- SETDMA: call adjust
- mov DMA_offset[bx],cx
- jmp BIOS_SETDMA[bx]
-
- READ: call adjust
- cmp byte ptr sek_dsk[bx],10
- jz $+7
- jmp BIOS_READ[bx]
- pushf
- push ds
- push es
- mov es,DMA_seg[bx]
- mov di,DMA_offset[bx]
- mov ax,sek_trk[bx]
- mov cl,6
- shl ax,cl
- add al,sek_sec[bx]
- mul one_twenty_eight[bx]
- mov cl,12
- shl dx,cl
- add dx,disk_seg[bx]
- mov ds,dx
- mov si,ax
- mov cx,64
- cld
- rep movs ax,ax
- pop es
- pop ds
- popf
- sub ax,ax
- ret
-
- WRITE: call adjust
- cmp byte ptr sek_dsk[bx],10
- jz $+7
- jmp BIOS_WRITE[bx]
- pushf
- push ds
- push es
- mov ax,sek_trk[bx]
- mov cl,6
- shl ax,cl
- add al,sek_sec[bx]
- mul one_twenty_eight[bx]
- mov cl,12
- shl dx,cl
- add dx,disk_seg[bx]
- mov es,dx
- mov di,ax
- mov si,DMA_offset[bx]
- mov ds,DMA_seg[bx]
- mov cx,64
- cld
- rep movs ax,ax
- pop es
- pop ds
- popf
- sub ax,ax
- ret
-
- SECTRAN: call adjust
- cmp byte ptr sek_dsk[bx],10
- jz $+7
- jmp BIOS_SECTRAN[bx]
- mov bx,cx
- ret
-
- SETDMAB: call adjust
- mov DMA_seg[bx],cx
- jmp BIOS_SETDMAB[bx]
-
- inttrap:
- cli
- pop ax ;pop old IP, CS, and flags
- pop ax
- pop ax
- or ax,0200h ;enable interrupts on return
- push ax
- mov ax,BIOS_segment ;return to WBOOT
- push ax
- mov ax,BIOS_jumptable+3
- push ax
- iret
-
- adjust: nop ;all variables to be offset
- db 0BBh ; by the amount the program moved
- adj_offset dw 0 ;this is a MOV BX,nnnn instruction
- ret
-
-
- eject
-
- BIOS_HOME DW 0
- BIOS_SELDSK DW 0
- BIOS_SETTRK DW 0
- BIOS_SETSEC DW 0
- BIOS_SETDMA DW 0
- BIOS_READ DW 0
- BIOS_WRITE DW 0
- BIOS_LISTST DW 0
- BIOS_SECTRAN DW 0
- BIOS_SETDMAB DW 0
-
- sek_dsk db 0
- sek_sec db 0
- sek_trk dw 0
- DMA_offset dw 0
- DMA_seg dw 0
- disk_pages dw 0
- disk_seg dw 0
-
- one_twenty_eight dw 128
-
- DPH_offset dw offset DPH
-
- DPH dw 0 ;no sector translation
- dw 0
- dw 0
- dw 0
- DIRBUF_offset dw offset DIRBUF
- DPB_offset dw offset DPB
- CSV_offset dw offset CSV
- ALV_offset dw offset ALV
-
- DIRBUF rs 128
- CSV rs 0
- ALV rs 32
-
- ;disk size: <256K >256K
- DPB dw 64 ;SPT
- BSH db 3 ;BSH 3 4
- BLM db 7 ;BLM 7 15
- EXM db 0 ;EXM 0 1
- DSM dw 0 ;DSM #K-1 (#K/2)-1
- DRM dw 63 ;DRM 63 127
- db 0C0h ;AL0
- db 0 ;AL1
- dw 0 ;CKS
- dw 0 ;OFF
-
- end_Kdrive db 0
-
- end