home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
cpm
/
utils
/
dskbuf
/
ramdrv5.mac
< prev
next >
Wrap
Text File
|
1994-07-13
|
15KB
|
572 lines
TITLE RAMDRIV5.MAC
;
;***********************************************************************
;
; RAMDRIV - A program that permits extended memory to function as
; a fast disk drive. This program does not require modification
; of the existing BIOS.
;
; Copyright 1982, by
; Herbert B. Shore
; Department of Physics
; San Diego State University
; San Diego, CA 92182
; (619) 265-6159
;
; Released to the public domain for non-commercial use.
;
; RAMDRIV has been extensively modified by Paul J. Gans. Changes
; are copyright (c) by Paul J. Gans, Department of Chemistry, New
; York University, New York, NY 10003 (212) 598-2515
;
; New or modified features include:
;
; For RAMDRIV5:
;
; 1. Code has been converted to Z80 code throughout.
; 2. The target assembler is now Microsoft's M80.
; 3. The code is now self-loading. The original RAMLD program is
; no longer required.
; 4. It is no longer required to have contiguous memory banks of
; the same size. Available memory is controlled by the
; BLEN table described below.
; 5. Track size is now a variable multiple of 1K and can be
; changed through an equate.
; 6. The original ALV parameter has been dropped in favor of
; TRAKLEN, the number of kilobytes per track.
; 7. The DRAM parameter has been dropped. Extended (bank)
; addresses are now contained in the BLEN table.
; 8. The program now uses both the directory buffer and the host
; buffer in the local BIOS instead of its own buffer.
; This requires that the user know the addresses of both
; of these buffers in his or her BIOS. To accomodate
; those who choose not to use the BIOS buffers, two DS
; definitions are required a few lines after the label
; WBOOT1. The proper spot is commented in the code
; below.
;
;
; INSTALLATION of RAMDRIV5:
;
; RAMDRIV assumes that the user's system has "extra" memory
; available beyond the normal 64K maximum directly addressable
; in Z80 systems. This memory may be either "bank select" or
; S-100 extended addressing.
;
; RAMDRIV is installed by setting a number of equates and by
; properly configuring the BLEN table located near the end of
; the code. After the proper values have been set by equates and
; the BLEN table has been set up, the code should be assembled
; using M80. The commands for so doing are:
;
; >M80 =RAMDRIV5/L <== /L optionally produces a .PRN file
; >L80 /P:100,RAMDRIV5,RAMDRIV5/N/E
;
; The equates for DIRBUF and RAMBUF must be set to reflect the
; location of these buffers in the user's BIOS. If this is not
; feasible, see the comments at the label WBOOT1.
;
; Equates that must be set are defined and explained below.
;
; In normal use the user must also configure the BLEN table for
; his or her system and recompile. There is one BLEN table entry
; for each bank of memory to be used by RAMDRIV. It is assumed
; that each of these banks starts at address 0000 and proceeds
; upward to some value without any holes. It is also assumed that
; at least the upper 1K of system memory is global, thus no bank
; can exceed 63K.
;
; A BLEN table entry consists of two bytes for each bank of memory
; to be used by RAMDRIV. The first byte is the number of kilo-
; bytes available for RAMDRIV in that bank. This value is placed
; into the BLEN table as the value divided by TRAKLEN. The actual
; number of kilobytes of that bank used by RAMDRIV is the integral
; part of the division. For instance a 30K bank of memory would
; be indicated to the system as 30/TRAKLEN.
;
; The second byte in the BLEN table entry is the extended (or
; bank) address byte for that bank of memory. There is one such
; entry pair for each bank. The table is terminated by a single
; zero byte.
;
; Thus a system with 20K at a bank addressed as 0DEH and 8K at a
; bank addressed as 70H could have a BLEN table as:
;
; BLEN: DB 20/TRAKLN,0DEH
; DB 08/TRAKLN,70H
; DB 0
;
; while the same system in which the user wanted to reserve 4K on
; the board at 0DEH for some other purpose could have a BLEN table
; as:
;
; BLEN: DB 16/TRAKLN,0DEH
; DB 08/TRAKLN,70H
; DB 0
;
;
;************************************************************************
;
; The code and tables in this file will reside in high memory, above the
; existing BIOS. The system is self-loading. Typing RAMDRIV3 from the
; console is sufficient to initiate RAMDRIV3.
;
.Z80
;
FALSE EQU 0
TRUE EQU NOT FALSE
;
; The following equates are system dependent.
;
; DIRBUF: This is the address of the CP/M directory buffer in the
; user's BIOS. CP/M 2.x systems are required to have such a buffer
; available. The address will vary in different implementations.
;
; RAMBUF: This is the address of the CP/M host buffer in the user's
; BIOS. In a normal CP/M 2.x system this buffer will be at least 1K
; long. The address will vary in different implementations.
;
; PANEL: If you have an (IMSAI-type) front panel, set PANEL=TRUE. The
; lights will display the extended address, simulating the LED on the
; door of the disk drive. Flipping switch D0 up will "write protect"
; the RAM drive.
;
; RAMDRIV: Set to a memory location above BIOS. Less than 1K of
; GLOBAL memory is required at this location; i.e. the same block
; of memory must be accessible independent of the setting of the ex-
; tended address bus or any bank byte.
;
; PRAM: The extended address of regular program RAM. Usually this is
; 00H, but need not be.
;
; XPORT: The output port that sets the extended address bus or bank
; byte.
;
; DNAME: The alphabetic designation of the RAM drive.
;
; LIGHTS: The output port for front panel lights. This is signif-
; icant only if PANEL is TRUE.
;
; SWITCH: The input port for front panel switches. This is signif-
; icant only if PANEL is TRUE.
;
; TRAKLN: The number of kilobytes per track. This must be a minimum
; of 1K and a maximum no greater than the smallest bank of memory to
; be made available to RAMDRIV. A good value to use is the greatest
; common divisor of each of the memory banks to be used by RAMDRIV.
;
; DIRECT: The number of directory entries permitted on the RAM drive.
; The number specified must be a multiple of 32. I used 32 to leave
; the maximum space for program files.
;
.Z80
;
DIRBUF EQU 0F77FH ; CP/M BIOS directory buffer address
RAMBUF EQU 0F7FFH ; CP/M BIOS host buffer
PANEL EQU FALSE ;IMSAI FRONT PANEL
RAMDRIV EQU 0FC00H ;START OF PROGRAM.
PRAM EQU 00H ;EXTENDED ADDR. OF MAIN RAM
XPORT EQU 0FDH ;PORT TO SET EXT. ADDR.
DNAME EQU 'C' ;DRIVE NAME OF RAMDRIV.
IF PANEL
LIGHTS EQU 0FFH ;FRONT PANEL LIGHTS.
SWITCH EQU 0FFH ;FRONT PANEL SWITCHES.
ENDIF
TRAKLN EQU 4 ; kilobytes per track
DIRECT EQU 32 ;NO. OF DIRECTORY ENTRIES.
;
; These equates will normally not need to be changed.
;
BDOS EQU 5
DELCHR EQU 0E5H ;DELETED DIRECTORY ENTRY.
DNUMB EQU DNAME - 'A' ;RAMDRIV DRIVE NUMBER
CR EQU 0DH
LF EQU 0AH
;
;
; The code below replaces the original loader code, since that
; mechanism will not work on a program compiled under M80. The
; M80 .PHASE commands have been used rather than the original
; ORG's.
;
LD DE,SIGNON ; print signon message from loader
LD C,9
CALL BDOS
;
LD HL,(0001) ; check to see if BIOS modified
INC HL ; point to jump vector
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
LD DE,RAMDRIV
AND A ; clear carry
SBC HL,DE ; WBOOT minus RAMDRIV
JP C,CONTIN ; if carry we are OK
LD DE,NOWAY
LD C,9
CALL BDOS
JP 0
;
SIGNON: DB 'RAMDRIV5'
DB CR,LF,'$'
NOWAY: DB 'Cannot load RAMDRIV',CR,LF
DB 'Cold boot system and try again'
DB CR,LF,'$'
;
CONTIN: LD HL,SETUP
LD DE,RAMDRIV
LD BC,1023
LDIR
JP RAMDRIV
;
.PHASE RAMDRIV
;
; ORIGINAL JUMP TABLE FROM BIOS
;
WBOOT1: DS 48
WCK: ;END OF BIOS TABLE.
;
CSV: DS DIRECT/4 ; this should probably be zero since no
; checking is done
ALV: DS 72 ; this is allocation vector space which
; must have 1 bit available per block.
; this value corresponds to 576 1K
; blocks.
;
; If the user does not wish to (or cannot) use the directory and host
; buffers in the system BIOS, the buffers can alternatively be defined
; here. In this case the following lines should be uncommented and the
; corresponding equates above commented.
;
;DIRBUF: DS 128 ; directory buffer
;RAMBUF: DS 128 ; bank communication buffer
;
ENDTBL: ;END OF DATA TABLES.
;
.DEPHASE
;
; The following code is executed once to set up the RAMDRIV system. In
; order to conserve space it will be overwritten by data buffers during
; actual access to RAMDRIV.
;
;
SETUP:
;
.PHASE RAMDRIV
;
; Determine the amount of available RAMDRIV memory
;
XOR A
LD C,A
LD HL,BLEN ; RAMDRIV memory table
LD DE,0002 ; table entry increment
BCHEK0: LD A,(HL) ; get bank kilobytesa
OR A ; zero means end of table
JR Z,BCHEK1
ADD A,C ; accumulate count
LD C,A ; and save it
ADD HL,DE ; point to next BLEN entry
JR BCHEK0
;
BCHEK1: CP C ; is there any ram available at all?
JR NZ,RAMOK ; jump if there is
LD DE,NORAM ; no ram, tell the user
LD C,9
CALL BDOS
RET ; avoid warm boots!
;
NORAM: DB 'Cannot activate RAMDRIV. No available RAM.'
DB CR,LF,'$'
;
RAMOK: XOR A ; clear counter
LD B,TRAKLN ; the count must be multiplied
; by TRAKLN to yeild kilobytes
RAMOK1: ADD A,C ; multiply by repeated adding
DJNZ RAMOK1
;
DEC A ; RAMDRIV kilobytes minus 1
LD (DSM),A ; maximum block number to DPB
;
; MODIFY BIOS JUMP TABLES
;
IF $ LT WCK ;MAKE SURE THAT WBOOT1 TABLE
JP BJUMP ;WILL NOT OVERWRITE
ENDIF ;BJUMP ROUTINE.
IF $ LT WCK
DEFS WCK - $
ENDIF
;
BJUMP: LD HL,(1) ;GET ADDRESS OF WARM BOOT
LD DE,WBOOT1 ;TRANSFER TABLE FROM BIOS UP HERE
LD BC,48 ;48 BYTES
LDIR
LD HL,WBOOT2 ;TRANSFER OUR TABLE TO BIOS
LD DE,(0001)
LD BC,48
LDIR
;
; PRINT MESSAGE AND ASK QUESTION
;
LD DE,QUEST
LD C,9 ;PRINT STRING
CALL BDOS
LD C,1 ;GET CHARACTER
CALL BDOS
RES 5,A ;CONVERT TO UPPER CASE.
CP 'Y'
JP NZ,QUIT
;
; CLEAR DIRECTORY OF RAMDRIV
;
LD BC,0000 ; directory on track 0 sector 0
CALL MAP
OUT (XPORT),A
IF PANEL
CPL
OUT (LIGHTS),A ;TO IMSAI FRONT PANEL
ENDIF
EX DE,HL ; HL = base location of directory
LD DE,32 ;EVERY 32 BYTES
LD B,DIRECT ;NO. OF ENTRIES.
LD A,DELCHR
CLEAR: LD (HL),A
ADD HL,DE
DJNZ CLEAR
LD A,PRAM ;RESET EXT. ADDR.
OUT (XPORT),A
IF PANEL
CPL
OUT (LIGHTS),A
ENDIF
;
QUIT: LD DE,CRLF
LD C,9
CALL BDOS
JP 0 ;BACK TO CP/M.
;
QUEST: DB CR,LF
DB 'RAMDRIV active on drive ',DNAME
DB CR,LF
DB 'Should directory of drive ',DNAME
DB ' be cleared (Y/N)? $'
CRLF: DB CR,LF,'$'
;
; NEW TABLE COPIED INTO BIOS
;
WBOOT2: JP WBOOT
JP WBOOT1+3
JP WBOOT1+6
JP WBOOT1+9
JP WBOOT1+12
JP WBOOT1+15
JP WBOOT1+18
JP HOME ;21
JP SELDSK ;24
JP SETTRK ;27
JP SETSEC ;30
JP SETDMA ;33
JP READ ;36
JP WRITE ;39
JP WBOOT1+42
JP SECTRN ;45
;
; IMPLEMENT BIOS FUNCTIONS
;
IF $ LT ENDTBL ;MAKE SURE THAT BIOS
DEFS ENDTBL - $ ; FUNCTIONS BEGIN
ENDIF ; AFTER TABLES.
;
WBOOT: LD HL,80H ;SET INITIAL DMA ADDR.
LD (DMAADR),HL
JP WBOOT1 ;BACK TO BIOS
;
;
HOME: LD A,(DISK) ;CHECK DISK NUMBER.
CP DNUMB ;IS IT THE RAMDRIV?
JP NZ,WBOOT1+21 ;IF NOT, LET BIOS HANDLE IT.
LD A,0 ;SET "TRACK" TO 0
LD (XTRAK),A
RET
;
;
SELDSK: LD A,C ;CHECK REQUESTED DISK,
LD (DISK),A
CP DNUMB
JP NZ,WBOOT1+24
LD HL,DPH ;RETURN DISK PAR. HEADER.
RET
;
; DISK PARAMETER HEADER FOR RAMDRIV
;
DPH:
DW 0 ;NO SECTOR TRANSLATION
DW 0,0,0 ;SCRATCH
DW DIRBUF ;LOC. OF SCRATCHPAD AREA.
DW DPB ;DISK PARAMETER BLOCK
DW CSV ;DIR. CHECK AREA
DW ALV ;ALLOC. VECTOR.
;
; DISK PARAMETER BLOCK
;
DPB:
DW (1024*TRAKLN)/128 ;SECTORS PER TRACK
DB 3 ;BSH
DB 7 ;BLM
DB 0 ;EXM
DSM: DW 62 ;MAX BLOCK NO.
DW DIRECT-1 ;HIGHEST DIRECT. NO.
;
AL0 EQU LOW (0FFH SHL (8-DIRECT/32))
AL1 EQU 0
;
DB AL0,AL1 ;DIRECTORY BLOCKS.
;
CKS EQU 0 ;CHECK DIRECT. ENTRIES.
;
DW CKS
DW 0 ;NO SKIPPED TRACKS.
;
;
SETTRK: LD A,(DISK)
CP DNUMB
JP NZ,WBOOT1+27
LD A,C ;TRACK NO.
LD (XTRAK),A
RET
;
;
SETSEC: LD A,(DISK)
CP DNUMB
JP NZ,WBOOT1+30
LD (SECTOR),BC
RET
;
;
SETDMA: LD (DMAADR),BC ;SAVE DMA ADDR. BOTH HERE
JP WBOOT1+33 ;AND IN BIOS.
;
;
READ: LD A,(DISK)
CP DNUMB
JP NZ,WBOOT1+36
LD BC,(SECTOR) ; but we asssume sector fits in one byte
LD A,(XTRAK) ;SET EXTENDED ADDRESS.
LD B,A
CALL MAP ; to compute bank and offset
OUT (XPORT),A
IF PANEL
CPL
OUT (LIGHTS),A
ENDIF
EX DE,HL
LD DE,RAMBUF ;TEMPORARY BUFFER.
LD BC,128 ;SECTOR=128 BYTES.
LDIR
LD A,PRAM ;RESET ADDR.
OUT (XPORT),A
IF PANEL
CPL
OUT (LIGHTS),A
ENDIF
LD HL,RAMBUF ;MOVE FROM BUFFER
LD DE,(DMAADR) ; back to main ram
LD BC,128
LDIR
XOR A ; show no errors
RET
;
;
WRITE: LD A,(DISK)
CP DNUMB
JP NZ,WBOOT1+39
IF PANEL
IN A,(SWITCH) ;CHECK D0 OF FRONT PANEL
AND 1
RET NZ ;RETURN IF WRITE PROTECT.
ENDIF
LD HL,(DMAADR) ;DMA --> BUFFER
LD DE,RAMBUF
LD BC,128
LDIR
;
LD BC,(SECTOR) ; but we assume sector < 256
LD A,(XTRAK)
LD B,A
CALL MAP
OUT (XPORT),A
IF PANEL
CPL
OUT (LIGHTS),A
ENDIF
LD HL,RAMBUF ;BUFFER --> RAMDRIV.
LD BC,128
LDIR
;
LD A,PRAM
OUT (XPORT),A
IF PANEL
CPL
OUT (LIGHTS),A
ENDIF
XOR A ; show no error
RET
;
;
SECTRN: LD A,(DISK)
CP DNUMB
JP NZ,WBOOT1+45
LD H,B
LD L,C
RET
;
;
; Subroutine to calculate RAM address and bank
;
; called with B = track number (starts from 0)
; C = sector number (starts from 0)
;
; returns with A = extended address byte
; DE = offset into bank for start of sector
;
MAP: XOR A ; clear A
LD A,B ; track number to A
LD DE,2 ; increment for BLEN table
LD HL,BLEN
;
MAP1: SUB (HL) ; subtract bank length in K's
JR C,MAP2 ; jump if track in this bank
ADD HL,DE ; point to next BLEN entry
JR MAP1 ; repeat till done
;
MAP2: ADD A,(HL) ; A = relative track number in bank
RLCA ; multiply by 4K
RLCA
RLCA
RLCA
LD E,D ; clear E
LD D,C ; multiply sector number by 128
RR D
RR E
ADD A,D ; add to track starting address
LD D,A ; DE = sector start in bank
INC HL
LD A,(HL) ; A = extended (bank) address
RET
;
BLEN: DB 32/TRAKLN,0FFH ; first bank has 32K at FF
DB 32/TRAKLN,0FEH ; second bank has 32K at FE
DB 04/TRAKLN,001H ; third bank has 4K at 01
DB 0 ; end of table
;
; DATA STORAGE AREA
;
DISK: DB 0
XTRAK: DB 0
DMAADR: DW 80H
SECTOR: DW 0
;
.DEPHASE
;
END