• 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)