From 80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Fri, 12 Aug 1983 17:53:34 -0700 Subject: MS-DOS v2.0 Release --- v2.0/source/GETSET.ASM | 627 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 627 insertions(+) create mode 100644 v2.0/source/GETSET.ASM (limited to 'v2.0/source/GETSET.ASM') diff --git a/v2.0/source/GETSET.ASM b/v2.0/source/GETSET.ASM new file mode 100644 index 0000000..289f4c8 --- /dev/null +++ b/v2.0/source/GETSET.ASM @@ -0,0 +1,627 @@ +TITLE GETSET - GETting and SETting MS-DOS system calls +NAME GETSET +; +; System Calls which get and set various things +; +; $GET_VERSION +; $GET_VERIFY_ON_WRITE +; $SET_VERIFY_ON_WRITE +; $SET_CTRL_C_TRAPPING +; $INTERNATIONAL +; $GET_DRIVE_FREESPACE +; $GET_DMA +; $SET_DMA +; $GET_DEFAULT_DRIVE +; $SET_DEFAULT_DRIVE +; $GET_INTERRUPT_VECTOR +; $SET_INTERRUPT_VECTOR +; RECSET +; $CHAR_OPER +; +.xlist +; +; get the appropriate segment definitions +; +INCLUDE DOSSEG.ASM + +IFNDEF ALTVECT +ALTVECT EQU 0 ; FALSE +ENDIF + +IFNDEF IBM +IBM EQU 0 +ENDIF + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME SS:DOSGROUP,CS:DOSGROUP + +.xcref +INCLUDE DOSSYM.ASM +INCLUDE DEVSYM.ASM +.cref +.list + + + i_need VERFLG,BYTE + i_need CNTCFLAG,BYTE + i_need DMAADD,DWORD + i_need CURDRV,BYTE + i_need Current_Country,WORD + i_need international_table,BYTE + i_need INDOS,BYTE + i_need SYSINITVAR,WORD + i_need NUMIO,BYTE + i_need SWITCH_CHARACTER,BYTE + i_need DEVICE_AVAILABILITY,BYTE + +USERNUM DW ? ; 24 bit user number + DB ? + IF IBM +OEMNUM DB 0 ; 8 bit OEM number + ELSE +OEMNUM DB 0FFH ; 8 bit OEM number + ENDIF + +MSVERS EQU THIS WORD ; MS-DOS version in hex for $GET_VERSION +MSMAJOR DB DOS_MAJOR_VERSION +MSMINOR DB DOS_MINOR_VERSION + + +BREAK <$Get_Version -- Return MSDOS version number> + procedure $GET_VERSION,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; None +; Function: +; Return MS-DOS version number +; Outputs: +; OEM number in BH +; User number in BL:CX (24 bits) +; Version number as AL.AH in binary +; NOTE: On pre 1.28 DOSs AL will be zero + + PUSH SS + POP DS +ASSUME DS:DOSGROUP + MOV BX,[USERNUM + 2] + MOV CX,[USERNUM] + MOV AX,[MSVERS] + invoke get_user_stack +ASSUME DS:NOTHING + MOV [SI.user_BX],BX + MOV [SI.user_CX],CX + MOV [SI.user_AX],AX ; Really only sets AH + return +$GET_VERSION ENDP + +BREAK <$International - return country-dependent information> +; +; Inputs: +; DS:DX point to a block +; Function: +; give users an idea of what country the application is running +; Outputs: +; AX = number of bytes transferred +; DS:DX ->+---------------------------------+ +; | WORD Date/time format | +; +---------------------------------+ +; | BYTE ASCIZ currency symbol | +; +---------------------------------+ +; | BYTE ASCIZ thousands separator | +; +---------------------------------+ +; | BYTE ASCIZ decimal separator | +; +---------------------------------+ + + procedure $INTERNATIONAL,NEAR +ASSUME DS:NOTHING,ES:NOTHING + MOV BL,AL + PUSH DS + POP ES + PUSH DX + POP DI + PUSH SS + POP DS +ASSUME DS:DOSGROUP + CMP DI,-1 + JZ international_set + OR BL,BL + JNZ international_find + MOV SI,[Current_Country] + MOV AX,WORD PTR [SI-2] ; Get size in AL, country code in AH + MOV BL,AH ; Set country code + JMP SHORT international_copy + +international_find: + CALL international_get + JNC international_copy + error country_not_found + +international_get: + MOV SI,OFFSET DOSGROUP:international_table +international_next: + LODSW ; Get size in AL, country code in AH + CMP AL,-1 + JNZ check_code + STC +RET35: + RET + +check_code: + CMP BL,AH + JZ RET35 ; Carry clear + XOR AH,AH + ADD SI,AX + JMP international_next + +international_copy: + MOV CL,AL + XOR CH,CH + PUSH DI + REP MOVSB + POP DI + MOV WORD PTR ES:[DI.MAP_CALL + 2],CS ; Set segment for case map call +international_ok: + XOR AX,AX + MOV AL,BL ; Return country code in AX + transfer SYS_RET_OK + +international_set: + CALL international_get + JNC international_store + error country_not_found + +international_store: + MOV [Current_Country],SI + JMP international_ok + +$INTERNATIONAL ENDP + +BREAK <$Get_Verify_on_Write - return verify-after-write flag> + procedure $GET_VERIFY_ON_WRITE,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; none. +; Function: +; returns flag +; Returns: +; AL = value of VERIFY flag + + MOV AL,[VERFLG] + return +$GET_VERIFY_ON_WRITE ENDP + +BREAK <$Set_Verify_on_Write - Toggle verify-after-write flag> + procedure $SET_VERIFY_ON_WRITE,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; AL = desired value of VERIFY flag +; Function: +; Sets flag +; Returns: +; None + + AND AL,1 + MOV [VERFLG],AL + return +$SET_VERIFY_ON_WRITE ENDP + +BREAK <$Set_CTRL_C_Trapping -- En/Disable ^C check in dispatcher> + procedure $SET_CTRL_C_TRAPPING,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; AL = 0 read ^C status +; AL = 1 Set ^C status, DL = 0/1 for ^C off/on +; Function: +; Enable disable ^C checking in dispatcher +; Outputs: +; If AL = 0 then DL = 0/1 for ^C off/on + + OR AL,AL + JNZ CTRL_C_set + invoke get_user_stack + MOV AL,[CNTCFLAG] + MOV BYTE PTR [SI.user_DX],AL + return +CTRL_C_set: + DEC AL + JNZ bad_val + AND DL,01h + MOV [CNTCFLAG],DL + return +bad_val: + MOV AL,0FFH + return +$SET_CTRL_C_TRAPPING ENDP + +BREAK <$Get_INDOS_Flag -- Return location of DOS critical-section flag> + procedure $GET_INDOS_FLAG,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; None +; Function: +; Returns location of DOS status for interrupt routines +; Returns: +; Flag location in ES:BX + + invoke get_user_stack + MOV [SI.user_BX],OFFSET DOSGROUP:INDOS + MOV [SI.user_ES],SS + return +$GET_INDOS_FLAG ENDP + +;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; +; C A V E A T P R O G R A M M E R ; +; ; + procedure $GET_IN_VARS,NEAR +; Return a pointer to interesting DOS variables This call is version +; dependent and is subject to change without notice in future versions. +; Use at risk. + invoke get_user_stack + MOV [SI.user_BX],OFFSET DOSGROUP:SYSINITVAR + MOV [SI.user_ES],SS + return +$GET_IN_VARS ENDP +; ; +; C A V E A T P R O G R A M M E R ; +;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; + +BREAK <$Get_Drive_Freespace -- Return bytes of free disk space on a drive> + procedure $GET_DRIVE_FREESPACE,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; DL = Drive number +; Function: +; Return number of free allocation units on drive +; Outputs: +; BX = Number of free allocation units +; DX = Total Number of allocation units on disk +; CX = Sector size +; AX = Sectors per allocation unit +; = -1 if bad drive specified +; This call returns the same info in the same registers (except for FAT pointer) +; as the old FAT pointer calls + + PUSH SS + POP DS +ASSUME DS:DOSGROUP + MOV AL,DL + invoke GETTHISDRV + MOV AX,-1 + JC BADFRDRIVE + invoke FATREAD + XOR DX,DX + MOV BX,2 + MOV CX,ES:[BP.dpb_max_cluster] + DEC CX + PUSH CX ; Save Total +SCANFREE: + invoke UNPACK + JNZ NOTFREECLUS + INC DX +NOTFREECLUS: + INC BX + LOOP SCANFREE + POP BX ; Remember Total + MOV AL,ES:[BP.dpb_cluster_mask] + INC AL + XOR AH,AH + MOV CX,ES:[BP.dpb_sector_size] +BADFRDRIVE: + invoke get_user_stack +ASSUME DS:NOTHING + MOV [SI. user_CX],CX + MOV [SI.user_DX],BX + MOV [SI.user_BX],DX + MOV [SI.user_AX],AX + return + +$GET_DRIVE_FREESPACE ENDP + +BREAK <$Get_DMA, $Set_DMA -- Get/Set current DMA address> + procedure $GET_DMA,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; None +; Function: +; Get DISK TRANSFER ADDRESS +; Returns: +; ES:BX is current transfer address + + MOV BX,WORD PTR [DMAADD] + MOV CX,WORD PTR [DMAADD+2] + invoke get_user_stack + MOV [SI.user_BX],BX + MOV [SI.user_ES],CX + return +$GET_DMA ENDP + + procedure $SET_DMA,NEAR ; System call 26 +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; DS:DX is desired new disk transfer address +; Function: +; Set DISK TRANSFER ADDRESS +; Returns: +; None + + MOV WORD PTR [DMAADD],DX + MOV WORD PTR [DMAADD+2],DS + return +$SET_DMA ENDP + +BREAK <$Get_Default_DPB,$Get_DPB -- Return pointer to DPB> +;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; +; C A V E A T P R O G R A M M E R ; +; ; + procedure $GET_DEFAULT_DPB,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; DL = Drive number (always default drive for call 31) +; Function: +; Return pointer to drive parameter table for default drive +; Returns: +; DS:BX points to the DPB +; AL = 0 If OK, = -1 if bad drive (call 50 only) + + MOV DL,0 + entry $GET_DPB + PUSH SS + POP DS +ASSUME DS:DOSGROUP + MOV AL,DL + invoke GETTHISDRV + JC ISNODRV + invoke FATREAD + invoke get_user_stack +ASSUME DS:NOTHING + MOV [SI.user_BX],BP + MOV [SI.user_DS],ES + XOR AL,AL + return + +ISNODRV: + MOV AL,-1 + return +$GET_Default_dpb ENDP +; ; +; C A V E A T P R O G R A M M E R ; +;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; + + +BREAK <$Get_Default_Drive, $Set_Default_Drive -- Set/Get default drive> + procedure $GET_DEFAULT_DRIVE,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; None +; Function: +; Return current drive number +; Returns: +; AL = drive number + + MOV AL,[CURDRV] + return +$GET_DEFAULT_DRIVE ENDP + + procedure $SET_DEFAULT_DRIVE,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; DL = Drive number for new default drive +; Function: +; Set the default drive +; Returns: +; AL = Number of drives, NO ERROR RETURN IF DRIVE NUMBER BAD + + MOV AL,[NUMIO] + CMP DL,AL + JNB RET17 + MOV [CURDRV],DL +RET17: return +$SET_DEFAULT_DRIVE ENDP + + +BREAK <$Get_Interrupt_Vector - Get/Set interrupt vectors> + procedure $GET_INTERRUPT_VECTOR,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; AL = interrupt number +; Function: +; Get the interrupt vector +; Returns: +; ES:BX is current interrupt vector + + CALL RECSET + LES BX,DWORD PTR ES:[BX] + invoke get_user_stack + MOV [SI.user_BX],BX + MOV [SI.user_ES],ES + return +$GET_INTERRUPT_VECTOR ENDP + + procedure $SET_INTERRUPT_VECTOR,NEAR ; System call 37 +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; AL = interrupt number +; DS:DX is desired new interrupt vector +; Function: +; Set the interrupt vector +; Returns: +; None + + CALL RECSET + MOV ES:[BX],DX + MOV ES:[BX+2],DS + return +$SET_INTERRUPT_VECTOR ENDP + + IF ALTVECT +VECIN: ; INPUT VECTORS + DB 22H ; Terminate + DB 23H ; ^C + DB 24H ; Hard error + DB 28H ; Spooler +LSTVEC DB ? ; ALL OTHER + +VECOUT: ; GET MAPPED VECTOR + DB int_terminate + DB int_ctrl_c + DB int_fatal_abort + DB int_spooler +LSTVEC2 DB ? ; Map to itself + +NUMVEC = VECOUT-VECIN + ENDIF + +procedure RECSET,NEAR + + IF ALTVECT + PUSH SS + POP ES + MOV [LSTVEC],AL ; Terminate list with real vector + MOV [LSTVEC2],AL ; Terminate list with real vector + MOV CX,NUMVEC ; Number of possible translations + MOV DI,OFFSET DOSGROUP:VECIN ; Point to vectors + REPNE SCASB + MOV AL,ES:[DI+NUMVEC-1] ; Get translation + ENDIF + + XOR BX,BX + MOV ES,BX + MOV BL,AL + SHL BX,1 + SHL BX,1 + return +recset ENDP + +BREAK <$Char_Oper - hack on paths, switches so that xenix can look like PCDOS> +; +; input: AL = function: +; 0 - read switch char +; 1 - set switch char (char in DL) +; 2 - read device availability +; 3 - set device availability (0/FF in DL) +; DL = 0 means /DEV/ must preceed device names +; DL = Non0 means /DEV/ need not preeceed +; output: (get) DL - character/flag +; + procedure $CHAR_OPER,NEAR + ASSUME DS:NOTHING,ES:NOTHING + PUSH SS + POP DS +ASSUME DS:DOSGROUP + OR AL,AL + JNZ char_oper_set_switch + MOV DL,[switch_character] + JMP SHORT char_oper_ret +char_oper_set_switch: + DEC AL + JNZ char_oper_read_avail + MOV [switch_character],DL + return +char_oper_read_avail: + DEC AL + JNZ char_oper_set_avail + MOV DL,[device_availability] + JMP SHORT char_oper_ret +char_oper_set_avail: + DEC AL + JNZ char_oper_bad_ret + MOV [device_availability],DL + return +char_oper_bad_ret: + MOV AL,0FFh + return +char_oper_ret: + invoke get_user_stack + MOV [SI.user_DX],DX + return +$CHAR_OPER ENDP + +BREAK <$SetDPB - Create a valid DPB from a user-specified BPB> + procedure $SETDPB,NEAR +ASSUME DS:NOTHING,ES:NOTHING + +; Inputs: +; ES:BP Points to DPB +; DS:SI Points to BPB +; Function: +; Build a correct DPB from the BPB +; Outputs: +; ES:BP and DS preserved all others destroyed + + MOV DI,BP + ADD DI,2 ; Skip over dpb_drive and dpb_UNIT + LODSW + STOSW ; dpb_sector_size + MOV DX,AX + LODSB + DEC AL + STOSB ; dpb_cluster_mask + INC AL + XOR AH,AH +LOG2LOOP: + TEST AL,1 + JNZ SAVLOG + INC AH + SHR AL,1 + JMP SHORT LOG2LOOP +SAVLOG: + MOV AL,AH + STOSB ; dpb_cluster_shift + MOV BL,AL + MOVSW ; dpb_first_FAT Start of FAT (# of reserved sectors) + LODSB + STOSB ; dpb_FAT_count Number of FATs + MOV BH,AL + LODSW + STOSW ; dpb_root_entries Number of directory entries + MOV CL,5 + SHR DX,CL ; Directory entries per sector + DEC AX + ADD AX,DX ; Cause Round Up + MOV CX,DX + XOR DX,DX + DIV CX + MOV CX,AX ; Number of directory sectors + INC DI + INC DI ; Skip dpb_first_sector + MOVSW ; Total number of sectors in DSKSIZ (temp as dpb_max_cluster) + LODSB + MOV ES:[BP.dpb_media],AL ; Media byte + LODSW ; Number of sectors in a FAT + STOSB ; dpb_FAT_size + MUL BH ; Space occupied by all FATs + ADD AX,ES:[BP.dpb_first_FAT] + STOSW ; dpb_dir_sector + ADD AX,CX ; Add number of directory sectors + MOV ES:[BP.dpb_first_sector],AX + SUB AX,ES:[BP.DSKSIZ] + NEG AX ; Sectors in data area + MOV CL,BL ; dpb_cluster_shift + SHR AX,CL ; Div by sectors/cluster + INC AX + MOV ES:[BP.dpb_max_cluster],AX + MOV ES:[BP.dpb_current_dir],0 ; Current directory is root + return +$SETDPB ENDP +; ; +; C A V E A T P R O G R A M M E R ; +;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; + + do_ext + +CODE ENDS + END + \ No newline at end of file -- cgit v1.2.3