IBM vdisk.asm (3/3)
From
T. Ment@21:1/5 to
All on Tue Jun 23 03:10:55 2020
[continued from previous message]
MOVE_VDISK ENDP
SUBTTL UPDATE_BOOT
PAGE ;-----------------------------------------------------------------------;
; UPDATE_BOOT updates the BOOT_EM word in the first extended ;
; memory VDISK (address 10 001EH) to show the kilobyte address ;
; of the first extended memory byte not used by any VDISK buffer. ; ;-----------------------------------------------------------------------; UPDATE_BOOT PROC
PUSH DS
MOV DS,FIRST_VDISK ;set DS to first VDISK
MOV AX,DS:AVAIL_LO ;24-bit end address of all VDISKs
MOV DL,DS:AVAIL_HI
XOR DH,DH
POP DS
DIV C1024 ;address / 1024
MOV BOOT_EM,AX ;store in temporary location
MOV AX,2 ;length of block move is 2 bytes
MOV TGT.DESC_LMT,AX
MOV SRC.DESC_LMT,AX
MOV AX,PARA_SIZE ;16
MOV CX,CS ;our segment address
MUL CX ;16 * segment address
ADD AX,OFFSET BOOT_EM ;+ offset of source data
ADC DL,0 ;pick up any carry
MOV SRC.DESC_BASEL,AX ;store source base address
MOV SRC.DESC_BASEH,DL
MOV TGT.DESC_BASEL,BOOT_EM_OFF ;offset of BOOT_EM
MOV TGT.DESC_BASEH,10H ;1 megabyte
MOV CX,1 ;move 1 word
PUSH CS
POP ES
MOV SI,OFFSET GDT ;ES:DI point to global descriptor table
MOV AH,EM_BLKMOVE ;function code
INT EM_INT ;move BOOT_EM to 10 001EH
RET
UPDATE_BOOT ENDP
SUBTTL STEAL_INT19
PAGE ;-----------------------------------------------------------------------;
; STEAL_INT19 changes the INT 19H vector to point to this VDISK ;
; so that subsequent extended memory VDISKS may locate the ;
; AVAIL_HI and AVAIL_LO fields to determine their buffer start ;
; addresses. ; ;-----------------------------------------------------------------------; STEAL_INT19 PROC
PUSH DS
XOR AX,AX
MOV DS,AX ;set DS = 0
ASSUME DS:INT_VEC
CLI ;disable interrupts
LES DI,DS:BOOT_VEC ;get original vector's content
MOV CS:INTV19O,DI ;save original vector
MOV CS:INTV19S,ES
MOV DS:BOOT_VECO,OFFSET VDISK_INT19 ;offset of new INT routine
MOV DS:BOOT_VECS,CS ;segment of new INT routine
STI ;enable interrupts again
POP DS ;restore DS
RET
STEAL_INT19 ENDP
SUBTTL FILL_RH Fill in Request Header
PAGE ;-----------------------------------------------------------------------;
; FILL_RH fills in the Request Header returned to DOS ; ;-----------------------------------------------------------------------;
ASSUME DS:CSEG
FILL_RH PROC ;fill in INIT Request Header fields
MOV CX,START_BUFFER_PARA ;segment end of VDISK resident code
MOV AX,PARAS_PER_SECTOR ;paragraphs per sector
MUL BPB_SECN ;* number of sectors
ADD AX,CX ;+ starting segment
MOV DX,AX ;DX is segment of end VDISK buffer
CMP EM_SW,0 ;if extended memory not requested
JE FILL_RH_A ;skip DX adjustment
MOV DX,CX ;end of code segment addr
FILL_RH_A: ;DX is proper ending segment address
MOV AL,1 ;number of units
test CS:err_flag2,err_baddos
jnz dont_install
TEST ERR_FLAG,ERR_SYSSZ+ERR_EXTSW ;if bypassing install
JZ FILL_RH_B ;jump if installing driver
dont_install:
MOV DX,CS ;segment of end address
XOR AL,AL ;number of units is zero
FILL_RH_B:
PUSH DS ;preserve DS
LDS BX,RH_PTRA ;get Request Header addr in DS:BX
MOV RH.RH0_NUN,AL ;store number of units (0 or 1)
MOV RH.RH0_ENDO,0 ;end offset is always zero
MOV RH.RH0_ENDS,DX ;end of VDISK or end of buffer
MOV RH.RH0_BPBO,OFFSET BPB_PTR
MOV RH.RH0_BPBS,CS ;BPB array address
POP DS ;restore DS
RET
FILL_RH ENDP
SUBTTL WRITE_MESSAGES and associated routines
PAGE ;-----------------------------------------------------------------------;
; WRITE_MESSAGE writes a series of messages to the standard ;
; output device showing the VDISK parameter values actually used. ; ;-----------------------------------------------------------------------;
CHAR4 DB 'nnnn$' ;build 4 ASCII decimal digits
ASSUME DS:CSEG
WRITE_MESSAGES PROC ;display all messages
MSG IMSG ;'VDISK virtual disk $'
test CS:err_flag2,err_baddos
jz check_dos_version
msg errm8
ret
;If DOS Version 3.x is in use, the Request Header contains a drive code
;that is displayed to show which drive letter was assigned to this
;VDISK. This field is not present in the DOS Version 2 Request Header.
check_dos_version:
MOV AH,DOS_VERS ;get DOS version call
INT DOS ;invoke DOS
CMP AL,3 ;DOS Version 3 or greater?
JB WRITE_MESSAGES_A ;no, bypass drive letter
PUSH DS ;preserve DS
LDS BX,RH_PTRA ;get Request Header Address
MOV DL,RH.RH0_DRIV ;get drive code
ADD DL,'A' ;convert to drive letter
POP DS ;restore DS
MOV AH,DOS_PCHR ;function code to write character in DL
INT DOS ;display drive letter
MOV DL,':' ;display trailing colon
INT DOS
WRITE_MESSAGES_A:
MSG MSGCRLF ;end the first line
;If any of the user specified values has been adjusted, issue an
;appropriate message
TEST ERR_FLAG,ERR_BSIZE ;was buffersize adjusted?
JZ WRITE_MESSAGES_B ;if not, skip message
MSG ERRM1 ;buffer size adjusted
WRITE_MESSAGES_B:
TEST ERR_FLAG,ERR_SSZ ;was sector size adjusted?
JZ WRITE_MESSAGES_C ;if not, skip message
MSG ERRM2 ;sector size adjusted
WRITE_MESSAGES_C:
TEST ERR_FLAG,ERR_DIRN ;were directory entries adjusted?
JZ WRITE_MESSAGES_D0 ;if not, skip message
MSG ERRM3 ;directory entries adjusted
WRITE_MESSAGES_D0:
TEST ERR_FLAG,ERR_ESIZE ;was transfer size adjusted?
JZ WRITE_MESSAGES_D ;if not, skip message
MSG ERRM7 ;transfer size adjusted
WRITE_MESSAGES_D:
TEST ERR_FLAG,ERR_SWTCH ;was an invalid switch character found?
JZ WRITE_MESSAGES_E ;if not, skip message
MSG ERRM5 ;invalid switch character
WRITE_MESSAGES_E:
TEST ERR_FLAG,ERR_SYSSZ ;is system size too small to install?
JZ WRITE_MESSAGES_F ;if not, bypass error message
MSG ERRM4 ;too large for system storage
RET ;skip messages showing adjusted sizes
WRITE_MESSAGES_F:
TEST ERR_FLAG,ERR_EXTSW ;extender card switches wrong?
JZ WRITE_MESSAGES_G ;if not, bypass error message
MSG ERRM6 ;extender card switches wrong msg
RET ;skip remaining messages
WRITE_MESSAGES_G: ;display adjusted size messages
MSG MSG1 ;buffer size:
MOV DX,BUFF_SIZE ;buffer size in binary
CALL STOR_SIZE ;convert binary to ASCII decimal
MSG CHAR4 ;print 4 decimals
MSG MSG2 ;KB,CR,LF
MSG MSG3 ;sector size:
MOV DX,BPB_SSZ
CALL STOR_SIZE ;convert binary to ASCII decimal
MSG CHAR4 ;print 4 decimals
MSG MSGCRLF ;finish off line
MSG MSG4 ;directory entries:
MOV DX,BPB_DIRN ;number of directory entries
CALL STOR_SIZE
MSG CHAR4 ;print 4 decimals
MSG MSGCRLF ;finish off the line
CMP CS:EM_SW,0 ;extended memory ?
JE END_LINE ;
MSG MSG5 ;transfer size:
MOV DX,MAXSEC_TRF
CALL STOR_SIZE ;convert binary to ASCII decimal
MSG CHAR4 ;print 4 decimals
MSG MSGCRLF ;finish off line
END_LINE:
MSG MSGCRLF ;one more blank line to set it off
RET ;return to INIT_P1
;SHOW_MSG displays a string at DS:DX on the standard output device
;String is terminated by a $
SHOW_MSG PROC ;display string at DS:DX
PUSH AX ;preserve AX across call
MOV AH,DOS_PSTR ;DOS function code
INT DOS ;invoke DOS print string function
POP AX ;restore AX
RET
SHOW_MSG ENDP
;STOR_SIZE converts the content of DX to 4 decimal characters in CHAR4
;(DX must be <= 9999)
STOR_SIZE PROC ;convert DX to 4 decimals in CHAR4
;develop 4 packed decimal digits in AX
XOR AX,AX ;clear result register
MOV CX,16 ;shift count
STOR_SIZE_B:
SHL DX,1 ;shift high bit into carry
ADC AL,AL ;double AL, carry in
DAA ;adjust for packed decimal
XCHG AL,AH
ADC AL,AL ;double high byte, carry in
DAA
XCHG AL,AH
LOOP STOR_SIZE_B ;AX contains 4 packed decimal digits
PUSH CS
POP ES ;point ES:DI to output string
MOV DI,OFFSET CHAR4
MOV CX,1310H ;10H in CL is difference between blank and zero
;13H in CH is decremented and ANDed to force
;last character not to be zero suppressed
PUSH AX ;save AX on stack
MOV DL,AH ;2 decimals to DL
CALL STOR_SIZE_2 ;display DL as 2 decimal characters
POP DX ;bring low 2 decimals into DL
STOR_SIZE_2: ;display DL as 2 decimal characters
MOV DH,DL ;save 2 decimals in DH
SHR DL,1 ;shift high order decimal right to low position
SHR DL,1
SHR DL,1
SHR DL,1
CALL STOR_SIZE_1 ;display low nibble of DL
MOV DL,DH ;get low decimal from pair
STOR_SIZE_1: ;display low nibble of DL as 1 decimal char
AND DL,0FH ;clear high nibble
JZ STOR_SIZE_Z ;if digit is significant,
XOR CL,CL ;defeat zero suppression
STOR_SIZE_Z:
DEC CH ;decrement zero suppress counter
AND CL,CH ;always display least significant digit
OR DL,'0' ;convert packed decimal to ASCII
SUB DL,CL ;zero suppress (nop or change '0' to ' ')
MOV AL,DL ;char to DL
STOSB ;store char at ES:DI, increment DI
RET
STOR_SIZE ENDP
WRITE_MESSAGES ENDP
INIT_P1 ENDP ;end of INIT part one
;-----------------------------------------------------------------------;
; VDISK Message definitions ; ;-----------------------------------------------------------------------;
IMSG DB 'VDISK virtual disk ','$'
ERRM1 DB ' Buffer size adjusted',CR,LF,'$'
ERRM2 DB ' Sector size adjusted',CR,LF,'$'
ERRM3 DB ' Directory entries adjusted',CR,LF,'$'
ERRM4 DB ' VDISK not installed - insufficient memory'
DB CR,LF,CR,LF,BEL,'$'
ERRM5 DB ' Invalid switch character',CR,LF,'$'
ERRM6 DB ' VDISK not installed - Extender Card switches'
DB CR,LF
DB ' do not match system memory size'
DB CR,LF,CR,LF,BEL,'$'
ERRM7 DB ' Transfer size adjusted',CR,LF,'$'
ERRM8 DB ' VDISK not installed - Incorrect DOS version'
DB CR,LF,CR,LF,BEL,'$'
MSG1 DB ' Buffer size: $'
MSG2 DB ' KB'
MSGCRLF DB CR,LF,'$'
MSG3 DB ' Sector size: $'
MSG4 DB ' Directory entries: $'
MSG5 DB ' Transfer size: $'
MSGEND LABEL BYTE ; End of message text
CSEG ENDS
END
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)