home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.update.uu.se
/
ftp.update.uu.se.2014.03.zip
/
ftp.update.uu.se
/
pub
/
rainbow
/
msdos
/
latrobe
/
b
/
biodif.arc
/
RX50DRV.DIF
< prev
next >
Wrap
Text File
|
1987-06-20
|
15KB
|
503 lines
----------RX50DRV.OLD
; CREATION DATE: 17 May 1986
;
----------RX50DRV.ASM
; CREATION DATE: 18 May 1986
;
-----------------------------------------------
----------RX50DRV.OLD
;
;--
----------RX50DRV.ASM
; RGT 17 Jan 1987 Changed names of offsets and added code
; for double-sided disks
;
;
;--
-----------------------------------------------
----------RX50DRV.OLD
; Define the global entry points for this routine
;
PUBLIC DECDISK, Z80ISR, PHYSDISK
;
----------RX50DRV.ASM
; Define the global entry points and global data for this routine
;
PUBLIC DECDISK, Z80ISR, PHYSDISK
PUBLIC DIRECT_DISK_TIMEOUT_FLAG
;
-----------------------------------------------
----------RX50DRV.OLD
; Define the IOCTL packet offsets
;
XCOMMAND EQU 000H ;IOCTL Packet command offset
XDRIVE EQU 001H ;Drive/side offset
XSECTOR EQU 002H ;Sector offset
XPHDRV EQU 003H ;Physical drive code
XTRACK EQU 004H ;Track # to use
XCOUNT EQU 006H ;# of sectors to transfer
XDMAOFF EQU 008H ;Offset of DMA transfer
XDMASEG EQU 00AH ;Segment of DMA transfer
;
; Define the return values for the disks
;
RX50 EQU 000H ;RX-50 return value
IBM8 EQU 008H ;IBM 8-sector single side
IBM9 EQU 002H ;IBM 9-sector single side
;
; Define the MS-DOS values for the disks
;
RX50VAL EQU 000H ;RX-50 value
IBM8VAL EQU 001H ;IBM 8-sector single side
IBM9VAL EQU 002H ;IBM 9-sector single side
----------RX50DRV.ASM
-----------------------------------------------
----------RX50DRV.OLD
;
----------RX50DRV.ASM
; ;RGT
; Define the calls to the disk cache routines ;RGT
; ;RGT
EXTRN INVALIDATE_DISK_CACHE:NEAR ;Routine to invalidate ;RGT
;disk in cache ;RGT
;
-----------------------------------------------
----------RX50DRV.OLD
----------RX50DRV.ASM
;
-----------------------------------------------
----------RX50DRV.OLD
PUSH ES ;Save reg ES
----------RX50DRV.ASM
;
; Start of code -- set up the segment registers as needed
;
PUSH ES ;Save reg ES
-----------------------------------------------
----------RX50DRV.OLD
XOR DL,DL ;Clear drive byte and assume
;single side
MOV DL,DRIVE[BX] ;Make drive
SHL DL,1 ;Select bits
----------RX50DRV.ASM
; ;RGT
; If this is a double-sided disk, ;RGT
; then the side number is the LSB of the track number. ;RGT
; ;RGT
XOR AX,AX ;Clear reg AH for side ;RGT
MOV AL,DISK_CMD_TRACK_OFF[BX] ;Get track number ;RGT
TEST BYTE PTR DISK_CMD_DENSITY_OFF[BX],FDISK_DSIDE ;RGT
;See if double-sided disk ;RGT
JZ STORE_TRK ;If not, store track number ;RGT
; ;RGT
; Disk is double-sided -- put side no. in reg AH ;RGT
; and track number in reg AL ;RGT
; ;RGT
MOV AH,AL ;Copy track number to reg AH ;RGT
AND AH,1 ;Mask out all but side no. ;RGT
SHR AL,1 ;Shift out side no. from track ;RGT
STORE_TRK: ;RGT
MOV LOCAL_TRACK,AL ;Store new track number ;RGT
MOV DL,DISK_CMD_DRIVE_OFF[BX] ;Get drive ;RGT
SHL DL,1 ;Select bits
-----------------------------------------------
----------RX50DRV.OLD
MOV ES:DRVNO,DL ;Store it
----------RX50DRV.ASM
OR DL,AH ;OR in side number ;RGT
MOV ES:DRVNO,DL ;Store it
-----------------------------------------------
----------RX50DRV.OLD
MOV AL,SECTOR[BX] ;Get sector
CMP BYTE PTR DENSITY[BX],0 ;See if RX-50
JNE ZW0 ;If not, do not skew
CMP BYTE PTR TRACK[BX],2 ;See if track < 2
JB ZW0 ;If so, do not skew
----------RX50DRV.ASM
MOV AL,DISK_CMD_SECTOR_OFF[BX] ;Get sector ;RGT
MOV AH,DISK_CMD_DENSITY_OFF[BX] ;Get disk density ;RGT
AND AH,NOT FDISK_DSIDE ;Mask out double-sided bit ;RGT
JNZ ZW0 ;If not, do not skew
CMP BYTE PTR DISK_CMD_TRACK_OFF[BX],2 ;See if track < 2 ;RGT
JB ZW0 ;If so, do not skew
-----------------------------------------------
----------RX50DRV.OLD
MOV AL,TRACK[BX] ;Get track number
MOV ES:TRACKN,AL ;Set track
MOV AL,COUNT[BX] ;Get number of sectors
MOV ES:NSECT,AL ;Set number of sectors
----------RX50DRV.ASM
MOV AL,LOCAL_TRACK ;Get track number
MOV ES:TRACKN,AL ;Set track
MOV AL,DISK_CMD_COUNT_OFF[BX] ;Get number of sectors ;RGT
MOV ES:NSECT,AL ;Set number of sectors
-----------------------------------------------
----------RX50DRV.OLD
MOV AX,DMASEG[BX] ;Get segment
SHL AX,1 ;Shift over 4 bits to make abs.
----------RX50DRV.ASM
MOV AX,DISK_CMD_DMASEG_OFF[BX] ;Get segment ;RGT
SHL AX,1 ;Shift over 4 bits to make abs.
-----------------------------------------------
----------RX50DRV.OLD
ADD AX,DMAOFF[BX] ;Add in offset
MOV ES:DMAADR,AX ;Set DMA address
MOV AL,COMMAND[BX] ;Get command
CBW ;Expand to word
----------RX50DRV.ASM
ADD AX,DISK_CMD_DMAOFF_OFF[BX] ;Add in offset ;RGT
MOV ES:DMAADR,AX ;Set DMA address
MOV AL,DISK_CMD_CMD_OFF[BX] ;Get command ;RGT
CBW ;Expand to word
-----------------------------------------------
----------RX50DRV.OLD
;
----------RX50DRV.ASM
LOCAL_TRACK DB 0 ;Storage for local track number
;
-----------------------------------------------
----------RX50DRV.OLD
MOV AL,XCOMMAND[BX] ;Get command to perform
CMP AL,6 ;Check if media function
JB PHYS1 ;If not, then do disk I/O
----------RX50DRV.ASM
MOV AL,IOCTL_CMD_OFF[BX] ;Get command to perform ;RGT
CMP AL,IOCTL_CMD_ENABLE_MC ;Check if media function ;RGT
JB PHYS1 ;If not, then do disk I/O
-----------------------------------------------
----------RX50DRV.OLD
; Command = 6 - Turn the function on
; Command = 7 - Turn the function off
; Command = 8 - Read the function status in Reg AL
;
----------RX50DRV.ASM
; Command = IOCTL_CMD_ENABLE_MC - Turn the function on ;RGT
; Command = IOCTL_CMD_DISABLE_MC - Turn the function off ;RGT
; Command = IOCTL_CMD_STATUS_MC - Read the func status ;RGT
;
-----------------------------------------------
----------RX50DRV.OLD
CMP AL,7 ;Check if turn function on
JNZ PHYS3 ;If > 8, then do as 8
----------RX50DRV.ASM
CMP AL,IOCTL_CMD_DISABLE_MC ;Check if turn function off ;RGT
JNZ PHYS3 ;If > 8, then do as 8
-----------------------------------------------
----------RX50DRV.OLD
MOV AX,SEG Z80SEG ;Set reg ES to Z80 segment
MOV ES,AX
XOR DL,DL ;Clear drive
MOV DL,XDRIVE[BX] ;Get driver number
CMP DL,0FFH ;Is this a physical I/O
JNZ LOGDRV ;If not, it is logical
MOV DL,XPHDRV[BX] ;Otherwise, get user
;pre-defined drive code
JMP SHORT STDRV ;And set up the drive
;
----------RX50DRV.ASM
MOV AL,IOCTL_TRACK_OFF[BX] ;Get track number ;RGT
MOV LOCAL_TRACK,AL ;Store as local track ;RGT
MOV AX,SEG Z80SEG ;Set reg ES to Z80 segment
MOV ES,AX
XOR DX,DX ;Clear drive
MOV DL,IOCTL_DRIVE_OFF[BX] ;Get driver number ;RGT
CMP DL,0FFH ;Is this a physical I/O
JNZ LOGDRV ;If not, it is logical
; ;RGT
; Since this is a direct call to the disk, invalidate disk cache ;RGT
; ;RGT
MOV AL,IOCTL_PHDRV_OFF[BX] ;Get user pre-defined drive code;RGT
SHR AL,1 ;Shift over to get drive ;RGT
SHR AL,1 ;RGT
SHR AL,1 ;RGT
SHR AL,1 ;RGT
CALL INVALIDATE_DISK_CACHE ;Invalidate cache for this disk ;RGT
MOV DL,IOCTL_PHDRV_OFF[BX] ;Get user pre-defined drive code;RGT
JMP SHORT STDRV ;And set up the drive
; ;RGT
; Logical drive. ;RGT
; Since this is a direct call to the disk, invalidate disk cache ;RGT
; ;RGT
LOGDRV:
MOV AL,IOCTL_DRIVE_OFF[BX] ;Get driver number ;RGT
CALL INVALIDATE_DISK_CACHE ;Invalidate cache for this disk ;RGT
;
-----------------------------------------------
----------RX50DRV.OLD
LOGDRV:
SHL DL,1 ;Move drive # to higher nybble
----------RX50DRV.ASM
SHL DL,1 ;Move drive # to higher nybble
-----------------------------------------------
----------RX50DRV.OLD
;
----------RX50DRV.ASM
; ;RGT
; If this is not a media check function, then a media check ;RGT
; must be done first to determine if this is a double-sided ;RGT
; media or not. ;RGT
; ;RGT
CMP BYTE PTR IOCTL_CMD_OFF[BX],IOCTL_CMD_MEDIA_CHK ;RGT
;Is this a media check? ;RGT
JE SHORT STDRV ;If so, then assume single side ;RGT
; ;RGT
; If this is a format disk for logical disk, then the media check ;RGT
; cannot be done, as the disk may be uninitialized. ;RGT
; Thus, must assume a single-sided disk. ;RGT
; ;RGT
CMP BYTE PTR IOCTL_CMD_OFF[BX],IOCTL_CMD_FMT_TRACK ;RGT
;Is this a format command? ;RGT
JE STDRV ;If so, then assume single side ;RGT
; ;RGT
; Not a media check or format command. ;RGT
; Must find out what type of media this is. ;RGT
; First, see if it is already stored. ;RGT
; ;RGT
MOV AL,IOCTL_DRIVE_OFF[BX] ;Get drive number ;RGT
CMP AL,LAST_DISK_ACCESSED ;See if same as last disk used ;RGT
JNZ DO_MEDIA_CHECK ;If not, then do media check ;RGT
; ;RGT
; Same disk is accessed as last time, but still may be different. ;RGT
; Now see if time has expired since last accessed. ;RGT
; ;RGT
CMP DIRECT_DISK_TIMEOUT_FLAG,0 ;Timeout ;RGT
JNZ SET_SIDE ;If not, then assume OK ;RGT
;and set side ;RGT
; ;RGT
; Do media check to set media type ;RGT
; ;RGT
DO_MEDIA_CHECK: ;RGT
MOV AL,QKCMCOM ;Get media check command ;RGT
MOV ES:FNCCOD,AL ;Store in packet ;RGT
MOV ES:DRVNO,DL ;Store drive no. in packet ;RGT
PUSH DS ;Save old reg DS ;RGT
MOV AX,CS ;Set DS to CS ;RGT
MOV DS,AX ;RGT
PUSH DX ;Save reg DX ;RGT
PUSH BX ;Save reg BX ;RGT
CALL EXECZ80 ;Call Z80 to do media check ;RGT
POP BX ;Restore saved reg BX ;RGT
POP DX ;Restore saved reg DX ;RGT
POP DS ;Restore saved reg DS ;RGT
XOR AX,AX ;Clear reg AX ;RGT
MOV AL,IOCTL_DRIVE_OFF[BX] ;Get drive number ;RGT
MOV SI,AX ;Store in reg SI ;RGT
MOV AL,ES:BYTE PTR TFORMAT[SI] ;Get media type ;RGT
MOV LAST_DISK_DENSITY,0 ;Set density to single-sided ;RGT
; ;RGT
; Reg AL now has media type -- see if double-sided ;RGT
; ;RGT
TEST AL,010H ;See if double-sided ;RGT
JZ STDRV ;If not, leave side zero ;RGT
; ;RGT
; This is a double-sided media -- store for last disk accessed ;RGT
; ;RGT
MOV LAST_DISK_DENSITY,0FFH ;Set density to double-sided ;RGT
; ;RGT
; This is a double-sided media -- set up side to LSB of track ;RGT
; ;RGT
SET_SIDE: ;RGT
CMP LAST_DISK_DENSITY,0 ;See if single-sided ;RGT
JZ STDRV ;If so, leave side zero ;RGT
MOV AL,LOCAL_TRACK ;Get track number ;RGT
AND AL,1 ;Mask out all but side bit ;RGT
OR DL,AL ;Put side in with drive ;RGT
MOV AL,LOCAL_TRACK ;Get track number again ;RGT
SHR AL,1 ;Shift out side number ;RGT
MOV LOCAL_TRACK,AL ;And store new value of track ;RGT
;
-----------------------------------------------
----------RX50DRV.OLD
MOV ES:DRVNO,DL ;Store drive/side in packet
MOV CX,XTRACK[BX] ;Get track number
XOR AX,AX ;Clear high byte
MOV AL,XSECTOR[BX] ;Get sector number
CMP CX,02 ;See if track > 2
JB SKWED ;If not, do not skew
----------RX50DRV.ASM
MOV AL,IOCTL_DRIVE_OFF[BX] ;Get drive number ;RGT
MOV LAST_DISK_ACCESSED,AL ;Store as last disk used ;RGT
MOV DIRECT_DISK_TIMEOUT_FLAG,DIRECT_DISK_TIMEOUT_TIME ;RGT
;Set timeout time ;RGT
MOV ES:DRVNO,DL ;Store drive/side in packet
MOV CL,IOCTL_TRACK_OFF[BX] ;Get track number ;RGT
XOR AX,AX ;Clear high byte
MOV AL,IOCTL_SECTOR_OFF[BX] ;Get sector number ;RGT
CMP CL,02 ;See if track > 2 ;RGT
JB SKWED ;If not, do not skew
-----------------------------------------------
----------RX50DRV.OLD
MOV ES:TRACKN,CL ;Save track number
----------RX50DRV.ASM
MOV CL,LOCAL_TRACK ;Get real track number ;RGT
MOV ES:TRACKN,CL ;Save track number
-----------------------------------------------
----------RX50DRV.OLD
MOV AL,XCOMMAND[BX] ;Get command
MOV SI,AX ;Move to index into function table
CMP AL,0 ;If read, use intermediate buffer
JZ REDFND1 ;and move the data later
MOV CX,XDMASEG[BX] ;Get users data buffer segment
MOV AX,XDMAOFF[BX] ;Get users data buffer offset
CMP SI,03 ;Is this a format?
JZ FMTFND1 ;If so, then user the user's buffer
----------RX50DRV.ASM
MOV AL,IOCTL_CMD_OFF[BX] ;Get command ;RGT
MOV SI,AX ;Move to index into function table
CMP AL,IOCTL_CMD_READ ;If read, use intermediate buf ;RGT
JZ REDFND1 ;and move the data later
MOV CX,IOCTL_DMASEG_OFF[BX] ;Get users data buffer segment ;RGT
MOV AX,IOCTL_DMAOFF_OFF[BX] ;Get users data buffer offset ;RGT
CMP SI,IOCTL_CMD_FMT_TRACK ;Is this a format? ;RGT
JZ FMTFND1 ;If so, then user the user's buffer
-----------------------------------------------
----------RX50DRV.OLD
MOV CX,0100H ;Get sector size
REP MOVSW ;Move the data
----------RX50DRV.ASM
MOV CX,0100H ;Get sector size in words
REP MOVSW ;Move the data
-----------------------------------------------
----------RX50DRV.OLD
CMP DX,04 ;Was this a media check
JNZ EGGSIT ;If not, just bail out
----------RX50DRV.ASM
CMP DX,IOCTL_CMD_MEDIA_CHK ;Was this a media check ;RGT
JNZ EGGSIT ;If not, just bail out
-----------------------------------------------
----------RX50DRV.OLD
CMP BYTE PTR XCOMMAND[BX],0 ;See if read
JNZ OUTHERE ;If not, get out of here
----------RX50DRV.ASM
; ;RGT
; If this is a media check, then copy the buffer as if in a read ;RGT
; ;RGT
CMP BYTE PTR IOCTL_CMD_OFF[BX],IOCTL_CMD_MEDIA_CHK ;RGT
;See if media check ;RGT
JZ COPYBUF ;If so, then copy the buffer ;RGT
CMP BYTE PTR IOCTL_CMD_OFF[BX],IOCTL_CMD_READ ;RGT
;See if read ;RGT
JNZ OUTHERE ;If not, get out of here
-----------------------------------------------
----------RX50DRV.OLD
;
PUSH DS ;Save registers for move
----------RX50DRV.ASM
; Or it is a media check -- move data to user buffer ;RGT
;
COPYBUF: ;RGT
PUSH DS ;Save registers for move
-----------------------------------------------
----------RX50DRV.OLD
MOV ES,XDMASEG[BX] ;Put data where user expects
MOV DI,XDMAOFF[BX]
PUSH CS ;Set up source address of buffer
----------RX50DRV.ASM
MOV ES,IOCTL_DMASEG_OFF[BX] ;Put data where user expects ;RGT
MOV DI,IOCTL_DMAOFF_OFF[BX] ;RGT
PUSH CS ;Set up source address of buffer
-----------------------------------------------
----------RX50DRV.OLD
;
----------RX50DRV.ASM
; ;RGT
; Define a byte for the last disk accessed and the timeout time. ;RGT
; ;RGT
LAST_DISK_ACCESSED DB 0 ;Last disk used ;RGT
LAST_DISK_DENSITY DB 0 ;Density of last disk used ;RGT
DIRECT_DISK_TIMEOUT_FLAG DB 0 ;Timeout for last disk used ;RGT
DIRECT_DISK_TIMEOUT_TIME EQU 5 ;Set timeout to 5 seconds ;RGT
;
-----------------------------------------------