home *** CD-ROM | disk | FTP | other *** search
-
- ;=======================================================================
- ;
- ; MEMORY DISK FORMAT PROGRAM FOR CP/M PLUS 29 Aug 87
- ; ---------------------------------------- ---------
- ; This program is executed from PROFILE.SUB which is itself processed
- ; on a system reset.
- ;
- ; It looks for a particular directory label on the memory drive. If
- ; one is found then the program assumes the memory drive is formatted
- ; and terminates with no further action. If one is not found then
- ; this program formats the memory drive and executes the command tail.
- ; Typically, the command tail would invoke some utility to copy files
- ; into the memory drive.
- ;
- ; The idea of all this is to automatically format and load the memory
- ; drive on a power up but to leave it alone on a system reset, thereby
- ; speeding up the reboot sequence considerably.
- ;
- ; This program requires CP/M3 and a Z80 but otherwise it is not
- ; hardware-dependent. If your BIOS supports a memory drive then you
- ; can probably use this program. My PROFILE.SUB contains:-
- ;
- ; MFORMAT NULU -O MDFILES -E P:*.* -X
- ;
- ; Jon Saxton,
- ; TIE-Line RCPM+
- ; Dural, NSW
- ; AUSTRALIA
- ; +61 2 651-1404
- ;
- ;=======================================================================
-
- ASEG
- .Z80 ; Keep M80 happy, Z80ASM doesn't care
- ORG 0100H
-
- BDOS EQU 5
- BS EQU 8
- CR EQU 13
- LF EQU 10
- PUTSTR EQU 9
- CPMVSN EQU 12
- SELDSK EQU 14
- DIR1ST EQU 17
- DIRNXT EQU 18
- SETDMA EQU 26
- GETDPB EQU 31
- CHNPGM EQU 47
- FLUSH EQU 48
- SGSCB EQU 49
- BIOSFN EQU 50
- DIRLBL EQU 100
- RTNCODE EQU 108
- DDMA EQU 80H
-
- JR START
- MEMDRV:
- DEFB 'P' ; Change 102h to match your RAM-drive
- START:
- LD DE,GREET
- CALL PRINT
- LD C,CPMVSN ; Ensure we are using CP/M version 3.x
- CALL BDOS
- CP 30H
- JR NC,CPM3
- LD DE,NEED3
- CALL PRINT
- RST 0
- CPM3:
- LD DE,DDMA
- PUSH DE
- LD C,SETDMA
- CALL BDOS
-
- POP HL ; Save command tail
- LD C,(HL)
- LD B,0
- INC BC
- LD DE,COMMAND
- LDIR
-
- LD C,SELDSK ; Select the disk via the BDOS
- LD A,(MEMDRV)
- SUB 'A'
- LD E,A
- PUSH DE
- CALL BDOS
- ;
- ; The following bit of code is PROBABLY unnecessary since it is highly
- ; unlikely anyone would implement record skewing on a RAM-disk. However
- ; since I did not write your BIOS I'm not taking that chance....
- ;
- LD HL,1 ; Select the disk via the BIOS
- LD (DEREG),HL
- POP HL
- LD A,BIOSSEL
- CALL BIOS ; DPH address returned in HL
- LD E,(HL) ; Pick up translate table address
- INC HL
- LD D,(HL)
- LD (TTA),DE ; Save it for RECTRAN
- ;
- ; Look for a particular directory label. If we find it then we assume
- ; the disk is already formatted and loaded up with files.
- ;
- LD DE,ALLFILES
- LD C,DIR1ST
- FILELU:
- CALL BDOS ; Get a directory entry
- CP 0FFH ; Finished?
- JP Z,FORMAT ; Yes but no label so do the format
- LD HL,DDMA ; Not yet - build directory entry address
- ADD A,A
- ADD A,A
- ADD A,A
- ADD A,A
- ADD A,A ; Offset = entry number * 32
- ADD A,L
- LD L,A
- ;; LD A,0 ; (unnecessary since offset < 256)
- ;; ADC A,H
- ;; LD H,A ; HL now points at the directory entry
- LD DE,LABEL ; Point at target directory label
- LD B,12 ; Number of bytes to compare
- CALL STRCMP
- LD C,DIRNXT
- JR NZ,FILELU ; Keep looking if no match
- ;
- ; We get to here if we found the target directory label
- ;
- LD DE,NOFMT
- CALL PRINT
- RST 0 ; Exit if directory label found
- ;
- ;-----------------------------------------------------------------------
- ;
- ; This section of code formats the RAMdisk via the BIOS
- ;
- ;-----------------------------------------------------------------------
- ;
- PRPT EQU 0 ; Word: logical records per track
- PBRH EQU 2 ; Byte: block shift factor
- PBLM EQU 3 ; Byte: block mask
- PEXM EQU 4 ; Byte: extent mask
- PDRM EQU 5 ; Word: blocks - 1
- POFF EQU 13 ; Word: reserved tracks
- PPRH EQU 15 ; Byte: physical record shift factor
- PPHM EQU 16 ; Byte: physical record mask
-
- BIOSSEL EQU 9
- SETTRK EQU 10
- SETREC EQU 11
- BSDMA EQU 12
- WRITE EQU 14
- RECTRN EQU 16
- SETBNK EQU 28
-
- TPABANK EQU 1
-
- FORMAT:
- LD C,GETDPB ; Get disk parameter block address
- CALL BDOS
- PUSH HL ; Put it into an index register for easy
- POP IY ; Reference to DPB fields
- LD HL,RECBUF ; Initialize the data area
- LD DE,RECBUF+1
- LD BC,2048 ; (Most memory drives use 128-byte records
- LDIR ; So this is probably more than enough)
- LD L,(IY+PRPT) ; Calculate number of physical
- LD H,(IY+PRPT+1) ; records per track
- LD A,(IY+PPRH)
- INC A
- PRHLOOP:
- DEC A
- JR Z,PRHEND
- SRL H
- RR L
- JR PRHLOOP
- PRHEND: ; HL now has physical records per track
- LD (RPT),HL ; Remember it
- LD A,(IY+PBRH) ; Calculate physical records per block
- SUB (IY+PPRH) ; A has a "block/record shift factor"
- LD L,(IY+PDRM) ; Get number of blocks
- LD H,(IY+PDRM+1)
- INC HL
- LD B,A
- DRMLOOP:
- ADD HL,HL ; HL ends up with number of physical
- DJNZ DRMLOOP ; records on the disk
- LD (RPD),HL ; (This breaks if memory disk is bigger
- ; than 8Mb and uses 128-byte records
- ; but I doubt if that will be a real
- ; problem.)
- ;
- ; Ready to do the formatting ....
- ;
- LD HL,0 ; Track = record = 0
- LD (TRACK),HL
- LD (RECORD),HL
- LD DE,FMSG ; Printf("Formatting pseudo-track 0000");
- CALL PRINT
- FMTLOOP:
- LD HL,(RPD) ; For (; rpd--;)
- LD A,H ; {
- OR L
- JR Z,FMTEXIT
- DEC HL
- LD (RPD),HL
- LD HL,(TRACK) ; SETRK(track);
- LD A,SETTRK
- CALL BIOS
- LD HL,(RECORD) ; SETREC(RECTRN(record));
- LD DE,(TTA)
- LD (DEREG),DE
- LD A,RECTRN
- CALL BIOS
- LD A,SETREC
- CALL BIOS
- LD DE,RECBUF ; SEDDMA(&RECBUF[0]);
- PUSH DE
- LD C,SETDMA
- CALL BDOS
- POP HL ; /* Must do it via BIOS as well! */
- LD A,BSDMA
- CALL BIOS
- ;; LD A,TPABANK ; SETBNK(TPABANK);
- ;; LD (AREG),A ; /* BIOS "set DMA" function selects
- ;; LD A,SETBNK ; The TPA bank automatically */
- ;; CALL BIOS
- LD A,WRITE ; If (rslt=WRITE())
- LD HL,1
- CALL BIOS
- OR A ; Printf("Write error ... Code=%02x\n",
- CALL NZ,FMTERR ; rslt);
- LD HL,(RECORD) ; If (++record == RPT)
- INC HL
- LD (RECORD),HL
- EX DE,HL
- LD HL,(RPT)
- OR A
- SBC HL,DE
- JR NZ,FMTLOOP ; {
- LD HL,0 ; Record = 0;
- LD (RECORD),HL
- LD DE,BACKSP ; Printf("\b\b\b\b%04x", ++track);
- CALL PRINT
- LD HL,(TRACK)
- INC HL
- LD (TRACK),HL
- CALL HEX16 ; }
- JR FMTLOOP ; }
-
- FMTEXIT:
- LD C,FLUSH ; Flush all disk buffers
- LD E,0 ; (probably not necessary)
- CALL BDOS
- LD DE,FMTDONE ; Say we've finished formatting
- CALL PRINT
- LD DE,LABEL ; Set the directory label
- LD A,(MEMDRV)
- SUB '@'
- LD (DE),A
- XOR A
- LD (LABEL+12),A
- LD C,DIRLBL
- CALL BDOS
- INC A ; Check for error (format must have failed!)
- JR NZ,EXECCMD
- LD DE,FMTFAIL ; Let human know we couldn't set the directory
- CALL PRINT ; Label and exit without doing anything further
- RST 0
- EXECCMD:
- LD DE,LBLDONE ; Say we've set the directory label
- CALL PRINT
- LD DE,DDMA ; Reload the command tail into
- LD HL,COMMAND ; the default DMA buffer at 80h
- LD C,(HL) ; and ensure it is terminated
- LD B,0 ; with a zero byte, then chain
- INC HL ; to the command.
- LDIR
- XOR A
- LD (DE),A
- LD C,CHNPGM
- CALL BDOS ; Should never return, but ....
-
- RST 0
-
- PCHL:
- JP (HL)
- ;
- ; Invokes the BIOS via BDOS(50). Expects function number in A and
- ; principal parameter in HL. Any secondary parameters must have been
- ; pre-loaded into the BIOS parameter block.
- ;
- BIOS:
- LD (BCREG),HL
- LD DE,BIOSPB
- LD (DE),A
- LD C,BIOSFN
- CALL BDOS
- RET
- ;
- ; Compares two strings and sets Z flag if they are equal. HL and DE
- ; point at the strings, B holds the (maximum) number of bytes to compare.
- ;
- STRCMP:
- LD A,(DE)
- CP (HL)
- RET NZ
- INC HL
- INC DE
- DJNZ STRCMP
- RET
- ;
- ; Reports an error if the BIOS returns one while writing to the memory
- ; drive.
- ;
- FMTERR:
- PUSH AF
- LD DE,ERRMSG
- CALL PRINT
- POP AF
- CALL HEX8
- LD DE,CRLF
- CALL PRINT
- RET
- ;
- ; Hexadecimal display routines
- ;
- HEX16:
- PUSH HL
- LD A,H
- CALL HEX8
- POP HL
- LD A,L
- HEX8:
- PUSH AF
- RRA
- RRA
- RRA
- RRA
- CALL HEX4
- POP AF
- HEX4:
- AND 15
- ADD A,90H
- DAA
- ADC A,40H
- DAA
- LD E,A
- LD C,2
- CALL BDOS
- RET
- ;
- ; Display a string on the console. Uses the normal BDOS function.
- ;
- PRINT:
- LD C,PUTSTR
- CALL BDOS
- RET
- ;
- ;-----------------------------------------------------------------------
- ;
- ; Data
- ;
- ;-----------------------------------------------------------------------
- ;
- GREET:
- DEFB 'RAM-disk format program by Jonathan Saxton',CR,LF
- DEFB 'TIE-Line RCPM+, AUSTRALIA. 29 August 1987',CR,LF
- DEFB CR,LF,'$'
- FMTFAIL:
- DEFB 'Error in setting directory label. Probably indicates a',CR,LF
- DEFB 'problem during the formatting phase which may not have',CR,LF
- DEFB 'shown up as a write error. Program terminated.$'
- NOFMT:
- DEFB 'RAM-disk is already formatted$'
- NEED3:
- DEFB 'This program only runs under CP/M version 3.x$'
- FMSG:
- DEFB 'Formatting pseudo-track 0000$'
- BACKSP:
- DEFB BS,BS,BS,BS,'$'
- ERRMSG:
- DEFB 'Write error during format. Code=$'
- CRLF:
- DEFB CR,LF,'$'
- FMTDONE:
- DEFB CR,LF,'RAM-disk formatted',CR,LF,'$'
- LBLDONE:
- DEFB 'Directory label set',CR,LF,LF,'$'
- RPT:
- DEFS 2 ; (Physical) records per track
- RPD:
- DEFS 2 ; (Physical) records per disk
- TRACK:
- DEFS 2 ; Current track number
- RECORD:
- DEFS 2 ; Current record number
- TTA:
- DEFS 2 ; Translate table address (probably zero)
- LABEL:
- DEFB 20H,'RAMDISK JRS' ; Directory label FCB
- DEFW 0,0,0,0,0,0,0,0,0,0,0,0
- ALLFILES:
- DEFB '????????????' ; FCB to match all files
- DEFW 0,0,0,0,0,0,0,0,0,0,0,0
-
- BIOSPB: ; BIOS parameter block
- DEFS 1 ; Function number
- AREG: DEFS 1 ; A register
- BCREG: DEFS 2 ; BC register
- DEREG: DEFS 2 ; DE register
- DEFS 2 ; HL register
- COMMAND:
- DEFS 256 ; Storage for command tail
- RECBUF:
- DEFB 0E5H ; Format pattern
-
- END START